I'm experimenting with building my own exe-files and dll-files, and the only bytes in an exe-file that I cannot find any info about is the data that the MASM linker always seems to put between the DOS stub code and the PE-header. I know that this data is not part of the exe-format itself (in files produced by other linkers, e.g. Delphi, this area is zeroed) but it would still be really interesting to know what kind of data MASM stores here?

I have noticed that the data is practically identical between different exe-files produced with MASM (only one byte in it has been observed to change) and it also always seems to include the string "Rich".

MASM outputs different data (and even different size of this data) when producing a dll file and when producing an exe file though.


This is a normal MASM DOS-stub code:



push cs
pop ds
mov dx, 0Eh
mov ah, 9
int 21h ; DOS - PRINT STRING
; DS : DX -> string terminated by "$"
mov ax, 4C01h
int 21h ; DOS - 2+ - QUIT WITH EXIT CODE (EXIT)

000E_string:
"This program cannot be run in DOS mode.", 2Eh, 0Dh, 0Dh, 0Ah, "$"


Directly after it comes this data I'm talking about, before the PE-header.



In my MASM exe-files it is the following:


00000070 <end of stub string here> 00 00 00 00 00 00 00 .......
00000080 5D 17 1D DB 19 76 73 88 19 76 73 88 19 76 73 88 ]..?.vs?.vs?.vs?
00000090 19 76 73 88 0D 76 73 88 E5 56 61 88 18 76 73 88 .vs?.vs??Va?.vs?
000000A0 52 69 63 68 19 76 73 88 00 00 00 00 00 00 00 00 Rich.vs?........
000000B0 <PE-header begins here>


In my MASM dll-files it is the following:


00000070 <end of stub string here> 00 00 00 00 00 00 00 .......
00000080 71 D4 F7 DB 35 B5 99 88 35 B5 99 88 35 B5 99 88 q???5???5???5???
00000090 C9 95 8B 88 34 B5 99 88 BB AA 8A 88 34 B5 99 88 ???4???????4???
000000A0 52 69 63 68 35 B5 99 88 00 00 00 00 00 00 00 00 Rich5???........
000000B0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
000000C0 <PE-header begins here>


It would be really interesting to know what kind of info that MASM "hides" in this data. Does anyone have any idea whatsoever?

Thanks!
Posted on 2003-03-01 08:40:32 by dELTA
Seems more to come from the linker than masm. With older linkers these bytes arent included.
Posted on 2003-03-01 11:17:55 by japheth
Yep, it most likely comes from the linker, but isn't the linker part of the masm package too? :confused: It still would be very interesting to know what it is anyway.
Posted on 2003-03-01 11:55:27 by dELTA
I did not Found CD 19 bytes. Where is it?.
Im a bit courious too, MZ what is it? Memory Zero?


4C 5A CD 19 ......

Posted on 2003-03-03 09:38:47 by realvampire
realvampire,

"MZ" is a signature sequence that is always the first two bytes in any executable module of exe or dll format (not in com-files). It is part of the DOS executable header. Windows executables need quite a lot more info, and this is stored in the PE-header (in 32 bits executables anyway, otherwise in the NE-header), which is located after the MZ header (you will find the exact offset as a dword at offset 60 in all Windows executables).

The data I'm talking about it located right before the PE-header (after the DOS-stub), and I'm sure that the contents of it may vary some, depending on linker version and possibly lots of other factors. That's why I'd like to know more about what it is.

Doesn't really anybody have the slightest idea? I'm sure there are at least some Microsoft MASM developers hanging around here occasionally, come on now guys, spill it. ;)
Posted on 2003-03-03 16:30:11 by dELTA
The real-mode stub program is an actual program run by MS-DOS when the executable is loaded. For an actual MS-DOS executable image file, the application begins executing here. For successive operating systems, including Windows, OS/2?, and Windows NT, an MS-DOS stub program is placed here that runs instead of the actual application. The programs typically do no more than output a line of text, such as: "This program requires Microsoft Windows v3.1 or greater." Of course, whoever creates the application is able to place any stub they like here, meaning you may often see such things as: "You can't run a Windows NT application on OS/2, it's simply not possible."

When building an application for Windows version 3.1, the linker links a default stub program called WINSTUB.EXE into your executable. You can override the default linker behavior by substituting your own valid MS-DOS-based program in place of WINSTUB and indicating this to the linker with the STUB module definition statement. Applications developed for Windows NT can do the same thing by using the -STUB: linker option when linking the executable file.
Posted on 2003-03-03 17:22:04 by wizzra
Yes, I know that, you can even see my disassembly of this stub in my first post above. But MASM inserts additional data (which is not referenced from the stub code) between the stub and the PE-header, and that's what I'd like to know what it is.
Posted on 2003-03-04 05:57:29 by dELTA
Try to see it with QuickViewer. Hope it help you.
Posted on 2003-03-04 06:38:16 by realvampire
MZ stands by the name of the programmer Mark Zbikowski.
Posted on 2004-03-16 05:17:13 by Opcode
dELTA,

Its usually junk, the space between the end of the MZ header and the start address of the PE header is undefined so you can use it for anything, store settings there or just zero it out if you want.
Posted on 2004-03-19 01:31:38 by hutch--

MZ stands by the name of the programmer Mark Zbikowski.

Was it really necessary to kick a thread of more than a year old just to post this? :)

Thomas
Posted on 2004-03-19 01:58:48 by Thomas
Following program is I used to test the usage of stub.
This program can run under MS DOS and WINDOWS, and Reports current operation system type.


the stub code:


;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
; FileName: os_type.asm
; Function: Reports current operation system type
; Author : Purple Endurer
; Version : 0.1
;
; OS Name Offset of INT 08h Offset of INT 43h
; -------------------------------------------------------
; MS DOS 7.00 001Fh 5710h
; MS DOS 7.10 18DEh 6EE5h
; UCDOS 1AF3h
; UCDOS98 1AEBh 6E20h
; MSDOS mode 0000h
; PDOS95 0A50h 6E20h
;
; Date Summary
; -------------------------------------------------------
; 2002.04.07 Created from software paper 95P125
; 2002.06.11 Show version if os is MS-DOS
; 2002.08.07 Convert it to DOS EXE format to be stub
; program in PE format execute file
; 2004.02.09 Added the condition asm var 'UseStack'

UseStack equ 0
data segment
strMSDOS db "MS DOS "
cMajorVer db ' '
db '.'
cMinorVer db " $"

strUCDOS db "UCDOS"
cUCDOSVer db " 98?????$"

strPDOS95 db "Windows95????DOS???PDOS95$"
data ends

if UseStack
sseg segment stack
db 10 dup(?)
sseg ends
endif
code segment
;--------------------------------------
if UseStack
assume cs: code, ds: data, ss: sseg
else
assume cs: code, ds: data
endif

main proc
start:
mov ax, data
mov ds, ax

if UseStack
mov ax, sseg
mov ss, ax
endif

mov ah, 30h ; Get Version
int 21h
add al, '0'
mov cMajorVer, al
mov bx, offset cMinorVer
call bin2dec

mov ax, 3508h
int 21h

mov dx, offset strMSDOS
mov ah, 09h
int 21h

cmp bx, 1fh
je @end ;Here is DOS 7.00 only
cmp bx, 18deh
je @End ;Here is DOS 7.10 only

mov dx, offset strUCDOS
cmp bx, 1aebh
je @Report

cmp bx, 1af3h
jne @next2
mov cUCDOSVer, '$'
jmp @report

@next2:

mov dx, offset strPDOS95
cmp bx, 0a50h
jne @End
@Report:
;mov ah, 09h
int 21h
@End:
mov ax, 4c00h
int 21h
main endp

;=================================================
; Input : AH = the Binary will be translated)
; BX = First offset of memory us to store the result
; Output: BX = First offset of memory stored the result
; --------------------------------------------------------
bin2dec proc
push dx
mov dl, 10
@LoopDiv:
mov al, ah
xor ah, ah
div dl ; (AL) <- (AX) / (DL) (AH) <- (AX) % (DL)
add al, '0'
mov [bx], al
inc bx
cmp ah, 10
jg @LoopDiv

add ah, '0'
mov [bx], ah
pop dx
ret
bin2dec endp
;=========================================
code ends
end main



PE code:


;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
;FileName: StubDemo.asm
; Fuction: Demo how to use the custome stub of PE exe files.
; Author: Purple Endurer
;The command line refered cursom STUB program:
;\masm32\bin\link /stub:<filename.exe> /subsystem:windows <objectname.obj>
;
;Example:
;D:\masm32v6\WORKS\my_stub>\masm32\bin\link /stub:os_type.exe /subsystem:windows stubdemo.obj
;Microsoft (R) Incremental Linker Version 5.12.8078
;Copyright (C) Microsoft Corp 1992-1998. All rights reserved.

;os_type.exe : warning LNK4060: stub file missing full MS-DOS header; rebuild stub with /KNOWEAS 16-bit LINK option

; Date Summary
; -------------------------------------------------------
; 2002.04.07 Created!
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib
includelib \masm32\lib\kernel32.lib

bDetailInfo equ 0

.data
szMsgBoxTitle db "?????????",0


if bDetailInfo ;?????? bDetailInfo
szWin31 db "Win32s on Windows 3.1 ", 0
szWin9x db "Win32 on Windows 95 ", 0
else
szWin31 db "Windows 3.1 ", 0
szWin9x db "Windows 95 ", 0
endif ;?????? bDetailInfo

szWinNT db "Windows NT ", 0

szFormat4OsVer db "%lu.%lu.%lu", 0
szGetOsInfoFail db "?????????????!", 0

.data?
OsVer OSVERSIONINFO <>
szOsVerInfo db 255 dup (?)
szOsVerInfoTmp db 255 dup (?)

.code
start:
mov OsVer.dwOSVersionInfoSize, SIZEOF OSVERSIONINFO
invoke GetVersionEx, ADDR OsVer

.if eax
mov eax, OsVer.dwPlatformId

;Identifies the build number of the operating
;system in the low-order word For Win9X

.if eax == VER_PLATFORM_WIN32s
mov esi, OFFSET szWin31
and OsVer.dwBuildNumber, 0FFFFh

.elseif eax == VER_PLATFORM_WIN32_WINDOWS
mov esi, OFFSET szWin9x
and OsVer.dwBuildNumber, 0FFFFh

.else ; eax ==VER_PLATFORM_WIN32_NT
mov esi, OFFSET szWinNT
.endif

invoke lstrcpy, ADDR szOsVerInfo, esi

invoke wsprintf, ADDR szOsVerInfoTmp,\
ADDR szFormat4OsVer, OsVer.dwMajorVersion,\
OsVer.dwMinorVersion, OsVer.dwBuildNumber

invoke lstrcat, ADDR szOsVerInfo, ADDR szOsVerInfoTmp
invoke lstrcat, ADDR szOsVerInfo, ADDR OsVer.szCSDVersion
mov edi, OFFSET szOsVerInfo
mov esi, MB_OK OR MB_ICONINFORMATION
.else
mov edi, OFFSET szGetOsInfoFail
mov esi, MB_OK OR MB_ICONWARNING
.endif

invoke MessageBox, NULL, edi, addr szMsgBoxTitle, esi

invoke ExitProcess,NULL

end start
Posted on 2004-03-19 06:38:09 by purpleendurer
Its usually junk, the space between the end of the MZ header and the start address of the PE header is undefined so you can use it for anything, store settings there or just zero it out if you want.

hutch--,

No, as was discussed and analyzed in this thread , that data is encrypted information added by Microsoft. Of course it can be deleted though, like you say, it has no function for the execution of the program, but it is still not "junk".

Sadly, this interesting info about what was encrypted into that data (and how to decode it) was edited out from that thread by "Lingo" a few days ago for some reason (see the edit date on his post in that thread). I have tried to contact him to ask why, and to get that information, but received no reply. :(

Does anyone have an archive of this board which is older than 2 weeks, from which you can retreive this info? That would be really great!


dELTA
Posted on 2004-03-19 07:38:31 by dELTA
Hmmmm,

This sounds like conspiracy theory, MS store the password to their repository of code at the beginning of every exe file made with ml/link even though its not used in the data.

We all know that the start address for the PE header is in the last member of the MZ header. I have seen different start addresses on many different PE files ranging from 80h to well over 100h and I have at times used the space between the MZ and PE headers to write information that I recover at runtime with the exe file.

If you use compressed exe files, the headers at the beginning are one of the few places where you can store settings in the disk file which can be changed after the exe is finished.
Posted on 2004-03-19 17:38:54 by hutch--
There was a couple of lengthy posts about it, and it seemed real enough, A bit interesting, actually. The data stored there wasn't really anything major, but it's still a bit creepy that it's stored there - especially since it was XOR'ed (according to the original posts).
Posted on 2004-03-19 17:42:12 by f0dder
The mystery is solved at last! (by Daniel Pistelli)  :)

http://www.woodmann.com/forum/showthread.php?t=11367
Posted on 2008-03-05 04:30:50 by dELTA
Wow! Hat off to Mr. Pistelli.
Posted on 2008-03-05 07:34:23 by JimmyClif
It was documented even before that, the topic appeared on DonationCoder and a guy posted a .txt file about it from around the same time period as lingo's postings, iirc. Unfortunately DonationCoder has been hacked and is down for scrutinizing, so I can't find the post right now... but I think Pistelli's is a bit more in-depth :)

Anyway dELTA, to remove suspicion about "evil asmcommunity moderators", can you please post at woodmann's that lingo actually removed the information himself? Dunno why he did it.
Posted on 2008-03-05 09:11:28 by f0dder

The mystery is solved at last! (by Daniel Pistelli)  :)

Hasn't the mystery already been solved?
http://www.woodmann.net/forum/attachment.php?attachmentid=1050

thread: http://www.woodmann.com/forum/showthread.php?t=5925
Posted on 2008-03-05 19:29:50 by drizz


The mystery is solved at last! (by Daniel Pistelli)  :)

Hasn't the mystery already been solved?
http://www.woodmann.net/forum/attachment.php?attachmentid=1050

That's the .txt file I was thinking about :), you might want to link to the topic where that file was attached? And, again, to be fair: the new article is more in-depth.
Posted on 2008-03-05 19:31:50 by f0dder