0% found this document useful (0 votes)
33 views

Sant Openme

The document provides instructions for reversing an executable called openme.exe by modifying its PE header and adding code before the first section. It describes adding code to call functions to get the process handle and load a custom DLL. The DLL uses WriteProcessMemory to inject code into openme.exe that will call functions in the DLL. These functions read a saved file to check checkboxes in the GUI based on its contents.

Uploaded by

John Longbeard
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
33 views

Sant Openme

The document provides instructions for reversing an executable called openme.exe by modifying its PE header and adding code before the first section. It describes adding code to call functions to get the process handle and load a custom DLL. The DLL uses WriteProcessMemory to inject code into openme.exe that will call functions in the DLL. These functions read a saved file to check checkboxes in the GUI based on its contents.

Uploaded by

John Longbeard
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 5

Lets get to reversing this thing :)

AND remember, if you dont understand something, email me at


[email protected]

********************
*Publishers Note
********************
The total package of this essay can be downloaded at:
http://www.immortaldescendants.org/database/extasy/solutions/sant_openme.zip

********************
*Intro
********************

Extasy was nice enough to give us some instructions and "rules" to abide by:
""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
It's not really an easy one as you need to understand and inverse the processus of
the save of a file,
to be able to implement the open of it :). But, as it will be easy for you all, i
decided to complicate things a bit.
Here are the good news :

1) You can modify *ONLY* the PE of the file, more exactly just everything before
the first section.

HINTS:
-- You can do what you want at runtime, so, have fun with
WriteProcessMemory :)
-- if you invoke GetCurrentProcessId, then you have a valid process handle
to play with.
-- I suggest you to write a dll. :)
-- I repeat that you can play with the space between the .pe and the first
section.
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
So, we have to:
1. enable the open button
2. write code for being able to interpret the saved file "save.sav"
3. only use the pe, everything before the first section
------Sounds fun!!!-------Lets get going then folks-------------------

My plan of action:
I plan on using the LoadLibraryA and GetProcAddress function that are within
openme.exe to call GetCurrentProcessId
and then pass the returned value to a function(1) within my custom made dll. The
function(1) will then use WriteProcessMemory
to add my reversed code to openme.exe so when you hit the "open" button, it will
then call function(2) from my dll.
The function(2) will then open the saved file "save.sav" and read it. While reading
it, the function will enable the correct
checkboxes within the dialog of openme.exe, according to "save.sav". So guys, seems
easy enough, right!?

********************
*Tools used
********************
1. Hiew - for everything!!
2. masm32 - for the dll
3. wdasm - for this tut!
4. OpGen - for correct opcodes for the jumps :)

********************
*Reversing Session
********************

The first thing I did was to add the code before the first section,
starting at offset 240:
push 0040315A <- "kernel32.dll"
call d,[0040308C] <- call to LoadLibraryA
push 00400279 <- "GetCurrentProcessId"
push eax <- returned value from LoadLibraryA
call d,[00403078] <- call to GetProcAddress
call eax <- call to GetCurrentProcessId
mov edi, eax <- stores the ProcessID in edi while I call my dll function
:p
push 0040028D <- "openme.dll"
call d,[0040308C] <- call to LoadLibraryA
push 1 <- push 1, meaning function 1 :)
<- I exported my dll functions as ordinals so that
<- I only need to use numbers when calling the functions :)
push eax <- returned value from LoadLibraryA
call d,[00403078] <- call to GetProcAddress
push edi <- the ProcessID, remember? :)
call eax <- call to 1 , which is the first function in my dll :)
mov eax, 401000 <- Store the programs real entry point
jmp eax <- jmp to the real entry point :)

I added two of the strings above, directly after the code above, they are:
"GetCurrentProcessId" at offset 279
"openme.dll" at offset 28D

After adding the code, I changed the entry point of the program to 240 by changing
the hex at offset A7 from 0010000
to 40020000. easy enough.

Well, that being done, lets move on to the dll an how I developed it.

Before going into the dll's code, understand this:


I wrote all the code that I was going to use WriteProcessMemory with ahead of time
into the program. This was done to
make life easier. And it is much smarter :). Of course, I did this to a copy of
openme.exe, for it would break extasy's
rules if I left it in there :). Here is the explanation. I found the code that
checks if the "open" button is hit at 401088:
:00401082 0F8508010000 jne 00401190
:00401088 6683F875 cmp ax, 0075 <-As you can see, this is it!!!
:0040108C 7505 jne 00401093
:0040108E E9F1000000 jmp 00401184
:00401093 6683F876 cmp ax, 0076
:00401097 7547 jne 004010E0
So what I did was replace the code at 401088 with:
:00401088 E943100000 jmp 4020D0 <-jumps to my code <--***see "below"***
:0040108D 90 nop <-not really needed :p
The hex code right above will be used with WriteProcessMemory!! - Understand!!!
ALSO take note of the two instructions I replaced and also the "jmp 401184" at
address 40108E, for we will need to replace
these at our new code location!

******this is "below" :)
I found free space in the .data section, 200(RawSize)-0CC(VirtualSize)=134(free
space). The raw offset for .data is 400, so
my free space starts at 400(offset)+0CC(VirtualSize)=4CC and since the Virtual
offset is 2000, my code would start at 4020CC.
That being found out, I just started my code at 4020D0 for neatness! - So my code
starts at raw offset 4D0!! - Get it!?
One more thing, since we are planing on having code in the .data section, I had to
change the characteristics of that section.
To do this, just goto .data's section header that is within the pe and change its
characteristics from C0000040 to E0000020 :)
- or use a program to help you :p
******

Here is my new code at 4020D0:


:004020D0 6683F875 cmp ax,075 <- I replaced these
:004020D4 0F85B9EFFFFF jne 401093 <- two from above!!
:004020DA 688D024000 push 40028D <- "openme.dll"
:004020DF FF158C304000 call d,[40308C] <- call to LoadLibraryA
:004020E5 6A02 push 2 <- for function 2 :)
:004020E7 50 push eax <- returned value from LoadLibraryA
:004020E8 FF1578304000 call d,[403078] <- call to GetProcAddress
:004020EE FFD0 call eax <- call function 2 from openme.dll
:004020F0 E98FF0FFFF jmp 401184 <- this is another instruction
<- I told you to remember from above
<- It puts the program back into flow.
The hex code right above will also be used with WriteProcessMemory!! -
Understand!!!

Check this out, the above two sets of code will be added to the correct locations
by way of using the hex of the code and
the starting addresses using WriteProcessMemory. It is very simple.

The last thing needed before going into the dll is an understanding of the saved
file's structure, so that we can read it
correctly and fill in the correct checkboxes :)
Below is some code I got from openme.exe which will help you understand the
structure:
:004010B7 6A00 push 00000000
:004010B9 6898204000 push 00402098
:004010BE 6A24 push 00000024 <-Read a total of 24h bytes
:004010C0 68A8204000 push 004020A8 <-starting buffer for WriteFile
:004010C5 FF359C204000 push dword ptr [0040209C]
:004010CB E806010000 Call 004011D6 <- KERNEL32.WriteFile, Ord:02B9h
:004010D0 FF359C204000 push dword ptr [0040209C]
:004010D6 E8D1000000 Call 004011AC <- KERNEL32.CloseHandle, Ord:0019h
:004010DB E9A4000000 jmp 00401184
:004010E0 6683F865 cmp ax, 0065 <-if checkbox 65 is hit,
:004010E4 750C jne 004010F2
:004010E6 8335A820400001 xor dword ptr [004020A8], 00000001 <-do this!!!
:004010ED E992000000 jmp 00401184
:004010F2 6683F866 cmp ax, 0066 <-if checkbox 65 is hit,
:004010F6 750C jne 00401104
:004010F8 8335AC20400001 xor dword ptr [004020AC], 00000001 <-do this!!!
:004010FF E980000000 jmp 00401184
As you can see from the above code, when the user hits a checkbox, say 65, and sees
the check, there will be 00000001
at address 4020A8. And if they click the same checkbox again and there is no check,
there will be 00000000 at address 4020A8.
This goes for all the checkboxes. And you can see from WriteFile that is starts at
address 4020A8 and uses that to write 24h
bytes into "save.sav". AND (24h bytes total)/(9 checkboxes)=4 bytes for each
checkbox. So what is being written to save.sav
is the status of the button!! In a DWORD!! So all we have to do to reverse this is
read the "save.sav" file 4 bytes at a
time(a DWORD) and if is a 1, we have to give the according checkbox a check, and if
0, we have to uncheck the checkbox.
We do this 9 times so that all the checkboxes are covered :)

************The dll
Below I have included the partial sources for the dll, so that I can comment them
for you :)
The FULL SOURCES are in openme.asm and openme.def AND they have ALL the necessary
info to understand my dll.
********************
**************
first function:
**************
invoke OpenProcess, PROCESS_ALL_ACCESS, 0, PID <-Open the process to get it's
handle
mov process_Handle, eax <-store handle
invoke WriteProcessMemory, process_Handle,\ <-writes my jmp replacing code into
401088h ,OFFSET jmp_replacer, 6h, 0 <-address 401088, remember from
above??
invoke WriteProcessMemory, process_Handle,\ <-writes my function 2 calling code
into
4020D0h ,OFFSET open_code, 25h, 0 <-address 4020D0, remember from
above??
ret
**************
second function:
**************
invoke CreateFile,OFFSET FileName,GENERIC_READ,NULL,\ <-Opens
NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL <-"save.sav"
mov hFile,eax <-stores handle
cmp eax, -1 <- was file there and did it open right?
jne itsok <-if so, jump down a bit
invoke MessageBoxA, NULL, OFFSET msg_text, OFFSET msg_caption, NULL <-if not,
tell us
ret <-leave dll
itsok: <-that was a nice jump :p
invoke SetFilePointer,hFile,0,NULL,FILE_BEGIN <- Sets the file pointer at the
start of file
mov keepcount, 65h <-starting ID for the checkboxes - there are 9 in total
AndAgain:
invoke ReadFile,hFile,OFFSET button_state,\ <-read 4 bytes from file
4h,OFFSET BytesReadWrite,NULL <-and put it in button_state
.if button_state==1
invoke SendDlgItemMessage,dword ptr [ebp+08],\ <-Check the checkbox at
id=keepcount
keepcount,BM_SETCHECK,BST_CHECKED,0 <-if button_state=1
.else
invoke SendDlgItemMessage,dword ptr [ebp+08],\ <-Uncheck the checkbox at
id=keepcount
keepcount,BM_SETCHECK,BST_UNCHECKED,0 <-if button_state=0
.endif
add keepcount, 1h <- increase it by 1 - to next checkbox ID
cmp keepcount, 6Eh <- Are we done yet?
jb AndAgain <- if not done with all checkboxes yet, do it again :)
invoke CloseHandle,hFile <- Close the files handle
ret <-leave dll

Check out the dll, whatever you don't understand, just email me at
[email protected]!!!

********************
*Greetings, Finale
********************

Well, I hope you got something from this tutorial. I really do. Why else would I
have
written it? :)

I would love to hear any questions or comments you have on this tutorial. You can
send
them to [email protected]

Greets to all the reversers out there!

Greets to all I know!!, you know who you are :)

� forever by SantMat of the Immortal Descendants.

You might also like