Binaries are here: https://megawrzuta.pl/download/ec3cd76488bbfddb2644122a07a66728.html
; stub for COFF file
;compile:
; fasm stubcoff.asm
; 32lite -m stubcoff.exe
; copy /b stubcoff.exe+cofffile.exe main.exe
format Adam on "d3x.exe"
entry Start
stack 1024
virtual at 0
SectionName db 8 dup ? ; 0 terminated string
SectionPAddr dd ?
SectionVAddr dd ? ; where to load
SectionSize dd ? ; how much to load
SectionFOfs dd ? ; file offset relative to coff header
dd 4 dup ? ; rubbish
CoffSection.Size:
end virtual
virtual at 0
CoffMagic dw ? ; must be 014Ch
db 18 dup ? ; rubbish
AoutHeader:
AoutMagic dw ? ; must be 010Bh
db 14 dup ? ; rubbish
AoutEntry dd ? ; initial EIP
db 08 dup ? ; rubbish
TextSection: rb CoffSection.Size
DataSection: rb CoffSection.Size
BsssSection: rb CoffSection.Size
CoffHeader.Size:
end virtual
StubInfo:
StubInfoMagic db 'go32stub, v 2.00' ; a fake
StubInfoSize dd StubInfoEnd-StubInfo
StubInfoMinstack dd 40000h
StubInfoMemoryHandle dd 0
StubInfoInitialSize dd 0
StubInfoMinkeep dw 4000h
StubInfoDsSelector dw 0
StubInfoDsSegment dw 0 ; not filled
StubInfoPspSelector dw 0 ; PSP selector
StubInfoCsSelector dw 0
StubInfoEnvSize dw 0
StubInfoBasename db 08 dup 0
StubInfoArgv0 db 16 dup 0
StubInfoDpmiServer db 16 dup 0
StubInfoEnd:
;
; DOS strings for possible error messages
;
StrErrDPMI db 'DPMI host returned an error',13,10,36
StrErrFile db 'Error reading executable',13,10,36
StrErrFormat db 'Not a valid .COFF executable',13,10,36
StrErrMem db 'Not enough memory to load executable',13,10,36
;
; error routines
;
ErrorDPMI:
mov edx,StrErrDPMI
jmp short ErrorMsg
ErrorFile:
mov edx,StrErrFile
jmp short ErrorMsg
ErrorFormat:
mov edx,StrErrFormat
jmp short ErrorMsg
ErrorMem:
mov edx,StrErrMem
ErrorMsg:
mov ah,9
int 21h
mov eax,4CFFh
int 21h
;
; Program entry point
;
Start: mov ah,62h
int 21h
mov [StubInfoPspSelector],bx
;
; allocate transfer buffer used by the main program
;
mov bx,0400h
mov ax,0100h
int 31h
jc ErrorDPMI
mov [StubInfoDsSegment],ax
;
; Create one code and one data alias. The reason for the data alias is
; that the selector of the DOS memory block is being freed by DJGPP when the
; memory itself is not. This might confuse certain DPMI hosts.
;
mov ebx,edx
mov ax,000Ah
int 31h
jc ErrorDPMI
mov [StubInfoDsSelector],ax
;
; For Win3.x blows up if the program terminates on a 16 bit stack, we force
; the B bit being set on this one.
;
push ebx
mov ebx,eax
lar ecx,ax
shr ecx,8
or ch,40h
mov ax,0009h
int 31h
jc ErrorDPMI
pop ebx
mov ax,000Ah
int 31h
jc ErrorDPMI
mov [StubInfoCsSelector],ax
mov ebx,eax
lar ecx,ax
shr ecx,8
or cl,8
mov ax,0009h
int 31h
jc ErrorDPMI
;
; Scan environment for filename
;
mov es,[StubInfoPspSelector]
mov es,[es:2Ch]
sub edi,edi
sub eax,eax
or ecx,-1
cld
EnvScan:
repne scasb ; Scan for end of env var
scasb ; Last env var?
jnz short EnvScan ; Not yet, keep scanning
times 2 inc edi ; move to exe filename (argv[0])
mov edx,edi
repne scasb
mov [StubInfoEnvSize],di ; store, DJGPP crt0/crt1 use this to
; set the environment structure and
; argv[0]
;
; Try to open the .exe
;
sub ebp,ebp ; preload file offset
push ds
push es
pop ds
mov ax,3D00h
int 21h
pop ds
jc ErrorFile
;
; First header is wdosx header
;
mov ebx,eax
mov ah,3Fh
mov ecx,32
mov edx,Headers
int 21h
jc ErrorFile
;
; If it wasn't there, we didn't even come here
; Get the size of wdosx.dx
;
movzx ecx,word [Headers+2]
movzx edx,word [Headers+4]
neg ecx
shl edx,9
and ecx,511
sub edx,ecx
shld ecx,edx,16
mov ebp,edx ; preserve this
mov ax,4200h
int 21h
jc ErrorFile
;
; Read loader header
;
mov ah,3Fh
mov ecx,32
mov edx,Headers
int 21h
jc ErrorFile
;
; This one should also cause no error...
; Get loader size and seek right behind the loader
;
mov edx,[Headers+16]
add edx,2Ch
add edx,ebp ; add wdosx.dx size
shld ecx,edx,16
mov ebp,edx ; preserve this
mov ax,4200h
int 21h
jc ErrorFile
;
; Read loader header
;
mov ah,3Fh
mov ecx,32
mov edx,Headers
int 21h
jc ErrorFile
;
; This one should also cause no error...
; Get loader size and seek right behind the loader
;
movzx ecx,word [Headers+2]
movzx edx,word [Headers+4]
neg ecx
shl edx,9
and ecx,511
sub edx,ecx
add edx,ebp ; add wdosx.dx size
shld ecx,edx,16
mov ebp,edx ; preserve this
mov eax,4200h
int 21h
jc ErrorFile
;
; Now (hopefully) pointing to coff header, so load this
;
openWfse:
mov edx,Headers
mov ecx,CoffHeader.Size
mov ah,3Fh
int 21h
jc ErrorFile
cmp eax,ecx
jnz ErrorFormat
;
; COFF header sucked in, verify that it is a coff and executable
;
cmp [Headers+CoffMagic],014Ch
jnz ErrorFormat
cmp [Headers+AoutMagic],010Bh
jnz ErrorFormat
;
; Get overall memory to allocate
;
push ebx ; save file handle
mov ecx,[Headers+BsssSection+SectionVAddr]
add ecx,[Headers+BsssSection+SectionSize]
add ecx,$FFFF
sub cx,cx
shld ebx,ecx,16
mov [StubInfoInitialSize],ecx
mov eax,0501h
int 31h
jc ErrorMem
;
; Start address in bx:cx, handle in si:di
;
mov word [StubInfoMemoryHandle+0],di
mov word [StubInfoMemoryHandle+2],si
push ebx
push ecx
;
; Time to get some selectors
;
sub eax,eax
mov ecx,2
int 31h
jc ErrorDPMI
mov ebx,eax
;
; Set base + limit
;
mov ax,0008h
stc
sbb ecx,ecx
sbb edx,edx
int 31h
jc ErrorDPMI
pop edx
pop ecx
mov ax,0007h
int 31h
add ebx,8
mov ax,0007h
int 31h
jc ErrorDPMI
stc
sbb ecx,ecx
sbb edx,edx
mov ax,0008h
int 31h
jc ErrorDPMI
;
; Set access rights
;
lar cx,bx
mov cl,ch
and cl,60h
or cl,92h ; data
mov ch,$C0
mov ax,9
int 31h
jc ErrorDPMI
mov es,ebx
mov ax,3
int 31h
sub ebx,eax
mov ax,9
or cl,9Ah ; code
int 31h
jc ErrorDPMI
;
; Zero out the memory
;
sub eax,eax
sub edi,edi
mov ecx,[StubInfoInitialSize]
shr ecx,2
rep stosd
;
; Load text section
;
xchg ebx,[esp] ; code selector on stack, handle back
push [Headers+AoutEntry] ; retf will launch the app
mov edx,[Headers+TextSection+SectionFOfs]
add edx,ebp
mov ecx,edx
shr ecx,16
mov ax,4200h
int 21h
jc ErrorFile
mov ecx,[Headers+TextSection+SectionSize]
mov edx,[Headers+TextSection+SectionVAddr]
mov ah,3Fh
push ds
push es
pop ds
int 21h
pop ds
jc ErrorFile
;
; Load data section
;
mov edx,[Headers+DataSection+SectionFOfs]
add edx,ebp
mov ecx,edx
shr ecx,16
mov ax,4200h
int 21h
jc ErrorFile
mov ecx,[Headers+DataSection+SectionSize]
mov edx,[Headers+DataSection+SectionVAddr]
mov ah,3Fh
push ds
push es
pop ds
int 21h
pop ds
jc ErrorFile
mov ah,3Eh
int 21h
push es
;
; Copy the Stub info to the low memory block
;
cld
mov es,[StubInfoDsSelector]
sub esi,esi
sub edi,edi
mov ecx,[StubInfoSize]
rep movs byte [es:edi],[ds:esi]
;
; FS: fake loader segment, DS: main app segment, ES: PSP
;
push es
pop fs
mov es,[StubInfoPspSelector]
pop ds
;
; Under Wudebug, the jump below will generate a GPF, thus signalling the end
; of the loading process.
;
jmp pword [cs:esp]
Headers:rb CoffHeader.Size
|