在 preprocessing/compilation 期间内联汇编到字节码?

Inline assembly to bytecodes during preprocessing/compilation?

我有一个程序,我想在运行时修补它,它由许多长函数组成。我认为如果我可以在函数中修补特定范围的指令而不是完全重写它们会更容易。

为此,我想创建一个函数,给定进程的内联程序集、起始地址和结束地址,该函数将用自定义给定程序集替换地址范围内的所有汇编代码。

如果使用 WriteProcessMemory 写入所有程序集的字节后地址范围内还有剩余内存(即,如果字节缓冲区小于地址范围)剩余地址 space 充满了 nop 指令。如果没有足够的 space 来容纳程序集,整个地址范围将被 nop 指令填充,并且 jmp 指令被放置在开始处,它将例程重定向到包含以下内容的函数所有集会。

为此,我需要在编译时知道程序集的字节码,我不确定该怎么做,或者是否可能。更重要的是,我希望函数是一个宏,它的行为很像 GCC 使用的内联汇编,所以函数看起来像:

BYTE* asm_bytecode = get_asm_bytecodes ( 0x0<start_address>, 0x0<end_address>, 
    "mov eax, eax;"
);
WriteProcessMemory(..., asm_bytecode, ...);

所以我的问题是:

请注意,我在 Windows 上为 GCC 使用 MinGW。

您可以在函数外部使用 asm 来 assemble 任何您喜欢的指令序列,并创建标签来标记开始和结束。然后你就会在内存中拥有这些字节,并且可以将它们复制到你喜欢的地方。

asm(".text \n\t"
    ".global my_code \n"
    "my_code: \n\t"
    "frob %rax \n\t"
    "grind 345, %rbx \n\t"
    // ...
    ".global end_of_my_code \n"
    "end_of_my_code: \n\t"
);

extern unsigned char *my_code;
extern unsigned char *end_of_my_code;
size_t my_code_size = end_of_my_code - my_code;

void overwrite(...) {
    WriteProcessMemory(..., my_code, my_code_size, ...);
}

(我忘记了 MinGW 是否需要在符号上使用前导下划线。如有必要请添加。)