我正在尝试找到UrbanTerror42的基本指针。
我的设置如下,我有一台带有2个播放器的服务器。
Cheat Engine 在客户端a上运行。
我与客户b爬上梯子,然后扫描增加/减少。
找到值后,我使用find out what writes to this address
但是偏移量很高,并且指向空的内存。
我真的不知道该怎么办

为了清楚起见,我查看了其他几个值,它们有相同的问题

我已经看过许多教程和论坛,但这总是与偏移量在0到100之间而不是80614之间的值有关。

如果有人能告诉我为什么会这样,以及我必须做/学习要做什么,我将非常感激。

pointers - 查找带有 'find out what writes to this address'奇怪偏移量的指针-LMLPHP

pointers - 查找带有 'find out what writes to this address'奇怪偏移量的指针-LMLPHP

提前致谢

最佳答案

Urban Terror使用Quake Engine。该引擎的早期版本使用Quake虚拟机,并且游戏逻辑以字节码的形式实现,由Quake虚拟机编译为汇编代码。自定义分配例程用于将这些模块加载到内存中,在运行时创建相对和硬编码的偏移量/地址以适应这些重定位,并且不使用可移植可执行文件格式的常规重定位表方法。这就是为什么您看到这些看似奇怪的数字在每次运行游戏时都会改变的原因。

Quake虚拟机的文件格式为.qvm,并且在QVM表中跟踪内存中的这些qvm。您必须找到QVM表才能揭开这个谜底。一旦找到了2-3个QVM并记录了它们的地址,查找表就很容易了,因为您只需扫描指向这些地址的指针,然后通过查找内存中彼此接近的指针来缩小结果范围。

QVM的定义如下:

struct vmTable_t
{
    vm_t vm[3];
};

struct vm_s {
    // DO NOT MOVE OR CHANGE THESE WITHOUT CHANGING THE VM_OFFSET_* DEFINES
    // USED BY THE ASM CODE
    int         programStack;       // the vm may be recursively entered
    intptr_t(*systemCall)(intptr_t *parms);

    //------------------------------------

    char        name[MAX_QPATH];

    // for dynamic linked modules
    void        *dllHandle;
    intptr_t     entryPoint;           //(QDECL *entryPoint)(int callNum, ...);
    void(*destroy)(vm_s* self);

    // for interpreted modules
    qboolean    currentlyInterpreting;

    qboolean    compiled;
    byte        *codeBase;
    int         codeLength;

    int         *instructionPointers;
    int         instructionCount;

    byte        *dataBase;
    int         dataMask;

    int         stackBottom;        // if programStack < stackBottom, error

    int         numSymbols;
    struct vmSymbol_s   *symbols;

    int         callLevel;      // counts recursive VM_Call
    int         breakFunction;      // increment breakCount on function entry to this
    int         breakCount;

    BYTE        *jumpTableTargets;
    int         numJumpTableTargets;
};
typedef struct vm_s vm_t;

原始屏幕快照中EAX中的值应与QVM结构的codeBase或dataBase成员变量相同。偏移量仅相对于这些地址。与处理ASLR相似,必须在运行时计算地址。

这是我的代码的截短版本,它可以做到这一点,并另外从内存中获取重要的结构,例如:
void OA_t::GetVM()
{
    cg = nullptr;
    cgs = nullptr;
    cgents = nullptr;
    bLocalGame = false;
    cgame = nullptr;

    for (auto &vm : vmTable->vm)
    {
        if (strstr(vm.name, "qagame")) { bLocalGame = true; continue; }

        if (strstr(vm.name, "cgame"))
        {
            cgame = &vm;
            gamestatus = GSTAT_GAME;
            //char* gamestring = Cvar_VariableString("fs_game");

            switch (cgame->instructionCount)
            {
            case 136054: //version 88
                cgents = (cg_entities*)(cgame->dataBase + 0x1649c);
                cg = (cg_t*)(cgame->dataBase + 0xCC49C);
                cgs = (cgs_t*)(cgame->dataBase + 0xf2720);
                return;

完整的源代码供引用,可以在OpenArena Aimbot Source Code上获得,甚至包括该代码的视频概述。

完全披露:这是指向我的网站的链接,而我所知的唯一可行的资源涵盖了此主题。

09-25 16:30