Log in

View Full Version : Newbie-Question: How to add code with WDASM or Code Snippet Creator?


Nat
August 18th, 2002, 16:29
Hi there,

I am an absolute newbie. Therefore, please do not read this thread if newbie questions bother you ;-)

I want to do a very simple thing. It has nothing to do with sophisticated reverse engineering. I just want to add some code to an application and, nevertheless, I find it very hard to do this.

The problem is that there are so many tools and I am not sure which tool I should use (my OS is WinXP). I also do not know how to use the tools.

This is what I have already done:

I have identified with Winhex the hexcode I want to change. It is "6A 00 E8 34 64 FF FF". Then I opened WDASM and tried to find this piece of code. I had some difficulties because the offsets in WinHex and WDASM are different (you probably roflka when you read this...but that's a poor newbie's prob ;-). I used the search function in WDASM and finally found "E8 34 64 FF FF". I found this code only once. Therefore, I am relatively confident that I am at the right place of the file.

WDASM told me that my piece of code means the following:

6A 00 = push 00000000
E8 34 64 FF FF = call 0040498C

Now ... I am already stuck ;-) I want to change this "call". What I want to do is the following. I want to jump to somewhere else and then return and continue with the "call". I am unable to figure out how to do this. I need to overwrite the hexcode at this place and insert a working piece of code which takes me to another place in the file and then I want to come back and continue with the call. I do not know which tool I need to use for this and how to use it. (Once I have managed to do this I can start to insert additional code which will be executed before I continue with the call. But that's not part of my question.).

I would be very grateful if someone could answer this question or help me out with a tutorial describing such most elementary stuff. If possible at all I would like to avoid the use of SoftICE because its seems to me that this tool is even more difficult to understand than WDASM or Code Snippet Creator.

Thanks so much for your help,

Nat

EDITED: I continue trying to find a solution for my problem and can report the following progress ;-)

I have loaded the file with WDASM and "loaded the process". It seems to me that something like a debugger with three windows popped up. One window has a button called "goto address". I entered the offset of the call and it seems to me that WDASM executed my file and stopped exactly before the call. Now I have found a button called "patch code". When I press this button, another window (the "Coder Patcher" pops up. I am asked to enter a new instruction for the call 0040498C @ EIP 0040E553. That's exactly what I want. But where should I jump? And how can I return from this location? And finally, how can I save the file after I have patched it in this way?

DakienDX
August 18th, 2002, 17:44
Hello Nat !

I would strongly recomment using a PE-Editor for this too. A good one is LordPE. You can get it from the Programmer's Tools link below. You can use it to view the sections of the executable and alter their attributes. You can then find out where the program's code section ends (it's called ".code" or "CODE" most time). You should have some space available between the end of the code and the end of the section (only 00h bytes). This is the place to add your code.

With LordPE you can see the BaseAddress of the .EXE. So if your program would have a Base of 00400000h (very common), your code section would start at the file offset 600h and the place near the end of the code section where you want to add your code would be F800h, you would calculate 00400000h-600h+F800h=40F200h. 0040F200h is the so called "virtual" address. So you would enter "Call 0040F200h" with W32DASM at your patch-location.

Then you can insert your own code there (remember to save the registers with "PushA" and restore them with "PopA". At the end of your code you should place a "Jmp 0040E553". This will jump back to the address which was called by the original call before you modified it.

Nat
August 18th, 2002, 18:14
@DakienDX Thank you! I will try this ...

Cheers,

Nat

EDITED:

Sorry for continuing my demonstration of incompetence ;-) I did what Dakien recommended and downloaded LordPE. There are several versions. I decided to use LordPE Deluxe. Unfortunately, the download does not include a manual. I my google search for "LordPE manual" did not help.

I started the application and a relatively small screen with two windows appeared. The first windows shows the path of my memory resident apps. The second window is empty. On the right there are several buttons. I clicked the button PE editor and loaded the application I want to manipulate.

I received the following PE Header information. Entry Point E504, Base of Code 1000 - Size of Headers 400. (Please let me know if I looked at the wrong information.) Then I clicked the button "Sections" and another window opened. Here it also says Code VOffset 1000, VSize EF0C, ROffset 400, RSize F000. I highlighted with my mouse the line showing the information about the code section, made a right click and chose "hex edit section". Another window (a hex editor) popped up. I see offset 400 (apparently the beginning of the code section).

I also discovered that my files has an "image base" of 400000. I guess that is the "base address" which Dakien mentioned. Now I tried to do the necessary calculation but I did not understand why Dakien used the numbers 600h (file offset - my file offset seems to be 1000) and F800h (is this the end of the code section? how did Dakien know this? it appears to me that the end of "my" code section is 400000 + VSize?). Anyway, I opened WDASM and checked in order to check whether the result of Dakiens calculation would help me.

With WDASM i opened my application with "file to disassemble" and had a look at the WDASM main window. My application is devided into several sections. It says that the code section starts at (virtual?) offset 4001000. Yipee...this seems to be in line with the information I derived from LordPE (image base + voffset). Now I move on and look for the end of the code section. The last thing I can find are a couple of zero bytes starting @ 40FF15. However, the last byte @ 40FFFB has a value of 32138BC000. Hope that's not a problem.

Now I decided that I want to modify the call @ 40E553. I want to call 40FF15 instead of 40498C.

Wonder how to do this with WDASM...I once again start "Debug -- Load Process" and the three windows open. The applications seemed to be executed but halted somewhere. It is not halted at the beginning of the code section but at the programme entry point (@40E504). Seems to make sense...although I do not understand it ;-) But let's continue. I go to the right WDASM window which does not have a title and press goto address. Another window pops up and I enter 40E553 (the offset of my call). Aha..it seems to work. Now the right window without title shows my call.

I try to patch this call. I highlight the respective line with my mouse and press the button "patch code". Another window pops up. I already know it. It says "EIP 40E553" and "call 40498C". There is a box called "Enter New Instruction Below". I enter call 0040FF15. Then I press "apply patch" and "make permanent".

It does not work...last time i tried this it did not work either. Damn..I am stuck again. Wait..I made a mistake...I need to press the enter key and now the new instruction is shown in a box called "Code Patch Listing". I press again "apply patch" and also "make permanent" and then I press "close".

Yeah..it did work. I am the most dangerous patcher the world has ever seen...

Now I need to go to 40FF15 and include the instructions mentioned by Dakien. I do not want to enter any additional code right now but just jump to the location to which the original call directed (which I have overwritten). Therefore I will simply include a "Jmp 40498C". Hopefully, this is correct.

I go to 40FF15, enter the patch mode and I can see that the current value of this byte is "add byte ptr [eax], al". Strange...I thought this was a zero byte? Have a bad feeling but I need to continue. Therefore I replace this command with "jmp 40498C".

Now I close WDASM...I hope everything is saved. Damn!! It was not saved. What am i doing wrong? Arghh..everything again.


****
I did everything again. But I can't find a way to save the modifications I have made. I am stuck once again. Can anybody help?

Thx,

Nat

cr.ap
August 18th, 2002, 21:30
hi nat,

im also a newbie so i could not help you really..but if want to patch a file i use hiew.
i think its a lot easier to path code with hiew than with w32dasm.

cr.ap

ps: sorry for the bad english...

Nat
August 18th, 2002, 21:45
Thx cr.ap for the tip and also for your moral support ;-)

I have already downloaded hiew...apparently the wrong version. I does not even have a GUI but seems to be a command line tool. I can't get it to work. But I probably ..just the wrong version. I will continue to look for it.

Cheers,

Nat

cr.ap
August 18th, 2002, 21:56
Quote:
Originally posted by Nat
I does not even have a GUI but seems to be a command line tool. [/B]


hmm..its a console app...perhaps you should run it from an ms-dos-window.

once your in you open your file press F4 choose decode...go to the location you wanna patch press F3 for edit mode then you can press enter an easily put in you code.

when you finished press F9 to save.

hopw it helps

cr.ap

DakienDX
August 18th, 2002, 21:59
Hello Nat !

OK, I may have started a bit too fast for you.

Yes, "BaseAddress" is "image base". I took the numbers I mentioned just as example. 600h or F800h will most likely not fit for your application.

As you found out, there is a V (=virtual) and a R (=real) size and offset. You must take the virtual offset if you're calculating something like addresses in memory and the real offset if you're calculating offsets in the file on disk.

So your ".code" section starts at 400h in the file on the disk and is F000h bytes long.

So If you want to calculate the end of the code-section in the file, you add 400h and F000h and get F400h. Before F400h you should have some hexadecimal 00h (in a hex-editor). This is the place where where you can place your own code.

However, in memory the end of the code-section is at "image base"+VOffset(code)+RSize(code). 400000h+1000h+F000h=410000h. This is where the code section ends in memory. Since the VSize is only EF0Ch, you should have at least F000h-EF0Ch=00F4h bytes to insert your own code.

The hex-code 0000h would be the ASM instruction "Add Byte Ptr [EAX], AL" if it was executed. It should start at 40FF0Ch in memory.

If W32DASM doesn't save the patches, you need to do it by hand.
You must write down what you patched, as well as the virtual offsets of the patch data.
You wrote that the first patch you did was at 40E553h, the second at 40FF15h.
So you need to calculate the virtual offsets back to real ones.
Subtract 401000h from the values (image base + VOffset) and you get D553h and EF15h. This is the position in the code-segment, so you need to add 400h (ROffset) to it to get it's position in the file on the disk. (D953h/F315h)
You can edit this locations with your favourite hex-editor and insert the patch-bytes you wrote down there.

HIEW is a text mode application which runs in a DOS command prompt, it has no GUI.

Nat
August 18th, 2002, 22:10
@cr.ap Thx again. Now I have Hiew6.81 and, in principle, it works fine.

I did what you said and found my call again. However, the offsets are completely different in hiew.

The call, which is located @ 0000D953 points to 3D8C now. Therefore, I am not sure to which address I should jump now.

I need to find some free space at the end of the code section so that I can include a jmp 3D8C and jump to the destination of the orginal call.

I do not know how to find the end of the code section with hiew. I can only scroll and gues...

Any ideas? Thx,

Nat

EDITED: @Dakien I replied to cr.ap before I saw your posting. Thanks so much for this detailed explanation!! I still need to read it thoroughly but I feel that I will really understand it :-)

I also believe that your suggestion to use a simple hex editor will be the easiest way for me because I already know winhex and now i also understand WDASM (just a little bit). The only question I currently have is the following:

When I use WinHex for patching, I need to insert hexcode. What is the easiest way to translate my assembler commands like jmp... and call... into hexcode? It seems to me that hiew can do this?

Cheers,
Nat

2ndEDIT: I withdraw my last stupid question because I figured out the answer myself. I can have WDASM do the translation. Thanks again @ all

I will try it out now ...

Kayaker
August 19th, 2002, 05:39
Hi Nat, Others

What you're experiencing is something everyone goes through at first, getting used to the tools and techniques, it will come soon. You would find help in some of the tutorials, but some of them don't explain the basics very well, assuming you already have the knowledge. If you want a complete example of how to do a basic reversing job, how to find a suitable location for and create an inline patch, and all the background information necessary to do it, then you might want to look at a few of my own tutorials. I tried to develop them as detailed guides to some basic reversing techniques as much as possible, something I found lacking when I was learning the stuff.

There are descriptions of any modifications you may need to make to the PE file, setting up the basic patch points for jump and return, how you can develop your inline patch in Softice memory to test it, how to dump the patch from memory or use HIEW to write it from scratch, and more, all without using any fancy patching tools which only hide what's being done.

There are other tuts that explain other things, but if you want some detailed information on creating an inline patch then I'd suggest looking at my TracePlus tutorial, which creates a patch for a new menu item resource and includes details of how to trace a menu item to the code it calls and modify it. The Regmon tutorial is a bit more advanced but the basic principles remain the same, in that it creates an inline patch which loads your own dll, and an example of how to create the dll. This can be used as a module to perform even further reversing tactics without the bother of having to create complete new inline patches on every target.

There's tons more information out there, but these might be a good starting point, hope they help.

http://www.woodmann.net/fravia/TracePlus_MenuPatch.html
http://www.woodmann.net/fravia/kayaker_RegmonPlus.htm

Regards,
Kayaker

Nat
August 19th, 2002, 20:43
...

1. I have changed the topic of the thread because it was misleading. We do not talk about Code Snippet Generator.

2. Thanks @ Kayaker. I have already read the tutorials and I will save them. At the moment, however, I am still too ...well too stupid to completely understand them.

3. I will continue to explain in detail what I am doing because I could imagine that other absolute newbies may encounter the same difficulties:

*******

Today, I was unable to continue my project because I needed to work. That's a pity because I am really excited about it now ;-) This evening, I have started again ...

I believe that I have understood the basic concepts of using PELord, WDasm and WinHex. I have modified the file as follows.

@ 40E553 : I have included a call to F315, i.e. I have inserted the hexcode E8 B8 0D C0 FF.

@ 40FF15 : I have included a jmp 3D8C (the original destination of the call which I have overwritten) = hexcode E9 2A 58 BF FF

Well...you will probably not be suprised...it did not work :-) The program crashed. I believe the reason are not my mediocre patching skills anymore but my lack of understanding assembler. In order to figure out what's wrong I need to understand the code which I want to patch. Therefore, I have dissassembled the (original) file with WDASM and saved the result:

{...}
:0040E51C E89763FFFF call 004048B8

* Possible StringData Ref from Data Obj ->"`"
|
:0040E521 BB3C014100 mov ebx, 0041013C
:0040E526 BF28014100 mov edi, 00410128
:0040E52B BE30014100 mov esi, 00410130
:0040E530 33C0 xor eax, eax
:0040E532 55 push ebp
:0040E533 6877FA4000 push 0040FA77
:0040E538 64FF30 push dword ptr fs:[eax]
:0040E53B 648920 mov dword ptr fs:[eax], esp
:0040E53E 6808434100 push 00414308
:0040E543 6A00 push 00000000
:0040E545 6A00 push 00000000
:0040E547 6898554000 push 00405598
:0040E54C 6800140000 push 00001400
:0040E551 6A00 push 00000000

* Reference To: kernel32.CreateThread, Ord:0000h
|
:0040E553 E83464FFFF Call 0040498C !!!!!!!!!!!!!!!!!!!!****
:0040E558 A174014100 mov eax, dword ptr [00410174]
:0040E55D 8B1508434100 mov edx, dword ptr [00414308]
:0040E563 8910 mov dword ptr [eax], edx
:0040E565 E81A78FFFF call 00405D84
{...}

I have marked with exclamation marks the section which has to be patched. (Please don't question the location.)

The idea is to redirect the call to somewhere else and then to come back and jump to the original destination of the call. I want to redirect the call to the following place in the file which seems to be "empty":

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FEB6(C)
|
:0040FF09 7B00 jpo 0040FF0B

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FF09(C)
|
:0040FF0B 00000000000000000000 BYTE 10 DUP(0)

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040FEBB(C)
|
:0040FF15 00000000000000000000 BYTE 10 DUP(0) !!!!!!!!!!!!****
:0040FF1F 00000000000000000000 BYTE 10 DUP(0)
:0040FF29 00000000000000000000 BYTE 10 DUP(0)
:0040FF33 00000000000000000000 BYTE 10 DUP(0)
:0040FF3D 00000000000000000000 BYTE 10 DUP(0)
:0040FF47 00000000000000000000 BYTE 10 DUP(0)
:0040FF51 00000000000000000000 BYTE 10 DUP(0)
:0040FF5B 00000000000000000000 BYTE 10 DUP(0)
:0040FF65 00000000000000000000 BYTE 10 DUP(0)
:0040FF6F 00000000000000000000 BYTE 10 DUP(0)
:0040FF79 00000000000000000000 BYTE 10 DUP(0)
:0040FF83 00000000000000000000 BYTE 10 DUP(0)
:0040FF8D 00000000000000000000 BYTE 10 DUP(0)
:0040FF97 00000000000000000000 BYTE 10 DUP(0)
:0040FFA1 00000000000000000000 BYTE 10 DUP(0)
:0040FFAB 00000000000000000000 BYTE 10 DUP(0)
:0040FFB5 00000000000000000000 BYTE 10 DUP(0)
:0040FFBF 00000000000000000000 BYTE 10 DUP(0)
:0040FFC9 00000000000000000000 BYTE 10 DUP(0)
:0040FFD3 00000000000000000000 BYTE 10 DUP(0)
:0040FFDD 00000000000000000000 BYTE 10 DUP(0)
:0040FFE7 00000000000000000000 BYTE 10 DUP(0)
:0040FFF1 00000000000000000000 BYTE 10 DUP(0)
:0040FFFB 000000000032138BC000 BYTE 10 DUP(0)

[This is the last part which has been disassembled by DASM and apparently it's the end of the code section.] I want to redirect the call to 40FF15.

Taking into account what I have done before (and which leaded to a crash) I am now worried about the following issues:

When I redirected the call @ 40E553 to 40FF15 I made probably a mistake because I did not take into account that a couple of bytes had been pushed on the stack (or in several registers?). Apparently, such bytes were used as parameters for the orginal call. I am worried that these parameters were somehow affected by my call and the subsequent jump to the original destination of the call. However, I do not know what exactly happens when I use the commands call, jmp, ret etc. I also do not know what exactly happens when I push bytes on the stack and/or in a register. I can also not properly distinguish between the several registers and the stack.

In addition, I am concerned about the fact that 40FF15 seems to be referenced by a jump @ 40FEFBB (according to the WDASM comment). This could be bad because this could result in a loop after I have inserted my jump @ 40FF15.

Alas....I definitely need to read some more tutorials. However, I find it hard to find a tutorial which deals with commands like call, jmp, ret etc. This is because most assembler tutorials use instructions like invoke and so on.

I would be really grateful if somone could point me into the right direction...

Thanks,

Nat

EDITED: In the meantime, I have started to "debug" the original file. I have loaded it with DASM and set a breakpoint with F2 in the main window. Then I went into the small window without title and pressed run. The application was executed but halted at the breakpoint. I have chosen 40E521 as a breakpoint. Now I have pressed "step into" / F7 and I was able to see exactly what happened. I could see (in the window with the title EIP...) how the values of the registers in the upper left of the window changed after the execution of each command. This was really interesting. I seems to me that everytime the command push is used the register esp is affected. (Need read about esp ;-).
Moreover, I need to figure out exactly what happens to the registers when I execute a call. Hmm...but I think that's it for today.

DakienDX
August 19th, 2002, 21:10
Hello Nat !

So you've patched the right location, but wrote the wrong bytes there.
How did you get the bytes to wrote there? (E8 B8 0D C0 FF)
(If you did it with HIEW, you probably entered a wrong value as the jump-destination.)

At first you must know how a "call" works. It's "E8 ?? ?? ?? ??", where the ?? denote how far to jump form the end of the jump-instruction (patch location + 5 bytes). So you calculate (F315h - (D953h + 5)) and place this value instead of the ?? in the call instruction.

The same counts for a jump (E9 ?? ?? ?? ??), also 5 bytes long. You calculate (EndLocation(=original call location) - (CurrectLocation + 5)) and replace the ?? by this number. It will be a negative number (>80000000h) since you're jumping back and not further.

"Jmp" instructions never change any registers (expect EIP, which is just a "virtual" register), "Call" and "Ret" instructions just change ESP, which is also not important most of the time.

You don't need to worrry about registers here. As far as I can see the situation, the original "Call" would call a "Jmp" to "CreateThread". The patch should "Call" a "Jmp" to your code which does a "Jmp" to "CreateThread". So nothing changed here. You just need to find out how jumps and calls are calculated.

Nat
August 19th, 2002, 21:31
...it's really great, Dakien, that you help me so much!! I will need to read your anwer thoroughly. Thereafter, I will tell you why I did the mistake.

Cheers,

Nat

EDITED: I understand! I mistakenly assumed that a call jumps to an absolute address. I was not aware that the jump goes to a relative address which has to be calculated. I will try this out now.


Ok...now I will do the following:

@ 40E553=9D53h : I will insert a call to F315. Because I am @9D53h it need to jump F315 - 9D53 + 5 (+5 because of the call...but don't ask me why ;-) = 55C7 bytes forward. That is I must insert a "call ..." which is equal to a hexcode E8 BE 70 BF FF (I did the conversion into hex with WDASM ... when you enter "call 55c7" as a patch it tells you also the corresponding hexcode).

*******
EDITED!!! (with reference to Dakien's reply): Thanks .. ok..then the hexcode to be inserted is E8 55 C7 00 00 -- i guess that your suggestion E8 C7 55 00 00 was just a typo ... or is there any reason to switch the numbers?)
********

(By the way...what does the "h" mean? HexWorkshop does not show this sign. And how do I calculate in hexadecimal...don't have my pocket calculator here...ahh..thanks god I have not deinstalled the Windows XP calculator ;-)

@ 40FF15 (virtual address) = F315 (address in the file): I will insert a jmp to Endlocation - CurrentLocation +5

EndLocation is original call location ...aehmm...its probably not 3D8C (because this is not the original destination of the call but just a relative number of bytes to be jumped forward). That is ... I need to actually calculate the EndLocation=original call location. (Arghh...I am not a mathematics professor!) Ok...9D53 + 3D8C = DADF ( I don't add + 5 this time...but am not sure whether this is correct). I do not trust my own calculation...but continue.

EndLocation (DADF) - CurrentLocation (F315) + 5 = FFFFFFFFFFFFE7CF
...at least that's what my calculator says. However...the number is to big...probably because the calculator used a qword and not a dword. The correct number should be FFFFE7CF ... possibly ;-)

The hexcode is E9 FF FF E7 CF. !?

Ok..now I need to insert E8 55 C7 00 00 with HexWorkshop @ 953h and hexcode E9 FF FF E7 CF @ F315.

ARGHHH...can't think anymore. Will do this tomorrow at work ;-)

[ to be completed...i just "save the thread" so that nothing gets lost]

DakienDX
August 19th, 2002, 22:21
Hello Nat !

It seems you made a mistake again.

If you're running W32DASM you must always use virtual addresses. So you would use "Call 0040FF15", but only if you're at EIP 0040E553h. Else W32DASM will generate an invalid jumps since it uses the wrong start address for the "Call".

So if you want to call a location 55C7 bytes forward from the end of the "Call" instruction, you call would be "E8 C7 55 00 00". Very simple.

Of course you must do the same thing again for the "Jmp".

I only use "h" to show that it's a hex number. In a hex-editor it's obsolete, but it's a difference if you tell somebody "go 256 bytes back" or "go 256h bytes back", since 256=100h, so 256!=256h.

Nat
August 20th, 2002, 22:06
...I am swamped. Left the office @ 10 p.m. (although I started early in the morning). Now I am too tired to do anything but watching a movie.

I know that my code is still not correct (have tried this yesterday night). The call still goes to the wrong address (have checked this with WDASM). Will try to identify my mistake tomorrow (if I have time). Need to check everything again...right from the beginning.

G'night,

Nat

JMI
August 21st, 2002, 00:09
Nat:

One of the confusing, but simple things which seems to be confusing you is the order of the listing of the bytes in the address that you are going to add for your new jump. What you have to remember is that in the assembly the bytes are listed in REVERSE order. For example you wrote:

*******
EDITED!!! (with reference to Dakien's reply): Thanks .. ok..then the hexcode to be inserted is E8 55 C7 00 00 -- i guess that your suggestion E8 C7 55 00 00 was just a typo ... or is there any reason to switch the numbers?)
********
He responded that you had it wrong and it had to be :

********
So if you want to call a location 55C7 bytes forward from the end of the "Call" instruction, you call would be "E8 C7 55 00 00". Very simple.
********

He just didn't state that the reason he was correct and that you were incorrect is that because of the way the processor works it pushes the bytes in REVERSE ORDER . Therefore is you want to end up with an address that the processor sees as 55C7 you have to push it as C755 and this is the way you would find the address in the assembly if you viewed the code with a hex viewer. It would also explain why you can't find addresses in a file listed in hex in the code if you don't understand this concept.

Regards.

Nat
August 21st, 2002, 00:41
@JMI Thank you for helping me out!!!

I believe that I now understand what you and Dakien are telling me. Initially, it confused me that neither 55 C7 nor 7C 55 is correct.

But now I see that 55 C7 consists of two separate bytes and not each byte is reversed within itself but only the order of the bytes is reversed. This must be because a byte is the smallest size which is interpreted by the processor. In other words, I do not push entire words on the stack but merely separate bytes. And because the stack works LIFO (last in first out) I need to reverse the order of the bytes. Hope ... this is a correct interpretation of your hint.

@Dakien Sorry for questioning you at all ;-)

Thx everyone,

Nat

P.S.: Why am I unable to find a tutorial which teaches me these basics right from the scratch. I guess I am the most ignorant person who has ever posted in this forum ;-)

P.P.S.: Now I can't go to bed but must try this out ... ;-)

EDITED:

Ok .. I will reverse

"Ok..now I need to insert E8 55 C7 00 00 with HexWorkshop @ 953h and hexcode E9 FF FF E7 CF @ F315."

to

"Ok..now I need to insert E8 C7 55 00 00 with HexWorkshop @ 953h and hexcode E9 CF E7 FF FF @ F315."


2nd EDIT: Ok..ok...still more mistakes..I know ;-)

JMI
August 21st, 2002, 01:07
Nat:

Here are three articles which may help. The first is "Calculating Offsets" by Lord Rhesus which explains how to calculate short and long jumps and the offsets and the "little edian" reversing of the bytes.

The second is The "Call Relocation Table and Its Importance" by Fravia+, which explains that there is something at the end of most windows files which contain, again in reverse order, the addresses of many jumps.

The third is part of the Mannon_'s Tales to his Grandson. this one is on "Registers, Memory, and how Assembly Language came to mankind." It has alot of useful information about the register system and how things are stored and viewed in disassembly of windows code.

All three of these articles, I believe are contined in the Fravia+ Forum which is a companion to this Board and linked at the very bottom of these pages. If for some reason my attachment doesn't work, let me know and I'll try to email them to you. I may be only able to attach one at a time.

Regards,

JMI
August 21st, 2002, 01:31
Nat:

I am also attaching a copy of the W32dasm.hlp file. This file is old, from 1997, but it may provide some useful information on use of the program. There are tutorials on the web, if you take the time to learn how to search, which will answer most of your questions.

I didn't follow all the addresses you have been using for your jumps, but a possible problem, addressed in the Lord Rhesus article I attached above, is that there are both short and far jumps and they use a different op code. If your first jump is a "far" jump and you used "EB" it wouldn't work. If its a "long" jump the op code has to be "E9". Just a thought.

There are also tools available to help you calculate jumps, but since you've been doing your homework, you knew that, right?
Just a gentle nudge that sometimes we get so excited by the prospect of cracking something NOW we forget to take the time to STUDY the process of how this is done as well as we should. There is a great deal to learn and always more to look for.

Regards.

Edit.

File is too big to attach.. If you want it send me a PM with an email address and I'll send it along.

Nat
August 21st, 2002, 07:22
@JMI Thanks again!! I have downloaded the Tutorials. Moreover, I believe that I already know the mistake...but let's not promise too much. Hopefully, I will have a little bit more time this evening.

As regards the WDASM helpfile...I will search the web for it and will contact you later if I am not able to find it.

As regards, the tools which help me to calculate jumps. No...I did not know that such tools are in existance. Actually, I did not even know that it's so difficult to calculate jumps ;-)) Will make my homework and learn how to calculate jumps manually. Thereafter, I will search for the tools.

Best regards,

Nat

Kayaker
August 21st, 2002, 08:10
You might want to try a "live approach" on this as well as learning to calculate offsets Nat. Personally I'm actually too damn lazy to bother calculating offsets if doing a patch I usually assemble it in Softice using the 'a' command where I want to begin the patch, then either dump those bytes with Icedump or take note of them and transfer those bytes to HIEW to hard write the patch. Offsets for jumps and calls, including API calls, are automatically calculated for you in the correct context as you type in the patch.

If you write the complete inline patch in Softice, you can continue to edit individual lines without tracing, then as you are happy with the code, start tracing to test it out, write a few more lines and trace/test it some more. You can even insert "INT 1" statements into your code to force a Softice break when your code is run, (when you have "I1HERE ON" enabled in Softice). A development and debugging environment all in one. For anything more than the simplest patch I figure it's easier to program it in and let Softice take care of the offset details. At the very least you can use the 'a' command to confirm that your offset calculations are correct.

To do this safely you need to set up a basic jump/return structure. You would try to find a location in code where it is convenient to overwrite the existing code for the initial jump. A jmp statement to an empty location in memory (often at the end of the .data section made executable and fully paged in), takes 5 bytes, and whatever is overwritten *may* need to be emulated in the patch. Start with a simple

jmp patch
/ restore overwritten bytes
/ jmp return to program code exactly where you left off

In Softice trace to the first line you've selected to overwrite, type 'a eip' for 'assemble at the current location', press Enter, write the new jmp statement pointing directly to your empty code section, and when you're finished press Enter twice. You may need to add nops (90h) after the jump statement to make up for bytes you've overwritten. Single trace this new line at you're at the start of your inline patch.

Type in the overwritten bytes and basic jmp return and now you've got a template to work on in Softice. Make several backup copies and just set a breakpoint on the starting address of your patch in empty code and start writing. Every so often you can dump a good section of your code patch and hard write it into the file to test it out. If you want to just exit from what you're doing, inserting a simple RET will usually give you a recoverable crash, rather than just letting improper code run which might be more likely to cause a system hang instead.

What's important is where you want the code to jump to after your inline patch runs. Depending on what you're doing you may want to return to program code to allow any default Windows processing to occur, or you might want to go to another part of code and not return, or you might want to access the return value of the call from the stack and exit directly from the main call you are within. You must be careful of the stack no matter what you do.

Just a few more ideas you can bring to work

Kayaker

Nat
August 22nd, 2002, 22:58
...it's getting better and better:

1. This time I left the office at 10:30pm.

2. My WinHEX sucks. It does not correctly show the hexcodes of the file. I believe that it's not properly cr**d. Well, at least HIEW works as it should.

3. My Internet Explorer sucks. I can't post anymore because there seems to be a cookie problem. The browser asks me to log in although I have already done so. Well, at least Opera works fine.

***

Despite these struggles, I made some progress last night! :-)

I correctly calculated the first (forward) call so that it takes me to F315. I patched E8 BD 19 00 00 into the file.

My previous patch (E8 C7 55 00 00) was completely wrong because

1. I did not carefully listen to grandmaster Dakien's advice. It screwed up the calculation with the brackets.

2. I mistakenly used WDASM for the calculation. It turned out that I get a different result when using the Windows calculator.

Anyway, now my call really leads me to F315 where my backward jmp is already waiting to be executed. I have confirmed this with WDASM's debugger.

****

So far I have not been able to correctly calculate the backward jump. This is because I do not completely understand Dakien's calculation method. He said:

"The same counts for a jump (E9 ?? ?? ?? ??), also 5 bytes long. You calculate (EndLocation(=original call location) - (CurrectLocation + 5)) and replace the ?? by this number. It will be a negative number (>80000000h) since you're jumping back and not further."

I am not sure how to figure out EndLocation. I believe it must be determined as follows:

The original destination of the call @ 9D53 was E8 34 64 FF FF. Therefore the EndLocation should be FF FF 64 34 (because the data is pushed onto the stack in reverse order for purposes of a call) + 9D53 (start location of the original call) = 10 00 00 187 (if my calculator is right). Seems strange to me...I have enabled Qword and Hex in the GUI of the calculator.


EndLocation - (F315 + 5) = 10 00 00 187 - F31A = FFFF0E6D should therefore be the address which I need to use for my backward jmp @ F315. The address still needs to be reversed (i.e., it must be 6D 0E FF FF).

Hmm...don't think that this is right.


Cheers,

Nat Nobrainer

P.S.: Thanks, Kayaker. I will keep your hints in mind.

DakienDX
August 23rd, 2002, 11:11
Hello Nat !

Maybe a hint in the right direction will help you.
So, here's what you have:
Code:

You are at: 0040E553h virtual, 0000D953h real
You want to go to: 0040498Ch virtual, 00003D8Ch real
You want to go over: 0040FF15h virtual, 0000F315h real

Take 0040FF15h, subtract (0040E553h + 5), get 000019BDh
Take F315h, subtract ( D953h + 5), get 000019BDh
Call would be: E8 BD 19 00 00

Take 0040498Ch, subtract (0040FF15h + 5), get FFFF4A72h
Take 3D8Ch, subtract ( F315h + 5), get FFFF4A72h
Jump would be E9 72 4A FF FF
I hope you understand now how to calculate calls and jumps.

Nat
August 26th, 2002, 17:16
Dakien,

Thank you once again. Your explanations are terrific. I definitely got the concept now. (My main mistake was that I did not properly distinguish between real and virtual offsets. Therefore, I used WDASM in an inappropriate manner.) But now everything is clear to me. The patched proggie works perfect and I can start with another learning project ... I will try to add a function (with the help of code snippet creator) to an existing application... ;-)

I would also like to thank everybody else who helped me.

Cheers,

Nat