总有人间一两风,填我十万八千梦

PE修改DOS Sub增加电脑喇叭嘟一声的功能

Windows C/C++ Zero、J 2962℃ 0评论

在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

debugh.exe

图1debug h.exe

 

加载成功后,在debug下输入命令d,如图2所示,将会看到当前的内存中PE文件的一段16进制信息。

d_hex

图2 d命令查看16进制代码

用C32Asm打开上述的h.exe可以看到,如图3所示的16进制信息,对比图2中的16进制信息可以看到,debug加载到内存中的数据是从文件的0x40处加载的。

c32asm_hex_code

图3 原始exe文件的16进制信息

在Debug中使用反汇编命令,u,例如这里的程序加载到了0B41:0000的位置,就使用命令u 0B41:000 D,反汇编起始的0xD字节,如图4所示。

图4 反汇编起始的D字节

图4 反汇编起始的D字节

查看图4中的汇编代码可以看出,这段程序就是显示了一个字串,然后退出了(int 21中断的09号功能是在屏幕上显示一段字串,mov ax,4c01 int 21是程序退出)。

这里如果我们要加入一段让电脑发出响声的代码应当在程序退出之前执行,所以这段代码应该放到MOV AX,4C10之前,使用debug下的a功能,我们写入一段让电脑发声的代码(其目的是为了查看这段代码对应的16进制信息)。

让电脑发声:在DOS模式下可以使用21中断的2号功能,就是向标准的输出设备显示一个字符,而ASCII码中的0x7即是响铃符号,如图5所示,是一段发声的汇编代码。

int 21中断2号功能,输出响铃字符

图5 int 21中断2号功能,输出响铃字符

使用U命令查看上面的汇编对应的16进制代码,如图6所示,从图中可以看出这一段代码占用了6个字节,其16进制的代码为:B2 07 B4 02 CD 21。

u_see_hexcode

图6 反汇编写入的代码查看对应的16进制数据

写到这里,思路已经很清晰了,也就是将图6中对应的6个16进制数据写入到原有的DOS代码中,但是又不能改变PE头的位置。打开C32Asm加载he.exe,查看图4可以知道,我们应当将上面的6个16进制插入到B409 CD21的后面,如图7所示,使用C32Asm的编辑菜单在B409 CD21后面插入6个字节。

图7 插入6个填充位置

图7 插入6个填充位置

将图7中的6个填充位置修改为图6中所得到的反汇编对应的16进制代码,如图8所示。

write_hex_6_code

图8 修改填充的6个16进制数据

由于填充了6个16进制,这会导致DOSStub的大小变大,且PE头的位置将会向后移动6个字节,所以,此处为了保证PE头的位置不发生改变,这里在DOSStub的最后删除了6个字节,也就是在PE标记前删除6个字节,如图9所示。

delete_6_hex_code

图9 删除6个冗余的字节

又因为在DOSStub中添加了6个字节,这将会导致字串This program cannot be run in DOS mode的位置往后移动了6个字节,所以在显示字串的中段调用中,需要将字串的地址增加6,如图10所示0x000E是原始的字串位置。

图10 将字串偏移位置加6

图10 将字串偏移位置加6

offset_add_6

使用C32Asm找到BA 0E 00 将0E加上6,如图11所示。

offset_add_result

图11 修改字串偏移位置结果

保存修改内容,使用Debug模式运行程序(debug C:\h.exe),然后按下g,可以看到在显示字串后会嘟的一声,如图12所示。

图11 测试执行结果

图11 测试执行结果

附上上述操作中使用的exe和asm文件,以及C32Asm工具。

百度网盘链接:http://pan.baidu.com/s/1kVH9eRX 密码:axub

 

转载请注明:悠然品鉴 » PE修改DOS Sub增加电脑喇叭嘟一声的功能

喜欢 (0)or分享 (0)
发表我的评论
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址