作者:Shminow
原文地址:
http://hi.baidu.com/wordsonwing/ ... 4d4488a977a4b3.html
逆向分析,是安全界永恒不变的主题, 就算未来世界是开源的. 也还是离不开逆向技术.
不管你是分析病毒,搞漏洞研究等等方面都离不开这. 逆向技术和脚本分析不一样. 脚本分析是开源方面的, 至少你学一门脚本语言就可以马上上手进行脚本漏洞发掘. 逆向技术需要的知识很广,想要从那一片片二进制数据中找从脆弱的地方, 确实需要很大的努力. 至少你要对PE文件格式有所了解. 熟悉PE对你以后脱未知壳是很有帮助的.
我不建议一开始就学汇编. 汇编对大多数人来说确实是个很头痛的东西. 里面的至少太抽象了,对于初学者是很难理解的, 会使你丧失继续学下去的兴趣. 所以汇编这个东西等到以后进入这个门到后再系统的学习.
还有就是各种常用的API函数, 不说每个都要记到,至少你看到这个API函数名字会一下就了解到这个函数的作用. 了解一下数据结构也是很有必要的.
有人经常问我逆向分析和编程需要对数学很了解吗~? 这个很不好回答. 毕竟现在和以前不一样, 原来编程都是些数学家干的事, 现在不一样了. 但是最好对一些基本的东西要了解下. 不敢相信连数学都不会的人写出来的程序是什么样子的, 尤其是算法. 还有些其他的东西,这里不列举了...
....... 看完上面,如果你下定决心了,继续看下去吧...
刚开始学程序分析,没必要一开始就搞复杂的,这容易把人的兴趣给驱散掉....所以我用C++写了个很简单的程序来分析. 如果还是看不懂也没事, 代码的旁边都有注释的...
对照源代码分析是很容易理解程序的流程的,,,,
代码如下:
#include<iostream>
#include<windows.h>
#include<winsock.h> //包含的头文件信息
#include<stdio.h>
#pragma comment(lib,"Ws2_32")
using namespace std; //标准名称空间.
int main() //main是程序的主函数
{
int put=520; //定义变量,并且初始化为520
printf("%d\n",put); //printf是C语言里面的打印函数,这里是把刚才定义的put打印出来
return 0; //return是返回值,这里返回0;
}
VC++6.0下把上面的代码编译. 程序的功能是把520打印出来
....生成的是debug版本, 便与调试... 用OD打开程序, OD停在入口处...
00408340 >/$ 55 push ebp
00408341 |. 8BEC mov ebp, esp
00408343 |. 6A FF push -1
00408345 |. 68 C0134300 push 004313C0
0040834A |. 68 60F44000 push _except_handler3 ; SE 处理程序安装
0040834F |. 64:A1 0000000>mov eax, dword ptr fs:[0]
00408355 |. 50 push eax
00408356 |. 64:8925 00000>mov dword ptr fs:[0], esp //下面还有好多代码省略...
...................
开始是装载器加载些PE文件之类的信息,想了解系统底层的可以往下看,这里就不分析了.
还是继续我们的主题...
在离开始不远处发现如下:
004083D4 |> \C745 FC 00000>mov dword ptr [ebp-4], 0
004083DB |. E8 00690000 call _ioinit
004083E0 |. FF15 60B14300 call dword ptr [<&KERNEL32.GetCommand>; [GetCommandLineA
....接着下面几个连续的push. 可以推断出mian函数离这不远,果然在下面发现了:
00408416 |. 52 push edx
00408417 |. A1 40894300 mov eax, dword ptr [__argv]
0040841C |. 50 push eax
0040841D |. 8B0D 3C894300 mov ecx, dword ptr [__argc]
00408423 |. 51 push ecx
00408424 |. E8 E68BFFFF call 0040100F ;这里就是main函数, F7进去
来到下面代码:
00401030 >/> \55 push ebp ;保存EBP
00401031 |. 8BEC mov ebp, esp ;设置程序的基址寄存器
00401033 |. 83EC 44 sub esp, 44 ;开辟栈的空间
00401036 |. 53 push ebx ;压栈保存
00401037 |. 56 push esi
00401038 |. 57 push edi
00401039 |. 8D7D BC lea edi, dword ptr [ebp-44]
0040103C |. B9 11000000 mov ecx, 11 ;设置ECX的值
00401041 |. B8 CCCCCCCC mov eax, CCCCCCCC
00401046 |. F3:AB rep stos dword ptr es:[edi] ;进行目标串的拷贝, 重复11次
00401048 |. C745 FC 08020>mov dword ptr [ebp-4], 208 ; 把16进制208压入栈里, 208就
;是10进制的520,就是我们刚才处始化int变量的值
0040104F |. 8B45 FC mov eax, dword ptr [ebp-4]
00401052 |. 50 push eax ; /<%d> ;这里push printf函数需要的参数
00401053 |. 68 1C104300 push 0043101C ; |format = "%d",LF,""
00401058 |. E8 03710000 call printf ; \printf ;调用printf函数;
在printf那个CALL上F8后,可以看到程序打印出来520 , 如图:
[img]http://hiphotos.baidu.com/wordsonwing/pic/item/b32f76ef1e7c9c24adafd56f.jpg[img]
.
接续往下看都是些pop把刚才保存的值弹出去, 保持栈的平衡嘛~! 最后调用exit函数程序退出.....
本文只是简单的分析,. 逆向分析往往是黑箱分析, 手里没源代码,盯着那一个个跳动的数据而失眠,正是那成功的一刻激励着我们不断的前进~!
By:Shminow