如何在C++中在线组装?

How to inline assembly in C++?

本文关键字:在线 C++      更新时间:2023-10-16

我正在尝试将一些程序集注入到应用程序中,但在此行出现错误: 这是完整的代码

#define _TOJUMP 0xCDFA43 
BYTE bak_InitDamageBuff[6];
void unHook(BYTE* from, BYTE* backup, size_t size) {
DWORD protect;
VirtualProtect(from, size, PAGE_EXECUTE_READWRITE, &protect);
memcpy(from, backup, size);
VirtualProtect(from, size, protect, &protect);
}
void Hook(BYTE* from, void* to, BYTE* backup, size_t size) {
DWORD protect;
VirtualProtect(from, size, PAGE_EXECUTE_READWRITE, &protect);
memcpy(backup, from, size);
DWORD diff = ((DWORD)to - (DWORD)from) - size;
memset(from, 0x90, size);
*(BYTE*)from = 0xE9;
*(DWORD*)((DWORD)from + 1) = diff;
VirtualProtect(from, size, protect, &protect);
}
DWORD return_address = _TOJUMP + 0x6;
static __declspec(naked) void NewInitDamageBuff() {
_asm {
mov [edx + 0x29D0], 0x‭0F4240‬;    <-------------
jmp return_address;
}
}
void Main_thread() {
while (1) {
Hook((PBYTE)_TOJUMP, &NewInitDamageBuff, bak_InitDamageBuff, 6);
}
}

这有什么问题?

编译器是Visual Studio

我用葡萄牙语使用它,但尝试翻译错误

-数字后缀不正确

-整数 litalars 必须至少有一个数字

  • 不好的令牌

你的0x‭0F4240‬里有一些非ASCII字符;这就是MSVC窒息的地方。


MSVC 内联 asm 确实接受 C 样式十六进制格式的数字文字0xDEADBEEF(与 MASM 不同(,因此您的 asm 看起来应该编译/汇编。 (它是否有用是另一回事。

错误消息是:

<source>(9): error C2059: syntax error: 'bad suffix on number'
<source>(9): error C2153: integer literals must have at least one digit
<source>(9): error C3872: '0xac': this character is not allowed in an identifier
<source>(9): error C2400: inline assembler syntax error in 'second operand'; found 'bad token'

我把你的函数放在Godbolt编译器资源管理器上,以获得实际的错误消息,DWORD有一个typedef,因为Godbolt没有Windows.h来定义它。

typedef unsigned long DWORD;
#define _TOJUMP 0xCDFA43
DWORD return_address = _TOJUMP + 0x6;
static __declspec(naked) void NewInitDamageBuff() {
_asm {
mov [edx + 0x29D0], 0x‭0F4240‬;   // original
mov [edx + 0x29D0], 0x0F4240;   // retyped compiles fine if you comment out the original
jmp return_address;
}
}

这些错误消息让我认为那里有一个非 ASCII 字符窒息,并且在我的 Linux 桌面上复制/粘贴到hexdump -C中证实了这一点:

00000000  6d 6f 76 20 5b 65 64 78  20 2b 20 30 78 32 39 44  |mov [edx + 0x29D|
00000010  30 5d 2c 20 30 78 e2 80  ad 30 46 34 32 34 30 e2  |0], 0x...0F4240.|
00000020  80 ac 3b 0a                                       |..;.|

(输出的 ASCII 端的.表示不可打印的字节(。

因此,在源操作数mov0x之后,有一个80 ad 30的3字节UTF-8序列,显然不会打印任何东西。