且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

nop掉call指令后,如何保持堆栈平衡

更新时间:2022-10-04 15:18:05

如果要nop掉的是一个call指令,如何保持堆栈平衡呢?
只要按ENTER“跟随”进入被call的函数,看一下函数的返回指令,如果是retn,就直接用Nop替换;如果是retn XXX,就把call替换成为add esp, XXX;
就这样。具体请查阅指令手册关于retn指令的说明。 我可能要气疯大家了,我也没脾气了,大家要生气的自便~!很菜的问题!nop掉call指令后,如何保持堆栈平衡 达文西,对不住您!

我用OD1加载一个OD2,F9运行起OD2,然后查看句柄,输入bp SetWindowTextA [esp+4]==003C0152下断,断在下面的位置:

代码:

004779DB  |.  E8 4CF20200   call 复件_吾?004A6C2C
004779E0  |.  83C4 10       add esp,10004779E3  |.  8D85 E0FEFFFF lea eax,[local.72]004779E9  |.  50            push eax                                 ; /Text004779EA  |.  8B15 7C3B4D00 mov edx,dword ptr ds:[4D3B7C]            ; |
004779F0  |.  52            push edx                                 ; |hWnd => 003C0152 ('吾爱破解 - [LCG]',class='1212121')004779F1  |.  E8 C87B0300   call <jmp.&USER32.SetWindowTextA>        ; \SetWindowTextA004779F6  |.  C705 88574D00>mov dword ptr ds:[4D5788],1
00477A00  |.  33C9          xor ecx,ecx

这里可以直接修改004779E9  push eax;eax指向“吾爱破解”地址003C0152
比如修改成004779E9  push 003C0152
(没错误吧!?)

还有直接修改 关键句:call <jmp.&USER32.SetWindowTextA> ,把这个call给NOP掉;
我看了一下004779E3  lea eax,[local.72]这句,汇编中显示的是lea eax,dword ptr ss:[ebp- 120],则004779E9  push eax就应该是push    dword ptr ss:[ebp-120]吧(应该没错误吧!?)按照堆 栈平衡方法,是不是要修改call <jmp.&USER32.SetWindowTextA> 为sun esp,120?或者是 别的,我觉得不对劲,因为有:
push eax
push edx
就要有
pop edx
pop eax
这样才保持堆栈平衡!(我在发表愚见了)

另外,理解


引用:

  只要按Enter“跟随”进入被call的函数,看一下函数的返回指令

这句,我是觉得他说的call是过程函数,而不是api函数的调用call。我先在call <jmp.&USER32.SetWindowTextA>按Enter“跟随”,进入下面一段代码:

代码:

004AF5BE   $- FF25 6CD95000 jmp dword ptr ds:[<&USER32.SetWindowText>;  user32.SetWindowTextA004AF5C4   $- FF25 70D95000 jmp dword ptr ds:[<&USER32.ShowCaret>]   ;  user32.ShowCaret
004AF5CA   $- FF25 74D95000 jmp dword ptr ds:[<&USER32.ShowScrollBar>;  user32.ShowScrollBar
004AF5D0   $- FF25 78D95000 jmp dword ptr ds:[<&USER32.ShowWindow>]  ;  user32.ShowWindow

然后在jmp dword ptr ds:[<&USER32.SetWindowText>处按Enter“跟随”,到下面一段代码:

代码:

77D17EEB >  8B4C24 04       mov ecx,dword ptr ss:[esp+4]
77D17EEF    56              push esi
77D17EF0    E8 2FBBFFFF     call user32.77D13A24
77D17EF5    8BF0            mov esi,eax
77D17EF7    85F6            test esi,esi
77D17EF9    74 23           je short user32.77D17F1E
77D17EFB    56              push esi
77D17EFC    E8 E8D9FFFF     call user32.77D158E9
77D17F01    85C0            test eax,eax
77D17F03    6A 01           push 1
77D17F05    FF7424 10       push dword ptr ss:[esp+10]
77D17F09    6A 00           push 0
77D17F0B    6A 0C           push 0C
77D17F0D    56              push esi
77D17F0E    74 12           je short user32.77D17F22
77D17F10    E8 86D4FFFF     call user32.77D1539B
77D17F15    33C9            xor ecx,ecx
77D17F17    85C0            test eax,eax
77D17F19    0F9DC1          setge cl
77D17F1C    8BC1            mov eax,ecx
77D17F1E    5E              pop esi77D17F1F    C2 0800         retn 8

可以看到最后的是retn 8,所以我直接修改call <jmp.&USER32.SetWindowTextA>为add esp,8。

我上面的思路很乱来,中心问题就是一个,怎么进入被call的函数USER32.SetWindowTextA,并找到函数USER32.SetWindowTextA的返回指令。                        



另外,要看一下被call函数的汇编代码,如果代码中有对esp操作的语句,比如add esp, 4,最后是retn 2,那么用NOP替换这个call时,要用add esp 6










本文转自 h2appy  51CTO博客,原文链接:http://blog.51cto.com/h2appy/1564887,如需转载请自行联系原作者