⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 symbolhandler.pas

📁 冒险岛吸怪源码UCE的制作材料 用于冒险岛游戏的外挂
💻 PAS
📖 第 1 页 / 共 2 页
字号:
        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;symbols:boolean; modules: boolean):string;
var symbol :PImagehlpSymbol;
    offset: dword;
    s: string;
    mi: tmoduleinfo;
begin
  if symbols 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 modules 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);  //default

end;

function TSymhandler.getNameFromAddress(address:dword):string;
begin
  result:=getNameFromAddress(address,self.showsymbols,self.showmodules);
end;

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;

    ws: widestring;
    pws: pwidechar;
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
    begin
      result:=result+offset;
      exit;
    end;

    {$ifndef autoassemblerdll}
    {if (darkbytekernel<>0) and (length(name)>3) then
    begin
      ws:=name;
      pws:=@ws[1];
      result:=dword(GetKProcAddress(pws));
      if result<>0 then
      begin
        result:=result+offset;
        exit;
      end;
    end;          }
    {$endif}


    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;
  end
end;


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;

destructor TSymhandler.destroy;
begin
  if symbolloaderthread<>nil then
  begin
    symbolloaderthread.Terminate;
    symbolloaderthread.WaitFor;
    symbolloaderthread.free;
  end;


  symbolloadervalid.Free;
  modulelistMREW.free;
  userdefinedsymbolsMREW.free;
  setlength(userdefinedsymbols,0);
  setlength(modulelist,0);
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 + -