Reverse Engineering and Malware Analysis

by crudd

start:
call [words]
cmp rax, [challenges]
jz [tools]
mov rax, [links]
ret
_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