TKC-Community

Hacking and Art => General Modding & Programming / Other Games => Topic started by: ninenine on October 16, 2007, 09:23:49 am

Title: Absolute Address of Labels
Post by: ninenine on October 16, 2007, 09:23:49 am
I am new to Cave Coding, so forgive me if my question seems too easy.  :smile

I am trying to create a Code Cave with TSearch's EasyWrite to inject into a program. Within my assembly code, I have a bunch of Labels and jmp instructions. The problem is that it is too tedious to count the size of each instruction in order to calculate the absolute address of the labels. Is there a way to use labels within EasyWrite (or is there a better program that lets me do this), or is there a fast way to calculate the absolute addresses?

Here is some example code:
Code: [Select]
offset 0x90b700
push ecx
mov ecx, 0x90b800
cmp DWORD [ebp], 1
je LABEL1
cmp DWORD [ebp], 2
je LABEL2
; -- a bunch more of these compare-jumps
LABEL1: add ecx, 0
jmp DONE
LABEL2: add ecx, 1
jmp DONE
; -- repeat with a lot more labels
DONE: pop ecx
 jmp 0x8b2cf3
Title: Re: Absolute Address of Labels
Post by: Subsky on October 16, 2007, 12:44:04 pm
The problem is that it is too tedious to count the size of each instruction in order to calculate the absolute address of the labels.

You're actually talking about relative addresses and x86 short or near jumps- not absolute ones, ninenine.  Basically- their position in code depends on where they jump- I'll elaborate.

Lets say you have an instruction @ 0x10000000 that shows up in a debugger as jmp 0x10000002.  In easywrite it would look something like:

offset 0x10000000:
jmp short 0x10000002 (writing the near keyword is optional)

Poke 10000000 EB 00

The whole instruction takes up 2 bytes- the JMP opcode in this case is 0xEB, followed by how many bytes it must jump past AFTER this instruction.

Short jumps only allow you to jump -127 (use twos compliment for negative numbers)  & +128 bytes from the start of the next instruction- if you want to jump further- x86 near jumps come into play.  Their opcode is the well know '0xE9' followed by a (32-bit) 4 byte address in Little Endian order, and easywrite will produce them automagically when you need to jump further than a short jump allows.

Both these jumps however- are relative ones.  If you relocate them you have to change the address part of the instruction which indicates where they jump to.

Is there a way to use labels within EasyWrite (or is there a better program that lets me do this), or is there a fast way to calculate the absolute addresses?

I'm assuming the last line of code in what I guess is your code cave:

DONE: pop ecx
 jmp 0x8b2cf3

crashes the program...

The answer is a far jmp- an absolute jump- which always jumps to a location no matter where it sits in code (eg it is not relative like near or short jumps).  According to the intel archecture dev guide- it should look like this:

offset 0x10000000
jmp far [0x10000002]

But I have never been able to construct an absolute/far jump this way in any debugger/T-Search etc.  To my knowledge, you can only create a far jump indirectly- using a register as the source of the jump, surrounded by the square brackets shown above.  This means you have to pick a register that is not currently being used (look for a mov E!X, E?X instructions below the jump- E!X should work).  Basically- assuming the register EAX is not being used- you can perform a far jump to 0x10000002 by writing these lines of code:

offset 0x10000000
mov eax, 0x10000002
jmp far [eax] (far keyword is optional- but good practice).

In your case- try this:

mov E?X, 0x8b2cf3
jmp far [E!X]

It's a fair bit of information to take in- but good code caving requires it... and unfortuantely; I don't think anyone else knows how to do it... especially willingly.

Hope that helps!

Subskii
Title: Re: Absolute Address of Labels
Post by: M. O. on October 16, 2007, 01:40:05 pm
Yea, they're relative so if you change your code you'll have to run that tool again and count or add/remove the size difference. I usually write directly into Cheat Engine. No need for counting (or I just take another code cave, or more or less static space after I know the code won't use up) etc. Or use the method Subsky wrote, then you don't have to update code due to rel jmps for every change.

If the repeated code is pretty much the same you could just make the loop a bit better too to avoid that many jumps to diff places. You could check against an array if you want other code to be executed (jump to diff locations etc).

Ill make a basic sketch:
Code: (asm) [Select]
push eax
mov eax, 0h  (might be superfluous)
LABEL2:
inc eax
cmp DWORD [ebp], eax
je EQUAL
jne NOTEQUAL

EQUAL:
dec eax
add ecx, eax
jmp DONE

DONE: (not necessary actually)
pop eax

So that should be a concept. Some problems might occur. If it never will be equal etc like takes too much time, you'll have to add another "DONE" condition. Like after 500 iterations, jump to done.
Title: Re: Absolute Address of Labels
Post by: mesengr on October 17, 2007, 09:54:37 pm
Thank you very much for your replies! Thanks for pointing out my error with the relative addressing, as well as for the tip about using registers for absolute jumps. You answered a lot of questions I probably would have asked later on. :icon_biggrin2

Like M.O. said, it is easier to write directly into Cheat Engine. First, CE finds and allocates memory you can use for your Code Cave. (With TSearch, I had to search/guess the available addresses.) Also, as you write directly into CE, the address you are writing to is displayed, so you could refer directly to it in your jmp instructions.

 :?: -- I am still confused about near jumps. I understand that a short jump is -127 to +128 bytes from the current location. Would a near jump also be -127 to +128 bytes from the current location, or would it be an actual address within the same code segment, or something else?
Title: Re: Absolute Address of Labels
Post by: Subsky on October 18, 2007, 06:14:21 pm
:?: -- I am still confused about near jumps. I understand that a short jump is -127 to +128 bytes from the current location. Would a near jump also be -127 to +128 bytes from the current location, or would it be an actual address within the same code segment, or something else?

Near jumps in the x86 IA-32 world are relative 32-bit (4 byte) jumps that essentially allow you to jump the 4GB memory space (values range from - to 4,294,967,295) (even though inbuilt OS security typically prevents you from doing so- kernel mode addresses etc).

While their size allows you to jump these great distances- as said before; they act like short jumps in the sense of relative jump location.

Subskii
Title: Re: Absolute Address of Labels
Post by: Subsky on January 03, 2008, 07:34:14 pm
I was going through some of my older posts- and landed on this one.

It's really informative and I'm going to ask the mod of this section if they could sticky it.  This information is valuable stuff and isn't discussed on the internet anywhere else.

Thanks

Subsky