This is the full code of loaddll.exe.
It can be compiled using Borland's TASM32 with following commands:
tasm32
-mx
-zi -m5 loaddll.asm,,loaddll.lst
tlink32 -v-
-c -S:40000 -B:400000 -Tpe -aa -m loaddll,,,import32.lib
brc32
loaddll.rc -feloaddll.exe
LOADDLL.ASM:
P586
; 32-bit instructions used!
MODEL FLAT,PASCAL
IDEAL
; I really like it!
LOCALS
PUBLICDLL WndProc,Firstbp,Prepatch,CallDLL,Finished;
PUBLICDLL Patcharea,Endpatch
PUBLICDLL Arg1,Arg2,Arg3,Arg4,Arg5,Arg6,Arg7,Arg8,Arg9,Arg10
SEGMENT _DATA1 PARA PUBLIC USE32 'DATA'
; Text below is a keyphrase used by OllyDbg to verify that LoadDll
; is correct. Loads at fixed address 00420000. Never change! Note
; how coward I am: you cannot replace copyright, otherwise this code
; will not work!
DB "DLL Loader (C) 2004 Oleh Yuschuk"
; Link area. Never change the meaning or order of next 32 dwords!
ERRMSG
DD
0
; Pointer to error
HINST
DD
0
; Process instance
HWND
DD
0
; Handle of main window
DLLBASE
DD
0
; Base address of loaded DLL or NULL
DD OFFSET
Firstbp ;
Address of first breakpoint
DD OFFSET
Prepatch ;
Address of patch area before call
DD OFFSET
Arg1
; Base of 10 arguments x 1024 bytes
DD OFFSET
Finished ;
Address of breakpoint after call
DUMMY
DD 4
DUP(0)
; Reserved for the future
PROCADR
DD
0
; Address of procedure, starts execution
REGEAX
DD
0
; Register arguments
REGECX
DD 0
REGEDX
DD 0
REGEBX
DD 0
REGESI
DD 0
REGEDI
DD 0
NARG
DD
0
; Number of arguments to push on stack
ARGLIST
DD 10
DUP(0)
; DLL argument list
ESPDIFF
DD
0
; Difference in ESP caused by code
DD
0
; Reserved for the future
WCLASS
= THIS
DWORD
; Hand-made WNDCLASS structure
DD
0000002Bh
; CS_HREDRAW|VREDRAW|DBLCLKS|OWNDC
DD
WndProc
; Window procedure
DD
0
; Class extra bytes
DD
0
; Window extra bytes
WCINST
DD
0
; Instance
WCICON
DD
0
; Icon
HCURS
DD
0
; Cursor
HBGND
DD
0
; Background brush
DD
0
; No menu
DD
CLSNAME
; Class name
MSG
= THIS
DWORD
; Hand-made MSG structure
DD 0
; Handle of window
MSGID
DD
0
; Message ID
DD
0
; wParam
DD
0
; lParam
DD
0
; Timestamp
DD
0
; X coordinate
DD
0
; Y coordinate
PSTRUCT
= THIS
DWORD
; Hand-made PAINTSTRUCT structure
DD
0
; HDC
DD
0
; fErase
DD
0
; rcPaint.left
DD
0
; rcPaint.top
DD
0
; rcPaint.right
DD
0
; rcPaint.bottom
DD
0
; fRestore
DD
0
; fIncUpdate
DB 32
DUP(0)
; rgbReserved
ORIGESP
DD
0
; Original ESP before call
ORIGEBP
DD
0
; Original EBP before call
EXPESP
DD
0
; Expected ESP after call (C)
WNDNAME
DB "OllyDbg DLL Loader",0
CLSNAME
DB "LoadDLLClass",0
ICONAME
DB
"MAINICON",0
; Green smashed bug - igitt!
E_NONAM
DB "Missing DLL name",0 ; Error notifications
to OllyDbg
E_NODLL
DB "Unable to load DLL",0
E_NPARM
DB "Too many parameters",0
ALIGN 16
Arg1
DB 1024 DUP
(?)
; Area for 10 memory arguments, 1 k each
Arg2
DB 1024 DUP (?)
Arg3
DB 1024 DUP (?)
Arg4
DB 1024 DUP (?)
Arg5
DB 1024 DUP (?)
Arg6
DB 1024 DUP (?)
Arg7
DB 1024 DUP (?)
Arg8
DB 1024 DUP (?)
Arg9
DB 1024 DUP (?)
Arg10
DB 1024 DUP (?)
ENDS _DATA1
SEGMENT _TEXT1 PARA PUBLIC USE32 'CODE'
EXTRN GetModuleHandleA: PROC
EXTRN GetCommandLineA: PROC
EXTRN
LoadIconA:
PROC
EXTRN
LoadCursorA: PROC
EXTRN GetStockObject: PROC
EXTRN RegisterClassA: PROC
EXTRN CreateWindowExA: PROC
EXTRN DestroyWindow: PROC
EXTRN PostQuitMessage: PROC
EXTRN
ShowWindow:
PROC
EXTRN
Sleep:
PROC
EXTRN
BeginPaint:
PROC
EXTRN
EndPaint:
PROC
EXTRN DefWindowProcA: PROC
EXTRN LoadLibraryA: PROC
EXTRN PeekMessageA: PROC
EXTRN TranslateMessage: PROC
EXTRN DispatchMessageA: PROC
EXTRN
ExitProcess: PROC
; Window procedure of main LoadDLL window.
PROC WndProc
ARG LP:DWORD,WP:DWORD,MS:DWORD,HW:DWORD
PUSH EDX
PUSH EDI
PUSH ESI
MOV EAX,[MS]
CMP
EAX,0001h
; WM_CREATE
JE RET0
CMP
EAX,0002h
; WM_DESTROY
JNE @@080
PUSH 0
CALL PostQuitMessage
JMP RET0
@@080:
CMP
EAX,000Fh
; WM_PAINT
JNE @@100
PUSH OFFSET PSTRUCT
PUSH [HW]
CALL BeginPaint
PUSH OFFSET PSTRUCT
PUSH [HW]
CALL EndPaint
JMP RET0
@@100:
CMP
EAX,0010h
; WM_CLOSE
JNE @@200
PUSH [HW]
CALL DestroyWindow
JMP RET0
@@200:
; None of listed above, pass to DefWindowProc().
PUSH [LP]
PUSH [WP]
PUSH [MS]
PUSH [HW]
CALL DefWindowProcA
JMP RETA
RET0:
XOR EAX,EAX
JMP SHORT RETA
RET1:
MOV EAX,1
RETA:
POP ESI
POP EDI
POP EDX
RET
ENDP WndProc
START:
MOV
EBP,ESP
; Here execution begins
PUSH 0
CALL GetModuleHandleA
MOV [DWORD DS:WCINST],EAX
MOV [DWORD DS:HINST],EAX
CALL GetCommandLineA ; Path
to LOADDLL is taken into quotes
MOV ESI,EAX
INC
ESI
; Skip first quote
@@10:
MOV AL,[BYTE DS:ESI] ; Skip path to
LOADDLL.EXE
INC ESI
OR AL,AL
JNE @@12
MOV [DWORD DS:ERRMSG],OFFSET E_NONAM
JMP ERROR
@@12:
CMP AL,'"'
JNE @@10
@@20:
MOV AL,[BYTE DS:ESI] ; Skip spaces
CMP AL,' '
JNE @@30
INC ESI
JMP SHORT @@20
@@30:
PUSH ESI
CALL
LoadLibraryA
; Load DLL
OR EAX,EAX
JNE @@32
MOV [DWORD DS:ERRMSG],OFFSET E_NODLL
JMP ERROR
@@32:
MOV [DWORD DS:DLLBASE],EAX
PUSH OFFSET ICONAME
PUSH [DWORD DS:HINST]
CALL LoadIconA
MOV [DWORD DS:WCICON],EAX
PUSH
7F88h
; IDC_NO
PUSH
0
; External resource
CALL LoadCursorA
MOV [DWORD DS:HCURS],EAX
PUSH
0
; WHITE_BRUSH
CALL GetStockObject
MOV [DWORD DS:HBGND],EAX
PUSH OFFSET WCLASS
CALL RegisterClassA
PUSH
0
; Parameters: none
PUSH [DWORD DS:HINST] ; Instance
PUSH
0
; Menu: none
PUSH
0
; Parent window: none
PUSH
100
; Width
PUSH
200
; Height
PUSH
80000000h
; CW_USEDEFAULT
PUSH
80000000h
; CW_USEDEFAULT
PUSH
10CF0000h
; WS_OVERLAPPEDWINDOW|WS_VISIBLE
PUSH OFFSET WNDNAME ;
Window name
PUSH OFFSET CLSNAME ;
Class name
PUSH
0
; Extended style: none
CALL CreateWindowExA
MOV [DWORD DS:HWND],EAX ; Save handle
PUSH
9
; SW_RESTORE
PUSH EAX
CALL ShowWindow
Firstbp:
NOP
; First breakpoint is set here
WINLOOP:
CMP [DWORD DS:PROCADR],0 ; Request to call some function?
JE NOCALL
MOV [DWORD DS:ORIGESP],ESP
MOV [DWORD DS:ORIGEBP],ESP
PUSH
0
; Security buffer (16 doublewords)
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
PUSH 0
MOV ECX,[DWORD DS:NARG]
JECXZ @@44
CMP ECX,10
JBE @@40
MOV [DWORD DS:ERRMSG],OFFSET E_NPARM
JMP ERROR
@@40:
MOV EAX,OFFSET ARGLIST
@@42:
PUSH [DWORD EAX] ; Push requested number
of arguments
ADD EAX,4
LOOP @@42
@@44:
MOV [DWORD DS:EXPESP],ESP ; Expected ESP after return (C)
MOV EAX,[DWORD DS:REGEAX] ; Preset registers
MOV ECX,[DWORD DS:REGECX]
MOV EDX,[DWORD DS:REGEDX]
MOV EBX,[DWORD DS:REGEBX]
MOV ESI,[DWORD DS:REGESI]
MOV EDI,[DWORD DS:REGEDI]
Prepatch:
NOP
; Patch area before call
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
CallDLL:
CALL [DWORD DS:PROCADR] ; Call DLL function
NOP
; Patch area after call
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
NOP
MOV [DWORD DS:REGEAX],EAX ; Get modified registers
MOV [DWORD DS:REGECX],ECX
MOV [DWORD DS:REGEDX],EDX
MOV [DWORD DS:REGEBX],EBX
MOV [DWORD DS:REGESI],ESI
MOV [DWORD DS:REGEDI],EDI
MOV EAX,ESP
SUB EAX,[DWORD DS:EXPESP]
MOV [DWORD DS:ESPDIFF],EAX
MOV EBP,[DWORD DS:ORIGEBP]
MOV ESP,[DWORD DS:ORIGESP]
MOV [DWORD DS:PROCADR],0 ; Confirm execution
NOP
Finished:
INT
3
; Pause after execution
NOP
NOCALL:
PUSH 0
CALL
Sleep
; Be fair to other applications
PUSH
1
; PM_REMOVE
PUSH
0
; Process all messages
PUSH 0
PUSH
0
; Any window
PUSH OFFSET MSG
CALL PeekMessageA
OR EAX,EAX
JZ WINLOOP
PUSH OFFSET MSG
CALL TranslateMessage
PUSH OFFSET MSG
CALL DispatchMessageA
MOV EAX,[DWORD DS:MSGID]
CMP
EAX,12h
; WM_QUIT
JNE WINLOOP
PUSH 0
CALL
ExitProcess
; Hasta la vista!
ERROR:
PUSH
00001001h
; Special return code, means error
CALL
ExitProcess
; Error detected
ALIGN 4
Patcharea: DB
2047
DUP(90h)
; Big patch area (2 K of NOPs)
Endpatch:
NOP
ENDS _TEXT1
END START
LOADDLL.RC:
MAINICON
ICON
// Green bug
{
'00
00 01 00 02 00 20 20 10 00 00 00 00 00 E8 02'
'00
00 26 00 00 00 10 10 10 00 00 00 00 00 28 01'
'00
00 0E 03 00 00 28 00 00 00 20 00 00 00 40 00'
'00
00 01 00 04 00 00 00 00 00 80 02 00 00 00 00'
'00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
'00
00 00 00 80 00 00 80 00 00 00 80 80 00 80 00'
'00
00 80 00 80 00 80 80 00 00 80 80 80 00 C0 C0'
'C0
00 00 00 FF 00 00 FF 00 00 00 FF FF 00 FF 00'
'00
00 FF 00 FF 00 FF FF 00 00 FF FF FF 00 00 00'
'00
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00'
'00
00 00 00 02 A0 00 00 00 00 A2 00 00 00 00 00'
'00
00 00 00 0A 20 00 00 00 0A 2A 2A 00 00 00 00'
'00
00 00 00 A2 A2 00 00 00 A2 A2 A2 00 00 00 00'
'00
00 00 00 2A 2A 00 00 0A 2A 2A 2A 00 00 00 00'
'00
00 00 00 A2 A2 00 00 A2 A2 A2 A0 00 00 00 00'
'00
00 00 00 2A 2A 00 0A 2A 2A 2A 20 00 00 02 A2'
'00
00 00 00 02 A2 A0 A2 A2 A2 A2 00 00 00 0A 2A'
'2A
2A 00 00 0A 2A 2A 2A 2A 2A 20 00 00 00 02 A2'
'A2
A2 A0 00 02 A2 A2 A2 A2 A2 00 00 00 00 0A 2A'
'2A
2A 2A 2A 2A 2A 2A 2A 2A 00 00 00 00 00 00 A2'
'A2
A2 A2 A2 A2 A2 A2 A2 00 00 00 00 00 00 00 00'
'2A
2A 2A 2A 2A 2A 2A 2A 00 00 00 00 00 00 00 00'
'00
02 A2 A2 A2 A2 A2 A2 00 00 00 00 00 00 00 00'
'00
00 0A 2A 2A 2A 2A 2A 2A 00 00 00 00 00 00 00'
'00
00 02 A2 A2 A2 A2 A2 A2 A2 A2 00 00 00 00 00'
'00
00 0A 2A 2A 2A 2A 2A 2A 2A 2A 20 00 00 00 00'
'00
00 02 A2 A2 A2 A2 A2 A2 A2 A2 A2 A2 00 00 00'
'00
00 0A 2A 2A 2A 2A 2A 00 00 2A 2A 2A 20 00 00'
'00
00 A2 A2 A0 A2 A2 A0 00 00 02 A2 A2 A0 00 00'
'00
00 2A 2A 00 0A 2A 20 00 00 00 2A 2A 20 00 00'
'00
00 00 00 00 00 A2 A0 00 00 00 00 00 00 00 00'
'00
00 00 00 00 00 2A 20 00 00 00 00 00 00 00 00'
'00
00 00 00 00 00 A2 A0 00 00 00 00 00 00 00 00'
'00
2A 20 00 00 00 2A 2A 00 00 00 00 00 00 00 00'
'A2
A2 A0 00 00 00 A2 A2 00 00 00 00 00 00 00 00'
'2A
2A 20 00 00 00 2A 2A 00 00 00 00 00 00 00 00'
'A2
A2 A0 00 00 00 02 A2 00 00 00 00 00 00 00 0A'
'2A
2A 20 00 00 00 0A 2A 00 00 00 00 00 00 00 02'
'A2
A2 00 00 00 00 00 00 00 00 00 00 00 00 00 0A'
'2A
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 FF F9'
'FF
3F FF F0 FE 0F FF F0 FC 07 FF E0 78 07 FF E0'
'70
07 FF E0 60 0F 8F E0 40 0F 00 F0 00 1F 00 70'
'00
3F 00 10 00 7F 00 00 00 FF 80 00 03 FF C0 00'
'0F
FF E0 00 03 FF FC 00 00 3F FF 00 00 1F FF 00'
'00
03 FF 00 00 01 FF 00 00 00 FE 00 0F 00 FE 04'
'0F
80 FF 0E 0F C1 FF FE 0F FF FC 7E 0F FF F0 3E'
'07
FF E0 3E 07 FF E0 3E 07 FF C0 3F 07 FF C0 3F'
'07
FF C0 7F 0F FF C0 FF FF FF E3 FF FF FF 28 00'
'00
00 10 00 00 00 20 00 00 00 01 00 04 00 00 00'
'00
00 C0 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 80 00 00 80'
'00
00 00 80 80 00 80 00 00 00 80 00 80 00 80 80'
'00
00 80 80 80 00 C0 C0 C0 00 00 00 FF 00 00 FF'
'00
00 00 FF FF 00 FF 00 00 00 FF 00 FF 00 FF FF'
'00
00 FF FF FF 00 00 00 00 00 00 00 00 00 00 00'
'00
AA 00 0A AA 00 00 00 00 AA 00 AA AA 00 00 00'
'00
AA 0A AA A0 00 0A AA 00 0A AA AA 00 00 0A AA'
'AA
AA AA 00 00 00 00 0A AA AA AA 00 00 00 00 00'
'0A
AA AA A0 00 00 00 00 0A AA AA AA AA 00 00 00'
'AA
AA AA 00 AA A0 00 00 00 00 A0 00 00 00 00 00'
'00
00 A0 00 00 00 00 0A 00 00 AA 00 00 00 00 AA'
'00
00 AA 00 00 00 00 AA 00 00 00 00 00 00 00 00'
'00
00 00 00 00 00 FC E3 00 00 F8 41 00 00 F8 01'
'00
00 88 03 00 00 00 07 00 00 00 0F 00 00 80 1F'
'00
00 E0 03 00 00 F0 01 00 00 E0 00 00 00 F0 31'
'00
00 EE 3F 00 00 86 1F 00 00 86 1F 00 00 87 3F'
'00
00 8F FF 00 00'
}