home *** CD-ROM | disk | FTP | other *** search
- Solution to douby's ReverseMe 1
- by Dracon (DREAD)
-
- Tools used:
- -----------
- * IDA 3.85 (Disassembler)
- * HIEW (hexeditor which can generate Opcodes)
- * SoftIce (to debug my new code)
- * Win32 Api reference
- * alphabetic list of important Api constants (very handy)
-
- Also usefull are:
- * SAdd (add new sections of any size to an exe)
- * ProcDump (has an integrated PE-Editor)
- * OpGen (Opcode Generator to create the opcodes for jumps from one virtual
- address to another AND it can retrieve the addresses of all imported
- windows-functions)
-
- First of all I must say that douby's idea of a "ReverseMe" is great. Adding new
- functions this way makes your best tools and programs even better. It's not easy
- though. You must know something about the PE file-format and of course win32asm.
- I also recommend that you read the essay about adding functions to Notepad by
- NeuRaL_NoiSE.
-
- The challenge was (sorted, easiest first):
- 1) Add a scrollbar to the editbox
- 2) Add the exit option to the program
- 3) Add the loading option to the program
- 4) Add the saving option to the program (easy if you solved #3)
-
- Let's start!
-
- 1. Scrollbar
- ============
-
- This one is easy. CreateWindowEx or CreateWindow are used to create an edit
- control, the one used in the ReverseMe. This is the snippet from IDA (in WDasm
- it looks the same, but without the ".text:", only the address is shown):
-
- .text:0040116D mov edx, [esp+8+HWND] ; move HWND to edx
- .text:00401171 push 0 ; pointer to some data
- .text:00401173 mov ecx, [eax+4]
- .text:00401176 push ecx ; hInstance
- .text:00401177 push 1 ; child ID
- .text:00401179 push edx ; parent window
- .text:0040117A push 0 ; initial height
- .text:0040117C push 0 ; initial width
- .text:0040117E push 0 ; initial y position
- .text:00401180 push 0 ; initial x position
- .text:00401182 push 508000C4h ; window style !!!
- .text:00401187 push 0 ; window name
- .text:00401189 push offset aEdit ; "EDIT" - class name
- .text:0040118E push 0 ; extended styles
- .text:00401190 call ds:CreateWindowExA ; Create the window
-
- Remember, all parameters are pushed in reverse order, the last one first. To get
- the scrollbars we must modify the style parameter - all styles are combined by a
- logical OR. I have already looked up the values for WS_HSCROLL (0x100000) and
- WS_VSCROLL (0x200000) for you, so we calculate:
-
- 0x508000C4 OR 0x100000 OR 0x200000 = 50B000C4
-
- file-offset 0x1182: 68 C4 00 80 50
- change to: 68 C4 00 B0 50
-
- Short test, okay, works. ;-)
-
- All constants can be found in the include files (win32.inc, user32.inc, ...) and
- someone has created html-pages with all important constants in alphabetic order
- which is VERY handy.
-
- 2. Exit menu entry
- ==================
-
- Now it's getting more difficult. If you click on a menu-entry the program will
- get a WM_COMMAND message with the id in the low-order word of WPARAM.
- Fortunately, douby decided to show us a messagebox "Nope, doesn't work yet!".
- Fine. Look for this error string and examine the code above it. I have already
- renamed some of the location and variables to make the code clearer. Other
- comments are inserted by IDA, e.g. for the switch jump:
-
- .text:004011CE WM_COMMAND_msg: ; CODE XREF: WindowProc+12
- .text:004011CE cmp esi, 7
- .text:004011D1 jz short WM_SETFOCUS_msg
- .text:004011D3 cmp esi, 111h
- .text:004011D9 jnz short DEFAULT_msg ; default
- .text:004011DB push edi
- .text:004011DC call ds:GetMenu ; Get the handle of the
- ; menu assigned to the
- ; given window
- .text:004011E2 mov eax, ebx
- .text:004011E4 and eax, 0FFFFh
- .text:004011E9 add eax, 0FFFF63BFh ; switch 5 cases
- .text:004011EE cmp eax, 4
- .text:004011F1 ja short DEFAULT_msg ; default
-
- ; ----> Important <----
- .text:004011F3 jmp ds:off_0_401260[eax*4] ; switch jump for
- ; Command IDs
-
- .text:004011FA loc_0_4011FA: ; case 0x9c41
- .text:004011FA push 0
- .text:004011FC push offset a3rr0r ; "3rr0r!"
- .text:00401201 push offset aNopeDoesnTWork ; "Nope doesn't
- ; work yet"
- .text:00401206 push edi
- .text:00401207 call ds:MessageBoxA
- .text:0040120D pop edi
- .text:0040120E pop esi
- .text:0040120F xor eax, eax
- .text:00401211 pop ebx
- .text:00401212 retn 10h
-
- Look at the line that I have marked. The next jump depends on the ID, here is
- the table for it (at location 401260):
-
- .text:00401260 dd offset loc_0_4011FA ; IDM_LOAD
- .text:00401260 dd offset DEFAULT_msg ; default
- .text:00401260 dd offset loc_0_4011FA ; IDM_EXIT
- .text:00401260 dd offset IDM_ABOUT ; IDM_ABOUT
- .text:00401260 dd offset loc_0_4011FA ; IDM_SAVE
-
- As you can see, 3 jumps go back (4011FA) and display our messagebox, one shows
- the Aboutbox and one jumps to DefWinProc. Okay, how can we know WHICH number
- belongs to the different IDs? I have already done the whole work for you: you
- can modify the jump table in that way that only ONE value will show the error
- message (0x4011FA), all others are set do DEFAULT_msg (0x403712). Run the
- program and click on the menu items. When you see the messagebox you know which
- entry in the jump table belongs to it. Got the idea? Good. Another approach
- would be to open the program with BRW (Borland Resource Workshop) and to examine
- the menu. The IDs should be right in front of you.
-
- Now you know when the user chooses "Exit" from the menu. How you exit a program?
- Very easy, you call PostQuitMessage(0). You could now add some code to do this,
- but wait a moment. There should already be a call to this function somewhere.
- Found it?
-
- .text:00401159 push 0
- .text:0040115B call ds:PostQuitMessage
- .text:00401161 pop edi
- .text:00401162 pop esi
- .text:00401163 xor eax, eax
- .text:00401165 pop ebx
- .text:00401166 retn 10h
-
- Fine, we store now this offset in the jumptable (3rd entry, file-offset 0x1268):
- FA 11 40 00 -----> 59 11 40 00
-
- I hope you know why to store the address this way. On all Intel computers, words
- and dwords will be stored with the lowest byte first:
- 00 40 11 59 -> 59 11 40 00.
-
- That's how these values are read and written from and to memory.
-
- Test it, and it works!
-
-
- 3. File loading
- ===============
-
- Now we get to the tricky parts. A filedialog should prompt the user for a file
- which will then be loaded. The problem is, the necessary API functions aren't
- included yet. We will use "GetProcAddress" to get the address of these functions
- at runtime. If the dll is already loaded (e.g. kernel32.dll for File I/O) you
- can use "GetFileModuleHandleA" to retrieve the handle. If the dll is NOT loaded
- (comdlg32.dll for the common dialogs) you will need "LoadLibraryA".
-
- An important question: where do we add our code?
-
- The (executable) code is in the "text" section of the file. Use a tool like IDA,
- PE-Browser or ProcDump to check it: Virtual Size = 0x2B3E, Section Size in File:
- 0x3000. What does this mean? Only 0x2B3E bytes are needed for the code, but
- 0x3000 bytes are reserved because of the alignment setting. Set the Virtual Size
- to 0x3000 and you have 0x4C2 (1218) bytes for your code. This should be more
- than enough! How do you change this value? Open the file with a hexeditor and
- look for "text" (offset 0x1C9). Read a good doc about the PE file header to find
- out more (Microsoft, Iczelion). The first 8 chars are reserved for the name of a
- section, after that follows the virtual size (WORD) - change it from 3E2B to
- 0030.
-
- Some more explanation:
- ProcDump is a very good tool which can modify an exe-file in different ways. It
- can change the pe-header for you. Run ProcDump, click on "PE Editor" and choose
- the ReverseMe. We are interested in the "Sections". You will get a list of all
- sections and you can right-click to edit them. The code is in the text-section.
- Two values are important: the virtual and the physical size. The physical size
- depends on the file alignment setting (Visual C++ uses 1000h, but it can be any
- multiply of 200h), the virtual size tells how much space is needed for the code
- and is important for the Windows PE-loader which loads the exe into memory and
- executes the code. If we set the virtual size to the physical one we can use the
- unused bytes for our purpose: in our case the virtual size is 0x2B3E and we can
- use the bytes from 0x2B40 (to have a rememberable value) to 0x2FFF (at 0x3000
- starts the next section) for our code.
-
- 1218 bytes are really a lot, but often you will have less, maybe too less. In
- this case you will need the program "SAdd" by NeuRaL_NoiSE. It creates, appends
- and zero pads a new section to a dll or exe, you only have to specify a name and
- the size. The only problem is that (according to NeuRal_NoiSE in his essay) HIEW
- can't assemble a jump to this section, you must use sice to get the opcodes.
- There is also a nice program, called "OpGen" by NeuRal_NoiSE himself, who can
- calculate the opcodes of every jump: you feed it with the starting and the
- ending virtual address and it will give you the opcodes. For jumps within a
- section you can use HIEW: enter "jmp xxxxxx" where xxxxxx is the PHYSICAL offset
- of the destination, don't use the virtual one here!
-
- Let's return to the ReverseMe. We need to allocate memory for a buffer to hold
- the filename and later for the whole file. If you look at the import-table of
- the exe you will find 2 functions for this task:
-
- "VirtualAlloc" reserves or commits a region of pages in the virtual address
- space of the calling process. Only whole 64k pages are allocated, so if you need
- 10 bytes you will actually get 64k. Our edit-control is (according to the
- helpfile) limited to 0xFFFF bytes (64k-1), but this is NOT true, the limit is
- smaller. You can use "EM_GETLIMITTEXT" to get the exact value, I used 60000
- which seems to be okay. Nevertheless, we will allocate 64k which are first used
- to retrieve the filename from the FileDialog and later to read the file into
- memory. The exact parameters for "VirtualAlloc" are:
-
- lpAddress: can be NULL
- dwSize: we allocate 64 kBytes
- flAllocationType: we choose MEM_COMMIT (0x1000)
- flProtect: PAGE_READWRITE (0x4) is okay
-
- When we don't need the memory anymore, it will be freed with "VirtualFree":
-
- lpAddress: the Address of our memory
- dwSize: must be 0
- dwFreeType: MEM_RELEASE (0x8000)
-
- Now we need some space for the OPENFILENAME structure. Again, we use
- VirtualAlloc to allocate the necessary memory (sizeof(OPENFILENAME) = 76 bytes)
- and later VirtualFree to free it. It's necessary to initialize the structure.
- The allocated memory contains only 0s, this saves us some typing:
-
- - size of the structure (important)
- - parent window (can be NULL, or you use [esp+10] which is the current handle,
- look below for more about it)
- - hInstance (only necessary if we use a custom template, can be 0)
- - pointer to a filter (maybe later...)
- - pointer for custom filter (not important - NULL)
- - size of custom filter (not important - NULL)
- - index of current filter (not important - NULL)
- - pointer to filename: very important, we will put our pointer here
- - size of file-buffer: use 512 bytes (200h), should be enough although we
- have allocated 64k
- - FileTitle, size of FileTitle, Initial Dir and Title can all be NULL
- - Flags: OFN_FILEMUSTEXIST (0x1000) is nice
- - the other members are also unimportant
-
- Where do we store the variables? The reference says, that only the registers
- EBX, EDI and ESI don't change if you call Win32-Api functions, all others could
- be modified. 3 registers are enough for now, but if you need more you should
- consider using the stack. We have also another option. The memory of the
- OPENFILENAME structure will be used only once, later we can use it to store our
- variables in it, e.g. if we save the offset of OPENFILENAME in esi you can use
- [esi+xx] to access the memory.
-
- Anything more? Yes, we will need the names of the functions which should be
- loaded with "GetProcAddress". I will put these zero-terminated strings at offset
- 0x3F00, you can also use the data-section for it. Do what we have done with the
- text-section: compare the virtual with the physical size, adjust the virtual one
- and you are ready to store more data in it. We have enough space, so there is no
- need for this.
-
- comdlg32.dll (virtual offset 0x403F00)
- kernel32.dll (0x403F0D)
- CloseHandle (0x403F1A)
- CreateFileA (0x403F26)
- GetOpenFileNameA (0x403F32)
- ReadFile (0x403F43)
- user32.dll (0x403F4C)
- GetDlgItem (0x403F57)
- SetWindowTextA (0x403F62)
-
- The code starts at offset 0x3B40. You can use HIEW to enter it, but be carefull
- with the calls like "VirtualAlloc". The address for these procedures must be
- looked up in the disassembled file. Search for the functions and you will see
- its addresses:
-
- VirtualAlloc: 0x00404034
- VirtualFree: 0x0040408C
- LoadLibraryA: 0x00404028
- GetProcAddress: 0x0040402C
- GetModuleHandleA: 0x00404044
-
- Another way to get these addresses is to use "OpGen" once more. Click on "Lookup
- Imports for patching" and the program will give you a list of all imported
- functions and its addresses. Now you can use them in HIEW like this:
-
- Function: VirtualAlloc
- address: 0x404034
- enter in HIEW: call d,[00404034]
-
- HIEW will show you (as a comment) that you actually call VirtualAlloc from
- Kernel32.dll. Let's have a look at the asm-code:
-
- ; Handle IDM_LOAD
- : starting at offset 0x3B40
- ;
- ; allocate memory for filename buffer
- push 4 ; PAGE_READWRITE
- push 1000h ; MEM_COMMIT
- push 10000h ; 64k
- push 0 ; let Windows decide
- call VirtualAlloc
- mov edi, eax ; store pointer in edi
-
- ; allocate memory for OPENFILENAME
- push 4
- push 1000h
- push 4Ch ; 76 bytes
- push 0
- call VirtualAlloc
- mov esi, eax ; store pointer in esi
-
- ; initialize the important members
- mov [esi], 4Ch ; size of structure
- mov eax, [esp+10h] ; this is the parent HWND
- mov [esi+4], eax
- mov [esi+1Ch], edi ; pointer to filename buffer
- mov [esi+20h], 200h ; size of buffer, 200h is enough
- mov [esi+34h], 1000h ; flags: OFN_FILEMUSTEXIST
-
- ; load comdlg32.dll
- ; I don't free it, this should be done at program exit
- push 403F00h ; offset "comdlg32.dll"
- call LoadLibraryA
- mov ebx, eax ; store handle in ebx
-
- ; get address of GetOpenFileNameA
- push 403F32h ; offset "GetOpenFileNameA"
- push ebx ; dll-handle
- call GetProcAddress
-
- ; call the function, only 1 parameter
- push esi ; offset OPENFILENAME structure
- call eax ; GetOpenFileNameA
-
- ; has the user choosen a file?
- or eax, eax ; eax == 0 ?
- jz FINISH ; yes, jump to end - use 0x3DA0
-
- Wouldn't it be nice to see the filename in the titlebar? Let's do it. We will
- need the handle for "user32.dll" and the address of "SetWindowTextA" also later,
- so we store them once they are retrieved. The OPENFILENAME structure won't be
- used anymore, so we use this memory, you must only keep track where you put all
- your variables.
-
- ; get handle to "user32.dll"
- push 403F4Ch ; offset "user32.dll"
- call GetModuleHandleA
- mov [esi+20], eax ; store handle for later use
-
- ; get address of SetWindowTextA
- push 403F62h ; offet "SetWindowTextA"
- push eax
- call GetProcAddress
- mov [esi+24], eax ; store address for later use
-
- ; call function
- push edi ; should contain the filename
- push [esp+14] ; push HWND
- call eax ; SetWindowTextA
-
- The user has choosen a file and we will now open and load it. I use
- "CreateFileA" and "ReadFile", please check the doc for the exact parameters. As
- mentioned above, only about 60000 bytes will be loaded, because the edit-control
- can't show more, and even if you load this amount you won't be able to edit the
- file until you delete some text. You can use "EM_SETLIMITTEXT" to increase the
- limit to a max. of FFFFh.
-
- ; open the file
- ; get library handle for kernel32.dll
- push 403F0D ; offset "kernel32.dll"
- call GetModuleHandleA
- mov ebx, eax ; store it in ebx
-
- ; get address of CreateFileA
- push 403F26h ; offset "CreateFileA"
- push eax
- call GetProcAddress
-
- ; call CreateFileA
- ; check its parameters in the doc
- push 0 ; hTemplateFile
- push 8000080h ; FILE_ATTRIBUT_NORMAL, FILE_FLAG_SEQUENTIAL_SCAN
- push 3h ; OPEN_EXISTING
- push 0 ; Security Attributes
- push 1 ; FILE_SHARE_READ is allowed
- push 80000000h ; GENERIC_READ
- push edi ; our file
- call eax ; CreateFileA
-
- cmp eax, -1 ; INVALID_HANDLE_VALUE (-1) ?
- je FINISH ; yes, do nothing, jump to end
-
- ; store handle in memory of OPENFILENAME
- mov [esi], eax
-
- ; get address of ReadFile
- push 403F43h ; offset ReadFile
- push ebx ; kernel32.dll handle
- call GetProcAddress
-
- ; set up parameters
- push 0 ; overlapped structure
-
- mov ecx, esi ; next parameter is a pointer for read bytes
- add ecx, 4 ; I use esi+4 for it
- push ecx
-
- push EA00h ; number of bytes to read (ca. 60000)
- push edi ; offset of buffer to receive data
- push [esi] ; filehandle
- call eax ; ReadFile
-
- ; close file, we don't need the handle anymore
- push 403F1Ah ; offset CloseHandle
- push ebx ; kernel32.dll handle
- call GetProcAddress
-
- push [esi] ; filehandle
- call eax ; CloseHandle
-
- ; now check how many bytes we have read
- mov eax, [esi+4]
- or eax, eax ; test if 0
- jz FINISH ; do nothing if no bytes read
-
- The file is now loaded and we want to display it. It's necessary to know the
- windows-handle of the edit-control. Do we know it? Look at the (disassembled)
- code for the messagebox "Nope doesn't work yet." The first parameter is HWND
- (last one pushed), and we see: it's stored in edi. If you scroll up a little bit
- you will find that [esp+10] is the location where the HWND is right now. This is
- the handle of the main window though. I have used a spy to get the handle of the
- edit-control and it was always HWND+4, but there is a cleaner approach.
-
- You can use "GetDlgItem" to retrieve the windows-handle. You need the HWND of
- the parent window and the ID of your child-window or dialog-control. The ID of
- the edit-control we can find out if we look at the "CreateWindowEx" code once
- more (I have explained every parameter in the Scrollbar-section) - it's 1. If we
- have the handle we can use "SetWindowTextA" which actually sends a WM_SETTEXT
- message to our control.
-
- ; get HWND of edit-control via GetDlgItem
- push 403F57h ; offet "GetDlgItem"
- push [esi+20] ; handle of "user32.dll"
- call GetProcAddress
-
- push 1 ; ID of edit control
- push [esp+14] ; parent window is stored in [esp+10]
- ; but we have already pushed a DWORD, so
- ; HWND is now in [esp+10+4]
- call eax ; GetDlgItem
-
- mov ebx, [esi+24] ; address of "SetWindowTextA"
- push edi ; address of filebuffer
- push eax ; HWND of edit-control
- call ebx ; SetWindowTextA
- jmp FINISH
-
- After writing this code I found out that you can also use "SetDlgItemText" to
- set the text of the control. This function does exactly the same and is shorter
- to code. :) The parameters are almost the same, you need the HWND of the parent
- window, the ID of your control and the pointer to the new text. I leave this as
- an exercise for you.
-
- Now we are ready. Only some cleanup has to be done: free all memory allocated
- with VirtualAlloc, pop the registers edi, esi and ebx, and finally return. This
- finishing code starts at offset 0x3DA0, so jmp (je, jz) FINISH means that you
- must enter "jmp 03DA0" in HIEW. It will generate the right opcode for this jump.
-
- FINISH:
- ; free memory
- push 8000h ; MEM_RELEASE
- push 0
- push esi ; OPENFILENAME
- call VirtualFree
- push 8000h
- push 0
- push edi ; filename buffer
- call VirtualFree
-
- pop edi
- pop esi
- pop ebx
- ret 10h
-
- Puh, that was much code. Does it work? YES!!! Great. I must say that it's much
- work to do something like this, you must be very carefull (and concentrated)
- while adding the code and the right offsets in HIEW.
-
- 4. File saving
- ==============
-
- Now that we have figured out how to load a file it shouldn't be a problem to
- save it. You must (again) allocate memory, initialize the OPENFILENAME
- structure, call GetSaveFileNameA, create a file, get the contents of the
- edit-control (this time with "GetDlgItemTextA") and save everything with
- "WriteFile". Here is the code, starting at offset 0x3C70. Don't forget to set
- the entry of the jumptable (0x1270) to 0x403C70! After reading the previous part
- you shouldn't have any problems to understand this one as well.
-
- ; allocate memory for filename buffer
- push 4 ; PAGE_READWRITE
- push 1000h ; MEM_COMMIT
- push 10000h ; 64k
- push 0 ; let Windows decide
- call VirtualAlloc
- mov edi, eax ; store pointer in edi
-
- ; allocate memory for OPENFILENAME
- push 4
- push 1000h
- push 4Ch ; 76 bytes
- push 0
- call VirtualAlloc
- mov esi, eax ; store pointer in esi
-
- ; initialize the important members
- mov [esi], 4Ch ; size of structure
- mov eax, [esp+10h] ; this is the parent HWND
- mov [esi+4], eax
- mov [esi+1Ch], edi ; pointer to filename buffer
- mov [esi+20h], 200h ; size of buffer, 200h is enough
-
- ; load comdlg32.dll
- push 403F00h ; offset "comdlg32.dll"
- call LoadLibraryA
- mov ebx, eax ; store handle in ebx
-
- ; get address of GetSaveFileNameA
- push 403F71h ; offset "GetSaveFileNameA"
- push ebx ; dll-handle
- call GetProcAddress
-
- ; call the function
- push esi ; offset OPENFILENAME structure
- call eax ; GetSaveFileNameA
-
- ; has the user choosen a file?
- or eax, eax ; eax == 0 ?
- jz FINISH
-
- ; get handle to "user32.dll"
- push 403F4Ch ; offset "user32.dll"
- call GetModuleHandleA
- mov ebx, eax ; store handle in ebx
-
- ; get address of SetWindowTextA
- push 403F62h ; offet "SetWindowTextA"
- push eax
- call GetProcAddress
-
- ; call function
- push edi ; should contain the filename
- push [esi+4] ; push HWND
- call eax ; SetWindowTextA
-
- ; get address of GetDlgItemTextA
- push 403F82h ; offet "GetDlgItemTextA"
- push ebx
- call GetProcAddress
-
- ; call GetDlgItemTextA
- ; The text won't be stored in edi because it still contains the filename
- ; which I will need later. I use edi+100h, no filename is THAT long and
- ; the buffer is still big enough for the max. 60000 bytes.
- push FEFFh ; max. size of string
- mov ecx, edi
- add ecx, 100h
- push ecx ; where to store the string
- push 1 ; ID of edit-control
- push [esp+1C] ; windows-handle
- call eax
-
- or eax, eax ; success?
- jz FINISH
- mov [esi+10], eax ; store number of bytes retrieved
-
- ; open the file
- ; get library handle for kernel32.dll
- push 403F0D ; offset "kernel32.dll"
- call GetModuleHandleA
- mov ebx, eax ; store it in ebx
-
- ; get address of CreateFileA
- push 403F26h ; offset "CreateFileA"
- push eax
- call GetProcAddress
-
- ; call CreateFileA
- ; check its parameters in the doc
- push 0 ; hTemplateFile
- push 8000080h ; FILE_ATTRIBUT_NORMAL, FILE_FLAG_SEQUENTIAL_SCAN
- push 2 ; CREATE_ALWAYS
- push 0 ; Security Attributes
- push 0 ; no sharing allowed
- push 40000000h ; GENERIC_WRITE
- push edi ; our file
- call eax ; CreateFileA
-
- cmp eax, -1 ; INVALID_HANDLE_VALUE ?
- je FINISH ; do nothing, jump to end
-
- ; store handle in memory of OPENFILENAME
- mov [esi], eax
-
- ; get address of WriteFile
- ; I thought this function was already imported. Deadly wrong!
- ; My computer crashed several times...
- push 403F92h ; offset "WriteFile"
- push ebx
- call GetProcAddress
-
- ; call WriteFile
- push 0 ; overlapped structure
- mov ecx, esi ; pointer to DWORD for written bytes
- add ecx, 8 ; I use [esi+8]
- push ecx ; push the address
- push [esi+10] ; number of bytes to write
- mov ecx, edi ; the buffer starts at edi+100h
- add ecx, 100h
- push ecx ; push the buffer
- push [esi] ; filehandle
- call eax ; WriteFile
-
- ; close file, we don't need the handle anymore
- push 403F1Ah ; offset CloseHandle
- push ebx ; kernel32.dll handle
- call GetProcAddress
-
- push [esi] ; filehandle
- call eax ; CloseHandle
-
- jmp FINISH
-
- The FINISH stuff is the same, starting at physical offset 0x3DA0. Don't use the
- virtual offset in HIEW, it will be calculated at runtime. Virtual offsets are
- only needed for strings and for the jumps of the jumptable.
-
- 5. Conclusion
- =============
-
- That's it and I am burnt out. I hope you got the idea HOW to add code to an
- unknown target without having the source. The "ReverseMe" is quite small so you
- have to use GetProcAddress very often. In a normal application MANY functions
- are already imported and ready to use. Read NNs essay how to add new menu-items
- and how to handle these messages.
-
- 6. Greetings:
- =============
-
- Knotty Dread
- NeuRaL NoiSE (his essay ROCKS)
- douby
- s^witz
- all DREAD members (you know show you are)
-
-
-
- Comments, critics, improvements go to:
- andreas.theDragon@gmx.net
-
-
- finished: 2000-06-01
-
-