 |
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
mgr.inz.Player I post too much
Reputation: 221
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Mon Jun 20, 2016 4:29 pm Post subject: |
|
|
This one?
Code: | if autoAssemble([[alloc(newmem,1024,7ff670daf4ee)
label(justtesting)
registersymbol(justtesting)
newmem:
justtesting:]])
then
print( 'justtesting =',string.format('%x',getAddress("justtesting")) )
end |
_________________
|
|
Back to top |
|
 |
NoMoreBSoD Advanced Cheater
Reputation: 3
Joined: 03 Sep 2013 Posts: 85
|
Posted: Mon Jun 20, 2016 4:31 pm Post subject: |
|
|
The last one gives me :
Code: |
justtesting = 26651870000
justtesting = 26651880000
justtesting = 26651890000 |
I did it 3 times just to test it out.
|
|
Back to top |
|
 |
mgr.inz.Player I post too much
Reputation: 221
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Mon Jun 20, 2016 4:45 pm Post subject: |
|
|
Interesting. Maybe it is win10 thing.
Try this script for two different games. Witcher3 and something else (e.g. Middle-earth: Shadow of Mordor).
Code: | if autoAssemble([[
alloc(newmem1,1024,0010000000)
label(justtesting1)
registersymbol(justtesting1)
alloc(newmem2,1024,0100000000)
label(justtesting2)
registersymbol(justtesting2)
alloc(newmem3,1024,0200000000)
label(justtesting3)
registersymbol(justtesting3)
alloc(newmem4,1024,0300000000)
label(justtesting4)
registersymbol(justtesting4)
newmem1:
justtesting1:
newmem2:
justtesting2:
newmem3:
justtesting3:
newmem4:
justtesting4:
]])
then
print( 'justtesting1 =',string.format('%016x',getAddress("justtesting1")) )
print( 'justtesting2 =',string.format('%016x',getAddress("justtesting2")) )
print( 'justtesting3 =',string.format('%016x',getAddress("justtesting3")) )
print( 'justtesting4 =',string.format('%016x',getAddress("justtesting4")) )
end |
_________________
|
|
Back to top |
|
 |
DarkIceCore Expert Cheater
Reputation: 0
Joined: 10 Jun 2012 Posts: 102 Location: Moscow
|
Posted: Mon Jun 20, 2016 4:57 pm Post subject: |
|
|
mgr.inz.Player wrote: | Interesting. Maybe it is win10 thing.
Try this script for two different games. Witcher3 and something else (e.g. Middle-earth: Shadow of Mordor).
|
Win 7 x64
"Man O'war Corsair" , mono features,
Code: |
justtesting1 = 000000000fee0000
justtesting2 = 0000000100000000
justtesting3 = 0000000200000000
justtesting4 = 0000000300000000
|
|
|
Back to top |
|
 |
NoMoreBSoD Advanced Cheater
Reputation: 3
Joined: 03 Sep 2013 Posts: 85
|
Posted: Mon Jun 20, 2016 5:02 pm Post subject: |
|
|
Here are the results :
Code: | Witcher 3
justtesting1 = 0000000010000000
justtesting2 = 0000000100000000
justtesting3 = 0000000200000000
justtesting4 = 0000000300000000
Batman : Arkham Knight
justtesting1 = 000000001b960000
justtesting2 = 000000001c810000
justtesting3 = 000000001c820000
justtesting4 = 000000001c830000
Star Wars : KOTOR 2
(1st time)
justtesting1 = 0000000007960000
justtesting2 = 000000000a060000
justtesting3 = 000000000a070000
justtesting4 = 000000000a080000
(2nd time with restarting CE and KOTOR)
justtesting1 = 000000000ffd0000
justtesting2 = 000000000cd40000
justtesting3 = 000000000cd50000
justtesting4 = 000000000cd60000
Final Fantasy XIII
justtesting1 = 000000000f0d0000
justtesting2 = 000000000f0f0000
justtesting3 = 000000000f100000
justtesting4 = 000000000f110000
Witcher 3 again just to be sure, after restarting CE and the game
justtesting1 = 0000000010000000
justtesting2 = 0000000100000000
justtesting3 = 0000000200000000
justtesting4 = 0000000300000000 |
Weirdly, Witcher is the only one which produced the addresses you put in assembly.
|
|
Back to top |
|
 |
mgr.inz.Player I post too much
Reputation: 221
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Mon Jun 20, 2016 5:12 pm Post subject: |
|
|
Quote: | Code: | Witcher 3
justtesting1 = 0000000010000000
justtesting2 = 0000000100000000
justtesting3 = 0000000200000000
justtesting4 = 0000000300000000 |
|
It is a good result. It tells us that internal FindFreeBlockForRegion function can find free blocks near preferred region on your machine. It just can not find it for witcher3.exe+9AF4EE. You are forced to use "14 byte jump" plus nops. Or code cave.
"Weirdly, Witcher is the only one which produced the addresses you put in assembly"
because Final Fantasy XIII is a 32bit application.
_________________
|
|
Back to top |
|
 |
NoMoreBSoD Advanced Cheater
Reputation: 3
Joined: 03 Sep 2013 Posts: 85
|
Posted: Mon Jun 20, 2016 7:19 pm Post subject: |
|
|
mgr.inz.Player wrote: | It is a good result. It tells us that internal FindFreeBlockForRegion function can find free blocks near preferred region on your machine. It just can not find it for witcher3.exe+9AF4EE. You are forced to use "14 byte jump" plus nops. Or code cave.
"Weirdly, Witcher is the only one which produced the addresses you put in assembly"
because Final Fantasy XIII is a 32bit application. |
So I reinstalled Shadow of Mordor just to test out CE on another 64 bits game and the results are :
Code: | justtesting1 = 0000000014320000
justtesting2 = 0000000100000000
justtesting3 = 0000000200000000
justtesting4 = 0000000300000000 |
How do I do a 14 bytes jump?
I did read a lot about code caves before I started using CE, but I haven't used them in years. I think those 2 threads will help me solve the problem at hand ( link1, link2).
If I understand correctly, I have to scan for a code cave far away, manually code the jump to and back from while using nops to make sure the code doesn't crash during execution.
Regarding the original problem, it seems like it's caused because CE doesn't look far away enough and/or can't not encode 14 byte jumps
|
|
Back to top |
|
 |
ParkourPenguin I post too much
Reputation: 150
Joined: 06 Jul 2014 Posts: 4654
|
Posted: Mon Jun 20, 2016 9:50 pm Post subject: |
|
|
In a 32-bit process, you can use the near jump (5 bytes) no problem regardless of where the memory is allocated because every address is within 2GB of every other address in a 4GB address space.
In a 64-bit process, however, the virtual address space is much greater than 4GB, so you won't always be able to use the near jump. That's what the third parameter to alloc is for: the computer will try to allocate that memory within 2GB of that address.
In order to jump to a memory location further than 2GB away, you'll need to store the address you want to go to in some r/m64 and use that instead. The 14 byte jump in this case refers to storing the address you want to jump to just after the jmp instruction. This subsequently overrides any instructions in the way and forms all the "garbage" disassembly you see. 6 byte jmp + 8 bytes for the address = 14 bytes overridden.
Thus, when doing a code injection using a 14-byte jump, the only noticeable difference to you is that you'll need to override nearly 3x more instructions. Using the OP as an example, here's how you'd explicitly use a 14-byte jmp:
Code: | [ENABLE]
aobscanmodule(aob_highlight,witcher3.exe,48 8B 39 8B 41 08 45 33 E4 48 8D 0C 80 4C 8B F2) // should be unique
alloc(newmem,$1000,"witcher3.exe"+9AF4EE)
alloc(pointer_highlight,8)
label(return)
registersymbol(pointer_highlight)
registersymbol(aob_highlight)
newmem:
mov [pointer_highlight],rcx
mov rdi,[rcx]
mov eax,[rcx+08]
xor r12d,r12d
lea rcx,[rax+rax*4]
mov r14,rdx
jmp return
aob_highlight:
db FF 25 00 00 00 00
dq newmem
nop
nop
return:
[DISABLE]
aob_highlight:
db 48 8B 39 8B 41 08 45 33 E4 48 8D 0C 80 4C 8B F2
dealloc(newmem)
dealloc(pointer_highlight)
unregistersymbol(pointer_highlight)
unregistersymbol(aob_highlight) |
CE automatically does this when it goes to assemble the instruction "jmp newmem" if newmem is further than 2GB away. However, something obviously isn't working perfectly right now, so do this in order to avoid any ambiguity.
For more technical information, refer to the Intel Software Developer's Manual Volume 2A section 2.2.1.6 "RIP-relative addressing", as well as the documentation on the JMP instruction within said manual (or any other valid x64 reference of your choice).
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
Back to top |
|
 |
Zanzer I post too much
Reputation: 126
Joined: 09 Jun 2013 Posts: 3278
|
Posted: Mon Jun 20, 2016 11:03 pm Post subject: |
|
|
The original code works fine for me. Windows 10, 64-bit.
No problem with ParkourPenguin's code either.
Depending on the address of pointer_highlight, I've been known to have issues with instructions like: Code: | mov [pointer_highlight],rcx |
In those cases, I use: Code: | mov rdi,pointer_highlight
mov [rdi],rcx
mov rdi,[rcx] |
|
|
Back to top |
|
 |
Dark Byte Site Admin
Reputation: 468
Joined: 09 May 2003 Posts: 25708 Location: The netherlands
|
Posted: Tue Jun 21, 2016 2:36 am Post subject: |
|
|
Sorry, i overlooked the important part.
You use kernelmode query memory regions.
You can't use a prefered base with that enabled. (Paged out memory will be seen as free memory, and if you try to allocate on existing memory windows will completely ignore the prefered address)
As for not activating without. Make sure you are on a release build of windows 10. Fast ring and especially insider preview builds are bugged. (Virtualquery returns broken results)
Instead of aobscan use the address witcher3.exe+9AF4EE
_________________
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
Last edited by Dark Byte on Tue Jun 21, 2016 3:01 am; edited 1 time in total |
|
Back to top |
|
 |
mgr.inz.Player I post too much
Reputation: 221
Joined: 07 Nov 2008 Posts: 4438 Location: W kraju nad Wisla. UTC+01:00
|
Posted: Tue Jun 21, 2016 2:54 am Post subject: |
|
|
@Zanzer, Yes, it is problematic when using two injection points which are inside two different modules. (or more)
Also, ordering is important when you have alloc with third parameter and "normal" alloc.
Code: | alloc(newmem1,$1000,cheatengine-x86_64.exe)
alloc(pointer_highlight,8)
alloc(newmem2,$1000,lua53-64.dll) |
Code: | alloc(newmem1,$1000,cheatengine-x86_64.exe)
alloc(newmem2,$1000,lua53-64.dll)
alloc(pointer_highlight,8) |
so, if pointer_highlight is not shared between two injection points (and two modules) better provide third parameter for all alloc. Or just use a label.
If it is shared, you can use "mov [pointer_highlight],rcx" in one module, and "mov rdi,pointer_highlight; mov [rdi],rcx" in another.
NoMoreBSoD wrote: | I'm now using windows 10 |
What "winver" shows?
_________________
Last edited by mgr.inz.Player on Tue Jun 21, 2016 2:56 am; edited 1 time in total |
|
Back to top |
|
 |
DarkIceCore Expert Cheater
Reputation: 0
Joined: 10 Jun 2012 Posts: 102 Location: Moscow
|
Posted: Tue Jun 21, 2016 2:56 am Post subject: |
|
|
ParkourPenguin wrote: | In a 32-bit process, you can use the near jump (5 bytes) no problem regardless of where the memory is allocated because every address is within 2GB of every other address in a 4GB address space.
In a 64-bit process, however, the virtual address space is much greater than 4GB, so you won't always be able to use the near jump. That's what the third parameter to alloc is for: the computer will try to allocate that memory within 2GB of that address.
In order to jump to a memory location further than 2GB away, you'll need to store the address you want to go to in some r/m64 and use that instead. The 14 byte jump in this case refers to storing the address you want to jump to just after the jmp instruction. This subsequently overrides any instructions in the way and forms all the "garbage" disassembly you see. 6 byte jmp + 8 bytes for the address = 14 bytes overridden.
Thus, when doing a code injection using a 14-byte jump, the only noticeable difference to you is that you'll need to override nearly 3x more instructions. Using the OP as an example, here's how you'd explicitly use a 14-byte jmp
CE automatically does this when it goes to assemble the instruction "jmp newmem" if newmem is further than 2GB away. However, something obviously isn't working perfectly right now, so do this in order to avoid any ambiguity.
For more technical information, refer to the Intel Software Developer's Manual Volume 2A section 2.2.1.6 "RIP-relative addressing", as well as the documentation on the JMP instruction within said manual (or any other valid x64 reference of your choice). |
Big thnx for sufficient information, now i solved my problems with injects by myself.
|
|
Back to top |
|
 |
NoMoreBSoD Advanced Cheater
Reputation: 3
Joined: 03 Sep 2013 Posts: 85
|
Posted: Tue Jun 21, 2016 4:49 am Post subject: |
|
|
ParkourPenguin wrote: | In a 32-bit process, you can use the near jump (5 bytes) no problem regardless of where the memory is allocated because every address is within 2GB of every other address in a 4GB address space.
In a 64-bit process, however, the virtual address space is much greater than 4GB, so you won't always be able to use the near jump. That's what the third parameter to alloc is for: the computer will try to allocate that memory within 2GB of that address.
In order to jump to a memory location further than 2GB away, you'll need to store the address you want to go to in some r/m64 and use that instead. The 14 byte jump in this case refers to storing the address you want to jump to just after the jmp instruction. This subsequently overrides any instructions in the way and forms all the "garbage" disassembly you see. 6 byte jmp + 8 bytes for the address = 14 bytes overridden.
Thus, when doing a code injection using a 14-byte jump, the only noticeable difference to you is that you'll need to override nearly 3x more instructions. Using the OP as an example, here's how you'd explicitly use a 14-byte jmp:
CE automatically does this when it goes to assemble the instruction "jmp newmem" if newmem is further than 2GB away. However, something obviously isn't working perfectly right now, so do this in order to avoid any ambiguity.
For more technical information, refer to the Intel Software Developer's Manual Volume 2A section 2.2.1.6 "RIP-relative addressing", as well as the documentation on the JMP instruction within said manual (or any other valid x64 reference of your choice). |
This is incredibly helpful! You've solved the problem and explained it to me in a way that makes sense! Now I can even manually update the other scripts myself
To recap :
A 16 bytes jump isn't shown as such in memory viewer and looks like random garbage. "FF 25 00 00 00 00" is the 6 bytes code that initiates an 8 bytes jump and must be followed by an 8 bytes address. This makes 14 bytes, and my injection point needs to be at least that long without breaking any existing instruction.
I nop the extra bytes (after 14) from those instructions when creating my jump.
"db FF 25 00 00 00 00" means jump to, and "dq newmem" means get the address of newmem.
Dark Byte wrote: | Sorry, i overlooked the important part.
You use kernelmode query memory regions.
You can't use a prefered base with that enabled. (Paged out memory will be seen as free memory, and if you try to allocate on existing memory windows will completely ignore the prefered address)
As for not activating without. Make sure you are on a release build of windows 10. Fast ring and especially insider preview builds are bugged. (Virtualquery returns broken results)
Instead of aobscan use the address witcher3.exe+9AF4EE | So another solution is to skip aobscan on 64 bits game? i'll try this.
mgr.inz.Player wrote: | What "winver" shows? |
Here is what I have :
I haven't done any change to windows.
Thanks for helping me everybody, it's really appreciated! I couldn't have solved it myself
|
|
Back to top |
|
 |
hhhuut Grandmaster Cheater
Reputation: 6
Joined: 08 Feb 2015 Posts: 607
|
Posted: Tue Jun 21, 2016 4:51 am Post subject: |
|
|
NoMoreBSoD wrote: | So another solution is to skip aobscan on 64 bits game? |
No, AOB-Scans within 64bit applications work fine as long as you use the regular windows version of the memoryquery routine, not CE's one ...
|
|
Back to top |
|
 |
NoMoreBSoD Advanced Cheater
Reputation: 3
Joined: 03 Sep 2013 Posts: 85
|
Posted: Tue Jun 21, 2016 4:53 am Post subject: |
|
|
hhhuut wrote: | NoMoreBSoD wrote: | So another solution is to skip aobscan on 64 bits game? |
No, AOB-Scans within 64bit applications work fine as long as you use the regular windows version of the memoryquery routine, not CE's one ... | But the regular windows version doesn't return anything at all when I scan for an array or when I do "find what accesses this address".
|
|
Back to top |
|
 |
|
|
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
|
|