Assembly 在汇编中,如何在调试器的3字节空间中添加5字节指令
我想换一条线Assembly 在汇编中,如何在调试器的3字节空间中添加5字节指令,assembly,x86,red-zone,Assembly,X86,Red Zone,我想换一条线 0041DE91 | 8B 46 64 | mov eax,dword ptr ds:[esi+64] 0041DE94 | 83 C4 0C | add esp,C 0041DE97 | 83 F8 01 | cmp eax,1 0041DE
0041DE91 | 8B 46 64 | mov eax,dword ptr ds:[esi+64]
0041DE94 | 83 C4 0C | add esp,C
0041DE97 | 83 F8 01 | cmp eax,1
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
到
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
但3字节的指令占用5字节,并溢出到它下面的两个地址:
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
可以在调试器中对预编译程序执行此操作吗 在32位代码中(无需关闭),您可以将imm8常量移动到具有3个字节的寄存器中(效率低下):
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
push 10 ; 2B
pop eax ; 1B
您还可以将1
放入3B中的寄存器中
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
xor eax, eax ; 2B
inc eax ; 1B
或者,鉴于任何其他已知内容的登记册:
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
lea eax, [ecx+/-imm8] ; 3B
其他代码/代码大小优化技巧:
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
xor eax,eax ; 2B
cdq ; 1B to zero edx as well
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
其中许多代码也适用于16位和64位代码。例如,请参见my.在32位代码中(没有可关闭的代码),您可以使用3个字节将imm8常量移动到寄存器中(效率低下):
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
push 10 ; 2B
pop eax ; 1B
您还可以将1
放入3B中的寄存器中
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
xor eax, eax ; 2B
inc eax ; 1B
或者,鉴于任何其他已知内容的登记册:
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
lea eax, [ecx+/-imm8] ; 3B
其他代码/代码大小优化技巧:
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
xor eax,eax ; 2B
cdq ; 1B to zero edx as well
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
其中许多代码也适用于16位和64位代码。例如,请参见my。如果在3字节区域周围还有一些空格,则可以将新代码放在那里,然后执行一次近似跳转,然后执行所需操作并跳回
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
该技术用于在Windows中实现热修补。它是通过将MOV EDI,EDI
作为2字节NOP
放在函数的开头来完成的。然后,当需要修补函数时,它们会用JMP$-5
替换该“NOP”,并在函数之前的5个字节中跳转到新函数
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
所以现在基本上你需要改变
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
mov eax, dword ptr ds:[esi+64]
add esp, C
cmp eax, 1
到
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
使用此方法,您可以将原始指令替换为任何指令序列。但是,对于设置小值,那么Peter的解决方案更好如果在3字节区域周围留有一些空格,您可以将新代码放在那里并进行一次近距离跳转,做您需要的并跳回去
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
该技术用于在Windows中实现热修补。它是通过将MOV EDI,EDI
作为2字节NOP
放在函数的开头来完成的。然后,当需要修补函数时,它们会用JMP$-5
替换该“NOP”,并在函数之前的5个字节中跳转到新函数
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
所以现在基本上你需要改变
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
mov eax, dword ptr ds:[esi+64]
add esp, C
cmp eax, 1
到
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc
使用此方法,您可以将原始指令替换为任何指令序列。但是,对于设置较小的值,Peter的解决方案更好no。在插入点之后,如果不修改代码的其余部分,就可以将所有内容移动2个字节。或者希望其他寄存器包含一个零,这样就不需要在其中嵌入32位的“零”。我需要寄存器中不是零的任何数字。为什么不
xor eax,eax
?这将使寄存器归零,只使用一两个字节。我想要相反的结果。寄存器中的非零数字。我只需要你的想法。只需添加任何其他寄存器。我不小心复制了超过0,在上面的例子中我是指10。否。在插入点之后,必须对代码的其余部分进行黑客攻击,将所有内容移动2个字节。或者希望其他寄存器包含一个零,这样就不需要在其中嵌入32位的“零”。我需要寄存器中不是零的任何数字。为什么不xor eax,eax
?这将使寄存器归零,只使用一两个字节。我想要相反的结果。寄存器中的非零数字。我只需要你的想法。只需添加任何其他寄存器。我无意中复制了超过0,在上面的示例中我是指10。您在注释中说,如果您希望ecx=eax,则比MOV短,但您在代码中使用了通用的xchg eax,r32。也许你的意思是xchg eax,ecx来匹配评论。@MichaelPetch:谢谢,我先写了ecx,然后把它改成了泛型。但我认为你是对的,在评论中讨论一个具体的例子会更好。(我忘记更新了,xD)前两个看起来很有希望,我明天醒来时必须试试。我可以只增加eax,因为我知道它将为零,但我也可以使用一个寄存器来保存地址(我知道它不会是负数),就像上面的esi一样。现在有人让我思考了很多方法。你在评论中说,如果你想要ecx=eax,那么比MOV短,但是你在代码中使用了通用的xchg-eax,r32。也许你的意思是xchg eax,ecx来匹配评论。@MichaelPetch:谢谢,我先写了ecx,然后把它改成了泛型。但我认为你是对的,在评论中讨论一个具体的例子会更好。(我忘记更新了,xD)前两个看起来很有希望,我明天醒来时必须试试。我可以只增加eax,因为我知道它将为零,但我也可以使用一个寄存器来保存地址(我知道它不会是负数),就像上面的esi一样。现在有很多方法可以做到,有人让我思考,“做一个近跳转,”--一个近32位的跳转不适合3个字节。也许你的意思是短跳转(2字节)。@ecm是的。我认为32位跳转是“远跳转”和“近跳转”——近32位跳转不适合3个字节。也许你的意思是短跳转(2字节)。@ecm是的。我以为32位跳远就是跳远
0041DE91 | B8 0A 00 00 00 | mov eax,10
0041DE96 | 0C 83 | or al,83
0041DE98 | F8 | clc