本帖最后由 小俊 于 2018-4-23 17:56 编辑
手工构造Windows程序
首先,我们要知道,Windows程序指的是什么,是(.exe)还是(.dll)。不管它是什么,他一定是操作系统规定的以某一种特定的格式的文件。也是就是所谓的PE文件
PE文件格式我在这里不会做非常详细的讲解,网上有其他很多教程
本章的目标就是手工打造弹出一个消息框的Windows程序
Hello.png 需要用到的工具:010editor
为了方便新手,这里我提供一个用汇编写的版本,方便大家做比较
下载地址:https://pan.baidu.com/s/1DAihSCt2i990dxI23phiCg
想知道如何编写的请看我另外的一篇帖子
https://www.52pojie.cn/thread-679902-1-1.html 好了,现在开始
010editor有个很方便的功能,能帮我们解析PE格式
把我们的汇编版本用010editor打开
ins.png
第一次exe文件打开会提示这个框,点击Install安装
这是一个帮我们解析PE格式的插件
2017-12-27_144623.png 我一个一个来解释这些是什么东西
吧第一个展开,我们向来看第一个
第一个是DOS头,需要注意的只有第一个字段,和最后一个字段,其他字段都不重要,可以随便改
2017-12-27_144847.png
2017-12-27_145507.png
第二个是DosStub,意思是在MS-DOS操作系统下,打开这个exe,会执行里面的代码,这个对我们来说一点也不只重要,现在谁还用DOS啊。待会我们构造的时候,这个部分直接不用写
2017-12-27_145911.png
接下来是最重要的NT头
NT头分为3个部分
2017-12-27_150212.png- PE标志
- 文件头
- 扩展头(也叫可选头,但是里面的字段不可以不写,所以我叫他扩展头,很重要)
PE标识里的内容始终为字符PE
2017-12-27_150523.png 接下来是文件头
2017-12-27_150759.png
2017-12-27_151429.png 扩展头
2017-12-27_151915.png 导入表为什么我要将导入表呢,因为我们的程序需要用到MessageBoxA这个函数,所以我们需要导入这个函数,这个函数是在user32.dll这个模块中的,所以我们需要导入。
除了用导入表找到函数API地址,我还有另外一种方法,就是动态获取,遍历kernel.dll的导出表找到loadlibrary函数地址,然后在用loadlibrary函数加载user32.dll,然后遍历user32.dll的导出表,找到MessageBoxA就可以了,有兴趣看我另一篇帖子:https://www.52pojie.cn/thread-674684-1-1.html说了这么多,导入表在哪呢? 导入表在数据目录表的第二项,也就是扩展头的最后一个数组的第二项,里面保存了导入表的RVA和大小
2017-12-27_154808.png 这里我们需要用RVA转文件偏移了
RVA是0x2100,我们先找0x2100在那个区段
先看.text段, .text段RVA为0x1000,大小没有超过0x1000,所以肯定不在 .text 区段
2017-12-27_155258.png 还有一个 .rdata 段,只读数据段,RVA为0x2000,大小为0x200,所以0x2100就在 .rdata 正中间,
2017-12-27_155650.png .rdata 区段首文件偏移为0x400
所以,导入表在文件偏移0x500的位置
2017-12-27_160014.png 到这里,Demo程序分析的差不多了,现在开始手工构造了新建一个十六进制文件
2017-12-27_161130.png 先构造DOS头
2017-12-27_161335.png 然后是文件头和PE标志
2017-12-27_161806.png 然后是扩展头
2017-12-27_162513.png 然后是区段描述表
一个代码段,一个数据段
2017-12-27_162945.png 然后填充空数据,试一下能不能跑起来
在代码段写一个C3,汇编就是ret,要不然会报错
2017-12-27_163318.png 双击没有反应,说明没错,因为我什么代码都没写
如果提示 此应用程序无法运行,或者这个程序不是windows程序,这样错误,说明你构造的有问题框架没问题,现在继续构造导入表 ,在rdata段构造,开始位置为0x400
2017-12-27_172225.png 然后调用MessageBoxA,在代码段中修改代码
修改为:0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0x6A, 0x00, 0xFF, 0x15, 0x60, 0x20, 0x40, 0x00, 0xC3 (图中有错误,CALL的是死地址,应该用FF15指令CALL IAT)
也就是汇编指令push 0 push 0 push 0 push 0 call MessageBoxA
2017-12-27_172407.png 运行
2017-12-27_172655.png 弹出了个没文字的信息框,因为我们给的参数都是0
想让他显示文字,只需要把字符串地址push进去就能显示文字了
分享一个非常非常好用的PE工具visualPE,由15pb的韦老师编写,这是我目前用过最好用的PE工具,每个字段都有详细的注释
下载地址:https://pan.baidu.com/s/1svfRnjHvgnS0F6nYfT-mMA
2017年12月29日 更新俩张图片,方便大家理解PE,图片来源:Malware Unicorn (独角兽) 团队
|