在无法使用ESP定律时—EBP的妙用                
                
                    所属分类:
                        网络安全 / 加密解密                    
                    阅读数:
                        139
                    
                        收藏 0赞 0分享
                    
                 
                
                    在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX用于记数等等。在win32的环境下EBP寄存器用与存放在进入call以后的ESP的值,便于退出的时候回复ESP的值,达到堆栈平衡的目的。 
应用以前说过的一段话: 
原程序的OEP,通常是一开始以 Push EBP 和MOV Ebp,Esp这两句开始的,不用我多说大家也知道这两句的意思是以EBP代替ESP,作为访问堆栈的指针。 
为什么要这样呢?为什么几乎每个程序都是的开头能?因为如果我们写过C等函数的时候就应该清楚,程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在win32的环境下保持平衡的办法是这样的: 
1.让EBP保存ESP的值; 
2.在结束的时候调用 
mov esp,ebp  
pop ebp  
retn 
  
或者是 
leave 
retn 
  
两个形式是一个意思。  
这样做的好处是不用考虑ESP等于多少,PUSH了多少次,要POP多少次了,因为我们知道EBP里面放的是开始时候的ESP值。 
2.推广的ESP定律 
在寻找OEP的时候,往往下断HW ESP-4不成功,除了壳代码将硬件断点删除了以外,很可能的情况就是因为壳代码在运行到OEP的时候他的ESP已经不再是在EP时候的ESP(12FFC4)了,这样我们下断当然是不成功的。 
那么如何找到在壳到达OEP的时候的堆栈的值将是关键。 
在这里我们应用的关键是 
Push EBP 
MOV Ebp,Esp----》关键是这句 
  
我来解释一下,当程序到达OEP的时候Push EBP这句对于ESP的值来说就是ESP-4,然后是ESP-4赋给了EBP,而做为保存ESP值作用的EBP寄存器在这个“最上层的程序”中的值将始终不会改变。虽然他可能在进入子call里面以后会暂时的改变(用于子程序的堆栈平衡)但是在退出了以后依*pop ebp这一句将还原原来的EBP的值。 
以这句做为突破口,就是说只要我们能断在“最上层的程序”中,就能通过观察EBP的值得到壳在JMP到OEP的时候的ESP的值了。 
3.实战 
来看看pespin1.1的壳,在pespin1.0的壳中,我们使用HW 12FFC0能很容易的找到stolen code的地方,但是到pespin1.1的时候,我们就不行了。用HW 12FFC0根本断不下来。 
现在我们就使用这个推广的ESP定律,载入程序后来到最后的一个异常 
0040ED85     2BDB             sub ebx,ebx                           //停在这里 
0040ED87     64:8F03          pop dword ptr fs:[ebx] 
0040ED8A     58               pop eax 
0040ED8B     5D               pop ebp 
0040ED8C     2BFF             sub edi,edi 
0040ED8E     EB 01            jmp short pespin1_.0040ED91 
0040ED90     C466 81          les esp,fword ptr ds:[esi-7F]  
我用使用内存断点办法来到FOEP处 
004010D3     0000             add byte ptr ds:[eax],al 
004010D5     0000             add byte ptr ds:[eax],al 
004010D7     0000             add byte ptr ds:[eax],al 
004010D9     0000             add byte ptr ds:[eax],al 
004010DB     0000             add byte ptr ds:[eax],al 
004010DD     0000             add byte ptr ds:[eax],al 
004010DF     75 1B            jnz short pespin1_.004010FC               //这里是FOEP 
004010E1     56               push esi  
004010E2     FF15 99F44000    call dword ptr ds:[40F499] 
004010E8     8BF0             mov esi,eax 
004010EA     8A00             mov al,byte ptr ds:[eax] 
好了,这里就是“最上层的程序”的地方了,看看寄存器  
EAX 00141E22 
ECX 0040C708 pespin1_.0040C708 
EDX 0040C708 pespin1_.0040C708 
EBX 0040C708 pespin1_.0040C708                     
ESP 0012F978 
EBP 0012F9C0                                  //注意这里 
ESI 00141EE0 
EDI 0040E5CD pespin1_.0040E5CD 
EIP 004010DF pespin1_.004010DF 
  
看到了吧,EBP=0012F9C0,我们来想象一下这个值是怎么得到的。 
首先肯定是通过MOV ESP,EBP这一句,也就是说ESP这时是0012F9C0的,然而上面还有一句PUSH EBP也就是说ESP在到达OEP的时候应该是0012F9C4的。好了得到这个结论我们就能很快的找到stolen code的所在了。 
重来停在最后的异常 
0040ED85     2BDB             sub ebx,ebx                           //停在这里 
0040ED87     64:8F03          pop dword ptr fs:[ebx] 
0040ED8A     58               pop eax 
0040ED8B     5D               pop ebp 
0040ED8C     2BFF             sub edi,edi 
0040ED8E     EB 01            jmp short pespin1_.0040ED91 
0040ED90     C466 81          les esp,fword ptr ds:[esi-7F] 
  
然后下断HW 0012F9C0 ,F9运行,来到这里 
0040D8FB     61               popad 
0040D8FC     55               push ebp 
0040D8FD     EB 01            jmp short pespin1_.0040D900           //停在这里 
0040D8FF     318B ECEB01AC    xor dword ptr ds:[ebx AC01EBEC],ecx 
0040D905     83EC 44          sub esp,44 
0040D908     EB 01            jmp short pespin1_.0040D90B 
0040D90A     72 56            jb short pespin1_.0040D962 
0040D90C     EB 01            jmp short pespin1_.0040D90F 
0040D90E     95               xchg eax,ebp 
0040D90F     FF15 6CF34000    call dword ptr ds:[40F36C] 
0040D915     EB 01            jmp short pespin1_.0040D918 
  
于是就很快的找到了stolen code的所在了。 
4.总结 
上面的这个办法大概可以总结以下的步骤: 
(1).直接或间接的断在“最上层的程序”的地方。 
(2).得到“最上层的程序”的EBP的值。 
(3).利用程序初始化的两个固定语句找到壳JMP到OEP的堆栈值。这个办法有很大的局限性,因为只有VC和delphi程序使用这个初始化的开头。 
但是找到“最上层的程序”的办法除了内存断点还有很多办法,例如对于VC来说使用 bp ExitProcess也是一个很好的断点,可以直接得到EBP的数值。 
5.后话 
原来这个办法有很强的前提条件,不是一个很具普遍性的办法,我原来也不想单独的提出来,但是对于jney2兄弟的anti-ESP定律来说这个办法却是一个解决之道。 
当然还有更多的办法,在这里我只想说很多事情有矛就有盾,没有什么办法是一定没有漏洞的,只是希望这篇文章给大家阔宽思路,起到抛砖引玉的作用。 
                                    
             
            
                
                Getright 5 手动脱壳和重建IAT--第二部分(图)
在本参考教程的第一部分我们学习了如何正确地转储(dump)Getright 5. 现在我们将要去找神奇跳转,这样IAT会被正确地转储下来,而不用手工修复了. 要完成这一点,我们需要打败程序中的一些陷阱, 并使它们即使在检测到被执行脱壳时也无所作为. 
让我们开始吧! 
第
                    
                    收藏 0赞 0分享
Getright 5 手动脱壳和重建IAT--第一部分(图)
这是一篇Armadillo加壳软件Getright 5.01的脱壳译文,我是参照Ricardo Narvaja的“Getright 5 脱壳和重建IAT”的文章以及Bighead[DFCG][YCG]的译文,一边实践一边再次翻译的。感谢Ricardo Narvaja和Bighea
                    
                    收藏 0赞 0分享
黑客破解Email账号最常用的三种方法
电子邮件并不是安全的,在邮件的发送、传送和接收整个过程中的每个环节都可能存在薄弱环节,恶意用户如果利用其漏洞,就能够轻易的破解出账号,获得邮件内容。
一、利用邮件服务器操作系统的漏洞
邮件服务器软件是运行在特定的操作系统上的,如Linux、Windows NT/20
                    
                    收藏 0赞 0分享
黑客技术之slv unpackme 脱壳
其实壳本身不要紧,问题是vm里面有个校验。
sm同学手下留情,我勉强能搞一个运行正常的,没精力还原vm了。
在virutalfree的retn上f4, 直到[esp]是一个exe image内的地址f7返回:
0040FA91    B8 BE180000     m
                    
                    收藏 0赞 0分享
Allok Video to 3GP Converter 脱壳+破解(图)
①。
下载好安装后,用DIT查看为MoleBox 2.5.x.
-----------------------------------------------------------------------------
OD,载如RUN,程序完全运行后,ALT+M查看内存映
                    
                    收藏 0赞 0分享
有密码 优酷视频 破解方法
优酷网站的视频可以设置独立的播放密码,不过你可知道:观看有密码的优酷视频其实不需要密码哦。下面讲述两种方法进行优酷视频密码破解的方法。 
优酷视频密码破解一: 
打开FLV解析网站,这里推荐使用该站点:http://www.flvcd.com,从浏览器地址栏复制需要解密的优酷
                    
                    收藏 0赞 0分享
                 查看更多