Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Jump near relative becoming jump near absolute indirect
Goto page 1, 2  Next
 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
chodness
Newbie cheater
Reputation: 0

Joined: 27 Feb 2015
Posts: 23

PostPosted: Wed Aug 31, 2016 11:07 pm    Post subject: Jump near relative becoming jump near absolute indirect Reply with quote

Hey guys, I've got an issue I unfortunately don't know nearly enough about assembly to diagnose: (each isolated segment of of bytecode and opcodes are supposed to be interchangeable - it helped me with bug testing Razz )

Code:

[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,32,"ROTTR.exe"+3A76924)
label(returnhere)

newmem:
shl ebp,1
add [rdi+38],ebp
shr ebp,1
mov [rsp+00000118],eax
jmp returnhere

"ROTTR.exe"+3A76924:

//db E9 ** ** ** **
//db FF 25 00 00 00 00 ** 00 ** 00 ** 00 ** 00
jmp newmem
/*
asterisks are dynamically generated by assembler
what's the difference? they both seem to jump the same distance
*/

nop
nop
nop
nop
nop
returnhere:


 
 
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"ROTTR.exe"+3A76924:

db 01 6F 38 89 84 24 18 01 00 00 84 DB 74 0A
/*
add [rdi+38],ebp
mov [rsp+00000118],eax
test bl,bl
je ROTTR.exe+3A7693C
*/


My problem is that "jmp newmem" normally becomes a near relative jump when the auto-assembler compiles (5 bytes) but for some reason, under certain conditions, it's becoming a near absolute indirect jump (14 bytes). This is a problem because I'm limited to using just the 10 bytes that belong to add [rdi+38],ebp and mov [rsp+00000118],eax. (I've only added the last 4 bytes to the disable part so it doesn't screw the original gamecode when I disable it, until I figure out how to bypass this)

Now, normally I would just specify the bytes of jmp newmem, except because it's dynamically allocated I need to have the assembler dynamically apply the jump location... and I can't have the assembler dynamically apply the jump location, because it uses a jump type that's too big for my purposes.

Any ideas how I can get around this?

EDIT: My actual request is this: depending on when I activate the code (in relation to the game state) the jump will be *either* relative or absolute indirect. I need to somehow force the assembler to make it a relative jump, but also let the assembler dynamically generate the jump parameter. (If that's even possible)


Last edited by chodness on Sat Sep 03, 2016 3:38 pm; edited 2 times in total
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 83

Joined: 06 Jul 2014
Posts: 2782

PostPosted: Thu Sep 01, 2016 12:15 am    Post subject: Reply with quote

Under what conditions would CE assemble that to a 14-byte jump? Give the virtual address of newmem and the virtual address of the injection point (not module.exe+offset).

Let CE build the basics of the script for you. Highlight the instruction at "ROTTR.exe"+3A76924 and use Template -> AOB Injection.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Dark Byte
Site Admin
Reputation: 384

Joined: 09 May 2003
Posts: 23110
Location: The netherlands

PostPosted: Thu Sep 01, 2016 4:18 am    Post subject: Reply with quote

If your code can somehow generate a 14 byte jmp (e.g you use kernelmode query memory fir some weird reason), then do not use nops/returnhere , but jump to codeinjection+d+possibleoverhead and always use the 14 bytes for the original code (+overhead)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.

Like my help? Join me on Patreon so i can keep helping
Back to top
View user's profile Send private message MSN Messenger
predprey
Master Cheater
Reputation: 19

Joined: 08 Oct 2015
Posts: 478

PostPosted: Thu Sep 01, 2016 4:45 am    Post subject: Reply with quote

i had asked a similar topic before. you can force the jmp type by adding short/long after.

i.e. jmp (short/long) (label/symbol)
Back to top
View user's profile Send private message
chodness
Newbie cheater
Reputation: 0

Joined: 27 Feb 2015
Posts: 23

PostPosted: Thu Sep 01, 2016 8:21 am    Post subject: Reply with quote

@ParkourPenguin: I'm not sure what the conditions are, with respect to memory or system conditions. All I know is, when the game is in the main menu, it creates near relative jumps just fine, but when I'm actually playing the game, it generates near absolute indirect jumps. And letting CE create my base code IS what I do, you can even see it in the basic formatting and comments on the enable and disable parts of the code. I just delete the parts of the base format that I don't use.

@Dark Byte: I'm pretty sure I'm not using kernelmode query memory. My CE is straight-out-of-the-box settings, except I've switched to the VEH debugger because the Windows debugger crashes everything. Could you explain more about the codeinjection+d+possibleoverhead ? That went way over my understanding. I'll see if Google can teach me something about it, as well.

@predprey: I'm not 100% certain that'll work for me, since both types of jump that are being assembled are nears, but I'll give it a shot.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 83

Joined: 06 Jul 2014
Posts: 2782

PostPosted: Thu Sep 01, 2016 9:23 am    Post subject: Reply with quote

chodness wrote:
I'm not sure what the conditions are, with respect to memory or system conditions.

Try looking. Turn off module addresses to see what the virtual address of "ROTTR.exe"+3A76924 is, and either follow the jmp or register newmem as a symbol to find out where newmem is.

chodness wrote:
And letting CE create my base code IS what I do

Minus the leading header and trailing disassembly, this is what a standard AoB injection template looks like:
Code:
[ENABLE]

aobscanmodule(INJECT,Tutorial-x86_64.exe,29 93 90 07 00 00) // should be unique
alloc(newmem,$1000,"Tutorial-x86_64.exe"+2A8B7)

label(code)
label(return)

newmem:

code:
  sub [rbx+00000790],edx
  jmp return

INJECT:
  jmp code
  nop
return:
registersymbol(INJECT)

[DISABLE]

INJECT:
  db 29 93 90 07 00 00

unregistersymbol(INJECT)
dealloc(newmem)

If you use the third parameter to alloc and treat everything as if it should use a near relative jump, CE will assemble it to be a near relative jump.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
chodness
Newbie cheater
Reputation: 0

Joined: 27 Feb 2015
Posts: 23

PostPosted: Sat Sep 03, 2016 3:36 pm    Post subject: Reply with quote

Oh, my mistake, I didn't read the sentence after "under what conditions would...". When it's jumping NAI, it's jumping from (at least under the current conditions) 0143A76937 to 00570000.

Another mistake I made was that I was using the "Code injection" menu option and not the "AoB injection" menu option. As far as I can tell, the only differences are: 1) the former doesn't do an AoB scan, it just injects at that module address, and 2) when it allocates memory, it allocates 2048 bytes, instead of $1000. I'll admit that I don't know the difference between using the $ sign before the number of bytes to be allocated, but beyond that it looks exactly like my original code does, minus my additions to the code post-jump.

Here's the base code after using Code injection:
Code:
[ENABLE]
//code from here to '[DISABLE]' will be used to enable the cheat
alloc(newmem,2048,"ROTTR.exe"+3A76924)
label(returnhere)
label(originalcode)
label(exit)

newmem: //this is allocated memory, you have read,write,execute access
//place your code here

originalcode:
add [rdi+38],ebp
mov [rsp+00000118],eax

exit:
jmp returnhere

"ROTTR.exe"+3A76924:
jmp newmem
nop
nop
nop
nop
nop
returnhere:


 
 
[DISABLE]
//code from here till the end of the code will be used to disable the cheat
dealloc(newmem)
"ROTTR.exe"+3A76924:
add [rdi+38],ebp
mov [rsp+00000118],eax
//Alt: db 01 6F 38 89 84 24 18 01 00 00


And here's the base code after using AoB injection:
Code:
[ENABLE]


aobscanmodule(INJECT,ROTTR.exe,01 6F 38 89 84 24 18 01 00 00) // should be unique
alloc(newmem,$1000,"ROTTR.exe"+3A76924)

label(code)
label(return)

newmem:

code:
  add [rdi+38],ebp
  mov [rsp+00000118],eax
  jmp return

INJECT:
  jmp code
  nop
  nop
  nop
  nop
  nop
return:
registersymbol(INJECT)

[DISABLE]

INJECT:
  db 01 6F 38 89 84 24 18 01 00 00

unregistersymbol(INJECT)
dealloc(newmem)


As far as I can tell, they're pretty much exactly the same thing. However, I'll try using AoB injection instead and edit this post with what I find.

@Dark Byte: I wasn't able to find what you meant by codeinjection+d+possibleoverhead. I'm guessing that codeinjection is the point in memory that I'm injecting into, d is the offset between there and my code cave, and possibleoverhead is any additional bytes to be taken into account, though I don't know what those would be. But, since dynamically generates a code cave in different places, I would have to know in advance where that was being placed, and... that's one way of interpreting my original question: how do I find with any certainty where CE is going to generate my cave, so I can jump directly to it?

EDIT: There's no change. Whether I use code generated by "Code injection" or "AoB injection" it still replaces code at the same point, with a near absolute indirect jump to, in this case, 00570000. I've only tested it during gameplay so far, but my hypothesis is that if I run the script when the game is in the main menu, it'll generate a relative jump. I'm thinking that CE is generating the code cave in a place that I can't jump to with a near relative, though I'm confused about why it would be forced to do that.

EDIT2: Forcing it to jump short or long jumped to incorrect parts of the code.

EDIT3: Since CE was generating my code cave at 00570000 I tried just putting "jmp 00570000" and it did another near absolute indirect jump. Why it would do so, I don't know. Maybe I was right, and that's too far for a near relative jump, maybe I was wrong and it's something else entirely. But that's what I'm here to find out.


Last edited by chodness on Sat Sep 03, 2016 4:23 pm; edited 1 time in total
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 83

Joined: 06 Jul 2014
Posts: 2782

PostPosted: Sat Sep 03, 2016 4:22 pm    Post subject: Reply with quote

Ignore the short/long recommendation; that's for 8-bit vs 32-bit relative addressing.

Are you doing anything abnormal (e.g. aforementioned kernel query memory region)? If not, it should not be possible for CE to allocate that memory in that region. Try testing an SSCCE that only allocates memory around that region.

The point I was trying to get across by telling you to use CE's template was that those comments and db pseudoinstructions were your fabrications. Notice how the template does not have any comments like db E9 ** ** ** ** (I don't know where you got that from). Because you edited out the mistake of using 4 nops instead of 5 like CE told you to do, I'll assume that has no baring on the cause of your problem.

Side note: I originally used the AoB injection template because it's more stable if a new version comes out. Even if you don't use an AoB scan, at least assert the bytes you're overriding so you don't accidentally mess up stuff you didn't mean to.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
chodness
Newbie cheater
Reputation: 0

Joined: 27 Feb 2015
Posts: 23

PostPosted: Sat Sep 03, 2016 4:38 pm    Post subject: Reply with quote

I don't believe I'm doing anything abnormal. Like I mentioned before, I'm using standard settings (minus the change to VEH debugger). Assuming I'm wrong, though, how do I check whether or not I'm using kernelmode query memory region? The only thing I can find is Settings->Extras->Query memory region, which is unchecked.

Also, how do I force CE to only allocate memory around that region? I figured putting the location inside the alloc() call (e.g. alloc(newmem,2048,"ROTTR.exe"+3A76924) ) would do it, but it's still alocating memory outside that region.

EDIT: I tried checking the Query memory region box, just to see what would happen. It loaded dbk64.sys, there was no change in the location of the allocated memory region. I tried restarting CE, and got a page fault in nonpaged area when CE tried to attach to the process. (I'm assuming it was because I didn't reboot with unsigned drivers allowed, like the menu tells me to. I'm also assuming that anything that causes me to crash if I'm not paying attention is not the intended use of CE, so I disabled it again)

As for my original post, I edited it because I realized a couple things: 1) I had the wrong number of 90's to coincide with the number of nop's I wanted. That didn't end up mattering, though I took the base injection template and then replaced the nops with db 90s because I was seeing assembly instructions I didn't want in my memory viewer, and the last time that happened, it was solved by using direct byte writes instead of just opcodes (CE was turning short conditional jumps into near relative jumps - I wanted something like 7F 02 and it was giving me something like E9 ** ** ** ** where the stars were the address for 2 bytes ahead of EIP - which was technically correct, but I was an idiot who was micro-optimizing at the time).

Anyway, 2) all the comments were drawing attention away from my actual issue, which was the comment above "jmp newmem" (which was essentially "why is it generating this 14-byte jmp operation, where the asterisks are the memory location of where to jump, instead of this 5-byte one, where the asterisks are the memory location of where to jump?")
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 83

Joined: 06 Jul 2014
Posts: 2782

PostPosted: Sat Sep 03, 2016 5:01 pm    Post subject: Reply with quote

The 14 byte jmp is being generated because the address you're jumping to is further than 2GB away from the address you're jumping from (i.e. not signed dword encodable = no rel32 jmp).

The third parameter to alloc makes CE allocate memory within 2GB of that region. Unless CE can't understand the symbol "ROTTR.exe"+3A76924 (it should be able to), I can't think of any explanation as to why you can't get this to work. Try removing the quotes and see if it works.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
chodness
Newbie cheater
Reputation: 0

Joined: 27 Feb 2015
Posts: 23

PostPosted: Sat Sep 03, 2016 6:03 pm    Post subject: Reply with quote

It did not work. This time, it allocated closer than previous attempts (jump to 381A0000 from 0143A76924) but that's still outside the 2GB range.

On a side note, is that why older programs that use a lot of memory have to be made large address aware? Because they don't jump outside of a 2GB region of memory?
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 83

Joined: 06 Jul 2014
Posts: 2782

PostPosted: Sat Sep 03, 2016 6:24 pm    Post subject: Reply with quote

At this point, I can only suggest the basic troublshooting stuff. Disable any antivirus software and/or reinstall CE. Neither I nor anyone else (to the best of my knowledge) have had any problems with CE allocating memory where it should with the latest official release.

There's a difference between 32-bit applications and 64-bit applications. Use Google for more information.

_________________
I don't know where I'm going, but I'll figure it out when I get there.
Back to top
View user's profile Send private message
Zanzer
I post too much
Reputation: 123

Joined: 09 Jun 2013
Posts: 3278

PostPosted: Sat Sep 03, 2016 7:43 pm    Post subject: Reply with quote

When you use the AOB Injection CE creates and don't change a thing, the game crashes when it's enabled?
Back to top
View user's profile Send private message
Csimbi
I post too much
Reputation: 77

Joined: 14 Jul 2007
Posts: 2673

PostPosted: Sat Nov 21, 2020 2:58 pm    Post subject: Reply with quote

Hi Guy,
sorry about resurrecting this thread, but I have a problem and I think this thread is the best fit.

So, I have an AA script that injects code into a mono game.
The AA script I generated contains a 5byte jump and a 5byte return jump.

The game is crashing randomly so I started looking around.

What I noticed is that randomly, the jump becomes a 14byte jump.
Not always, say, 40% of the cases.
When this happens, the 14byte jump overwrites tons of code that was supposed to stay there and the return 14byte jump points in the middle of the first jump.

I figured the only way around this sporadic behavior would be forcing the 14byte jump every time.
Question is: how do I force a jump to be a 14byte jump in AA?
Is there a jmp14 command? Razz

Thank you!
Back to top
View user's profile Send private message
panraven
Grandmaster Cheater
Reputation: 35

Joined: 01 Oct 2008
Posts: 837

PostPosted: Sat Nov 21, 2020 4:46 pm    Post subject: Reply with quote

The 'long' jump is make by ce, It is just like there is no actual 'nop 8' instruction but ce created for better disassemble display.

The 'long' jump can be make like
Code:

globalalloc(__,$1000)

__:
jmp  [@b+6]
dq 1001 //// target_address

jmp  [@f]
@@:
dq 1002


ref: https://stackoverflow.com/questions/54745872/how-do-rip-relative-variable-references-like-rip-a-in-x86-64-gas-intel-sy

Since ce don't have rip/rel addressing in assemble format, some label has to be refereed; @@: anonymous label is handy, but be cautious usage of nearby @f and @b.

Another option is to make a registerAssembler to custom assemble jump/call instruction,

1. it has no anonymous label problem
2. automatic short jmp
3. it has the opportunity to create auto-trampoline (seemly solution to multiple mono inject point in same script with one allocation and still keep 5-bytes jump/call),

but it is complicated.


ADDED:

-- obsoleted, try https://forum.cheatengine.org/viewtopic.php?t=616480 --

An attempt (without auto-trampoline)
Code:

if _cutsomJumpCall then
  _cutsomJumpCall = nil,unregisterAssembler(_cutsomJumpCall)
end

_cutsomJumpCall = registerAssembler(function (addr, inst)
--  print(inst)
  local force, target, isJmp = inst:match'^%s*[jJ][mM][pP]!(%a*)%s+(.-)%s*$'
  if target then isJmp = true else
    force, target = inst:match'^%s*[cC][aA][lL][lL]!(%a*)%s+(.-)%s*$'
  end

  target = target and target:len()>1 and GetAddressSafe(target)

  local forceShort, forceNear, forceLong
  if target and force:len()>1 then
    force=force:lower()
    if force=='short' then forceShort = true-- should be redundancy?
    elseif force=='near' then forceNear = true
    elseif force=='long' then forceLong = true
    else target = nil end -- unknown jump distance modifier, error
  end
  if target then
    local cmd = isJmp and {0xeb,0xe9,0x25ff} or {0xe8,0xe8,0x15ff}
---    target = tonumber(target,16)
    local diff, bs = target - addr
    if isJmp and (forceShort or not forceNear and not forceLong) and diff>-0x7e and diff <0x82 then
      bs = string.pack('Bb',cmd[1], diff-2)
    elseif not forceLong and diff>-0x7ffffffb and diff<0x80000005 then
      bs = string.pack('Bi4',cmd[2],diff-5)
    elseif targetIs64Bit() then
      bs = string.pack('I6I8',cmd[3],target)
    else -- 32bit long jump?
      bs = string.pack('I2I4I4',cmd[3],(addr+6)& 0xffffffff,target & 0xffffffff)
    end
    local r = {}
    for c in bs:gmatch'.' do r[1+#r]=c:byte()end
    return r
  end
end)

The target address should be expected to evaluate to a static address, ie. no [...] format and no register etc.
Without the distance modifier after !, it select the shortest form possible, else it force near/long if specified and possible. !short is redundancy I guess.

_________________
- Retarded.


Last edited by panraven on Sun Nov 22, 2020 3:28 pm; edited 5 times in total
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites