今のところ、そのようなものが存在しないゲームの基本的な「フライモード」を作ろうとしています。そのためには、ゲームのメモリを操作する必要があります。つまり、メモリにアクセスするには(DLLを使用して)ポインタを使用する必要があります。
今のところ私はこのコードを使用しています:
#define AddVar(Type,Name,Address) Type& Name = *reinterpret_cast<Type*>(Address)
AddVar(unsigned int,gameBaseAddress,0x0089CDA8);//base address
//*Reveal* pointer, dunno how to name this
#define RevPointer(addr,type) (*(type *)(addr))
void FrameTick(IDirect3DDevice9 * device, HWND wnd)
{
DirectXFont::Access(0)->Print(0.0,0.0,0xFFFFFFFF,"{FFFF0000}N{FF00FF00}F{FF0000FF}S {FFFFFF00}MOD {FF00FFFF}1.0",true);
if(gameBaseAddress)//check if the game has loaded <accessing the VALUE at gameBaseAddress)
{
//lvl 1 ptr
unsigned int BaseAddr = RevPointer(gameBaseAddress+0x20,unsigned int);//base + pointer offset 1 (+0x20)
//lvl2 ptr
BaseAddr += 0x20;//(base + offset 1 (+0x20)) + pointer offset 2 (+0x20) - X pos
unsigned int PosXAddr = RevPointer(&BaseAddr,unsigned int);//got this line of code by trial and error, don't know how this magicly works
BaseAddr += 0x4;//y pos is 4 bytes further
unsigned int PosYAddr = RevPointer(&BaseAddr,unsigned int);
BaseAddr += 0x4;//z the same
unsigned int PosZAddr = RevPointer(&BaseAddr,unsigned int);
float *PosX = (float*)PosXAddr;
float *PosY = (float*)PosYAddr;
float *PosZ = (float*)PosZAddr;
if(PosXAddr && PosXAddr < 0xAAAA0000)//check if pointer is valid
{
DirectXFont::Access(0)->Print(0.0,60.0,0xFFFFFFFF,string_format("%.2f %.2f %.2f",*PosX,*PosY,*PosZ).c_str(),true);//works
}
}
}
ゲームのデバッグから、すべてのポインターが..まあ..マルチレベルポインターであることがわかりました。
(((base_adderss + 0xOFFSET1)+ 0xOFFSET2)+ 0xOFFSET3)..。
ただし、この方法では、これらすべてのアドレスとオフセットを管理するのは非常に不便になります。
このコードで私が行っているのは、ゲームのベースアドレスにアクセスし、最初のオフセットをポインターに追加してから、そのポインターからXYZオフセット(+ 0x20、+ 0x24、+ 0x28)を適用して、のXYZ位置を取得することです。メモリからオブジェクトが必要でした。
このコードはすでに醜いように見えます。私がやりたいことを達成するためのより良い方法はありますか?
ご入力ありがとうございました。誰かが私が持っている現在のコードが欲しいなら:
#define AddVar(Type,Name,Address) Type& Name = *reinterpret_cast<Type*>(Address)
AddVar(unsigned int,PositionBaseAddress,0x0089CDA8);//base address
struct Point { float x, y, z; };
void FrameTick(IDirect3DDevice9 * device, HWND wnd)
{
DirectXFont::Access(0)->Print(0.0,0.0,0xFFFFFFFF,"{FFFF0000}N{FF00FF00}F{FF0000FF}S {FFFFFF00}MOD {FF00FFFF}1.0",true);
if(PositionBaseAddress)
{
auto BaseAddr = *(unsigned int*)(PositionBaseAddress + 0x20);
if(IsBadReadPtr(&BaseAddr,0x04) != 0)
return;
auto& p = *(Point*)(BaseAddr + 0x20);
auto& v = *(Point*)(BaseAddr + 0x70);
if(IsBadReadPtr(&p,0x04) != 0)
return;
DirectXFont::Access(0)->Print(0.0,45.0,0xFFFFFFFF,string_format("Position: %.2f %.2f %.2f",p.x,p.y,p.z).c_str(),true);
DirectXFont::Access(0)->Print(0.0,60.0,0xFFFFFFFF,string_format("Velocity: %.2f %.2f %.2f",v.x,v.y,v.z).c_str(),true);
}
}
/*
Position.X: (0x0089CDA8 + 0x20) + 0x20
Position.Y: (0x0089CDA8 + 0x20) + 0x24
Position.Z: (0x0089CDA8 + 0x20) + 0x28
Velocity.X: (0x0089CDA8 + 0x20) + 0x70
Velocity.Y: (0x0089CDA8 + 0x20) + 0x74
Velocity.Z: (0x0089CDA8 + 0x20) + 0x78
*/
その後、構造体を巧みに利用できることに気づきました。
そして私はこのコードを作りました:
#define AddVar(Type,Name,Address) Type& Name = *reinterpret_cast<Type*>(Address)
AddVar(unsigned int,PositionBaseAddress,0x0089CDA8);//base address
struct Point { float x, y, z; };
struct VehicleInfo
{
Point Pos;
int unknown[0x11];
Point Velocity;
};
void FrameTick(IDirect3DDevice9 * device, HWND wnd)
{
DirectXFont::Access(0)->Print(0.0,0.0,0xFFFFFFFF,"{FFFF0000}N{FF00FF00}F{FF0000FF}S {FFFFFF00}MOD {FF00FFFF}1.0",true);
if(PositionBaseAddress)
{
auto BaseAddr = *(unsigned int*)(PositionBaseAddress + 0x20);
if(IsBadReadPtr(&BaseAddr,0x04) != 0)
return;
auto& info = *(VehicleInfo*)(BaseAddr + 0x20);
if(IsBadReadPtr(&info,0x04) != 0)
return;
DirectXFont::Access(0)->Print(0.0,45.0,0xFFFFFFFF,string_format("Position: %.2f %.2f %.2f",info.Pos.x,info.Pos.y,info.Pos.z).c_str(),true);
DirectXFont::Access(0)->Print(0.0,60.0,0xFFFFFFFF,string_format("Velocity: %.2f %.2f %.2f",info.Velocity.x,info.Velocity.y,info.Velocity.z).c_str(),true);
}
}