在PE文件的头部有一个DOS Stub,而这一段代码已经在32位系统之后废弃了,只有在16位的DOS环境下才会执行,在16位的DOS环境下,执行一个32位的程序将会出现This Program cannot be run in DOS mod的提示,为了更好的学习PE文件,这里还是在了解一下DOS Stub的执行功能比较好,本文将会在Win x86的环境下对一个Win32 Hello Word程序的DOS Stub段的代码进行修改,为其增加一段在显示This Program cannot be run in DOS mod后电脑发成嘟一声的功能。
准备工具
1、首先编写一个Win 32的Hello World程序(其他的Win32程序也可以)
2、C32Asm或者WinHex这种16进制编辑器
3、一个X86的系统,x64下没有debug工具
Hello World代码
.386 .model flat,stdcall option casemap:none include windows.inc include user32.inc includelib user32.lib include kernel32.inc includelib kernel32.lib ;数据段 .data szText db 'HelloWorld',0 ;代码段 .code start: invoke MessageBox,NULL,offset szText,NULL,MB_OK invoke ExitProcess,NULL end start
将上述代码编译成一个h.exe。
开始调试
打开cmd命令窗口,如图1所示,使用Debug命令对此exe进行调试,debug h.exe
加载成功后,在debug下输入命令d,如图2所示,将会看到当前的内存中PE文件的一段16进制信息。
用C32Asm打开上述的h.exe可以看到,如图3所示的16进制信息,对比图2中的16进制信息可以看到,debug加载到内存中的数据是从文件的0x40处加载的。
在Debug中使用反汇编命令,u,例如这里的程序加载到了0B41:0000的位置,就使用命令u 0B41:000 D,反汇编起始的0xD字节,如图4所示。
查看图4中的汇编代码可以看出,这段程序就是显示了一个字串,然后退出了(int 21中断的09号功能是在屏幕上显示一段字串,mov ax,4c01 int 21是程序退出)。
这里如果我们要加入一段让电脑发出响声的代码应当在程序退出之前执行,所以这段代码应该放到MOV AX,4C10之前,使用debug下的a功能,我们写入一段让电脑发声的代码(其目的是为了查看这段代码对应的16进制信息)。
让电脑发声:在DOS模式下可以使用21中断的2号功能,就是向标准的输出设备显示一个字符,而ASCII码中的0x7即是响铃符号,如图5所示,是一段发声的汇编代码。
使用U命令查看上面的汇编对应的16进制代码,如图6所示,从图中可以看出这一段代码占用了6个字节,其16进制的代码为:B2 07 B4 02 CD 21。
写到这里,思路已经很清晰了,也就是将图6中对应的6个16进制数据写入到原有的DOS代码中,但是又不能改变PE头的位置。打开C32Asm加载he.exe,查看图4可以知道,我们应当将上面的6个16进制插入到B409 CD21的后面,如图7所示,使用C32Asm的编辑菜单在B409 CD21后面插入6个字节。
将图7中的6个填充位置修改为图6中所得到的反汇编对应的16进制代码,如图8所示。
由于填充了6个16进制,这会导致DOSStub的大小变大,且PE头的位置将会向后移动6个字节,所以,此处为了保证PE头的位置不发生改变,这里在DOSStub的最后删除了6个字节,也就是在PE标记前删除6个字节,如图9所示。
又因为在DOSStub中添加了6个字节,这将会导致字串This program cannot be run in DOS mode的位置往后移动了6个字节,所以在显示字串的中段调用中,需要将字串的地址增加6,如图10所示0x000E是原始的字串位置。
使用C32Asm找到BA 0E 00 将0E加上6,如图11所示。
保存修改内容,使用Debug模式运行程序(debug C:\h.exe),然后按下g,可以看到在显示字串后会嘟的一声,如图12所示。
附上上述操作中使用的exe和asm文件,以及C32Asm工具。
百度网盘链接:http://pan.baidu.com/s/1kVH9eRX 密码:axub
转载请注明:悠然品鉴 » PE修改DOS Sub增加电脑喇叭嘟一声的功能