B8 00 00 00 00 00 00 00 40 00 1A 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00
BA 10 00 0E 1F B4 09 CD 21 B8 01 4C CD 21 90 90 //从这行开始是DOS Stub
54 68 69 73 20 70 72 6F 67 72 61 6D 20 6D 75 73 // This program mus
74 20 62 65 20 72 75 6E 20 75 6E 64 65 72 20 57
69 6E 33 32 0D 0A 24 37 00 00 00 00 00 00 00 00 // 24就是'$'
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
------------------------------------------------------------------------------------------------------
我很早就有这个想法,但是直到今天还是没解决这个问题。很多人连我自己都认为我在干一件很蠢的事情,但是这个问题不解决就一直压在我心里,真不好受啊?
上面那个是Delphi编译出的默认头部,我用Debug 1.exe再用U命令查看到
0B8D:0000 BA1000 MOV DX,0010
0B8D:0003 0E PUSH CS
0B8D:0004 1F POP DS
0B8D:0005 B409 MOV AH,09
0B8D:0007 CD21 INT 21
0B8D:0009 B8014C MOV AX,4C01
0B8D:000C CD21 INT 21
Dos Stub中真正有价值的命令就这几条,但是问题是运行此命令的硬件(寄存器、内存等)环境怎么提取出来,在DOS MZ Head块的那些信息好像帮不上我。我是XP时代接触电脑的,请各位高手帮帮我!
4D 5A 00 01 01 00
- _IMAGE_DOS_HEADER = packed record { DOS .EXE header }
- e_magic: Word; { Magic number }
- e_cblp: Word; { Bytes on last page of file }
- e_cp: Word; { Pages in file }
- e_crlc: Word; { Relocations }
- e_cparhdr: Word; { Size of header in paragraphs }
- e_minalloc: Word; { Minimum extra paragraphs needed }
- e_maxalloc: Word; { Maximum extra paragraphs needed }
- e_ss: Word; { Initial (relative) SS value }
- e_sp: Word; { Initial SP value }
- e_csum: Word; { Checksum }
- e_ip: Word; { Initial IP value }
- e_cs: Word; { Initial (relative) CS value }
- e_lfarlc: Word; { File address of relocation table }
- e_ovno: Word; { Overlay number }
- e_res: array [0..3] of Word; { Reserved words }
- e_oemid: Word; { OEM identifier (for e_oeminfo) }
- e_oeminfo: Word; { OEM information; e_oemid specific}
- e_res2: array [0..9] of Word; { Reserved words }
- _lfanew: LongInt; { File address of new exe header }
- end;
Magic number :用于標識可執行文件的類型,如下常量表示不同的類型
cDOSMagic = $5A4D; // magic number for a DOS executable
cNEMagic = $454E; // magic number for a NE executable (Win 16)
cPEMagic = $4550; // magic nunber for a PE executable (Win 32)
cLEMagic = $454C; // magic number for a Virtual Device Driver
Bytes on last page of file : 文件在最后一個頁面的字節數
Pages in file : 文件所占用的頁面數
Relocations : 需要重定位的segment數目
size of header in paragraphs : dos文件頭占用大小
Minimum extra paragraphs needed : 需要額外的最少段數目
Maximum extra paragraphs needed : 需要額外的最大段數目
Initial (relative) SS value : 堆棧段寄存器的初始值
Initial (relative) sp value :堆棧寄存器的初始值
Checksum : 校驗和
A checksum or hash sum 是固定的值,由任意的一塊數字計算而來。這塊數字用于檢測意外的錯誤。任何時候可以重新計算checksum,然后比對是否一致。更多詳細參考:http://en.wikipedia.org/wiki/Checksum
Initial IP value : 初始的指令寄存器值
File address of relocation table: 重定位表,在早期的16位系統中,為使得尋址能力達到20位,以滿足可訪問更多的空間,搭配使用了段(segment)。這里記錄了指向代碼段(code)、數據段(data)的地址,但這些地址并不是絕對、固定的。因為代碼段和數據段等,只有在被加載到內存時,才能他們的實際地址。當程序被加載到內存後,exe loader會通過重定位表,再修正segment中的相對值(偏移量),以正確定位到代碼段及數據段的真實地址。
隨著32系統的到來,windows exe被設計為遵循PE的格式,這時的重定位表就不再被使用了。這是因為虛擬地址的出現——在虛擬空間里,Exe可以被加載到任意的地址,程序總是被以虛擬空間的基址加載,所以也就不要調整重定位表了。然而,在dll文件里,重定位表,仍是需要的,因為會被加載到已存在進程地址空間中,不再已既定的基址加載,所以需要矯正表中的偏移值。
++++++++++++++++++++++++++++++++++++
残留的DOS文件头真正有价值的地方是三处,如下:
DOS_HEADER db 'MZ' ; e_magic 证明这是一个可执行文件,且运行在dos或win系统下
......
......
dw 40h ; e_lfarlc 指向那段小程序,目的是,如果你不小心将这个32为程序运行在
; DOS 下出现提示信息:“This program cannot be run in DOS mode.”
; 如果这是一个真正的DOS程序,这里就是DOS程序的入口
......
......
dd offset PE_HEADER ; e_lfanew 指向真正的win32的PE 可执行文件头
你说的什么真正的有用的程序,只不过是一句提示,对于变形类PE可执行文件头,基本都是将段东西直接删除,根本就没有用处,就算你不小心将这样的没有提示的32为程序运行在DOS下,也没有什么,不过是没有提示而已。
这段提示不过是利用DOS中断服务程序 int 21h 的09号功能,显示几个提示字符,然后使用4c号功能直接退到DOS,这段代码完全没有用处,不过你有水平的话,可以将这段东西改为病毒代码,放在那里永远也不运行,假如那天有人不小心运行在DOS下,那么对不起,杀掉你的硬盘(太简单,直接抹去主引导,分区引导和文件分配表),杀掉你的BIOS,(如果是现在的带保护的BIOS无效),然后喇叭里放点难听的东西,哈哈。
| ||
|
#4楼 得分:3回复于:2009-08-09 22:53:58
|