c++ - 引用多级指针的更好方法?

标签 c++ visual-c++ pointers memory visual-studio-2012

至于现在,我正在尝试为不存在此类游戏的游戏制作基本的“飞行模式”。为此,我需要操纵游戏内存,这意味着必须使用指针来访问内存(通过 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)...

但是这样一来,管理所有这些地址和偏移量将变得非常不方便。

我在此代码中所做的是访问游戏的基地址,将第一个偏移量添加到指针,然后从该指针应用 X Y Z 偏移量(+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);
    }
}

最佳答案

让我们从简化算术开始:

unsigned int BaseAddr = *(unsigned int*)(gameBaseAddress + 0x20) + 0x20;

float* PosX = (float*)(BaseAddr);
float* PosY = (float*)(BaseAddr + 4);
float* PosZ = (float*)(BaseAddr + 8);

…string_format(…*PosX,*PosY,*PosZ)…

(请注意,这会跳过 RevPointer(&BaseAddr,unsigned int) 步骤。请参阅我对原始问题的评论以了解原因。)

据此,我们可以进一步简化:

struct Point { float x, y, z; };
auto BaseAddr = *(unsigned int*)(gameBaseAddress + 0x20);
auto& p = *(Point*)(BaseAddr + 0x20);
…string_format(…p.x,p.y,p.z)…

我不会为 AddVarRevPointer 宏操心。它们只会混淆视听,IMO。

关于c++ - 引用多级指针的更好方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15047644/

相关文章:

android - 在 Android 上使用 Instrumentation 进行 Clang 分析

c++ - 奇怪的默认构造函数语法

c++ - 在 C++ 中使用指针按引用传递数组

c++ - 是什么导致此代码中的段错误?

c++ - 在类的初始化列表中初始化 std::vector

c++ - 如何将 char 数组插入到 float vector 中

c++ - fatal error LNK1158 : cannot run 'mt.exe'

c - fgets() 函数不起作用

c++ - 创建一个 boolean 函数来确定两个数组是否移位等效

c++ - 如何将 wchar_t* 转换为 long C++