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]](https://i.stack.imgur.com/b825y.png)
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;
}
