x86方式来告诉数据的指令
有没有一种或多或少的可靠方式来判断内存中某个位置的数据是处理器指令的开始还是其他数据?
例如, E8 3F BD 6A 00
可以是相对偏移量为0x6ABD3F
call
指令( E8
),也可以是属于某个其他指令的三个字节的数据,然后push 0
( 6A 00
)。
我知道这个问题听起来很愚蠢,可能没有简单的方法,但也许指令集是为了解决这个问题而设计的,也许一些检查位置周围的+ -100字节的简单代码可以给出很可能是正确的答案。
我想知道这一点,因为我扫描程序的代码,并用呼叫替换所有呼叫到一些功能。 它工作到目前为止,但在某些时候,并不是不可能的,因为我增加了我要替换的函数的数量,一些数据看起来就像是对该确切地址的函数调用,并且将被替换,并且这会导致程序以最意想不到的方式打破。 我想减少这种可能性。
如果它是您的代码(或另一个保留链接和调试信息的代码),最好的方法是扫描目标文件中的符号/重定位表。 否则,没有可靠的方法来确定某个字节是否是导致数据丢失。
可能最有效的数据验证方法是递归反汇编。 I. e。 从实体点和发现的所有跳转目标中分解代码。 但是这不是完全可靠的,因为它不会遍历跳转表(你可以尝试使用一些启发式的方法,但这也不完全可靠)。
解决你的问题的方法是将补丁函数自己替换掉:用跳转指令覆盖其开头的函数。
不幸的是,没有100%可靠的方法来区分代码和数据。 从CPU的角度来看,只有当某些跳转操作码诱使处理器尝试执行字节,就好像它们是代码一样,代码才是代码。 您可以尝试从程序入口点开始进行控制流分析,并遵循所有可能的执行路径,但是在存在指向函数的指针时可能会失败。
对于你的具体问题:我收集你想用自己的替代替换现有的功能。 我建议你修补被替换的函数本身。 即,而不是定位调用所有foo()
函数,并用电话代替他们bar()
只需更换的第一个字节foo()
有一个跳转到bar()
(A jmp
,而不是一个call
:你做不想乱用堆栈)。 由于双跳,这不太令人满意,但它是可靠的。
一般来说,不可能区分数据和指令,这是因为冯诺依曼架构。 分析代码很有帮助,反汇编工具可以做到这一点。 (这可能会有所帮助,如果您不能使用IDA Pro /这是商业/,请使用其他反汇编工具。)
链接地址: http://www.djcxy.com/p/80349.html