内存地址,知道偏移量和 dll 的基址如何获取内存地址以设置值
Memory address, knowing the offsets and the base address of a dll how can I obtain the memory adress to set values
我有我的基本内存地址 "GameAssembly.dll"+00DA5A84
和一些偏移量。加起来我得到了我需要的地址。 (红色矩形)。每次重置游戏时都会更改。
获得内存地址后,我可以执行以下操作:
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);
尽管如此,我不确定如何获得该内存地址。不知道该怎么做:
"GameAssembly.dll" + 0x00DA5A94 + 0x28 + 0x34 + 0x0 + 0x5C
得到 0x210A83A8
.
已更新:
为了知道 GameAssembly.dll 的 AddressBase 是什么,我有这个方法。
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.
它 returns 一个 int
所以我不能添加 GameAssembly.dll + 0x00DA5A94。假设我将此结果转换为 IntPtr
。一旦它被转换为 IntPtr 我就可以做到这一点。
IntPtr A_ptr =(IntPtr)GetModuleAddress("Among Us", "GameAssembly.dll") + 0x00DA5A94;
但我收到此消息错误:
System.ComponentModel.Win32Exception: 'Couldn't read 4 byte(s) from 0x5C.'
我也尝试过使用 toString("X")
方法将地址转换为十六进制,得到的结果是 79C80000
但我既不能做 79C80000 + 0x00DA5A94
也不能做 0x79C80000 + 0x00DA5A94
.
查看变量内部的值我明白了。
BaseAdressDLL: 2043150336
A: 0, Aptr: 2057460372 (or 0x00000000 and 0x7aa25a94 respectively)
Bptr: 92 (or 0x0000005c)
我做错了什么?我也为我的英语感到抱歉。
我尝试使用 Cheat engines 给我的 BaseAdress,它工作得很好,所以我假设我不知道如何正确获取 AdressBase。
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);
这些偏移量就是变量在栈上的地址。它们的位置完全取决于起点之前调用的函数。
例如,想象一下这段代码,在一个假想的简单 16 位处理器中,它使用堆栈来传递所有参数:
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
}
当代码遇到断点时,堆栈看起来像(X = 基地址):
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
假设您知道基地址,并且了解如何返回堆栈,您可以找到 var1 的地址并修改它。
你有的是一堆指针。让我们给他们起个名字:
"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)
如果你想知道isImpostor
的值,比方说,你需要解引用(读取存储在内存地址的值)isImpostor_ptr
:
isImpostor = [isImpostor_ptr] or isImpostor = [D + 0x28]
要获得 D
你需要取消引用 C + 0x34
等等,你最终会得到:
isImpostor = [[[[["GameAssembly.dll" + 0x00DA5A94] + 0x5C] + 0x0] + 0x34] + 0x28]
在 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);
我有我的基本内存地址 "GameAssembly.dll"+00DA5A84
和一些偏移量。加起来我得到了我需要的地址。 (红色矩形)。每次重置游戏时都会更改。
获得内存地址后,我可以执行以下操作:
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);
尽管如此,我不确定如何获得该内存地址。不知道该怎么做:
"GameAssembly.dll" + 0x00DA5A94 + 0x28 + 0x34 + 0x0 + 0x5C
得到 0x210A83A8
.
已更新:
为了知道 GameAssembly.dll 的 AddressBase 是什么,我有这个方法。
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.
它 returns 一个 int
所以我不能添加 GameAssembly.dll + 0x00DA5A94。假设我将此结果转换为 IntPtr
。一旦它被转换为 IntPtr 我就可以做到这一点。
IntPtr A_ptr =(IntPtr)GetModuleAddress("Among Us", "GameAssembly.dll") + 0x00DA5A94;
但我收到此消息错误:
System.ComponentModel.Win32Exception: 'Couldn't read 4 byte(s) from 0x5C.'
我也尝试过使用 toString("X")
方法将地址转换为十六进制,得到的结果是 79C80000
但我既不能做 79C80000 + 0x00DA5A94
也不能做 0x79C80000 + 0x00DA5A94
.
查看变量内部的值我明白了。
BaseAdressDLL: 2043150336
A: 0, Aptr: 2057460372 (or 0x00000000 and 0x7aa25a94 respectively)
Bptr: 92 (or 0x0000005c)
我做错了什么?我也为我的英语感到抱歉。
我尝试使用 Cheat engines 给我的 BaseAdress,它工作得很好,所以我假设我不知道如何正确获取 AdressBase。
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);
这些偏移量就是变量在栈上的地址。它们的位置完全取决于起点之前调用的函数。
例如,想象一下这段代码,在一个假想的简单 16 位处理器中,它使用堆栈来传递所有参数:
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
}
当代码遇到断点时,堆栈看起来像(X = 基地址):
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
假设您知道基地址,并且了解如何返回堆栈,您可以找到 var1 的地址并修改它。
你有的是一堆指针。让我们给他们起个名字:
"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)
如果你想知道isImpostor
的值,比方说,你需要解引用(读取存储在内存地址的值)isImpostor_ptr
:
isImpostor = [isImpostor_ptr] or isImpostor = [D + 0x28]
要获得 D
你需要取消引用 C + 0x34
等等,你最终会得到:
isImpostor = [[[[["GameAssembly.dll" + 0x00DA5A94] + 0x5C] + 0x0] + 0x34] + 0x28]
在 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);