小俊 发表于 2017-12-27 17:34

【原创】如何手工构造一个windows程序

本帖最后由 小俊 于 2018-4-23 17:56 编辑

手工构造Windows程序
首先,我们要知道,Windows程序指的是什么,是(.exe)还是(.dll)。不管它是什么,他一定是操作系统规定的以某一种特定的格式的文件。也是就是所谓的PE文件
PE文件格式我在这里不会做非常详细的讲解,网上有其他很多教程
本章的目标就是手工打造弹出一个消息框的Windows程序
http://upload-images.jianshu.io/upload_images/6462920-efe1ecf079e7c79a.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

Hello.png需要用到的工具:010editor
为了方便新手,这里我提供一个用汇编写的版本,方便大家做比较
下载地址:https://pan.baidu.com/s/1DAihSCt2i990dxI23phiCg
想知道如何编写的请看我另外的一篇帖子
https://www.52pojie.cn/thread-679902-1-1.html好了,现在开始
010editor有个很方便的功能,能帮我们解析PE格式
把我们的汇编版本用010editor打开

http://upload-images.jianshu.io/upload_images/6462920-f8dc325b1bc39b87.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

ins.png
第一次exe文件打开会提示这个框,点击Install安装
这是一个帮我们解析PE格式的插件

http://upload-images.jianshu.io/upload_images/6462920-36a5f81991575ef7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_144623.png我一个一个来解释这些是什么东西
吧第一个展开,我们向来看第一个
第一个是DOS头,需要注意的只有第一个字段,和最后一个字段,其他字段都不重要,可以随便改

http://upload-images.jianshu.io/upload_images/6462920-593d15144415b9bc.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_144847.png

http://upload-images.jianshu.io/upload_images/6462920-918f8c3b10709394.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_145507.png
第二个是DosStub,意思是在MS-DOS操作系统下,打开这个exe,会执行里面的代码,这个对我们来说一点也不只重要,现在谁还用DOS啊。待会我们构造的时候,这个部分直接不用写

http://upload-images.jianshu.io/upload_images/6462920-5365680a7dd2fc30.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_145911.png
接下来是最重要的NT头
NT头分为3个部分

http://upload-images.jianshu.io/upload_images/6462920-1801c5695bfcd54c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_150212.png
[*]PE标志
[*]文件头
[*]扩展头(也叫可选头,但是里面的字段不可以不写,所以我叫他扩展头,很重要)
PE标识里的内容始终为字符PE
http://upload-images.jianshu.io/upload_images/6462920-e93a156c90e0dd41.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_150523.png接下来是文件头
http://upload-images.jianshu.io/upload_images/6462920-ddb49b01d92df3b6.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_150759.png

http://upload-images.jianshu.io/upload_images/6462920-e824e9185dceed63.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_151429.png扩展头
http://upload-images.jianshu.io/upload_images/6462920-658cd01b612a85d5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

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和大小

http://upload-images.jianshu.io/upload_images/6462920-04a543334e9bd1d1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_154808.png这里我们需要用RVA转文件偏移了
RVA是0x2100,我们先找0x2100在那个区段
先看.text段, .text段RVA为0x1000,大小没有超过0x1000,所以肯定不在 .text 区段
http://upload-images.jianshu.io/upload_images/6462920-b4c51b512a475ff4.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_155258.png还有一个 .rdata 段,只读数据段,RVA为0x2000,大小为0x200,所以0x2100就在 .rdata 正中间,
http://upload-images.jianshu.io/upload_images/6462920-7e8f6b468011460b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_155650.png.rdata 区段首文件偏移为0x400
所以,导入表在文件偏移0x500的位置
http://upload-images.jianshu.io/upload_images/6462920-8e6350540e0a69f1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_160014.png到这里,Demo程序分析的差不多了,现在开始手工构造了新建一个十六进制文件
http://upload-images.jianshu.io/upload_images/6462920-e9ad80f759dc93f1.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_161130.png先构造DOS头
http://upload-images.jianshu.io/upload_images/6462920-c3bb5b74b0c9787f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_161335.png然后是文件头和PE标志
http://upload-images.jianshu.io/upload_images/6462920-6d372f9aa415c542.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_161806.png然后是扩展头
http://upload-images.jianshu.io/upload_images/6462920-5a18cc72efe5a32e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_162513.png然后是区段描述表
一个代码段,一个数据段
http://upload-images.jianshu.io/upload_images/6462920-0eaa9b1db54ca304.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_162945.png然后填充空数据,试一下能不能跑起来
在代码段写一个C3,汇编就是ret,要不然会报错
http://upload-images.jianshu.io/upload_images/6462920-98f24cf07b9714e5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_163318.png双击没有反应,说明没错,因为我什么代码都没写
如果提示 此应用程序无法运行,或者这个程序不是windows程序,这样错误,说明你构造的有问题框架没问题,现在继续构造导入表 ,在rdata段构造,开始位置为0x400
http://upload-images.jianshu.io/upload_images/6462920-cedc9f3aa690a89f.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

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
http://upload-images.jianshu.io/upload_images/6462920-052a3667ad12fb45.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_172407.png运行
http://upload-images.jianshu.io/upload_images/6462920-da541f12e6c9fe2d.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

2017-12-27_172655.png弹出了个没文字的信息框,因为我们给的参数都是0
想让他显示文字,只需要把字符串地址push进去就能显示文字了

分享一个非常非常好用的PE工具visualPE,由15pb的韦老师编写,这是我目前用过最好用的PE工具,每个字段都有详细的注释
下载地址:https://pan.baidu.com/s/1svfRnjHvgnS0F6nYfT-mMA
http://upload-images.jianshu.io/upload_images/6462920-70de94e80eecea92.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240


2017年12月29日 更新俩张图片,方便大家理解PE,图片来源:Malware Unicorn (独角兽) 团队
http://upload-images.jianshu.io/upload_images/6462920-3945872059de0d03.gif?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240
http://upload-images.jianshu.io/upload_images/6462920-149211f68d31f5b5.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240

xuanqing 发表于 2018-1-4 07:28

自己动手编写个pe是了解这种格式最方便的方法了

明月相照 发表于 2017-12-27 21:59

本帖最后由 明月相照 于 2017-12-27 22:04 编辑

其实LZ这个贴说明白了些,WINDOWS或DOS程序和汇编之间的对应关系;各种高低级语言、汇编之间的转换和编译。明白了相应的原理后,就用这个方法直写出程序。算是一种对程序语言的逆向,因为用过编程语言后再来看这个方式,真的来编程好吃力呀。:wwqwq;www。
通过这个了解PE文件的结构,对于逆向、脱壳等学习还是很有帮助的。

Poner 发表于 2017-12-27 17:45

好像在哪看过类似的文章

都同学 发表于 2017-12-27 17:50

学习一波,楼主辛苦了

小俊 发表于 2017-12-27 17:52

Poner 发表于 2017-12-27 17:45
好像在哪看过类似的文章

完完全全原创,没有产考过任何文章,这是我对PE的理解,自己构造的,产考过任何文章全家暴毙

我是你老大 发表于 2017-12-27 17:54

学习了!

Poner 发表于 2017-12-27 17:59

小俊 发表于 2017-12-27 17:52
完完全全原创,没有产考过任何文章,这是我对PE的理解,自己构造的,产考过任何文章全家暴毙

我可没说你抄了别人的东西当原创,不用对家里人说这么重的话吧!!
我的意思是之前看过类似的文章也是手工打造一个PE 方法应该不一样

小俊 发表于 2017-12-27 18:02

Poner 发表于 2017-12-27 17:59
我可没说你抄了别人的东西当原创,不用对家里人说这么重的话吧!!
我的意思是之前看过类似的文章也是手 ...

给我帖子上个色把,发了好多技术贴,根本没人看,现在随便发一个外挂帖,几万浏览量轻轻松松

Poner 发表于 2017-12-27 18:05

小俊 发表于 2017-12-27 18:02
给我帖子上个色把,发了好多技术贴,根本没人看,现在随便发一个外挂帖,几万浏览量轻轻松松

你发错版块了额以后这样的技术文章你应该发在脱壳破解区

Poner 发表于 2017-12-27 18:12

写的还算是可以   给你个精华   希望以后能写出更好的文章!

小俊 发表于 2017-12-27 18:24

Poner 发表于 2017-12-27 18:12
写的还算是可以   给你个精华   希望以后能写出更好的文章!

感谢大佬给我信心,我会持续跟新技术贴的
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: 【原创】如何手工构造一个windows程序