2011-07-04 19:52:53 +00:00
unit FoundCodeUnit;
{$MODE Delphi}
interface
uses
2019-12-18 12:07:17 +01:00
{$ifdef darwin}
macport, math,
{$endif}
{$ifdef windows}
windows,
{$endif}
LCLIntf, LResources, Messages, SysUtils, Variants, Classes, Graphics,
2011-07-04 19:52:53 +00:00
Controls, Forms, Dialogs, StdCtrls, disassembler, ExtCtrls, Menus,
2018-03-28 21:18:37 +02:00
NewKernelHandler, clipbrd, ComCtrls, fgl, formChangedAddresses, LastDisassembleData,
2022-08-15 23:51:27 +02:00
vmxfunctions, betterControls, Maps, syncobjs, contexthandler;
2011-07-04 19:52:53 +00:00
2013-06-06 23:53:32 +00:00
type
Tcoderecord = class
2020-10-22 13:54:51 +02:00
private
fhitcount: integer ;
2022-08-15 23:51:27 +02:00
fcontext: pointer ;
contexthandler: TContextInfo;
2022-08-29 12:04:35 +02:00
function getContext: pointer ;
2022-08-15 23:51:27 +02:00
procedure setContext( ctx: Pointer ) ;
2020-10-22 13:54:51 +02:00
procedure setHitcount( c: integer ) ;
2011-07-04 19:52:53 +00:00
public
2020-10-22 13:54:51 +02:00
firstSeen: TDateTime;
lastSeen: TDateTime;
2020-08-21 20:00:21 +02:00
addressString: string ;
2011-07-04 19:52:53 +00:00
address: ptrUint;
size: integer ;
opcode: string ;
description: string ;
2022-08-15 23:51:27 +02:00
2011-07-04 19:52:53 +00:00
stack: record
2014-05-11 03:08:36 +00:00
savedsize: ptruint;
2011-07-04 19:52:53 +00:00
stack: pbyte ;
end ;
2018-03-28 21:18:37 +02:00
2022-09-22 00:48:23 +02:00
ipt: record
log: pointer ;
size: integer ;
end ;
2018-03-28 21:18:37 +02:00
dbvmcontextbasic: PPageEventBasic;
2020-10-22 13:54:51 +02:00
2013-06-06 23:53:32 +00:00
diffcount: integer ;
2013-09-23 21:48:43 +00:00
LastDisassembleData: TLastDisassembleData;
2013-06-06 23:53:32 +00:00
formChangedAddresses: TfrmChangedAddresses;
2020-10-22 13:54:51 +02:00
property hitcount: integer read fhitcount write setHitcount;
2022-08-29 12:04:35 +02:00
property context: pointer read getContext write setContext;
2011-07-04 19:52:53 +00:00
procedure savestack;
2018-06-11 15:36:17 +02:00
constructor create;
2011-07-04 19:52:53 +00:00
destructor destroy; override ;
end ;
type
{ TFoundCodeDialog }
2018-03-28 21:18:37 +02:00
TFoundCodeDialog= class ;
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2018-03-28 21:18:37 +02:00
TDBVMWatchPollThread= class( TThread)
private
results: PPageEventListDescriptor;
resultsize: integer ;
cr3disassembler: Tcr3Disassembler;
procedure addEntriesToList;
public
id: integer ;
2021-09-27 09:03:37 +02:00
fcd: TFoundCodeDialog;
2018-03-28 21:18:37 +02:00
procedure execute; override ;
end ;
2019-12-18 12:07:17 +01:00
{$endif}
2011-07-04 19:52:53 +00:00
2013-06-06 23:53:32 +00:00
2011-07-04 19:52:53 +00:00
TFoundCodeDialog = class( TForm)
FoundCodeList: TListView;
2019-05-13 20:28:29 +02:00
fcdImageList: TImageList;
2020-03-18 21:12:33 +01:00
dbvmMissedEntries: TLabel;
2013-05-04 21:58:14 +00:00
MenuItem1: TMenuItem;
MenuItem2: TMenuItem;
2021-08-10 15:34:32 +02:00
miFindWhatCodeAccesses: TMenuItem;
MenuItem4: TMenuItem;
2013-06-06 23:53:32 +00:00
miFindWhatAccesses: TMenuItem;
2013-05-04 21:58:14 +00:00
miSaveTofile: TMenuItem;
2011-07-04 19:52:53 +00:00
mInfo: TMemo;
Panel1: TPanel;
Description: TLabel;
Panel4: TPanel;
pmOptions: TPopupMenu;
ReplacewithcodethatdoesnothingNOP1: TMenuItem;
2013-05-04 21:58:14 +00:00
SaveDialog1: TSaveDialog;
2011-07-04 19:52:53 +00:00
Showthisaddressinthedisassembler1: TMenuItem;
Addtothecodelist1: TMenuItem;
MoreInfo1: TMenuItem;
Panel2: TPanel;
btnOK: TButton;
Panel3: TPanel;
btnExtraInfo: TButton;
btnAddToCodeList: TButton;
btnOpenDisassembler: TButton;
btnReplacewithnops: TButton;
N1: TMenuItem;
Copyselectiontoclipboard1: TMenuItem;
Splitter1: TSplitter;
2021-05-04 14:49:20 +02:00
timerEntryInfoUpdate: TTimer;
2011-07-04 19:52:53 +00:00
procedure FormCreate( Sender: TObject) ;
procedure FormDeactivate( Sender: TObject) ;
procedure FormDestroy( Sender: TObject) ;
2016-08-12 23:17:36 +02:00
procedure FormShow( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
procedure FoundCodeListChange( Sender: TObject; Item: TListItem;
Change: TItemChange) ;
procedure FoundcodeListClick( Sender: TObject) ;
procedure btnOKClick( Sender: TObject) ;
procedure FormClose( Sender: TObject; var Action: TCloseAction) ;
procedure btnReplacewithnopsClick( Sender: TObject) ;
procedure btnOpenDisassemblerClick( Sender: TObject) ;
procedure btnAddToCodeListClick( Sender: TObject) ;
2020-01-09 01:26:41 +01:00
procedure FoundCodeListColumnClick( Sender: TObject; Column: TListColumn) ;
2011-07-04 19:52:53 +00:00
procedure FoundcodeListDblClick( Sender: TObject) ;
procedure btnExtraInfoClick( Sender: TObject) ;
procedure FormCloseQuery( Sender: TObject; var CanClose: Boolean ) ;
procedure FoundCodeListSelectItem( Sender: TObject; Item: TListItem;
Selected: Boolean ) ;
2013-05-04 21:58:14 +00:00
procedure MenuItem1Click( Sender: TObject) ;
2013-06-06 23:53:32 +00:00
procedure miFindWhatAccessesClick( Sender: TObject) ;
2021-08-10 15:34:32 +02:00
procedure miFindWhatCodeAccessesClick( Sender: TObject) ;
2013-05-04 21:58:14 +00:00
procedure miSaveTofileClick( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
procedure pmOptionsPopup( Sender: TObject) ;
procedure Copyselectiontoclipboard1Click( Sender: TObject) ;
2021-05-04 14:49:20 +02:00
procedure timerEntryInfoUpdateTimer( Sender: TObject) ;
2011-07-04 19:52:53 +00:00
private
{ Private declarations }
2022-08-29 23:26:02 +02:00
loadedPosition: boolean ;
2017-04-06 15:24:56 +02:00
setcountwidth: boolean ;
2023-10-20 17:32:15 +02:00
fdebuggerinterfacewatchid: integer ;
2019-12-18 12:07:17 +01:00
{$ifdef windows}
2018-03-28 21:18:37 +02:00
dbvmwatchpollthread: TDBVMWatchPollThread;
2019-12-18 12:07:17 +01:00
{$endif}
2018-06-11 15:36:17 +02:00
usedmiFindWhatAccesses: boolean ; //debug
2020-01-09 01:26:41 +01:00
countsortdirection: integer ;
addresssortdirection: integer ;
2018-03-28 21:18:37 +02:00
procedure stopdbvmwatch;
2011-07-04 19:52:53 +00:00
procedure addInfo( Coderecord: TCoderecord) ;
procedure moreinfo;
2013-05-04 21:58:14 +00:00
function getSelection: string ;
2023-10-20 17:32:15 +02:00
procedure setdebuggerinterfacewatchid( id: integer ) ;
2021-08-22 12:50:43 +02:00
procedure ChangedAddressClose( Sender: TObject; var CloseAction: TCloseAction) ;
2011-07-04 19:52:53 +00:00
public
{ Public declarations }
2013-06-06 23:53:32 +00:00
addresswatched: ptruint;
2011-07-04 19:52:53 +00:00
useexceptions: boolean ;
usesdebugregs: boolean ;
2018-03-28 21:18:37 +02:00
multiplerip: boolean ;
dbvmwatch_unlock: qword;
2021-05-04 14:49:20 +02:00
addRecord_Address: ptruint;
2022-09-22 00:48:23 +02:00
iptlog: pointer ; //do not free this. owned by the debugthreadhandler
iptlogsize: integer ;
2021-05-04 14:49:20 +02:00
breakpoint: pointer ;
seenAddressListCS: TCriticalSection; //should only be accessed by the debugger thread, but just in case...
seenAddressList: TMap; //list for the debugger thread to determine if it should be added to the list
2011-07-04 19:52:53 +00:00
procedure AddRecord;
2013-06-06 23:53:32 +00:00
procedure setChangedAddressCount( address : ptruint) ;
2023-10-20 17:32:15 +02:00
property debuggerinterfacewatchid: integer read fdebuggerinterfacewatchid write setdebuggerinterfacewatchid;
2011-07-04 19:52:53 +00:00
end ;
resourcestring
strClose= 'Close' ;
2015-10-10 13:21:06 +02:00
rsFCThesWillSetASiftwareBreakpointInt3OnEverySingleOpcodeEtc = 'This will set a Software Breakpoint (int3) on every single opcode that will be reported here. Are you sure ?' ;
2011-07-04 19:52:53 +00:00
//var
// FoundCodeDialog: TFoundCodeDialog;
implementation
2014-11-07 00:29:54 +00:00
uses CEFuncProc, CEDebugger, debughelper, debugeventhandler, MemoryBrowserFormUnit,
MainUnit, kerneldebugger, AdvancedOptionsUnit , formFoundcodeListExtraUnit,
2021-03-14 16:17:30 -07:00
MainUnit2, ProcessHandlerUnit, Globals, Parsers, DBK32functions, symbolhandler,
2021-05-04 14:49:20 +02:00
DebuggerInterfaceAPIWrapper, DBVMDebuggerInterface, breakpointtypedef;
2018-03-28 21:18:37 +02:00
2019-12-18 12:07:17 +01:00
{$IFDEF windows}
2018-03-28 21:18:37 +02:00
procedure TDBVMWatchPollThread. execute;
var
i: integer ;
2018-04-03 11:39:00 +02:00
size: integer ;
2018-03-28 21:18:37 +02:00
begin
cr3disassembler: = TCR3Disassembler. create;
getmem( results, 4 0 9 6 ) ;
resultsize: = 4 0 9 6 ;
2018-04-03 11:39:00 +02:00
zeromemory( results, resultsize) ;
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
try
while not terminated do
2018-03-28 21:18:37 +02:00
begin
2018-04-03 11:39:00 +02:00
size: = resultsize;
i: = dbvm_watch_retrievelog( id, results, size) ;
if i= 0 then
2018-03-28 21:18:37 +02:00
begin
2020-09-04 22:45:47 +02:00
// OutputDebugString('TDBVMWatchPollThread returned 0');
// OutputDebugString('results^.numberOfEntries='+inttostr(results^.numberOfEntries));
// OutputDebugString('results^.maxSize='+inttostr(results^.maxSize));
2018-04-03 11:39:00 +02:00
//process data
if results^ . numberOfEntries> 0 then
begin
2020-09-04 22:45:47 +02:00
// OutputDebugString('calling addEntriesToList');
2018-04-03 11:39:00 +02:00
synchronize( addEntriesToList) ;
sleep( 1 0 ) ;
end
else
sleep( 5 0 ) ;
2018-03-28 21:18:37 +02:00
end
else
2018-04-03 11:39:00 +02:00
if i= 2 then
begin
//not enough memory. Allocate twice the needed amount
2020-09-04 22:45:47 +02:00
// outputdebugstring(inttostr(resultsize)+' is too small for the buffer. It needs to be at least '+inttostr(size));
2018-06-12 20:23:45 +02:00
freememandnil( results) ;
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
resultsize: = size* 2 ;
getmem( results, resultsize) ;
zeromemory( results, resultsize) ;
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
continue; //try again, no sleep
end else
begin
2020-09-04 22:45:47 +02:00
outputdebugstring( 'dbvm_watch_retrievelog returned ' + inttostr( i) + ' which is not supported' ) ;
2018-04-03 11:39:00 +02:00
exit;
end ;
end ;
except
on e: exception do
outputdebugstring( 'TDBVMWatchPollThread crash:' + e. Message ) ;
2018-03-28 21:18:37 +02:00
end ;
2018-06-12 20:23:45 +02:00
freememandnil( results) ;
2018-03-28 21:18:37 +02:00
freeandnil( cr3disassembler) ;
end ;
2019-12-18 12:07:17 +01:00
{$ENDIF}
2011-07-04 19:52:53 +00:00
destructor TCodeRecord. Destroy;
begin
if stack. stack< > nil then
2018-06-12 20:23:45 +02:00
freememandnil( stack. stack) ;
2022-09-22 00:48:23 +02:00
if ipt. log< > nil then
freememandnil( ipt. log) ;
2022-08-15 23:51:27 +02:00
if fcontext< > nil then
freememandnil( fcontext) ;
2011-07-04 19:52:53 +00:00
inherited destroy;
end ;
2018-06-11 15:36:17 +02:00
constructor TCodeRecord. create;
begin
formChangedAddresses: = nil ;
2020-10-22 13:54:51 +02:00
firstseen: = now;
2018-06-11 15:36:17 +02:00
end ;
2019-12-18 12:07:17 +01:00
{$IFDEF windows}
2018-03-28 21:18:37 +02:00
procedure TDBVMWatchPollThread. addEntriesToList;
var
coderecord: TCodeRecord;
2022-08-15 23:51:27 +02:00
c: pcontext;
2018-03-28 21:18:37 +02:00
i, j: integer ;
opcode, desc: string ;
li: TListItem;
ldi: TLastDisassembleData;
basicinfo: TPageEventBasic;
basic: PPageEventBasicArray;
extended : PPageEventExtendedArray absolute basic;
basics: PPageEventBasicWithStackArray absolute basic;
extendeds: PPageEventExtendedWithStackArray absolute basic;
2018-05-02 23:20:35 +02:00
address, address2: ptruint;
2018-03-28 21:18:37 +02:00
skip: boolean ;
2018-04-03 11:39:00 +02:00
debug, debug2: pointer ;
2022-08-29 12:04:35 +02:00
2018-03-28 21:18:37 +02:00
begin
2018-04-03 11:39:00 +02:00
outputdebugstring( 'addEntriesToList' ) ;
2018-03-28 21:18:37 +02:00
2020-03-18 21:12:33 +01:00
if results^ . missedEntries> 0 then
begin
fcd. dbvmMissedEntries. caption: = string . format( rsDBVMMissedEntries, [ results^ . missedEntries] ) ;
if fcd. dbvmMissedEntries. visible= false then
fcd. dbvmMissedEntries. visible: = true ;
end ;
2018-04-03 11:39:00 +02:00
try
basic: = PPageEventBasicArray( ptruint( results) + sizeof( TPageEventListDescriptor) ) ;
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
for i: = 0 to results^ . numberOfEntries- 1 do
2018-03-28 21:18:37 +02:00
begin
2019-02-24 00:13:58 +01:00
2018-04-03 11:39:00 +02:00
case results^ . entryType of
0 : basicinfo: = basic^ [ i] ;
1 : basicinfo: = extended ^ [ i] . basic;
2 : basicinfo: = basics^ [ i] . basic;
3 : basicinfo: = extendeds^ [ i] . basic;
end ;
address: = basicinfo. RIP;
2019-02-24 00:13:58 +01:00
outputdebugstring( 'testing entry ' + inttostr( i) + '(' + inttohex( address, 8 ) + ') - basicinfo.Count=' + inttostr( basicinfo. Count+ 1 ) ) ;
2018-04-03 11:39:00 +02:00
//check if this address is inside the list
skip: = false ;
for j: = 0 to fcd. foundcodelist. Items. Count- 1 do
2018-03-28 21:18:37 +02:00
begin
2018-04-03 11:39:00 +02:00
if TCodeRecord( fcd. foundcodelist. Items[ j] . data) . address= address then
2018-03-28 21:18:37 +02:00
begin
2018-04-03 11:39:00 +02:00
//it's already in the list
if fcd. multiplerip= false then
2018-03-28 21:18:37 +02:00
begin
2019-02-24 00:13:58 +01:00
OutputDebugString( inttostr( j) + ':Already in the list' ) ;
TCodeRecord( fcd. foundcodelist. Items[ j] . data) . hitcount: = TCodeRecord( fcd. foundcodelist. Items[ j] . data) . hitcount+ ( basicinfo. Count+ 1 ) ;
2018-03-28 21:18:37 +02:00
skip: = true ;
2019-02-21 22:27:47 +01:00
fcd. foundcodelist. Items[ j] . caption: = inttostr( TCodeRecord( fcd. foundcodelist. Items[ j] . data) . hitcount) ;
2018-03-28 21:18:37 +02:00
break;
2018-04-03 11:39:00 +02:00
end
else
begin
//check the other registers
if ( basicinfo. RAX= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . RAX) and
( basicinfo. RBX= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . RBX) and
( basicinfo. RCX= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . RCX) and
( basicinfo. RDX= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . RDX) and
( basicinfo. RSP= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . RSP) and
( basicinfo. RBP= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . RBP) and
( basicinfo. RSI= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . RSI) and
( basicinfo. RDI= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . RDI) and
( basicinfo. R8= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . R8) and
( basicinfo. R9= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . R9) and
( basicinfo. R10= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . R10) and
( basicinfo. R11= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . R11) and
( basicinfo. R12= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . R12) and
( basicinfo. R13= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . R13) and
( basicinfo. R14= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . R14) and
( basicinfo. R15= TCodeRecord( fcd. foundcodelist. Items[ j] . data) . dbvmcontextbasic^ . R15) THEN
begin
2020-10-22 13:54:51 +02:00
TCodeRecord( fcd. foundcodelist. Items[ j] . data) . hitcount: = TCodeRecord( fcd. foundcodelist. Items[ j] . data) . hitcount+ basicinfo. count;
2018-04-03 11:39:00 +02:00
skip: = true ;
break;
end ;
2018-03-28 21:18:37 +02:00
end ;
end ;
end ;
2018-04-03 11:39:00 +02:00
if skip then
begin
OutputDebugString( 'Skipping entry. it' 's in the list' ) ;
continue;
end
else
OutputDebugString( 'Not in the list yet. Adding it' ) ;
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
coderecord: = TCoderecord. create;
getmem( coderecord. dbvmcontextbasic, sizeof( TPageEventBasicArray) ) ;
2022-08-29 12:04:35 +02:00
c: = coderecord. context;
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
coderecord. dbvmcontextbasic^ : = basicinfo;
2018-03-28 21:18:37 +02:00
2022-08-29 12:04:35 +02:00
2022-08-15 23:51:27 +02:00
2018-04-03 11:39:00 +02:00
outputdebugstring( 'created coderecord and dbvmcontextbasic' ) ;
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
case results^ . entryType of
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
0 : ; //already done
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
1 : //extended
begin
2022-08-15 23:51:27 +02:00
copymemory( @ c^ . {$ifdef cpu64} FltSave{$else} ext{$endif} , @ extended ^ [ i] . fpudata, sizeof( c^ . {$ifdef cpu64} FltSave{$else} ext{$endif} ) ) ;
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
end ;
2018-03-28 21:18:37 +02:00
2018-04-03 11:39:00 +02:00
2 : //basic with stack
begin
coderecord. stack. savedsize: = 4 0 9 6 ;
getmem( coderecord. stack. stack, 4 0 9 6 ) ;
copymemory( coderecord. stack. stack, @ basics^ [ i] . stack[ 0 ] , 4 0 9 6 ) ;
end ;
3 : //extended with stack
begin
2022-08-15 23:51:27 +02:00
copymemory( @ c^ . {$ifdef cpu64} FltSave{$else} ext{$endif} , @ extendeds^ [ i] . fpudata, sizeof( c^ . {$ifdef cpu64} FltSave{$else} ext{$endif} ) ) ;
2018-04-03 11:39:00 +02:00
coderecord. stack. savedsize: = 4 0 9 6 ;
getmem( coderecord. stack. stack, 4 0 9 6 ) ;
copymemory( coderecord. stack. stack, @ basics^ [ i] . stack[ 0 ] , 4 0 9 6 ) ;
end ;
else
begin
//error
outputdebugstring( 'unexpected type' ) ;
2018-06-12 20:23:45 +02:00
freememandnil( coderecord. dbvmcontextbasic) ;
2018-04-03 11:39:00 +02:00
freeandnil( coderecord) ;
exit;
end ;
end ;
address: = coderecord. dbvmcontextbasic^ . RIP;
address2: = address;
cr3disassembler. cr3: = coderecord. dbvmcontextbasic^ . CR3;
outputdebugstring( format( 'disassembling %.8x with CR3 %.8x: ' , [ address, cr3disassembler. cr3] ) ) ;
opcode: = cr3disassembler. disassemble( address2, desc) ;
ldi: = cr3disassembler. LastDisassembleData;
outputdebugstring( 'opcode=' + opcode) ;
coderecord. address: = address;
coderecord. size: = address2- address;
coderecord. opcode: = opcode;
coderecord. description: = desc;
coderecord. LastDisassembleData: = ldi;
coderecord. hitcount: = coderecord. dbvmcontextbasic^ . Count;
//make compatible with older code:
OutputDebugString( 'setting up compatibility context' ) ;
2022-08-15 23:51:27 +02:00
c^ . {$ifdef cpu64} Rax{$else} Eax{$endif} : = coderecord. dbvmcontextbasic^ . RAX;
c^ . {$ifdef cpu64} Rbx{$else} Ebx{$endif} : = coderecord. dbvmcontextbasic^ . RBX;
c^ . {$ifdef cpu64} Rcx{$else} Ecx{$endif} : = coderecord. dbvmcontextbasic^ . RCX;
c^ . {$ifdef cpu64} Rdx{$else} Edx{$endif} : = coderecord. dbvmcontextbasic^ . RDX;
c^ . {$ifdef cpu64} Rsi{$else} Esi{$endif} : = coderecord. dbvmcontextbasic^ . RSI;
c^ . {$ifdef cpu64} Rdi{$else} Edi{$endif} : = coderecord. dbvmcontextbasic^ . RDI;
c^ . {$ifdef cpu64} Rbp{$else} Ebp{$endif} : = coderecord. dbvmcontextbasic^ . RBP;
c^ . {$ifdef cpu64} Rsp{$else} Esp{$endif} : = coderecord. dbvmcontextbasic^ . Rsp;
c^ . {$ifdef cpu64} Rip{$else} Eip{$endif} : = coderecord. dbvmcontextbasic^ . Rip;
2018-05-02 23:20:35 +02:00
{$ifdef cpu64}
2022-08-15 23:51:27 +02:00
c^ . R8: = coderecord. dbvmcontextbasic^ . R8;
c^ . R9: = coderecord. dbvmcontextbasic^ . R9;
c^ . R10: = coderecord. dbvmcontextbasic^ . R10;
c^ . R11: = coderecord. dbvmcontextbasic^ . R11;
c^ . R12: = coderecord. dbvmcontextbasic^ . R12;
c^ . R13: = coderecord. dbvmcontextbasic^ . R13;
c^ . R14: = coderecord. dbvmcontextbasic^ . R14;
c^ . R15: = coderecord. dbvmcontextbasic^ . R15;
2018-05-02 23:20:35 +02:00
{$endif}
2022-08-15 23:51:27 +02:00
c^ . EFlags: = coderecord. dbvmcontextbasic^ . FLAGS;
c^ . SegCs: = coderecord. dbvmcontextbasic^ . CS;
c^ . SegSs: = coderecord. dbvmcontextbasic^ . SS;
c^ . SegDs: = coderecord. dbvmcontextbasic^ . DS;
c^ . SegEs: = coderecord. dbvmcontextbasic^ . ES;
c^ . SegFs: = coderecord. dbvmcontextbasic^ . FS;
c^ . SegGs: = coderecord. dbvmcontextbasic^ . GS;
2018-04-03 11:39:00 +02:00
2019-02-24 00:16:54 +01:00
coderecord. hitcount: = coderecord. dbvmcontextbasic^ . Count+ 1 ;
2022-06-19 10:58:16 +02:00
coderecord. diffcount: = 0 ;
2019-02-24 00:13:58 +01:00
2018-04-03 11:39:00 +02:00
OutputDebugString( 'adding to the foundlist' ) ;
li: = fcd. FoundCodeList. Items. Add;
li. caption: = '1' ;
li. SubItems. add( opcode) ;
li. data: = coderecord;
OutputDebugString( 'done with no errors' ) ;
end ;
except
on e: exception do
outputdebugstring( 'TDBVMWatchPollThread.addEntriesToList error: ' + e. message ) ;
2018-03-28 21:18:37 +02:00
end ;
end ;
2019-12-18 12:07:17 +01:00
{$ENDIF}
2018-03-28 21:18:37 +02:00
2020-10-22 13:54:51 +02:00
procedure TCodeRecord. setHitcount( c: integer ) ;
begin
fHitcount: = c;
lastSeen: = now;
end ;
2022-08-29 12:04:35 +02:00
function TCodeRecord. getContext: pointer ;
begin
if fcontext= nil then
begin
outputdebugstring( 'TCodeRecord.getContext: fContext was nil. Allocating it' ) ;
contexthandler: = getBestContextHandler;
fcontext: = getmem( contexthandler. ContextSize) ;
ZeroMemory( fcontext, contexthandler. ContextSize) ;
end ;
result : = fcontext;
end ;
2022-08-15 23:51:27 +02:00
procedure TCodeRecord. setContext( ctx: Pointer ) ;
begin
contexthandler: = getBestContextHandler;
fcontext: = contexthandler. getCopy( ctx) ;
end ;
2011-07-04 19:52:53 +00:00
procedure TCodeRecord. savestack;
2011-09-10 21:09:46 +00:00
var base: qword;
2011-07-04 19:52:53 +00:00
begin
getmem( stack. stack, savedStackSize) ;
2022-08-15 23:51:27 +02:00
base: = contexthandler. StackPointerRegister^ . getValue( context) ;
2011-09-10 21:09:46 +00:00
if ReadProcessMemory( processhandle, pointer( base) , stack. stack, savedStackSize, stack. savedsize) = false then
begin
//for some reason this sometimes returns 0 bytes read even if some of the bytes are readable.
stack. savedsize: = 4 0 9 6 - ( base mod 4 0 9 6 ) ;
ReadProcessMemory( processhandle, pointer( base) , stack. stack, stack. savedsize, stack. savedsize) ;
end ;
2011-07-04 19:52:53 +00:00
end ;
2021-09-27 09:03:37 +02:00
procedure TFoundCodeDialog. AddRecord;
2011-07-04 19:52:53 +00:00
{
Invoked by the debugger thread
It takes the data from the current thread and stores it in the processlist
}
var currentthread: TDebugThreadHandler;
opcode: string ;
2013-09-23 21:48:43 +00:00
ldi: TLastDisassembleData;
2011-07-04 19:52:53 +00:00
address, address2: ptrUint;
desc: string ;
coderecord: TCodeRecord;
i: integer ;
li: tlistitem;
2013-06-06 23:53:32 +00:00
f: TfrmChangedAddresses;
2013-09-23 21:48:43 +00:00
d: TDisassembler;
2011-07-04 19:52:53 +00:00
begin
2021-05-04 14:49:20 +02:00
currentthread: = debuggerthread. CurrentThread;
address: = addRecord_Address;
//disassemble to get the opcode and size
address2: = address;
d: = TDisassembler. Create;
opcode: = d. disassemble( address2, desc) ;
ldi: = d. LastDisassembleData;
freeandnil( d) ;
coderecord: = TCoderecord. create;
coderecord. address: = address;
coderecord. size: = address2- address;
coderecord. opcode: = opcode;
coderecord. description: = desc;
2023-10-20 17:32:15 +02:00
coderecord. context: = currentthread. context; //this makes a copy, so no worries about pointers
2021-05-04 14:49:20 +02:00
coderecord. LastDisassembleData: = ldi;
coderecord. savestack;
coderecord. hitcount: = 1 ;
2022-06-19 10:58:16 +02:00
coderecord. diffcount: = 0 ;
2021-05-04 14:49:20 +02:00
2023-10-20 17:32:15 +02:00
if iptlogsize< > 0 then
begin
getmem( coderecord. ipt. log, iptlogsize) ;
copymemory( coderecord. ipt. log, iptlog, iptlogsize) ;
end
else
coderecord. ipt. log: = nil ;
2022-09-22 00:48:23 +02:00
coderecord. ipt. size: = iptlogsize;
2021-05-04 14:49:20 +02:00
seenAddressListCS. Enter;
try
seenAddressList. Add( address, coderecord) ;
except
//should NEVER happen as AddRecord is only called when it's not in the list, but just to be sure...
end ;
seenAddressListCS. Leave;
2011-07-04 19:52:53 +00:00
2021-05-04 14:49:20 +02:00
li: = FoundCodeList. Items. Add;
li. caption: = '1' ;
li. SubItems. add( opcode) ;
li. data: = coderecord;
2013-09-23 21:48:43 +00:00
2021-05-04 14:49:20 +02:00
if miFindWhatAccesses. Checked then //add it
coderecord. formChangedAddresses: = debuggerthread. FindWhatCodeAccesses( address, self) ; //ffffffuuuuuuuuuu. Rebuild again
2013-06-06 23:53:32 +00:00
2021-05-04 14:49:20 +02:00
debuggerthread. guiupdate: = true ;
2011-07-04 19:52:53 +00:00
end ;
2018-03-28 21:18:37 +02:00
procedure TFoundCodeDialog. stopdbvmwatch;
begin
2019-12-18 12:07:17 +01:00
{$IFDEF windows}
2018-03-28 21:18:37 +02:00
if dbvmwatchpollthread< > nil then
begin
dbvmwatchpollthread. Terminate;
dbvmwatchpollthread. WaitFor;
freeandnil( dbvmwatchpollthread) ;
end ;
2019-12-18 12:07:17 +01:00
2023-10-20 17:32:15 +02:00
if debuggerinterfacewatchid< > - 1 then
2018-03-28 21:18:37 +02:00
begin
2023-10-20 17:32:15 +02:00
dbvm_watch_delete( debuggerinterfacewatchid) ;
debuggerinterfacewatchid: = - 1 ;
2018-03-28 21:18:37 +02:00
end ;
if dbvmwatch_unlock< > 0 then
begin
UnlockMemory( dbvmwatch_unlock) ;
dbvmwatch_unlock: = 0 ;
end ;
2019-12-18 12:07:17 +01:00
{$endif}
2018-03-28 21:18:37 +02:00
end ;
2023-10-20 17:32:15 +02:00
procedure TFoundCodeDialog. setdebuggerinterfacewatchid( id: integer ) ;
2018-03-28 21:18:37 +02:00
begin
2019-12-18 12:07:17 +01:00
{$IFDEF windows}
2023-10-20 17:32:15 +02:00
fdebuggerinterfacewatchid: = id;
2018-03-28 21:18:37 +02:00
if id< > - 1 then
begin
if dbvmwatchpollthread< > nil then
freeandnil( dbvmwatchpollthread) ;
dbvmwatchpollthread: = TDBVMWatchPollThread. Create( true ) ;
dbvmwatchpollthread. id: = id;
dbvmwatchpollthread. fcd: = self;
dbvmwatchpollthread. Start;
useexceptions: = true ;
end ;
2019-12-18 12:07:17 +01:00
{$ENDIF}
2018-03-28 21:18:37 +02:00
end ;
2013-06-06 23:53:32 +00:00
2021-09-27 09:03:37 +02:00
procedure TFoundCodeDialog. setChangedAddressCount( address : ptruint) ;
2013-06-06 23:53:32 +00:00
var i: integer ;
begin
for i: = 0 to foundcodelist. Items. Count- 1 do
if TCodeRecord( foundcodelist. Items[ i] . data) . address= address then
begin
//increase the counter
inc( TCodeRecord( foundcodelist. Items[ i] . data) . diffcount) ;
FoundcodeList. items[ i] . caption: = inttostr( TCodeRecord( foundcodelist. Items[ i] . data) . hitcount) + ' (' + inttostr( TCodeRecord( foundcodelist. Items[ i] . data) . diffcount) + ')' ;
exit;
end ;
end ;
2021-09-27 09:03:37 +02:00
procedure TFoundCodeDialog. addInfo( Coderecord: TCoderecord) ;
2011-07-04 19:52:53 +00:00
var
address: ptruint;
disassembled: array [ 1 .. 5 ] of string ;
firstchar: char ;
hexcount: integer ;
temp: string ;
2022-04-19 00:08:51 +02:00
i: integer ;
2022-08-15 23:51:27 +02:00
gplist: PContextElementRegisterList;
2011-07-04 19:52:53 +00:00
begin
if processhandler. is64Bit then
hexcount: = 1 6
else
hexcount: = 8 ;
address: = Coderecord. address;
address: = previousopcode( address) ;
address: = previousopcode( address) ;
disassembled[ 1 ] : = disassemble( address, temp) ;
disassembled[ 2 ] : = disassemble( address, temp) ;
if address< > coderecord. address then
begin
disassembled[ 1 ] : = '' ;
disassembled[ 2 ] : = '' ;
disassembled[ 3 ] : = coderecord. opcode;
disassembled[ 4 ] : = '' ;
disassembled[ 5 ] : = '' ;
end
else
begin
disassembled[ 3 ] : = disassemble( address, temp) ;
disassembled[ 4 ] : = disassemble( address, temp) ;
disassembled[ 5 ] : = disassemble( address, temp) ;
end ;
2013-06-01 16:20:57 +00:00
minfo. Lines. BeginUpdate;
try
2020-08-21 20:00:21 +02:00
if coderecord. addressString< > '' then minfo. Lines. add( coderecord. addressString+ ':' ) ;
2013-06-01 16:20:57 +00:00
minfo. Lines. Add( disassembled[ 1 ] ) ;
minfo. Lines. Add( disassembled[ 2 ] ) ;
minfo. Lines. Add( disassembled[ 3 ] + ' <<' ) ;
minfo. Lines. Add( disassembled[ 4 ] ) ;
minfo. Lines. Add( disassembled[ 5 ] ) ;
minfo. Lines. Add( '' ) ;
2013-08-13 23:12:14 +00:00
2022-08-15 23:51:27 +02:00
gplist: = coderecord. contexthandler. getGeneralPurposeRegisters;
if gplist< > nil then
for i: = 0 to length( gplist^ ) - 1 do
minfo. Lines. Add( gplist^ [ i] . name + '=' + gplist^ [ i] . getFullValueString( coderecord. context) ) ;
2011-07-04 19:52:53 +00:00
2013-06-01 16:20:57 +00:00
minfo. lines. add( '' ) ;
minfo. lines. add( '' ) ;
2011-07-04 19:52:53 +00:00
2020-10-22 13:54:51 +02:00
minfo. lines. add( 'First seen:' + TimeToStr( coderecord. firstSeen) ) ;
minfo. lines. add( 'Last seen:' + TimeToStr( coderecord. lastSeen) ) ;
2013-06-01 16:20:57 +00:00
finally
minfo. lines. EndUpdate;
end ;
2011-07-04 19:52:53 +00:00
end ;
2021-09-27 09:03:37 +02:00
procedure TFoundCodeDialog. ChangedAddressClose( Sender: TObject; var CloseAction: TCloseAction) ;
2021-08-22 12:50:43 +02:00
var i: integer ;
coderecord: Tcoderecord;
begin
for i: = 0 to FoundCodeList. Items. Count- 1 do
begin
coderecord: = TCodeRecord( foundcodelist. items[ i] . data) ;
if coderecord. formChangedAddresses= sender then
coderecord. formChangedAddresses: = nil ;
end ;
end ;
2021-09-27 09:03:37 +02:00
procedure TFoundCodeDialog. moreinfo;
2016-08-12 22:56:50 +02:00
var
disassembled: array [ 1 .. 5 ] of record
s: string ;
a: ptruint;
end ;
2011-07-04 19:52:53 +00:00
address: ptrUint;
itemindex: integer ;
temp, temp2: string ;
maxregistervalue: ptrUint;
p: ptrUint;
i: integer ;
coderecord: TCodeRecord;
firstchar: string ;
2012-05-10 23:36:03 +00:00
2011-07-04 19:52:53 +00:00
w: integer ;
2012-05-10 23:36:03 +00:00
FormFoundCodeListExtra: TFormFoundCodeListExtra;
2013-06-08 12:56:11 +00:00
ew: trect; //extra window rect
cw: trect; //changed address window rect
2013-09-23 21:48:43 +00:00
offset: integer ;
2018-03-28 21:18:37 +02:00
2022-04-19 00:08:51 +02:00
lbl: TLabel;
2018-03-28 21:18:37 +02:00
d: TDisassembler;
2022-08-15 23:51:27 +02:00
gplist: PContextElementRegisterList;
2011-07-04 19:52:53 +00:00
begin
2018-06-01 12:50:03 +02:00
if processhandler. is64bit then
firstchar: = 'R' else firstchar: = 'E' ;
2011-07-04 19:52:53 +00:00
itemindex: = foundcodelist. ItemIndex;
if itemindex< > - 1 then
begin
2012-04-06 23:08:22 +00:00
FormFoundCodeListExtra: = TFormFoundCodeListExtra. Create( application) ;
2021-03-14 16:17:30 -07:00
if useexceptions or ( currentdebuggerinterface is TDBVMDebugInterface) then
2011-07-04 19:52:53 +00:00
FormFoundCodeListExtra. Label18. Visible: = false
else
FormFoundCodeListExtra. Label18. Visible: = true ;
coderecord: = TCodeRecord( foundcodelist. items[ itemindex] . data) ;
2013-06-06 23:53:32 +00:00
if coderecord. formChangedAddresses< > nil then
2013-06-07 23:14:02 +00:00
begin
if not coderecord. formChangedAddresses. visible then //override userdefined positioning
2013-06-08 12:56:11 +00:00
begin
2021-08-22 12:50:43 +02:00
//LCLIntf.GetWindowRect(coderecord.formChangedAddresses.handle, cw);
//LCLIntf.GetWindowRect(FormFoundCodeListExtra.handle, ew);
2013-06-08 12:56:11 +00:00
2021-08-22 12:50:43 +02:00
//coderecord.formChangedAddresses.left:=(ew.Left-(cw.Right-cw.left));
//coderecord.formChangedAddresses.top:=FormFoundCodeListExtra.top;
2013-06-08 12:56:11 +00:00
end ;
2013-06-07 23:14:02 +00:00
2013-06-06 23:53:32 +00:00
coderecord. formChangedAddresses. show;
2021-08-22 12:50:43 +02:00
coderecord. formChangedAddresses. AddHandlerClose( ChangedAddressClose) ;
2013-06-07 23:14:02 +00:00
end ;
2011-07-04 19:52:53 +00:00
2018-03-28 21:18:37 +02:00
2011-07-04 19:52:53 +00:00
address: = coderecord. address;
2019-12-18 12:07:17 +01:00
{$IFDEF windows}
2021-03-14 16:17:30 -07:00
if CurrentDebuggerInterface is TDBVMDebugInterface then
begin
2021-03-25 23:22:22 +01:00
{$ifdef cpu64}
2022-08-15 23:51:27 +02:00
if pcontext( coderecord. context) ^ . P2Home< > 0 then
2021-03-14 16:17:30 -07:00
begin
d: = TCR3Disassembler. Create;
2022-08-15 23:51:27 +02:00
TCR3Disassembler( d) . CR3: = pcontext( coderecord. context) ^ . P2Home;
2021-03-14 16:17:30 -07:00
end
else
2021-03-25 23:22:22 +01:00
{$endif}
2021-03-14 16:17:30 -07:00
d: = TDisassembler. Create;
end
else
2018-03-28 21:18:37 +02:00
if coderecord. dbvmcontextbasic< > nil then
begin
d: = TCR3Disassembler. Create;
TCR3Disassembler( d) . CR3: = coderecord. dbvmcontextbasic^ . CR3;
end
else
2019-12-18 12:07:17 +01:00
{$ENDIF}
2018-03-28 21:18:37 +02:00
d: = TDisassembler. Create;
address: = previousopcode( address, d) ;
address: = previousopcode( address, d) ;
2011-07-04 19:52:53 +00:00
2016-08-12 22:56:50 +02:00
disassembled[ 1 ] . a: = address;
2018-03-28 21:18:37 +02:00
disassembled[ 1 ] . s: = d. disassemble( address, temp) ;
2016-08-12 22:56:50 +02:00
disassembled[ 2 ] . a: = address;
2018-03-28 21:18:37 +02:00
disassembled[ 2 ] . s: = d. disassemble( address, temp) ;
2011-07-04 19:52:53 +00:00
if address< > coderecord. address then
begin
2016-08-12 22:56:50 +02:00
disassembled[ 1 ] . s: = '' ;
disassembled[ 2 ] . s: = '' ;
disassembled[ 3 ] . s: = coderecord. opcode;
disassembled[ 4 ] . s: = '' ;
disassembled[ 5 ] . s: = '' ;
2011-07-04 19:52:53 +00:00
end
else
begin
2016-08-12 22:56:50 +02:00
disassembled[ 3 ] . a: = address;
2018-04-03 11:39:00 +02:00
disassembled[ 3 ] . s: = d. disassemble( address, temp) ;
2016-08-12 22:56:50 +02:00
disassembled[ 4 ] . a: = address;
2018-04-03 11:39:00 +02:00
disassembled[ 4 ] . s: = d. disassemble( address, temp) ;
2016-08-12 22:56:50 +02:00
disassembled[ 5 ] . a: = address;
2018-04-03 11:39:00 +02:00
disassembled[ 5 ] . s: = d. disassemble( address, temp) ;
2011-07-04 19:52:53 +00:00
end ;
2018-03-28 21:18:37 +02:00
freeandnil( d) ;
2013-06-06 23:53:32 +00:00
2011-07-04 19:52:53 +00:00
//convert disassembled strings to address+opcode only (no bytes)
//xxxxxxxx - xx xx xx - opcode
2016-08-12 22:56:50 +02:00
temp: = copy( disassembled[ 1 ] . s, pos( '-' , disassembled[ 1 ] . s) + 2 , length( disassembled[ 1 ] . s) ) ;
2011-07-04 19:52:53 +00:00
temp: = copy( temp, pos( '-' , temp) + 2 , length( temp) ) ;
2016-08-12 22:56:50 +02:00
disassembled[ 1 ] . s: = copy( disassembled[ 1 ] . s, 1 , pos( '-' , disassembled[ 1 ] . s) ) + ' ' + temp;
2011-07-04 19:52:53 +00:00
2016-08-12 22:56:50 +02:00
temp: = copy( disassembled[ 2 ] . s, pos( '-' , disassembled[ 2 ] . s) + 2 , length( disassembled[ 2 ] . s) ) ;
2011-07-04 19:52:53 +00:00
temp: = copy( temp, pos( '-' , temp) + 2 , length( temp) ) ;
2016-08-12 22:56:50 +02:00
disassembled[ 2 ] . s: = copy( disassembled[ 2 ] . s, 1 , pos( '-' , disassembled[ 2 ] . s) ) + ' ' + temp;
2011-07-04 19:52:53 +00:00
2016-08-12 22:56:50 +02:00
temp: = copy( disassembled[ 3 ] . s, pos( '-' , disassembled[ 3 ] . s) + 2 , length( disassembled[ 3 ] . s) ) ;
2011-07-04 19:52:53 +00:00
temp: = copy( temp, pos( '-' , temp) + 2 , length( temp) ) ;
2016-08-12 22:56:50 +02:00
disassembled[ 3 ] . s: = copy( disassembled[ 3 ] . s, 1 , pos( '-' , disassembled[ 3 ] . s) ) + ' ' + temp;
2011-07-04 19:52:53 +00:00
2016-08-12 22:56:50 +02:00
temp: = copy( disassembled[ 4 ] . s, pos( '-' , disassembled[ 4 ] . s) + 2 , length( disassembled[ 4 ] . s) ) ;
2011-07-04 19:52:53 +00:00
temp: = copy( temp, pos( '-' , temp) + 2 , length( temp) ) ;
2016-08-12 22:56:50 +02:00
disassembled[ 4 ] . s: = copy( disassembled[ 4 ] . s, 1 , pos( '-' , disassembled[ 4 ] . s) ) + ' ' + temp;
2011-07-04 19:52:53 +00:00
2016-08-12 22:56:50 +02:00
temp: = copy( disassembled[ 5 ] . s, pos( '-' , disassembled[ 5 ] . s) + 2 , length( disassembled[ 5 ] . s) ) ;
2011-07-04 19:52:53 +00:00
temp: = copy( temp, pos( '-' , temp) + 2 , length( temp) ) ;
2016-08-12 22:56:50 +02:00
disassembled[ 5 ] . s: = copy( disassembled[ 5 ] . s, 1 , pos( '-' , disassembled[ 5 ] . s) ) + ' ' + temp;
2011-07-04 19:52:53 +00:00
with FormFoundCodeListExtra do
begin
2022-04-19 00:08:51 +02:00
pnlEPTWatch. visible: = false ;
2020-12-18 02:20:01 +01:00
label1. Caption: = disassembled[ 1 ] . s;
label1. tag: = disassembled[ 1 ] . a;
2011-07-04 19:52:53 +00:00
2016-08-12 22:56:50 +02:00
Label2. Caption: = disassembled[ 2 ] . s;
Label2. tag: = disassembled[ 2 ] . a;
Label3. Caption: = disassembled[ 3 ] . s;
Label3. tag: = disassembled[ 3 ] . a;
Label4. Caption: = disassembled[ 4 ] . s;
Label4. tag: = disassembled[ 4 ] . a;
Label5. Caption: = disassembled[ 5 ] . s;
Label5. tag: = disassembled[ 5 ] . a;
2011-07-04 19:52:53 +00:00
2022-08-15 23:51:27 +02:00
BeginFormUpdate;
while pnlRegisters. ControlCount> 0 do
pnlRegisters. Controls[ 0 ] . Destroy;
//controlsPerLine:
//9 - 8 digit registers = 3 controls/line (3 rows) (3x3) (24 digits/row)
//16 - 16 digit registers = registers = 5
gplist: = coderecord. contexthandler. getGeneralPurposeRegisters;
if gplist< > nil then
begin
pnlRegisters. ChildSizing. ControlsPerLine: = length( gplist^ ) div 3 ;
for i: = 0 to length( gplist^ ) - 1 do
begin
lbl: = tlabel. create( FormFoundCodeListExtra) ;
lbl. Caption: = gplist^ [ i] . name + '=' + gplist^ [ i] . getValueString( coderecord. context) ;
lbl. tag: = ptruint( @ gplist^ [ i] ) ;
lbl. parent: = pnlRegisters;
lbl. OnMouseDown: = registerMouseDown;
lbl. OnDblClick: = RegisterDblClick;
end ;
end ;
EndFormUpdate;
( *
2013-08-13 23:12:14 +00:00
if processhandler. SystemArchitecture= archarm then
2011-07-04 19:52:53 +00:00
begin
2022-04-19 00:08:51 +02:00
formfoundcodelistextra. label17. caption: = '' ;
if processhandler. is64Bit then
begin
//just start from scratch
while pnlRegisters. ControlCount> 0 do
pnlRegisters. Controls[ 0 ] . Destroy;
pnlRegisters. ChildSizing. ControlsPerLine: = 6 ;
for i: = 0 to 3 0 do
begin
lbl: = tlabel. create( FormFoundCodeListExtra) ;
lbl. Caption: = format( 'X%d=%.8x' , [ i, coderecord. arm64context. regs. X[ i] ] ) ;
lbl. parent: = pnlRegisters;
lbl. OnMouseDown: = registerMouseDown;
lbl. OnDblClick: = RegisterDblClick;
end ;
lbl: = tlabel. create( FormFoundCodeListExtra) ;
lbl. Caption: = format( 'SP=%.8x' , [ coderecord. arm64context. SP] ) ;
lbl. parent: = pnlRegisters;
lbl. OnMouseDown: = registerMouseDown;
lbl. OnDblClick: = RegisterDblClick;
lbl: = tlabel. create( FormFoundCodeListExtra) ;
lbl. Caption: = format( 'PC=%.8x' , [ coderecord. arm64context. PC] ) ;
lbl. parent: = pnlRegisters;
lbl. OnMouseDown: = registerMouseDown;
lbl. OnDblClick: = RegisterDblClick;
lbl: = tlabel. create( FormFoundCodeListExtra) ;
lbl. Caption: = format( 'PSTATE=%.8x' , [ coderecord. arm64context. PSTATE] ) ;
lbl. parent: = pnlRegisters;
lbl. OnMouseDown: = registerMouseDown;
lbl. OnDblClick: = RegisterDblClick;
end
else
begin
//repurpose the x86 32-bit labels
lblRAX. caption: = ' R0=' + IntToHex( coderecord. armcontext. R0, 8 ) ;
lblRDX. caption: = ' R1=' + IntToHex( coderecord. armcontext. R1, 8 ) ;
lblRBP. caption: = ' R2=' + IntToHex( coderecord. armcontext. R2, 8 ) ;
lblRBX. caption: = ' R3=' + IntToHex( coderecord. armcontext. R3, 8 ) ;
lblRSI. caption: = ' R4=' + IntToHex( coderecord. armcontext. R4, 8 ) ;
lblRSP. caption: = ' R5=' + IntToHex( coderecord. armcontext. R5, 8 ) ;
lblRCX. caption: = ' R6=' + IntToHex( coderecord. armcontext. R6, 8 ) ;
lblRDI. caption: = ' R7=' + IntToHex( coderecord. armcontext. R7, 8 ) ;
lblRIP. caption: = ' R8=' + IntToHex( coderecord. armcontext. R8, 8 ) ;
lblR9: = tlabel. Create( FormFoundCodeListExtra) ;
lblR9. caption: = ' R9=' + IntToHex( coderecord. armcontext. R9, 8 ) ;
lblR9. parent: = pnlRegisters;
lblR9. OnMouseDown: = registerMouseDown;
lblR9. OnDblClick: = RegisterDblClick;
lblR10: = tlabel. Create( FormFoundCodeListExtra) ;
lblR10. caption: = 'R10=' + IntToHex( coderecord. armcontext. R10, 8 ) ;
lblR10. parent: = pnlRegisters;
lblR10. OnMouseDown: = registerMouseDown;
lblR10. OnDblClick: = RegisterDblClick;
lblR11: = tlabel. Create( FormFoundCodeListExtra) ;
lblR11. caption: = ' FP=' + IntToHex( coderecord. armcontext. FP, 8 ) ;
lblR11. parent: = pnlRegisters;
lblR11. OnMouseDown: = registerMouseDown;
lblR11. OnDblClick: = RegisterDblClick;
//new row
lblR12: = tlabel. Create( FormFoundCodeListExtra) ;
lblR12. caption: = ' IP=' + IntToHex( coderecord. armcontext. IP, 8 ) ;
lblR12. parent: = pnlRegisters;
lblR12. OnMouseDown: = registerMouseDown;
lblR12. OnDblClick: = RegisterDblClick;
2013-08-13 23:12:14 +00:00
2022-04-19 00:08:51 +02:00
lblR13: = tlabel. Create( FormFoundCodeListExtra) ;
lblR13. caption: = ' SP=' + IntToHex( coderecord. armcontext. SP, 8 ) ;
lblR13. parent: = pnlRegisters;
lblR13. OnMouseDown: = registerMouseDown;
lblR13. OnDblClick: = RegisterDblClick;
lblR14: = tlabel. Create( FormFoundCodeListExtra) ;
lblR14. caption: = ' LR=' + IntToHex( coderecord. armcontext. LR, 8 ) ;
lblR14. parent: = pnlRegisters;
lblR14. OnMouseDown: = registerMouseDown;
lblR14. OnDblClick: = RegisterDblClick;
//new line
lblR15: = tlabel. Create( FormFoundCodeListExtra) ;
lblR15. caption: = ' PC=' + IntToHex( coderecord. armcontext. PC, 8 ) ;
lblR15. parent: = pnlRegisters;
lblR15. OnMouseDown: = registerMouseDown;
lblR15. OnDblClick: = RegisterDblClick;
lblR16: = tlabel. Create( FormFoundCodeListExtra) ;
lblR16. caption: = ' CPSR=' + IntToHex( coderecord. armcontext. CPSR, 8 ) ;
lblR16. parent: = pnlRegisters;
lblR16. OnMouseDown: = registerMouseDown;
lblR16. OnDblClick: = RegisterDblClick;
lblR17: = tlabel. Create( FormFoundCodeListExtra) ;
lblR17. caption: = ' ORIG_R0=' + IntToHex( coderecord. armcontext. ORIG_R0, 8 ) ;
lblR17. parent: = pnlRegisters;
lblR17. OnMouseDown: = registerMouseDown;
lblR17. OnDblClick: = RegisterDblClick;
end ;
2016-08-24 18:00:13 +02:00
{ Constraints. MinHeight: = panel6. top+ ( lblR17. top+ lblR17. height) + 1 6 + panel5. height;
2012-05-10 23:36:03 +00:00
if height< Constraints. MinHeight then
2016-08-24 18:00:13 +02:00
height: = Constraints. MinHeight; }
2013-08-13 23:12:14 +00:00
end
2022-08-15 23:51:27 +02:00
else * )
2013-08-13 23:12:14 +00:00
begin
2018-06-01 12:50:03 +02:00
2022-08-15 23:51:27 +02:00
( *
2013-08-13 23:12:14 +00:00
lblRAX. caption: = firstchar+ 'AX=' + IntToHex( coderecord. context. {$ifdef cpu64} Rax{$else} Eax{$endif} , 8 ) ;
lblRBX. caption: = firstchar+ 'BX=' + IntToHex( coderecord. context. {$ifdef cpu64} Rbx{$else} Ebx{$endif} , 8 ) ;
lblRCX. caption: = firstchar+ 'CX=' + IntToHex( coderecord. context. {$ifdef cpu64} Rcx{$else} Ecx{$endif} , 8 ) ;
lblRDX. caption: = firstchar+ 'DX=' + IntToHex( coderecord. context. {$ifdef cpu64} Rdx{$else} Edx{$endif} , 8 ) ;
lblRSI. caption: = firstchar+ 'SI=' + IntToHex( coderecord. context. {$ifdef cpu64} Rsi{$else} Esi{$endif} , 8 ) ;
lblRDI. caption: = firstchar+ 'DI=' + IntToHex( coderecord. context. {$ifdef cpu64} Rdi{$else} Edi{$endif} , 8 ) ;
lblRSP. caption: = firstchar+ 'SP=' + IntToHex( coderecord. context. {$ifdef cpu64} Rsp{$else} Esp{$endif} , 8 ) ;
lblRBP. caption: = firstchar+ 'BP=' + IntToHex( coderecord. context. {$ifdef cpu64} Rbp{$else} Ebp{$endif} , 8 ) ;
lblRIP. caption: = firstchar+ 'IP=' + IntToHex( coderecord. context. {$ifdef cpu64} Rip{$else} Eip{$endif} , 8 ) ;
{$ifdef cpu64}
if processhandler. is64bit then
begin
2016-08-12 22:56:50 +02:00
pnlRegisters. ChildSizing. ControlsPerLine: = 5 ;
2013-08-13 23:12:14 +00:00
lblR8: = tlabel. Create( FormFoundCodeListExtra) ;
lblR8. caption: = ' R8=' + IntToHex( coderecord. context. r8, 8 ) ;
2016-08-12 22:56:50 +02:00
lblR8. parent: = FormFoundCodeListExtra. pnlRegisters;
2013-08-13 23:12:14 +00:00
lblR8. OnMouseDown: = registerMouseDown;
lblR8. OnDblClick: = RegisterDblClick;
lblR8. Align: = lblrcx. Align;
2019-07-27 13:10:35 +02:00
lblR8. Color: = lblRAX. Color;
lblR8. Name : = 'lblR8' ;
2013-08-13 23:12:14 +00:00
lblR9: = tlabel. Create( FormFoundCodeListExtra) ;
lblR9. caption: = ' R9=' + IntToHex( coderecord. context. r9, 8 ) ;
2016-08-12 22:56:50 +02:00
lblR9. parent: = FormFoundCodeListExtra. pnlRegisters;
2013-08-13 23:12:14 +00:00
lblR9. OnMouseDown: = registerMouseDown;
lblR9. OnDblClick: = RegisterDblClick;
lblR9. Align: = lblrcx. Align;
2019-07-27 13:10:35 +02:00
lblR9. Color: = lblRAX. Color;
2013-08-13 23:12:14 +00:00
lblR10: = tlabel. Create( FormFoundCodeListExtra) ;
lblR10. caption: = 'R10=' + IntToHex( coderecord. context. r10, 8 ) ;
2016-08-12 22:56:50 +02:00
lblR10. parent: = FormFoundCodeListExtra. pnlRegisters;
2013-08-13 23:12:14 +00:00
lblR10. OnMouseDown: = registerMouseDown;
lblR10. OnDblClick: = RegisterDblClick;
lblR10. Align: = lblrcx. Align;
2019-07-27 13:10:35 +02:00
lblR10. Color: = lblRAX. Color;
2013-08-13 23:12:14 +00:00
lblR11: = tlabel. Create( FormFoundCodeListExtra) ;
lblR11. caption: = 'R11=' + IntToHex( coderecord. context. r11, 8 ) ;
2016-08-12 22:56:50 +02:00
lblR11. parent: = FormFoundCodeListExtra. pnlRegisters;
2013-08-13 23:12:14 +00:00
lblR11. OnMouseDown: = registerMouseDown;
lblR11. OnDblClick: = RegisterDblClick;
lblR11. Align: = lblrcx. Align;
2019-07-27 13:10:35 +02:00
lblR11. Color: = lblRAX. Color;
2013-08-13 23:12:14 +00:00
lblR12: = tlabel. Create( FormFoundCodeListExtra) ;
lblR12. caption: = 'R12=' + IntToHex( coderecord. context. r12, 8 ) ;
2016-08-12 22:56:50 +02:00
lblR12. parent: = FormFoundCodeListExtra. pnlRegisters;
2013-08-13 23:12:14 +00:00
lblR12. OnMouseDown: = registerMouseDown;
lblR12. OnDblClick: = RegisterDblClick;
lblR12. Align: = lblrcx. Align;
2019-07-27 13:10:35 +02:00
lblR12. Color: = lblRAX. Color;
2013-08-13 23:12:14 +00:00
lblR13: = tlabel. Create( FormFoundCodeListExtra) ;
lblR13. caption: = 'R13=' + IntToHex( coderecord. context. r13, 8 ) ;
2016-08-12 22:56:50 +02:00
lblR13. parent: = FormFoundCodeListExtra. pnlRegisters;
2013-08-13 23:12:14 +00:00
lblR13. OnMouseDown: = registerMouseDown;
lblR13. OnDblClick: = RegisterDblClick;
lblR13. Align: = lblrcx. Align;
2019-07-27 13:10:35 +02:00
lblR13. Color: = lblRAX. Color;
2013-08-13 23:12:14 +00:00
lblR14: = tlabel. Create( FormFoundCodeListExtra) ;
lblR14. caption: = 'R14=' + IntToHex( coderecord. context. r14, 8 ) ;
2016-08-12 22:56:50 +02:00
lblR14. parent: = FormFoundCodeListExtra. pnlRegisters;
2013-08-13 23:12:14 +00:00
lblR14. OnMouseDown: = registerMouseDown;
lblR14. OnDblClick: = RegisterDblClick;
lblR14. Align: = lblrcx. Align;
2019-07-27 13:10:35 +02:00
lblR14. Color: = lblRAX. Color;
2013-08-13 23:12:14 +00:00
lblR15: = tlabel. Create( FormFoundCodeListExtra) ;
lblR15. caption: = 'R15=' + IntToHex( coderecord. context. r15, 8 ) ;
2016-08-12 22:56:50 +02:00
lblR15. parent: = FormFoundCodeListExtra. pnlRegisters;
2013-08-13 23:12:14 +00:00
lblR15. OnMouseDown: = registerMouseDown;
lblR15. OnDblClick: = RegisterDblClick;
lblR15. Align: = lblrcx. Align;
2019-07-27 13:10:35 +02:00
lblR15. Color: = lblRAX. Color;
2021-03-14 16:17:30 -07:00
if ( currentdebuggerinterface is TDBVMDebugInterface) and ( coderecord. context. P2Home< > 0 ) then
begin
lblR16: = tlabel. Create( FormFoundCodeListExtra) ;
lblR16. caption: = ' CR3=' + IntToHex( coderecord. context. P2Home, 8 ) ;
lblR16. parent: = FormFoundCodeListExtra. pnlRegisters;
lblR16. OnMouseDown: = registerMouseDown;
lblR16. OnDblClick: = RegisterDblClick;
lblR16. Align: = lblrcx. Align;
lblR16. Color: = lblRAX. Color;
end ;
2013-08-13 23:12:14 +00:00
2016-08-12 22:56:50 +02:00
lblRBP. BringToFront;
lblRSP. BringToFront;
lblRIP. BringToFront;
2013-08-13 23:12:14 +00:00
end ;
{$endif}
2022-08-15 23:51:27 +02:00
* )
2018-03-28 21:18:37 +02:00
if coderecord. dbvmcontextbasic< > nil then
begin
pnlEPTWatch. visible: = true ;
lblPhysicalAddress. caption: = format( 'Physical Address=%.8x' , [ coderecord. dbvmcontextbasic^ . PhysicalAddress] ) ;
lblVirtualAddress. caption: = format( 'Virtual Address=%.8x' , [ coderecord. dbvmcontextbasic^ . VirtualAddress] ) ;
lblFSBase. caption: = format( 'FS Base=%.8x' , [ coderecord. dbvmcontextbasic^ . FSBASE] ) ;
lblGSBase. caption: = format( 'GS Base=%.8x' , [ coderecord. dbvmcontextbasic^ . GSBASE] ) ;
2021-03-11 07:37:44 -08:00
lblGSBaseKernel. caption: = format( 'GS Base Kernel=%.8x' , [ coderecord. dbvmcontextbasic^ . GSBASE_KERNEL] ) ;
2018-03-28 21:18:37 +02:00
lblCR3. caption: = format( 'CR3=%.8x' , [ coderecord. dbvmcontextbasic^ . CR3] ) ;
end
else
pnlEPTWatch. visible: = false ;
2011-07-04 19:52:53 +00:00
end ;
label6. Caption: = coderecord. description;
end ;
//parse the disassembled[3] string to help the user find the pointer
//first find the [xxx]
2016-08-12 22:56:50 +02:00
temp: = lowercase( copy( disassembled[ 3 ] . s, pos( '[' , disassembled[ 3 ] . s) + 1 , ( pos( ']' , disassembled[ 3 ] . s) - 1 ) - ( pos( '[' , disassembled[ 3 ] . s) ) ) ) ;
2011-07-04 19:52:53 +00:00
firstchar: = lowercase( firstchar) ;
maxregistervalue: = 0 ;
if temp< > '' then
begin
//parse
//find the biggest value, registers or exact value
2013-09-23 21:48:43 +00:00
if ( ( coderecord. LastDisassembleData. modrmValueType= dvtValue) and ( coderecord. LastDisassembleData. hasSib= false ) ) then
2011-07-04 19:52:53 +00:00
begin
2013-09-23 21:48:43 +00:00
//only a value and no sib (the sib part can get messed up if it's a read)
2011-07-04 19:52:53 +00:00
2013-09-23 21:48:43 +00:00
offset: = integer( coderecord. LastDisassembleData. modrmValue) ;
2011-07-04 19:52:53 +00:00
2022-04-19 00:08:51 +02:00
if processhandler. SystemArchitecture= archX86 then
formfoundcodelistextra. probably: = addresswatched- offset;
2013-09-23 21:48:43 +00:00
end
else
2011-07-04 19:52:53 +00:00
begin
2022-08-15 23:51:27 +02:00
if processhandler. SystemArchitecture= archX86 then
2013-09-23 21:48:43 +00:00
begin
2022-08-15 23:51:27 +02:00
//todo: contexthandler lookups
//try the old code (coderecord.context is
if pos( firstchar+ 'ax' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . {$ifdef cpu64} Rax{$else} Eax{$endif} ) ;
if pos( firstchar+ 'bx' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . {$ifdef cpu64} Rbx{$else} Ebx{$endif} ) ;
if pos( firstchar+ 'cx' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . {$ifdef cpu64} Rcx{$else} Ecx{$endif} ) ;
if pos( firstchar+ 'dx' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . {$ifdef cpu64} Rdx{$else} Edx{$endif} ) ;
if pos( firstchar+ 'di' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . {$ifdef cpu64} Rdi{$else} Edi{$endif} ) ;
if pos( firstchar+ 'si' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . {$ifdef cpu64} Rsi{$else} Esi{$endif} ) ;
if pos( firstchar+ 'bp' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . {$ifdef cpu64} Rbp{$else} Ebp{$endif} ) ;
if pos( firstchar+ 'sp' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . {$ifdef cpu64} Rsp{$else} Esp{$endif} ) ;
{$ifdef cpu64}
if processhandler. is64Bit then
begin
if pos( 'r8' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . r8) ;
if pos( 'r9' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . r9) ;
if pos( 'r0' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . r10) ;
if pos( 'r1' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . r11) ;
if pos( 'r2' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . r12) ;
if pos( 'r3' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . r13) ;
if pos( 'r4' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . r14) ;
if pos( 'r5' , temp) > 0 then maxregistervalue: = MaxX( maxregistervalue, pcontext( coderecord. context) ^ . r15) ;
end ;
{$endif}
2013-09-23 21:48:43 +00:00
2022-08-15 23:51:27 +02:00
//the offset is always at the end, so read from back to front
//todo: use addresswatched
2013-09-23 21:48:43 +00:00
2011-07-04 19:52:53 +00:00
2013-09-23 21:48:43 +00:00
2022-08-15 23:51:27 +02:00
temp2: = '' ;
for i: = length( temp) downto 1 do
if temp[ i] in [ '0' .. '9' , 'a' .. 'f' ] then temp2: = temp[ i] + temp2 else break;
2013-09-23 21:48:43 +00:00
2022-08-15 23:51:27 +02:00
if temp2< > '' then //I know this isn't completely correct e.g: [eax*4] but even then the 4 will NEVER be bigger than eax (unless it's to cause a crash)
begin
p: = StrToQWordEx( '$' + temp2) ;
if p> maxregistervalue then maxregistervalue: = p;
end ;
2013-09-23 21:48:43 +00:00
2022-08-15 23:51:27 +02:00
formfoundcodelistextra. probably: = maxregistervalue;
end ; //todo: arm
2013-09-23 21:48:43 +00:00
end ;
2011-07-04 19:52:53 +00:00
end else formfoundcodelistextra. label17. caption: = '' ;
w: = formfoundcodelistextra. width;
w: = max( w, formfoundcodelistextra. label1. width) ;
w: = max( w, formfoundcodelistextra. label2. width) ;
w: = max( w, formfoundcodelistextra. label3. width) ;
w: = max( w, formfoundcodelistextra. label4. width) ;
w: = max( w, formfoundcodelistextra. label5. width) ;
if w< > formfoundcodelistextra. Width then
formfoundcodelistextra. Width: = w+ 5 ;
2022-08-15 23:51:27 +02:00
formfoundcodelistextra. context: = coderecord. contexthandler. getCopy( coderecord. context) ;
2018-04-03 11:39:00 +02:00
2011-07-04 19:52:53 +00:00
if coderecord. stack. stack< > nil then
begin
getmem( formfoundcodelistextra. stack. stack, coderecord. stack. savedsize) ;
formfoundcodelistextra. stack. savedsize: = coderecord. stack. savedsize;
CopyMemory( formfoundcodelistextra. stack. stack, coderecord. stack. stack, coderecord. stack. savedsize) ;
end ;
2022-09-22 00:48:23 +02:00
if coderecord. ipt. log< > nil then
begin
getmem( formfoundcodelistextra. ipt. log, coderecord. ipt. size) ;
formfoundcodelistextra. ipt. size: = coderecord. ipt. size;
copymemory( FormFoundCodeListExtra. ipt. log, coderecord. ipt. log, coderecord. ipt. size) ;
end ;
2011-07-04 19:52:53 +00:00
FormFoundCodeListExtra. Show;
end ;
end ;
procedure TFoundCodeDialog. FoundcodeListClick( Sender: TObject) ;
begin
end ;
procedure TFoundCodeDialog. FormCreate( Sender: TObject) ;
var x: array of integer ;
begin
btnOk. caption: = strStop;
setlength( x, 0 ) ;
2022-08-29 23:26:02 +02:00
if loadformposition( self, x) then
loadedPosition: = true ;
2017-04-06 15:24:56 +02:00
if length( x) > = 1 then
begin
2017-04-08 00:07:55 +02:00
foundcodelist. Columns[ 0 ] . Width: = x[ 0 ] ;
2017-04-06 15:24:56 +02:00
setcountwidth: = true ;
end ;
2018-03-28 21:18:37 +02:00
2023-10-20 17:32:15 +02:00
fdebuggerinterfacewatchid: = - 1 ;
2020-01-09 01:26:41 +01:00
countsortdirection: = 1 ;
addresssortdirection: = 1 ;
2021-05-04 14:49:20 +02:00
seenAddressList: = tmap. Create( ituPtrSize, sizeof( pointer ) ) ;
seenAddressListCS: = TCriticalSection. Create;
2011-07-04 19:52:53 +00:00
end ;
procedure TFoundCodeDialog. FormDeactivate( Sender: TObject) ;
begin
end ;
procedure TFoundCodeDialog. FormDestroy( Sender: TObject) ;
var i: integer ;
cr: Tcoderecord;
2018-06-11 15:36:17 +02:00
s: string ;
2011-07-04 19:52:53 +00:00
begin
2018-06-11 15:36:17 +02:00
stopDBVMWatch( ) ;
2011-07-04 19:52:53 +00:00
for i: = 0 to FoundCodeList. Items. count- 1 do
begin
cr: = Tcoderecord( FoundCodeList. Items[ i] . data) ;
2013-06-06 23:53:32 +00:00
if cr. formChangedAddresses< > nil then
begin
2018-06-11 15:36:17 +02:00
if usedmiFindWhatAccesses= false then
begin
MessageDlg( 'cr.formChangedAddresses is not nil but the function was never used. Fuck! cr.formChangedAddresses=' + inttohex( ptruint( cr. formChangedAddresses) , 8 ) , mtError, [ mbok] , 0 ) ;
exit;
end ;
2013-06-06 23:53:32 +00:00
cr. formChangedAddresses. Close;
end ;
2018-06-11 15:36:17 +02:00
FoundCodeList. Items[ i] . data: = nil ;
2018-06-12 20:23:45 +02:00
freeandnil( cr) ;
2011-07-04 19:52:53 +00:00
end ;
2021-05-04 14:49:20 +02:00
FoundCodeList. Clear;
timerEntryInfoUpdate. Enabled: = false ;
freeandnil( seenAddressList) ;
freeandnil( seenAddressListCS) ;
2011-07-04 19:52:53 +00:00
end ;
2016-08-12 23:17:36 +02:00
procedure TFoundCodeDialog. FormShow( Sender: TObject) ;
begin
2017-04-06 15:24:56 +02:00
if not setcountwidth then
begin
FoundCodeList. Column[ 0 ] . Width: = max( FoundCodeList. Column[ 0 ] . Width, FoundCodeList. Canvas. TextWidth( '9999' ) ) ;
setcountwidth: = true ;
end ;
2022-08-29 23:26:02 +02:00
if not loadedPosition then
begin
width: = canvas. TextWidth( 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX' ) ;
height: = canvas. TextHeight( 'Q' ) * 2 0 ;
FoundCodeList. Columns[ 0 ] . Width: = canvas. TextWidth( ' ' + FoundCodeList. Columns[ 0 ] . Caption+ ' ' ) ;
end ;
2016-08-12 23:17:36 +02:00
end ;
2011-07-04 19:52:53 +00:00
procedure TFoundCodeDialog. FoundCodeListChange( Sender: TObject;
Item: TListItem; Change: TItemChange) ;
begin
end ;
procedure TFoundCodeDialog. btnOKClick( Sender: TObject) ;
var original: dword;
i: integer ;
begin
if btnOK. caption= strStop then
begin
if debuggerthread< > nil then
debuggerthread. CodeFinderStop( self) ;
btnOK. caption: = strClose;
2018-03-28 21:18:37 +02:00
stopdbvmwatch;
2011-07-04 19:52:53 +00:00
end
else close;
end ;
procedure TFoundCodeDialog. FormClose( Sender: TObject;
var Action: TCloseAction) ;
2021-09-27 09:03:37 +02:00
var
x: array of integer ;
2011-07-04 19:52:53 +00:00
begin
2021-08-22 12:50:43 +02:00
if miFindWhatAccesses. Checked then
miFindWhatAccesses. Click; //unchecks it
2011-07-04 19:52:53 +00:00
if btnOK. caption= strStop then
if debuggerthread< > nil then
debuggerthread. CodeFinderStop( self) ;
2021-08-22 12:50:43 +02:00
2021-05-04 14:49:20 +02:00
if breakpoint< > nil then
begin
action: = caHide; //don't free. Only when the breakpoint is fully gone free it
dec( pbreakpoint( breakpoint) ^ . referencecount) ;
end
else
action: = caFree;
2021-09-27 09:03:37 +02:00
setlength( x, 1 ) ;
x[ 0 ] : = FoundCodeList. Columns[ 0 ] . Width;
saveformposition( self, x) ;
try
//rename so that the next created dialog can have this name
self. name : = self. name + '_tobedeleted' + inttohex( random( 6 5 5 3 5 ) , 4 ) + inttohex( random( 6 5 5 3 5 ) , 4 ) + inttohex( random( 6 5 5 3 5 ) , 4 ) + inttohex( random( 6 5 5 3 5 ) , 4 ) + '_' + inttohex( GetTickCount64, 1 ) ;
except
end ;
2011-07-04 19:52:53 +00:00
end ;
procedure TFoundCodeDialog. btnReplacewithnopsClick( Sender: TObject) ;
var codelength: dword;
written: dword;
i, j: integer ;
nops: array of byte ;
a: dword;
original: dword;
mbi : _MEMORY_BASIC_INFORMATION;
coderecord: TCodeRecord;
begin
with foundcodelist do
begin
for j: = 0 to foundcodelist. items. Count- 1 do
begin
if foundcodelist. items[ j] . Selected then
begin
coderecord: = TcodeRecord( foundcodelist. items[ j] . data) ;
codelength: = coderecord. size;
//add it to the codelist
2021-10-02 22:17:31 +02:00
try
advancedoptions. AddToCodeList( coderecord. address, coderecord. size, false , foundcodelist. SelCount> 1 ) ;
except
//already in the list, undo
end ;
2011-07-04 19:52:53 +00:00
2021-10-02 22:17:31 +02:00
for i: = 0 to AdvancedOptions. count- 1 do
begin
2021-11-23 13:24:24 +01:00
advancedoptions. lvCodelist. ClearSelection;
2021-10-02 22:17:31 +02:00
if symhandler. getAddressFromName( AdvancedOptions. entries[ i] . code. symbolname, false ) = coderecord. address then
begin
advancedoptions. lvCodelist. selected: = advancedoptions. lvCodelist. Items[ i] ;
advancedoptions. lvCodelist. Items[ i] . Selected: = true ;
if AdvancedOptions. entries[ i] . code. changed then
advancedoptions. miRestoreWithOriginalClick( advancedoptions. miRestoreWithOriginal)
else
advancedoptions. miReplaceWithNopsClick( advancedoptions. miReplaceWithNops) ;
end ;
2011-07-04 19:52:53 +00:00
end ;
2021-10-02 22:17:31 +02:00
2011-07-04 19:52:53 +00:00
end ;
end ;
end ;
end ;
procedure TFoundCodeDialog. btnOpenDisassemblerClick( Sender: TObject) ;
var coderecord: TCodeRecord;
begin
if foundcodelist. itemindex< > - 1 then
begin
coderecord: = TcodeRecord( foundcodelist. items[ foundcodelist. itemindex] . data) ;
memorybrowser. disassemblerview. SelectedAddress: = coderecord. address;
memorybrowser. panel1. visible: = true ;
memorybrowser. show;
end ;
end ;
procedure TFoundCodeDialog. btnAddToCodeListClick( Sender: TObject) ;
var i: integer ;
coderecord: TCodeRecord;
2019-06-18 20:30:18 +02:00
added: boolean = false ;
2011-07-04 19:52:53 +00:00
begin
for i: = 0 to foundcodelist. items. count- 1 do
begin
if foundcodelist. items[ i] . Selected then
begin
coderecord: = TcodeRecord( foundcodelist. items[ i] . data) ;
2019-06-18 20:30:18 +02:00
if advancedoptions. AddToCodeList( coderecord. address, coderecord. size, false , foundcodelist. SelCount> 1 ) then
added: = true ;
2011-07-04 19:52:53 +00:00
end ;
end ;
2019-06-18 20:30:18 +02:00
if added then
advancedoptions. Show;
2011-07-04 19:52:53 +00:00
end ;
2020-01-09 01:26:41 +01:00
function SortByAddress( Item1, Item2: TListItem; AOptionalParam: PtrInt) : Integer stdcall ;
begin
result : = AOptionalParam* ( TcodeRecord( Item1. data) . address- TcodeRecord( Item2. data) . address) ;
end ;
function SortByCount( Item1, Item2: TListItem; AOptionalParam: PtrInt) : Integer stdcall ;
begin
result : = AOptionalParam* ( TcodeRecord( Item2. data) . hitcount- TcodeRecord( Item1. data) . hitcount) ;
end ;
procedure TFoundCodeDialog. FoundCodeListColumnClick( Sender: TObject; Column: TListColumn) ;
begin
case column. index of
0 :
begin
FoundcodeList. CustomSort( SortByCount, countsortdirection) ;
countsortdirection: = countsortdirection* - 1 ;
end ;
1 :
begin
FoundcodeList. CustomSort( SortByAddress, addresssortdirection) ;
addresssortdirection: = addresssortdirection* - 1 ;
end ;
end ;
end ;
2011-07-04 19:52:53 +00:00
procedure TFoundCodeDialog. FoundcodeListDblClick( Sender: TObject) ;
begin
MoreInfo;
end ;
procedure TFoundCodeDialog. btnExtraInfoClick( Sender: TObject) ;
begin
moreinfo;
end ;
procedure TFoundCodeDialog. FormCloseQuery( Sender: TObject;
var CanClose: Boolean ) ;
begin
if btnOK. caption= strStop then btnOK. Click;
CanClose: = true ;
end ;
procedure TFoundCodeDialog. FoundCodeListSelectItem( Sender: TObject;
Item: TListItem; Selected: Boolean ) ;
var coderecord: TCodeRecord;
selectedRecord: integer ;
i: integer ;
begin
minfo. clear;
if foundcodelist. Selected< > nil then
begin
btnReplacewithnops. enabled: = true ;
btnOpenDisassembler. enabled: = true ;
btnAddToCodeList. enabled: = true ;
btnExtraInfo. Enabled: = true ;
coderecord: = TCodeRecord( foundcodelist. Selected. data) ;
description. Caption: = coderecord. description;
2013-05-05 08:52:11 +00:00
addinfo( coderecord) ;
{
2011-07-04 19:52:53 +00:00
for i: = 0 to FoundCodeList. Items. Count- 1 do
begin
if foundcodelist. items[ i] . Selected then
begin
coderecord: = TCodeRecord( foundcodelist. items[ i] . data) ;
addinfo( coderecord) ;
end ;
2013-05-05 08:52:11 +00:00
end ; }
2011-07-04 19:52:53 +00:00
//minfo.VertScrollBar.Position:=0;
minfo. SelStart: = 0 ;
minfo. SelLength: = 0 ;
end
else
begin
btnReplacewithnops. enabled: = false ;
btnOpenDisassembler. enabled: = false ;
btnAddToCodeList. enabled: = false ;
btnExtraInfo. Enabled: = false ;
if foundcodelist. Items. Count= 0 then
description. caption: = rsUseTheGameApplicationForAWhile
else
description. caption: = rsSelectAnItemFromTheListForASmallDescription;
end ;
end ;
2013-05-04 21:58:14 +00:00
procedure TFoundCodeDialog. MenuItem1Click( Sender: TObject) ;
var i: integer ;
begin
2013-05-05 08:52:11 +00:00
FoundCodeList. OnSelectItem: = nil ;
2013-05-04 21:58:14 +00:00
for i: = 0 to foundcodelist. items. count- 1 do
FoundCodeList. Items[ i] . Selected: = true ;
2013-05-05 08:52:11 +00:00
FoundCodeList. OnSelectItem: = FoundCodeListSelectItem;
2013-05-04 21:58:14 +00:00
end ;
2013-06-06 23:53:32 +00:00
procedure TFoundCodeDialog. miFindWhatAccessesClick( Sender: TObject) ;
var i: integer ;
coderecord: Tcoderecord;
f: TfrmChangedAddresses;
begin
2018-06-11 15:36:17 +02:00
usedmiFindWhatAccesses: = true ;
2013-06-06 23:53:32 +00:00
if miFindWhatAccesses. checked then
begin
2015-10-10 13:21:06 +02:00
if MessageDlg( rsFCThesWillSetASiftwareBreakpointInt3OnEverySingleOpcodeEtc, mtWarning, [ mbyes, mbno] , 0 ) = mryes then
2013-06-06 23:53:32 +00:00
begin
//go through all existing entries and set a FindWhatCodeAccesses bp
for i: = 0 to FoundCodeList. Items. Count- 1 do
begin
coderecord: = TCodeRecord( foundcodelist. items[ i] . data) ;
2013-06-07 14:57:31 +00:00
coderecord. diffcount: = 0 ;
2013-06-06 23:53:32 +00:00
coderecord. formChangedAddresses: = debuggerthread. FindWhatCodeAccesses( coderecord. address, self) ;
end ;
2013-06-07 14:57:31 +00:00
if FoundCodeList. Column[ 0 ] . Width< FoundCodeList. Canvas. TextWidth( '9999 (8)' ) then //make sure it's displayed
FoundCodeList. Column[ 0 ] . Width: = FoundCodeList. Canvas. TextWidth( '9999 (8)' ) ;
2013-06-06 23:53:32 +00:00
end
else
miFindWhatAccesses. checked: = false ;
end
else
begin
//deactivate all bp's
//go through bplist and remove all bp's
for i: = 0 to FoundCodeList. Items. Count- 1 do
begin
coderecord: = TCodeRecord( foundcodelist. items[ i] . data) ;
if coderecord. formChangedAddresses< > nil then
2021-08-22 12:50:43 +02:00
begin
coderecord. formChangedAddresses. Close; //brings reference count to 0, so will autodestroy
coderecord. formChangedAddresses: = nil ;
end ;
2013-06-06 23:53:32 +00:00
end ;
end ;
end ;
2021-08-10 15:34:32 +02:00
procedure TFoundCodeDialog. miFindWhatCodeAccessesClick( Sender: TObject) ;
var a: ptruint;
begin
if foundcodelist. ItemIndex< > - 1 then
MemoryBrowser. findWhatthisCodeAccesses( TcodeRecord( foundcodelist. items[ foundcodelist. itemindex] . data) . address) ;
end ;
2013-05-04 21:58:14 +00:00
function TFoundCodeDialog. getSelection: string ;
var
i: integer ;
begin
result : = '' ;
for i: = 0 to FoundcodeList. Items. count- 1 do
if FoundcodeList. items[ i] . selected then
result : = result + FoundcodeList. Items[ i] . subitems[ 0 ] + #13 #10 ;
end ;
procedure TFoundCodeDialog. miSaveTofileClick( Sender: TObject) ;
var
s: TStringList;
begin
if savedialog1. execute then
begin
s: = tstringlist. create;
s. text : = getSelection;
2018-06-12 20:23:45 +02:00
try
s. SaveToFile( savedialog1. filename) ;
finally
freeandnil( s) ;
end ;
2013-05-04 21:58:14 +00:00
end ;
end ;
2011-07-04 19:52:53 +00:00
procedure TFoundCodeDialog. pmOptionsPopup( Sender: TObject) ;
begin
ReplacewithcodethatdoesnothingNOP1. Enabled: = foundcodelist. selcount> 0 ;
Showthisaddressinthedisassembler1. enabled: = foundcodelist. itemindex< > - 1 ;
Addtothecodelist1. enabled: = foundcodelist. selcount> 0 ;
MoreInfo1. Enabled: = foundcodelist. itemindex< > - 1 ;
2021-08-22 12:50:43 +02:00
miFindWhatCodeAccesses. enabled: = foundcodelist. itemindex< > - 1 ;
2011-07-04 19:52:53 +00:00
Copyselectiontoclipboard1. enabled: = foundcodelist. selcount> 0 ;
2016-09-24 14:02:05 +02:00
miSaveTofile. enabled: = Copyselectiontoclipboard1. Enabled;
2011-07-04 19:52:53 +00:00
end ;
procedure TFoundCodeDialog. Copyselectiontoclipboard1Click( Sender: TObject) ;
begin
2013-05-04 21:58:14 +00:00
clipboard. AsText: = getSelection;
2011-07-04 19:52:53 +00:00
end ;
2021-05-04 14:49:20 +02:00
procedure TFoundCodeDialog. timerEntryInfoUpdateTimer( Sender: TObject) ;
2020-08-21 20:00:21 +02:00
var
i: integer ;
starttime: qword;
c: FoundCodeUnit. TCodeRecord;
2021-05-04 14:49:20 +02:00
updateAddressString: boolean ;
news: string ;
2020-08-21 20:00:21 +02:00
begin
starttime: = GetTickCount64;
2021-05-04 14:49:20 +02:00
updateAddressString: = true ;
2020-08-21 20:00:21 +02:00
for i: = 0 to foundcodelist. Items. Count- 1 do
begin
c: = FoundCodeUnit. TCodeRecord( foundcodelist. items[ i] . data) ;
2021-05-04 14:49:20 +02:00
if c< > nil then
begin
if updateAddressString and ( c. addressString= '' ) then
c. addressString: = symhandler. getNameFromAddress( c. address) ;
if gettickcount64- starttime> 2 5 0 then updateAddressString: = false ; //next time better
2022-06-19 10:58:16 +02:00
if miFindWhatAccesses. checked or ( TCodeRecord( foundcodelist. Items[ i] . data) . diffcount< > 0 ) then
2021-05-04 14:49:20 +02:00
news: = inttostr( c. hitcount) + ' (' + inttostr( TCodeRecord( foundcodelist. Items[ i] . data) . diffcount) + ')'
else
news: = inttostr( c. hitcount) ;
2020-08-21 20:00:21 +02:00
2021-05-04 14:49:20 +02:00
if FoundcodeList. items[ i] . caption< > news then
FoundcodeList. items[ i] . caption: = news;
2020-08-21 20:00:21 +02:00
2021-05-04 14:49:20 +02:00
end ;
2020-08-21 20:00:21 +02:00
end ;
2021-05-04 14:49:20 +02:00
2020-08-21 20:00:21 +02:00
end ;
2011-07-04 19:52:53 +00:00
initialization
{$i FoundCodeUnit.lrs}
end .