|
Cheat Engine The Official Site of Cheat Engine
|
View previous topic :: View next topic |
Author |
Message |
TDWL Newbie cheater Reputation: 0
Joined: 28 Jan 2020 Posts: 10
|
Posted: Sat Jan 01, 2022 2:26 pm Post subject: How to write a specific amount of 00 bytes to memory |
|
|
Hi, a bit of context. For my AA scripts instead of allocating memory for all of them I like to allocate once and use that memory for all my injections. So I'll normally do something like this:
Code: |
[ENABLE]
alloc(myMem,$1000)
registersymbol(myMem)
define(assertionBytes, DE AD BE E7 BE EF 70 70)
registersymbol(assertionBytes)
myMem:
db assertionBytes
[DISABLE]
dealloc(myMem)
unregistersymbol(myMem)
unregistersymbol(assertionBytes)
|
for allocating my general memory, and then for my scripts I do:
Code: |
[ENABLE]
assert(myMem,assertionBytes)
define(currentMem,myMem+10)
aobscan(infMoney,48 63 8E 74 02 00 00) // should be unique
registersymbol(infMoney)
label(return)
currentMem:
mov [rsi+274],(int)1000000
movsxd rcx,dword ptr [rsi+00000274]
jmp return
infMoney:
jmp currentMem
nop 2
return:
[DISABLE]
infMoney:
db 48 63 8E 74 02 00 00
unregistersymbol(infMoney)
|
I know this is not necessary at all but I like it this way.
However, there is a problem when disabling the scripts. As I'm leaving the code I wrote to myMem intact, It sometimes causes problems with the AOB scan. In this case for example I'm doing a scan for 48 63 8E 74 02 00 00, which corresponds to the instruction movsxd rcx,dword ptr [rsi+00000274] which I'm not modifying, so after I disable my script there will now be two results for the AOB scan.
What I want to do to solve this issue is to rewrite with 00 all the bytes I wrote to myMem in the infMoney script. But I'm having trouble achieving this. What I tried was to add a currentMemEnd label like so:
Code: |
label(currentMemEnd)
currentMem:
mov [rsi+274],(int)1000000
movsxd rcx,dword ptr [rsi+00000274]
jmp return
currentMemEnd:
|
si I could get the ammount of bytes my instructions use by doing currentMemEnd-currentMem. So I added this to my disable section:
Code: |
define(rewriteBytes,currentMem-currentMemEnd)
currentMem:
nop rewriteBytes
|
But, first of all, this throws and error saying "Not all code is injectable. (Error in line 38 (nop currentMemEnd-ffffffffffffffff):This instruction can't be compiled". And secondly, nop is actually 90 not 00, which still works but isn't what I want because it looks uglier when looking at the allocated memory. I wanted something like db 00 times rewriteBytes.
Ideally I'd like to do it without plain AA code, but not sure if it's possible. If not, a for loop with Lua or C to get my array of 00 bytes should probably work, but I'm also not sure what the syntax for this would be.
Anyways, sorry for the long post and any help is appreciated!
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Sat Jan 01, 2022 3:10 pm Post subject: |
|
|
I really hope you use the 3th alloc parameter to allocate nearby else your scripts are going to cause issues, as it doesn't look like you're saving 14 bytes for the jmp
anyhow,
Code: |
{$lua}
local s='db '
for i=1,bytelength do
s=s..'0 '
end
return s
{$asm}
|
will return a db command with 'bytelength' 0's
the only issue is automatically getting the size so you'll have to keep track of that
_________________
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 |
|
|
TDWL Newbie cheater Reputation: 0
Joined: 28 Jan 2020 Posts: 10
|
Posted: Sat Jan 01, 2022 4:38 pm Post subject: |
|
|
Thanks for the help Dark Byte. Does returning s run the db command automatically, or what should I do with the returned value?
Quote: | the only issue is automatically getting the size so you'll have to keep track of that |
For this I was trying to use define(bytelength,currentMem-currentMemEnd), but that doesn't seem to work, could that be done in Lua? (currentMem and currentMemEnd are labels storing the address of the beginning and ending of the injection respectively).
Quote: | I really hope you use the 3th alloc parameter to allocate nearby else your scripts are going to cause issues |
I usually do, but this game doesn't have a module name (all instructions just appear as 19C43157470 for example), so I don't really know what I would put as third parameter.
Quote: | as it doesn't look like you're saving 14 bytes for the jmp |
I'm not really sure what this means.
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 457
Joined: 09 May 2003 Posts: 25262 Location: The netherlands
|
Posted: Sat Jan 01, 2022 5:14 pm Post subject: |
|
|
lua blocks get replaced by the string they return. The result then gets parsed by the assembler in the assembler pass
for alloc you can give as 3th parameter the address you're going to overwrite
If you don't allocate nearby the jmp instruction can be 14 bytes long
So if you only restore 5+overhead you're going to get issues
_________________
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 |
|
|
ParkourPenguin I post too much Reputation: 138
Joined: 06 Jul 2014 Posts: 4275
|
Posted: Sat Jan 01, 2022 7:52 pm Post subject: |
|
|
The "normal" jump instruction takes up 5 bytes: 1 byte for the opcode, and 4 for the 32-bit signed displacement from RIP (address of the next instruction). A 32-bit displacement means it can only jump to addresses within 2 GiB of the next instruction.
The address space of 64-bit processes is far greater than 4 GiB. This means you can't jump to any address you want using that 5-byte jump.
If you try to jump to some place more than 2 GiB away, CE cheats and assembles a pseudoinstruction that will work but takes up 14 bytes of memory. This can obviously cause problems if you weren't expecting the injection point to consume 14 bytes of original code. Even finding a good injection point using a 14-byte jump can be problematic (e.g. can't be any jumps into the middle of the injection point).
This is what the third parameter to alloc solves: CE will allocate memory well within 2 GiB of the specified address so that it can always safely use the 5 byte jump. You can use the result of an aobscan for the third parameter:
Code: | aobscan(foo,xx xx)
alloc(bar,4096,foo) |
Using only one alloc, there's no guarantee all your injection points will be within 2 GiB of your code, so you'll have to assume a 14-byte jump.
TDWL wrote: | I know this is not necessary at all but I like it this way. | Why?
_________________
I don't know where I'm going, but I'll figure it out when I get there. |
|
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
|
|