Aob injection copy help?

Section's for general approaches on hacking various options in games. No online-related discussions/posts OR warez!
Post Reply
Icirian
Cheater
Cheater
Posts: 35
Joined: Thu Dec 14, 2017 2:06 am
Reputation: 3

Aob injection copy help?

Post by Icirian »

I'm very new to coding and assembly language, so this is probably a dumb question...
for some reason, the loop (?) only captures Noctis and Prompto's address, and dump Prompto's address for both Ignis and Gladiol.
but if I change the ID for Prompto to the other 2, they display the proper address.
Am I missing something to code the loop properly?
BTW, I'm looking at the script written by Tuuuup!, and trying to understand how these scripts work.
Also, because I set my display language to simplified Chinese, the string at +D4 is different, so I went with character ID
Also, it seems that Tuuuup! declared all the labels and symbols in 1 bracket. and when I tried it, the engine tells me that they are not declared. Why?

My code:

Code: Select all

{ Game   : ffxv_s.exe
  Version:
  Date   : 2023-02-28
  Author : Icirian

  This script does blah blah blah
}

[ENABLE]

aobscanmodule(heros_stats,ffxv_s.exe,8B 83 A4 01 00 00 85 C0 0F 8E) // should be unique
alloc(newmem,$100,heros_stats)

label(code)
label(return)
label(noctis)
label(gladiol)
label(ignis)
label(prompto)
label(noctis_base)
label(gladiol_base)
label(ignis_base)
label(prompto_base)
registersymbol(noctis_base)
registersymbol(gladiol_base)
registersymbol(ignis_base)
registersymbol(prompto_base)

newmem:
   cmp [rbx+58],'6101'
   je ignis
   cmp [rbx+58],'9152'
   je gladiol
   cmp [rbx+58],'8950'
   je noctis
   cmp [rbx+58],'9153'
   je prompto
   jne code

noctis:
mov [noctis_base],rbx
prompto:
mov [prompto_base],rbx
ignis:
mov [ignis_base],rbx
gladiol:
mov [gladiol_base],rbx

code:

  mov eax,[rbx+000001A4]
  jmp return

  noctis_base:
  dq 0
  prompto_base:
  dq 0
  ignis_base:
  dq 0
  gladiol_base:
  dq 0


heros_stats:
  jmp newmem
  nop
return:
registersymbol(heros_stats)

[DISABLE]

heros_stats:
  db 8B 83 A4 01 00 00

unregistersymbol(*)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: ffxv_s.exe+1C3C5D

ffxv_s.exe+1C3C2E: 75 0A                    - jne ffxv_s.exe+1C3C3A
ffxv_s.exe+1C3C30: 8B 83 E0 01 00 00        - mov eax,[rbx+000001E0]
ffxv_s.exe+1C3C36: 89 44 24 28              - mov [rsp+28],eax
ffxv_s.exe+1C3C3A: F3 0F 10 2D BE 1F EC 02  - movss xmm5,[ffxv_s.exe+3085C00]
ffxv_s.exe+1C3C42: 41 B9 01 00 00 00        - mov r9d,00000001
ffxv_s.exe+1C3C48: F3 0F 10 35 18 85 EF 02  - movss xmm6,[ffxv_s.exe+30BC168]
ffxv_s.exe+1C3C50: 85 F6                    - test esi,esi
ffxv_s.exe+1C3C52: 7F 09                    - jg ffxv_s.exe+1C3C5D
ffxv_s.exe+1C3C54: 45 85 E4                 - test r12d,r12d
ffxv_s.exe+1C3C57: 0F 8E DD 00 00 00        - jng ffxv_s.exe+1C3D3A
// ---------- INJECTING HERE ----------
ffxv_s.exe+1C3C5D: 8B 83 A4 01 00 00        - mov eax,[rbx+000001A4]
// ---------- DONE INJECTING  ----------
ffxv_s.exe+1C3C63: 85 C0                    - test eax,eax
ffxv_s.exe+1C3C65: 0F 8E CF 00 00 00        - jng ffxv_s.exe+1C3D3A
ffxv_s.exe+1C3C6B: 8B 8B A8 01 00 00        - mov ecx,[rbx+000001A8]
ffxv_s.exe+1C3C71: F3 0F 10 1D 9B 08 EC 02  - movss xmm3,[ffxv_s.exe+3084514]
ffxv_s.exe+1C3C79: F3 0F 10 A3 5C 09 00 00  - movss xmm4,[rbx+0000095C]
ffxv_s.exe+1C3C81: 66 41 0F 6E D4           - movd xmm2,r12d
ffxv_s.exe+1C3C86: 0F 5B D2                 - cvtdq2ps xmm2,xmm2
ffxv_s.exe+1C3C89: 66 0F 6E C1              - movd xmm0,ecx
ffxv_s.exe+1C3C8D: 0F 5B C0                 - cvtdq2ps xmm0,xmm0
ffxv_s.exe+1C3C90: F3 0F 59 D0              - mulss xmm2,xmm0
}
Tuuuup! code

Code: Select all

{ Game   : ffxv_s.exe
  Version: 
  Date   : 2021-12-30
  Author : Tuuup!

  This script does blah blah blah
}

[ENABLE]

aobscanmodule(INJECTactorbase,ffxv_s.exe,49 8B 06 4C 89 F1 FF 90 88 05 00 00 89 C2 48 89 E9 E8 CF) // should be unique
alloc(newmem,$1000,INJECTactorbase)
registersymbol(INJECTactorbase godm)
registersymbol(noct1 glad1 ignis1 prom1)
label(code noct glad ignis prom noct1 glad1 ignis1 prom1)
label(return god godm)

newmem:
pushf
push r10
mov r10,[r14+20e0] //status
test r10,r10
je code
  cmp [r10+000000D4],#1952673614 //noc 74636F4E
  je noct
  cmp [r10+000000D4],#1684106311 //glad 64616C47
  je glad
  cmp [r10+000000D4],#1768843081 //ignis 696E6749
  je ignis
  cmp [r10+000000D4],#1836020304 //prom 6D6F7250
  je prom
  jmp code

noct:
mov [noct1],r10
jmp god
glad:
mov [glad1],r10
jmp god
ignis:
mov [ignis1],r10
jmp god
prom:
mov [prom1],r10
jmp god

god:
cmp [godm],1
jne @f
mov [r10+89b],1 //No Knockback/Stagger?
mov [r10+89c],1 //No Damage?
mov [r10+89d],1 //Stasis Block?
mov [r10+8a0],1 //Invulnerable?


code:
pop r10
popf
  mov rax,[r14]  //rsi rdi r10 r11 r12 r13 leeg
  mov rcx,r14
  jmp return

  noct1:
  dq 0
  glad1:
  dq 0
  ignis1:
  dq 0
  prom1:
  dq 0
  godm:
  dd 0

INJECTactorbase:
  jmp newmem
  nop
return:


[DISABLE]

INJECTactorbase:
  db 49 8B 06 4C 89 F1

unregistersymbol(*)
dealloc(newmem)

{
// ORIGINAL CODE - INJECTION POINT: ffxv_s.exe+5BBA4BB

ffxv_s.exe+5BBA49F: 48 8B 40 08        - mov rax,[rax+08]
ffxv_s.exe+5BBA4A3: EB 11              - jmp ffxv_s.exe+5BBA4B6
ffxv_s.exe+5BBA4A5: 83 3B 00           - cmp dword ptr [rbx],00
ffxv_s.exe+5BBA4A8: 74 0A              - je ffxv_s.exe+5BBA4B4
ffxv_s.exe+5BBA4AA: 48 89 D9           - mov rcx,rbx
ffxv_s.exe+5BBA4AD: E8 8E 9C 20 00     - call ffxv_s.exe+5DC4140
ffxv_s.exe+5BBA4B2: EB 02              - jmp ffxv_s.exe+5BBA4B6
ffxv_s.exe+5BBA4B4: 31 C0              - xor eax,eax
ffxv_s.exe+5BBA4B6: 4C 39 F0           - cmp rax,r14
ffxv_s.exe+5BBA4B9: 75 1F              - jne ffxv_s.exe+5BBA4DA
// ---------- INJECTING HERE ----------
ffxv_s.exe+5BBA4BB: 49 8B 06           - mov rax,[r14]
// ---------- DONE INJECTING  ----------
ffxv_s.exe+5BBA4BE: 4C 89 F1           - mov rcx,r14
ffxv_s.exe+5BBA4C1: FF 90 88 05 00 00  - call qword ptr [rax+00000588]
ffxv_s.exe+5BBA4C7: 89 C2              - mov edx,eax
ffxv_s.exe+5BBA4C9: 48 89 E9           - mov rcx,rbp
ffxv_s.exe+5BBA4CC: E8 CF 18 00 00     - call ffxv_s.exe+5BBBDA0
ffxv_s.exe+5BBA4D1: 45 84 FF           - test r15l,r15l
ffxv_s.exe+5BBA4D4: 74 2F              - je ffxv_s.exe+5BBA505
ffxv_s.exe+5BBA4D6: 85 C0              - test eax,eax
ffxv_s.exe+5BBA4D8: 74 2B              - je ffxv_s.exe+5BBA505
ffxv_s.exe+5BBA4DA: FF C6              - inc esi
}

User avatar
happyTugs
Table Makers
Table Makers
Posts: 127
Joined: Mon Apr 20, 2020 1:01 am
Reputation: 148

Re: Aob injection copy help?

Post by happyTugs »

Take a look here...

Code: Select all

noctis:
mov [noctis_base],rbx
prompto:
mov [prompto_base],rbx
ignis:
mov [ignis_base],rbx
gladiol:
mov [gladiol_base],rbx
You are overwriting all base values with rbx since you didn't redirect execution to the original code segment after the write.

Take a look here...

Code: Select all

alloc(newmem,$100,heros_stats)
Regardless of whatever size you provide (0x100 in your case), the smallest memory page size in Windows is 4 KB (0x1000). This is the default page size used by the Windows operating system for both 32-bit and 64-bit versions.
Last edited by happyTugs on Fri Mar 03, 2023 11:54 am, edited 1 time in total.

User avatar
Rhark
Expert Cheater
Expert Cheater
Posts: 3473
Joined: Tue Apr 16, 2019 1:27 am
Reputation: 1395

Re: Aob injection copy help?

Post by Rhark »

So, in other words you need to add a jump to the code after you move RBX into each symbol.

E.g.

Code: Select all

label:
mov [pointer],rbx
jmp code
label2:
mov [pointer2],rbx
jmp code
label3:
mov [pointer3],rbx
jmp code

Icirian
Cheater
Cheater
Posts: 35
Joined: Thu Dec 14, 2017 2:06 am
Reputation: 3

Re: Aob injection copy help?

Post by Icirian »

Oh! Thank you very much for this! It's interesting to peek behind the curtains for me. And I learned new things every time I come up here.

Icirian
Cheater
Cheater
Posts: 35
Joined: Thu Dec 14, 2017 2:06 am
Reputation: 3

Re: Aob injection copy help?

Post by Icirian »

So I'm guessing after every jump, it will move down the list of labels instead of infinite loop the first label? (The last loop I've seen was in Python and I remember there was something to do with i++ in each loop, otherwise it's a infinite loop and crashes the computer)
Rhark wrote:
Fri Mar 03, 2023 11:53 am
So, in other words you need to add a jump to the code after you move RBX into each symbol.

E.g.

Code: Select all

label:
mov [pointer],rbx
jmp code
label2:
mov [pointer2],rbx
jmp code
label3:
mov [pointer3],rbx
jmp code

User avatar
happyTugs
Table Makers
Table Makers
Posts: 127
Joined: Mon Apr 20, 2020 1:01 am
Reputation: 148

Re: Aob injection copy help?

Post by happyTugs »

Icirian wrote:
Sat Mar 04, 2023 6:28 am
So I'm guessing after every jump, it will move down the list of labels instead of infinite loop the first label? (The last loop I've seen was in Python and I remember there was something to do with i++ in each loop, otherwise it's a infinite loop and crashes the computer)
The jump to code will redirect execution flow to the code label...

Code: Select all

label:
mov [pointer],rbx
jmp code
label2:
mov [pointer2],rbx
jmp code
label3:
mov [pointer3],rbx
jmp code
At code, more instructions will be executed and eventually jumping to the return label because you coded it as such...

Code: Select all

code:
mov eax,[rbx+000001A4]
jmp return
All of which resolves here....

Code: Select all

heros_stats:
jmp newmem
nop
return:

Icirian
Cheater
Cheater
Posts: 35
Joined: Thu Dec 14, 2017 2:06 am
Reputation: 3

Re: Aob injection copy help?

Post by Icirian »

I understand the purpose and the function of a jmp code. It's after return part i'm not really getting?
would the code just kept on looping to

label->jmp code->return-> label -> jmp code -> return-> ...

or is it

label->jmp code->return->label1-jmp code->return->label2->jmp code->return

again sorry i can't properly express myself here, i don't really know the lingo for these things yet.

User avatar
happyTugs
Table Makers
Table Makers
Posts: 127
Joined: Mon Apr 20, 2020 1:01 am
Reputation: 148

Re: Aob injection copy help?

Post by happyTugs »

Icirian wrote:
Sun Mar 05, 2023 7:07 pm
I understand the purpose and the function of a jmp code. It's after return part i'm not really getting?
would the code just kept on looping to

label->jmp code->return-> label -> jmp code -> return-> ...

or is it

label->jmp code->return->label1-jmp code->return->label2->jmp code->return

again sorry i can't properly express myself here, i don't really know the lingo for these things yet.
I am sorry as well. I might be misunderstanding what you are trying to say.

Let's look at the following code...

Code: Select all

newmem:
  //execute some code
  jmp code

code:
  mov eax,[rbx+000001A4]
  jmp return

heros_stats:
  jmp newmem
  nop
return:
Think of labels as identifiers of an address in virtual memory.

So, in reality, this is how the code would look like...

Code: Select all

0x2400000:
  //execute some code
  jmp 0x2400100

0x2400100:
  mov eax,[rbx+000001A4]
  jmp 0x410006

0x410000:
  jmp 0x2400000
  nop
0x410006:
When you jump to the return label, you are actually jumping to an address in memory associated with that label.

In this case, return is actually an address a few bytes after the hook:heros_stats. Jumping back to the hook will resume game execution; eventually, heros_stats will be executed again which will be a jump to newmem and eventually a jump to return.

Icirian
Cheater
Cheater
Posts: 35
Joined: Thu Dec 14, 2017 2:06 am
Reputation: 3

Re: Aob injection copy help?

Post by Icirian »

So... I made the changes that was suggested, adding jmp code in each label fixed the script. BUT I still don't understand why that worked.
say I have 4 labels in parallel, label 1,2,3,4.

Code: Select all

newmem
cmp [constant],value_1
je lable1
cmp [constant],value_2
je lable2
cmp [constant],value_3
je lable3
cmp [constant],value_4
je lable4
jne code

label1:
mov [pointer1],rbx
jmp code
label2:
mov [pointer2],rbx
jmp code
label3:
mov [pointer3],rbx
jmp code
label4:
mov [pointer4],rbx
jmp code

code:
{some code}
return
so if I understand everything correctly, in the first loop, the order of operation would be,
compare [constant] with value_1=>found a match=>jmp to label 1=>moved address to pointer 1=> jump to original code got to return=>then exit loop/script.
so in the second loop, shouldn't the script just repeat what was done in the first loop? since it would execute the code from top to bottom, and the first thing it sees is to compare [constant] with value_1 and since [constant] and value_1 were not altered in any way during the 1st loop, there should be a match and thus execute jmp label 1, and just kept on repeating the same operation every loop?

User avatar
happyTugs
Table Makers
Table Makers
Posts: 127
Joined: Mon Apr 20, 2020 1:01 am
Reputation: 148

Re: Aob injection copy help?

Post by happyTugs »

Icirian wrote:
Tue Mar 07, 2023 5:31 am
So... I made the changes that was suggested, adding jmp code in each label fixed the script. BUT I still don't understand why that worked.
If you didn't add jumps, execution will not be redirected after you have made a write due to a comparison. You'll understand if you just debug and step through your own scripts.

Code: Select all

newmem:
  cmp [rbx+58],'6101'
  je ignis
   cmp [rbx+58],'9152'
  je gladiol
  cmp [rbx+58],'8950'
  je noctis
  cmp [rbx+58],'9153'
  je prompto
  jmp code
    
noctis:
  mov [noctis_base],rbx 
prompto:
  mov [prompto_base],rbx
ignis:
  mov [ignis_base],rbx
gladiol:
  mov [gladiol_base],rbx

code:
  mov eax,[rbx+000001A4]
  jmp return
Suppose that [rbx+58] is equal to '8950', you will jump to noctis because of the equality. At this point, rbx is the address that contains the noctis object (since you named it as such). So, mov [noctis_base],rbx will be executed.

Afterwards, the program will execute the next instruction which is mov [prompto_base],rbx. Obviously, this is wrong; rbx is the address that contains the noctis object - not the prompto object. Therefore, you redirect execution flow somewhere more appropriate: the code section, where you execute the original code, then jump to return.
Icirian wrote:
Tue Mar 07, 2023 5:31 am
so in the second loop, shouldn't the script just repeat what was done in the first loop? since it would execute the code from top to bottom, and the first thing it sees is to compare [constant] with value_1 and since [constant] and value_1 were not altered in any way during the 1st loop, there should be a match and thus execute jmp label 1, and just kept on repeating the same operation every loop?
But in your case, you are not comparing something constant...

rbx will change for each execution; therefore, you add some checks to determine which memory address belongs to which object, or character. If rbx never changed, there would be no need for a comparison in the first place.

Post Reply

Who is online

Users browsing this forum: No registered users