作者:重楼 
时间:2009-08-23 

目标:还是那个模拟器 
  今天我加了封包加密,如图下.看看代码有什么变化,并且调用加密 和发送CALL 


  



  


老套路,OD加载模拟器,返回6层 到发送封包 

  




  


我们对比上次找的  发现多了一个CALL  这个应该就是 封包加密()了 




  



我们直接到 那个CALL看看 



  

将上面那个CALL所得到的完整封包 从出栈到EAX 



  


将 封包指针地址 存放到 [ebp-4]  也就是说第二个堆栈地址(12F5B8) 

*这里[EBP-4]为什么会等于 堆栈地址 12F5B8 
因为这里在一开始 就给  EBP 赋值了 ESP 堆栈指针  所以说 给EBP赋值也就是给堆栈赋值. 



  
将 [EBP-4]的指针地址压入堆栈 
压入堆栈后 堆栈的变化如上 


  

加密CALL 后 返回 加密后的封包数据  并把封包数据的指针 放在EAX里 

我们查看下EAX的值 跟 封包助手 截包的封包内容 

在下面那个就是 客户.发送数据() 了 



====================汇编分析======= 

00404916    58              pop    eax 
00404917    8945 FC        mov    dword ptr [ebp-4], eax 
0040491A    8D45 FC        lea    eax, dword ptr [ebp-4] 
0040491D    50              push    eax 
0040491E    E8 5E000000    call    00404981                                                00404923    8945 F8        mov    dword ptr [ebp-8], eax 

====================粗略分析======= 

第一行弹出的是组合后的封包数据. "jx50" 
第二行把封包压入第二个堆栈地址 
第三行把地址放入EAX里 
第四行压入堆栈 
第五行CALL 
第六行把加密后的封包放入第二个堆栈里 

====================详细分析======== 
pop    eax 
在这里 我们直接把封包  写入内存 然后赋值给EAX 
所以 我们打开CE  找到一个空白内存 把类型改成文本  值为 jx50 
mov eax,地址 

mov    dword ptr [ebp-4], eax 

这里的EBP  等于ESP (为什么等于ESP 因为在子程序头部,程序把ESP值赋给了EBP) 所以我们必须 
也这样写上

mov ebp,esp 

*如果程序还需要原有的EBP值那么就要把EBP 压入堆栈,保存原有的EBP值 然后在还原 
*这里因为不需要 所以我们没写 如果想写也不会有问题 不过记得最后POP出来 

*这里有些朋友可能会好奇,为什么不给ESP赋值
*因为ESP永远指向堆栈栈顶,如果一改的话,堆栈就不会平衡,程序就会出错

mov    dword ptr [ebp-4], eax 

这里因为我们已经赋值了EBP的值 所以可以直接写  

mov [ebp-4],eax 


lea    eax, dword ptr [ebp-4] 

这里也一样  lea作用跟MOV差不多 不过MOV不能用 减号 

lea eax,[ebp-4] 



push    eax 

这里EAX的值已经有了 所以直接 

PUSH eax 

然后 

call    00404981 


最后 我们要把 EAX的值 保存到另外一个空白的地方 

CE找一个空白的地方 

mov ebx,地址 


mov [ebx],eax 


这样就取出来了 

最后做堆栈平衡 

我们压入了一个堆栈 
那么 

add esp,4 


===========================CALL的结果======= 


  

CE里 第一个是 封包的内容 
第二个是 加密后返回的 封包内容指针地址 
第三个是 指针地址里 封包的数据.用字节集查看 


在这里 我们发现 出来的 加密封包 跟我们之前的 封包不一样 看来是哪里弄错了.先不管他 


我们继续把  发送数据的 封包也写出来 



  
=========================汇编分析======== 

00404923    8945 F8        mov    dword ptr [ebp-8], eax 
00404926    68 04000080    push    80000004 
0040492B    6A 00          push    0 
0040492D    8B45 F8        mov    eax, dword ptr [ebp-8] 
00404930    85C0            test    eax, eax 
00404932    75 05          jnz    short 00404939 
00404934    B8 D8314000    mov    eax, 004031D8 
00404939    50              push    eax                                                      ; 要发送的数据 
0040493A    68 25000100    push    10025 
0040493F    68 08000116    push    16010008 
00404944    68 01000152    push    52010001 
00404949    68 02000000    push    2 
0040494E    BB E0060000    mov    ebx, 6E0 
00404953    E8 7C1E0000    call    004067D4                                                ; 客户1.发送数据() 
00404958    83C4 1C        add    esp, 1C 



====================================== 
第一行 把 加密后的封包指针地址 放入堆栈里 
第二行 push    80000004 
第三行  push    0 
第四行 mov    eax, dword ptr [ebp-8]  把堆栈的指针地址放到EAX里 (真会折腾~) 
然后对比跳转 


push    eax      // 要发送的数据 
push    10025 
push    16010008 
push    52010001 
push    2上面的就不分析了全是压入堆栈 


mov ebx,6e0 
call 4067d4 

然后就是 堆栈平衡 

add esp,1c 

这里为什么要把ESP加上1C
压入一个堆栈需要4个字节 
而上面压入了7个 所以是7*4=28=1c 
所以要加上1C 来平衡堆栈 

好了 我们来整理下 


  

OD里 下bp send 

然后CALL这段汇编 



  


好了 到这里 我们已经成功的调用了 加密封包 子程序 和 客户.发送数据() 
当然了 前面还是有点问题,加密出来的东西不是我们想要的.这里的错误就当成作业了

作业
跟踪并修改第一个CALL的错误.

posted on 2011-10-17 12:02  巅枫  阅读(4197)  评论(0编辑  收藏  举报