I have my base memory address "GameAssembly.dll"+00DA5A84
and some offets. Adding this up I got the address I need. (The red rectangle). This one changes every time that the game is reset.
Once I got the memory address I can do the following:
public void isImpostor(IntPtr addrs, int valueToWriteInMemory)
{
using (var sharp = new MemorySharp(Process.GetProcessesByName("Among Us").FirstOrDefault()))
{
sharp[addrs, false].Write(valueToWriteInMemory);
}
}
var addrs = new IntPtr(0x210A83A8);
isImpostor(addrs, 0x0);
nevertheless I'm not sure how I can get that memory address. Not sure how to do:
"GameAssembly.dll" + 0x00DA5A94 + 0x28 + 0x34 + 0x0 + 0x5C
and obtain as a result 0x210A83A8
.
Updated:
In order to know what the AddressBase from GameAssembly.dll is I have this method.
public int GetModuleAddress(String pName, String dllName)
{
Process p = Process.GetProcessesByName(pName).FirstOrDefault();
foreach(ProcessModule pm in p.Modules)
if (pm.ModuleName.Equals(dllName))
return (int)pm.BaseAddress;
return 0;
}
Console.WriteLine(GetModuleAddress("Among Us", "GameAssembly.dll");
Console.WriteLine((IntPtr)GetModuleAddress("Among Us", "GameAssembly.dll"));
Result1 (As integer): 2043150336
Result2 (After Casting to IntPtr): 2043150336 here I can do the addition I mentioned before.
it returns an int
so I can't do the addition of GameAssembly.dll + 0x00DA5A94. Assuming this I cast this result to IntPtr
. once it was cast to IntPtr I can do this.
IntPtr A_ptr =(IntPtr)GetModuleAddress("Among Us", "GameAssembly.dll") + 0x00DA5A94;
But I got this message error:
System.ComponentModel.Win32Exception: 'Couldn't read 4 byte(s) from 0x5C.'
I tried also to cast the address to HEX, with toString("X")
method and I got as result 79C80000
but I can't do neither 79C80000 + 0x00DA5A94
nor 0x79C80000 + 0x00DA5A94
.
looking at values inside of variables I got this.
BaseAdressDLL: 2043150336
A: 0, Aptr: 2057460372 (or 0x00000000 and 0x7aa25a94 respectively)
Bptr: 92 (or 0x0000005c)
What I'm doing wrong? I'm also sorry for my English.
I tried using the BaseAdress that Cheat engines gives me, and it works perfectly so I assume that I don't know how to get the AdressBase properly.
var sharp = new MemorySharp(Process.GetProcessesByName("Among Us").FirstOrDefault());
/* This does`t work
IntPtr GameB = (IntPtr)GetModuleAddress("Among Us", "GameAssembly.dll");
IntPtr GameAssemblyDllBaseAddress = sharp.Read<IntPtr>(GameB, false);
IntPtr A_ptr = GameAssemblyDllBaseAddress + 0x00DA5A94;
IntPtr A = sharp.Read<IntPtr>(A_ptr, false);
*/
// But this does it.
IntPtr A = (IntPtr)0x11F7FC18; // Using AddressBase directly.
// -------------
IntPtr B_ptr = A + 0x5C;
IntPtr B = sharp.Read<IntPtr>(B_ptr, false);
IntPtr C_ptr = B + 0x0;
IntPtr C = sharp.Read<IntPtr>(C_ptr, false);
IntPtr D_ptr = C + 0x34;
IntPtr D = sharp.Read<IntPtr>(D_ptr, false);
IntPtr isImpostor_ptr = D + 0x28;
// read
int isImpostor = sharp.Read<int>(isImpostor_ptr, false);
// write
sharp[isImpostor_ptr, false].Write(0x1);
What you have is a bunch of pointers. Lets give them names:
"GameAssembly.dll" + 0x00DA5A94 - pointer to A
+ 0x5C - A + 0x5C - pointer to B
+ 0x0 - B + 0x0 - pointer to C
+ 0x34 - C + 0x34 - pointer to D
+ 0x28 - D + 0x28 - pointer to int (let's call it isImpostor_ptr)
If you want to know the value of isImpostor
, let's say, you need to dereference (read the value stored at the memory address) isImpostor_ptr
:
isImpostor = [isImpostor_ptr] or isImpostor = [D + 0x28]
To get D
you need to dereference C + 0x34
and so on and you eventually get:
isImpostor = [[[[["GameAssembly.dll" + 0x00DA5A94] + 0x5C] + 0x0] + 0x34] + 0x28]
In C#:
IntPtr A_ptr = GameAssemblyDllBaseAddress + 0x00DA5A94;
IntPtr A = sharp.Read<IntPtr>(A_ptr, false);
IntPtr B_ptr = A + 0x5C;
IntPtr B = sharp.Read<IntPtr>(B_ptr, false);
IntPtr C_ptr = B + 0x0;
IntPtr C = sharp.Read<IntPtr>(C_ptr, false);
IntPtr D_ptr = C + 0x34;
IntPtr D = sharp.Read<IntPtr>(D_ptr, false);
IntPtr isImpostor_ptr = D + 0x28;
// read
int isImpostor = sharp.Read<int>(isImpostor_ptr, false);
// write
sharp[isImpostor_ptr, false].Write(valueToWriteInMemory);
Those offsets are the addresses of variables on the stack. Where they are positioned depends completely on the functions called before the starting point.
For example, imagine this code, in an imaginary simple 16-bit processor that uses the stack to pass all parameters:
void Func1()
{
int var1 = 1;
Func2();
}
void Func2()
{
int var2 = 2;
Func3(var2);
}
void Func3(int i)
{
int var3 = 3;
BREAKPOINT // This is where your calculations should start
}
When the code hits BREAKPOINT, the stack looks like (X = base address):
0xX0000000 <- Return address of the next line Func1 after the call to Func2
0xX0000004 <- var1
0xX0000008 <- Return address of the next line Func2 after the call to Func3
0xX000000C <- var2
0xX0000010 <- contents of var2 as passed to Func3
Given that you know the base address, and you understand how to walk back up the stack, you can find the address of var1 and modify it.
User contributions licensed under CC BY-SA 3.0