用较长的指令替换较短的指令 in-place(汇编)
Replacing shorter with longers instructions in-place (assembly)
当用较短的指令替换较长的指令时,我们可以只用 nop
s 填充。
我将如何以相反的方式进行内联替换?
内联我的意思是不是 jmp
到其他空闲内存然后返回。
换句话说,是否有可能以某种方式插入更多操作?这是怎么做到的?是否应该以某种方式修改二进制文件的 header ?所有 jmp
ops 会发生什么(他们会在理论改变后继续工作吗?)。如果有绝对 jmp
怎么办?那些也应该修改,对吧?还有什么应该做的(如果这实际上是可能的)?
这里有几个问题:
所有类型的简单跳转,无论是有条件的(je
、jne
等)还是无条件的(jmp
),都存在short和near两种形式,其中前者有一个有符号字节大小的偏移量(范围 -128 到 +127),后者有一个有符号双字大小的偏移量(范围 -2147483648 到 +2147483647)。
更改条件跳转的条件不需要更改跳转大小,但如果所需目标地址超出范围,则可能需要更改跳转的目标地址。
如果您想真正将跳转目标更改到一个新位置,该位置超出当前跳转类型的范围,或者在代码位置插入更多指令,则需要重新定位代码在它之后。
正如您所怀疑的那样,这样做涉及修复所有跨越代码中新间隙的相对引用以及间隙之后的任何绝对引用,如果被引用的内容也被重新定位,那么绝对引用也被重新定位赶在差距之前。
此类操作的难度从中等复杂到不可能,具体取决于代码的结构和您掌握的信息。
如果有问题的代码是由编译器发出的,并且您有可用的符号信息,则可以完成,否则通常很难完成,除非所需的更改非常小。
如果你有机器指令
A; B; C; D; E;
并且需要用更大的 X 替换 B,然后您可以删除 C、D 等,以获得足够的 space 进行跳跃。
说 C; D;
够大了。所以你最终得到
A; jmp freeSpace; back: E
...
<previous end of binary>
freeSpace: X; C; D; jmp back;
如果 C and/or D 本身就是跳跃,这会有所不同。但你总能让它发挥作用。
那天我用它来修补只有纸质汇编列表可用的二进制文件。不优雅,但工作正常。如果这就是 Ida Pro 所做的,我不会感到惊讶。
当用较短的指令替换较长的指令时,我们可以只用 nop
s 填充。
我将如何以相反的方式进行内联替换?
内联我的意思是不是 jmp
到其他空闲内存然后返回。
换句话说,是否有可能以某种方式插入更多操作?这是怎么做到的?是否应该以某种方式修改二进制文件的 header ?所有 jmp
ops 会发生什么(他们会在理论改变后继续工作吗?)。如果有绝对 jmp
怎么办?那些也应该修改,对吧?还有什么应该做的(如果这实际上是可能的)?
这里有几个问题:
所有类型的简单跳转,无论是有条件的(je
、jne
等)还是无条件的(jmp
),都存在short和near两种形式,其中前者有一个有符号字节大小的偏移量(范围 -128 到 +127),后者有一个有符号双字大小的偏移量(范围 -2147483648 到 +2147483647)。
更改条件跳转的条件不需要更改跳转大小,但如果所需目标地址超出范围,则可能需要更改跳转的目标地址。
如果您想真正将跳转目标更改到一个新位置,该位置超出当前跳转类型的范围,或者在代码位置插入更多指令,则需要重新定位代码在它之后。
正如您所怀疑的那样,这样做涉及修复所有跨越代码中新间隙的相对引用以及间隙之后的任何绝对引用,如果被引用的内容也被重新定位,那么绝对引用也被重新定位赶在差距之前。
此类操作的难度从中等复杂到不可能,具体取决于代码的结构和您掌握的信息。
如果有问题的代码是由编译器发出的,并且您有可用的符号信息,则可以完成,否则通常很难完成,除非所需的更改非常小。
如果你有机器指令
A; B; C; D; E;
并且需要用更大的 X 替换 B,然后您可以删除 C、D 等,以获得足够的 space 进行跳跃。
说 C; D;
够大了。所以你最终得到
A; jmp freeSpace; back: E
...
<previous end of binary>
freeSpace: X; C; D; jmp back;
如果 C and/or D 本身就是跳跃,这会有所不同。但你总能让它发挥作用。
那天我用它来修补只有纸质汇编列表可用的二进制文件。不优雅,但工作正常。如果这就是 Ida Pro 所做的,我不会感到惊讶。