_extasy's DllLord, Tutorial by Crudd
_extasy's DllLord
Tut by Crudd
Tools:
Disassembler (i used IDA 4.04 and w32dasm, but either one is suffient)
SoftIce (for debugging our code)
MASM (for our loader)
Some Friends for when you get stuck
Step 1: The dialog box...
First things first, lets take a look at our .dll and see whut we have goin on:
1000100C Entrance proc near
1000100C
1000100C arg_0 = dword ptr 8
1000100C arg_4 = dword ptr 0Ch
1000100C arg_8 = dword ptr 10h
1000100C
1000100C push ebp
1000100D mov ebp, esp
1000100F push [ebp+arg_4]
10001012 push 0
10001014 push 172h
10001019 push [ebp+arg_8]
1000101C call j_SendMessageA
10001021 push 0
10001023 push 0
10001025 push 173h
1000102A push [ebp+arg_8]
1000102D call j_SendMessageA
10001032 cmp eax, 0
10001035 jz short locret_1000104B
10001037 push 0
10001039 push 402020h
1000103E push 402000h
10001043 push [ebp+arg_0]
10001046 call j_MessageBoxA
1000104B
1000104B locret_1000104B: ; CODE XREF: Entrance+29j
1000104B leave
1000104C retn 0Ch
1000104C Entrance endp
1000104C
Ok, so we see we have one export that takes 3 paramaters. Lets see if we can figure out whut these paramaters are. Well arg_0 is pretty easy. Its the owner window of our messagebox. Well thats no big deal. We can just make that one NULL (no owner) or use the the handle of our dialog box, but we'll worry about this in a bit. Hmm, the other 2 args are gonna be a bit harder. Lets take a look at SendMessage in our API guide:
The SendMessage function sends the specified message to a window or windows. The function calls the window procedure for the specified window and does not return until the window procedure has processed the message. The PostMessage function, in contrast, posts a message to a thread’s message queue and returns immediately.
LRESULT SendMessage(
HWND hWnd, // handle of destination window
UINT Msg, // message to send
WPARAM wParam, // first message parameter
LPARAM lParam // second message parameter
);
Now we see that 172h and 173h are our messages, so lets dig out our windows.inc file and see whut messages they are. Well 172h is STM_SETIMAGE and 173h is STM_GETIMAGE. Lets take a quick look at our APIs again to see whut it has to say about them:
An application sends an STM_SETIMAGE message to associate a new image (icon or bitmap) with a static control.
STM_SETIMAGE
wParam = (WPARAM) fImageType; // image-type flag
lParam = (LPARAM) (HANDLE) hImage; // handle of the image
Parameters
fImageType
Value of wParam. Specifies the type of image to associate with the static control. This parameter can be one of the following values:
IMAGE_BITMAP
IMAGE_CURSOR
IMAGE_ENHMETAFILE
IMAGE_ICON
hImage
Value of lParam. Identifies the image to associate with the static control.
Im not gonna paste STM_GETIMAGE, its basically the oppisite. Note that both return 0 if they fail.
Now we can see whut our other 2 args are gonna be: arg_4 is the handle of our bitmap (itworks.bmp) and arg_8 is the handle of the picture box that is gonna hold our .bmp. So lets code ourselves a little dialog box program and see whut we can get going on.
Step 2: Coding the loader, Part 1...
First thing we're gonna need to do is to edit our resources. I did this in notepad with a little help from the ppl in #win32asm. You can check out the source to see how i did it. Its pretty self explanitory so i wont go over it. This was the first time i ever screwed around with bitmaps so i spent quite awhile trying to figure out whut was going on. I kept trying to use the Dialogs handle to display the .bmp but then noptical told me i needed to make a pitcure box. I didnt know whut the hell this was, so if you dont either thats the control in the dialog in the .rc file. Now that we have a dialog and a box for the picture lets code a little program to see if we can get this working. We wont worry about the messagebox yet, lets just focus on the .bmp.
After a bit of screwing around with the wrong API's or the wrong params being passed to those API's i figured it out. This is how we get the .bmp working:
invoke LoadBitmap,hInstance,IDB_MAIN ;Loads our bitmap
mov hBitmap,eax ;Save the Handle
invoke GetDlgItem,hWnd,65535 ;Get the handle of our picturebox
mov hPic,eax ;Save it
invoke LoadLibraryA,ADDR LibName ;Load our dll
invoke GetProcAddress,eax,ADDR FuncName ;Get the offset of our Exported function (Entrance)
mov OurFunc,eax ;Save it
push hPic ;Picturebox handle (arg_8 in our dll)
push hBitmap ;Bitmap handle (arg_4 in our dll)
push hWnd ;Our dialog handle (arg_0 in our dll)
call OurFunc ;Call 'Entrance' from our dll
Now it works. The messagebox pops up with some garabage, but we'll fix that in the next step.
Step 3: Coding the loader, Part 2...
Yeah, more shit i dont know how to do. Now, look back up at our exported function in our dll. Ok, the message we have to put in the box is at 402000 and the title is at 402020. It turns our that the message we are suppose to put in there fits perfectly and the title is directly after it. That means we can just patch one time and have them both ready. Heres my message: Mess db "Yes, you made it work ! Cool !",0,"Crudd Rules!",0
Cool, we set the title and the message with one string now lets process patch this into our program. It looks like this:
invoke GetCurrentProcessId ;Get our ID
invoke OpenProcess,PROCESS_ALL_ACCESS,FALSE,eax ;Open it for everything
mov PId,eax ;Our handle
invoke WriteProcessMemory,PId,402000h,ADDR Mess,45,ADDR count ;Write it
Compile it, run it, and Boom it looks like it worked. Now just close it and... shit, it crashes. WTF? Well, after stepping through with Soft-Ice we will notice that the offset we copied over is our imports and it crashes our program. So we gotta save the address of the offsets we need. It turns out after the call to _extasy's dll all we need are User32!EndDialog and Kernal32!ExitProcess. Heres the code to get them:
invoke LoadLibraryA,ADDR K32 ;Get Kernal32.dll
mov _K32,eax ;Save the handle
invoke LoadLibraryA,ADDR U32 ;Get User32.dll
mov _U32,eax ;Save it
invoke GetProcAddress,_K32,ADDR ExitProcess_ ;Get ExitProcess
mov _ExitProcess,eax ;Save
invoke GetProcAddress,_U32,ADDR EndDialog_ ;Blah,
mov _EndDialog,eax ;Blah
invoke FreeLibrary,ADDR _K32 ;Unload the dll's
invoke FreeLibrary,ADDR _U32 ;Geuss
Now we just change our invoke EndDialog,hWnd,0 to:
push 0
push hWnd
call _EndDialog
and ExitProcess to:
push eax
call _ExitProcess
Save, compile, run. Bask in your glory. Email _extasy and tell him to write another damned reme cause this one is over. Sources are included uncommented :) in source.zip.
Greets: Muad'Dib, SantMat, Sheep140 and all of [CrEaM], Optical, extasy, all of the Immortal Descendants for thier great work, anyone who has helped me along the way, L!m!t and all of [TeX],
anyone i forgot (sorry) and anyone who reads this.
Thanks to: Beer, SantMat and noptical for help along the way, _extasy for another great reme, and of course you.
Mail me at: crudd@cruddco.com
Or check out:
crudd.re
Sources, binaries, and everything else
here