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

📄 pointerscannerfrm.pas.svn-base

📁 这是一段游戏修改工具的源代码.ring3功能由dephi开发,驱动是C开发.希望对大家有帮助
💻 SVN-BASE
📖 第 1 页 / 共 4 页
字号:

procedure TMethod2scanner.flushresults;
begin
  resultsfile.WriteBuffer(results.Memory^,results.Size);
  results.Seek(0,sofrombeginning);
  results.Clear;
end;


function TMethod2scanner.haspossiblepath(level: integer; address: dword;var recnr: integer):boolean;
var i: integer;
    first,last: integer;
begin
  result:=false;
  recnr:=0;
  first:=0;


  //check possible paths in higher levels
  if level<self.maxlevel then
  begin
    result:=haspossiblepath(level+1,address,recnr); //recnr is only used when it is NOT found
    if result then exit;
  end;

  //no need for a critical section, it doesnt become shorter, only thing that can happen is a address being added twice, but thats not the end of the world
  last:=possiblepathslevelpos[level];

  while first<last do
  begin
    i:=first+((last-first) div 2);
    if (i=first) or (i=last) then
    begin
      for i:=first to last-1 do
      begin
        if possiblepathslevel[level][i]=address then
        begin
          recnr:=i;
          result:=true;
          exit;
        end;
        if possiblepathslevel[level][i]>address then break;
      end;

      break;
    end;

    if possiblepathslevel[level][i]=address then
    begin
      recnr:=i;
      result:=true;
      exit;
    end;

    if address<possiblepathslevel[level][i] then
      last:=i
    else
      first:=i;
  end;
  recnr:=last;
end;



procedure TMethod2scanner.addpossiblepath(address: dword; level: integer);
var x,y: dword;
    i,j: integer;
    originalpos: integer;
begin
  //offsetlist now contains a pointer path
  if not haspossiblepath(level,address,i) then
  begin
    possiblepathsLevelMREWS[level].beginwrite;
    try

      if possiblepathslevelpos[level]+1>=length(possiblepathslevel[level]) then //reallocate array
        setlength(possiblepathslevel[level],length(possiblepathslevel[level])*2); //double the memory (4mb, 8mb, 16mb,32mb,64mb,128mb,256mb,512mb,1024mb.....)

      //not found so add , i is a good indication of where
      dec(i);
      while (i>=0) and (possiblepathslevel[level][i]>address) do dec(i);
      if i=-1 then i:=0;

      while (i<possiblepathslevelpos[level]) and (possiblepathslevel[level][i]<address) do inc(i);

      //add it to the spot of i

      //first move evrything else to the right
      for j:=possiblepathslevelpos[level]-1 downto i do
        possiblepathslevel[level][j+1]:=possiblepathslevel[level][j];

      possiblepathslevel[level][i]:=address;

      possiblepathslevelpos[level]:=possiblepathslevelpos[level]+1;
    finally
      possiblepathsLevelMREWS[level].EndWrite;
    end;
  end;
end;


procedure TMethod2Scanner.ScanAddress(saddress:dword; currentlevel: integer);
type
    PDWordArray = ^TDWordArray;
    TDWordArray = array[0..0] of DWORD;

var struct: PDWordArray;
    x: dword;
    i,j,k,l,m: integer;

    tempoffsetlist: array of toffsetlist;

    tempoffset: toffsetlist;

    sz: integer;
    mi: tmoduleinfo;

begin
  inc(scanaddresscount);
  
  if terminated then exit;

  if currentlevel=1 then
    sz:=structsize0
  else
    sz:=structsize;

  try
    if frmPointerScanner.Staticscanner=nil then
    begin
      terminate;
      exit; //it got freed
    end;

    if frmPointerScanner.Staticscanner.Terminated then
    begin
      terminate;
      exit;
    end;
  except
    terminate;
    exit;
  end;

  if (addresstofind>=saddress) and (addresstofind<(saddress+sz)) then
  begin
    //found it

    offsetlist[currentlevel]:=addresstofind-saddress;


    if results.Size>50*1024*1024 then flushresults;

    try
      //recheck to see if one of the poitners have changed in the meantime
      x:=offsetlist[0];
      pathlist[1]:=x;

      for i:=2 to currentlevel do
      begin
        x:=pdword(vm.AddressToPointer(x))^+offsetlist[i];
        pathlist[i]:=x;
      end;

      if x<>addresstofind then inc(incorrectresult)
      else
      begin
        //correct so add it to the list of possible paths
        if not fast then
        begin
          for i:=1 to currentlevel do
            addpossiblepath(pathlist[i],i);
        end;


        if not symhandler.getmodulebyaddress(offsetlist[0],mi) then
        begin
          mi.modulename:='';
          mi.baseaddress:=0;
          mi.basesize:=$7fffffff;
        end;

        x:=length(mi.modulename);
        results.WriteBuffer(x,sizeof(x));
        results.WriteBuffer(mi.modulename[1],x);

        x:=offsetlist[0]-mi.baseaddress; //offset
        results.WriteBuffer(x,sizeof(x));

        i:=currentlevel-1;
        results.WriteBuffer(i,sizeof(i));
        results.WriteBuffer(offsetlist[2],(currentlevel-1)*sizeof(offsetlist[0]));
        inc(pointersfound);
      end;
    except
      inc(incorrectresult);
    end;

    
  end;


  if (not psychotic) and method3 and (currentlevel>1) and isdissected(currentlevel-1,saddress,i) then
  begin
    if fast then exit;

    //else see if it is in a possible path and if so continue, else exit
    if haspossiblepath(currentlevel-1,saddress,i) then
    begin
      //I see hope in this path
      inc(continued);
    end
    else
    begin
      inc(skipped);
      exit;
    end;
  end;



  try
    if frmPointerScanner.staticscanner=nil then exit;
  except
    exit;
  end;

  struct:=pointer(vm.AddressToPointer(dword(saddress)));


  try
    for i:=0 to (sz-1) div 4 do
    begin
      if (unalligned or ((struct[i] mod 4)=0)) and vm.isvalid(struct[i]) and (currentlevel<maxlevel) and (struct[i]>=filterstart) and (struct[i]<=filterstop) then
      begin
        if currentlevel>1 then offsetlist[currentlevel]:=i*4;
        
        scanaddress(struct[i],currentlevel+1);
        if not psychotic then adddisectedaddress(currentlevel,struct[i]);
      end;
    end;
  except
    //end of structure reached
  end;
end;



procedure TMethod2Scanner.execute;
var wr: twaitresult;
    err: integer;
begin
  filename:=inttostr(getcurrentprocessid)+'-'+inttostr(getcurrentthreadid)+'.ptr';
  resultsfile:= tfilestream.Create(filename,fmcreate);

  
  while not terminated do
  begin
    wr:=startworking.WaitFor(infinite);
    if stop then exit; //happens when the thread was idle and the staticscanner already terminated so send it it event to go out of idle

    if wr=wrSignaled then
    begin
      try
        err:=0;
        if length(offsetlist)<maxlevel*2+1 then
        begin
          setlength(offsetlist,maxlevel*2+1);
          setlength(pathlist,maxlevel*2+1);
        end;

        offsetlist[0]:=address;
        offsetlist[1]:=address;
        scanaddress(address,1);
        err:=3;
        //adddisectedaddress(0,address);
      except
      end;

      isdone:=true;  //set isdone to true
      try
        method2semaphore.release;  //release the mainthead if it was waiting
      except
        messagebox(0,'err','err',0);
      end;
    end;
  end;
end;


constructor Tmethod2scanner.create(suspended:boolean);
begin
  results:= tmemorystream.Create;

  startworking:=tevent.create(nil,false,false,'');
  isdone:=true;

  inherited create(suspended);
end;

destructor TMethod2scanner.destroy;
begin
  results.free;
  resultsfile.free;
  startworking.free;
end;


//----------------------- staticscanner -------------------------


procedure Tfrmpointerscanner.drawtreeview;
begin
  file1.Enabled:=false;
  Pointerscanner1.Enabled:=false;
  treeview2.Items.BeginUpdate;
  DrawTreeviewthread:=TDrawtreeview.Create(true);
  DrawTreeviewThread.pointerlist:=pointerlist;
  DrawTreeviewThread.treeview:=treeview2;
  DrawTreeviewThread.progressbar:=progressbar1;
  DrawTreeviewThread.Resume;
end;

procedure TFrmpointerscanner.loadpointers;
begin
  if pointerlist=nil then pointerlist:=tmemorystream.create;
  pointerlist.loadfromfile(staticscanner.filenames[0]);
end;

procedure TFrmpointerscanner.doneui;
begin
  progressbar1.position:=0;

  panel2.Visible:=false;
  TreeView2.Visible:=true;
  TreeView2.Align:=alclient;
  open1.Enabled:=true;
  new1.enabled:=true;
  save1.Enabled:=true;
  rescanmemory1.Enabled:=true;
end;

procedure Tfrmpointerscanner.m_staticscanner_done(var message: tmessage);
var x: tfilestream;
    result: tfilestream;
    i: integer;
begin
  //update the treeview

  //now combile all thread results to 1 file
  result:=tfilestream.Create('result.ptr',fmcreate);
  for i:=0 to length(staticscanner.filenames)-1 do
  begin
    x:=tfilestream.Create(staticscanner.filenames[i],fmopenread);
    result.CopyFrom(x,0);
    x.free;
    deletefile(staticscanner.filenames[i]);
  end;
  result.Free;

  setlength(staticscanner.filenames,1);
  staticscanner.filenames[0]:='result.ptr';

  loadpointers;

  showresults1.Enabled:=true;
  showresults1.Click;

  doneui;  
end;






procedure TStaticScanner.method2scan(address:dword);
var i,j: integer;
begin
  //find one that is either empty or done

  j:=-1;
  method2semaphore.Aquire; //allow cpucount+1 to go through

  //this only gets called by 1 thread, so no threadchooser cs needed

  if terminated then
  begin
    method2semaphore.Release;
    exit;
  end;

  for i:=0 to length(method2scanners)-1 do
  begin
    if method2scanners[i].isdone then
    begin
      j:=i;
      break;
    end;
  end;

  if j<>-1 then //otherwhise impossible, but for debugging purposes... (mem corruption)
  begin
    method2scanners[j].address:=address;
    method2scanners[j].addresstofind:=automaticaddress;
    method2scanners[j].maxlevel:=maxlevel;
    method2scanners[j].structsize:=sz;
    method2scanners[j].structsize0:=sz0;
    method2scanners[j].unalligned:=unalligned;
    method2scanners[j].filterstart:=filterstart;
    method2scanners[j].filterstop:=filterstop;
    method2scanners[j].method3:=method3;
    method2scanners[j].fast:=fast;
    method2scanners[j].psychotic:=psychotic;
    method2scanners[j].isdone:=false;
   

    method2scanners[j].startworking.SetEvent; //it should start working now...
  end
  else
    messagebox(0,'error','error',mb_ok);
end;




//-----------

procedure TReverseScanWorker.flushresults;
begin
  resultsfile.WriteBuffer(results.Memory^,results.Size);
  results.Seek(0,sofrombeginning);
  results.Clear;
end;

constructor TReverseScanWorker.create(suspended:boolean);
begin
  results:=tmemorystream.Create;

  startworking:=tevent.create(nil,false,false,'');
  isdone:=true;

  inherited create(suspended);
end;

destructor TReverseScanWorker.destroy;
begin
  results.free;
  if resultsfile<>nil then
    resultsfile.free;

  startworking.free;
end;

procedure TReverseScanWorker.execute;
var wr: twaitresult;
begin
  filename:=inttostr(getcurrentprocessid)+'-'+inttostr(getcurrentthreadid)+'.ptr';
  resultsfile:= tfilestream.Create(filename,fmcreate);

  
  while not terminated do
  begin
    wr:=startworking.WaitFor(infinite);
    if stop then exit;

    if wr=wrSignaled then
    begin
      try
        rscan(startaddress,startlevel+1);

      finally
        isdone:=true;  //set isdone to true
        reversescansemaphore.release;
      end;
    end;
  end;

end;


var fcount:integer=0;
var scount:integer=0;

procedure TReverseScanWorker.StorePath(level: integer);
{Store the current path to memory and flush if needed}
var i: integer;
    x: dword;

    foundstatic: boolean;
    mi: tmoduleinfo;
begin
  inc(fcount);

  foundstatic:=false;
  for i:=0 to level do
    if symhandler.getmodulebyaddress(tempresults[i],mi) then
    begin
      //we found a static address in the path!!!
      level:=i; //cut it off at i, not level
      inc(scount);
      foundstatic:=true;
      break;
    end;

  if not foundstatic then
  begin
    if staticonly then exit; //don't save
    
    mi.modulename:=inttohex(tempresults[level],8);
    mi.baseaddress:=tempresults[level];
  end;

  //fill in the offset list


  offsetlist[level]:=addresstofind-pdword(vm.AddressToPointer(tempresults[0]))^;
  for i:=1 to level do
    offsetlist[level-i]:=tempresults[i-1]-pdword(vm.AddressToPointer(tempresults[i]))^;

  x:=length(mi.modulename);
  results.WriteBuffer(x,sizeof(x));
  results.WriteBuffer(mi.modulename[1],x);

  x:=tempresults[level]-mi.baseaddress;
  results.WriteBuffer(x,sizeof(x));


  i:=level+1;
  results.WriteBuffer(i,sizeof(i));
  results.WriteBuffer(offsetlist[0], i*sizeof(offsetlist[0]) );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -