fix getmodules for windows process

This commit is contained in:
skuater 2015-04-14 10:07:35 +02:00 committed by pancake
parent 997dda6e5b
commit a853b35c8f
2 changed files with 99 additions and 23 deletions

View File

@ -908,12 +908,15 @@ static int r_debug_native_reg_read(RDebug *dbg, int type, ut8 *buf, int size) {
}
#if __WINDOWS__ && !__CYGWIN__
int tid = dbg->tid;
HANDLE hProcess=tid2handler (pid, tid);
CONTEXT ctx __attribute__ ((aligned (16)));
ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
if (!GetThreadContext (tid2handler (pid, tid), &ctx)) {
if (!GetThreadContext (hProcess, &ctx)) {
eprintf ("GetThreadContext: %x\n", (int)GetLastError ());
CloseHandle(hProcess);
return R_FALSE;
}
CloseHandle(hProcess);
if (type==R_REG_TYPE_FPU || type==R_REG_TYPE_MMX || type==R_REG_TYPE_XMM) {
#if __MINGW64__
eprintf ("TODO: r_debug_native_reg_read fpu/mmx/xmm\n");
@ -1414,10 +1417,15 @@ static int r_debug_native_reg_write(RDebug *dbg, int type, const ut8* buf, int s
#if __WINDOWS__
int tid = dbg->tid;
int pid = dbg->pid;
BOOL ret;
HANDLE hProcess;
CONTEXT ctx __attribute__((aligned (16)));
memcpy (&ctx, buf, sizeof (CONTEXT));
ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
return SetThreadContext (tid2handler (pid, tid), &ctx)? R_TRUE: R_FALSE;
hProcess=tid2handler (pid, tid);
ret=SetThreadContext (hProcess, &ctx)? R_TRUE: R_FALSE;
CloseHandle(hProcess);
return ret;
#endif
return R_FALSE;
#endif
@ -1429,11 +1437,16 @@ static int r_debug_native_reg_write(RDebug *dbg, int type, const ut8* buf, int s
int pid = dbg->pid;
#if __WINDOWS__ && !__CYGWIN__
int tid = dbg->tid;
BOOL ret;
HANDLE hProcess;
CONTEXT ctx __attribute__((aligned (16)));
memcpy (&ctx, buf, sizeof (CONTEXT));
ctx.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
// eprintf ("EFLAGS =%x\n", ctx.EFlags);
return SetThreadContext (tid2handler (pid, tid), &ctx)? R_TRUE: R_FALSE;
hProcess=tid2handler (pid, tid);
ret=SetThreadContext (hProcess, &ctx)? R_TRUE: R_FALSE;
CloseHandle(hProcess);
return ret;
#elif __linux__
int ret = ptrace (PTRACE_SETREGS, pid, 0, (void*)buf);
if (sizeof (R_DEBUG_REG_T) < size)
@ -1773,7 +1786,7 @@ static RList *r_debug_native_map_get(RDebug *dbg) {
#if __APPLE__
list = darwin_dbg_maps (dbg);
#elif __WINDOWS__ && !__CYGWIN__
list = w32_dbg_maps (); // TODO: moar?
list = w32_dbg_maps (dbg); // TODO: moar?
#else
#if __sun
char path[1024];

View File

@ -98,6 +98,8 @@ static HANDLE WINAPI (*w32_openthread)(DWORD, BOOL, DWORD) = NULL;
static HANDLE WINAPI (*w32_dbgbreak)(HANDLE) = NULL;
static DWORD WINAPI (*w32_getthreadid)(HANDLE) = NULL; // Vista
static DWORD WINAPI (*w32_getprocessid)(HANDLE) = NULL; // XP
static HANDLE WINAPI (*w32_openprocess)(DWORD, BOOL, DWORD) = NULL;
static void r_str_wtoc(char* d, const WCHAR* s) {
int i = 0;
@ -180,6 +182,8 @@ static int w32_dbg_init() {
"DebugActiveProcessStop");
w32_openthread = (HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
GetProcAddress (GetModuleHandle ("kernel32"), "OpenThread");
w32_openprocess=(HANDLE WINAPI (*)(DWORD, BOOL, DWORD))
GetProcAddress (GetModuleHandle ("kernel32"), "OpenProcess");
w32_dbgbreak = (HANDLE WINAPI (*)(HANDLE))
GetProcAddress (GetModuleHandle ("kernel32"),
"DebugBreakProcess");
@ -199,7 +203,6 @@ static int w32_dbg_init() {
GetProcAddress (lib, "GetModuleBaseNameA");
gmi = (int (*)(HANDLE, HMODULE, LPMODULEINFO, int))
GetProcAddress (lib, "GetModuleInformation");
if (w32_detach == NULL || w32_openthread == NULL || w32_dbgbreak == NULL ||
gmbn == NULL || gmi == NULL) {
// OOPS!
@ -285,10 +288,10 @@ eprintf ("w32thread: Oops\n");
static int debug_exception_event (unsigned long code) {
switch (code) {
case EXCEPTION_BREAKPOINT:
eprintf ("breakpoint\n");
//eprintf ("breakpoint\n");
break;
case EXCEPTION_SINGLE_STEP:
eprintf ("singlestep\n");
//eprintf ("singlestep\n");
break;
/* fatal exceptions */
case EXCEPTION_ACCESS_VIOLATION:
@ -417,24 +420,82 @@ static inline int CheckValidPE(unsigned char * PeHeader) {
return 0;
}
static RList *w32_dbg_maps() {
SYSTEM_INFO SysInfo;
MEMORY_BASIC_INFORMATION mbi;
HANDLE hProcess = 0; // XXX NEEDS TO HAVE A VALUE
LPBYTE page;
char *mapname = NULL;
/* DEPRECATED */
ut8 PeHeader[1024];
MODULEINFO ModInfo;
static RList *w32_dbg_maps(RDebug *dbg) {
HANDLE hProcess = 0;
HANDLE hModuleSnap = 0;
IMAGE_DOS_HEADER *dos_header;
IMAGE_NT_HEADERS *nt_headers;
IMAGE_SECTION_HEADER *SectionHeader;
int NumSections, i;
SIZE_T ret_len;
MODULEENTRY32 me32;
RDebugMap *mr;
ut8 PeHeader[1024];
DWORD cbNeeded=0;
char *mapname = NULL;
int NumSections, i;
int tid = dbg->tid;
int pid = dbg->pid;
RList *list = r_list_new ();
#if !__MINGW64__ // TODO: Fix this , for win64 cant walk over all process memory, use psapi.dll to get modules
memset (&SysInfo, 0, sizeof (SysInfo));
hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pid );
if( hModuleSnap == NULL ) {
//print_lasterr ((char *)__FUNCTION__);
CloseHandle( hModuleSnap );
return NULL;
}
me32.dwSize = sizeof( MODULEENTRY32 );
if( !Module32First(hModuleSnap, &me32)) {
//print_lasterr ((char *)__FUNCTION__);
CloseHandle( hModuleSnap );
return NULL;
}
hProcess=w32_openprocess(PROCESS_QUERY_INFORMATION |PROCESS_VM_READ,FALSE, pid );
do {
ReadProcessMemory (WIN32_PI (hProcess), (const void *)me32.modBaseAddr,(LPVOID)PeHeader, sizeof (PeHeader), &ret_len);
if (ret_len == sizeof (PeHeader) && CheckValidPE (PeHeader)) {
dos_header = (IMAGE_DOS_HEADER *)PeHeader;
if (dos_header != NULL) {
nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header + dos_header->e_lfanew);
if (nt_headers != NULL) {
NumSections = nt_headers->FileHeader.NumberOfSections;
SectionHeader = (IMAGE_SECTION_HEADER *) ((char *)nt_headers + sizeof(IMAGE_NT_HEADERS));
mr = r_debug_map_new (me32.szModule,
(ut64)(size_t) (me32.modBaseAddr),
(ut64)(size_t) (me32.modBaseAddr +SectionHeader->VirtualAddress),
SectionHeader->Characteristics,
0);
if (mr != NULL)
r_list_append (list, mr);
if(NumSections > 0) {
mapname = (char *)malloc(MAX_PATH);
for (i=0; i<NumSections; i++) {
if (SectionHeader->Misc.VirtualSize>0) {
sprintf(mapname,"%s | %s",me32.szModule,SectionHeader->Name);
mr = r_debug_map_new (mapname,
(ut64)(size_t) (SectionHeader->VirtualAddress + me32.modBaseAddr),
(ut64)(size_t) (SectionHeader->VirtualAddress + me32.modBaseAddr + SectionHeader->Misc.VirtualSize),
SectionHeader->Characteristics, // XXX?
0);
if (mr != NULL)
r_list_append (list, mr);
}
SectionHeader++;
}
free (mapname);
}
}
}
}
} while(Module32Next(hModuleSnap, &me32));
CloseHandle( hModuleSnap );
CloseHandle( hProcess );
return( list );
/*
SYSTEM_INFO SysInfo;
LPBYTE page;
MODULEINFO ModInfo;
MEMORY_BASIC_INFORMATION mbi;
memset (&SysInfo, 0, sizeof (SysInfo));
GetSystemInfo (&SysInfo); // TODO: check return value
if (gmi == NULL) {
eprintf ("w32dbg: no gmi\n");
@ -445,6 +506,7 @@ static RList *w32_dbg_maps() {
return 0;
}
#if !__MINGW64__ // TODO: Fix this , for win64 cant walk over all process memory, use psapi.dll to get modules
for (page=(LPBYTE)SysInfo.lpMinimumApplicationAddress;
page<(LPBYTE)SysInfo.lpMaximumApplicationAddress;) {
if (!VirtualQueryEx (WIN32_PI (hProcess), page, &mbi, sizeof (mbi))) {
@ -454,6 +516,7 @@ static RList *w32_dbg_maps() {
//return NULL;
}
if (mbi.Type == MEM_IMAGE) {
eprintf ("MEM_IMAGE address = 0x%08X\n", page);
ReadProcessMemory (WIN32_PI (hProcess), (const void *)page,
(LPVOID)PeHeader, sizeof (PeHeader), &ret_len);
@ -464,7 +527,7 @@ static RList *w32_dbg_maps() {
nt_headers = (IMAGE_NT_HEADERS *)((char *)dos_header
+ dos_header->e_lfanew);
if (nt_headers == NULL) {
/* skip before failing */
// skip before failing
break;
}
NumSections = nt_headers->FileHeader.NumberOfSections;
@ -500,12 +563,12 @@ static RList *w32_dbg_maps() {
if (gmi (WIN32_PI (hProcess), (HMODULE) page,
(LPMODULEINFO) &ModInfo, sizeof(MODULEINFO)) == 0)
return NULL;
/* THIS CODE SEGFAULTS WITH NO REASON. BYPASS IT! */
// THIS CODE SEGFAULTS WITH NO REASON. BYPASS IT!
#if 0
eprintf("--> 0x%08x\n", ModInfo.lpBaseOfDll);
eprintf("sz> 0x%08x\n", ModInfo.SizeOfImage);
eprintf("rs> 0x%08x\n", mbi.RegionSize);
/* avoid infinite loops */
// avoid infinite loops
// if (ModInfo.SizeOfImage == 0)
// return 0;
// page += ModInfo.SizeOfImage;
@ -519,13 +582,13 @@ static RList *w32_dbg_maps() {
// XXX leak
return NULL;
}
r_list_append (list, mr);
page += mbi.RegionSize;
}
}
#endif
return list;
*/
}
static HANDLE tid2handler(int pid, int tid) {