2

私は現在、Assault Cube というゲームをメモリー編集しています。残念ながら、動的メモリ割り当てのため、編集したい値へのアドレスはゲームが開始するたびに変わります。幸いなことに、常に動的アドレスを指す静的ポインターがあります。チート エンジンを使用すると、ポインターを見つけることができますが、8 レベルまで上がることもあります。********pointer毎回行うのではなく、次のようにします*pointer。その上、オフセットがあるため、ハードコードするのは悪夢です。

代わりに、次の関数を使用しています。

int* getLowestPointer(int** highestPointer, int levels, int offsets[])
{
    for (int i = 0; i < levels; i++) {
        highestPointer = (int**) (*highestPointer + offsets[i]/sizeof(int)); // I am dividing by sizeof(int) here to undo pointer arithmetic (since the offsets are the difference between the offsetted pointer and the base pointer - not in integer increments)
    }
    return (int*) highestPointer;
}

しかし、それは非常に面倒です。私は int* を int** に、またはその逆にキャストしていますが、これは悪い習慣と考えられています。悪い習慣にならないようにできることはありますか?これもウェブで見つけました:

DWORD FindDmaAddy(int PointerLevel, DWORD Offsets[], DWORD BaseAddress)
{
    DWORD Ptr = *(DWORD*)(BaseAddress);
    if(Ptr == 0) return NULL;

    for(int i = 0; i < PointerLevel; i ++)
    {
        if(i == PointerLevel-1)
        {
            Ptr = (DWORD)(Ptr+Offsets[i]);
            if(Ptr == 0) return NULL;
            return Ptr;
        }
        else
        {
            Ptr = *(DWORD*)(Ptr+Offsets[i]);
            if(Ptr == 0) return NULL;
        }
    }
    return Ptr;
}

私が書いたものよりもさらに醜いと思います。片頭痛が必要でない限り、読むことはお勧めしません。

4

2 に答える 2

2

「最もクリーンな方法」についてはわかりませんが、これらのポインターを逆参照する以外にできることはありません。typedefsコードを読みやすくするためだけに使用することをお勧めします。

int *へのキャストについても心配する必要はありませんint **。確かに「悪い習慣」と見なされますが、自分が何をしているのかを知っていれば、まさに必要なことかもしれません。ただ注意が必要です。

typedef int *** intPtr3;
typedef int ****** intPtr6;

いくつかのマクロを使用して、構文をクリーンアップすることもできます。これは、マクロを賢く使用して可読性と簡潔さを向上させ、エラーの可能性を減らす良い例です。

#define DEREF6( PTR ) \
  ******(PTR)

最後に、ポインタをメモリ内のバイト数だけ移動するためによく使用する素敵なマクロがあります。

#define PTR_ADD( PTR, OFFSET ) \
   (((char *)(PTR)) + (OFFSET))
于 2013-04-27T22:13:38.157 に答える