📄 mainunit.pas.svn-base
字号:
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 pointers 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; 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(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.drawtreeviewdone(var message: tmessage);begin if DrawTreeviewThread<>nil then DrawTreeviewThread.done;end;procedure Tfrmpointerscanner.drawtreeviewAddToList(var message: tmessage); begin if DrawTreeviewThread<>nil then DrawTreeviewThread.AddToList;end;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... 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; //no vm so no phase 1 currentpos:=pointer(start); phase:=2; 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; if isstatic and (currentpos^>=filterstart) and (currentpos^<=filterstop) then begin method2scan(dword(currentpos)); end; inc(i); i:=i mod 40; if i=0 then progressbar.position:=(dword(currentpos)-start); if unallignedbase then inc(pbyte(currentpos)) else inc(pbyte(currentpos),4); 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; except 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; end; //done finally setlength(filenames,length(method2scanners)); for i:=0 to length(method2scanners)-1 do begin method2scanners[i].stop:=true; method2scanners[i].startworking.SetEvent; //run it in case it was waiting method2scanners[i].WaitFor; //wait till this thread has terminated because the main thread has termianted method2scanners[i].flushresults; filenames[i]:=method2scanners[i].filename; //save the filename method2scanners[i].Free; end; postmessage(frmpointerscanner.Handle,staticscanner_done,0,0); terminate; freeandnil(Method2semaphore); end;end;destructor TStaticscanner.destroy;begin terminate; waitfor; inherited destroy;end;//---------------------------------main--------------------------procedure Tfrmpointerscanner.Method3Fastspeedandaveragememoryusage1Click(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -