Mercurial > projects > ddbg_continued
view src/dbgprocess.d @ 1:4a9dcbd9e54f
-files of 0.13 beta
-fixes so that it now compiles with the current dmd version
author | marton@basel.hu |
---|---|
date | Tue, 05 Apr 2011 20:44:01 +0200 |
parents | |
children |
line wrap: on
line source
/* Ddbg - Win32 Debugger for the D programming language * Copyright (c) 2007 Jascha Wetzel * All rights reserved. See LICENSE.TXT for details. */ module dbgprocess; import win32.winbase; import win32.windef; import std.string; import std.c.string; import util; import breakpoint; import dbgthread; import callstack; import codeview.coff; /************************************************************************************************** **************************************************************************************************/ class DbgProcess { public: HANDLE process_handle; uint processId, mainThreadId; DLL[] loaded_dlls; DbgThread[uint] threads; /********************************************************************************************** **********************************************************************************************/ DLL loadDLL(LOAD_DLL_DEBUG_INFO* lddi) { DLL dll = new DLL; dll.filehandle = lddi.hFile; dll.base = cast(uint)lddi.lpBaseOfDll; dll.debug_info_offset = lddi.dwDebugInfoFileOffset; dll.debug_info_size = lddi.nDebugInfoSize; loaded_dlls ~= dll; size_t filesize = GetFileSize(lddi.hFile, null); if ( filesize == 0 ) { debug DbgIO.println("Couldn't get DLL %s image size: %s", dll.image.name, lastError); return dll; } ubyte[] buf; buf.length = filesize; if ( !ReadFile(lddi.hFile, cast(void*)buf.ptr, buf.length, &filesize, null) || filesize != buf.length ) { debug DbgIO.println("Couldn't read DLL image for %s: %s", dll.image.name, lastError); return dll; } dll.image = new COFFImage; dll.image.load(buf); return dll; } /********************************************************************************************** **********************************************************************************************/ DLL findDLL(size_t vaddress) { foreach ( dll; loaded_dlls ) { if ( vaddress < dll.base ) continue; assert( dll !is null ); assert( dll.image !is null ); uint size_image = dll.image.imageSize; if ( vaddress-dll.base > size_image ) continue; return dll; } return null; } /********************************************************************************************** Loads the given thread's stack and the index of the current frame pointer (ebp). Returns: Arrays of uints. **********************************************************************************************/ CallStack loadStack(DbgThread thread) { CONTEXT ctx; if ( !thread.getContext(ctx, CONTEXT_CONTROL) ) throw new Exception("Couldn't get thread's context"); CallStack stack = new CallStack(thread.stack_base, ctx.Esp, ctx.Ebp); uint read = readProcessMemory(ctx.Esp, stack.data.ptr, stack.data.length); if ( read == 0 ) throw new Exception("Couldn't read thread's stack memory"); else if ( read < stack.data.length ) stack.data.length = read; return stack; } /********************************************************************************************** Read from debuggee's memory. Returns: #bytes read **********************************************************************************************/ size_t readProcessMemory(size_t address, void* data, size_t size, bool changeProtect=false) { uint oldprot; if( changeProtect && !VirtualProtectEx(process_handle, cast(void*)address, size, PAGE_READONLY, &oldprot) ) { debug DbgIO.println("readProcessMemory(): Failed to obtain read access to page at 0x%08x: %s", address, lastError); return false; } size_t numbytes; if( !ReadProcessMemory(process_handle, cast(void*)address, data, size, &numbytes) ) { debug DbgIO.println("ReadProcessMemory() returned false reading address 0x%08x: %s", address, lastError); return 0; } if ( numbytes != size ) { debug DbgIO.println("readProcessMemory(): Failed to read at address 0x%08x: %s", address, lastError); } if( changeProtect && !VirtualProtectEx(process_handle, cast(void*)address, size, oldprot, &oldprot) ) { DbgIO.println("writeProcessMemory(): Failed to restore access to page at 0x%08x: %s", address, lastError); return 0; } return numbytes; } /********************************************************************************************** Write to debuggee's memory. Returns success. **********************************************************************************************/ size_t writeProcessMemory(size_t address, void* data, size_t size) { uint oldprot; if( !VirtualProtectEx(process_handle, cast(void*)address, size, PAGE_EXECUTE_READWRITE, &oldprot) ) { DbgIO.println("writeProcessMemory(): Failed to obtain write access to page at 0x%08x: %s", address, lastError); return false; } size_t numbytes; if( !WriteProcessMemory(process_handle, cast(void*)address, data, size, &numbytes) ) DbgIO.println("writeProcessMemory(): Failed to write byte at 0x%08x: %s", address, lastError); if( !VirtualProtectEx(process_handle, cast(void*)address, size, oldprot, &oldprot) ) { DbgIO.println("writeProcessMemory(): Failed to restore access to page at 0x%08x: %s", address, lastError); return false; } if ( !FlushInstructionCache(process_handle, cast(void*)address, numbytes) ) { DbgIO.println("writeProcessMemory(): FlushInstructionCache failed for 0x%08x: %s", address, lastError()); return false; } return numbytes; } /********************************************************************************************** **********************************************************************************************/ ClassInfo getClassInfo(size_t obj_ptr) { uint vtbl, ci_ptr; readProcessMemory(obj_ptr, &vtbl, size_t.sizeof); readProcessMemory(vtbl, &ci_ptr, size_t.sizeof); ubyte[] data; data.length = ClassInfo.classinfo.init.length; readProcessMemory(ci_ptr, data.ptr, data.length); return cast(ClassInfo)data.ptr; } /********************************************************************************************** simple check for invalidity of a memory block **********************************************************************************************/ const size_t MEMCHECK_MIN = 0x1000; bool isInvalidMem(size_t ptr, size_t len) { uint tmp; if ( uint.sizeof != readProcessMemory(ptr, &tmp, uint.sizeof) || uint.sizeof != readProcessMemory(ptr+len-uint.sizeof, &tmp, uint.sizeof) ) return true; return false; } /********************************************************************************************** **********************************************************************************************/ MEMORY_BASIC_INFORMATION[] walkMemory() { SYSTEM_INFO si; MEMORY_BASIC_INFORMATION[] mbis; GetSystemInfo(&si); for ( void* ptr = si.lpMinimumApplicationAddress; ptr < si.lpMaximumApplicationAddress; ) { mbis.length = mbis.length + 1; VirtualQueryEx(process_handle, ptr, &mbis[$-1], MEMORY_BASIC_INFORMATION.sizeof); ptr = mbis[$-1].BaseAddress + mbis[$-1].RegionSize; } return mbis; } } /************************************************************************************************** **************************************************************************************************/ class DLL { public: HANDLE filehandle; uint base, debug_info_offset, debug_info_size; COFFImage image; }