unit frmMemoryViewExUnit; {$mode delphi} interface uses windows, Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls, ComCtrls, Menus, memdisplay, newkernelhandler, cefuncproc, syncobjs, math, savedscanhandler, foundlisthelper, CustomTypeHandler, symbolhandler, inputboxtopunit, commonTypeDefs; type TMVCompareMethod=(cmOr, cmXor, cmAnd); type TMemoryDataSource=class(TThread) private cs: TCriticalSection; address: ptruint; buf: pbytearray; bufsize: integer; faddresslistonly: boolean; fcompareagainstsavedscan: boolean; fvartype: TVariableType; fvarsize: integer; comparemethod: TMVCompareMethod; temppagebuf: pbytearray; addresslist: TFoundList; previousvaluelist: TSavedScanHandler; ct: TCustomtype; public procedure lock; procedure unlock; procedure setRegion(address: ptruint; buf: pointer; size: integer); procedure execute; override; procedure fetchmem; procedure setaddresslist(state: boolean; listname: string); procedure setcompare(state: boolean; compareMethod: TMVCompareMethod; listname: string); constructor create(suspended: boolean); end; { TfrmMemoryViewEx } TfrmMemoryViewEx = class(TForm) cbAddresslist: TComboBox; cbAddresslistOnly: TCheckBox; cbColor: TComboBox; cbCompare: TCheckBox; cbSavedList: TComboBox; edtPitch: TEdit; Label2: TLabel; Label3: TLabel; lblAddress: TLabel; MenuItem1: TMenuItem; Panel1: TPanel; Panel2: TPanel; Panel3: TPanel; Panel4: TPanel; pmMemview: TPopupMenu; rbAnd: TRadioButton; rbOr: TRadioButton; rbXor: TRadioButton; tbPitch: TTrackBar; Timer1: TTimer; procedure cbAddresslistChange(Sender: TObject); procedure cbAddresslistOnlyChange(Sender: TObject); procedure cbAddresslistDropDown(Sender: TObject); procedure cbCompareChange(Sender: TObject); procedure cbSavedListChange(Sender: TObject); procedure cbColorChange(Sender: TObject); procedure edtPitchChange(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure MenuItem1Click(Sender: TObject); procedure Panel1DblClick(Sender: TObject); procedure Timer1Timer(Sender: TObject); procedure tbPitchChange(Sender: TObject); private { private declarations } buf: pbytearray; bufsize: integer; datasource: TMemoryDataSource; history: TStringList; function getCompareMethod: TMVCompareMethod; function ondata(newAddress: ptruint; PreferedMinimumSize: integer; var newbase: pointer; var newsize: integer): boolean; public { public declarations } md: TMemDisplay; end; var frmMemoryViewEx: TfrmMemoryViewEx; implementation uses MemoryBrowserFormUnit, MainUnit, ProcessHandlerUnit; {$R *.lfm} resourcestring rsGotoAddress = 'Goto Address'; rsFillInTheAddressYouWantToGoTo = 'Fill in the address you want to go to'; rsAddressZoom = 'Address : %s zoom : %s'; { TMemoryDataSource } constructor TMemoryDataSource.create(suspended: boolean); begin cs:=tcriticalsection.create; getmem(temppagebuf, 4096); //so it doesn't need to be allocated/freed each fetchmem call inherited create(suspended); end; procedure TMemoryDataSource.setcompare(state: boolean; compareMethod: TMVCompareMethod; listname: string); begin if state then begin cs.Enter; try if previousvaluelist<>nil then freeandnil(previousvaluelist); previousvaluelist:=TSavedScanHandler.create(mainform.memscan.GetScanFolder, listname); previousvaluelist.AllowNotFound:=true; previousvaluelist.AllowRandomAccess:=true; self.compareMethod:=comparemethod; finally cs.Leave; end; end; fcompareagainstsavedscan:=state; end; procedure TMemoryDataSource.setaddresslist(state: boolean; listname: string); begin if state then begin //Open a "PreviousValue object for the current memscan results. cs.Enter; try if addresslist<>nil then freeandnil(addresslist); addresslist:=TFoundList.create(nil, mainform.memscan, listname); addresslist.Initialize; fvartype:=mainform.memscan.VarType; ct:=mainform.memscan.CustomType; fvarsize:=mainform.memscan.Getbinarysize div 8; finally cs.leave; end; end; faddresslistonly:=state; fetchmem; //update now end; procedure TMemoryDataSource.fetchmem; var x: ptrUint; a,a2: ptruint; s: integer; s2: integer; p: PByteArray; i: qword; j: integer; toread: integer; begin lock; if buf<>nil then //not yet initialized begin a:=address; i:=qword(-1); if faddresslistonly then i:=addresslist.FindClosestAddress(address-fvarsize+1); //all following accesses will be sequential toread:=bufsize; //while a
0 do begin s:=minX((address+bufsize)-a, 4096-(a mod 4096)); //the number of bytes left in this page or for this buffer x:=0; if faddresslistonly then begin //check if this page has any addresses. zeromemory(@buf[a-address], s); if int64(i)<>-1 then begin a2:=addresslist.GetAddress(i); //get the first addresses that belong to this page (or has bytes in it) while (i