作者:重楼
时间: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的错误.