UnhappyHelpPointers and offsets

Posts 115 of 18 · Page 1 of 2
Pointers and offsets
Hello comm,

I've been trying to create a hack for a long time and now that I begin to understand the concepts which are required I find myself in a road block .
I already succeeded to find the pointer and its offsets for what I'm trying to accomplish.

Image

So if I understand correctly, "0x007CE020" points to "0x5193BD6C" and then we must add the offset to the adress that the pointer points at.

I think the problem is in the code, i'm using this function to read the memory:

Code:
public static byte[] ReadMemory(Process process, int address, int numOfBytes, out int bytesRead)
        {
            IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);

            byte[] buffer = new byte[numOfBytes];

            ReadProcessMemory(hProc, new IntPtr(address), buffer, numOfBytes, out bytesRead);
            return buffer;
        }
And I'm using it like this:

Code:
Process process12 = Process.GetProcessesByName("PROCESS_NAME").FirstOrDefault();
            //Get Adress to change from pointer

            int bytesRead;
            //int bytesWritten;
            byte[] addr = Memory.ReadMemory(process12, 0x007CE020, 4, out bytesRead);
            Array.Reverse(addr); //Converting to Big Endian
            lb.Items.Add(BitConverter.ToInt32(addr, 0)); //Checking the value
The value that I receive is "1824363345" not the expected "0x5193BD6C". Is the received value the decimal value of "0x5193BD6C"?
If so, how can I convert an hexadecimal value as byte array to int so I can add the offset?

Thanks in advance
vLK8b.png17 KB · 19 downloads
If you convert 1824363345 to hex you'll see that it is actually 0x6CBD9351, i.e., the value you want, but on reverse order. That's because you're reversing the byte array for some reason with Array.Reverse(addr);. Get that off and you'll get your value... probably.

Quote Originally Posted by NoLabel View Post
If so, how can I convert an hexadecimal value as byte array to int so I can add the offset?
well... i don't know if I get your question here.. cause you're already converting the value to int on your code... BitConverter.ToInt32(addr, 0)
Don't reverse it and yes "0x007CE020" points to "0x5193BD6C"

Easy way to remember pointers. The base should always be static.
Your case 0x007CE020.
If you read the value (int) of 0x007CE020, it equals 0x5193BD6C (hex)
This is also the next address to read and if you have an offset, add it.

Read the value as (int) of 0x5193BD6C + 8 which equals 0x79928F38

Just keep repeating untill you get your address.

Understanding how pointers work, makes it simple when making a function to read them.
But when I get the first address how do I convert it to a usable address (acceptable to the function ReadMemory)? Because my function reads the address value as int not as byte[].
.net BitConverter class.

Code:
byte[] theBytes = ReadMemory(0x007CE020);
int theAddr = BitConvert.ToInt(theBytes); // theAddr = 0x5193BD6C
"Because my function reads the address value as int not as byte[]."
^^make 1 functions for each data type you expect to read: Int, UInt, Short, UShort, Int64, etc etc. so you're getting returned a core data type, not bytes.


Code:
public static Int32 ReadMemory(Process process, int address, out int bytesRead)
        {
            IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);

            byte[] buffer = new byte[4];

            ReadProcessMemory(hProc, new IntPtr(address), buffer, 4, out bytesRead);
           return BitConvert.ToInt32(buffer);
        }

public static Int64 ReadMemory(Process process, int address, out int bytesRead)
        {
            IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);

            byte[] buffer = new byte[8];

            ReadProcessMemory(hProc, new IntPtr(address), buffer, 8, out bytesRead);
           return BitConvert.ToInt62(buffer);
        }
public static UInt32 ReadMemory(Process process, int address, out int bytesRead)
        {
            IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);

            byte[] buffer = new byte[4];

            ReadProcessMemory(hProc, new IntPtr(address), buffer, 4, out bytesRead);
           return BitConvert.ToUInt32(buffer);
        }
^^there is still room for improvement (IntPtr?), but hopefully that gives you ideas.

edit: you were already using BitConverter, so..

If, for debugging, you want to see the number in hex, just call .ToString("X") which will format the string as hex, not decimal.

ie. int someNum = 100; string myStr = someNum.ToString("X"); // myString = "64"
ie. int someNum = 196; string myStr = someNum.ToString("X"); // myString = "C4"
Code:
byte[] theBytes = ReadMemory(0x007CE020);
int theAddr = BitConvert.ToInt(theBytes);
MsgBox(theAddr.ToString("X"));
- in your original idea "If so, how can I convert an hexadecimal value as byte array"
it's not a hex value, it's just a value
-- it's a byte array, it's not "stored" in some specific representation like hex,decimal,binary etc.. in reality, it's all the same value, so no conversion required.
99% of the time, leave your addresses as Int (should be IntPtr), you should never have to convert to hex. Except, maybe to debug/test, because for example, CE displays addr in hex, not decimal.


repeat: .ToString("X"); for DISPLAYING in Hex.
.
As humans, we default to base 10...so when we say "34" it's kind of implied that we mean base 10
..However, because it's less digits to look at, sometimes we *view* the number in a different base(CE: hex), but really it still has exactly the same value.
When you display a number in c#, like an int, you're actually calling .ToString() on that int! Which makes sense because, INT is a NUMBER, but we're trying to display it as a "string"..so it has to convert it's "value" to a string --> by default, again, because humans like base 10, it uses base 10 and shows the string of "34". (22 in hex)
So when you put MsgBox(someInt), it's actually saying MsgBox(someInt.ToString(decimal))
and if you're trying to see the same addr as CE displays, you probably want
MsgBox(someInt.ToString("X")); //in hex

and to avoid confusion, any time you debug/output a value in hex, prefix it with "0x" so you know it's being displayed in hex
ie. msgBox("0x" + someInt.ToString("X")); // hex, with prefix, so we know* it's displayed in hex.
Thank you very much for the explainning. I shall say something if I have any further doubt.
Np. I just noticed in your first post, the image of your app:

Looks like you're typing in the address as hex...how is your code converting the txt box value to an Int?
It's not my app, it's the cheat engine's Add pointer window. I have another problem.

Comparing Addresses

Code

Code:
            Process process12 = Process.GetProcessesByName("processname").FirstOrDefault();
            

            int bytesRead;
            int bytesWritten;
            int baseAddr = 0x007CE020;

            //Get Adress to change from pointer
            int addr = Memory.ReadMemoryInt32(process12, 0x007CE020, out bytesRead);
            lb.Items.Add("1-" + addr.ToString("X"));

            //Add offset and get 2n adress
            int addr2 = Memory.ReadMemoryInt32(process12, addr + 8, out bytesRead);
            lb.Items.Add("2-" + addr2.ToString("X"));

            //Add 2n offset and get 3rd adress
            int addr3 = Memory.ReadMemoryInt32(process12, addr2 + 680, out bytesRead);
            lb.Items.Add("3-" + addr3.ToString("X"));

            //Write value to final address
            Memory.WriteMemory(process12, addr3, 1, out bytesWritten);

            //Read value from the final address
            int addr4 = Memory.ReadMemoryInt32(process12, addr3, out bytesRead);

            lb.Items.Add("4-" + addr4);
ReadMemoryInt32 function:

Code:
        public static Int32 ReadMemoryInt32(Process process, int address, out int bytesRead)
        {
            IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);

            byte[] buffer = new byte[4];

            ReadProcessMemory(hProc, new IntPtr(address), buffer, 4, out bytesRead);
            return BitConverter.ToInt32(buffer, 0);
        }
I can't find out why the last address is different
@NoLabel
Code:
int addr3 = Memory.ReadMemoryInt32(process12, addr2 + 0x680, out bytesRead);
Nop, same error . First and second addresses are correct, but the third is always wrong...

Image

Code

Code:
        Process process12 = Process.GetProcessesByName("processname").FirstOrDefault();
            

            int bytesRead;
            int bytesWritten;
            int baseAddr = 0x007CE020;

            //Get Adress to change from pointer
            int addr = Memory.ReadMemoryInt32(process12, 0x007CE020, out bytesRead);
            lb.Items.Add("1-" + addr.ToString("X"));

            //Add offset and get 2n adress
            int addr2 = Memory.ReadMemoryInt32(process12, addr + 0x8, out bytesRead);
            lb.Items.Add("2-" + addr2.ToString("X"));

            //Add 2n offset and get 3rd adress
            int addr3 = Memory.ReadMemoryInt32(process12, addr2 + 0x680, out bytesRead);
            lb.Items.Add("3-" + addr3.ToString("X"));

            //Write value to final address
            Memory.WriteMemory(process12, addr3, 0x1, out bytesWritten);

            //Read value from the final address
            int addr4 = Memory.ReadMemoryInt32(process12, addr3, out bytesRead);

            lb.Items.Add("4-" + addr4);
hmm, the code looks correct to me.
lets see the ReadMemoryInt32 function
It's the one I posted above:

Code:
      public static Int32 ReadMemoryInt32(Process process, int address, out int bytesRead)
        {
            IntPtr hProc = OpenProcess(ProcessAccessFlags.All, false, process.Id);

            byte[] buffer = new byte[4];

            ReadProcessMemory(hProc, new IntPtr(address), buffer, 4, out bytesRead);
            return BitConverter.ToInt32(buffer, 0);
        }
value.ToString("X"); ???
These lines: ?

lb.Items.Add("3-" + addr3.ToString("X"));

Just for debugging purposes.

Edit: The problem still persists... Any solutions?
"but the third is always wrong" ... well the code is working -- if it reads the first 2 correctly, the code is working.
I have no idea what CE is telling you: my advice, don't use CE features unless you know what it's doing..

Also, un-related, but: if the 2nd addr never changes....why even bother reading the first addr? If it always points to 0x5193BD6C: just start reading at 0x519***. No point in reading addr1 is you already know it always points to 0x519**

^^ @OP, not other ppl: I know you know the answer.
Posts 115 of 18 · Page 1 of 2

Post a Reply

Similar Threads

Tags for this Thread

None

Need help?