Quote:
|
Are you aware of a way to do that without any api ?
|
Without API and from RING 3?
Here you are!
Platform Windows XP.
Code:
// get_parent.c - coded by bilbo, 23jul04 - build with "cl -W3 get_parent.c"
// platform: Windows XP
#include <windows.h>
#include <stdio.h>
#pragma comment(lib, "advapi32")
#define DebugReadMemory 8
#define FCHK(a) if (!(a)) { printf(#a " failed\n"); exit(0); }
typedef DWORD (NTAPI *PZwSystemDebugControl)(DWORD ControlCode,
PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer,
ULONG OutputBufferLength, PULONG ReturnLength);
PZwSystemDebugControl ZwSystemDebugControl;
DWORD pSystemProc;
struct mem {
PVOID kernel_addr;
PVOID user_addr;
DWORD len;
};
void
EnablePrivilege(LPCSTR lpszName)
{
HANDLE hToken;
TOKEN_PRIVILEGES tok;
FCHK(OpenProcessToken(GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken));
tok.PrivilegeCount = 1;
tok.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
FCHK(LookupPrivilegeValue(NULL, lpszName, &tok.Privileges[0].Luid));
FCHK(AdjustTokenPrivileges(hToken, FALSE, &tok, sizeof(tok), NULL, NULL));
}
/*
* read one long from kernel space
*/
DWORD
rd(DWORD addr)
{
struct mem mem;
DWORD m;
mem.kernel_addr = (PVOID)addr;
mem.user_addr = &m;
mem.len = 4;
FCHK(!ZwSystemDebugControl(DebugReadMemory, &mem, sizeof(mem), 0, 0, 0));
return m;
}
void
rdstr(DWORD addr, LPSTR buf, int buflen)
{
int i;
struct mem mem;
mem.kernel_addr = (PVOID)addr;
mem.user_addr = buf;
mem.len = 1;
for (i=0; i<buflen; i++) {
FCHK(!ZwSystemDebugControl(DebugReadMemory, &mem, sizeof(mem), 0,0,0));
if (!*buf++) break;
addr++;
// reassign structure mem
mem.kernel_addr = (PVOID)addr;
mem.user_addr = buf;
}
}
void
prepare_me(void)
{
HMODULE hModule;
// get the API address
FCHK(hModule = GetModuleHandle("ntdll.dll"));
FCHK((ZwSystemDebugControl = (PZwSystemDebugControl)
GetProcAddress(hModule, "ZwSystemDebugControl")));
EnablePrivilege(SE_DEBUG_NAME);
}
void
main(void)
{
DWORD eprocess, mypid, parentpid, tmppid;
char myname[17]={0}, parentname[17]={0};
prepare_me();
// get current EPROCESS from kernel space
eprocess = rd(0xFFDFF000+0x124); // KPRCB.KTHREAD
eprocess = rd(eprocess+0x44); // KTHREAD.KAPC_STATE.KPROCESS
// get pids from kernel space
mypid = rd(eprocess+0x84); // EPROCESS.UniqueProcessId
parentpid = rd(eprocess+0x14C); // EPROCESS.InheritedFromUniqueProcessId
// get my name from current EPROCESS
rdstr(eprocess+0x174, myname, 16); // EPROCESS.ImageFileName
// scan back process list to find parent EPROCESS
//printf("%x %d\n", eprocess, mypid);
eprocess = rd(eprocess+0x8C); // ActiveProcessLinks
while (1) {
tmppid = rd(eprocess+(0x84-0x88)); // UniqueProcessId
//printf("%x %d\n", eprocess, tmppid);
if (tmppid == parentpid) break;
eprocess = rd(eprocess+(0x8c-0x88)); // Blink
}
// get parent name from parent EPROCESS
rdstr(eprocess+(0x174-0x88), parentname, 16); // EPROCESS.ImageFileName
printf("mypid: %d(%.16s), parentpid: %d(%.16s)\n",
mypid, myname, parentpid, parentname);
}
Have fun! bilbo