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 


Copying newmem1 to newmem2?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine
View previous topic :: View next topic  
Author Message
Arcansel
Cheater
Reputation: 0

Joined: 04 Jun 2022
Posts: 28

PostPosted: Fri Aug 26, 2022 1:56 am    Post subject: Copying newmem1 to newmem2? Reply with quote

Can you copy everything inside newmem1 to newmem2? it is not pratical having to paste the same code of newmem1 to newmem2 everytime, i tried using reamem and it seems there is a limit to how many bytes you can copy, i tried messing around in Lua with writeBytes and readBytes but didnt work, not sure if it is because Lua is faster than asm and since i am allocating the newmems in asm because itm gives me errors when i try to deallocate it in Lua due to my limited knowledge. Can anyone help here? Also do ask for more info if you need it to solve the problem.
Back to top
View user's profile Send private message
LeFiXER
Grandmaster Cheater Supreme
Reputation: 20

Joined: 02 Sep 2011
Posts: 1069
Location: 0x90

PostPosted: Fri Aug 26, 2022 6:58 am    Post subject: Reply with quote

It would be helpful to show your script currently.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4708

PostPosted: Fri Aug 26, 2022 12:06 pm    Post subject: Reply with quote

Arcansel wrote:
it is not pratical having to paste the same code of newmem1 to newmem2 everytime
That's what functions are for. I don't know what you're trying to do, but there's probably a better way of doing it.
_________________
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
Arcansel
Cheater
Reputation: 0

Joined: 04 Jun 2022
Posts: 28

PostPosted: Fri Aug 26, 2022 7:05 pm    Post subject: Reply with quote

LeFiXER wrote:
It would be helpful to show your script currently.


Here is my whole script,

let me summarize, i'm recording every character unique ID to filter out from the enemies so that i can give godmode to my allies and instakill for the enemies, i plan to have instakill on its own script and removing from here later so i am not using atm. The problem as you will see is that there are 2 newmems with the exact same data with the diference between 1 and 2 ofc, and the reason why is that this is an emulated game and it needs 2 instructions to be exactly the same in order for the change to happen which is sucks, these i found these instruction by "find out what writes to this address", so they only show up when i get hit, the first instruction shows up with 1 attack, the second shows up after 4 attacks on my character, i did try all the instructions from "find what accesses this address" but it only applies to my character and the godmode breaks when it swaps characters because the addresses of the characters that swap get reallocated, also, i can't have characters that were not unlocked yet have the godmode script checking for them or the game crashes. The script works in AA, i mixed it with Lua because it is faster to activate.

Note: I just noticed that the lines that have tonumber probably arent needed anymore.
Code:

{$lua}
if syntaxcheck then return end

[ENABLE]
scan1 = AOBScan("B8 D0 2E 17 08 49 89 87 00 01 00 00 E9 ?? ?? ?? FD")[0]
scan2 = AOBScan("B8 D0 2E 17 08 49 89 87 00 01 00 00 E9 ?? ?? ?? F?")[1]

offset1 = tonumber(scan1,16)
offset1 = offset1 - 0x34
offset2 = tonumber(scan2,16)
offset2 = offset2 - 0x34

registerSymbol("HEALTH1",offset1)
registerSymbol("HEALTH2",offset2)

AA =
[[
  alloc(newmem,$1000,HEALTH1)
  alloc(newmem2,$1000,HEALTH2)
  label(code)
  label(return)
  label(code2)
  label(return2)

  ////////////////////1st Instruction/////////////////////////////////////
  newmem:

  //Character IDs
  cmp dword ptr [r13+rax+58],00010000 //Main Character
  je code
  cmp dword ptr [r13+rax+58],00040000 //Edelgard
  je code
  cmp dword ptr [r13+rax+58],00050000 //Hubert
  je code
  cmp dword ptr [r13+rax+58],00070000 //Ferdinand
  je code
/*
  cmp dword ptr [r13+rax+58],00090000 //Caspar
  je code
  cmp dword ptr [r13+r12+58],000A0000 //Petra
  je code
*/
  cmp dword ptr [r13+rax+58],000C0000 //Dimitri
  je code
  cmp dword ptr [r13+rax+58],00140000 //Claude
  je code
  cmp dword ptr [r13+rax+58],002E0100 //Jeritza
  je code
  cmp dword ptr [r13+rax+58],003B0000 //Monica
  je code

  //Normal Code
  mov [r13+rax+00],r12
  jmp return

  //Instakill
  movss xmm0,[r13+rax+04]
  movss xmm1,[r13+rax+00]
  subss xmm1,xmm0
  movss [r13+rax+00],xmm1
  jmp return

  //Godmode
  code:
  mov [r13+rax+00],461c3c00
  jmp return

  ///////////////////////2nd instruction/////////////////////////////////////////////
  newmem2:

  //Character
  cmp dword ptr [r13+rax+58],00010000 //Main Character
  je code2
  cmp dword ptr [r13+rax+58],00040000 //Edelgard
  je code2
  cmp dword ptr [r13+rax+58],00050000 //Hubert
  je code2
  cmp dword ptr [r13+rax+58],00070000 //Ferdinand
  je code2
/*
  cmp dword ptr [r13+rax+58],00090000 //Caspar
  je code2
  cmp dword ptr [r13+r12+58],000A0000 //Petra
  je code2
*/
  cmp dword ptr [r13+rax+58],000C0000 //Dimitri
  je code2
  cmp dword ptr [r13+rax+58],00140000 //Claude
  je code2
  cmp dword ptr [r13+rax+58],002E0100 //Jeritza
  je code2
  cmp dword ptr [r13+rax+58],003B0000 //Monica
  je code2

  //Normal Code
  mov [r13+rax+00],r12
  jmp return2

  //Instakill
  movss xmm0,[r13+rax+04]
  movss xmm1,[r13+rax+00]
  subss xmm1,xmm0
  movss [r13+rax+00],xmm1
  jmp return2

  //Godmode
  code2:
  mov [r13+rax+00],461c3c00
  jmp return2

  //////////////////////////////////////////////////////////////////////////
  HEALTH1:
    jmp newmem
  return:

  HEALTH2:
    jmp newmem2
  return2:
]]

autoAssemble(AA)

[DISABLE]
writeBytes(offset1, 0x43, 0x8B, 0x44, 0x25, 0x00)
unregisterSymbol("HEALTH1")
scan1 = nil
offset1 = nil
writeBytes(offset2, 0x43, 0x8B, 0x44, 0x25, 0x00)
unregisterSymbol("HEALTH2")
scan2 = nil
offset2 = nil

{$asm}
dealloc(*)


ParkourPenguin wrote:
Arcansel wrote:
it is not pratical having to paste the same code of newmem1 to newmem2 everytime
That's what functions are for. I don't know what you're trying to do, but there's probably a better way of doing it.


I completely agree with you, i come from a C#, Unity background and reusing is a must, but i am learning little by little Asm and Lua to hopefully understand it better and better, until then i m trial and erroring a lot and checking for info here and there.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4708

PostPosted: Fri Aug 26, 2022 7:59 pm    Post subject: Reply with quote

Thank you for checking the syntaxcheck variable- few people do that.

Local variables exist in Lua and you should prefer them over globals.

That "Instakill" code will never get executed. (see the previous jmp return)

The final `dealloc(*)` does nothing. No memory was allocated in the top-level AA invocation.

Calling autoAssemble in a {$lua} block inside the auto assembler is almost always unnecessary and just leads to problems. I'd have the {$lua} block return `define(...)`s for the aobscans and keep everything else in the top-level AA.

If it really is the exact same, you could almost simply have the second injection point jump directly to the first injection point's code. Two main problems: the return address (simple, use call, RSP isn't accessed so there's nothing to worry about), and RIP-relative addressing (if the alloc isn't within 2GiB of both injection points, bad things happen; use a trampoline).
Something like this:
Code:
[ENABLE]
{$lua}
if syntaxcheck then return [[
define(HEALTH1,0)
define(HEALTH2,0)
]]
end

-- note: maybe use AOBScan("...", "+X-C-W") to speed up scans further
local scan1 = AOBScan("B8 D0 2E 17 08 49 89 87 00 01 00 00 E9 ?? ?? ?? FD")
local scan2 = AOBScan("B8 D0 2E 17 08 49 89 87 00 01 00 00 E9 ?? ?? ?? F?")
assert(scan1, 'Could not find AOB1')
assert(scan2 and scan2.Count >= 2, 'Could not find AOB2')

local addr1 = getAddress(scan1[0])
local addr2 = getAddress(scan2[1])

scan1.destroy()
scan2.destroy()

return ([[
define(HEALTH1,%08X)
define(HEALTH2,%08X)
]]):format(addr1 - 0x34, addr2 - 0x34)
{$asm}

alloc(newmem,$1000,HEALTH1)
alloc(newmem2,$1000,HEALTH2)
registersymbol(HEALTH1)
registersymbol(HEALTH2)

label(injection)
label(code)
label(return)
label(return2)

newmem:
  call injection
  jmp return

db CC
injection:
  //Character IDs
  cmp dword ptr [r13+rax+58],00010000 //Main Character
  je code
  cmp dword ptr [r13+rax+58],00040000 //Edelgard
  je code
  cmp dword ptr [r13+rax+58],00050000 //Hubert
  je code
  cmp dword ptr [r13+rax+58],00070000 //Ferdinand
  je code
/*
  cmp dword ptr [r13+rax+58],00090000 //Caspar
  je code
  cmp dword ptr [r13+r12+58],000A0000 //Petra
  je code
*/
  cmp dword ptr [r13+rax+58],000C0000 //Dimitri
  je code
  cmp dword ptr [r13+rax+58],00140000 //Claude
  je code
  cmp dword ptr [r13+rax+58],002E0100 //Jeritza
  je code
  cmp dword ptr [r13+rax+58],003B0000 //Monica
  je code

  //Normal Code
  mov [r13+rax+00],r12
  ret

  //Instakill
  movss xmm0,[r13+rax+04]
  movss xmm1,[r13+rax+00]
  subss xmm1,xmm0
  movss [r13+rax+00],xmm1
  ret

  //Godmode
code:
  mov [r13+rax+00],461c3c00
  ret

newmem2:
  call injection  // CE 7.4 can assemble this as a pseudoinstruction if the
                  // target is more than 2GiB away; extra bytes are benign here
  jmp return2


HEALTH1:
  jmp newmem
return:

HEALTH2:
  jmp newmem2
return2:

[DISABLE]

HEALTH1:
  db 43 8B 44 25 00

HEALTH2:
  db 43 8B 44 25 00

unregistersymbol(HEALTH1)
unregistersymbol(HEALTH2)
dealloc(*)

_________________
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
Arcansel
Cheater
Reputation: 0

Joined: 04 Jun 2022
Posts: 28

PostPosted: Fri Aug 26, 2022 9:15 pm    Post subject: Reply with quote

ParkourPenguin wrote:
Thank you for checking the syntaxcheck variable- few people do that.

Local variables exist in Lua and you should prefer them over globals.

That "Instakill" code will never get executed. (see the previous jmp return)

The final `dealloc(*)` does nothing. No memory was allocated in the top-level AA invocation.

Calling autoAssemble in a {$lua} block inside the auto assembler is almost always unnecessary and just leads to problems. I'd have the {$lua} block return `define(...)`s for the aobscans and keep everything else in the top-level AA.

If it really is the exact same, you could almost simply have the second injection point jump directly to the first injection point's code. Two main problems: the return address (simple, use call, RSP isn't accessed so there's nothing to worry about), and RIP-relative addressing (if the alloc isn't within 2GiB of both injection points, bad things happen; use a trampoline).
Something like this:
Code:
[ENABLE]
{$lua}
if syntaxcheck then return [[
define(HEALTH1,0)
define(HEALTH2,0)
]]
end

-- note: maybe use AOBScan("...", "+X-C-W") to speed up scans further
local scan1 = AOBScan("B8 D0 2E 17 08 49 89 87 00 01 00 00 E9 ?? ?? ?? FD")
local scan2 = AOBScan("B8 D0 2E 17 08 49 89 87 00 01 00 00 E9 ?? ?? ?? F?")
assert(scan1, 'Could not find AOB1')
assert(scan2 and scan2.Count >= 2, 'Could not find AOB2')

local addr1 = getAddress(scan1[0])
local addr2 = getAddress(scan2[1])

scan1.destroy()
scan2.destroy()

return ([[
define(HEALTH1,%08X)
define(HEALTH2,%08X)
]]):format(addr1 - 0x34, addr2 - 0x34)
{$asm}

alloc(newmem,$1000,HEALTH1)
alloc(newmem2,$1000,HEALTH2)
registersymbol(HEALTH1)
registersymbol(HEALTH2)

label(injection)
label(code)
label(return)
label(return2)

newmem:
  call injection
  jmp return

db CC
injection:
  //Character IDs
  cmp dword ptr [r13+rax+58],00010000 //Main Character
  je code
  cmp dword ptr [r13+rax+58],00040000 //Edelgard
  je code
  cmp dword ptr [r13+rax+58],00050000 //Hubert
  je code
  cmp dword ptr [r13+rax+58],00070000 //Ferdinand
  je code
/*
  cmp dword ptr [r13+rax+58],00090000 //Caspar
  je code
  cmp dword ptr [r13+r12+58],000A0000 //Petra
  je code
*/
  cmp dword ptr [r13+rax+58],000C0000 //Dimitri
  je code
  cmp dword ptr [r13+rax+58],00140000 //Claude
  je code
  cmp dword ptr [r13+rax+58],002E0100 //Jeritza
  je code
  cmp dword ptr [r13+rax+58],003B0000 //Monica
  je code

  //Normal Code
  mov [r13+rax+00],r12
  ret

  //Instakill
  movss xmm0,[r13+rax+04]
  movss xmm1,[r13+rax+00]
  subss xmm1,xmm0
  movss [r13+rax+00],xmm1
  ret

  //Godmode
code:
  mov [r13+rax+00],461c3c00
  ret

newmem2:
  call injection  // CE 7.4 can assemble this as a pseudoinstruction if the
                  // target is more than 2GiB away; extra bytes are benign here
  jmp return2


HEALTH1:
  jmp newmem
return:

HEALTH2:
  jmp newmem2
return2:

[DISABLE]

HEALTH1:
  db 43 8B 44 25 00

HEALTH2:
  db 43 8B 44 25 00

unregistersymbol(HEALTH1)
unregistersymbol(HEALTH2)
dealloc(*)


Hey thanks for the help, local variables better used than globals? Gotcha.

The instakill i know that, it is intentional, i wrote in the post above i intend to use it in a separate script later, right now is just there to be "saved" or applied if i remove the normal code part.

The final dealloc isn't doing anything, hmm, okay i will remove it, i though it was deallocating the newmems that i allocated inside the autoAssemble(AA).

Using autoAssemble can lead to problems? Okay, so far i ve been okay, i don't see much diference from doing {$lua} or {$asm} atm though, so i am fine either way, still, good to know.

In the AOBScan part you say:

"-- note: maybe use AOBScan("...", "+X-C-W") to speed up scans further"

Does it mean to add the +X-C-W" part exactly as it is or is it something i have to change there? And what do those letters mean?

I will try out the changed script and then report how it went.
Back to top
View user's profile Send private message
ParkourPenguin
I post too much
Reputation: 152

Joined: 06 Jul 2014
Posts: 4708

PostPosted: Fri Aug 26, 2022 9:21 pm    Post subject: Reply with quote

Arcansel wrote:
Does it mean to add the +X-C-W" part exactly as it is or is it something i have to change there? And what do those letters mean?

It's an optional second argument to AOBScan. celua.txt:
Code:
AOBScan("aobstring", protectionflags OPTIONAL, alignmenttype OPTIONAL, alignmentparam HALFOPTIONAL):
protectionflags is a string.
  X=Executable W=Writable memory C=Copy On Write. Add a + to indicate that flag MUST be set and a - to indicate that that flag MUST NOT be set. (* sets it to don't care)
  Examples:
    +W-C = Writable memory exluding copy on write and doesn't care about the Executable flag
    +X-C-W = Find readonly executable memory
    +W = Finds all writable memory and don't care about copy on write or execute
    "" = Find everything (is the same as "*X*C*W" )
...
If you're scanning for code, the code is probably protected as readonly executable memory. A lot of memory is marked as writable, so if you only scan through memory that's non-writable (i.e. readonly), scans will be faster.
_________________
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
Arcansel
Cheater
Reputation: 0

Joined: 04 Jun 2022
Posts: 28

PostPosted: Sat Aug 27, 2022 9:11 am    Post subject: Reply with quote

ParkourPenguin wrote:
Arcansel wrote:
Does it mean to add the +X-C-W" part exactly as it is or is it something i have to change there? And what do those letters mean?

It's an optional second argument to AOBScan. celua.txt:
Code:
AOBScan("aobstring", protectionflags OPTIONAL, alignmenttype OPTIONAL, alignmentparam HALFOPTIONAL):
protectionflags is a string.
  X=Executable W=Writable memory C=Copy On Write. Add a + to indicate that flag MUST be set and a - to indicate that that flag MUST NOT be set. (* sets it to don't care)
  Examples:
    +W-C = Writable memory exluding copy on write and doesn't care about the Executable flag
    +X-C-W = Find readonly executable memory
    +W = Finds all writable memory and don't care about copy on write or execute
    "" = Find everything (is the same as "*X*C*W" )
...
If you're scanning for code, the code is probably protected as readonly executable memory. A lot of memory is marked as writable, so if you only scan through memory that's non-writable (i.e. readonly), scans will be faster.


Good good, i tested the script, it is working fine, there was something i did wrong, i swapped the original bytes from another script lol, so it was restoring the wrong ones when i disabled it, i fixed it now, just letting ppl who read it know, those bytes are wrong. Now all i need is to hook the swapping characters addresses through script somehow, i intend to add addresses below this script so that they load the characters values at all times, i fear the godmode wont go that far because it crashes the game if you don't have the character yet and also the godmode does not apply for characters that arent near the character you are controlling for some reason.
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
Page 1 of 1

 
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