Mercurial > projects > ddbg_continued
diff 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 diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/dbgprocess.d Tue Apr 05 20:44:01 2011 +0200 @@ -0,0 +1,221 @@ +/* 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; +}