📄 mainunit.pas
字号:
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;
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(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;
results.WriteBuffer(currentlevel,sizeof(currentlevel));
results.WriteBuffer(offsetlist[0],(currentlevel+1)*sizeof(offsetlist[0]));
inc(pointersfound);
end;
except
inc(incorrectresult);
end;
exit;
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(saddress);
try
for i:=0 to (sz-1) div 4 do
begin
if (unalligned or ((struct[i] mod 4)=0)) and (not IsBadReadPtr(pointer(struct[i]), 4)) 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;
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[1]:=address;
offsetlist[0]:=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;
var i,j: integer;
offsetsize: integer;
offsetlist: array of dword;
total: integer;
y: ttreenode;
begin
treeview2.Items.BeginUpdate;
try
pointerlist.Seek(0,sofrombeginning);
treeview2.items.clear;
total:=0;
setlength(offsetlist,10);
try
while pointerlist.Position<>pointerlist.Size do
begin
pointerlist.ReadBuffer(offsetsize,sizeof(offsetsize));
if length(offsetlist)<(offsetsize+1) then
setlength(offsetlist,offsetsize*2);
pointerlist.ReadBuffer(offsetlist[0],(offsetsize+1)*sizeof(offsetlist[0]));
y:=treeview2.Items.Add(nil,inttohex(offsetlist[0],8));
for j:=2 to offsetsize do
treeview2.Items.AddChild(y,inttohex(offsetlist[j],1));
inc(total);
end;
except
//done, eof
end;
pointersfound:=total;
finally
treeview2.Items.EndUpdate;
end;
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...
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].Priority:=scannerpriority;
method2scanners[j].startworking.SetEvent; //it should start working now...
end
else
messagebox(0,'error','error',mb_ok);
end;
procedure TStaticScanner.execute;
var currentpos: ^Dword;
i,j,k: integer;
x,opcode:string;
t:dword;
hexcount,hexstart: integer;
isstruct: boolean;
isstatic: boolean;
found: boolean;
mbi: _MEMORY_BASIC_INFORMATION;
tn,tempnode: ttreenode;
th: TDissectData;
lastnode: ttreenode;
oldshowsymbols: boolean;
oldshowmodules: boolean;
bitcount: integer;
scanregions: tmemoryregions;
currentregion: integer;
maxpos: dword;
dw: byte;
begin
if terminated then exit;
currentpos:=pointer(start);
Method2semaphore:=tsemaphore.create(threadcount);
setlength(method2scanners,threadcount);
for i:=0 to threadcount-1 do
method2scanners[i]:=tmethod2scanner.create(false);
i:=0;
threadcount:=bitcount;
try
//create some regions it should scan
setlength(scanregions,0);
if not unallignedbase then
begin
if (start mod 4)>0 then
start:=start+(4-(start mod 4));
end;
symhandler.fillMemoryRegionsWithModuleData(scanregions,start,stop-start);
if length(scanregions)=0 then exit; //no memory found
currentregion:=0;
currentpos:=pointer(scanregions[currentregion].BaseAddress);
progressbar.Position:=0;
progressbar.Max:=stop-start;
maxpos:=scanregions[currentregion].BaseAddress+scanregions[currentregion].MemorySize-4;
while (not terminated) and (dword(currentpos)<=stop) do
begin
isstatic:=false;
try
if ((currentpos^ mod 4)=0) or (unalligned) then //unaligned check after the first one so it includes a readable check
isstatic:=true;
if (writableonly) and ((dword(currentpos) mod 4096)=0) then
begin
if isbadwriteptr(currentpos,4) then
begin
inc(pbyte(currentpos),4096);
isstatic:=false;
if dword(currentpos)>=maxpos then
begin
inc(currentregion);
if currentregion=length(scanregions) then break; //no more regions
currentpos:=pointer(scanregions[currentregion].BaseAddress);
maxpos:=scanregions[currentregion].BaseAddress+scanregions[currentregion].MemorySize-4;
end;
inc(i);
i:=i mod 40;
if i=0 then progressbar.position:=(dword(currentpos)-start);
continue;
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -