如何在 C++ 中内联汇编?
How to inline assembly in C++?
我正在尝试将一些程序集注入应用程序,但我在这一行遇到了错误:
这是完整的代码
#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], 0x0F4240; <-------------
jmp return_address;
}
}
void Main_thread() {
while (1) {
Hook((PBYTE)_TOJUMP, &NewInitDamageBuff, bak_InitDamageBuff, 6);
}
}
它有什么问题吗?
编译器是Visual Studio
我用的是葡萄牙语,但我会尝试翻译错误
-号码后缀不正确
-整数 litarals 必须至少有一个数字
- 一些错误的令牌
您的 0x0F4240
中有一些非 ASCII 字符;这就是 MSVC 令人窒息的原因。
MSVC 内联 asm 确实接受 0xDEADBEEF
C 风格十六进制格式的数字文字(与 MASM 不同),因此您的 asm 看起来应该编译/assemble。 (有用没用是另外一回事。)
错误信息是:
<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'
我将你的函数放在 the Godbolt compiler explorer 上以获取实际的错误消息,并使用 DWORD
的类型定义,因为 Godbolt 没有 Windows.h 来定义它。
typedef unsigned long DWORD;
#define _TOJUMP 0xCDFA43
DWORD return_address = _TOJUMP + 0x6;
static __declspec(naked) void NewInitDamageBuff() {
_asm {
mov [edx + 0x29D0], 0x0F4240; // original
mov [edx + 0x29D0], 0x0F4240; // retyped compiles fine if you comment out the original
jmp return_address;
}
}
那些错误消息让我觉得里面有一个非 ASCII 字符,它正在窒息,在我的 Linux 桌面上 copy/paste 进入 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 端的 .
表示不可打印的字节)。
所以在 mov
的源操作数中的 0x
之后,有一个 80 ad 30
3 字节的 UTF-8 序列,显然不会打印任何东西。
我正在尝试将一些程序集注入应用程序,但我在这一行遇到了错误: 这是完整的代码
#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], 0x0F4240; <-------------
jmp return_address;
}
}
void Main_thread() {
while (1) {
Hook((PBYTE)_TOJUMP, &NewInitDamageBuff, bak_InitDamageBuff, 6);
}
}
它有什么问题吗?
编译器是Visual Studio
我用的是葡萄牙语,但我会尝试翻译错误
-号码后缀不正确
-整数 litarals 必须至少有一个数字
- 一些错误的令牌
您的 0x0F4240
中有一些非 ASCII 字符;这就是 MSVC 令人窒息的原因。
MSVC 内联 asm 确实接受 0xDEADBEEF
C 风格十六进制格式的数字文字(与 MASM 不同),因此您的 asm 看起来应该编译/assemble。 (有用没用是另外一回事。)
错误信息是:
<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'
我将你的函数放在 the Godbolt compiler explorer 上以获取实际的错误消息,并使用 DWORD
的类型定义,因为 Godbolt 没有 Windows.h 来定义它。
typedef unsigned long DWORD;
#define _TOJUMP 0xCDFA43
DWORD return_address = _TOJUMP + 0x6;
static __declspec(naked) void NewInitDamageBuff() {
_asm {
mov [edx + 0x29D0], 0x0F4240; // original
mov [edx + 0x29D0], 0x0F4240; // retyped compiles fine if you comment out the original
jmp return_address;
}
}
那些错误消息让我觉得里面有一个非 ASCII 字符,它正在窒息,在我的 Linux 桌面上 copy/paste 进入 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 端的 .
表示不可打印的字节)。
所以在 mov
的源操作数中的 0x
之后,有一个 80 ad 30
3 字节的 UTF-8 序列,显然不会打印任何东西。