storing addresses in memory to be used as base pointers

Memory scanning, code injection, debugger internals and other gamemodding related discussion
Post Reply
RKH4X
Noobzor
Noobzor
Posts: 12
Joined: Sun May 14, 2017 2:07 pm
Reputation: 0

storing addresses in memory to be used as base pointers

Post by RKH4X »

Okay so context:

I have 3 characters. They all have a set amount of movement points per turn. I scan for what accesses. I select an instruction that writes 1 to 1 when movement points are added or removed. Show in disassembler. Scan for what addresses this instruction accesses. and there are 3, as you'd expect, for my 3 characters.

Now I want to use the fact that this instruction is used on these 3 addresses to my advantage. I want to be able to write a code that saves the base address of all 3 characters from this instruction into memory so that I can register them as variables, call them in the table and nest offsets underneath it.

Here is an example code to show you what I'm trying and failing to do:

Code: Select all

[ENABLE]
aobscan(baseptr,48 8B C8 48 8B 45 E8 89 88 48 01 00 00)
alloc(newmem,$100,baseptr)

label(code)
label(return)
label(ptr)

newmem:
  push rbx
  mov rbx,ptr
  mov [ptr],rax
code:
  mov [rax+00000148],ecx
  pop rbx
  jmp return
ptr:
  dq 0
  dq 0
  dq 0
baseptr+07:
  jmp newmem
  nop
return:
registersymbol(baseptr)
registersymbol(ptr)

[DISABLE]
baseptr+07:
  db 89 88 48 01 00 00

unregistersymbol(baseptr)
unregistersymbol(ptr)
dealloc(newmem)
In this case, whenever the instruction fires, the RAX register contains the base address of the currently controlled character. When I end the turn and the instruction fires, I want CE to save the remaining addresses into [ptr+8] and [ptr+10].

Currently this script only updates [ptr], (the first dq 0), whenever the instruction fires.

Any ideas on how to modify this script so that instead of overwriting the first dq 0, it overflows to the next dq? So that essentially I'd only need to call [ptr+08] from the table.

I managed to somehow pull this off once before but I just cant remember, and it's late, and I'm getting frustrated at my stupidity and it's time to ask for help.

Also if anyone has other suggestions on more efficient ways to save base addresses as variables via injection/aob feel free to share your dirty little secrets ;D

Bloodybone
Table Makers
Table Makers
Posts: 288
Joined: Thu Aug 03, 2017 6:19 am
Reputation: 133

Re: storing addresses in memory to be used as base pointers

Post by Bloodybone »

RKH4X wrote:
Thu Mar 15, 2018 9:20 pm
Okay so context:

I have 3 characters. They all have a set amount of movement points per turn. I scan for what accesses. I select an instruction that writes 1 to 1 when movement points are added or removed. Show in disassembler. Scan for what addresses this instruction accesses. and there are 3, as you'd expect, for my 3 characters.

Now I want to use the fact that this instruction is used on these 3 addresses to my advantage. I want to be able to write a code that saves the base address of all 3 characters from this instruction into memory so that I can register them as variables, call them in the table and nest offsets underneath it.

Here is an example code to show you what I'm trying and failing to do:

Code: Select all

[ENABLE]
aobscan(baseptr,48 8B C8 48 8B 45 E8 89 88 48 01 00 00)
alloc(newmem,$100,baseptr)

label(code)
label(return)
label(ptr)

newmem:
  push rbx
  mov rbx,ptr
  mov [ptr],rax
code:
  mov [rax+00000148],ecx
  pop rbx
  jmp return
ptr:
  dq 0
  dq 0
  dq 0
baseptr+07:
  jmp newmem
  nop
return:
registersymbol(baseptr)
registersymbol(ptr)

[DISABLE]
baseptr+07:
  db 89 88 48 01 00 00

unregistersymbol(baseptr)
unregistersymbol(ptr)
dealloc(newmem)
In this case, whenever the instruction fires, the RAX register contains the base address of the currently controlled character. When I end the turn and the instruction fires, I want CE to save the remaining addresses into [ptr+8] and [ptr+10].

Currently this script only updates [ptr], (the first dq 0), whenever the instruction fires.

Any ideas on how to modify this script so that instead of overwriting the first dq 0, it overflows to the next dq? So that essentially I'd only need to call [ptr+08] from the table.

I managed to somehow pull this off once before but I just cant remember, and it's late, and I'm getting frustrated at my stupidity and it's time to ask for help.

Also if anyone has other suggestions on more efficient ways to save base addresses as variables via injection/aob feel free to share your dirty little secrets ;D
The First thing you have to do is compare all of them out. But here is a code that will work if you compare out all of them

Code: Select all

[ENABLE]
aobscan(baseptr,48 8B C8 48 8B 45 E8 89 88 48 01 00 00)
alloc(newmem,$100,baseptr)

label(code)
label(return)
label(player1ptr)
label(player2ptr)
label(player3ptr)
label(player1)
label(player2)
label(player3)
registersymbol(player1ptr)
registersymbol(player2ptr)
registersymbol(player3ptr)

newmem:
cmp rcx,1  // This is just a example of course you have to find your own difference
je player1
cmp rcx,2
je player2
cmp rcx,3
je player3
jmp code

player1:
mov [player1ptr],rax
jmp code

player2:
mov [player2ptr],rax
jmp code

player3:
mov [player3ptr],rax
jmp code

code:
  mov [rax+00000148],ecx
  jmp return

player1ptr:
dq 0

player2ptr:
dq 0

player3ptr:
dq 0

baseptr+07:
  jmp newmem
  nop
return:
registersymbol(baseptr)

[DISABLE]
baseptr+07:
  db 89 88 48 01 00 00

unregistersymbol(baseptr)
unregistersymbol(player1ptr)
unregistersymbol(player2ptr)
unregistersymbol(player3ptr)
dealloc(newmem)
Now add [player1ptr]+148 and [player2ptr]+148 and [player3ptr]+148 to the adresslist and that would be all three of them

User avatar
SunBeam
RCE Fanatics
RCE Fanatics
Posts: 4665
Joined: Sun Feb 04, 2018 7:16 pm
Reputation: 4186

Re: storing addresses in memory to be used as base pointers

Post by SunBeam »

The only way to do it like you explained is to create an iterator when you save your pointer. Iterator has to check for NULL pointers first, then check if in your "list" the address has been saved before. If yes, then don't save. Else, write it in the list. If you only have 3 positions then that gets even simpler, cuz you can skip the NULL check and simply do a cmp for 8 times 8 bytes (each pointer is a qword, so 8 bytes).

Am currently on phone, can't write an elaborate example without testing :P

More after the 20th, when I return (if still unsolved).

BR,
Sun

Post Reply

Who is online

Users browsing this forum: No registered users