至此,我完成了Cheat Engine教程的第8步,并获得了带有相应偏移量的静态地址来操纵一个值,该值应更改为在教程中进行的进度。我获得的表达式看起来像这样
[[[[[00645390]+C]+14]+0]+18]


我想更进一步,编写一个简单的程序(C ++或C#),该程序将访问存储在此的值点和两者都从内存中读取并写入。我还不确定如何特别访问此内容。我想这不像直接访问内存中的地址00645390那样容易-我是否必须将其添加到应用程序本身的基址?如果是,我如何获取地址以开始处理所有这些指针?

#1 楼

您需要OpenProcess()-> ReadprocessMemory()和或QueryVirtualEx()

您可以使用lkd或livekd获得结果

livekd.exe
kd> !process 0 0
................
PROCESS 89d1d328  SessionId: 0  Cid: 0238    Peb: 7ffde000  ParentCid: 075c
    DirBase: 14980320  ObjectTable: e14106f0  HandleCount:  23.
    Image: Tutorial-i386.exe
........................
kd> .process /p /r 89d1d328
Implicit process is now 89d1d328
Loading User Symbols
.................
kd> ? poi(poi(poi(poi(poi(645390)+c)+14)+0)+18)
Evaluate expression: 1666 = 00000682]




这是使用来自windbg sdk的dbgeng functions的示例代码,
为了简洁起见,错误检查了dbg打印错误
假设模块地址空间为not randomised / rebased(因此按原样使用645390
否则,您可能需要从Ce计算R中找到模块基础VA from address (645390 -modbase)
在代码中找到modbase并添加计算出的rva来读取指针if modbase,其中代码为400000rva1390,请改用401390645390

#include <stdio.h>
#include <engextcpp.hpp>
int __cdecl main( void  ){
    IDebugClient*     g_Client      = NULL;
    IDebugControl*    g_Control     = NULL;
    IDebugSymbols*    g_Symbols     = NULL;
    IDebugDataSpaces* g_Data        = NULL;
    ULONG             Pid           = NULL;
    ULONG             bytesread     = NULL;
    ULONG             ptr           = NULL;
    DebugCreate( __uuidof(IDebugClient), (void**)&g_Client );
    g_Client->QueryInterface( __uuidof(IDebugControl), (void**)&g_Control );
    g_Client->QueryInterface( __uuidof(IDebugSymbols), (void**)&g_Symbols );
    g_Client->QueryInterface( __uuidof(IDebugDataSpaces), (void**)&g_Data );
    g_Client->GetRunningProcessSystemIdByExecutableName(
        0,"Tutorial-i386.exe",DEBUG_GET_PROC_ONLY_MATCH,&Pid);
    g_Client->AttachProcess(0,Pid,DEBUG_ATTACH_NONINVASIVE);
    g_Control->WaitForEvent( 0, INFINITE );
    g_Data->ReadVirtualUncached(0x645390,&ptr,sizeof(ptr),&bytesread);
    g_Data->ReadVirtualUncached((ptr+0xc),&ptr,sizeof(ptr),&bytesread);
    g_Data->ReadVirtualUncached((ptr+0x14),&ptr,sizeof(ptr),&bytesread);
    g_Data->ReadVirtualUncached((ptr+0x0),&ptr,sizeof(ptr),&bytesread);
    g_Data->ReadVirtualUncached((ptr+0x18),&ptr,sizeof(ptr),&bytesread);
    printf("%-15s%d\n","5th lvl ptr =", ptr);
    g_Client->DetachProcesses();
    return 0;
}