能力值:
(RANK:260 )
4 楼
DOS_STUB是一个完整的DOS程序。
从DOS头到PE头,这中间的部分都属于DOS_STUB。
这样,由于DOS下的MZ文件也是以EXE扩展名为特征,而PE文件的前面部分,实际上是一个合法的DOS下的MZ可执行文件。也就是说,微软实现了从DOS到WIN32的“无缝”升级。
最初这样的设计,DOS用户在看到一个EXE文件时,键入它的名字,不会出现意外的事情(要知道DOS的加载器是比较简单的,如果一个含有随机内容的EXE文件被加载,可能会对系统千万严重破坏)。
而且,这样设计还带来了一个额外的好处,微软早期的软件产品充分利用了这一设计——早期的office产品,是既可以在DOS下运行,也可以在Windows下运行的。而PE文件的特殊设计,使其只有一个EXE文件,该文件在DOS下和在Windows下都可以运行。
还有,微软早期Windows产品,内核是从DOS下引导的,这样的就要求程序同时具有16位代码和32位代码,而PE文件恰好可以做到(实际上微软最初用的是叫NE的一种格式,后来才演化成现在的PE格式)。 理论上,可以是任意的DOS程序。但由于DOS已经退出历史舞台,所以DOS_STUB现成已经完全退化成一个由于向下“兼容”的需要而存在的东西了。链接器默认使用的DOS_STUB,它打印出“This program can not run in DOS”然后退出。
DOS_STUB可以通过连接器参数而改变,这样你可以利用这一特性,实现自己特殊的功能,比如一个OS的Loader等。
能力值:
( LV2,RANK:10 )
5 楼
多谢版主解答。 看个例子:
00000000: 4D 5A 90 00-03 00 00 00-04 00 00 00-FF FF 00 00 MZ..............
00000010: B8 00 00 00-00 00 00 00-40 00 00 00-00 00 00 00
00000020: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
00000030: 00 00 00 00-00 00 00 00-00 00 00 00-C0 00 00 00
00000040: 0E 1F BA 0E-00 B4 09 CD-21 B8 01 4C-CD 21 54 68 ..............Th
00000050: 69 73 20 70-72 6F 67 72-61 6D 20 63-61 6E 6E 6F is program canno
00000060: 74 20 62 65-20 72 75 6E-20 69 6E 20-44 4F 53 20 t be run in DOS
00000070: 6D 6F 64 65-2E 0D 0D 0A-24 00 00 00-00 00 00 00 mode....$
00000080: E3 2B 61 C1-A7 4A 0F 92-A7 4A 0F 92-A7 4A 0F 92
00000090: 29 55 1C 92-80 4A 0F 92-5B 6A 1D 92-A6 4A 0F 92
000000A0: 60 4C 09 92-A6 4A 0F 92-52 69 63 68-A7 4A 0F 92
000000B0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
000000C0: 50 45 00 00-4C 01 04 00-B4 52 BC 49-00 00 00 00 PE..............
000000D0: 00 00 00 00-E0 00 0F 01-0B 01 05 0C-00 0A 00 00
000000E0: 00 1E 00 00-00 00 00 00-00 10 00 00-00 10 00 00
000000F0: 00 20 00 00-00 00 40 00-00 10 00 00-00 02 00 00 ╔════════[ MZ-header ]═════════╗
║ Signature 4D5A ║
║ Bytes on last page 0090 ║
║ Pages in file 0003 ║
║ Relocations 0000 ║
║ Paragraphs in header 0004 ║
║ Minimum memory 0000 ║
║ Maximum memory FFFF ║
║ SS:SP 0000:00B8 ║
║ Checksum 0000 ║
║ CS:IP 0000:0000 ║
║ Relocation table adress 0040 ║
║ Overlay number 0000 ║
║ Overlay length 00002770 ║
║ NewExe offset 000000C0 ║
║ >Entry point 00000040 ║
╚══════════════════════════════╝ CS:0000--->0E 1F BA 0E-00 B4 09 CD-21 B8 01 4C-CD 21 54 68 ..............Th
00000050: 69 73 20 70-72 6F 67 72-61 6D 20 63-61 6E 6E 6F is program canno
00000060: 74 20 62 65-20 72 75 6E-20 69 6E 20-44 4F 53 20 t be run in DOS
00000070: 6D 6F 64 65-2E 0D 0D 0A-24 00 00 00-00 00 00 00 mode....$
00000080: E3 2B 61 C1-A7 4A 0F 92-A7 4A 0F 92-A7 4A 0F 92
00000090: 29 55 1C 92-80 4A 0F 92-5B 6A 1D 92-A6 4A 0F 92
000000A0: 60 4C 09 92-A6 4A 0F 92-52 69 63 68-A7 4A 0F 92
000000B0: 00 00 00 00-00 00 00 00-00<---SS:00B8 我的理解:
下面这段是有用的(有效代码):
CS:0000 -> 0E 1F BA 0E-00 B4 09 CD-21 B8 01 4C-CD 21 54 68 ..............Th
00000050: 69 73 20 70-72 6F 67 72-61 6D 20 63-61 6E 6E 6F is program canno
00000060: 74 20 62 65-20 72 75 6E-20 69 6E 20-44 4F 53 20 t be run in DOS
00000070: 6D 6F 64 65-2E 0D 0D 0A-24 00 00 00-00 00 00 00 mode....$ 下面这段是无用的?
00000080: E3 2B 61 C1-A7 4A 0F 92-A7 4A 0F 92-A7 4A 0F 92
00000090: 29 55 1C 92-80 4A 0F 92-5B 6A 1D 92-A6 4A 0F 92
000000A0: 60 4C 09 92-A6 4A 0F 92-52 69 63 68-A7 4A 0F 92
000000B0: 00 00 00 00-00 00 00 00-00<---SS:00B8
可以改为:
00000080: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
00000090: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
000000A0: 00 00 00 00-00 00 00 00-00 00 00 00-00 00 00 00
000000B0: 00 00 00 00-00 00 00 00-00<---SS:00B8
也不会影响该程序在DOS/WINDOWS下运行。 那么,
00000080: E3 2B 61 C1-A7 4A 0F 92-A7 4A 0F 92-A7 4A 0F 92
00000090: 29 55 1C 92-80 4A 0F 92-5B 6A 1D 92-A6 4A 0F 92
000000A0: 60 4C 09 92-A6 4A 0F 92-52 69 63 68-A7 4A 0F 92
这段代码到底有没有用呢?
难道是随机填入的?
能力值:
(RANK:260 )
6 楼
修改这些字节,对程序在Windows下的运行没有影响,但是对DOS下的运行有没有影响我就不知道了。
我的x64系统不支持对16位程序的兼容,所以没法验证。
反正我也不打算对DOS做深入研究,这个问题不必考虑。
至于你问的那些数据是不是随机填充的,我也不知道,想知道可以去问一下微软的设计师。
能力值:
( LV2,RANK:10 )
8 楼
DOS STUB和PEHEAD之间的数据分析
==============================
建立一个简单的test.asm:
.386
.model flat, stdcall
option casemap:none
.data
.code
start:
mov eax,eax
ret
end start 编译:
\masm32\bin\ml /c /coff test.asm
连接:
Link.exe /SUBSYSTEM:WINDOWS test.obj 运行OLLYDBG,单独跟踪调试:
Link.exe /SUBSYSTEM:WINDOWS test.obj ;; LINK.EXE VERSION: 5.12.8078.0 ;; EBP=n
0043FD52 |. 896C24 10 MOV DWORD PTR SS:[ESP+10],EBP
0043FD56 |> 8D5424 28 LEA EDX,DWORD PTR SS:[ESP+28]
0043FD5A |. 52 PUSH EDX
0043FD5B |. E8 90FAFCFF CALL link.0040F7F0
0043FD60 |. 8BB7 E0010000 MOV ESI,DWORD PTR DS:[EDI+1E0] ;; ESI = 80
0043FD66 |. 33C9 XOR ECX,ECX
0043FD68 |. 85F6 TEST ESI,ESI
0043FD6A |. 8BFE MOV EDI,ESI
0043FD6C |. 76 1C JBE SHORT link.0043FD8A
0043FD6E |. 8B4424 14 MOV EAX,DWORD PTR SS:[ESP+14]
0043FD72 |. 8BA8 DC010000 MOV EBP,DWORD PTR DS:[EAX+1DC] ;; ESI = 80
;; EDI = 884F3421 checksum of the 80 bytes
00406EB4 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 MZ..............
00406EC4 B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ................
00406ED4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00406EE4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
00406EF4 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ..............Th
00406F04 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F is program canno
00406F14 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 t be run in DOS
00406F24 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 mode....$.......
0043FD78 |> 33D2 /XOR EDX,EDX
0043FD7A |. 8A1429 |MOV DL,BYTE PTR DS:[ECX+EBP]
0043FD7D |. D3C2 |ROL EDX,CL
0043FD7F |. 03FA |ADD EDI,EDX
0043FD81 |. 41 |INC ECX
0043FD82 |. 3BCE |CMP ECX,ESI
0043FD84 |.^ 72 F2 \JB SHORT link.0043FD78
;; EDI = 884F3421 0043FD86 |. 8B6C24 10 MOV EBP,DWORD PTR SS:[ESP+10]
0043FD8A |> 85DB TEST EBX,EBX
0043FD8C |. 8BC3 MOV EAX,EBX
0043FD8E |. 74 10 JE SHORT link.0043FDA0 ;; EAX = 0039D438
0039D438 00 00 00 00 FC 20 12 00 01 00 00 00 AB AB AB AB ................
0043FD90 |> 8B50 04 /MOV EDX,DWORD PTR DS:[EAX+4]
0043FD93 |. 8B48 08 |MOV ECX,DWORD PTR DS:[EAX+8]
0043FD96 |. 8B00 |MOV EAX,DWORD PTR DS:[EAX]
0043FD98 |. D3C2 |ROL EDX,CL
0043FD9A |. 03FA |ADD EDI,EDX
0043FD9C |. 85C0 |TEST EAX,EAX
0043FD9E |.^ 75 F0 \JNZ SHORT link.0043FD90
;; EDI = 88737619 0043FDA0 |> 8BC7 MOV EAX,EDI
0043FDA2 |. 33D2 XOR EDX,EDX
0043FDA4 |. C1E8 05 SHR EAX,5
0043FDA7 |. B9 03000000 MOV ECX,3
0043FDAC |. F7F1 DIV ECX
0043FDAE |. 03D5 ADD EDX,EBP
0043FDB0 |. 8D2CD5 200000>LEA EBP,DWORD PTR DS:[EDX*8+20]
0043FDB7 |. 55 PUSH EBP
0043FDB8 |. E8 A3130100 CALL link.00451160
;; call calloc(n*8+20)
00451160 /$ 8B4424 04 MOV EAX,DWORD PTR SS:[ESP+4]
00451164 |. 56 PUSH ESI
00451165 |. 50 PUSH EAX ; /size
00451166 |. 6A 01 PUSH 1 ; |nitems = 1
00451168 |. FF15 4C124000 CALL DWORD PTR DS:[<&MSVCRT.calloc>] ; \calloc
0045116E |. 8BF0 MOV ESI,EAX
00451170 |. 83C4 08 ADD ESP,8
00451173 |. 85F6 TEST ESI,ESI
00451175 |. 75 05 JNZ SHORT link.0045117C
00451177 |. E8 6405FEFF CALL link.004316E0
0045117C |> 8BC6 MOV EAX,ESI
0045117E |. 5E POP ESI
0045117F \. C2 0400 RETN 4 ;; EAX = 0039D460
0039D460 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0039D470 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
0039D480 00 00 00 00 00 00 00 00 AB AB AB AB AB AB AB AB ........ 0043FDBD |. 8B5424 3C MOV EDX,DWORD PTR SS:[ESP+3C]
0043FDC1 |. 8BF0 MOV ESI,EAX
0043FDC3 |. 8932 MOV DWORD PTR DS:[EDX],ESI
0043FDC5 |. A1 A0934600 MOV EAX,DWORD PTR DS:[4693A0] ;; const [004693A0] = F93BF822
0043FDCA |. 33C7 XOR EAX,EDI
0043FDCC |. 897E 04 MOV DWORD PTR DS:[ESI+4],EDI ;; PE[80][04]=EDI
0043FDCF |. 35 669955AA XOR EAX,AA559966
0043FDD4 |. 8906 MOV DWORD PTR DS:[ESI],EAX ;; PE[80][00]=????
0043FDD6 |. 83C6 08 ADD ESI,8
0043FDD9 |. 8BC3 MOV EAX,EBX
0043FDDB |. 893E MOV DWORD PTR DS:[ESI],EDI ;; PE[80][08]=EDI
0043FDDD |. 897E 04 MOV DWORD PTR DS:[ESI+4],EDI ;; PE[80][0C]=EDI
0043FDE0 |. 83C6 08 ADD ESI,8
0043FDE3 |. 85DB TEST EBX,EBX
0043FDE5 |. 74 24 JE SHORT link.0043FE0B
0043FDE7 |> 8B48 04 /MOV ECX,DWORD PTR DS:[EAX+4]
0043FDEA |. 50 |PUSH EAX ; /block
0043FDEB |. 33CF |XOR ECX,EDI ; |
0043FDED |. 890E |MOV DWORD PTR DS:[ESI],ECX ; | ;; PE[80][10+(n-1)*8+0]=????
0043FDEF |. 8B50 08 |MOV EDX,DWORD PTR DS:[EAX+8] ; |
0043FDF2 |. 33D7 |XOR EDX,EDI ; |
0043FDF4 |. 8956 04 |MOV DWORD PTR DS:[ESI+4],EDX ; | ;; PE[80][10+(n-1)*8+4]=????
0043FDF7 |. 8B18 |MOV EBX,DWORD PTR DS:[EAX] ; |
0043FDF9 |. 83C6 08 |ADD ESI,8 ; |
0043FDFC |. FF15 48124000 |CALL DWORD PTR DS:[<&MSVCRT.free>] ; \free
0043FE02 |. 83C4 04 |ADD ESP,4
0043FE05 |. 8BC3 |MOV EAX,EBX
0043FE07 |. 85DB |TEST EBX,EBX
0043FE09 |.^ 75 DC \JNZ SHORT link.0043FDE7
0043FE0B |> A1 A4934600 MOV EAX,DWORD PTR DS:[4693A4] ;; const [004693A4] = C236F034
0043FE10 |. 897E 04 MOV DWORD PTR DS:[ESI+4],EDI ;; PE[80][10+n*8+4] = EDI
0043FE13 |. 35 669955AA XOR EAX,AA559966
0043FE18 |. 8906 MOV DWORD PTR DS:[ESI],EAX ;; PE[80][10+n*8+0] = C236F034 XOR AA559966 = 68636952 ("Rich")
0043FE1A |. 8BC5 MOV EAX,EBP
0043FE1C |. 5E POP ESI
0043FE1D |. 5D POP EBP
0043FE1C |. 5E POP ESI
0043FE1D |. 5D POP EBP
0043FE1E |. 5B POP EBX
0043FE1F |. 5F POP EDI
0043FE20 |. 83C4 28 ADD ESP,28
0043FE23 |. C2 0400 RETN 4
;; PE[80][00] --- PE[80][10+n*8+7]
;; TOTAL 18+n*8 bytes
;; if add 8 dup(0), TOTAL 20+n*8 bytes
有个简单的规律:第2,3,4及最后1个DWORD是相同的(都等于EDI),倒数第2个DWORD是Rich Signature("Rich") 。 找到另外一篇文章:Microsoft's Rich Signature (undocumented)
http://www.ntcore.com/Files/richsign.htm
能力值:
( LV2,RANK:10 )
9 楼
在网上找到一篇文章:
https://wasm.ru/forum/viewtopic.php?id=7056
里面有这段代码:
mov eax, const1 ; 0F93BF822h
xor eax, edi ; edi==...Rich
mov [esi+4], edi
xor eax, 0AA559966h
mov [esi], eax
只是这篇文章我实在看不懂,如有朋友能看懂俄语,希望能翻译一下更好。