📄 pointerscannerfrm.pas.svn-base
字号:
unit pointerscannerfrm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls, ComCtrls,disassembler,cefuncproc,newkernelhandler,
syncobjs,syncobjs2, Menus, virtualmemory, symbolhandler,mainunit;
const staticscanner_done=wm_user+1;
const rescan_done=wm_user+2;
const open_scanner=wm_user+3;
type TDrawTreeview=class(tthread)
private
st: string;
offset: dword;
offsetlist: array of dword;
offsetsize: integer;
public
treeview: ttreeview;
pointerlist: tmemorystream;
progressbar: tprogressbar;
procedure execute; override;
procedure done;
procedure AddToList;
end;
type TMatches = array of ttreenode;
type tpath = array of dword;
type TDissectData = class(tthread)
private
output: array [0..63] of string;
addresses: array [0..63] of dword;
ispointer: array [0..64] of boolean;
outputpos: integer;
public
dissectaddress: dword;
treenode: ttreenode;
structsize,structsize0: dword;
automatic: boolean;
maxlevel: integer;
filterstart,filterstop: integer;
unalligned: boolean;
end;
type trescanpointers=class(tthread)
public
progressbar: tprogressbar;
oldpointerlist: tmemorystream;
newpointerlist: tmemorystream;
address: dword;
procedure execute; override;
end;
type
toffsetlist = array of dword;
TStaticscanner = class;
TReverseScanWorker = class (tthread)
private
tempresults: array of dword;
results: tmemorystream;
resultsfile: tfilestream;
offsetlist: array of dword;
procedure flushresults;
procedure rscan(address:dword; level: integer);
procedure StorePath(level: integer);
public
addresstofind: dword;
maxlevel: integer;
structsize: integer;
startaddress: dword;
startlevel: integer;
alligned: boolean;
staticonly: boolean;
isdone: boolean;
startworking: tevent;
stop: boolean;
staticscanner: TStaticscanner;
filename: string;
procedure execute; override;
constructor create(suspended: boolean);
destructor destroy; override;
end;
TMethod2scanner = class (tthread)
private
results: tmemorystream;
resultsfile: tfilestream;
pathlist: array of dword;
// procedure updatelist;
function haspossiblepath(level: integer; address: dword;var recnr: integer):boolean;
procedure addpossiblepath(address:dword; level: integer);
procedure ScanAddress(saddress:dword; currentlevel: integer);
public
method3: boolean;
startworking: tevent;
isdone: boolean;
stop: boolean;
//--------------
address: dword;
addresstofind: dword;
maxlevel: integer;
structsize,structsize0: integer;
filterstart,filterstop: integer;
unalligned: boolean;
paintlevel: integer;
offsetlist: toffsetlist;
fast: boolean;
psychotic: boolean;
filename: string;
procedure flushresults;
procedure execute; override;
constructor create(suspended: boolean);
destructor destroy; override;
end;
TStaticscanner = class(TThread)
private
updateline: integer; //not used for addentry
memoryregion: array of tmemoryregion;
lasttreenodeadded: ttreenode;
addnode: ttreenode;
addnodeextension: tmatches;
method2scanners: array of tmethod2scanner;
reversescanners: array of treversescanworker;
// procedure UpdateList;
//procedure done;
// procedure automaticfinish;
// procedure addentry;
procedure method2scan(address:dword);
procedure reversescan;
public
//reverse
firstaddress: pointer;
currentaddress: pointer;
lastaddress: pointer;
//reverse^
reuse: boolean;
reverse: boolean;
automatic: boolean;
automaticaddress: dword;
filterstart:dword;
filterstop:dword;
start: dword;
stop: dword;
progressbar: TProgressbar;
sz,sz0: integer;
maxlevel: integer;
unalligned: boolean;
codescan: boolean;
method2: boolean;
method3: boolean;
fast: boolean;
psychotic: boolean;
writableonly: boolean;
unallignedbase: boolean;
threadcount: integer;
scannerpriority: TThreadPriority;
filenames: array of string;
phase: integer;
currentpos: ^Dword;
starttime: dword;
isdone: boolean;
staticonly: boolean; //for reverse
procedure execute; override;
destructor destroy; override;
end;
type
Tfrmpointerscanner = class(TForm)
ProgressBar1: TProgressBar;
Panel2: TPanel;
Label1: TLabel;
Label2: TLabel;
Label10: TLabel;
Label11: TLabel;
Label3: TLabel;
Label4: TLabel;
Label7: TLabel;
Label8: TLabel;
Label12: TLabel;
Label13: TLabel;
Label14: TLabel;
Label15: TLabel;
Button1: TButton;
TreeView2: TTreeView;
Panel1: TPanel;
MainMenu1: TMainMenu;
File1: TMenuItem;
New1: TMenuItem;
N2: TMenuItem;
Open1: TMenuItem;
Save1: TMenuItem;
Pointerscanner1: TMenuItem;
Method3Fastspeedandaveragememoryusage1: TMenuItem;
N1: TMenuItem;
Rescanmemory1: TMenuItem;
Showresults1: TMenuItem;
SaveDialog1: TSaveDialog;
OpenDialog1: TOpenDialog;
Timer2: TTimer;
Label9: TLabel;
Label16: TLabel;
Label17: TLabel;
Label18: TLabel;
Label19: TLabel;
Label20: TLabel;
Label21: TLabel;
procedure Method3Fastspeedandaveragememoryusage1Click(Sender: TObject);
procedure Timer2Timer(Sender: TObject);
procedure Showresults1Click(Sender: TObject);
procedure Save1Click(Sender: TObject);
procedure Open1Click(Sender: TObject);
procedure Rescanmemory1Click(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormShow(Sender: TObject);
procedure TreeView2DblClick(Sender: TObject);
procedure New1Click(Sender: TObject);
private
{ Private declarations }
start:tdatetime;
rescan: trescanpointers;
cewindowhandle: thandle;
drawtreeviewthread: TDrawTreeview;
procedure m_staticscanner_done(var message: tmessage); message staticscanner_done;
procedure rescandone(var message: tmessage); message rescan_done;
procedure openscanner(var message: tmessage); message open_scanner;
procedure drawtreeview;
procedure doneui;
procedure loadpointers;
public
{ Public declarations }
pointerlist: tmemorystream;
Staticscanner:TStaticScanner;
end;
type TExecuter = class(tthread)
public
procedure execute; override;
end;
type tarraypath= array of tpath;
var
frmPointerScanner: TfrmPointerScanner;
staticlist: array of dword;
dissectedstatics: dword=0;
dissectedpointersLevelpos:array of integer;
dissectedpointersLevel: array of array of dword;
dissectedpointersLevelMREWS: array of TMultiReadExclusiveWriteSynchronizer; //every level has it's own lock
treenodeswithchildrenpos: integer;
treenodeswithchildren: array of ttreenode;
treenodeswithchildrencs: tcriticalsection;
matchednodescs: tcriticalsection;
matchednodes: array of Tmatches;
matchednodespos: integer;
reverseScanCS: TCriticalSection;
PossiblepathsLevelMREWS: array of TMultiReadExclusiveWriteSynchronizer;
possiblepathsLevel: array of array of dword; //all addresses that finished in a address
possiblepathsLevelpos: array of integer;
method2semaphore: tsemaphore;
reverseScanSemaphore: tsemaphore;
totalpointers: integer;
lastlevel: integer;
pointersfound: dword=0;
foundbyappending: dword=0;
skipped: dword;
lastaddress: dword;
cpucount: integer;
scanaddresscount: dword;
incorrectresult: dword;
continued: dword;
vm: tvirtualmemory;
implementation
{$R *.dfm}
uses PointerscannerSettingsFrm;
procedure TExecuter.execute;
begin
try
frmpointerscanner:=tfrmpointerscanner.Create(nil);
frmpointerscanner.ShowModal;
messagebox(0,'Exit pointerscan','exit',mb_ok);
FreeLibraryAndExitThread(getmodulehandle('pscan.dll'),0);
except
on e: exception do
begin
messagebox(0,pchar('pointerscan crash.'),'error',mb_ok);
messagebox(0,pchar('pointerscan crash. '+e.message),'error',mb_ok);
end;
end;
end;
function isdissected(level: integer; address: dword;var recnr: integer):boolean;
var i: integer;
first,last: integer;
begin
result:=false;
recnr:=0;
first:=0;
if level>0 then
begin
result:=isdissected(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:=dissectedpointerslevelpos[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 dissectedpointerslevel[level][i]=address then
begin
recnr:=i;
result:=true;
exit;
end;
if dissectedpointerslevel[level][i]>address then break;
end;
break;
end;
if dissectedpointerslevel[level][i]=address then
begin
recnr:=i;
result:=true;
exit;
end;
if address<dissectedpointerslevel[level][i] then
last:=i
else
first:=i;
end;
recnr:=last;
end;
procedure adddisectedaddress(level:integer; dissectedaddress:dword);
var i,j: integer;
begin
if not isdissected(level,dissectedaddress,i) then
begin
dissectedpointersLevelMREWS[level].beginwrite;
try
if dissectedpointerslevelpos[level]+1>=length(dissectedpointerslevel[level]) then //reallocate array
setlength(dissectedpointerslevel[level],length(dissectedpointerslevel[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 (dissectedpointerslevel[level][i]>dissectedaddress) do dec(i);
if i=-1 then i:=0;
while (i<dissectedpointerslevelpos[level]) and (dissectedpointerslevel[level][i]<dissectedaddress) do inc(i);
//add it to the spot of i
//first move evrything else to the right
for j:=dissectedpointerslevelpos[level]-1 downto i do
dissectedpointerslevel[level][j+1]:=dissectedpointerslevel[level][j];
dissectedpointerslevel[level][i]:=dissectedaddress;
dissectedpointerslevelpos[level]:=dissectedpointerslevelpos[level]+1;
finally
dissectedpointersLevelMREWS[level].EndWrite;
end;
end;
end;
procedure TDrawTreeview.done;
begin
if frmpointerscanner<>nil then
begin
frmpointerscanner.treeview2.Items.EndUpdate;
frmpointerscanner.progressbar1.position:=0;
frmpointerscanner.file1.Enabled:=true;
frmpointerscanner.Pointerscanner1.Enabled:=true;
end;
end;
procedure TDrawtreeView.AddToList;
var y: ttreenode;
i,j: integer;
begin
y:=treeview.Items.Add(nil,st+inttohex(offset,8));
for j:=0 to offsetsize-1 do
treeview.Items.AddChild(y,inttohex(offsetlist[j],1));
end;
procedure TDrawTreeview.execute;
var total: integer;
s: pchar;
ssize: dword;
stringlength: dword;
begin
//frmpointerscanner can nevr be closed while this routine is running. See the onclose event for why
try
pointerlist.Seek(0,sofrombeginning);
treeview.items.clear;
total:=0;
setlength(offsetlist,10);
getmem(s,100);
ssize:=100;
progressbar.Position:=0;
progressbar.Max:=pointerlist.Size;
try
while (not terminated) and (frmpointerscanner.pointerlist.Position<>pointerlist.Size) do
begin
pointerlist.ReadBuffer(stringlength,sizeof(stringlength));
if ssize<=stringlength then
begin
freemem(s);
getmem(s,stringlength+1);
ssize:=stringlength+1;
end;
pointerlist.ReadBuffer(s^,stringlength);
s[stringlength]:=#0;
st:=s;
pointerlist.readbuffer(offset,sizeof(offset));
pointerlist.ReadBuffer(offsetsize,sizeof(offsetsize));
if length(offsetlist)<(offsetsize) then
setlength(offsetlist,offsetsize*2);
pointerlist.ReadBuffer(offsetlist[0],(offsetsize)*sizeof(offsetlist[0]));
if st<>'' then st:=st+'+';
if not terminated then
synchronize(AddToList);
inc(total);
if (total mod 50)=0 then
progressbar.Position:=pointerlist.Position;
end;
except
//done, eof
end;
pointersfound:=total;
finally
freemem(s);
end;
if not terminated then
synchronize(done);
end;
//----------------------- scanner info --------------------------
//----------------------- method2scanner-------------------------
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -