From 8b74d738fc1e33efd300ced1fbfcaf9fdef1dcba Mon Sep 17 00:00:00 2001 From: Dark Byte Date: Tue, 13 Dec 2016 14:26:18 +0100 Subject: [PATCH] some structure spider fixes --- Cheat Engine/frmStringMapUnit.lfm | 1 + Cheat Engine/frmStringMapUnit.pas | 6 + Cheat Engine/frmStringPointerScanUnit.lfm | 55 +++++--- Cheat Engine/frmStringPointerScanUnit.lrt | 1 + Cheat Engine/frmStringPointerScanUnit.pas | 151 +++++++++++++--------- 5 files changed, 130 insertions(+), 84 deletions(-) diff --git a/Cheat Engine/frmStringMapUnit.lfm b/Cheat Engine/frmStringMapUnit.lfm index e12ba2cb73..7f0580beb5 100644 --- a/Cheat Engine/frmStringMapUnit.lfm +++ b/Cheat Engine/frmStringMapUnit.lfm @@ -8,6 +8,7 @@ object frmStringMap: TfrmStringMap ClientHeight = 400 ClientWidth = 480 OnClose = FormClose + OnDestroy = FormDestroy OnResize = FormResize Position = poScreenCenter LCLVersion = '1.6.0.4' diff --git a/Cheat Engine/frmStringMapUnit.pas b/Cheat Engine/frmStringMapUnit.pas index d4675037fd..78aa99b4a7 100644 --- a/Cheat Engine/frmStringMapUnit.pas +++ b/Cheat Engine/frmStringMapUnit.pas @@ -69,6 +69,7 @@ TfrmStringMap = class(TForm) procedure cbRegExpChange(Sender: TObject); procedure FindDialog1Find(Sender: TObject); procedure FormClose(Sender: TObject; var CloseAction: TCloseAction); + procedure FormDestroy(Sender: TObject); procedure FormResize(Sender: TObject); procedure ListView1DblClick(Sender: TObject); procedure miFindClick(Sender: TObject); @@ -577,6 +578,11 @@ procedure TfrmStringMap.FormClose(Sender: TObject; var CloseAction: TCloseAction isfillinglist:=false; end; +procedure TfrmStringMap.FormDestroy(Sender: TObject); +begin + cleanup; +end; + procedure TfrmStringMap.FormResize(Sender: TObject); begin listview1.Column[listview1.ColumnCount-1].Width:=listview1.ClientWidth-listview1.Column[0].Width-3; diff --git a/Cheat Engine/frmStringPointerScanUnit.lfm b/Cheat Engine/frmStringPointerScanUnit.lfm index abf0240bbc..79b28046e9 100644 --- a/Cheat Engine/frmStringPointerScanUnit.lfm +++ b/Cheat Engine/frmStringPointerScanUnit.lfm @@ -53,7 +53,7 @@ object frmStringPointerScan: TfrmStringPointerScan AnchorSideRight.Side = asrBottom Left = 20 Height = 23 - Top = 330 + Top = 349 Width = 164 Anchors = [akTop, akLeft, akRight] BorderSpacing.Right = 4 @@ -66,7 +66,7 @@ object frmStringPointerScan: TfrmStringPointerScan AnchorSideTop.Side = asrBottom Left = 20 Height = 19 - Top = 311 + Top = 330 Width = 89 Caption = 'Must be start' Enabled = False @@ -78,7 +78,7 @@ object frmStringPointerScan: TfrmStringPointerScan AnchorSideTop.Side = asrBottom Left = 20 Height = 19 - Top = 292 + Top = 311 Width = 93 Caption = 'Case sensitive' Enabled = False @@ -86,11 +86,11 @@ object frmStringPointerScan: TfrmStringPointerScan end object cbRegExp: TCheckBox AnchorSideLeft.Control = rbStringscan - AnchorSideTop.Control = rbStringscan + AnchorSideTop.Control = cbReuseStringmap AnchorSideTop.Side = asrBottom Left = 20 Height = 19 - Top = 273 + Top = 292 Width = 164 BorderSpacing.Left = 16 BorderSpacing.Right = 4 @@ -116,7 +116,7 @@ object frmStringPointerScan: TfrmStringPointerScan AnchorSideTop.Side = asrBottom Left = 4 Height = 19 - Top = 353 + Top = 372 Width = 71 Caption = 'Data scan' OnChange = rbDatascanChange @@ -130,7 +130,7 @@ object frmStringPointerScan: TfrmStringPointerScan AnchorSideRight.Side = asrBottom Left = 20 Height = 23 - Top = 387 + Top = 406 Width = 164 Anchors = [akTop, akLeft, akRight] BorderSpacing.Right = 4 @@ -144,7 +144,7 @@ object frmStringPointerScan: TfrmStringPointerScan AnchorSideTop.Side = asrBottom Left = 20 Height = 15 - Top = 372 + Top = 391 Width = 47 BorderSpacing.Left = 16 Caption = 'Alignsize' @@ -212,7 +212,7 @@ object frmStringPointerScan: TfrmStringPointerScan AnchorSideTop.Side = asrBottom Left = 20 Height = 15 - Top = 330 + Top = 349 Width = 34 Caption = 'String:' Enabled = False @@ -374,19 +374,19 @@ object frmStringPointerScan: TfrmStringPointerScan AnchorSideBottom.Control = Panel1 AnchorSideBottom.Side = asrBottom Left = 0 - Height = 41 - Top = 449 + Height = 22 + Top = 468 Width = 188 Anchors = [akTop, akLeft, akRight, akBottom] AutoSize = True BevelOuter = bvNone - ClientHeight = 41 + ClientHeight = 22 ClientWidth = 188 TabOrder = 13 object lblInfo: TLabel Left = 0 Height = 15 - Top = 26 + Top = 7 Width = 188 Align = alBottom Caption = 'Info' @@ -401,19 +401,22 @@ object frmStringPointerScan: TfrmStringPointerScan AnchorSideRight.Side = asrBottom Left = 0 Height = 39 - Top = 410 + Top = 429 Width = 188 Anchors = [akTop, akLeft, akRight] AutoSize = True BevelOuter = bvNone + ChildSizing.LeftRightSpacing = 8 + ChildSizing.HorizontalSpacing = 8 + ChildSizing.EnlargeHorizontal = crsHomogenousSpaceResize + ChildSizing.Layout = cclLeftToRightThenTopToBottom + ChildSizing.ControlsPerLine = 2 ClientHeight = 39 ClientWidth = 188 TabOrder = 14 object btnNewScan: TButton - AnchorSideLeft.Control = Panel9 AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = Panel9 - Left = 54 + Left = 10 Height = 25 Top = 7 Width = 80 @@ -427,10 +430,8 @@ object frmStringPointerScan: TfrmStringPointerScan Visible = False end object btnScan: TButton - AnchorSideLeft.Control = Panel9 AnchorSideLeft.Side = asrCenter - AnchorSideTop.Control = Panel9 - Left = 54 + Left = 100 Height = 25 Top = 7 Width = 80 @@ -445,6 +446,20 @@ object frmStringPointerScan: TfrmStringPointerScan TabOrder = 1 end end + object cbReuseStringmap: TCheckBox + AnchorSideLeft.Control = rbStringscan + AnchorSideTop.Control = rbStringscan + AnchorSideTop.Side = asrBottom + Left = 20 + Height = 19 + Top = 273 + Width = 139 + BorderSpacing.Left = 16 + Caption = 'Use existing stringmap' + Checked = True + State = cbChecked + TabOrder = 15 + end end object Panel2: TPanel Left = 188 diff --git a/Cheat Engine/frmStringPointerScanUnit.lrt b/Cheat Engine/frmStringPointerScanUnit.lrt index a73116f829..012ac77f6b 100644 --- a/Cheat Engine/frmStringPointerScanUnit.lrt +++ b/Cheat Engine/frmStringPointerScanUnit.lrt @@ -27,6 +27,7 @@ TFRMSTRINGPOINTERSCAN.LBLMAXLEVEL.CAPTION=Max Level TFRMSTRINGPOINTERSCAN.LBLINFO.CAPTION=Info TFRMSTRINGPOINTERSCAN.BTNNEWSCAN.CAPTION=New Scan TFRMSTRINGPOINTERSCAN.BTNSCAN.CAPTION=Scan +TFRMSTRINGPOINTERSCAN.CBREUSESTRINGMAP.CAPTION=Use existing stringmap TFRMSTRINGPOINTERSCAN.LBLEXTRA.CAPTION=Compare against TFRMSTRINGPOINTERSCAN.CBHASSHADOW2.HINT=Use this if you're spidering a previously saved memory region that currently resides in a different location. Most commonly used for stacks where stack pointers point to it's own structure diff --git a/Cheat Engine/frmStringPointerScanUnit.pas b/Cheat Engine/frmStringPointerScanUnit.pas index 7553ad5509..e1587710c2 100644 --- a/Cheat Engine/frmStringPointerScanUnit.pas +++ b/Cheat Engine/frmStringPointerScanUnit.pas @@ -221,6 +221,7 @@ TfrmStringPointerScan = class(TForm) cbRegExp: TCheckBox; cbPointerInRange: TCheckBox; cbMapPointerValues: TCheckBox; + cbReuseStringmap: TCheckBox; comboCompareType: TComboBox; comboType: TComboBox; edtBase: TEdit; @@ -320,7 +321,7 @@ TfrmStringPointerScan = class(TForm) function pointerCompare(Tree: TAvgLvlTree; Data1, Data2: Pointer): integer; procedure cleanup; procedure OpenPointerfile(filename: string); - procedure scanDone(var m: tmessage); message wm_sps_done; + procedure scanDone; function getStringFromPointer(address: ptruint; offsets: TDwordArray; level, bytesize: integer; unicode: boolean; var a: ptruint): string; procedure setGUIStateEnabled(state: boolean); @@ -635,7 +636,8 @@ function TRescan.checkByte(p: PPointerRecord): boolean; v:=pointerfilereader.getByteFromAddress(a, error); result:=not error; - if result and (diffkind<>dkDontCare) then + + if result and (address2<>0) then begin a:=pointerfilereader.getAddressFromPointerRecord(p, address2, shadow2, shadowsize2); if a<>0 then @@ -643,7 +645,7 @@ function TRescan.checkByte(p: PPointerRecord): boolean; v2:=pointerfilereader.getByteFromAddress(a, error); result:=not error; - if result then + if result and (diffkind<>dkDontcare) then begin if diffkind=dkMustBeDifferent then result:=v<>v2 @@ -670,7 +672,7 @@ function TRescan.checkWord(p: PPointerRecord): boolean; v:=pointerfilereader.getWordFromAddress(a, error); result:=not error; - if result and (diffkind<>dkDontCare) then + if result and (address2<>0) then begin a:=pointerfilereader.getAddressFromPointerRecord(p, address2, shadow2, shadowsize2); if a<>0 then @@ -678,7 +680,7 @@ function TRescan.checkWord(p: PPointerRecord): boolean; v2:=pointerfilereader.getWordFromAddress(a, error); result:=not error; - if result then + if result and (diffkind<>dkDontCare) then begin if diffkind=dkMustBeDifferent then result:=v<>v2 @@ -705,7 +707,7 @@ function TRescan.checkDWord(p: PPointerRecord): boolean; v:=pointerfilereader.getDwordFromAddress(a, error); result:=not error; - if result and (diffkind<>dkDontCare) then + if result and (address2<>0) then begin a:=pointerfilereader.getAddressFromPointerRecord(p, address2, shadow2, shadowsize2); if a<>0 then @@ -713,7 +715,7 @@ function TRescan.checkDWord(p: PPointerRecord): boolean; v2:=pointerfilereader.getDwordFromAddress(a, error); result:=not error; - if result then + if result and (diffkind<>dkDontCare) then begin if diffkind=dkMustBeDifferent then result:=v<>v2 @@ -740,7 +742,7 @@ function TRescan.checkQWord(p: PPointerRecord): boolean; v:=pointerfilereader.getQwordFromAddress(a, error); result:=not error; - if result and (diffkind<>dkDontCare) then + if result and (address2<>0) then begin a:=pointerfilereader.getAddressFromPointerRecord(p, address2, shadow2, shadowsize2); if a<>0 then @@ -748,7 +750,7 @@ function TRescan.checkQWord(p: PPointerRecord): boolean; v2:=pointerfilereader.getQwordFromAddress(a, error); result:=not error; - if result then + if result and (diffkind<>dkDontCare) then begin if diffkind=dkMustBeDifferent then result:=v<>v2 @@ -775,7 +777,7 @@ function TRescan.checkSingle(p: PPointerRecord): boolean; v:=pointerfilereader.getSingleFromAddress(a, error); result:=not error; - if result and (diffkind<>dkDontCare) then + if result and (address2<>0) then begin a:=pointerfilereader.getAddressFromPointerRecord(p, address2, shadow2, shadowsize2); if a<>0 then @@ -783,7 +785,7 @@ function TRescan.checkSingle(p: PPointerRecord): boolean; v2:=pointerfilereader.getSingleFromAddress(a, error); result:=not error; - if result then + if result and (diffkind<>dkDontCare) then begin if diffkind=dkMustBeDifferent then result:=v<>v2 @@ -810,7 +812,7 @@ function TRescan.checkDouble(p: PPointerRecord): boolean; v:=pointerfilereader.getDoubleFromAddress(a, error); result:=not error; - if result and (diffkind<>dkDontCare) then + if result and (address2<>0) then begin a:=pointerfilereader.getAddressFromPointerRecord(p, address2, shadow2, shadowsize2); if a<>0 then @@ -818,7 +820,7 @@ function TRescan.checkDouble(p: PPointerRecord): boolean; v2:=pointerfilereader.getDoubleFromAddress(a, error); result:=not error; - if result then + if result and (diffkind<>dkDontCare) then begin if diffkind=dkMustBeDifferent then result:=v<>v2 @@ -845,7 +847,7 @@ function TRescan.checkPointer(p: PPointerRecord): boolean; v:=pointerfilereader.getPointerFromAddress(a, error); result:=not error; - if result and (diffkind<>dkDontCare) then + if result and (address2<>0) then begin a:=pointerfilereader.getAddressFromPointerRecord(p, address2, shadow2, shadowsize2); if a<>0 then @@ -853,7 +855,7 @@ function TRescan.checkPointer(p: PPointerRecord): boolean; v2:=pointerfilereader.getPointerFromAddress(a, error); result:=not error; - if result then + if result and (diffkind<>dkDontCare) then begin if diffkind=dkMustBeDifferent then result:=v<>v2 @@ -933,20 +935,28 @@ procedure TRescan.execute; passed:=false; - if passed and (diffkind<>dkDontCare) then + if passed and (address2<>0) then begin s2:=pointerfilereader.getStringFromPointerRecord(p, address2, shadow2, shadowsize2); - if diffkind=dkMustBeDifferent then - passed:=s<>s2 + if (s2<>'') then + begin + if (diffkind<>dkDontCare) then + begin + if diffkind=dkMustBeDifferent then + passed:=s<>s2 + else + passed:=s=s2; + end; + end else - passed:=s=s2; + passed:=false; if (passed) and (regex<>nil) then begin index:=0; len:=0; - passed:=RegExprPos(regex, pchar(s), index, len); + passed:=RegExprPos(regex, pchar(s2), index, len); if passed and mustbestart then passed:=index=0; @@ -980,10 +990,12 @@ procedure TRescan.execute; if pointerfilereader<>nil then freeandnil(pointerfilereader); - deletefile(outputfilename); - RenameFileUTF8(outputfilename+'.temp', outputfilename); + if deletefile(outputfilename)=false then + OutputDebugString('Failure deleting '+outputfilename); - PostMessage(ownerFrmStringPointerScan.Handle, wm_sps_done, 0,0); + RenameFile(outputfilename+'.temp', outputfilename); + + Queue(TfrmStringPointerScan(ownerFrmStringPointerScan).scandone); end; @@ -1031,7 +1043,7 @@ constructor TRescan.create(suspended: boolean; address, address2: ptruint; mustb end; end; - deletefile(outputfilename+'.temp'); + outputfile:=TFileStream.Create(outputfilename+'.temp', fmCreate or fmShareDenyNone); outputfile.Free; //so it can be reopened by other processes @@ -1448,9 +1460,13 @@ function TScanner.comparePath(level: integer; path: tpointerpath; stringsize: in if value[0]=0 then exit; //marked as unreadable if value2[0]=0 then exit; // " " " + if diffkind=dkDontCare then exit(true); + value:=@value[1]; value2:=@value2[1]; + + if address=address2 then begin result:=diffkind=dkMustBeSame; @@ -1476,7 +1492,7 @@ function TScanner.comparePath(level: integer; path: tpointerpath; stringsize: in function TScanner.addStringPath(level: integer; path: tpointerpath; stringsize: integer; unicode: BOOL): boolean; begin result:=false; - if (diffkind<>dkDontCare) and (not comparePath(level, path, stringsize)) then exit; + if (baseaddress2<>0) and (not comparePath(level, path, stringsize)) then exit; results.WriteBuffer(level, sizeof(level)); @@ -1615,7 +1631,7 @@ procedure TScanner.execute; finally //reached the end, tell the main thread that the scan is done - PostMessage(OwnerFrmStringPointerScan.Handle, wm_sps_done, 0,0); + Queue(TfrmStringPointerScan(ownerFrmStringPointerScan).scandone); end; end; @@ -1644,7 +1660,7 @@ constructor TScanner.create(isDataScan, mustbeinregion: boolean; alignment: inte self.ownerFrmStringPointerScan:=ownerFrmStringPointerScan; - if diffkind<>dkDontCare then + //if diffkind<>dkDontCare then begin case vartype of vtString: variablesize:=8; //string @@ -1855,7 +1871,7 @@ procedure TfrmStringPointerScan.OpenPointerfile(filename: string); btnScan.tag:=1; end; -procedure TfrmStringPointerScan.scanDone(var m: tmessage); +procedure TfrmStringPointerScan.scanDone; begin if scanner<>nil then lblInfo.caption:=rsSPSUFound+inttostr(scanner.count); @@ -1975,17 +1991,10 @@ procedure TfrmStringPointerScan.btnScanClick(Sender: TObject); oldpointerfile: string; begin + vartype:=vtPointer; if (scanner=nil) and (rescanner=nil) then begin - if pointerfilereader<>nil then - oldpointerfile:=pointerfilereader.filename - else - oldpointerfile:=''; - - cleanup; - - baseaddress:=symhandler.getAddressFromName(edtBase.text); baseaddress2:=0; @@ -1998,7 +2007,6 @@ procedure TfrmStringPointerScan.btnScanClick(Sender: TObject); pointerstop:=0; alignsize:=4; - if cbHasShadow.checked then begin shadow:=symhandler.getAddressFromName(edtShadowAddress.text); @@ -2022,8 +2030,6 @@ procedure TfrmStringPointerScan.btnScanClick(Sender: TObject); shadow2:=symhandler.getAddressFromName(edtShadowAddress2.text); shadowsize2:=strtoint(edtShadowSize2.text); end; - - end; if rbDatascan.checked then @@ -2039,6 +2045,17 @@ procedure TfrmStringPointerScan.btnScanClick(Sender: TObject); if savedialog1.execute then begin + if pointerfilereader<>nil then + oldpointerfile:=pointerfilereader.filename + else + oldpointerfile:=''; + + cleanup; + + + + + //we got till this point so everything is fine, disable the gui disableGui; @@ -2050,20 +2067,23 @@ procedure TfrmStringPointerScan.btnScanClick(Sender: TObject); else diffkind:=dkDontCare; - if diffkind<>dkDontCare then - begin - case comboCompareType.itemindex of - 0: vartype:=vtString; - 1: vartype:=vtByte; - 2: vartype:=vtWord; - 3: vartype:=vtDword; - 4: vartype:=vtQword; - 5: vartype:=vtSingle; - 6: vartype:=vtDouble; - 7: vartype:=vtPointer; - end; + if diffkind=dkDontCare then + vartype:=vtByte + else + case comboCompareType.itemindex of + 0: vartype:=vtString; + 1: vartype:=vtByte; + 2: vartype:=vtWord; + 3: vartype:=vtDword; + 4: vartype:=vtQword; + 5: vartype:=vtSingle; + 6: vartype:=vtDouble; + 7: vartype:=vtPointer; end; + if rbStringscan.checked then + vartype:=vtString; + if btnScan.tag=0 then //first scan begin mappedRegions:=TAvgLvlTree.CreateObjectCompare(mapCompare); @@ -2074,20 +2094,27 @@ procedure TfrmStringPointerScan.btnScanClick(Sender: TObject); if rbStringscan.checked then begin + vartype:=vtString; + + if (frmStringMap<>nil) and (cbReuseStringmap.checked=false) then + freeandnil(frmStringMap); + if frmStringMap=nil then + begin frmStringMap:=tfrmStringMap.Create(application); - //fill the stringmap + //fill the stringmap + frmstringmap.cbRegExp.checked:=cbRegExp.checked; + frmstringmap.cbCaseSensitive.checked:=cbCaseSensitive.checked; + frmstringmap.cbMustBeStart.checked:=cbMustBeStart.checked; + frmstringmap.edtRegExp.text:=edtRegExp.text; - frmstringmap.cbRegExp.checked:=cbRegExp.checked; - frmstringmap.cbCaseSensitive.checked:=cbCaseSensitive.checked; - frmstringmap.cbMustBeStart.checked:=cbMustBeStart.checked; - frmstringmap.edtRegExp.text:=edtRegExp.text; + frmstringmap.btnScan.click; + lblInfo.caption:=rsGeneratingStringmap; + lblInfo.Repaint; + frmstringmap.scanner.WaitFor; - frmstringmap.btnScan.click; - lblInfo.caption:=rsGeneratingStringmap; - lblInfo.Repaint; - frmstringmap.scanner.WaitFor; + end; end; lblInfo.caption:=rsGeneratedScanning; @@ -2102,12 +2129,8 @@ procedure TfrmStringPointerScan.btnScanClick(Sender: TObject); else begin //next scan aka Rescan - pointerfilereader:=TPointerfileReader.create(oldpointerfile); - pointerfilereader.vartype:=vartype; - listview1.items.count:=0; rescanner:=trescan.create(false, address, address2, cbpointerinrange.checked, pointerstart, pointerstop, rbStringscan.checked, cbCaseSensitive.checked, cbMustBeStart.checked, edtRegExp.text, diffkind, vartype, oldpointerfile, savedialog1.filename , self); - end; btnScan.caption:=rsStop; btnScan.enabled:=true;