Artifact Content
Not logged in

Artifact 8a71f59402b61712fa10c9387c5e0377d12a5024


     1  /*************************************************************
     2  Copyright (c) 2010
     3  
     4  Benjamin Thaut. All rights reserved.
     5  
     6  Redistribution and use in source and binary forms, with or without modification, are permitted
     7  provided that the following conditions are met:
     8  
     9    1. Redistributions of source code must retain the above copyright notice, this list of conditions
    10       and the following disclaimer.
    11  
    12    2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions
    13       and the following disclaimer in the documentation and/or other materials provided with the distribution.
    14  
    15  THIS SOFTWARE IS PROVIDED BY BENJAMIN THAUT "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
    16  BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
    17  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
    18  OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
    19  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
    20  STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
    21  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    22  
    23  web: http://3d.benjamin-thaut.de
    24  *************************************************************/
    25  module dbghelp;
    26  
    27  version (Windows){
    28  
    29  import std.c.windows.windows;
    30  import core.runtime;
    31  	
    32  class Dbghelp {
    33  public:
    34  	typedef char TCHAR;
    35  	typedef ulong DWORD64;
    36  	typedef char* CTSTR;
    37  	typedef char* PTSTR;
    38  	typedef const(char)* PCSTR;
    39  	
    40  	enum ADDRESS_MODE : DWORD {
    41  		AddrMode1616 = 0,
    42  		AddrMode1632 = 1,
    43  		AddrModeReal = 2,
    44  		AddrModeFlat = 3
    45  	};
    46  	
    47  	enum : DWORD {
    48  		SYMOPT_FAIL_CRITICAL_ERRORS = 0x00000200,
    49  		SYMOPT_LOAD_LINES = 0x00000010
    50  	};
    51  	
    52  	struct GUID {
    53  		uint Data1;
    54  		ushort Data2;
    55  		ushort Data3;
    56  		ubyte[8] Data4;
    57  	};
    58  	
    59  	struct ADDRESS64 {
    60  		DWORD64 Offset;
    61  		WORD Segment;
    62  		ADDRESS_MODE Mode;
    63  	};
    64  	
    65  	struct KDHELP64 {
    66  		DWORD64 Thread;
    67  		DWORD ThCallbackStack;
    68  		DWORD ThCallbackBStore;
    69  		DWORD NextCallback;
    70  		DWORD FramePointer;
    71  		DWORD64 KiCallUserMode;
    72  		DWORD64 KeUserCallbackDispatcher;
    73  		DWORD64 SystemRangeStart;
    74  		DWORD64 KiUserExceptionDispatcher;
    75  		DWORD64[7] Reserved;
    76  	};
    77  	
    78  	struct STACKFRAME64 {
    79  		ADDRESS64 AddrPC;
    80  		ADDRESS64 AddrReturn;
    81  		ADDRESS64 AddrFrame;
    82  		ADDRESS64 AddrStack;
    83  		ADDRESS64 AddrBStore;
    84  		PVOID FuncTableEntry;
    85  		DWORD64[4] Params;
    86  		BOOL Far;
    87  		BOOL Virtual;
    88  		DWORD64[3] Reserved;
    89  		KDHELP64 KdHelp;
    90  	};
    91  	
    92  	enum : DWORD {
    93  		IMAGE_FILE_MACHINE_I386 = 0x014c,
    94  		IMGAE_FILE_MACHINE_IA64 = 0x0200,
    95  		IMAGE_FILE_MACHINE_AMD64 = 0x8664
    96  	};
    97  	
    98  	struct IMAGEHLP_LINE64 {
    99  		DWORD SizeOfStruct;
   100  		PVOID Key;
   101  		DWORD LineNumber;
   102  		PTSTR FileName;
   103  		DWORD64 Address;
   104  	};
   105  	
   106  	enum SYM_TYPE : int {
   107  	    SymNone = 0,
   108  	    SymCoff,
   109  	    SymCv,
   110  	    SymPdb,
   111  	    SymExport,
   112  	    SymDeferred,
   113  	    SymSym,
   114  	    SymDia,
   115  	    SymVirtual,
   116  	    NumSymTypes
   117  	};
   118  	
   119  	struct IMAGEHLP_MODULE64 {
   120  		DWORD SizeOfStruct;
   121  		DWORD64 BaseOfImage;
   122  		DWORD ImageSize;
   123  		DWORD TimeDateStamp;
   124  		DWORD CheckSum;
   125  		DWORD NumSyms;
   126  		SYM_TYPE SymType;
   127  		TCHAR[32] ModuleName;
   128  		TCHAR[256] ImageName;
   129  		TCHAR[256] LoadedImageName;
   130  		TCHAR[256] LoadedPdbName;
   131  		DWORD CVSig;
   132  		TCHAR[MAX_PATH*3] CVData;
   133  		DWORD PdbSig;
   134  		GUID PdbSig70;
   135  		DWORD PdbAge;
   136  		BOOL PdbUnmatched;
   137  		BOOL DbgUnmachted;
   138  		BOOL LineNumbers;
   139  		BOOL GlobalSymbols;
   140  		BOOL TypeInfo;
   141  		BOOL SourceIndexed;
   142  		BOOL Publics;
   143  	};
   144  	
   145  	struct IMAGEHLP_SYMBOL64 {
   146  		DWORD SizeOfStruct;
   147  		DWORD64 Address;
   148  		DWORD Size;
   149  		DWORD Flags;
   150  		DWORD MaxNameLength;
   151  		TCHAR[1] Name;
   152  	};
   153  	
   154  	extern(System){
   155  		typedef BOOL function(HANDLE hProcess, DWORD64 lpBaseAddress, PVOID lpBuffer, DWORD nSize, LPDWORD lpNumberOfBytesRead) ReadProcessMemoryProc64;
   156  		typedef PVOID function(HANDLE hProcess, DWORD64 AddrBase) FunctionTableAccessProc64;
   157  		typedef DWORD64 function(HANDLE hProcess, DWORD64 Address) GetModuleBaseProc64;
   158  		typedef DWORD64 function(HANDLE hProcess, HANDLE hThread, ADDRESS64 *lpaddr) TranslateAddressProc64;
   159  		
   160  		typedef BOOL function(HANDLE hProcess, PCSTR UserSearchPath, bool fInvadeProcess) SymInitializeFunc;
   161  		typedef BOOL function(HANDLE hProcess) SymCleanupFunc;
   162  		typedef DWORD function(DWORD SymOptions) SymSetOptionsFunc;
   163  		typedef DWORD function() SymGetOptionsFunc;
   164  		typedef PVOID function(HANDLE hProcess, DWORD64 AddrBase) SymFunctionTableAccess64Func;
   165  		typedef BOOL function(DWORD MachineType, HANDLE hProcess, HANDLE hThread, STACKFRAME64 *StackFrame, PVOID ContextRecord, 
   166  		                      ReadProcessMemoryProc64 ReadMemoryRoutine, FunctionTableAccessProc64 FunctoinTableAccess,
   167  		                      GetModuleBaseProc64 GetModuleBaseRoutine, TranslateAddressProc64 TranslateAddress) StackWalk64Func;
   168  		typedef BOOL function(HANDLE hProcess, DWORD64 dwAddr, PDWORD pdwDisplacement, IMAGEHLP_LINE64 *line) SymGetLineFromAddr64Func;
   169  		typedef DWORD64 function(HANDLE hProcess, DWORD64 dwAddr) SymGetModuleBase64Func;
   170  		typedef BOOL function(HANDLE hProcess, DWORD64 dwAddr, IMAGEHLP_MODULE64 *ModuleInfo) SymGetModuleInfo64Func;
   171  		typedef BOOL function(HANDLE hProcess, DWORD64 Address, DWORD64 *Displacement, IMAGEHLP_SYMBOL64 *Symbol) SymGetSymFromAddr64Func;
   172  		typedef DWORD function(CTSTR *DecoratedName, PTSTR UnDecoratedName, DWORD UndecoratedLength, DWORD Flags) UnDecorateSymbolNameFunc;
   173  		typedef DWORD64 function(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll) SymLoadModule64Func;
   174  		typedef BOOL function(HANDLE HProcess, PTSTR SearchPath, DWORD SearchPathLength) SymGetSearchPathFunc;
   175  		typedef BOOL function(HANDLE hProcess, DWORD64 Address) SymUnloadModule64Func;
   176  	}
   177  	
   178  	private static bool isInit = false;
   179  	private static HANDLE dbghelp_lib = cast(HANDLE)null;
   180  	static SymInitializeFunc SymInitialize;
   181  	static SymCleanupFunc SymCleanup;
   182  	static StackWalk64Func StackWalk64;
   183  	static SymGetOptionsFunc SymGetOptions;
   184  	static SymSetOptionsFunc SymSetOptions;
   185  	static SymFunctionTableAccess64Func SymFunctionTableAccess64;
   186  	static SymGetLineFromAddr64Func SymGetLineFromAddr64;
   187  	static SymGetModuleBase64Func SymGetModuleBase64;
   188  	static SymGetModuleInfo64Func SymGetModuleInfo64;
   189  	static SymGetSymFromAddr64Func SymGetSymFromAddr64;
   190  	static UnDecorateSymbolNameFunc UnDecorateSymbolName;
   191  	static SymLoadModule64Func SymLoadModule64;
   192  	static SymGetSearchPathFunc SymGetSearchPath;
   193  	static SymUnloadModule64Func SymUnloadModule64;
   194  	
   195  	static bool Init(){
   196  		if(isInit)
   197  			return true;
   198  		
   199  		dbghelp_lib = cast(HANDLE)Runtime.loadLibrary("dbghelp.dll");
   200  		if(dbghelp_lib == null)
   201  			return false;
   202  		
   203  		SymInitialize = cast(SymInitializeFunc) GetProcAddress(dbghelp_lib,"SymInitialize");
   204  		SymCleanup = cast(SymCleanupFunc) GetProcAddress(dbghelp_lib,"SymCleanup");
   205  		StackWalk64 = cast(StackWalk64Func) GetProcAddress(dbghelp_lib,"StackWalk64");
   206  		SymGetOptions = cast(SymGetOptionsFunc) GetProcAddress(dbghelp_lib,"SymGetOptions");
   207  		SymSetOptions = cast(SymSetOptionsFunc) GetProcAddress(dbghelp_lib,"SymSetOptions");
   208  		SymFunctionTableAccess64 = cast(SymFunctionTableAccess64Func) GetProcAddress(dbghelp_lib,"SymFunctionTableAccess64");
   209  		SymGetLineFromAddr64 = cast(SymGetLineFromAddr64Func) GetProcAddress(dbghelp_lib,"SymGetLineFromAddr64");
   210  		SymGetModuleBase64 = cast(SymGetModuleBase64Func) GetProcAddress(dbghelp_lib,"SymGetModuleBase64");
   211  		SymGetModuleInfo64 = cast(SymGetModuleInfo64Func) GetProcAddress(dbghelp_lib,"SymGetModuleInfo64");
   212  		SymGetSymFromAddr64 = cast(SymGetSymFromAddr64Func) GetProcAddress(dbghelp_lib,"SymGetSymFromAddr64");
   213  		SymLoadModule64 = cast(SymLoadModule64Func) GetProcAddress(dbghelp_lib,"SymLoadModule64");
   214  		SymGetSearchPath = cast(SymGetSearchPathFunc) GetProcAddress(dbghelp_lib,"SymGetSearchPath");
   215  		SymUnloadModule64 = cast(SymUnloadModule64Func) GetProcAddress(dbghelp_lib,"SymUnloadModule64");
   216  		
   217  		if(!SymInitialize || !SymCleanup || !StackWalk64 || !SymGetOptions || !SymSetOptions || !SymFunctionTableAccess64
   218  		   || !SymGetLineFromAddr64 || !SymGetModuleBase64 || !SymGetModuleInfo64 || !SymGetSymFromAddr64
   219  		   || !SymLoadModule64 || !SymGetSearchPath || !SymUnloadModule64){
   220  			return false;
   221  		}
   222  		
   223  		isInit = true;
   224  		return true;
   225  	
   226  	}
   227  	
   228  	void DeInit(){
   229  		if(isInit){
   230  			Runtime.unloadLibrary(dbghelp_lib);
   231  			isInit = false;
   232  		}
   233  	}
   234  };
   235  	
   236  }