📄 symbolhandlerlite.pas.svn-base
字号:
while sizeleft>0 do begin //find a module with currentaddress if nothing found, find the one with the lowest base address after it if getmodulebyaddress(currentaddress,mi) then begin setlength(mr,length(mr)+1); mr[length(mr)-1].BaseAddress:=currentaddress; mr[length(mr)-1].MemorySize:=mi.basesize-(currentaddress-mi.baseaddress); if mr[length(mr)-1].MemorySize>sizeleft then mr[length(mr)-1].MemorySize:=sizeleft; sizeleft:=sizeleft-mr[length(mr)-1].MemorySize; inc(currentaddress,mr[length(mr)-1].MemorySize); end else begin //move the currentaddress to the next module closest:=-1; for i:=0 to modulelistpos-1 do begin if modulelist[i].baseaddress>currentaddress then begin closest:=i; break; end; end; //irst make sure there is a bigger module for i:=0 to modulelistpos-1 do if (modulelist[i].baseaddress>currentaddress) and (modulelist[i].baseaddress<modulelist[closest].baseaddress) then closest:=i; if modulelist[closest].baseaddress<currentaddress then exit; //nothing found mi:=modulelist[closest]; inc(sizeleft,mi.baseaddress-currentaddress); currentaddress:=mi.baseaddress; end; end; finally modulelistMREW.endread; end;end;function TSymhandler.getmodulebyaddress(address: dword; var mi: TModuleInfo):BOOLEAN;var i: integer;begin result:=false; modulelistMREW.beginread; for i:=0 to modulelistpos-1 do if (address>=modulelist[i].baseaddress) and (address<modulelist[i].baseaddress+modulelist[i].basesize) then begin mi:=modulelist[i]; result:=true; break; end; modulelistMREW.endread;end;function TSymhandler.getmodulebyname(modulename: string; var mi: TModuleInfo):BOOLEAN;var i: integer;begin result:=false; modulelistMREW.beginread; for i:=0 to modulelistpos-1 do if (uppercase(modulelist[i].modulename)=uppercase(modulename)) then begin mi:=modulelist[i]; result:=true; break; end; modulelistMREW.endread;end;function TSymhandler.getNameFromAddress(address:dword):string;var symbol :PImagehlpSymbol; offset: dword; s: string; mi: tmoduleinfo;begin if self.showsymbols then begin //first see if it is a symbol symbolloadervalid.beginread; try if (symbolloaderthread<>nil) then begin if isloaded then begin getmem(symbol,sizeof(IMAGEHLP_SYMBOL)+255); try zeromemory(symbol,sizeof(IMAGEHLP_SYMBOL)+255); symbol.SizeOfStruct:=sizeof(IMAGEHLP_SYMBOL)+255; symbol.MaxNameLength:=254; if SymGetSymFromAddr(processhandle,address,@offset,symbol^) then begin //found it s:=pchar(@symbol.Name[0]); if offset=0 then result:=s else result:=s+'+'+inttohex(offset,1); exit; end; finally freemem(symbol); end; end; end; finally symbolloadervalid.endread; end; //check the userdefined symbols result:=self.GetUserdefinedSymbolByAddress(address); if result<>'' then exit; end; if self.showmodules then begin //get the dllname+offset if getmodulebyaddress(address,mi) then begin if address-mi.baseaddress=0 then result:=mi.modulename else result:=mi.modulename+'+'+inttohex(address-mi.baseaddress,1); exit; end; end; result:=inttohex(address,8); //defaultend;function TSymhandler.getAddressFromName(name:string):dword;begin result:=getAddressFromName(name,true);end;function TSymhandler.getAddressFromName(name: string; waitforsymbols: boolean):dword;var mi: tmoduleinfo; newaddress: string; symbol :PImagehlpSymbol; oldoptions: dword; offset: dword; sn: string; i: integer;begin result:=0; val('$'+name,result,i); if i=0 then exit; //it's a valid hexadecimal string try //first cut of the name from the offset offset:=0; for i:=length(name)-1 downto 1 do if name[i] in ['+','-'] then begin sn:=copy(name,i+1,length(name)); offset:=strtoint('$'+sn); if name[i]='-' then offset:=-offset; name:=copy(name,1,i-1); break; end; except raise exception.create(sn+' is not a valid value'); end; val('$'+name,result,i); if i=0 then begin result:=result+offset; exit; //it was a simple +/- calculation end; //see if it is a module if getmodulebyname(name,mi) then result:=mi.baseaddress+offset else begin //if not, see if you can find it as a symbol //first check the userdefined symbols (small list, so faster than the symbols) result:=GetUserdefinedSymbolByName(name); if result<>0 then exit; symbolloadervalid.beginread; try if (symbolloaderthread<>nil) then begin if symbolloaderthread.isloading and not waitforsymbols then raise exception.create('This is not a valid address'); symbolloaderthread.WaitFor; //wait for it to finish if it's still busy //it's not a valid address, it's not a calculation, it's not a modulename+offset, so lets see if it's a module getmem(symbol,sizeof(IMAGEHLP_SYMBOL)+255); try zeromemory(symbol,sizeof(IMAGEHLP_SYMBOL)+255); symbol.SizeOfStruct:=sizeof(IMAGEHLP_SYMBOL)+255; symbol.MaxNameLength:=254; if SymGetSymFromName(processhandle,pchar(name),symbol^) then result:=symbol.Address+offset else raise exception.Create('This is not a valid address'); //no hex string, no module, no symbol, so invalid finally freemem(symbol); end; end else raise exception.Create('This is not a valid address'); finally symbolloadervalid.endread; end; endend;procedure TSymhandler.loadmodulelist;var ths: thandle; me32:MODULEENTRY32; x: pchar;begin modulelistMREW.BeginWrite; try modulelistpos:=0; if processid=0 then exit; //refresh the module list ths:=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,processid); if ths<>0 then begin me32.dwSize:=sizeof(MODULEENTRY32); if ths<>0 then begin try if module32first(ths,me32) then repeat if modulelistpos+1>=length(modulelist) then setlength(modulelist,length(modulelist)*2); x:=me32.szExePath; modulelist[modulelistpos].modulename:=extractfilename(x); modulelist[modulelistpos].baseaddress:=dword(me32.modBaseAddr); modulelist[modulelistpos].basesize:=me32.modBaseSize; inc(modulelistpos); until not module32next(ths,me32); finally closehandle(ths); end; end; end; finally modulelistmrew.EndWrite; end;end;constructor TSymhandler.create;begin symbolloadervalid:=TMultiReadExclusiveWriteSynchronizer.create; modulelistMREW:=TMultiReadExclusiveWriteSynchronizer.create; userdefinedsymbolsMREW:=TMultireadExclusiveWriteSynchronizer.create; setlength(userdefinedsymbols,32); setlength(modulelist,32); showmodules:=false; showsymbols:=true;end;initialization symbolprocesshandle:=0; symhandler:=tsymhandler.create;finalization symhandler.free;end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -