I've written a little program in C++2019 for theHunter (x64) that reads a global variable (number of animals I've scared away) and plays a short sound clip whenever that increments. It works well until there is a game update and then I need to update the pointers, so I would like to transition to an AOB-based system (for the challenge and for convenience), and this is where I've come a bit unstuck.
I have some code from here that I've tweaked to address x64, and I have a candidate AOB from CE. So far so good.
The existing code it expects to find the AOB within the external module's address range (e.g. theHunter.exe), but my target variable isn't in this range (according to CE). If I tweak the code to just run everything from 0x0 to 0x7fffffffffff then I get bad_alloc errors from VS (I wonder if this is due to how the code tries to clone the memory space in its entirety) but either way it is a massive range to trudge through even if broken up into chunks. If I instead use my a-priori knowledge of the location of the variable and set it to run over a small range, say +/- 0xffff then it finds the address, so the code works in some sense.
So yeah, full-disclosure: my understanding of this is weak, and address 0x1804405B300 (for example) may as well be in outer space. I am not clear on whether this is an address 'owned' by the game or a shared space, but either way I think I need to fine tune the range I'm scanning and I have only a primitive sense of how to do that. Using pointers might mean I'm back to square one, so is a brute force scan from 0x0 to 0xMAX likely to work?
Alternatively, should I be using the AOB corresponding to the instructions that modify the variable? I don't want to do any code injection, and my meagre understanding is that the register storing the address will only hold it for a short while while those instructions run and won't be a reliable place to read it from. I'm sure there is a way, I just don't know it and will need a steer.
Which strategy is likely to pay off and how might I move on from here?
Finally, What should I be googling/reading to understand how memory addressing (?) works?
Thanks for reading this far and any help you can give. I'm happy to provide additional detail on anything. I love this new hobby, but there is just so much to learn!
EDIT 29/1/20: its probably not a global variable, but a variable generated at runtime. Oops.
Which strategy to find a variable using AOB scan in Cpp?
-
- Noobzor
- Posts: 5
- Joined: Sat Jul 27, 2019 12:04 am
- Reputation: 0
Which strategy to find a variable using AOB scan in Cpp?
Last edited by hardjack79 on Wed Jan 29, 2020 12:34 am, edited 2 times in total.
Re: Which strategy to find a global variable using AOB scan in Cpp?
I find it's better to look for a reference that leads to the global you're looking for:
x86:
mov ecx,eax
call func
func:
mov eax,[global]
ret
So you'd look for the bytes that correspond to "mov ecx,eax + call func" (you can go above 'mov ecx,eax', if that makes the AOB more unique). Then what you do is you use the eip of your aob, add x bytes to get to the call, calculate the destination of the call, then read from destination + x bytes to get the global. Sounds complicated, but in reality it really isn't. You can do this with CE's Lua very easily, just to mimic the steps I mentioned.
Otherwise, if the simplest way for you is to use a location that directly contains the global, you may do so. Just keep in mind "mov eax,[global]" + bytes around it might often change with updates. Whereas the "mov ecx,eax + call func" won't
BR,
Sun
x86:
mov ecx,eax
call func
func:
mov eax,[global]
ret
So you'd look for the bytes that correspond to "mov ecx,eax + call func" (you can go above 'mov ecx,eax', if that makes the AOB more unique). Then what you do is you use the eip of your aob, add x bytes to get to the call, calculate the destination of the call, then read from destination + x bytes to get the global. Sounds complicated, but in reality it really isn't. You can do this with CE's Lua very easily, just to mimic the steps I mentioned.
Otherwise, if the simplest way for you is to use a location that directly contains the global, you may do so. Just keep in mind "mov eax,[global]" + bytes around it might often change with updates. Whereas the "mov ecx,eax + call func" won't
BR,
Sun
-
- Noobzor
- Posts: 5
- Joined: Sat Jul 27, 2019 12:04 am
- Reputation: 0
Re: Which strategy to find a global variable using AOB scan in Cpp?
Thanks SunBeam. I think the idea of testing a method in Lua first is a great one. I'll try and figure out how to use a reference from within .text rather than looking directly in .data or .bss, which is what I think I have done so far (e.g. I haven't found a reference to my global variable, I've just found the global variable itself).
Because I won't be reading the function at the time of a call, am I dependent on it having a hardcoded address to my global variable? Things like eax, ecx will only hold the address fleetingly during a call (I assume).
I'll read up on Lua, and assembly for that matter, and give this a crack when I get home.
Because I won't be reading the function at the time of a call, am I dependent on it having a hardcoded address to my global variable? Things like eax, ecx will only hold the address fleetingly during a call (I assume).
I'll read up on Lua, and assembly for that matter, and give this a crack when I get home.
Last edited by hardjack79 on Wed Jan 29, 2020 12:36 am, edited 1 time in total.
-
- Noobzor
- Posts: 5
- Joined: Sat Jul 27, 2019 12:04 am
- Reputation: 0
Re: Which strategy to find a global variable using AOB scan in Cpp?
A clarification: I think it was misleading and ignorant of me to call my target a "global variable". I've done some more reading and I think the variable is part of a structure that probably lives within the heap. In any case it resides in a 'black' address in CE that changes on each application startup.
Who is online
Users browsing this forum: No registered users