我的程序通过将jmp指令写入函数的前几个字节(仅i386)将函数重定向到另一个函数。它的工作方式与预期相同,但这意味着我不能再调用原始函数了,因为它总会跳转到新函数。
我可以想到两种可能的解决方法:
创建一个新函数,它覆盖目标函数的jmp指令并调用它。然后该函数写回jmp指令。 但是我不确定如何传递参数,因为它们可以有任意数量。我想知道目标函数是否可以在其他地方jmp并跳过写回jmp指令(比如throw catch?)。
创建一个新函数,执行我用jmp指令覆盖的代码。但我不能确定覆盖的数据是完整的指令。我必须知道我需要复制多少字节才能获得完整的说明。
所以,最后,我的问题:
还有另一种我没想到的方式吗?
如何找到指令的大小?我已经查看了binutils并找到了this,但我不知道如何解释它。
以下是一个示例:
mov, 2, 0xa0, None, 1, Cpu64, D|W|CheckRegSize|No_sSuf|No_ldSuf, { Disp64|Unspecified|Byte|Word|Dword|Qword, Acc|Byte|Word|Dword|Qword }
第二列显示操作数(2),最后一列显示有关操作数的信息,用逗号分隔
我也发现这个问题几乎相同,但我不能确定7个字节是否包含整个指令。 Writing a Trampoline Function
任何帮助表示赞赏!感谢。
答案 0 :(得分:1)
Sebastian,您可以使用hotpatch中的exe_load_symbols()函数获取符号列表及其在现有exe中的位置,然后查看是否可以覆盖内存中的符号。我还没有尝试过。您也可以使用LD_PRELOAD环境变量代替hotpatch。
- 维卡斯
答案 1 :(得分:0)
这样的事情怎么样:
让我们说这是原始功能:
Instruction1
Instruction2
Instruction3
...
RET
将其转换为:
JMP new_stuff
old:
Instruction2
Instruction3
...
RET
...
new_stuff:
CMP call_my_function,0
JNZ my_function
Instruction1
JMP old
my_function:
...
当然,您必须考虑原始说明的大小(例如,您可以通过使用objdump
反汇编来找到它),以便第一个JMP
完全适合(填充) NOP
如果JMP
比原始指令短,则为{{1}}。