6.1.2 方法一、野蛮的暴力搜索
“在国内,首先想出方法的是guange。”老师说道。
“哦!又是他啊!”大家想起在编码时讲过他的方法。
“他在很早以前,就对Windows的系统技术炉火纯青。不仅编码,动态定位,而且在ShellCode高级功能、高级提取方面都有很深的造诣,但……鲜有详细的文档记录。现在他也把很多东西都忘了吧!我们只能通过他的程序临摹一招半式了。”
“哦!”
“所以,我给你们上的课,都是在做扫地的工作,也就是‘扫地僧’!”
“哇!做‘扫地僧’好啊,是金庸大侠手下武功最高的人物了!”小倩一副很羡慕的样子。
“汗~是啊!为了让像大家一样的初学者引起兴趣,尽快入门!我会担当起‘扫地僧’责任的。”老师说道。
“多谢老师!我们也会努力学习的,不会辜负老师的期望。”教室里大家都纷纷表态。
“别谢我什么,要谢就谢《Q版黑客》系列图书吧!谢谢他们全力的支持,才使这门课得以顺利开展。
”好了,我们来看看yuange提出的方法。”老师又回到了正题。
“yuange提出的思路就是:SHELLCODE只依靠GetProcAddress和LoadLibraryA这两个函数;而LoadLibraryA是在系统库KERNEL32.DLL里面的,也可以使用GetProcAddress得到,所以我们只需知道GetProcAddress的地址就可以了。
“哦!是啊!但GetProcAddress的地址又怎么获得呢?这是关键啊!”大家着急的说。
“呵呵,yuange说了(怎么像黑社会的……),kernel32.dll一般都会被加载,所以解决办法就是在内存里查找kernel32.dll这个系统库和GetprocAddress函数的地址。”
“查找?”
“俗称就是暴力搜索!”
“啊!暴力搜索!好恐怖啊!”大家紧张的的说。
“其实,只要了解了Windows的系统结构就不难。袁哥的程序,是从0x77e0000 或0xbff00000 开始搜索,搜索到MZ和PE标志时,就表示是kernel32.dll的开始地方。”
小知识:PE结构
PE的意思就是 Portable Executable(可移植的执行体)。它是 Win32环境自身所带的执行体文件格式。所有 Win32执行体都使用PE文件格式,包括NT的内核模式驱动程序。
PE文件结构以一个IMAGE_DOS_HEADER结构开始,所以开头是一个简单的 DOS MZ header,紧随 MZ header之后的是DOS stub。紧接着DOS stub的是PE header,所以可以根据MZ和PE标志来判断一个程序是否是可执行程序,其详细结构如下:
typedef struct _IMAGE_DOS_HEADER {??
WORD e_magic; ;DOS可执行文件标记“MZ”
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
LONG e_lfanew; ;指向PE文件头"PE",0,0
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
“找到kernel32后,再搜索函数的引出表,找到LoadLibrary的函数名和LoadLibrary函数对应的地址就完成了搜索。”
“我把yange的程序加上了一些注释,大家下来可参考SearchByYuange.cpp(光盘有收录),这里就不作详细解释了。”老师说道。
“啊?为什么不解释呢?还不大懂呢!”
“呵呵,第一是因为代码复杂难懂,我这个‘扫地僧’要解释清楚也很困难;第二是从0x77e00000或0xbff00000开始搜索,已经不完全通用了;第三是技术不断进步,后来有了更为优雅、更为完美的方法。而且后面讲的方法和yuange的方法大部分是一样的,我们学习之后,也就都清楚了。”