在自修改代码中,如何获得要修改字节的实际运行地址



在自修改代码的例子中,您可以使用函数名作为标签来获得程序的实际地址,加上要修改的字节的偏移量,然后获得要修改字节的实际地址。那么,是否可以在运行时直接获取基地址,而不使用函数名之类的标记?加上我提前得到的直接到要修改的字节的实际地址的偏移量?

示例:https://shanetully.com/2013/12/writing-a-self-mutating-x86_64-c-program/

void *foo_addr = (void*)foo; // Get the actual address of the function
// Change the immediate value in the addl instruction in foo() to 42
unsigned char *instruction = (unsigned char*)foo_addr + 22;
*instruction = 0x2A;

其地址信息为:foo_addr=0x3b882c0,+22=0x3b 882d6

现在,我不想受到函数的约束,假设我通过静态分析得到了要修改的当前字节的起始位置的偏移量。所以现在我想在运行时直接获得基址,基址+偏移量=要修改的字节的位置。这可行吗?如果是,如何获取基本地址?

Linux使用地址空间布局随机化(自2001年以来(,因此您不能盲目地假设代码在您期望的位置。这对函数指针来说并不重要,因为您的编译器知道ASLR是如何工作的。无论foo实际加载在哪里,调用&foo都能工作。静态分析在这里没有帮助,因为现在还为时过早。

此外,函数指针指向第一条指令。不能假设函数中的所有其他指令都直接跟在后面。嵌入和勾勒都可以打破这种局面。

最新更新