3.Essay
(steps)
|
Let's
start by adding a new section to our exe, let's call it '.tank_'.
Use Sadd to do this. But hey, what happens !? (The exe gets smaller
????) So, the exe header must be a little bit tampered with I think.
Take a look at the .rsrc section details in PEBuild. It starts at
1400 and ends at 5908 (hex). that means a difference of 4508 (actual
size of section). But the Virtual and Phisical Size of the section
are 62C. Let's change that to 4508. Now try again to add the '.tank_'
section. Voila, the file size is more like it.
Now, at this point take a look at both the exe and the dll, so that
you can get the idea on how to start. I will tell you what I have discovered.
Here is where the exe loads the functions from the dll.
00401380 push offset aString_dll ; "String.dll"
00401385 call _LoadLibraryA@4
0040138A mov ds:MyDLL, eax
0040138F cmp ds:MyDLL, 0
00401396 jnz short loc_4013B8
00401398 push 0
0040139A push offset Title ; "Crudd's String Manipulator"
0040139F push offset aANeededDllCoul
; "A needed DLL could not be loaded."
004013A4 push [ebp+hDlg]
004013A7 call _MessageBoxA@16
004013AC push 0
004013AE push [ebp+hDlg]
004013B1 call _EndDialog@8
004013B6 jmp short loc_40140C
004013B8 push offset aCut_his_dick_o ; "Cut_his_dick_off"
004013BD push ds:MyDLL
004013C3 call _GetProcAddress@8
004013C8 mov ds:CutIt, eax
004013CD push offset aSomeone_bit_me ; "Someone_BIT_me"
004013D2 push ds:MyDLL
004013D8 call _GetProcAddress@8
004013DD mov ds:BiteIt, eax
004013E2 push offset aSo_byte_him_ba ; "So_BYTE_him_back"
004013E7 push ds:MyDLL
004013ED call _GetProcAddress@8
004013F2 mov ds:ByteIt, eax
004013F7 push offset aYoure_worthles ; "Youre_worthless_anyway"
004013FC push ds:MyDLL
00401402 call _GetProcAddress@8
00401407 mov ds:Worthless, eax
Now, by looking at the dll we realise that:
1. Someone_BIT_me does the ROL part
2. So_BYTE_him_back does the XOR part
3. Youre_worthless_anyway displays the 2 messageboxes
4. Cut_his_dick_off does some variable initialisation that ROL and
XOR need.
Now, we realise that our dll actually needs to export 5 functions
( Someone_BIT_me, So_BYTE_him_back and Youre_worthless_anyway from
the original exe and our functions for ROL and NOT).
Therefore, the original exe importing only 4 functions, we need to
add one by altering the code. First look in the exe for 'string.dll'
and replace it with 'tank.dll' (the name of our dll)
We will call our 5 functions in the DLL f_CUT f_ROL f_ROR f_NOT f_XOR.
Replace the original names in the exe at .4040DF with these strings.
I did it like this:
004040DF aF_ror db 'f_ROR',0 ; DATA XREF: _InitializeApp+13Fo
004040E5 db 0 ;
004040E6 db 0 ;
004040E7 db 0 ;
004040E8 db 0 ;
004040E9 db 0 ;
004040EA db 0 ;
004040EB db 0 ;
004040EC db 0 ;
004040ED db 0 ;
004040EE db 0 ;
004040EF db 0 ;
004040F0 aF_not db 'f_NOT',0 ; DATA XREF: .tank:_0040B11Ao
004040F6 aF_xor db 'f_XOR',0 ; DATA XREF: _InitializeApp+12Ao
004040FC db 0 ;
004040FD db 0 ;
004040FE db 0 ;
004040FF db 0 ;
00404100 db 0 ;
00404101 db 0 ;
00404102 db 0 ;
00404103 db 0 ;
00404104 db 0 ;
00404105 db 0 ;
00404106 db 0 ;
00404107 aF_rol db 'f_ROL',0 ; DATA XREF: _InitializeApp+115o
0040410D align 4
00404110 unk_404110 db 0 ; ; DATA XREF: .tank:_0040B000o
00404111 db 0 ;
00404112 db 0 ;
00404113 db 0 ;
00404114 db 0 ;
00404115 db 0 ;
00404116 aF_cut db 'f_CUT',0 ; DATA XREF: .tank_:0040B010o
00404116 ; .tank:_0040B12Fo
0040411C db 0 ;
Also, at .4013B8 make a jump to our code which will be at .40B11A.
So, if you do that, it will look something like this:
004013B8 jmp loc_40B11A
004013BD push ds:MyDLL
004013C3 call _GetProcAddress@8
004013C8 mov ds:CutIt, eax
004013CD push offset aF_rol ; "f_ROL"
004013D2 push ds:MyDLL
004013D8 call _GetProcAddress@8
004013DD mov ds:BiteIt, eax
004013E2 push offset aF_xor ; "f_XOR"
004013E7 push ds:MyDLL
004013ED call _GetProcAddress@8
004013F2 mov ds:ByteIt, eax
004013F7 push offset aF_ror ; "f_ROR"
004013FC push ds:MyDLL
00401402 call _GetProcAddress@8
00401407 mov ds:Worthless, eax
Now, at .40B11A, enter the following code:
0040B11A push offset aF_not ; "f_NOT"
0040B11F push ds:MyDLL
0040B125 call _GetProcAddress@8 ;get f_NOT's process address
0040B12A mov ds:dword_40B1F0, eax ;store it in 40B1F00
0040B12F push offset aF_cut
; "f_CUT" -overwritten by our jump from .4013B8
0040B134 jmp loc_4013BD ;go back to main code
If you did as adviced, now when the program runs you will have the
5 functions from tank.dll ready for use.
Next step, let us change the code that shows the 2 messageboxes when
you click ROL or NOT. It's easy to find by looking in the disasm of
the file. You probably found it by now, but just in case you haven't,
I'll tell you where it is: .4015A7 for ROL and .4015C9 for NOT. So,
@.4015A7 assemble a jmp .40B01A and @.4015C9
assemble a jmp .40B05A. And starting with
.40B01A assemble:
0040B01A push 5 ;SW_SHOW
0040B01C push ds:hEdit2
0040B022 call _ShowWindow@8
0040B027 push 5 ;SW_SHOW
0040B029 push ds:hStatic1
0040B02F call _ShowWindow@8
0040B034 push 0 ;SW_HIDE
0040B036 push ds:hCB1
0040B03C call _ShowWindow@8
0040B041 push offset aNumberOfBits ; "Number of Bits:"
0040B046 push 66h ;ID of second label (get it with BRW)
0040B048 push dword ptr [ebp+8] ;application window handle
0040B04B call _SetDlgItemTextA@12 ;set the second label to "Number of Bits:"
0040B050 mov eax, 1 ;don't ask me why, just do so
0040B055 jmp loc_40163E ;go back to original code
0040B05A push 0 ;SW_HIDE
0040B05C push ds:hEdit2 ;second edit box handle
(remember, Crudd wanted us to hide second edit box when NOT is selected)
0040B062 call _ShowWindow@8 ;hide second edit box
0040B067 push 0
0040B069 push ds:hStatic1
0040B06F call _ShowWindow@8 ;hide first label
0040B074 push 0
0040B076 push ds:hCB1
0040B07C call _ShowWindow@8 ;hide checkbox
0040B081 push offset aSecondString ; "Second String:"
0040B086 push 66h
0040B088 push dword ptr [ebp+8]
0040B08B call _SetDlgItemTextA@12 ;put "Second String:" in second label
0040B090 mov eax, 1
0040B095 jmp loc_40163E ;back to original code
Now,
we have our 2 radio buttons getting things changing, we only need
to add the code for them. Therefore, we need to find the main message
loop. Again, take a good look at the dissassembly. See at .401446
that 'cmp edi,111h'. That means - compare message to WM_COMMAND,
or see if a button was clicked or smth. If so, go at .40146E. Then,
let's do that:
0040146E movzx ebx, word ptr [ebp+wParam]
00401472 cmp ebx, 1
00401475 jz short loc_401496
So, if ebx==1 (wParam of WM_COMMAND, it means control with id equal
to 1, that is if the Do it! button was pushed) go at .401496 and start
the code. Therefore, at .401496 we will jump to our code which will
check which radio button was used. So, at .401496 do a jmp
.40B0A0, and at that location assemble:
0040B0A0 push ds:hEdit1 ;handle of first textbox
0040B0A6 call _GetWindowTextLengthA@4 ;get the length of text
0040B0AB mov [ebp-4], eax ;store it in [ebp-4]
0040B0AE cmp eax, 0 ;if it is 0
0040B0B1 jz loc_4014AA ;then go to original code that displays an error message
0040B0B7 push 69h ;ID of ROL radio button
0040B0B9 push dword ptr [ebp+8] ;handle of app window
0040B0BC call _IsDlgButtonChecked@8 ;see if ROL is checked
0040B0C1 cmp eax, 0 ;see if do
0040B0C4 jnz short loc_40B0E4 ;if eax!=0, that means ROL checked go to .40B0E4
0040B0C6 push 6Ah ;same
0040B0C8 push dword ptr [ebp+8] ;for
0040B0CB call _IsDlgButtonChecked@8 ;NOT
0040B0D0 cmp eax, 0 ;if NOT isnt selected
0040B0D3 jz loc_4014C2 ;return to normal program flow
0040B0D9 call ds:dword_40B1F0 ;if it is call the function we have stored in .40B1F0
0040B0DF jmp loc_401639 ;return to normal program flow
0040B0E4 call ds:Worthless ;call f_ROL in tank.dll
0040B0EA jmp loc_401639 ;return to normal program flow
Well, that's about it for the exe, we now need to code the dll, and
we're all set. |