3

So I have finished step 8 of the Cheat Engine tutorial and obtained a static address with corresponding offsets to manipulate a value which should be changed to progress in the tutorial. The expression I obtained looks like this

[[[[[00645390]+C]+14]+0]+18]

I want to go a step further and write a simple (either C++ or C#) program which will access the value stored at this spot and both read from the memory and write to it. What I am not sure about yet is how to access this particularly. I guess it isn't as easy as directly accessing the address 00645390 in memory - do I have to add it to the base address of the application itself? If yes, how may I acquire the address to start working through all those pointers?

2

you need OpenProcess()->ReadprocessMemory() and or QueryVirtualEx()

you can use lkd or livekd to achieve the result

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]

[1]

here is a sample code that employs dbgeng functions from windbg sdk
error checks dbg prints removed for brevity
assumes the module address space is not randomised / rebased (so uses 645390 as it is )
else you may need to find the module base from Ce calculate RVA from address (645390 -modbase)
in your code find the modbase and add the calculated rva to read the pointer
if modbase in your code was 400000 and rva was 1390 use 401390 instead of 645390

#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;
}

enter image description here

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.