Yes, it is possible
I'm going to explain you a bit how most games do it (I have never reversed any GTA but I suppose it's something like this anyway).
I'm going to cover static and dynamic allocation of structures.
The static way:
g_info.some_data = 1;
This is what ends up being a static offset in IDA, like so:
lea eax, [...
The variable being assigned to:
The type cast needed to convert the result of the subroutine to the type of v14:
(int (__cdecl *)(signed int))
The subroutine call, with one argument: 1:
The typecast is needed because hexrays did not figure out automatically what the return type of sub_8048FB6 is, so it probably defaulted to int, ...
lea = address
mov = contents
if address 0x401000 contains 0xDeadBeef like ef be ad de
lea MySecretPlace,  MySecretPlace will be 0x401000
Mov MySecretPlace,  MySecretPlace will be DeadBeef
mov MySecretPlace, byte ptr  MySecretPlace will be 0xef 0r 0xef depending on EndianNess
mov MySecretPlace, word ptr  ...
Right-click on the disassembly line above in OllyDbg and choose Follow in Dump. That will tell OllyDbg to navigate to address 7FEEC617750 in the dump pane and allow you to see the memory at that address:
To see what accesses and writes to the memory at that address, right-click in the dump pane on the first byte of memory at that address and set a hardware ...
There are many reasons for this. I'll jot down a bunch that I can think of off the top of my head.
Many hackers use things like Cheat Engine's built-in automatic pointer scanning functionality because it's easy. Even if they don't understand what's going on, the YouTube videos and/or tutorials they've followed in the past have pigeonholed their approach.
There is no such thing. There is only pointer obfuscation. This is essentially how Microsoft markets a couple of functions, and they're pretty open about it from the docs on EncodePointer
Encoding globally available pointers helps protect them from being exploited. The EncodePointer function obfuscates the pointer value with a secret ...
Let's split this up a bit. I'll skip over some stuff that you might already understand, but we may need to expand this if some stuff is not clear.
MOV DWORD PTR SS:[EBP-30],400400
MOV DWORD PTR SS:[EBP-30],DWORD PTR DS:
The syntax is a bit wonky but we can understand that you want to encode a MOV with two memory operands.
Let's take a look at some ...
Warning: Illegal instruction used for explanation.
If you are wondering if mov can do the work of lea,
mov eax, esp+4 and lea eax, [esp+4] copies the same value to eax.
However, mov eax, esp+4 is not a legal instruction! (esp+4 is not a legal addressing mode.)
But then, can you replace lea eax, [esp+4] with the following?
mov eax, esp
add eax, 4
Not really! ...
mov ds:dword_804C0D4, offset unk_804C0B8
so if this instruction was executed first before the sub was called then
0x804c0d4 would contain 0x804c0b8
v2 = *(_DWORD *)dword_804C0D4;
so v2 would be 0x804c0b8
assuming int a1 == 0
v3 = *(_DWORD *)(8 * a1 + 4 + *(_DWORD *)dword_804C0D4);
v3 would be ((8 * 0) + 4 + 0x804c0b8) == (0 + 4 +0x804c0b8) == *(...
The Itanium C++ ABI is sometimes not very clear about what exactly is “vtable”.
In practice, the symbol such as _ZTV12DerivedClass points to the complete vtable structure, which includes the two pointer-sized slots before it (RTTI pointer and offset to top).
So, to get the start of the virtual function pointers table (what is commonly understood as “the ...
What you're looking it is actually a VTable. As you know, a VTable is a table of function pointers and as you can see, at address 0x19B64 you actually see a single function address (this looks like dd offset sub_XXXX). That is actually a virtual function table of a size of one. Since you only have one virtual function in your demo class. That offset points ...
This is basic. Assume that rpb has a value of 55h (Assembler syntax). then
lea rax, [rbp-50h]
would result in 5.
On the other hand, mov rax, [rbp-50h] would most probable crash your application, as it would try to read the content of the address 5 and put it into rax.
Thus, the difference is that the first is direct, the second indirect.
BTW, you can ...
The topic of pointer analysis is an important part of theoretical static analysis. Many articles and academic publications have been written about pointer analysis, this is a heavily researched field.
Besides the theoretical research, it is often an difficult issue to address even by skilled and trained reverse engineers. In certain cases it can be nearly ...
FAR is just an attribute, not a data type. Not even a standard attribute, but an attribute that was introduced with MS-DOS C compilers, to distinguish between 16-bit and 32-bit pointers, and carried over to windows 16 bit, windows 32 bit and, recently, windows 64 bit.
What is stored in the structure is a pointer to a character (in fact, an array of ...
lets have a look how Cheat Engine calculates its offsets:
4C 8B 05 471EE300 translates to mov r8,QWORD PTR [rip+0xe31e47]
As you can see, the value depends on rip (the instruction pointer). You can see the actual bytes of the offset in the instructions bytes. Since Cheat Engine knows where this instruction actually is in memory, they use the image base as ...
Your question is a bit unclear as you first say "Class C has a method "addListerner" which points to an attribute (this + 0x34).", then D::addListener(this + 0x34);. Typo?
Also, you should read about (typical) implementations of multiple inheritance. Assume your classes B, C, D have methods b, c, d respectively. A will inherit all of them. Now, if A does ...
I'd change the variable right when it's created and stored into its position. For example, if one function calls another, that other function returns the variable, and the first function stores it somewhere, this will look in assembly somewhat like
80483e7: e8 d8 ff ff ff call 80483c4 <value>
80483ec: 8b 54 24 1c mov ...
In order to get Hexrays to detect that your subtype passed as an argument is actually a member of a bigger parent type, you have to declare the parent type as a structure, and declare the corresponding field in this parent struct as a pointer to the subtype.
The function argument type is irrelevant for this purpose, and should have the type of the substruct....
The difference is that lea only calculates the address while mov actually moves the data. If you know C or C++, it’s somewhat similar to:
Lea:rax = rbp + 0x50;
Mov: rax = rbp[0x50];
(Not equivalent to assembly because of different way of counting)
There is no specific stack pointer register in ARM. By convention R13 is used as the stack pointer. There is no specific push and pop style stack pointer operands either.
Pushing and popping from the stack is carried out using the STM (store to memory) and LDM (load from memory) operands. These operands can be modified with the post fixes IA and DB. IA is ...
I think you are running into a case of "shifted pointers". For various reasons the compiler might generate code where a pointer to the middle of a struct is returned. There is a Ghidra PR for this, but this isn't merged yet and still has various issues, IDA discusses this feature here
ntohs basically converts a netshort to hostshort
>>> import socket
>>> print (hex(socket.ntohs(0x1337)))
>>> print (hex(socket.ntohs(0x3713)))
it will write back
0x3713-0x2 = 0x3711 or 0x1337 - 0x2 = 0x1335
in the address pointed by remaining if it is > 1u
and return back an address a pointer to ...
Memory-to-memory MOV does not exist. You could try the following:
MOV eax, DWORD PTR DS : 
MOV DWORD PTR SS : [EBP - 30], eax
Please check also if the absolute numbers are interpreted as hex values in your assembler.
By declaring d inside main() it is a local scope variable, which exists on the stack and is therefore dynamic.
If you declare this pointer outside of main, it will be a global variable and it will have the same address every time, as long as there is know memory randomization provided as security measure of the OS.
It's way simpler than you'd think.
461EE300 is the relative offset to your variable. The relative offset needs to be added to the rip-register. And you already have the value of the rip-register. It's the address of the pattern you found.
So simply add the address of your pattern with 461EE300 and you have your variable.
If you disassemble the instructions for
mov edx, offset ds:mystring
lea rdx, offset ds:mystring
You'll notice the LEA instruction length (in bytes) was smaller. Its a compiler optimization!
Or, it could be the compilers way of addressing pointer arithmetic in an easier manner.
Check out this for more info on both.
Regarding the potential bug in IDA:
First of all, you can add references yourself with idaapi.add_cref and idaapi.add_dref IDAPython APIs. This may be done with relatively simple script like this:
predefined_r13 = YOUR_R13_VALUE
for h in idautils.Heads():
dis = idc.GetDisasm(h) #probably there is another way ...