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 


Injecting player set values via assembly?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking
View previous topic :: View next topic  
Author Message
Valatros
Cheater
Reputation: 1

Joined: 21 Nov 2015
Posts: 36

PostPosted: Mon Apr 02, 2018 2:25 pm    Post subject: Injecting player set values via assembly? Reply with quote

I have an assembly code (well, actually, someone else found it, but regardless), enclosed below. What I would like, is instead of the values already present, which I have to manually go in and change the script, I could set a variable which reads the value that the player sets elsewhere on the cheat table.

Code:
[ENABLE]

aobscanmodule(SYNTH3,Atelier_Lydie_and_Suelle.exe,41 0F 11 85 B8 00 00 00 0F) // should be unique
alloc(newmem,$1000,"Atelier_Lydie_and_Suelle.exe"+E5B62)

label(code)
label(return)

newmem:

code:
  movups [r13+000000B8],xmm0
  mov [r13+000000b8],#20  //set saturn to value
  mov [r13+000000bc],#20  //set sun to value
  mov [r13+000000c0],#20  //set moon to value
  mov [r13+000000c4],#20  //add value to quantity
  jmp return

SYNTH3:
  jmp newmem
  nop
  nop
  nop
return:
registersymbol(SYNTH3)

[DISABLE]

SYNTH3:
  db 41 0F 11 85 B8 00 00 00

unregistersymbol(SYNTH3)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B62

"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
"Atelier_Lydie_and_Suelle.exe"+E5B85: 48 8B C8                 -  mov rcx,rax
"Atelier_Lydie_and_Suelle.exe"+E5B88: E8 73 4F FF FF           -  call Atelier_Lydie_and_Suelle.exe+DAB00
"Atelier_Lydie_and_Suelle.exe"+E5B8D: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B90: 48 8B 48 48              -  mov rcx,[rax+48]
}


With my very minimal programming knowledge I'm thinking something along the lines of the variables SaturnValue, QuantityValue, etcetera. Those values would be from a... header? not a memory address, just an entry on the cheat table players could set the value to quickly and easily, and the script would read from whenever it was executed. If possible I'd like this to work even if I changed the value while leaving the code active, but I imagine once the code is injected that's it, variables are set, so on Enable is fine too.

Just showing me how to do it is fine, but if you don't mind fully explaining the process I'd love to gain what insights I can into the assembly code injection process; I only know a little bit of LUA, so while I understand the general concept of the code above and how it works, I couldn't make it myself even if I knew the addresses to edit.
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Mon Apr 02, 2018 2:39 pm    Post subject: This post has 1 review(s) Reply with quote

Code:
[ENABLE]

aobscanmodule(SYNTH3,Atelier_Lydie_and_Suelle.exe,41 0F 11 85 B8 00 00 00 0F) // should be unique
alloc(newmem,$1000,"Atelier_Lydie_and_Suelle.exe"+E5B62)

label(code)
label(return)

label(intSYNTH3)  //// make a label for the value
registerSymbol(intSYNTH3)  //// register it as a user symbol so it can be accessed else where.

newmem:
   code:
      movups [r13+000000B8],xmm0
      push rax  ////  save/push the registry's value on the stack
      mov eax,[intSYNTH3]  //// set EAX (32 bits of RAX) to the value at the address of intSYNTH3
      mov [r13+000000b8],eax  //set saturn to value
      mov [r13+000000bc],eax  //set sun to value
      mov [r13+000000c0],eax  //set moon to value
      mov [r13+000000c4],eax  //add value to quantity
      pop rax  ////  restore/pop the registry's value from the stack
      jmp return
   align 10 CC //// Not required but makes the value easy to see in the memory viewer.
   intSYNTH3: ////  intSYNTH3 (type: 4 bytes) can be used as an address for a memory record on the cheat table.
      dd (int)20  //// "#20" works just fine I just like "(int)20" better my self.


SYNTH3:
   jmp newmem
   nop
   nop
   nop
return:
registersymbol(SYNTH3)

[DISABLE]

SYNTH3:
   db 41 0F 11 85 B8 00 00 00

unregistersymbol(SYNTH3)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B62

"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
"Atelier_Lydie_and_Suelle.exe"+E5B85: 48 8B C8                 -  mov rcx,rax
"Atelier_Lydie_and_Suelle.exe"+E5B88: E8 73 4F FF FF           -  call Atelier_Lydie_and_Suelle.exe+DAB00
"Atelier_Lydie_and_Suelle.exe"+E5B8D: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B90: 48 8B 48 48              -  mov rcx,[rax+48]
}

_________________
Back to top
View user's profile Send private message Visit poster's website
Valatros
Cheater
Reputation: 1

Joined: 21 Nov 2015
Posts: 36

PostPosted: Mon Apr 02, 2018 5:23 pm    Post subject: Reply with quote

Awesome, thanks. So if I wanted to expand it so that I could set each one individually, I'd edit it like... so?

Code:
[ENABLE]

aobscanmodule(SYNTH3,Atelier_Lydie_and_Suelle.exe,41 0F 11 85 B8 00 00 00 0F) // should be unique
alloc(newmem,$1000,"Atelier_Lydie_and_Suelle.exe"+E5B62)

label(code)
label(return)

label(intSATURN)  //// make a label for the value
registerSymbol(intSATURN)  //// register it as a user symbol so it can be accessed else where.
label(intSUN)
registerSymbol(intSUN)
label(intMOON)
registerSymbol(intMOON)
label(intQUANTITY)
registerSymbol(intQUANTITY)

newmem:
   code:
      movups [r13+000000B8],xmm0
      push rax  ////  save/push the registry's value on the stack
      mov eax,[intSATURN]  //// set EAX (32 bits of RAX) to the value at the address of SATURN
      mov [r13+000000b8],eax  //set saturn to value
      mov eax,[intSUN]
      mov [r13+000000bc],eax  //set sun to value
      mov eax,[intMOON]
      mov [r13+000000c0],eax  //set moon to value
      mov eax,[intQUANTITY]
      mov [r13+000000c4],eax  //add value to quantity
      pop rax  ////  restore/pop the registry's value from the stack
      jmp return
   align 10 CC //// Not required but makes the value easy to see in the memory viewer.
   intSATURN: ////  intSATURN (type: 2 bytes) can be used as an address for a memory record on the cheat table.
      dw (int)20  //// "#20" works just fine I just like "(int)20" better my self.
   intSUN
      dw (int)20  //// "#20" works just fine I just like "(int)20" better my self.
   intMOON
      dw (int)20
   intQUANTITY
      dw (int)20
SYNTH3:
   jmp newmem
   nop
   nop
   nop
return:
registersymbol(SYNTH3)

[DISABLE]

SYNTH3:
   db 41 0F 11 85 B8 00 00 00

unregistersymbol(SYNTH3)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B62

"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
"Atelier_Lydie_and_Suelle.exe"+E5B85: 48 8B C8                 -  mov rcx,rax
"Atelier_Lydie_and_Suelle.exe"+E5B88: E8 73 4F FF FF           -  call Atelier_Lydie_and_Suelle.exe+DAB00
"Atelier_Lydie_and_Suelle.exe"+E5B8D: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B90: 48 8B 48 48              -  mov rcx,[rax+48]
}


Did I do that right? Then I'd just make 4 entries with the address set to "intSaturn", "intMOON", etc. and all four would be separately editable? I'd test to know but I'm not actually at my home computer for that at the moment and I really don't understand how the memory allocation works well enough to know if its overwriting itself in that mess or not.

Oh, I also switched the dd to dw at the end since I'm editing 2-byte values. Does that mess anything up/matter?
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Mon Apr 02, 2018 7:21 pm    Post subject: Reply with quote

The main thing is for the labels they need a colon (:) for the declaration; and if working on 2 bytes you can just use AX.

Code:
[ENABLE]

aobscanmodule(SYNTH3,Atelier_Lydie_and_Suelle.exe,41 0F 11 85 B8 00 00 00 0F) // should be unique
alloc(newmem,$1000,"Atelier_Lydie_and_Suelle.exe"+E5B62)

label(code)
label(return)

label(intSATURN)  //// make a label for the value
registerSymbol(intSATURN)  //// register it as a user symbol so it can be accessed else where.
label(intSUN)
registerSymbol(intSUN)
label(intMOON)
registerSymbol(intMOON)
label(intQUANTITY)
registerSymbol(intQUANTITY)

newmem:
   code:
      movups [r13+000000B8],xmm0
      push rax  ////  save/push the registry's value on the stack
      mov ax,[intSATURN]  //// set AX (16 bits of RAX) to the value at the address of SATURN
      mov [r13+000000b8],ax  //set saturn to value
      mov ax,[intSUN]
      mov [r13+000000bc],ax  //set sun to value
      mov ax,[intMOON]
      mov [r13+000000c0],ax  //set moon to value
      mov ax,[intQUANTITY]
      mov [r13+000000c4],ax  //add value to quantity
      pop rax  ////  restore/pop the registry's value from the stack
      jmp return
   align 10 CC //// Not required but makes the value easy to see in the memory viewer.
   intSATURN: ////  intSATURN (type: 2 bytes) can be used as an address for a memory record on the cheat table.
      dw (int)20  //// "#20" works just fine I just like "(int)20" better my self.
   intSUN:
      dw (int)20  //// "#20" works just fine I just like "(int)20" better my self.
   intMOON:
      dw (int)20
   intQUANTITY:
      dw (int)20

SYNTH3:
   jmp newmem
   nop
   nop
   nop
return:
registersymbol(SYNTH3)

[DISABLE]

SYNTH3:
   db 41 0F 11 85 B8 00 00 00

unregistersymbol(SYNTH3)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B62

"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
"Atelier_Lydie_and_Suelle.exe"+E5B85: 48 8B C8                 -  mov rcx,rax
"Atelier_Lydie_and_Suelle.exe"+E5B88: E8 73 4F FF FF           -  call Atelier_Lydie_and_Suelle.exe+DAB00
"Atelier_Lydie_and_Suelle.exe"+E5B8D: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B90: 48 8B 48 48              -  mov rcx,[rax+48]
}

_________________
Back to top
View user's profile Send private message Visit poster's website
Valatros
Cheater
Reputation: 1

Joined: 21 Nov 2015
Posts: 36

PostPosted: Mon Apr 02, 2018 9:38 pm    Post subject: Reply with quote

It works flawlessly, thank you so much for your help. There's actually four separate codes doing this on this table, I gave you the third, I was able to make every single one have values that can be edited in the table instead of via a script!

If I could get your help with one more thing, I'll paste a couple separate codes below. I'm trying to merge them, but for some magical reason (maybe not enough memory allocated? how does one even determine that?) if I try to combine more than four lines of codes, even though they're all right next to each other, it gives up and dies after the fourth address. We (the original maker and my bug testing) actually ran into this when the initial code had all 5 colors grouped together into one, and the "fix" was to split synthesis into a bunch of smaller codes. I'm hoping to learn why this was necessary so that when I make my own I don't have the same problem.

Code:
[ENABLE]

aobscanmodule(SYNTH1,Atelier_Lydie_and_Suelle.exe,41 0F 11 85 98 00 00 00 0F) // should be unique
alloc(newmem,$1000,"Atelier_Lydie_and_Suelle.exe"+E5B48)

label(code)
label(return)

label(intRED)
registerSymbol(intRED)
label(intBLUE)
registerSymbol(intBLUE)
label(intGREEN)
registerSymbol(intGREEN)
label(intYELLOW)
registerSymbol(intYELLOW)

newmem:
code:
  movups [r13+00000098],xmm0
  push rax
  mov ax,[intRED]
  mov [r13+00000098],ax  //set red to value
  mov ax,[intBLUE]
  mov [r13+0000009c],ax  //set blue to value
  mov ax,[intGREEN]
  mov [r13+000000a0],ax  //set green to value
  mov ax,[intYELLOW]
  mov [r13+000000a4],ax  //set yellow to value
  pop rax
  jmp return
  intRED:
  dw (int)25
  intBLUE:
  dw (int)25
  intGREEN:
  dw (int)25
  intYELLOW:
  dw (int)25

SYNTH1:
  jmp newmem
  nop
  nop
  nop
return:
registersymbol(SYNTH1)

[DISABLE]

SYNTH1:
  db 41 0F 11 85 98 00 00 00

unregistersymbol(intYELLOW)
unregistersymbol(intGREEN)
unregistersymbol(intBLUE)
unregistersymbol(intRED)
unregistersymbol(SYNTH1)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B48

"Atelier_Lydie_and_Suelle.exe"+E5B1D: 41 3B BE C0 01 00 00     -  cmp edi,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B24: 7C BA                    -  jl Atelier_Lydie_and_Suelle.exe+E5AE0
"Atelier_Lydie_and_Suelle.exe"+E5B26: 33 F6                    -  xor esi,esi
"Atelier_Lydie_and_Suelle.exe"+E5B28: 41 8B 86 C0 01 00 00     -  mov eax,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
}


Code:
[ENABLE]


aobscanmodule(SYNTH2,Atelier_Lydie_and_Suelle.exe,41 0F 11 8D A8 00 00 00) // should be unique
alloc(newmem,$1000,"Atelier_Lydie_and_Suelle.exe"+E5B55)

label(code)
label(return)
label(intPURPLE)
registerSymbol(intPURPLE)
label(intMERCURY)
registerSymbol(intMERCURY)
label(intMARS)
registerSymbol(intMARS)
label(intJUPITER)
registerSymbol(intJUPITER)

newmem:

code:
  movups [r13+000000A8],xmm1
  push rax
  mov ax,[intPURPLE]
  mov [r13+000000a8],ax  //set purple to value
  mov ax,[intMERCURY]
  mov [r13+000000ac],ax  //set mercury to value
  mov ax,[intMARS]
  mov [r13+000000b0],ax  //set mars to value
  mov ax,[intJUPITER]
  mov [r13+000000b4],ax  //set jupiter to value
  pop rax
  jmp return
  intPURPLE:
  dw #25
  intMERCURY:
  dw #0
  intMARS:
  dw #0
  intJUPITER:
  dw #0

SYNTH2:
  jmp newmem
  nop
  nop
  nop
return:
registersymbol(SYNTH2)

[DISABLE]

SYNTH2:
  db 41 0F 11 8D A8 00 00 00

unregistersymbol(intJUPITER)
unregistersymbol(intMARS)
unregistersymbol(intMERCURY)
unregistersymbol(intPURPLE)
unregistersymbol(SYNTH2)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B55

"Atelier_Lydie_and_Suelle.exe"+E5B26: 33 F6                    -  xor esi,esi
"Atelier_Lydie_and_Suelle.exe"+E5B28: 41 8B 86 C0 01 00 00     -  mov eax,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
"Atelier_Lydie_and_Suelle.exe"+E5B85: 48 8B C8                 -  mov rcx,rax
"Atelier_Lydie_and_Suelle.exe"+E5B88: E8 73 4F FF FF           -  call Atelier_Lydie_and_Suelle.exe+DAB00
}


I'd like to combine those. I have two more, for a total of 8 edited addresses, but they follow the exact same theme of each address being +4 of the one before it, so I figure if I can learn how to merge two I can learn how to merge four. I tried the following:

Code:
[ENABLE]

aobscanmodule(SYNTH1,Atelier_Lydie_and_Suelle.exe,41 0F 11 85 98 00 00 00 0F) // should be unique
alloc(newmem,$1000,"Atelier_Lydie_and_Suelle.exe"+E5B48)

label(code)
label(return)

label(intRED)
registerSymbol(intRED)
label(intBLUE)
registerSymbol(intBLUE)
label(intGREEN)
registerSymbol(intGREEN)
label(intYELLOW)
registerSymbol(intYELLOW)
label(intPURPLE)
registerSymbol(intPURPLE)

newmem:
code:
  movups [r13+00000098],xmm0
  push rax
  mov ax,[intRED]
  mov [r13+00000098],ax  //set red to value
  mov ax,[intBLUE]
  mov [r13+0000009c],ax  //set blue to value
  mov ax,[intGREEN]
  mov [r13+000000a0],ax  //set green to value
  mov ax,[intYELLOW]
  mov [r13+000000a4],ax  //set yellow to value
  mov ax,[intPURPLE]
  mov [r13+000000a8],ax
  pop rax
  jmp return
  intRED:
  dw (int)25
  intBLUE:
  dw (int)25
  intGREEN:
  dw (int)25
  intYELLOW:
  dw (int)25
  intPURPLE:
  dw (int)25

SYNTH1:
  jmp newmem
  nop
  nop
  nop
return:
registersymbol(SYNTH1)

[DISABLE]

SYNTH1:
  db 41 0F 11 85 98 00 00 00

unregistersymbol(intPURPLE)
unregistersymbol(intYELLOW)
unregistersymbol(intGREEN)
unregistersymbol(intBLUE)
unregistersymbol(intRED)
unregistersymbol(SYNTH1)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B48

"Atelier_Lydie_and_Suelle.exe"+E5B1D: 41 3B BE C0 01 00 00     -  cmp edi,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B24: 7C BA                    -  jl Atelier_Lydie_and_Suelle.exe+E5AE0
"Atelier_Lydie_and_Suelle.exe"+E5B26: 33 F6                    -  xor esi,esi
"Atelier_Lydie_and_Suelle.exe"+E5B28: 41 8B 86 C0 01 00 00     -  mov eax,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
}


But while it seems like it ought to work, purple doesn't change, wether I use the new label/symbol method you taught me to set the value or put it directly into the script. Purple changes just fine in the second code batch though, and I just... I don't get why.
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Mon Apr 02, 2018 10:10 pm    Post subject: Reply with quote

Looking at the original code it looks like where you're changing purple is before the original code sets it, so your change is being over written.
Code:
{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B48

"Atelier_Lydie_and_Suelle.exe"+E5B1D: 41 3B BE C0 01 00 00     -  cmp edi,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B24: 7C BA                    -  jl Atelier_Lydie_and_Suelle.exe+E5AE0
"Atelier_Lydie_and_Suelle.exe"+E5B26: 33 F6                    -  xor esi,esi
"Atelier_Lydie_and_Suelle.exe"+E5B28: 41 8B 86 C0 01 00 00     -  mov eax,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0  //// You're setting it here
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1  //// Game sets it here, so your's is overwritten
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1  //// I would inject here this will allow you to change all values
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
}



And with these offsets (i.e.: 0, 4, 8, C) are you sure these values are 2 bytes and not 4 bytes?


EDIT:
You could also create a label to store the base in.

Code:
// ...
label(ptrSYNTH1)
registerSymbol(ptrSYNTH1)

newmem:
code:
  mov [ptrSYNTH1],r13
// ...
  jmp return
// ...
  ptrSYNTH1:
  dq 0
// ...


Then you can add pointers with the right offsets and use "ptrSYNTH1" as the address/base; and edit the values directly if that works better for what you're doing, but if it's constantly written to then the way your going seems like it would be the best way. But the pointers can be useful for debugging.

_________________
Back to top
View user's profile Send private message Visit poster's website
Valatros
Cheater
Reputation: 1

Joined: 21 Nov 2015
Posts: 36

PostPosted: Mon Apr 02, 2018 11:22 pm    Post subject: Reply with quote

About the 2byte 4byte thing, uh... good question. While we were doing traits we found they were 2byte and all 3 or 4 of us just started using byte or 2byte for everything from there on out. The highest value for the lot in this code achieveable in-game is 100 quality, with everything else not intended to go above 30 or so though, so... I guess even byte would work. You're right though, the full range of values savable to those addresses should be 4byte, whoopsie.

Also! It took me awhile and some screwups from typos (argh, computer needs to learn how to understand what i MEANT to type already) but I got it working!


Code:
[ENABLE]

aobscanmodule(SYNTH,Atelier_Lydie_and_Suelle.exe,41 0F 11 8D C8 00 00 00) // should be unique
alloc(newmem,$1000,"Atelier_Lydie_and_Suelle.exe"+E5B6F)

label(code)
label(return)

label(intRED)
registerSymbol(intRED)
label(intBLUE)
registerSymbol(intBLUE)
label(intGREEN)
registerSymbol(intGREEN)
label(intYELLOW)
registerSymbol(intYELLOW)
label(intPURPLE)
registerSymbol(intPURPLE)
label(intMERCURY)
registerSymbol(intMERCURY)
label(intMARS)
registerSymbol(intMARS)
label(intJUPITER)
registerSymbol(intJUPITER)
label(intSATURN)
registerSymbol(intSATURN)
label(intSUN)
registerSymbol(intSUN)
label(intMOON)
registerSymbol(intMOON)
label(intQUANTITY)
registerSymbol(intQUANTITY)
label(intUSES)
registerSymbol(intUSES)
label(intQUALITY)
registerSymbol(intQUALITY)
label(intTRAITS)
registerSymbol(intTRAITS)
label(intEFFECTMAX)
registerSymbol(intEFFECTMAX)

newmem:
code:
  movups [r13+00000098],xmm0
  push rax
  mov ax,[intRED]
  mov [r13+00000098],ax  //set red to value
  mov ax,[intBLUE]
  mov [r13+0000009c],ax  //set blue to value
  mov ax,[intGREEN]
  mov [r13+000000a0],ax  //set green to value
  mov ax,[intYELLOW]
  mov [r13+000000a4],ax  //set yellow to value
  mov ax,[intPURPLE]
  mov [r13+000000a8],ax  //set purple to value
  mov ax,[intMERCURY]
  mov [r13+000000ac],ax  //set mercury to value
  mov ax,[intMARS]
  mov [r13+000000b0],ax  //set mars to value
  mov ax,[intJUPITER]
  mov [r13+000000b4],ax  //set jupiter to value
  mov ax,[intSATURN]  //// set AX (16 bits of RAX) to the value at the address of SATURN
  mov [r13+000000b8],ax  //set saturn to value
  mov ax,[intSUN]
  mov [r13+000000bc],ax  //set sun to value
  mov ax,[intMOON]
  mov [r13+000000c0],ax  //set moon to value
  mov ax,[intQUANTITY]
  mov [r13+000000c4],ax  //add value to quantity
  mov ax,[intUSES]
  mov [r13+000000c8],ax  //add value to uses
  mov ax,[intQUALITY]
  mov [r13+000000cc],ax  //add value to quality
  mov ax,[intTRAITS]
  mov [r13+000000d0],ax  //add value to traits transferred
  mov ax,[intEFFECTMAX]
  mov [r13+000000d4],ax  //add value to effect level max
  pop rax
  jmp return
  intRED:
  dw (int)25
  intBLUE:
  dw (int)25
  intGREEN:
  dw (int)25
  intYELLOW:
  dw (int)25
  intPURPLE:
  dw (int)25
  intMERCURY:
  dw #0
  intMARS:
  dw #0
  intJUPITER:
  dw #0
  intSATURN: ////  intSATURN (type: 2 bytes) can be used as an address for a memory record on the cheat table.
  dw (int)20  //// "#20" works just fine I just like "(int)20" better my self.
  intSUN:
  dw (int)20  //// "#20" works just fine I just like "(int)20" better my self.
  intMOON:
  dw (int)20
  intQUANTITY:
  dw (int)20
  intUSES:
  dw #10
  intQUALITY:
  dw #200
  intTRAITS:
  dw #3
  intEFFECTMAX:
  dw #25


SYNTH:
  jmp newmem
  nop
  nop
  nop
return:
registersymbol(SYNTH)

[DISABLE]

SYNTH:
  db 41 0F 11 8D C8 00 00 00

unregistersymbol(intEFFECTMAX)
unregistersymbol(intTRAITS)
unregistersymbol(intQUALITY)
unregistersymbol(intUSES)
unregistersymbol(intQUANTITY)
unregistersymbol(intMOON)
unregistersymbol(intSUN)
unregistersymbol(intSATURN)
unregistersymbol(intJUPITER)
unregistersymbol(intMARS)
unregistersymbol(intMERCURY)
unregistersymbol(intPURPLE)
unregistersymbol(intYELLOW)
unregistersymbol(intGREEN)
unregistersymbol(intBLUE)
unregistersymbol(intRED)
unregistersymbol(SYNTH)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B48

"Atelier_Lydie_and_Suelle.exe"+E5B1D: 41 3B BE C0 01 00 00     -  cmp edi,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B24: 7C BA                    -  jl Atelier_Lydie_and_Suelle.exe+E5AE0
"Atelier_Lydie_and_Suelle.exe"+E5B26: 33 F6                    -  xor esi,esi
"Atelier_Lydie_and_Suelle.exe"+E5B28: 41 8B 86 C0 01 00 00     -  mov eax,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
}


That one works for editing every single thing about synthesizing on the fly perfectly, thanks a ton for your help!

I just wanna make sure my understanding is right, the reason the old codes stopped working is because the game itself was writing the values in 16 addresses at a time (or 10 in hex), then go read the values and write the next four 4bytes, up through all 16 synthesis addresses. The original code was injecting at every single instance of the game read/writing, but by doing it at the end we could just overwrite all the games old work and substitute the code above and it wouldn't get overwritten since it went last. The code after the injection point is basically the games memory buggering off from synthesis and going to whatever the next thing is, I take it?

Hopefully I understood that properly. Again, thank you for the help with this, none of us working on the original table were able to clean it up over at fearless, and this is my first time viewing/editing assembly codes so your explanations helped a lot.

Edit:
TheyCallMeTim13 wrote:
snipsnipsnip

EDIT:
You could also create a label to store the base in.

Code:
// ...
label(ptrSYNTH1)
registerSymbol(ptrSYNTH1)

newmem:
code:
  mov [ptrSYNTH1],r13
// ...
  jmp return
// ...
  ptrSYNTH1:
  dq 0
// ...


Then you can add pointers with the right offsets and use "ptrSYNTH1" as the address/base; and edit the values directly if that works better for what you're doing, but if it's constantly written to then the way your going seems like it would be the best way. But the pointers can be useful for debugging.

Hrm, so, instead of having to type out that whole 6 0's 98, 9c, etc. I could just do ptrSYNTH1+98, ptrSYNTH1+9c, etc.? I'm confused on how that helps debugging, though, even if it does save a good amount of typing. Don't think I understand what you mean properly.

Also, what's the DQ for? Double precision float, but, why? None of the codes are saved that way. Or is it just to save the maximum memory possible for the base of the pointer so that it works no matter how long it is? Don't think I really understand what you mean for this part either haha. I'll check back after bed, don't think I've lost interest it's cool to finally learn how some of this stuff works, there's been a lot of times where I just had to give up because I couldn't edit something via a basic memory entry.
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Tue Apr 03, 2018 12:56 am    Post subject: Reply with quote

Valatros wrote:
...
I just wanna make sure my understanding is right, the reason the old codes stopped working is because the game itself was writing the values in 16 addresses at a time (or 10 in hex), then go read the values and write the next four 4bytes, up through all 16 synthesis addresses.
...


Basically yeah, the main thing is the purple gets set after you set it.



Valatros wrote:
...
The original code was injecting at every single instance of the game read/writing, but by doing it at the end we could just overwrite all the games old work and substitute the code above and it wouldn't get overwritten since it went last.
...


Yes, no need injection at each line; it's like making a whole pizza one slice at a time, each piece will be fresher but it will be less efficient over all. The main exception being if each line is surrounded by jumps and/or calls, then multiple injection could be needed.


Valatros wrote:
...
The code after the injection point is basically the games memory buggering off from synthesis and going to whatever the next thing is, I take it?
...


Basically yeah.

In detail it seems that some where (probably above the injection point) the values are calculated then stored on the stack, then at the injection point the game is just quickly pulling the values from the stack to set the actual value in memory. And this is just a guess but then calling a function to render stuff may be (I base this on the color names).

Code:
{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B48

"Atelier_Lydie_and_Suelle.exe"+E5B1D: 41 3B BE C0 01 00 00     -  cmp edi,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B24: 7C BA                    -  jl Atelier_Lydie_and_Suelle.exe+E5AE0
"Atelier_Lydie_and_Suelle.exe"+E5B26: 33 F6                    -  xor esi,esi
"Atelier_Lydie_and_Suelle.exe"+E5B28: 41 8B 86 C0 01 00 00     -  mov eax,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]    //// You could write the values to the stack here, but if you don't understand the stack then save this kinda thing for later.
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0  //// So this is just a quick way to set all 16 (0x10) bytes at a time.
// ---------- DONE INJECTING  ----------
//// But any thing after "R13+A8" (all bytes up to "R13+D8") will be overwritten by the code below. So "R13+A8" is set below by the game.
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1  /// Modify the values here to prvent the game from overwitting, and no need for multiple injections you can just set all value here.
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
}




Valatros wrote:
...
Hrm, so, instead of having to type out that whole 6 0's 98, 9c, etc. I could just do ptrSYNTH1+98, ptrSYNTH1+9c, etc.?
...


Well yes, but that was just for adding to the table as a pointer; it's just a way to do scripted pointers.

But you don't need all the zeros "[r13+00000098]" is the same as "[r13+98]". Note that if your setting a value this tells CE what size it is, but you can tell it explicitly; "mov [r13+98],00000014" is the same as "mov dword ptr [r13+98],14" or "mov dword ptr [r13+98],(int)20".



Valatros wrote:
...
Also, what's the DQ for?
...


db : Data byte
dw : Data word
dd : Data dword (double word)
dq : Data qword (quad word)

It's just cause it's 64 bit so the address needs 8 bytes.


A bit more
You could also align the values and do it the same as the game is, less code and you can just use the XMM registry like the original code is.
Code:
[ENABLE]

aobscanmodule(SYNTH,Atelier_Lydie_and_Suelle.exe,41 0F 11 8D C8 00 00 00) // should be unique
alloc(newmem,$1000,"Atelier_Lydie_and_Suelle.exe"+E5B6F)

label(code)
label(return)

label(intRED)
registerSymbol(intRED)
label(intBLUE)
registerSymbol(intBLUE)
label(intGREEN)
registerSymbol(intGREEN)
label(intYELLOW)
registerSymbol(intYELLOW)
label(intPURPLE)
registerSymbol(intPURPLE)
label(intMERCURY)
registerSymbol(intMERCURY)
label(intMARS)
registerSymbol(intMARS)
label(intJUPITER)
registerSymbol(intJUPITER)
label(intSATURN)
registerSymbol(intSATURN)
label(intSUN)
registerSymbol(intSUN)
label(intMOON)
registerSymbol(intMOON)
label(intQUANTITY)
registerSymbol(intQUANTITY)
label(intUSES)
registerSymbol(intUSES)
label(intQUALITY)
registerSymbol(intQUALITY)
label(intTRAITS)
registerSymbol(intTRAITS)
label(intEFFECTMAX)
registerSymbol(intEFFECTMAX)

newmem:
code:
  movaps xmm0,[intRED]  //// Aligned
  movups [r13+98],xmm0  //// Unaligned
  movaps xmm0,[intPURPLE]
  movups [r13+A8],xmm0
  movaps xmm0,[intSATURN]
  movups [r13+B8],xmm0
  movaps xmm0,[intUSES]
  movups [r13+C8],xmm0
  jmp return
  align 10 CC //// this will allow you the us aligned instructions (like the game is for the reads from the stack).
  intRED:
  dd (int)25 //// back to dword for the alignmant
  intBLUE:
  dd (int)25
  intGREEN:
  dd (int)25
  intYELLOW:
  dd (int)25
  intPURPLE:
  dd (int)25
  intMERCURY:
  dd #0
  intMARS:
  dd #0
  intJUPITER:
  dd #0
  intSATURN: ////  intSATURN (type: 2 bytes) can (STILL) be used as an address for a memory record on the cheat table.
  dd (int)20  //// "#20" works just fine I just like "(int)20" better my self.
  intSUN:
  dd (int)20  //// "#20" works just fine I just like "(int)20" better my self.
  intMOON:
  dd (int)20
  intQUANTITY:
  dd (int)20
  intUSES:
  dd #10
  intQUALITY:
  dd #200
  intTRAITS:
  dd #3
  intEFFECTMAX:
  dd #25


SYNTH:
  jmp newmem
  nop
  nop
  nop
return:
registersymbol(SYNTH)

[DISABLE]

SYNTH:
  db 41 0F 11 8D C8 00 00 00

unregistersymbol(intEFFECTMAX)
unregistersymbol(intTRAITS)
unregistersymbol(intQUALITY)
unregistersymbol(intUSES)
unregistersymbol(intQUANTITY)
unregistersymbol(intMOON)
unregistersymbol(intSUN)
unregistersymbol(intSATURN)
unregistersymbol(intJUPITER)
unregistersymbol(intMARS)
unregistersymbol(intMERCURY)
unregistersymbol(intPURPLE)
unregistersymbol(intYELLOW)
unregistersymbol(intGREEN)
unregistersymbol(intBLUE)
unregistersymbol(intRED)
unregistersymbol(SYNTH)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: "Atelier_Lydie_and_Suelle.exe"+E5B48

"Atelier_Lydie_and_Suelle.exe"+E5B1D: 41 3B BE C0 01 00 00     -  cmp edi,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B24: 7C BA                    -  jl Atelier_Lydie_and_Suelle.exe+E5AE0
"Atelier_Lydie_and_Suelle.exe"+E5B26: 33 F6                    -  xor esi,esi
"Atelier_Lydie_and_Suelle.exe"+E5B28: 41 8B 86 C0 01 00 00     -  mov eax,[r14+000001C0]
"Atelier_Lydie_and_Suelle.exe"+E5B2F: 41 FF C7                 -  inc r15d
"Atelier_Lydie_and_Suelle.exe"+E5B32: 48 83 C5 38              -  add rbp,38
"Atelier_Lydie_and_Suelle.exe"+E5B36: 44 3B F8                 -  cmp r15d,eax
"Atelier_Lydie_and_Suelle.exe"+E5B39: 7C 9C                    -  jl Atelier_Lydie_and_Suelle.exe+E5AD7
"Atelier_Lydie_and_Suelle.exe"+E5B3B: 48 8B AC 24 D0 00 00 00  -  mov rbp,[rsp+000000D0]
"Atelier_Lydie_and_Suelle.exe"+E5B43: 0F 28 44 24 20           -  movaps xmm0,[rsp+20]
"Atelier_Lydie_and_Suelle.exe"+E5B48: 41 0F 11 85 98 00 00 00  -  movups [r13+00000098],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B50: 0F 28 4C 24 30           -  movaps xmm1,[rsp+30]
"Atelier_Lydie_and_Suelle.exe"+E5B55: 41 0F 11 8D A8 00 00 00  -  movups [r13+000000A8],xmm1
"Atelier_Lydie_and_Suelle.exe"+E5B5D: 0F 28 44 24 40           -  movaps xmm0,[rsp+40]
"Atelier_Lydie_and_Suelle.exe"+E5B62: 41 0F 11 85 B8 00 00 00  -  movups [r13+000000B8],xmm0
"Atelier_Lydie_and_Suelle.exe"+E5B6A: 0F 28 4C 24 50           -  movaps xmm1,[rsp+50]
// ---------- INJECTING HERE ----------
"Atelier_Lydie_and_Suelle.exe"+E5B6F: 41 0F 11 8D C8 00 00 00  -  movups [r13+000000C8],xmm1
// ---------- DONE INJECTING  ----------
"Atelier_Lydie_and_Suelle.exe"+E5B77: 49 8B 06                 -  mov rax,[r14]
"Atelier_Lydie_and_Suelle.exe"+E5B7A: 48 8B 48 48              -  mov rcx,[rax+48]
"Atelier_Lydie_and_Suelle.exe"+E5B7E: E8 0D 6B FF FF           -  call Atelier_Lydie_and_Suelle.exe+DC690
"Atelier_Lydie_and_Suelle.exe"+E5B83: 33 D2                    -  xor edx,edx
}

_________________
Back to top
View user's profile Send private message Visit poster's website
Valatros
Cheater
Reputation: 1

Joined: 21 Nov 2015
Posts: 36

PostPosted: Tue Apr 03, 2018 1:26 pm    Post subject: Reply with quote

H-uh, okay don't understand 100% why that works. I take it the "XMM registry" is the "batches" of four addresses it was shoving values into that we started with, and by doing 4byte, or "dd", it automatically fills up all the space inbetween, so it all aligns itself naturally the way it did in the original code. Because of that, you only need to make it move four times, once for each injection/"set" in the original code?

Why/what are moveups/moveaps though? Just guessing moveaps sets the xmm registry to our pile of values (in this case, 4 sets of 4bytes), then moveups is the address, then that edited xmm registry getting slotted in as the value. This works because the game was originally using the xmm0 for the values anyway?

What is the XMM registry, though? The original code down at the bottom sometimes has xmm0 or xmm1, what's the difference?

You mentioned not needing the zeroes because the only advantage is it tells CE how big the address is. Is the reason we don't need to say "dword" or anything else, despite not explicitly telling CE the size, is because we define the size of the values when we set intRED as a "dd" down below?

Also, could you explain the pointer thing to me like I'm 5? I understand a pointer is "(games address in process list)+<offset1>+<offset2>..." but I don't understand why you'd want to do that, in this case, because up top the ""Atelier_Lydie_and_Suelle.exe"+E5B6F" is already a pointer, based off that understanding? I feel like I'm misunderstanding something critical on that somewhere.

Oh! It might be because I don't actually know what the "r13" is or where it's from. I just saw that it worked for magic-computer-reasons in the original codes and followed the pattern. Maybe explain that to me too?
Back to top
View user's profile Send private message
TheyCallMeTim13
Wiki Contributor
Reputation: 50

Joined: 24 Feb 2017
Posts: 976
Location: Pluto

PostPosted: Tue Apr 03, 2018 3:07 pm    Post subject: Reply with quote

Valatros wrote:
H-uh, okay don't understand 100% why that works. I take it the "XMM registry" is the "batches" of four addresses it was shoving values into that we started with, and by doing 4byte, or "dd", it automatically fills up all the space inbetween, so it all aligns itself naturally the way it did in the original code. Because of that, you only need to make it move four times, once for each injection/"set" in the original code?
...

So a registry is just a container if you will, the game/computer has no idea what the values are or their size. All values are just bytes after all, so by aligning them it just makes it easier to work with. Else you would need to convert the values to the right type/size.

Here's a page on the wiki about the assembler, the "structure" part is about the registry.
http://wiki.cheatengine.org/index.php?title=Assembler

Valatros wrote:
...
Why/what are moveups/moveaps though? Just guessing moveaps sets the xmm registry to our pile of values (in this case, 4 sets of 4bytes), then moveups is the address, then that edited xmm registry getting slotted in as the value. This works because the game was originally using the xmm0 for the values anyway?
...


MOVAPS : Move Aligned Packed Single
MOVUPS : Move Unaligned Packed Single

It's mostly just a way to move/set 16 bytes at a time. Basically the original code uses the XMM0 and XMM1 registries so they are ok to use.


Valatros wrote:
...
What is the XMM registry, though? The original code down at the bottom sometimes has xmm0 or xmm1, what's the difference?
...


Just different ones, you have XMM0 up to XMM15. We could use XMM1, but just using XMM0 is just fine in this case. If the game was using them later you could need to use the some registry but it doesn't seem to use or need them after the original code.


Valatros wrote:
...
You mentioned not needing the zeroes because the only advantage is it tells CE how big the address is. Is the reason we don't need to say "dword" or anything else, despite not explicitly telling CE the size, is because we define the size of the values when we set intRED as a "dd" down below?
...


So CE can get the size from the registry size it self too. So "mov word ptr [RCX+10],0" will work the same as "mov [RCX+10],ax" (if ax is set to zero), because the registry is 2 bytes in size. But in the code I posted using the XMM registry, it's just working on the fact a single precision float is 4 bytes same as a dword. If we needed to do a compare or some math then exactly what registry is used matters, but for just moving values around any registry will work so long as the size is correct.


Valatros wrote:
...
Also, could you explain the pointer thing to me like I'm 5? I understand a pointer is "(games address in process list)+<offset1>+<offset2>..." but I don't understand why you'd want to do that, in this case, because up top the ""Atelier_Lydie_and_Suelle.exe"+E5B6F" is already a pointer, based off that understanding? I feel like I'm misunderstanding something critical on that somewhere.
...


This is mostly a habit for me, but if the game's pointers where say 10 levels then pointers would be hard to find, but a scripted pointer can be quick and easy. So if the pointers are 1 level in this game then there really is no need for it, but if in testing you see the address for the scripted pointer jumping around (changing addresses) then this would tell you that the injection point is shared code.
You can even do some thing like this, to help with changes on updates:
Code:
[Enable]
label(ptrSomePointer)
registerSymbol(ptrSomePointer)
"Atelier_Lydie_and_Suelle.exe"+E5B6F:
  ptrSomePointer:
[Disable]
unregisterSymbol(ptrSomePointer)

So with this "ptrSomePointer" can be changed out for ""Atelier_Lydie_and_Suelle.exe"+E5B6F" because they are the same address after this is enabled. So if this was a base address used all over (say for other pointers) a lot of changes could be avoided after updates.


Valatros wrote:
...
Oh! It might be because I don't actually know what the "r13" is or where it's from. I just saw that it worked for magic-computer-reasons in the original codes and followed the pattern. Maybe explain that to me too?


Best I can say is read up. And ask about what you don't understand. But basically it's just a registry on 64 bit processors.

http://wiki.cheatengine.org/index.php?title=Assembler#Structure


Stephen Chapman has a great series of CE video tuts.
https://www.youtube.com/playlist?list=PLNffuWEygffbbT9Vz-Y1NXQxv2m6mrmHr

Cheat the Game is also a good place for video tuts on CE.
https://www.youtube.com/user/BloodFayte

_________________
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General Gamehacking 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