📄 symbolhandlerlite.pas.svn-base
字号:
unit symbolhandlerlite;interfaceuses classes,windows,imagehlp,sysutils,syncobjs,tlhelp32;Type TMemoryRegion = record BaseAddress: Dword; MemorySize: Dword; IsChild: boolean; startaddress: pointer; end;type TMemoryregions = array of tmemoryregion;type TUserdefinedsymbol=record symbolname: string; address: dword;end;type TModuleInfo=record modulename: string; baseaddress: dword; basesize: dword;end;type TUserdefinedSymbolCallback=procedure;type TSymHandler=class private lastmodulelistupdate: integer; modulelistpos: integer; modulelist: array of TModuleInfo; symbolloadervalid: TMultiReadExclusiveWriteSynchronizer; modulelistMREW: TMultiReadExclusiveWriteSynchronizer; userdefinedsymbolspos: integer; userdefinedsymbols: array of TUserdefinedsymbol; userdefinedsymbolsMREW: TMultireadExclusiveWriteSynchronizer; fshowmodules: boolean; //--determines what is returned by getnamefromaddress fshowsymbols: boolean; /// UserdefinedSymbolCallback: TUserdefinedSymbolCallback; function getusedprocesshandle :thandle; function getusedprocessid:dword; function getisloaded:boolean; procedure setshowmodules(x: boolean); procedure setshowsymbols(x: boolean); public locked: boolean; property showmodules: boolean read fshowmodules write setshowmodules; property showsymbols: boolean read fshowsymbols write setshowsymbols; property usedprocesshandle: thandle read getusedprocesshandle; property usedprocessid: dword read getusedprocessid; property isloaded: boolean read getisloaded; procedure waitforsymbolsloaded; procedure reinitialize; procedure loadmodulelist; procedure fillMemoryRegionsWithModuleData(var mr: TMemoryregions; startaddress: dword; size: dword); function getmodulebyaddress(address: dword; var mi: TModuleInfo):BOOLEAN; function getmodulebyname(modulename: string; var mi: TModuleInfo):BOOLEAN; function getNameFromAddress(address:dword):string; function getAddressFromName(name: string):dword; overload; function getAddressFromName(name: string; waitforsymbols: boolean):dword; overload; //userdefined symbols function DeleteUserdefinedSymbol(symbolname:string):boolean; function GetUserdefinedSymbolByName(symbolname:string):dword; function GetUserdefinedSymbolByAddress(address:dword):string; procedure AddUserdefinedSymbol(address: dword; symbolname: string); procedure EnumerateUserdefinedSymbols(list:tstrings); procedure RegisterUserdefinedSymbolCallback(callback: TUserdefinedSymbolCallback); constructor create;end;var symhandler: TSymhandler; processhandle: thandle; processid: dword;implementationtype TSymbolloaderthread=class(tthread) public isloading: boolean; symbolsloaded: boolean; thisprocesshandle: thandle; thisprocessid: dword; procedure execute; override; constructor create(CreateSuspended: boolean);end;var symbolloaderthread: TSymbolloaderthread; symbolprocesshandle: thandle;procedure TSymbolloaderthread.execute;begin try SymbolsLoaded:=false; if symbolprocesshandle<>0 then Symcleanup(symbolprocesshandle); //cleanup first SymbolsLoaded:=SymInitialize(thisprocesshandle,nil,true); symsetoptions(symgetoptions or SYMOPT_CASE_INSENSITIVE); symbolprocesshandle:=processhandle; finally isloading:=false; end;end;constructor TSymbolloaderthread.create(CreateSuspended: boolean);begin thisprocesshandle:=processhandle; thisprocessid:=processid; isloading:=true; SymbolsLoaded:=false; inherited create(suspended);end;function TSymhandler.getisloaded:boolean;begin symbolloadervalid.beginread; if symbolloaderthread<>nil then result:=not symbolloaderthread.isloading else result:=false; symbolloadervalid.endread;end;procedure TSymhandler.RegisterUserdefinedSymbolCallback(callback: TUserdefinedSymbolCallback);begin UserdefinedSymbolCallback:=callback;end;procedure TSymhandler.setshowmodules(x: boolean);begin if locked then raise exception.Create('You can''t change this setting at the moment'); fshowmodules:=x;end;procedure TSymhandler.setshowsymbols(x: boolean);begin if locked then raise exception.Create('You can''t change this setting at the moment'); fshowsymbols:=x;end;function TSymhandler.getusedprocessid:dword;begin symbolloadervalid.beginread; if symbolloaderthread<>nil then result:=symbolloaderthread.thisprocessid else result:=0; symbolloadervalid.endread;end;function TSymhandler.getusedprocesshandle:thandle;begin symbolloadervalid.beginread; if symbolloaderthread<>nil then result:=symbolloaderthread.thisprocesshandle else result:=0; symbolloadervalid.endread;end;procedure TSymhandler.reinitialize;var previousprocesshandle: thandle;begin loadmodulelist; symbolloadervalid.BeginWrite; if symbolloaderthread<>nil then begin symbolloaderthread.WaitFor; //wait till it's done symbolloaderthread.Free; end; symbolloaderthread:=tsymbolloaderthread.Create(false); symbolloadervalid.EndWrite;end;procedure TSymhandler.Waitforsymbolsloaded;begin symbolloadervalid.beginread; if symbolloaderthread<>nil then symbolloaderthread.WaitFor; symbolloadervalid.endread;end;function TSymhandler.DeleteUserdefinedSymbol(symbolname:string):boolean;var i,j: integer;begin result:=false; userdefinedsymbolsMREW.beginwrite; for i:=0 to userdefinedsymbolspos-1 do if uppercase(userdefinedsymbols[i].symbolname)=uppercase(symbolname) then begin //found it, now move up all the others and decrease the list for j:=i to userdefinedsymbolspos-2 do userdefinedsymbols[j]:=userdefinedsymbols[j+1]; dec(userdefinedsymbolspos); result:=true; break; end; userdefinedsymbolsMREW.endwrite; if assigned(UserdefinedSymbolCallback) then UserdefinedSymbolCallback();end;function TSymhandler.GetUserdefinedSymbolByName(symbolname:string):dword;var i:integer;begin result:=0; userdefinedsymbolsMREW.beginread; for i:=0 to userdefinedsymbolspos-1 do if uppercase(userdefinedsymbols[i].symbolname)=uppercase(symbolname) then begin result:=userdefinedsymbols[i].address; break; end; userdefinedsymbolsMREW.endread;end;function TSymhandler.GetUserdefinedSymbolByAddress(address:dword):string;var i:integer;begin result:=''; userdefinedsymbolsMREW.beginread; for i:=0 to userdefinedsymbolspos-1 do if userdefinedsymbols[i].address=address then begin result:=userdefinedsymbols[i].symbolname; break; end; userdefinedsymbolsMREW.endread;end;procedure TSymhandler.AddUserdefinedSymbol(address: dword; symbolname: string);begin if address=0 then raise exception.Create('You can''t add a symbol with address 0'); if getuserdefinedsymbolbyname(symbolname)>0 then raise exception.Create(symbolname+' already exists'); userdefinedsymbolsMREW.beginwrite; try if userdefinedsymbolspos+1>=length(userdefinedsymbols) then setlength(userdefinedsymbols,length(userdefinedsymbols)*2); userdefinedsymbols[userdefinedsymbolspos].address:=address; userdefinedsymbols[userdefinedsymbolspos].symbolname:=symbolname; inc(userdefinedsymbolspos); if assigned(UserdefinedSymbolCallback) then UserdefinedSymbolCallback(); finally userdefinedsymbolsMREW.endwrite; end;end;procedure TSymhandler.EnumerateUserdefinedSymbols(list:tstrings);var i: integer;begin list.Clear; userdefinedsymbolsMREW.BeginRead; for i:=0 to userdefinedsymbolspos-1 do list.Addobject(userdefinedsymbols[i].symbolname,pointer(userdefinedsymbols[i].address)); userdefinedsymbolsMREW.EndRead;end;procedure TSymhandler.fillMemoryRegionsWithModuleData(var mr: TMemoryregions; startaddress: dword; size: dword);var currentaddress: dword; mi: tmoduleinfo; sizeleft: dword; i: integer; closest: integer; ok: boolean;begin modulelistMREW.beginread; try if modulelistpos=0 then exit; currentaddress:=startaddress; sizeleft:=size;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -