unit MemoryBrowserFormUnit; {$MODE Delphi} interface uses {$ifdef darwin} LCLType, {$endif} {$ifdef windows} jwawindows, windows,imagehlp, {$endif} LCLProc, LCLIntf, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, frmMemoryAllocHandlerUnit, math, StdCtrls, Spin, ExtCtrls,CEFuncProc,symbolhandler,Clipbrd, Menus,plugin,CEDebugger,KernelDebugger, Assemblerunit,disassembler,addressparser, Buttons, Contnrs, disassemblerviewunit, PEInfoFunctions ,DissectCodeThread,stacktrace2, NewKernelHandler, ComCtrls, LResources, byteinterpreter, StrUtils, hexviewunit, debughelper, debuggertypedefinitions,frmMemviewPreferencesUnit, registry, disassemblerComments, multilineinputqueryunit, frmMemoryViewExUnit, LastDisassembleData, ProcessHandlerUnit, commonTypeDefs, binutils, fontSaveLoadRegistry, LazFileUtils, ceregistry, frmCR3SwitcherUnit, betterControls, ScrollBoxEx, contexthandler,iptlogdisplay {$ifdef darwin}, macport, macportdefines{$endif} ; type { TMemoryBrowser } TMemoryBrowser = class(TForm) aflabel: TLabel; cflabel: TLabel; CSLabel: TLabel; dflabel: TLabel; dispQwords: TMenuItem; DSLabel: TLabel; EAXLabel: TLabel; EBPlabel: TLabel; EBXlabel: TLabel; ECXlabel: TLabel; EDIlabel: TLabel; EDXlabel: TLabel; EIPlabel: TLabel; ESIlabel: TLabel; ESlabel: TLabel; ESPlabel: TLabel; FSlabel: TLabel; GSlabel: TLabel; miClearCache: TMenuItem; miIPTLog: TMenuItem; miShowRelativeDisassembler: TMenuItem; miArchX86: TMenuItem; miArchArm: TMenuItem; miArchAutodetect: TMenuItem; MenuItem4: TMenuItem; copyBytesAndOpcodesAndComments: TMenuItem; MenuItem5: TMenuItem; MenuItem6: TMenuItem; miArchitecture: TMenuItem; miCR3Switcher: TMenuItem; miShowSectionAddresses: TMenuItem; miOpenInDissectData: TMenuItem; miCopyOpcodesOnly: TMenuItem; miUndoLastEdit: TMenuItem; miFollowInHexview: TMenuItem; miSetSpecificBreakpoint: TMenuItem; miWatchBPHardware: TMenuItem; miWatchBPException: TMenuItem; miWatchBPDBVM: TMenuItem; N9: TMenuItem; miSetBreakpointSW: TMenuItem; miSetBreakpointHW: TMenuItem; miSetBreakpointPE: TMenuItem; miSetBreakpointDBVMExec: TMenuItem; mvImageList: TImageList; MenuItem1: TMenuItem; MenuItem10: TMenuItem; miSearchForAccessibleStrings: TMenuItem; MenuItem12: TMenuItem; MenuItem13: TMenuItem; MenuItem14: TMenuItem; miDBVMFindoutwhataddressesthisinstructionaccesses: TMenuItem; Showdebugtoolbar1: TMenuItem; miCopyAddressesOnly: TMenuItem; miHideToolbar: TMenuItem; miDBVMActivateCloak: TMenuItem; miDBVMDisableCloak: TMenuItem; miUltimap: TMenuItem; MenuItem15: TMenuItem; MenuItem16: TMenuItem; MenuItem17: TMenuItem; MenuItem18: TMenuItem; MenuItem19: TMenuItem; miLoadTrace: TMenuItem; dispChar: TMenuItem; dispShorts: TMenuItem; DispLongs: TMenuItem; miTextEncoding: TMenuItem; miWatchMemoryPageAccess: TMenuItem; miSetUnsetBookmark: TMenuItem; miGotoBookmark: TMenuItem; miUserWriteInteger: TMenuItem; miUltimap2: TMenuItem; miWatchList: TMenuItem; miStackTraceSep: TMenuItem; miCompareStructures: TMenuItem; miCodeFilter: TMenuItem; miExceptionIgnoreList: TMenuItem; N19: TMenuItem; miUnexpectedExceptionBreakNever: TMenuItem; miUnexpectedExceptionBreakAlways: TMenuItem; miUnexpectedExceptionBreakIfInRegion: TMenuItem; miExceptionRegionSeperator: TMenuItem; miExceptionRegionManageList: TMenuItem; miExceptionRegionAutoAddAllocs: TMenuItem; miBreakOnExceptions: TMenuItem; miRunUnhandled: TMenuItem; miChangeProtectionRWE: TMenuItem; miChangeProtectionRE: TMenuItem; miChangeProtectionRW: TMenuItem; miChangeProtectionR: TMenuItem; miTextEncodingCodePage: TMenuItem; miSVCopy: TMenuItem; miShowRelative: TMenuItem; miHVBack: TMenuItem; miHVFollow: TMenuItem; miAddRef: TMenuItem; miTextEncodingUTF8: TMenuItem; miDebugSetAddress: TMenuItem; miGNUAssembler: TMenuItem; miBinutilsSelect: TMenuItem; miBinUtils: TMenuItem; miSetBookmark0: TMenuItem; miGotoBookmark0: TMenuItem; miSetBookmark1: TMenuItem; miSetBookmark2: TMenuItem; miSetBookmark3: TMenuItem; miSetBookmark4: TMenuItem; miSetBookmark5: TMenuItem; miSetBookmark6: TMenuItem; miSetBookmark7: TMenuItem; miSetBookmark8: TMenuItem; miSetBookmark9: TMenuItem; miGotoBookmark1: TMenuItem; miGotoBookmark2: TMenuItem; miGotoBookmark3: TMenuItem; miGotoBookmark4: TMenuItem; miGotoBookmark5: TMenuItem; miGotoBookmark6: TMenuItem; miGotoBookmark7: TMenuItem; miGotoBookmark8: TMenuItem; miGotoBookmark9: TMenuItem; miTextEncodingAscii: TMenuItem; miTextEncoding16: TMenuItem; miReferencedFunctions: TMenuItem; miUserDefinedHeader: TMenuItem; miShowIndisassembler: TMenuItem; miShowInHexview: TMenuItem; miCopyBytesOnly: TMenuItem; miDissectData2: TMenuItem; miPointerSpider: TMenuItem; MenuItem9: TMenuItem; miDisassembly32: TMenuItem; miDisassembly64: TMenuItem; miDisassemblyAutodetect: TMenuItem; miDisassemblerType: TMenuItem; miAddEBP: TMenuItem; miAddESP: TMenuItem; miFindWhatWrites: TMenuItem; miSelectCurrentFunction: TMenuItem; MenuItem3: TMenuItem; miDataBreakPointMenu: TMenuItem; miWatchAccess: TMenuItem; miWatchWrite: TMenuItem; MenuItem7: TMenuItem; miBreakAndTrace: TMenuItem; miFindWhatAccesses: TMenuItem; miDeleteBP: TMenuItem; miLock: TMenuItem; miShowDifference: TMenuItem; miUserdefinedComment: TMenuItem; miSepEvery4Bytes: TMenuItem; miSepEvery8Bytes: TMenuItem; miSepEvery2Bytes: TMenuItem; miSeperators: TMenuItem; miConditionalBreak: TMenuItem; miTextPreferences: TMenuItem; miLuaEngine: TMenuItem; miPaging: TMenuItem; miDebugEvents: TMenuItem; miLockRowsize: TMenuItem; memorypopup: TPopupMenu; Goto1: TMenuItem; debuggerpopup: TPopupMenu; oflabel: TLabel; pnlGeneralRegisters: TPanel; pnlExtraRegisters: TPanel; pnlFlags: TPanel; pflabel: TLabel; pmRegisters: TPopupMenu; pmDebugToolbar: TPopupMenu; sbShowFloats: TButton; sflabel: TLabel; SSlabel: TLabel; Timer2: TTimer; Panel1: TPanel; Panel4: TPanel; miReplacewithnops: TMenuItem; Gotoaddress1: TMenuItem; Search1: TMenuItem; Change1: TMenuItem; Addthisaddresstothelist1: TMenuItem; miAddToTheCodelist: TMenuItem; N1: TMenuItem; N2: TMenuItem; Splitter1: TSplitter; Panel5: TPanel; RegisterView: TPanel; MainMenu1: TMainMenu; File1: TMenuItem; Loadsymbolfile1: TMenuItem; Debug1: TMenuItem; miDebugStep: TMenuItem; miDebugStepOver: TMenuItem; miDebugRunTill: TMenuItem; miDebugToggleBreakpoint: TMenuItem; tbDebug: TToolBar; tbRun: TToolButton; tbStepInto: TToolButton; tbStepOver: TToolButton; tbSeparator1: TToolButton; tbStepOut: TToolButton; tbSeparator2: TToolButton; tbToggleBreakpoint: TToolButton; tbRunTill: TToolButton; tbSeparator3: TToolButton; tbRunUnhandled: TToolButton; View1: TMenuItem; Stacktrace1: TMenuItem; ScrollBox1: TScrollBox; lblRegisters: TLabel; sRegisters: TShape; lblFlags: TLabel; sFlags: TShape; lblSpecial: TLabel; sSpecial: TShape; miDebugRun: TMenuItem; Threadlist1: TMenuItem; Assemble1: TMenuItem; N3: TMenuItem; miDebugBreak: TMenuItem; Extra1: TMenuItem; Reservememory1: TMenuItem; Savedisassemledoutput1: TMenuItem; Savememoryregion1: TMenuItem; Loadmemolryregion1: TMenuItem; N4: TMenuItem; OpenMemory: TOpenDialog; Debugstrings1: TMenuItem; CreateThread1: TMenuItem; MemoryRegions1: TMenuItem; FillMemory1: TMenuItem; Disectwindow1: TMenuItem; SaveDialog1: TSaveDialog; Heaps1: TMenuItem; N5: TMenuItem; N6: TMenuItem; EnumeratedllsandSymbols1: TMenuItem; InjectDLL1: TMenuItem; OpenDllDialog: TOpenDialog; AutoInject1: TMenuItem; Dissectcode1: TMenuItem; N7: TMenuItem; N8: TMenuItem; Findstaticpointers1: TMenuItem; Scanforcodecaves1: TMenuItem; Changestateofregisteratthislocation1: TMenuItem; miTogglebreakpoint: TMenuItem; Breakpointlist1: TMenuItem; Makepagewritable1: TMenuItem; Dissectdata1: TMenuItem; N10: TMenuItem; miShowSymbols: TMenuItem; miDissectData: TMenuItem; N11: TMenuItem; N12: TMenuItem; miShowModuleAddresses: TMenuItem; miUserdefinedSymbols: TMenuItem; Kerneltools1: TMenuItem; Allocatenonpagedmemory1: TMenuItem; Getaddress1: TMenuItem; Search2: TMenuItem; Assemblycode1: TMenuItem; Findmemory1: TMenuItem; Driverlist1: TMenuItem; Plugins1: TMenuItem; Sericedescriptortable1: TMenuItem; N13: TMenuItem; Cut1: TMenuItem; Pastefromclipboard1: TMenuItem; N14: TMenuItem; Setsymbolsearchpath1: TMenuItem; miKernelmodeSymbols: TMenuItem; Breakandtraceinstructions1: TMenuItem; GDTlist1: TMenuItem; IDTlist1: TMenuItem; Newwindow1: TMenuItem; Follow1: TMenuItem; Copytoclipboard1: TMenuItem; copyBytes: TMenuItem; copyOpcodes: TMenuItem; copyBytesAndOpcodes: TMenuItem; DissectPEheaders1: TMenuItem; Back1: TMenuItem; Showvaluesofstaticaddresses1: TMenuItem; Findoutwhataddressesthisinstructionaccesses1: TMenuItem; DisplayType1: TMenuItem; N15: TMenuItem; dispBytes: TMenuItem; dispWords: TMenuItem; dispDwords: TMenuItem; dispFloat: TMenuItem; dispDouble: TMenuItem; dispInts: TMenuItem; Jumplines1: TMenuItem; Showjumplines1: TMenuItem; Onlyshowjumplineswithinrange1: TMenuItem; Watchmemoryallocations1: TMenuItem; Continueanddetachdebugger1: TMenuItem; N16: TMenuItem; Panel3: TPanel; Splitter3: TSplitter; pnlStacktrace: TPanel; pmStacktrace: TPopupMenu; All1: TMenuItem; Modulesonly1: TMenuItem; Nonsystemmodulesonly1: TMenuItem; lvStacktraceData: TListView; N17: TMenuItem; Maxstacktracesize1: TMenuItem; Splitter2: TSplitter; Referencedstrings1: TMenuItem; N18: TMenuItem; stacktrace2: TMenuItem; miDebugExecuteTillReturn: TMenuItem; zflabel: TLabel; procedure Debug1Click(Sender: TObject); procedure FormActivate(Sender: TObject); procedure GotoBookmarkClick(Sender: TObject); procedure Makepagewritable1Click(Sender: TObject); procedure memorypopupPopup(Sender: TObject); procedure MenuItem10Click(Sender: TObject); procedure miClearCacheClick(Sender: TObject); procedure miSearchForAccessibleStringsClick(Sender: TObject); procedure MenuItem12Click(Sender: TObject); procedure MenuItem14Click(Sender: TObject); procedure MenuItem8Click(Sender: TObject); procedure miArchChangeClick(Sender: TObject); procedure miCR3SwitcherClick(Sender: TObject); procedure miDBVMFindoutwhataddressesthisinstructionaccessesClick(Sender: TObject); procedure MenuItem4Click(Sender: TObject); procedure miIPTLogClick(Sender: TObject); procedure miOpenInDissectDataClick(Sender: TObject); procedure miShowRelativeDisassemblerClick(Sender: TObject); procedure miShowSectionAddressesClick(Sender: TObject); procedure miUndoLastEditClick(Sender: TObject); procedure miFollowInHexviewClick(Sender: TObject); procedure miSetSpecificBreakpointClick(Sender: TObject); procedure miSetBreakpointClick(Sender: TObject); procedure miCodeFilterClick(Sender: TObject); procedure miDBVMActivateCloakClick(Sender: TObject); procedure miDBVMDisableCloakClick(Sender: TObject); procedure miHideToolbarClick(Sender: TObject); procedure miUltimapClick(Sender: TObject); procedure MenuItem17Click(Sender: TObject); procedure MenuItem18Click(Sender: TObject); procedure miLoadTraceClick(Sender: TObject); procedure miWatchMemoryPageAccessClick(Sender: TObject); procedure miUserWriteIntegerClick(Sender: TObject); procedure miUltimap2Click(Sender: TObject); procedure miWatchListClick(Sender: TObject); procedure miCompareStructuresClick(Sender: TObject); procedure miAddRefClick(Sender: TObject); procedure miBreakOnExceptionsClick(Sender: TObject); procedure miChangeProtectionClick(Sender: TObject); procedure miExceptionIgnoreListClick(Sender: TObject); procedure miExceptionRegionAutoAddAllocsClick(Sender: TObject); procedure miExceptionRegionManageListClick(Sender: TObject); procedure miHVBackClick(Sender: TObject); procedure miHVFollowClick(Sender: TObject); procedure miDebugSetAddressClick(Sender: TObject); procedure miGNUAssemblerClick(Sender: TObject); procedure miBinutilsSelectClick(Sender: TObject); procedure miRunUnhandledClick(Sender: TObject); procedure miShowRelativeClick(Sender: TObject); procedure miSVCopyClick(Sender: TObject); procedure miUnexpectedExceptionBreakOptionClick(Sender: TObject); procedure pmRegistersPopup(Sender: TObject); procedure pmStacktracePopup(Sender: TObject); procedure RegisterViewResize(Sender: TObject); procedure SetBookmarkClick(Sender: TObject); procedure miTextEncodingClick(Sender: TObject); procedure miReferencedFunctionsClick(Sender: TObject); procedure miShowIndisassemblerClick(Sender: TObject); procedure miCopyBytesOnlyClick(Sender: TObject); procedure miDissectData2Click(Sender: TObject); procedure miPointerSpiderClick(Sender: TObject); procedure miSelectCurrentFunctionClick(Sender: TObject); procedure miDataBreakPointMenuClick(Sender: TObject); procedure miWatchAccessClick(Sender: TObject); procedure miWatchWriteClick(Sender: TObject); procedure miBreakAndTraceClick(Sender: TObject); procedure MenuItem9Click(Sender: TObject); procedure miAddESPClick(Sender: TObject); procedure miConditionalBreakClick(Sender: TObject); procedure miDeleteBPClick(Sender: TObject); procedure miDisassemblyAutodetectClick(Sender: TObject); procedure miFindWhatAccessesClick(Sender: TObject); procedure miFindWhatWritesClick(Sender: TObject); procedure miSepClick(Sender: TObject); procedure miShowInHexviewClick(Sender: TObject); procedure miTextPreferencesClick(Sender: TObject); procedure miDebugEventsClick(Sender: TObject); procedure miLuaEngineClick(Sender: TObject); procedure miPagingClick(Sender: TObject); procedure miUserdefinedCommentClick(Sender: TObject); procedure miUserDefinedHeaderClick(Sender: TObject); procedure Panel5Click(Sender: TObject); procedure RegisterMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure miLockRowsizeClick(Sender: TObject); procedure Showdebugtoolbar1Click(Sender: TObject); procedure Splitter1Moved(Sender: TObject); procedure FormShow(Sender: TObject); procedure FormCreate(Sender: TObject); procedure Goto1Click(Sender: TObject); procedure FormResize(Sender: TObject); procedure Splitter2Moved(Sender: TObject); procedure Timer2Timer(Sender: TObject); procedure miReplacewithnopsClick(Sender: TObject); procedure FControl1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure FControl1KeyPress(Sender: TObject; var Key: Char); procedure Gotoaddress1Click(Sender: TObject); procedure Search1Click(Sender: TObject); procedure Change1Click(Sender: TObject); procedure Addthisaddresstothelist1Click(Sender: TObject); procedure miAddToTheCodelistClick(Sender: TObject); procedure Splitter1CanResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean); procedure ScrollBar2Scroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure miDebugRunClick(Sender: TObject); procedure miDebugStepClick(Sender: TObject); procedure miDebugStepOverClick(Sender: TObject); procedure miDebugRunTillClick(Sender: TObject); procedure Stacktrace1Click(Sender: TObject); procedure Threadlist1Click(Sender: TObject); procedure Assemble1Click(Sender: TObject); procedure HexEditKeyPress(Sender: TObject; var Key: Char); procedure HexEditExit(Sender: TObject); procedure HexEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure RegisterLabelDblClick(Sender: TObject); procedure miDebugBreakClick(Sender: TObject); procedure Reservememory1Click(Sender: TObject); procedure Savememoryregion1Click(Sender: TObject); procedure Loadmemolryregion1Click(Sender: TObject); procedure HexEditDblClick(Sender: TObject); procedure Debugstrings1Click(Sender: TObject); procedure TextEditExit(Sender: TObject); procedure TextEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure CreateThread1Click(Sender: TObject); procedure MemoryRegions1Click(Sender: TObject); procedure TextEditKeyPress(Sender: TObject; var Key: Char); procedure FillMemory1Click(Sender: TObject); procedure Disectwindow1Click(Sender: TObject); procedure Savedisassemledoutput1Click(Sender: TObject); procedure Heaps1Click(Sender: TObject); procedure EnumeratedllsandSymbols1Click(Sender: TObject); procedure InjectDLL1Click(Sender: TObject); procedure AutoInject1Click(Sender: TObject); procedure Dissectcode1Click(Sender: TObject); procedure Createjumptocodecave1Click(Sender: TObject); procedure Findstaticpointers1Click(Sender: TObject); procedure Scanforcodecaves1Click(Sender: TObject); procedure Changestateofregisteratthislocation1Click(Sender: TObject); procedure miTogglebreakpointClick(Sender: TObject); procedure Breakpointlist1Click(Sender: TObject); procedure Dissectdata1Click(Sender: TObject); procedure miShowSymbolsClick(Sender: TObject); procedure miDissectDataClick(Sender: TObject); procedure miShowModuleAddressesClick(Sender: TObject); procedure miUserdefinedSymbolsClick(Sender: TObject); procedure Allocatenonpagedmemory1Click(Sender: TObject); procedure Getaddress1Click(Sender: TObject); procedure Findmemory1Click(Sender: TObject); procedure Assemblycode1Click(Sender: TObject); procedure Driverlist1Click(Sender: TObject); procedure Sericedescriptortable1Click(Sender: TObject); procedure MBCanvasMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); procedure Cut1Click(Sender: TObject); procedure Pastefromclipboard1Click(Sender: TObject); procedure Setsymbolsearchpath1Click(Sender: TObject); procedure miKernelmodeSymbolsClick(Sender: TObject); procedure Breakandtraceinstructions1Click(Sender: TObject); procedure debuggerpopupPopup(Sender: TObject); procedure GDTlist1Click(Sender: TObject); procedure IDTlist1Click(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure Newwindow1Click(Sender: TObject); procedure Follow1Click(Sender: TObject); procedure copyBytesAndOpcodesClick(Sender: TObject); procedure DissectPEheaders1Click(Sender: TObject); procedure Back1Click(Sender: TObject); procedure Showvaluesofstaticaddresses1Click(Sender: TObject); procedure Findoutwhataddressesthisinstructionaccesses1Click( Sender: TObject); procedure sbShowFloatsClick(Sender: TObject); procedure ScriptConsole1Click(Sender: TObject); procedure DisplayTypeClick(Sender: TObject); procedure Showjumplines1Click(Sender: TObject); procedure Onlyshowjumplineswithinrange1Click(Sender: TObject); procedure View1Click(Sender: TObject); procedure Watchmemoryallocations1Click(Sender: TObject); procedure Maxstacktracesize1Click(Sender: TObject); procedure All1Click(Sender: TObject); procedure Modulesonly1Click(Sender: TObject); procedure Nonsystemmodulesonly1Click(Sender: TObject); procedure Referencedstrings1Click(Sender: TObject); procedure stacktrace2Click(Sender: TObject); procedure miDebugExecuteTillReturnClick(Sender: TObject); procedure lvStacktraceDataData(Sender: TObject; Item: TListItem); procedure lvStacktraceDataDblClick(Sender: TObject); private { Private declarations } hasBeenShown: boolean; R8Label: TLabel; R9Label: TLabel; R10Label: TLabel; R11Label: TLabel; R12Label: TLabel; R13Label: TLabel; R14Label: TLabel; R15Label: TLabel; xlabel: array [16..31] of tlabel; posloadedfromreg: boolean; displaytype: TDisplayType; editing: boolean; editing2: boolean; srow,scolumn: integer; memorylabelcount: integer; addresslabelcount: integer; addresslabel: array of TLabel; memorylabel: array of TLabel; //hex memoryLabelA: array of TLabel; //ascii MemoryLabelVerticalLines: integer; //number of rows MemoryLabelHorizontalLines: Integer; //the number of lines addressestext: array of string[8]; memorytext: array of string[2]; memorystring: array of string; lengthof8bytes: Integer; // x:tno lines: integer; oldlines: integer; Highlightcolor: Tcolor; fAccessedRegisterColor: TColor; fChangedRegisterColor: TColor; numberofaddresses: integer; part: integer; lastmodulelistupdate: integer; disassemblerHistory: TStringList; memorybrowserHistory: TStringList; assemblerHistory: TStringList; lastspecialwidth: integer; FShowValues: boolean; FShowDebugPanels: boolean; FStacktraceSize: integer; strace: Tstringlist; lastBreakpointCondition: record script: string; easy: boolean; end; bookmarks: array [0..9] of record addressString: string; lastAddress: ptruint; setMi: TMenuItem; gotoMi: TMenuItem; end; currentBinutils: Tbinutils; StackReference: ptruint; adjustedsize: boolean; registerpanelfont: TFont; overridebreakpointmethod: boolean; preferedF5BreakpointMethod: TBreakpointMethod; followRegister: PContextElement_register; fcr3: qword; fcr3switcher: TfrmCR3Switcher; procedure ShowDebugToolbar; procedure HideDebugToolbar; procedure cr3switcherCR3Change(sender: TObject); procedure SetStacktraceSize(size: integer); procedure setShowDebugPanels(state: boolean); function getShowValues: boolean; procedure setShowValues(newstate: boolean); procedure disassemblerviewDblClick(Sender: TObject); procedure setHexviewAddress(a: ptrUint); function getHexviewAddress:ptrUint; procedure hexviewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); procedure ApplyFollowRegister; procedure setCR3(newcr3: qword); function ReadProcessMemory(hProcess: THandle; lpBaseAddress, lpBuffer: Pointer; nSize: size_t; var lpNumberOfBytesRead: PTRUINT): BOOL; procedure setCaption(c: string); function getCaption: string; public { Public declarations } FSymbolsLoaded: Boolean; thhandle: Thandle; disassemblerview: TDisassemblerview; hexview: THexview; context: pointer; contexthandler: TContextInfo; laststack: pbytearray; disassembler: boolean; cancelsearch: boolean; ischild: boolean; //determines if it's the main memorybrowser or a child // backlist: TStack; frmiptlog: TfrmIPTLogDisplay; showdebugpaneltimer: TTimer; procedure showDebugPaneltimertimer(sender: TObject); procedure setRegisterPanelFont(f: TFont); procedure FindwhatThiscodeAccesses(address: ptrUint); procedure DBVMFindwhatThiscodeAccesses(address: ptrUint); procedure AssemblePopup(x: string); procedure plugintype1click(sender:tobject); procedure plugintype6click(sender:tobject); procedure setcodeanddatabase; procedure GetEntryPointAndDataBase(var code: ptrUint; var data: ptrUint); property showvalues: boolean read getShowValues write setShowValues; property showDebugPanels: boolean read fShowDebugPanels write setShowDebugPanels; property stacktraceSize: integer read FStacktraceSize write SetStacktraceSize; property memoryaddress: ptrUint read getHexviewAddress write setHexviewAddress; procedure reloadStacktrace; function GetReturnaddress: ptrUint; procedure OnMemoryViewerRunning; procedure UpdateDebugContext(threadhandle: THandle; threadid: dword; changeSelection: boolean=true; _debuggerthread: TDebuggerthread=nil); procedure miLockOnClick(Sender: TObject); procedure miLockMemviewClick(sender: TObject); procedure miDifferenceClick(Sender: TObject); procedure miStopDifferenceClick(Sender: TObject); procedure Scrollboxscroll(sender: TObject); procedure createcr3switcher; property cr3switcher: TfrmCR3Switcher read fcr3switcher; published //support for old scripts that reference these property Run1: TMenuItem read miDebugRun; property Step1: TMenuItem read miDebugStep; property StepOver1: TMenuItem read miDebugStepOver; property Executetillreturn1: TMenuItem read miDebugExecuteTillReturn; property RunTill1: TMenuItem read miDebugRunTill; property miSetAddress: TMenuItem read miDebugSetAddress; property Setbreakpoint1: TMenuItem read miDebugToggleBreakpoint; property Showsymbols1: TMenuItem read miShowSymbols; property Kernelmodesymbols1: TMenuItem read miKernelmodeSymbols; property Showmoduleaddresses1: TMenuItem read miShowModuleAddresses; property Symbolhandler1: TMenuItem read miUserdefinedSymbols; property AccessedRegisterColor: TColor read faccessedRegisterColor write faccessedRegisterColor; property ChangedRegisterColor: TColor read fChangedRegisterColor write fChangedRegisterColor; property CR3: QWORD read fCR3 write setCR3; property Caption: string read getCaption write setCaption; end; var MemoryBrowser: TMemoryBrowser; mbchildcount: integer; //global so all other children can increase it as well MemoryBrowsers: TList; //contains a list of all the memorybrowsers implementation uses Valuechange, MainUnit, debugeventhandler, findwindowunit, frmstacktraceunit, frmBreakThreadUnit, FormDebugStringsUnit, frmDissectWindowUnit, frmEnumerateDLLsUnit, frmThreadlistunit, formmemoryregionsunit, frmHeapsUnit, frmFindstaticsUnit, frmModifyRegistersUnit, savedisassemblyfrm, frmBreakpointlistunit, AdvancedOptionsUnit, frmautoinjectunit, formsettingsunit, frmSaveMemoryRegionUnit, frmLoadMemoryunit, inputboxtopunit, formAddToCodeList, frmFillMemoryUnit, frmCodecaveScannerUnit, FoundCodeUnit, frmSelectionlistunit, symbolconfigunit, frmFloatingPointPanelUnit, frmTracerUnit, dissectcodeunit, DriverList, formChangedAddresses, PEInfounit, frmGDTunit, frmIDTunit, frmDisassemblyscanunit, ServiceDescriptorTables, frmReferencedStringsUnit, frmReferencedFunctionsUnit, Structuresfrm, StructuresFrm2, pointerscannerfrm, frmDebugEventsUnit, frmPagingUnit, frmluaengineunit, disassemblerviewlinesunit, frmBreakpointConditionUnit, frmStringMapUnit, frmStringPointerScanUnit, frmFilePatcherUnit, frmUltimapUnit, frmUltimap2Unit, frmAssemblyScanUnit, MemoryQuery, AccessedMemory, Parsers, GnuAssembler, frmEditHistoryUnit, frmWatchlistUnit, vmxfunctions, frmstructurecompareunit, globals, UnexpectedExceptionsHelper, frmExceptionRegionListUnit, frmExceptionIgnoreListUnit, frmcodefilterunit, frmDBVMWatchConfigUnit, DBK32functions, DPIHelper, DebuggerInterface, DebuggerInterfaceAPIWrapper, BreakpointTypeDef, CustomTypeHandler, frmSourceDisplayUnit, sourcecodehandler, tcclib, mainunit2, GDBServerDebuggerInterface {$ifdef ONEBYTEJUMPS}, autoassemblerexeptionhandler{$endif}; resourcestring rsUnlinkFromOtherHexview = 'Unlink from other hexview'; rsLinkWithOtherHexview = 'Link with other hexview'; rsStopShowingTheDifference = 'Stop showing the difference'; rsShowDifference = 'Show difference'; rsBetween = 'Between %s'; rsHowLongShouldAChangeBeShown = 'How long should a change be shown?'; rsChangeDisplayFader = 'Change display fader'; rsGotoAddress = 'Goto Address'; rsFillInTheAddressYouWantToGoTo = 'Fill in the address you want to go to'; rsMemoryViewerRunning = 'Memory Viewer - Running'; rsCheatEngineSingleLingeAssembler = 'Single-line assembler'; rsTypeYourAssemblerCodeHereAddress = 'Type your assembler code here: (address=%s)'; rsTheGeneratedCodeIsByteSLongButTheSelectedOpcodeIsB = 'The generated code is %s byte(s) long, but the selected opcode is %s byte(s) long! Do you want to replace the ' +'incomplete opcode(s) with NOP''s?'; rsIDonTUnderstandWhatYouMeanWith = 'I don''t understand what you mean with %s'; rsChangeRegister = 'Change register'; rsWhatIsTheNewValueOf = 'What is the new value of %s?'; rs0Or1 = '(0 or 1)'; rsIsNotAValidValue = '%s is not a valid value'; rsAllocateMemory = 'Allocate memory'; rsHowMuchMemoryDoYouWantToAddToThisProcess = 'How much memory do you want to add to this process?'; rsHowMuchIs = 'How much is %s?'; rsErrorAllocatingMemory = 'Error allocating memory!'; rsAtLeastBytesHaveBeenAllocatedAtDoYouWantToGoThereN = 'At least %s bytes have been allocated at %s%sDo you want to go there now?'; rsCreateRemoteThread = 'Create remote thread'; rsWhatWillBeTheStartaddressOfThisThread = 'What will be the startaddress of this thread?'; rsPleaseEnterAValidHexadecimalAddres = 'Please enter a valid hexadecimal addres'; rsYouWantToGiveAnAdditional32BitParameterWillShowUpI = 'You want to give an additional 32-bit parameter? (Will show up in (R)/(E)BX)'; rsPleaseEnterAValidHexadecimalValue = 'Please enter a valid hexadecimal value'; rsPleaseTargetAProcessFirst = 'Please target a process first'; rsPleaseTargetAnotherProcess = 'Start another version of '+strCheatEngine+' and attach to that instead'; rsDoYouWantToExecuteAFunctionOfTheDll = 'Do you want to execute a function of the dll?'; rsInjectDll = 'Inject dll'; rsSelectTheFunctionYouWantToExecute = 'Select the function you want to execute'; rsDLLInjected = 'DLL Injected'; rsHowMuchMemoryDoYouWishToAllocate = 'How much memory do you wish to allocate?'; rsAtLeastBytesHaveBeenAllocatedAtGoThereNow = 'At least %s bytes have been allocated at %s. Go there now?'; rsGetKernelAddress = 'Get kernel address'; rsGiveTheNameOfTheFunctionYouWantToFindCaseSensitive = 'Give the name of the function you want to find (Case sensitive,certain words can cause blue screens)'; rsAssemblyScan = 'Assembly scan'; rsInputTheAssemblyCodeToFindWilcardsSupported = 'Input the assembly code to find. Wildcards( * ) supported.'; rsSymbolHandler = 'Symbol handler'; rsPleaseSpecifyTheNewSymbolSearchpathSeperatesPaths = 'Please specify the new symbol searchpath (; separates paths)'; rsMemoryBrowser = 'MemoryBrowser'; rsReturnAddress = 'Return Address'; rsParameters = 'Parameters'; rsAddress = 'Address'; rsValue = 'Value'; rsStacktrace = 'Stacktrace'; rsNewSize = 'New size'; rsMaxStacktraceSize = 'Max stacktrace size'; rsNeedToRunDissectCode = 'You will need to run the dissect code routine first before this window is usable. Run it now?'; rsMemoryViewerCurrentlyDebuggingThread = 'Memory Viewer - Currently debugging thread %s'; rsRestoreWithOrginalCode = 'Restore with original code'; rsReplaceWithCodeThatDoesNothing = 'Replace with code that does nothing'; rsComment = 'Comment'; rsCommentFor = 'Comment for %s'; rsHeaderFor = 'Header for %s'; rsSShowsTheAutoguessValue = '(%s shows the autoguess value)'; rsMBBookmark = 'Bookmark %d'; rsMBBookmark2 = 'Bookmark %d: %s'; rsMBCreationOfTheRemoteThreadFailed = 'Creation of the remote thread failed'; rsMBThreadCreated = 'Thread Created'; rsBecauseOfUnhandledExeption = 'Because of unhandled exception %s'; rsSomethingHappened = 'something happened'; rsSetBreakpoint = 'Set breakpoint'; rsRemoveBreakpoint = 'Remove breakpoint'; rsInjectDYLIB = 'Inject DYLIB'; rsSetCustomAlignment = 'Set custom alignment'; //property functions: function TMemoryBrowser.getShowValues: boolean; begin result:=FShowValues; end; procedure TMemoryBrowser.setShowValues(newstate: boolean); begin Showvaluesofstaticaddresses1.checked:=newstate; FShowValues:=newstate; if disassemblerview<>nil then disassemblerview.setCommentsTab(FShowValues); end; procedure TMemoryBrowser.setShowDebugPanels(state: boolean); var oldstackwidth: integer; oldpanel3width: integer; cw: integer; ew: integer; begin oldstackwidth:=pnlStacktrace.Width; oldpanel3width:=panel3.width; FShowDebugPanels:=state; registerview.Visible:=state; pnlStacktrace.Visible:=state; splitter2.Visible:=state; splitter3.Visible:=state; pnlStacktrace.width:=oldstackwidth; end; procedure TMemoryBrowser.SetStacktraceSize(size: integer); var x: ptrUint; begin if (context=nil) or (contexthandler=nil) then exit; FStacktraceSize:=size; if laststack<>nil then freememandnil(laststack); laststack:=getmem(size); readprocessmemory(processhandle, pointer(contexthandler.StackPointerRegister^.getValue(context)), laststack, size, x); reloadStacktrace; end; procedure TMemoryBrowser.setCaption(c: string); var cr3pos, cr3posend: integer; begin cr3pos:=pos(' (CR3 ',c); if (fcr3<>0) and (cr3pos=0) then //add the statement which CR3 this is c:=c+' (CR3 '+inttohex(fcr3,8)+')'; if (fcr3=0) and (cr3pos<>0) then //delete it begin cr3posend:=Pos(')',c,cr3pos+1); if cr3posend>0 then c:=copy(c,1,cr3pos-1)+copy(c,cr3posend+1); end; inherited caption:=c; end; function TMemoryBrowser.getCaption: string; begin result:=inherited caption; end; //^^^^ function TMemoryBrowser.ReadProcessMemory(hProcess: THandle; lpBaseAddress, lpBuffer: Pointer; nSize: size_t; var lpNumberOfBytesRead: PTRUINT): BOOL; begin if fcr3=0 then result:={$ifdef windows}newkernelhandler.{$endif}{$ifdef darwin}macport.{$endif}ReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nsize, lpNumberOfBytesRead) {$ifdef windows} else result:=ReadProcessMemoryCR3(fcr3,lpBaseAddress, lpBuffer, nsize, lpNumberOfBytesRead){$endif}; end; procedure TMemoryBrowser.Splitter1Moved(Sender: TObject); begin disassemblerview.Update; end; procedure TMemoryBrowser.miLockRowsizeClick(Sender: TObject); var rs: string; waslocked: boolean; newsize: integer; begin waslocked:=hexview.LockedRowSize<>0; hexview.LockRowsize; //fills in lockedRowSize rs:=inttostr(hexview.LockedRowSize); if InputQuery('Alignment','Enter the custom alignment (<=0 is automatic)', rs) then begin try newsize:=StrToInt(rs); if newsize<=0 then newsize:=0; hexview.LockedRowSize:=newsize; except if waslocked=false then hexview.UnlockRowsize; end; end else begin if waslocked=false then hexview.UnlockRowsize; end; end; procedure TMemoryBrowser.ShowDebugToolbar; begin tbDebug.Visible:=true; tbDebug.Tag:=0; Showdebugtoolbar1.Checked:=true; showDebugPanels:=true; end; procedure TMemoryBrowser.HideDebugToolbar; begin tbDebug.Visible:=false; Showdebugtoolbar1.Checked:=false; showDebugPanels:=false; end; procedure TMemoryBrowser.Showdebugtoolbar1Click(Sender: TObject); begin if tbDebug.Visible=false then ShowDebugToolbar else HideDebugToolbar; end; procedure TMemoryBrowser.RegisterMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var s: string; i: integer; begin if button = mbright then begin if (sender is TLabel) then begin s:=trim(tlabel(sender).Caption); i:=pos(' ',s); if i>0 then //should always be true begin s:=copy(s,i+1,length(s)); clipboard.AsText:=s; end; end; end; end; procedure TMemoryBrowser.miDebugEventsClick(Sender: TObject); begin if frmDebugEvents=nil then frmDebugEvents:=tfrmDebugEvents.create(application); frmDebugEvents.show; end; procedure TMemoryBrowser.miLuaEngineClick(Sender: TObject); begin //start lua engine window if frmLuaEngine=nil then frmLuaEngine:=TfrmLuaEngine.create(MemoryBrowser); //main mb frmLuaEngine.show; end; procedure TMemoryBrowser.miPagingClick(Sender: TObject); begin TfrmPaging.create(application).show; end; procedure TMemoryBrowser.miUserdefinedCommentClick(Sender: TObject); var s: tstringlist; begin s:=tstringlist.create; try s.text:=dassemblercomments.comments[disassemblerview.SelectedAddress]; if multilineinputquery(Format(rsCommentFor, [inttohex(disassemblerview.SelectedAddress, 8)]), Format(rsCommentFor, [inttohex(disassemblerview.SelectedAddress, 8)])+' '+rsSShowsTheAutoguessValue, s) then dassemblercomments.comments[disassemblerview.SelectedAddress]:=utf8toansi(s.text); finally s.free; end; disassemblerview.Refresh; end; procedure TMemoryBrowser.miUserDefinedHeaderClick(Sender: TObject); var s: tstringlist; begin s:=tstringlist.create; try s.text:=ansitoutf8(dassemblercomments.commentHeader[disassemblerview.SelectedAddress]); if multilineinputquery(rsHeaderFor, Format(rsCommentFor, [inttohex(disassemblerview.SelectedAddress, 8)])+' '+rsSShowsTheAutoguessValue, s) then dassemblercomments.commentHeader[disassemblerview.SelectedAddress]:=utf8toansi(s.text); finally s.free; end; disassemblerview.Refresh; end; procedure TMemoryBrowser.Panel5Click(Sender: TObject); begin end; procedure TMemoryBrowser.miLockOnClick(Sender: TObject); begin hexview.unlock; end; procedure TMemoryBrowser.miLockMemviewClick(sender: TObject); begin hexview.Lock(TMemoryBrowser(MemoryBrowsers[(sender as TMenuItem).tag]).hexview); end; procedure TMemoryBrowser.miDifferenceClick(Sender: TObject); begin hexview.ShowDifference(TMemoryBrowser(MemoryBrowsers[(sender as TMenuItem).tag]).hexview); end; procedure TMemoryBrowser.miStopDifferenceClick(Sender: TObject); begin hexview.EndDifferenceView; end; procedure TMemoryBrowser.memorypopupPopup(Sender: TObject); var m: TMemorybrowser; mi: menus.tmenuitem; i,j: integer; islocked: boolean; a,a2: ptruint; hasbp: boolean; mbi: TMEMORYBASICINFORMATION; begin miClearCache.visible:=(CurrentDebuggerInterface<>nil) and (CurrentDebuggerInterface is TGDBServerDebuggerInterface) and GDBReadProcessMemory; //update customtypes for i:=0 to customTypes.Count-1 do begin j:=dispDouble.MenuIndex+1+i; if jdispDouble.MenuIndex+customTypes.Count+1 do DisplayType1.Delete(dispDouble.MenuIndex+customTypes.Count+1); miShowDifference.clear; miLock.Clear; islocked:=hexview.isLocked; if isLocked then begin miLock.OnClick:=miLockOnClick; miLock.caption:=rsUnlinkFromOtherHexview; end else begin miLock.OnClick:=nil; miLock.caption:=rsLinkWithOtherHexview; end; if hexview.isShowingDifference then begin miShowDifference.caption:=rsStopShowingTheDifference; miShowDifference.onclick:=miStopDifferenceClick; end else begin miShowDifference.caption:=rsShowDifference; miShowDifference.onclick:=nil; end; miLock.enabled:=MemoryBrowsers.count>1; for i:=0 to MemoryBrowsers.count-1 do begin m:=Memorybrowsers[i]; if m<>self then begin if not hexview.isShowingDifference then begin miClearCache:=TMenuItem.Create(miShowDifference); miClearCache.Caption:=Format(rsBetween, [m.Caption]); miClearCache.OnClick:=miDifferenceClick; miClearCache.tag:=i; miShowDifference.Add(miClearCache); end; if not islocked then begin miClearCache:=TMenuItem.Create(miLock); miClearCache.caption:=m.caption; miClearCache.OnClick:=miLockMemviewClick; miClearCache.tag:=i; miLock.add(miClearCache); end; end; end; if (hexview.hasSelection) then begin hexview.GetSelectionRange(a,a2); hasbp:=(debuggerthread<>nil) and (debuggerthread.isBreakpoint(a,a2)<>nil); miDataBreakPointMenu.visible:=(not ischild) and (not hasbp); miWatchWrite.visible:=not hasbp; miWatchAccess.visible:=not hasbp; MenuItem7.visible:=not hasbp; miBreakAndTrace.visible:=not hasbp; miDeleteBP.visible:=hasbp; miHVFollow.Visible:=hexview.CanFollow; Addthisaddresstothelist1.visible:=true; end else begin miDataBreakPointMenu.visible:=false; miWatchWrite.visible:=false; miWatchAccess.visible:=false; MenuItem7.visible:=false; miBreakAndTrace.visible:=false; miDeleteBP.visible:=false; Addthisaddresstothelist1.visible:=false; end; miHVBack.visible:=hexview.hasBackList; miShowRelative.checked:=hexview.UseRelativeBase; miChangeProtectionRWE.checked:=false; miChangeProtectionRE.checked:=false; miChangeProtectionRW.checked:=false; miChangeProtectionR.checked:=false; if VirtualQueryEx(processhandle, pointer(hexview.Address), mbi, sizeof(mbi))=sizeof(mbi) then begin miChangeProtectionRWE.checked:=((mbi.Protect and PAGE_EXECUTE_READWRITE)=PAGE_EXECUTE_READWRITE) or ((mbi.Protect and PAGE_EXECUTE_WRITECOPY)=PAGE_EXECUTE_WRITECOPY); miChangeProtectionRE.checked:=((mbi.Protect and PAGE_EXECUTE)=PAGE_EXECUTE) or ((mbi.Protect and PAGE_EXECUTE_READ)=PAGE_EXECUTE_READ); miChangeProtectionRW.checked:=((mbi.Protect and PAGE_READWRITE)=PAGE_READWRITE) or ((mbi.Protect and PAGE_WRITECOPY)=PAGE_WRITECOPY); miChangeProtectionR.checked:=((mbi.Protect and PAGE_READONLY)=PAGE_READONLY); end; // miWatchBPHardware.enabled:=(CurrentDebuggerInterface=nil) or (dbcHardwareBreakpoint in CurrentDebuggerInterface.DebuggerCapabilities); miWatchBPException.enabled:=(CurrentDebuggerInterface=nil) or (dbcSoftwareBreakpoint in CurrentDebuggerInterface.DebuggerCapabilities); miWatchBPDBVM.enabled:=(CurrentDebuggerInterface=nil) or (dbcExceptionBreakpoint in CurrentDebuggerInterface.DebuggerCapabilities); miWatchBPDBVM.visible:={$ifdef windows}hasEPTSupport{$else}false{$endif}; if hexview.LockedRowSize<>0 then miLockRowsize.caption:=rsSetCustomAlignment+' ('+inttostr(hexview.LockedRowSize)+')' else miLockRowsize.caption:=rsSetCustomAlignment; miChangeProtectionRWE.enabled:=SystemSupportsWritableExecutableMemory; miChangeProtectionRWE.visible:=SystemSupportsWritableExecutableMemory; end; procedure TMemoryBrowser.MenuItem10Click(Sender: TObject); begin if frmStringMap=nil then frmStringMap:=TfrmStringMap.Create(application); frmStringMap.show; end; procedure TMemoryBrowser.miClearCacheClick(Sender: TObject); begin if (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then TGDBServerDebuggerInterface(CurrentDebuggerInterface).ClearRPMCachePage(hexview.Address); end; procedure TMemoryBrowser.miSearchForAccessibleStringsClick(Sender: TObject); begin if frmStringPointerscan=nil then frmStringpointerscan:=Tfrmstringpointerscan.create(MemoryBrowser); frmStringpointerscan.rbStringscan.Checked:=true; frmStringpointerscan.edtBase.text:=inttohex(hexview.address,8); frmStringpointerscan.show; end; procedure TMemoryBrowser.MenuItem12Click(Sender: TObject); var f: Tfrmfilepatcher; begin f:=tfrmfilepatcher.create(self); f.showmodal; f.free; end; procedure TMemoryBrowser.MenuItem14Click(Sender: TObject); begin EnableWindowsSymbols(true); end; procedure TMemoryBrowser.MenuItem8Click(Sender: TObject); begin end; procedure TMemorybrowser.setCR3(newcr3: qword); var oldcr3: qword; begin oldcr3:=fcr3; if debuggerthread<>nil then debuggerthread.execlocation:=4120; fcr3:=newcr3; disassemblerview.cr3:=fcr3; if debuggerthread<>nil then debuggerthread.execlocation:=4121; hexview.cr3:=fcr3; if debuggerthread<>nil then debuggerthread.execlocation:=4122; if (newcr3<>oldcr3) then begin if debuggerthread<>nil then debuggerthread.execlocation:=4123; createcr3switcher; if debuggerthread<>nil then debuggerthread.execlocation:=4124; fcr3switcher.addCR3ToList(newcr3); if debuggerthread<>nil then debuggerthread.execlocation:=4125; fcr3switcher.Show; if debuggerthread<>nil then debuggerthread.execlocation:=4126; end; caption:=caption; end; procedure TMemoryBrowser.cr3switcherCR3Change(sender: TObject); begin //cr3 changed, notify the disassembler and hexview cr3:=cr3switcher.cr3; end; procedure TMemoryBrowser.createcr3switcher; begin if fcr3switcher=nil then begin fcr3switcher:=TfrmCR3Switcher.Create(self); fcr3switcher.OnCR3Change:=cr3switcherCR3Change; end; end; procedure TMemoryBrowser.miCR3SwitcherClick(Sender: TObject); begin //the cr3 switcher is unique for each memview window createcr3switcher; fcr3switcher.Show; end; procedure TMemoryBrowser.miDBVMFindoutwhataddressesthisinstructionaccessesClick(Sender: TObject); begin DBVMFindwhatThiscodeAccesses(disassemblerview.SelectedAddress); end; procedure TMemoryBrowser.MenuItem4Click(Sender: TObject); begin if tbDebug.Visible=true then HideDebugToolbar; tbDebug.Tag:=-1; end; procedure TMemoryBrowser.miIPTLogClick(Sender: TObject); var log: pointer; logsize: integer; begin {$IFDEF WINDOWS} log:=nil; if (debuggerthread<>nil) and (debuggerthread.CurrentThread<>nil) then begin //broken state if debuggerthread.CurrentThread.getLastIPTLog(log,logsize)=false then begin if useintelptfordebug=false then begin if messagedlg('This will require the IPT feature to be enabled in the debugger. Activate it now? (You will need a new break to record a log)', mtConfirmation, [mbyes,mbno],0)=mryes then begin useintelptfordebug:=true; debuggerthread.initIntelPTTracing; end; end else begin if debuggerthread.initIntelPTTracing then messagedlg('Error retrieving the IPT log. Try again later', mtError, [mbok],0) else messagedlg('Error activating the IPT log', mtError, [mbok],0) end; exit; end; if frmiptlog=nil then begin frmiptlog:=TfrmIPTLogDisplay.Create(MemoryBrowser); frmiptlog.OnClose:=nil; end; frmiptlog.show; if log<>nil then begin frmiptlog.loadlog(debuggerthread.CurrentThread.ThreadId.ToHexString+'-'+GetTickCount.ToHexString,log,logsize, contexthandler.InstructionPointerRegister^.getValue(context)); freemem(log); end; end; {$ENDIF} end; procedure TMemoryBrowser.miOpenInDissectDataClick(Sender: TObject); begin //create it with tfrmstructures2.create(application) do begin initialaddress:=hexview.SelectionStart; show; end; end; procedure TMemoryBrowser.miShowRelativeDisassemblerClick(Sender: TObject); begin if miShowRelativeDisassembler.checked then begin if disassemblerview.SelectedAddress<>0 then begin disassemblerview.RelativeBase:=disassemblerview.SelectedAddress; disassemblerview.UseRelativeBase:=true; end else begin disassemblerview.RelativeBase:=disassemblerview.TopAddress; disassemblerview.UseRelativeBase:=true; end; end else disassemblerview.UseRelativeBase:=false; disassemblerview.update; end; procedure TMemoryBrowser.miUndoLastEditClick(Sender: TObject); begin if logWrites then begin undowrite(disassemblerview.SelectedAddress); end; end; procedure TMemoryBrowser.ApplyFollowRegister; begin if (followRegister<>nil) and (context<>nil) then hexview.address:=followRegister^.getValue(context); end; procedure TMemoryBrowser.miFollowInHexviewClick(Sender: TObject); begin if miFollowInHexview.checked then followRegister:=PContextElement_register(pmRegisters.PopupComponent.Tag) else followRegister:=nil; end; procedure TMemoryBrowser.miSetSpecificBreakpointClick(Sender: TObject); begin end; procedure TMemoryBrowser.miSetBreakpointClick(Sender: TObject); var bpm: TBreakpointMethod; begin if startdebuggerifneeded(true) then begin case tmenuitem(sender).tag of 0: bpm:=bpmDebugRegister; 1: bpm:=bpmInt3; 2: bpm:=bpmException; 3: bpm:=bpmDBVM; end; overridebreakpointmethod:=true; preferedF5BreakpointMethod:=bpm; try DebuggerThread.SetOnExecuteBreakpoint(disassemblerview.SelectedAddress, bpm); disassemblerview.Update; except on e:exception do MessageDlg(e.message,mtError,[mbok],0); end; end; end; procedure TMemoryBrowser.miCodeFilterClick(Sender: TObject); begin if frmcodefilter=nil then frmcodefilter:=tfrmcodefilter.create(application); frmcodefilter.show; end; procedure TMemoryBrowser.miDBVMActivateCloakClick(Sender: TObject); var PA,VA: qword; begin {$ifdef windows} if isRunningDBVM and hasEPTSupport and (not hasCloakedRegionInRange(disassemblerview.SelectedAddress,1,VA,PA)) then begin VA:=disassemblerview.SelectedAddress; if GetPhysicalAddress(processhandle,pointer(VA),PA) then dbvm_cloak_activate(PA,VA) else MessageDlg('Failed obtaining the physical address of this memory', mtError, [mbok],0); end; {$endif} end; procedure TMemoryBrowser.miDBVMDisableCloakClick(Sender: TObject); var PA,VA: Qword; begin {$ifdef windows} if isRunningDBVM and hasEPTSupport and (hasCloakedRegionInRange(disassemblerview.SelectedAddress,1,VA,PA)) then dbvm_cloak_deactivate(PA); {$endif} end; procedure TMemoryBrowser.miHideToolbarClick(Sender: TObject); begin if tbDebug.Visible=true then HideDebugToolbar; end; procedure TMemoryBrowser.miUltimapClick(Sender: TObject); begin if frmUltimap=nil then frmUltimap:=TfrmUltimap.create(application); frmUltimap.show; end; procedure TMemoryBrowser.MenuItem17Click(Sender: TObject); begin //build a structure using a registered template and the current data stream end; procedure TMemoryBrowser.MenuItem18Click(Sender: TObject); begin TfrmMemoryViewEx.create(self).show; end; procedure TMemoryBrowser.miLoadTraceClick(Sender: TObject); var t: Tfrmtracer; begin t:=TFrmTracer.create(self,false,true); try t.miLoad.Click; except on e: exception do begin t.free; //not needed anymore messagedlg(e.Message, mterror, [mbok],0); exit; end; end; t.show; end; procedure TMemoryBrowser.miWatchMemoryPageAccessClick(Sender: TObject); begin if frmAccessedMemory=nil then frmAccessedMemory:=TfrmAccessedMemory.Create(application); frmAccessedMemory.Show; end; procedure TMemoryBrowser.miUserWriteIntegerClick(Sender: TObject); begin if frmEditHistory=nil then frmEditHistory:=tfrmEditHistory.create(application); frmEditHistory.show; end; procedure TMemoryBrowser.miUltimap2Click(Sender: TObject); begin if frmUltimap2=nil then frmUltimap2:=TfrmUltimap2.create(application); frmUltimap2.show; end; procedure TMemoryBrowser.miWatchListClick(Sender: TObject); begin if frmWatchlist=nil then frmWatchlist:=tfrmWatchlist.create(Application); frmWatchlist.UpdateContext(context); frmWatchlist.show; end; procedure TMemoryBrowser.miCompareStructuresClick(Sender: TObject); begin if frmStructureCompare=nil then frmStructureCompare:=tfrmStructureCompare.create(application); frmStructureCompare.show; end; procedure TMemoryBrowser.miDebugSetAddressClick(Sender: TObject); begin if (debuggerthread<>nil) and (debuggerthread.isWaitingToContinue) then begin debuggerthread.CurrentThread.context.{$ifdef cpu32}eip{$else}Rip{$endif}:=disassemblerview.SelectedAddress; debuggerthread.CurrentThread.setContext; debuggerthread.CurrentThread.UpdateMemoryBrowserContext; UpdateDebugContext(debuggerthread.CurrentThread.Handle, debuggerthread.CurrentThread.ThreadId); end; end; procedure TMemoryBrowser.miGNUAssemblerClick(Sender: TObject); var gnua: TfrmAutoInject; begin gnua:=TfrmAutoInject.Create(self); gnua.ScriptMode:=smGnuAssembler; gnua.show; end; procedure TMemoryBrowser.miBinutilsSelectClick(Sender: TObject); var id: integer; begin if (sender is TMenuItem) then begin id:=tmenuitem(sender).tag; if (id<0) or (id>=binutilslist.count) then begin defaultBinutils:=nil; miDisassemblerType.Enabled:=true; end else begin defaultBinutils:=TBinUtils(binutilslist[id]); miDisassemblerType.Enabled:=false; end; end; end; procedure TMemoryBrowser.miRunUnhandledClick(Sender: TObject); begin if debuggerthread<>nil then debuggerthread.continueDebugging(co_run, 0, false); OnMemoryViewerRunning; caption:=rsMemoryViewerRunning; end; procedure TMemoryBrowser.miShowRelativeClick(Sender: TObject); begin if miShowRelative.checked then begin if hexview.HasSelection then begin hexview.RelativeBase:=hexview.SelectionStart; hexview.UseRelativeBase:=true; end else begin hexview.RelativeBase:=hexview.TopAddress; hexview.UseRelativeBase:=true; end; end else hexview.UseRelativeBase:=false; hexview.update; end; procedure TMemoryBrowser.miSVCopyClick(Sender: TObject); var i,j: integer; s: tstringlist; str: string; begin s:=tstringlist.create; try for i:=0 to lvStacktraceData.Items.Count-1 do begin if lvStacktraceData.Items[i].Selected then begin str:=PadRight(lvStacktraceData.items[i].caption,20); for j:=0 to lvStacktraceData.items[i].SubItems.Count-1 do str:=str+' - '+PadRight(lvStacktraceData.items[i].SubItems[j],20); s.add(str); end; end; clipboard.AsText:=s.Text; finally s.free; end; end; procedure TMemoryBrowser.miUnexpectedExceptionBreakOptionClick(Sender: TObject); begin case TMenuItem(Sender).tag of 0: UnexpectedExceptionAction:=ueaIgnore; 1: UnexpectedExceptionAction:=ueaBreak; 2: UnexpectedExceptionAction:=ueaBreakIfInRegion; end; end; procedure TMemoryBrowser.pmRegistersPopup(Sender: TObject); begin miFollowInHexview.checked:=(followRegister<>nil) and (pmRegisters.PopupComponent<>nil) and (pmRegisters.PopupComponent.Tag=ptruint(followRegister)); end; procedure TMemoryBrowser.pmStacktracePopup(Sender: TObject); var i: integer; x: ptruint; s: string; haserror: boolean=true; begin if processhandler.is64Bit then begin miAddESP.Caption:='(rsp+*)'; miAddEBP.Caption:='(rbp+*)'; end else begin miAddESP.Caption:='(esp+*)'; miAddEBP.Caption:='(ebp+*)'; end; if lvStacktraceData.Selected<>nil then begin s:=lvStacktraceData.Selected.Caption; i:=pos('(', s); if i>0 then s:=copy(s,1,i-1); x:=symhandler.getAddressFromName(s,false,haserror); if not haserror then miAddRef.caption:=format('(ref+*) Ref will be %x',[x]); end; end; procedure TMemoryBrowser.RegisterViewResize(Sender: TObject); begin {$ifndef darwin} if scrollbox1.VertScrollBar.IsScrollBarVisible then sbShowFloats.Left:=scrollbox1.VertScrollBar.ClientSizeWithBar-sbShowFloats.Width else sbShowFloats.Left:=scrollbox1.VertScrollBar.ClientSizeWithoutBar-sbShowFloats.Width; {$endif} end; procedure TMemoryBrowser.miAddRefClick(Sender: TObject); var i: integer; s: string; haserror: boolean=true; x: ptruint; begin if lvStacktraceData.Selected<>nil then begin s:=lvStacktraceData.Selected.Caption; i:=pos('(', s); if i>0 then s:=copy(s,1,i-1); x:=symhandler.getAddressFromName(s,false,haserror); if not haserror then begin StackReference:=x; reloadStacktrace; end; end else begin miAddESP.Checked:=true; reloadStacktrace; end; end; procedure TMemoryBrowser.miBreakOnExceptionsClick(Sender: TObject); var n: TNotifyEvent; begin miExceptionRegionSeperator.Visible:=UnexpectedExceptionAction in [ueaBreak, ueaBreakIfInRegion]; miExceptionRegionAutoAddAllocs.Visible:=UnexpectedExceptionAction=ueaBreakIfInRegion; miExceptionRegionManageList.Visible:=UnexpectedExceptionAction=ueaBreakIfInRegion; miExceptionIgnoreList.visible:=UnexpectedExceptionAction in [ueaBreak, ueaBreakIfInRegion]; n:=miExceptionRegionAutoAddAllocs.OnClick; miExceptionRegionAutoAddAllocs.OnClick:=nil; miExceptionRegionAutoAddAllocs.checked:=allocsAddToUnexpectedExceptionList; miExceptionRegionAutoAddAllocs.OnClick:=n; miUnexpectedExceptionBreakNever.checked:=UnexpectedExceptionAction=ueaIgnore; miUnexpectedExceptionBreakAlways.checked:=UnexpectedExceptionAction=ueaBreak; miUnexpectedExceptionBreakIfInRegion.checked:=UnexpectedExceptionAction=ueaBreakIfInRegion; end; procedure TMemoryBrowser.miChangeProtectionClick(Sender: TObject); var protection: dword; oldprotect: dword; l: integer; begin case (sender as TMenuItem).Tag of 0: protection:=PAGE_EXECUTE_READWRITE; 1: protection:=PAGE_EXECUTE_READ; 2: protection:=PAGE_READWRITE; 3: protection:=PAGE_READONLY; else protection:=PAGE_EXECUTE_READWRITE; //never end; l:=max(1, hexview.SelectionStop-hexview.SelectionStart+1); //OutputDebugString(format('start=%d stop=%x l=%d',[hexview.SelectionStart, hexview.SelectionStop, l])); if hexview.HasSelection then VirtualProtectEx(processhandle, pointer(hexview.SelectionStart),l,protection, oldprotect) else VirtualProtectEx(processhandle, pointer(hexview.Address),l,protection, oldprotect) end; procedure TMemoryBrowser.miExceptionIgnoreListClick(Sender: TObject); begin if frmExceptionIgnoreList=nil then frmExceptionIgnoreList:=tfrmExceptionIgnoreList.Create(self); frmExceptionIgnoreList.show; end; procedure TMemoryBrowser.miExceptionRegionAutoAddAllocsClick(Sender: TObject); var n: TNotifyEvent; begin if frmExceptionRegionList<>nil then begin n:=frmExceptionRegionList.cbAutoAddAllocs.OnChange; frmExceptionRegionList.cbAutoAddAllocs.OnChange:=nil; frmExceptionRegionList.cbAutoAddAllocs.Checked:=miExceptionRegionAutoAddAllocs.checked; frmExceptionRegionList.cbAutoAddAllocs.OnChange:=n; end; allocsAddToUnexpectedExceptionList:=miExceptionRegionAutoAddAllocs.checked; end; procedure TMemoryBrowser.miExceptionRegionManageListClick(Sender: TObject); begin if frmExceptionRegionList=nil then frmExceptionRegionList:=tfrmExceptionRegionList.Create(self); frmExceptionRegionList.show; end; procedure TMemoryBrowser.miHVBackClick(Sender: TObject); begin hexview.back; end; procedure TMemoryBrowser.miHVFollowClick(Sender: TObject); begin hexview.follow; end; procedure TMemoryBrowser.SetBookmarkClick(Sender: TObject); var id: integer; begin if (sender=nil) or (not (sender is TMenuItem)) then exit; id:=TMenuItem(Sender).Tag; if (id<0) or (id>9) then exit; if disassemblerview.SelectedAddress=bookmarks[id].lastAddress then begin //delete bookmarks[id].addressString:=''; bookmarks[id].lastAddress:=0; bookmarks[id].setMi.caption:=format(rsMBBookmark, [id]); bookmarks[id].gotoMi.caption:=bookmarks[id].setMi.caption; end else begin //update bookmarks[id].addressString:=symhandler.getNameFromAddress(disassemblerview.SelectedAddress); bookmarks[id].lastAddress:=disassemblerview.SelectedAddress; bookmarks[id].setMi.Caption:=format(rsMBBookmark2, [id, bookmarks[id].addressString]); bookmarks[id].gotoMi.Caption:=bookmarks[id].setMi.caption; end; end; procedure TMemoryBrowser.GotoBookmarkClick(Sender: TObject); var err: boolean; id: integer; newaddress: ptruint; s: string; begin if (sender=nil) or (not (sender is TComponent)) then exit; id:=TComponent(Sender).Tag; if (id<0) or (id>9) then exit; if bookmarks[id].addressString='' then exit; s:=bookmarks[id].addressString; newaddress:=symhandler.getAddressFromName(s, false, err); if err then newaddress:=bookmarks[id].lastAddress; disassemblerview.SelectedAddress:=newaddress; end; procedure TMemoryBrowser.Makepagewritable1Click(Sender: TObject); begin end; procedure TMemoryBrowser.FormActivate(Sender: TObject); begin disassemblerview.LastFormActiveEvent:=getTickCount64; end; procedure TMemoryBrowser.Debug1Click(Sender: TObject); begin end; procedure TMemoryBrowser.miTextEncodingClick(Sender: TObject); begin if miTextEncodingAscii.checked then hexview.CharEncoding:=ceAscii else if miTextEncodingCodePage.checked then hexview.CharEncoding:=ceCodepage else if miTextEncodingUTF8.checked then hexview.CharEncoding:=ceUtf8 else hexview.CharEncoding:=ceUtf16; end; procedure TMemoryBrowser.miCopyBytesOnlyClick(Sender: TObject); var start, stop: ptruint; l,i: integer; x: string; x2: ptrUint; buf: pbytearray; result: string; begin //Unrelated to the copy bytes. This indicates the user just wants and AOB start:=minX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2); stop:=maxX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2); //adjust stop to go AFTER the instruction disassemble(stop, x); l:=stop-start; if l<65535 then //not going to do more than that begin getmem(buf, l); try if readprocessmemory(processhandle, pointer(start), buf, l, x2) then begin result:=''; for i:=0 to l-1 do result:=result+inttohex(buf[i],2)+' '; Clipboard.AsText:=copy(result,1,length(result)-1); end; finally freememandnil(buf); end; end; end; procedure TMemoryBrowser.miDissectData2Click(Sender: TObject); begin if frmStructures2.count>0 then begin // TfrmStructures2(frmStructures2[0]).edtAddress.Text:=inttohex(memorybrowser.memoryaddress,8); TfrmStructures2(frmStructures2[0]).show; end else begin //create it with tfrmstructures2.create(application) do begin initialaddress:=memoryaddress; show; if initialaddress=0 then //address 0 would normally NOT add a new address, but this is a user specified address, so do it anyhow addColumn; end; end; end; procedure TMemoryBrowser.miPointerSpiderClick(Sender: TObject); begin if frmStringPointerscan=nil then frmStringpointerscan:=Tfrmstringpointerscan.create(application); frmStringpointerscan.rbDatascan.Checked:=true; frmStringpointerscan.edtBase.text:=inttohex(hexview.address,8); frmStringpointerscan.show; end; procedure TMemoryBrowser.miSelectCurrentFunctionClick(Sender: TObject); var start,stop: ptrUint; pa, a: ptruint; d: TDisassembler; s: string; infloop: integer; begin //disassemble the code and find the last address // parametervaluetype:=dvtaddress; d:=TDisassembler.create; try start:=disassemblerview.SelectedAddress; //find stop: stop:=start; a:=stop; infloop:=0; while infloop<100000 do begin inc(infloop); pa:=a; d.disassemble(a,s); if (length(d.LastDisassembleData.Bytes)>=2) and (d.LastDisassembleData.Bytes[0]=0) and (d.LastDisassembleData.Bytes[1]=0) then begin stop:=pa; break; end; if (d.LastDisassembleData.opcode='??') or (d.LastDisassembleData.opcode='ret') or (d.LastDisassembleData.opcode='int 3') or (d.LastDisassembleData.opcode='nop') then //found the end begin stop:=pa; break; end; if (d.LastDisassembleData.isjump) and (not d.LastDisassembleData.iscall) then begin //adjust the current address to point if d.LastDisassembleData.parameterValueType=dvtAddress then //direct address begin if isAddress(d.LastDisassembleData.parameterValue) then begin if d.LastDisassembleData.parameterValue < start then begin start:=d.LastDisassembleData.parameterValue; continue; end; if d.LastDisassembleData.parameterValue > pa then begin stop:=d.LastDisassembleData.parameterValue; a:=stop; continue; end; if (d.LastDisassembleData.parameterValue <= a) and (d.LastDisassembleData.opcode='jmp') then //an unconditonal jump that jumps back and no conditonal jump encountered that went after this. Meaning: Infinite loop begin stop:=pa; break; end; end; end; end; end; //find start infloop:=0; pa:=start; d.disassemble(pa,s); //start from next one in case it's started from the begin while infloop<100000 do begin inc(infloop); a:=previousopcode(pa); pa:=a; d.disassemble(a,s); //look for 00 , 00 (add [eax],al is an 100% completely useless instruction) if (length(d.LastDisassembleData.Bytes)>=2) and (d.LastDisassembleData.Bytes[0]=0) and (d.LastDisassembleData.Bytes[1]=0) then begin start:=a; break; end; //look for ret, int3 or nop if (d.LastDisassembleData.opcode='??') or (d.LastDisassembleData.opcode='ret') or (d.LastDisassembleData.opcode='int 3') then begin start:=a; //start from next instruction break; end; if processhandler.is64Bit then begin //looks for sub rsp,xxxx on an address that is dividable by 0x10 if (pa mod $10 = 0) and (d.LastDisassembleData.opcode='sub') then begin if pos('rsp,', lowercase(d.LastDisassembleData.parameters))>0 then begin start:=pa; break; end; end; end else begin //look for push ebp if (d.LastDisassembleData.opcode='push') then begin if lowercase(d.LastDisassembleData.parameters)='ebp' then begin start:=pa; break; end; end; end; end; finally d.free; end; disassemblerview.SelectedAddress:=start; disassemblerview.SelectedAddress2:=stop; end; procedure TMemoryBrowser.miDataBreakPointMenuClick(Sender: TObject); begin end; procedure TMemoryBrowser.miWatchAccessClick(Sender: TObject); var a,a2: ptruint; bpm: TBreakpointMethod; begin try if (startdebuggerifneeded(true)) and (hexview.hasSelection) then begin hexview.GetSelectionRange(a,a2); bpm:=bpmDebugRegister; if miWatchBPException.checked then bpm:=bpmException else if miWatchBPDBVM.checked then bpm:=bpmDBVM; DebuggerThread.SetOnAccessBreakpoint(a, 1+(a2-a), bpm); hexview.Update; end; except on e: exception do messagedlg(e.message, mtError, [mbOK], 0); end; end; procedure TMemoryBrowser.miWatchWriteClick(Sender: TObject); var a,a2: ptruint; bpm: TBreakpointMethod; begin try if (startdebuggerifneeded(true)) and (hexview.hasSelection) then begin hexview.GetSelectionRange(a,a2); bpm:=bpmDebugRegister; if miWatchBPException.checked then bpm:=bpmException else if miWatchBPDBVM.checked then bpm:=bpmDBVM; DebuggerThread.SetOnWriteBreakpoint(a, 1+(a2-a),bpm); hexview.Update; end; except on e: exception do messagedlg(e.message, mtError, [mbOK], 0); end; end; procedure TMemoryBrowser.miBreakAndTraceClick(Sender: TObject); var bpm: TBreakpointMethod; begin bpm:=bpmDebugRegister; if miWatchBPException.checked then bpm:=bpmException else if miWatchBPDBVM.checked then bpm:=bpmDBVM; TFrmTracer.createWithBreakpointMethodSet(self,true,false,bpm).show; end; procedure TMemoryBrowser.MenuItem9Click(Sender: TObject); var stime: string; begin stime:=inttostr(hexview.fadetimer); if InputQuery(rsHowLongShouldAChangeBeShown, rsChangeDisplayFader, stime) then hexview.fadeTimer:=strtoint(stime); end; procedure TMemoryBrowser.miAddESPClick(Sender: TObject); begin reloadStacktrace; end; procedure TMemoryBrowser.miConditionalBreakClick(Sender: TObject); var script: string; easy: boolean; bp: PBreakpoint; begin bp:=debuggerthread.isBreakpoint(disassemblerview.SelectedAddress); if bp<>nil then begin inc(bp.referencecount); try with TfrmBreakpointCondition.create(self) do begin script:=debuggerthread.getbreakpointcondition(bp, easy); if script='' then begin script:=lastBreakpointCondition.script; easy:=lastBreakpointCondition.easy; if script='' then easy:=true; end; if easy then edtEasy.text:=script else mComplex.text:=script; rbEasy.Checked:=easy; rbComplex.checked:=not easy; if showmodal=mrok then begin easy:=rbEasy.checked; if easy then script:=edtEasy.text else script:=mComplex.text; lastBreakpointCondition.script:=script; lastBreakpointCondition.easy:=easy; debuggerthread.setbreakpointcondition(bp, easy, script); end; free; end; finally dec(bp.referencecount); end; end; end; procedure TMemoryBrowser.miDeleteBPClick(Sender: TObject); var bp: PBreakpoint; a,a2: ptruint; begin if (debuggerthread<>nil) then begin hexview.GetSelectionRange(a,a2); debuggerthread.lockbplist; try repeat bp:=debuggerthread.isBreakpoint(a,a2); if bp<>nil then debuggerthread.RemoveBreakpoint(bp); until bp=nil; finally debuggerthread.unlockbplist; end; hexview.update; end; end; procedure TMemoryBrowser.miArchChangeClick(Sender: TObject); begin if miArchAutodetect.checked then visibleDisassembler.architecture:=darchAutoDetect else if miArchX86.checked then visibleDisassembler.architecture:=darchX86 else visibleDisassembler.architecture:=darchArm; disassemblerview.Update; if ssCtrl in GetKeyShiftState then begin case visibleDisassembler.architecture of darchX86: processhandler.SystemArchitecture:=archX86; darchArm: processhandler.SystemArchitecture:=archArm; end; end; end; procedure TMemoryBrowser.miDisassemblyAutodetectClick(Sender: TObject); begin if miDisassemblyAutodetect.checked then visibleDisassembler.is64bitOverride:=false else if miDisassembly32.checked then begin visibleDisassembler.is64bitOverride:=true; visibleDisassembler.is64bitOverridestate:=false end else begin visibleDisassembler.is64bitOverride:=true; visibleDisassembler.is64bitOverridestate:=true; end; defaultDisassembler.is64bitOverride:=visibleDisassembler.is64bitoverride; defaultDisassembler.is64bitOverridestate:=visibleDisassembler.is64bitOverridestate; disassemblerview.update; if ssCtrl in GetKeyShiftState then begin if miDisassembly32.checked then processhandler.is64Bit:=false else processhandler.is64Bit:=true; end; end; procedure TMemoryBrowser.miFindWhatAccessesClick(Sender: TObject); var a,a2: ptruint; bpm: TBreakpointMethod; begin if (startdebuggerifneeded(true)) and (hexview.hasSelection) then begin hexview.GetSelectionRange(a,a2); bpm:=bpmDebugRegister; if miWatchBPException.checked then bpm:=bpmException else if miWatchBPDBVM.checked then bpm:=bpmDBVM; DebuggerThread.FindWhatAccesses(a,1+(a2-a), bpm); hexview.Update; end; end; procedure TMemoryBrowser.miFindWhatWritesClick(Sender: TObject); var a,a2: ptruint; bpm: TBreakpointMethod; begin if (startdebuggerifneeded(true)) and (hexview.hasSelection) then begin hexview.GetSelectionRange(a,a2); bpm:=bpmDebugRegister; if miWatchBPException.checked then bpm:=bpmException else if miWatchBPDBVM.checked then bpm:=bpmDBVM; DebuggerThread.FindWhatWrites(a,1+(a2-a), bpm); hexview.Update; end; end; procedure TMemoryBrowser.miSepClick(Sender: TObject); begin hexview.bytesPerSeperator:=TMenuItem(sender).Tag; end; procedure TMemoryBrowser.miShowInHexviewClick(Sender: TObject); begin hexview.address:=PContextElement_register(pmRegisters.PopupComponent.Tag)^.getValue(context); end; procedure TMemoryBrowser.miTextPreferencesClick(Sender: TObject); var x: TfrmMemviewPreferences; i: TDisassemblerViewColorsState; reg: tregistry; fd: TFontData; begin with TfrmMemviewPreferences.create(self) do begin fd:=Graphics.GetFontData(disassemblerview.font.handle); fontdialog1.font.Name:=fd.Name; fontdialog1.font.height:=fd.height; fontdialog1.font.Pitch:=fd.Pitch; fontdialog1.font.Style:=fd.Style; fontdialog1.font.CharSet:=fd.CharSet; fontdialog1.font.Quality:=fd.Quality; fontdialog1.font.Orientation:=fd.Orientation; btnFont.Caption:=fontdialog1.Font.Name+' '+inttostr(fontdialog1.Font.Size); //FontDialog2.Font.Assign(hexview.HexFont); fd:=Graphics.GetFontData(hexview.HexFont.handle); fontdialog2.font.Name:=fd.Name; fontdialog2.font.height:=fd.height; fontdialog2.font.Pitch:=fd.Pitch; fontdialog2.font.Style:=fd.Style; fontdialog2.font.CharSet:=fd.CharSet; fontdialog2.font.Quality:=hexview.HexFont.Quality; fontdialog2.font.Orientation:=fd.Orientation; cbFontQuality.ItemIndex:=integer(hexview.HexFont.Quality); btnHexFont.Caption:=fontdialog2.Font.Name+' '+inttostr(fontdialog2.Font.Size); fd:=Graphics.GetFontData(scrollbox1.Font.Reference.Handle); fontdialog3.font.Name:=fd.Name; fontdialog3.font.height:=fd.height; fontdialog3.font.Pitch:=fd.Pitch; fontdialog3.font.Style:=fd.Style; fontdialog3.font.CharSet:=fd.CharSet; fontdialog3.font.Quality:=scrollbox1.Font.Quality; fontdialog3.font.Orientation:=fd.Orientation; btnRegisterViewFont.Caption:=fontdialog3.Font.Name+' '+inttostr(fontdialog3.Font.Size); //set the current colors colors:=disassemblerview.colors; //and now apply those colors cbColorGroupChange(cbColorGroup); lblCall.font.color:=disassemblerview.jlCallColor; lblUnconditionalJump.font.color:=disassemblerview.jlUnconditionalJumpColor; lblConditionalJump.font.color:=disassemblerview.jlconditionalJumpColor; jlThickness:=disassemblerview.jlThickness; jlSpacing:=disassemblerview.jlSpacing; spaceAboveLines:=disassemblerview.spaceAboveLines; spaceBelowLines:=disassemblerview.spaceBelowLines; hexSpaceBetweenLines:=hexview.spaceBetweenLines; cbShowStatusBar.checked:=hexview.statusbar.Visible; {$ifdef USELAZFREETYPE} cbOriginalRenderingSystem.checked:=UseOriginalRenderingSystem; {$endif} cbCenterDisassemblerWhenOutsideView.checked:=disassemblerview.CenterOnAddressChangeOutsideView; lblHexNormal.font.color:=hexview.normalFontColor; lblHexNormal.color:=hexview.normalBackgroundColor; lblHexStatic.font.color:=hexview.staticFontColor; lblHexStatic.color:=hexview.staticBackgroundColor; lblHexHighlighted.font.color:=hexview.highlightedFontColor; lblHexHighlighted.color:=hexview.highlightedBackgroundColor; lblHexEditing.font.color:=hexview.EditingFontColor; lblHexEditing.color:=hexview.EditingBackgroundColor; lblHexSecondaryEditing.font.color:=hexview.SecondaryEditingFontColor; lblHexSecondaryEditing.color:=hexview.SecondaryEditingBackgroundColor; lblHexBreakpoint.font.color:=hexview.BreakpointFontColor; lblHexBreakpoint.color:=hexview.BreakpointBackgroundColor; lblHexDifferent.font.color:=hexview.DifferentFontColor; lblHexDifferent.color:=hexview.DifferentBackgroundColor; lblHexTopLine.Font.color:=hexview.toplinecolor; lblHexSeperator.Font.color:=hexview.seperatorColor; lblHexCursor.Font.color:=hexview.cursorcolor; lblHexFadeColor.font.color:=hexview.normalFontColor; lblHexFadeColor.color:=hexview.fadecolor; lblRegHighLightChange.color:=fChangedRegisterColor; lblRegHighLightAccess.color:=fAccessedRegisterColor; if showmodal=mrok then begin //set the colors and save to registry {$ifdef USELAZFREETYPE} UseOriginalRenderingSystem:=cbOriginalRenderingSystem.checked; {$endif} disassemblerview.Font.assign(fontdialog1.Font); disassemblerview.Font.style:=[]; disassemblerview.colors:=colors; disassemblerview.jlCallColor:=lblCall.font.color; disassemblerview.jlUnconditionalJumpColor:=lblUnconditionalJump.font.color; disassemblerview.jlconditionalJumpColor:=lblConditionalJump.font.color; disassemblerview.spaceAboveLines:=spaceAboveLines; disassemblerview.spaceBelowLines:=spaceBelowLines; disassemblerview.jlThickness:=jlThickness; disassemblerview.jlSpacing:=jlSpacing; disassemblerview.CenterOnAddressChangeOutsideView:=cbCenterDisassemblerWhenOutsideView.checked; hexview.HexFont:=fontdialog2.Font; hexview.normalFontColor:=lblHexNormal.font.color; hexview.normalBackgroundColor:=lblHexNormal.color; hexview.staticFontColor:=lblHexStatic.font.color; hexview.staticBackgroundColor:=lblHexStatic.color; hexview.highlightedFontColor:=lblHexHighlighted.font.color; hexview.highlightedBackgroundColor:=lblHexHighlighted.color; hexview.EditingFontColor:= lblHexEditing.font.color; hexview.EditingBackgroundColor:=lblHexEditing.color; hexview.SecondaryEditingFontColor:= lblHexSecondaryEditing.font.color; hexview.SecondaryEditingBackgroundColor:=lblHexSecondaryEditing.color; hexview.BreakpointFontColor:= lblHexBreakpoint.font.color; hexview.BreakpointBackgroundColor:=lblHexBreakpoint.color; hexview.DifferentFontColor:=lblHexDifferent.font.color; hexview.DifferentBackgroundColor:=lblHexDifferent.color; hexview.toplinecolor:=lblHexTopLine.Font.color; hexview.seperatorColor:=lblHexSeperator.Font.color; hexview.cursorcolor:=lblHexCursor.Font.color; hexview.fadecolor:=lblHexFadeColor.color; fChangedRegisterColor:=lblRegHighLightChange.color; fAccessedRegisterColor:=lblRegHighLightAccess.color; hexview.spaceBetweenLines:=hexSpaceBetweenLines; hexview.statusbar.Visible:=cbShowStatusBar.checked; hexview.OnResize(hexview); scrollbox1.Font:=fontdialog3.font; setRegisterPanelFont(fontdialog3.font); free; end else begin free; exit; end; end; disassemblerview.reinitialize; //save to the registry {$ifdef USELAZFREETYPE} cereg.writeBool('OriginalRenderingSystem', UseOriginalRenderingSystem); {$endif} reg:=Tregistry.Create; try if reg.OpenKey('\Software\'+strCheatEngine+'\Disassemblerview '+inttostr(screen.PixelsPerInch)+darkmodestring+'\',true) then begin reg.{$ifdef windows}WriteBinaryData{$else}WriteString{$endif}('colors', {$ifndef windows}bintohexs({$endif}disassemblerview.colors, sizeof(disassemblerview.colors)){$ifndef windows}){$endif}; reg.WriteInteger('AccessedRegisterColor', integer(fAccessedRegisterColor)); reg.WriteInteger('ChangedRegisterColor', integer(fChangedRegisterColor)); reg.WriteInteger('jlCallColor', integer(disassemblerview.jlCallColor)); reg.WriteInteger('jlUnconditionalJumpColor', integer(disassemblerview.jlUnconditionalJumpColor)); reg.WriteInteger('jlConditionalJumpColor', integer(disassemblerview.jlconditionalJumpColor)); reg.writeInteger('spaceAboveLines', disassemblerview.SpaceAboveLines); reg.writeInteger('spaceBelowLines', disassemblerview.SpaceBelowLines); reg.writeInteger('jlThickness', disassemblerview.jlThickness); reg.writeInteger('jlSpacing', disassemblerview.jlSpacing); reg.WriteBool('CenterOnAddressChangeOutsideView', disassemblerview.CenterOnAddressChangeOutsideView); end; if reg.OpenKey('\Software\'+strCheatEngine+'\Disassemblerview '+inttostr(screen.PixelsPerInch)+'\Font'+darkmodestring,true) then SaveFontToRegistry(disassemblerview.font, reg); if reg.OpenKey('\Software\'+strCheatEngine+'\Hexview '+inttostr(screen.PixelsPerInch),true) then begin reg.writeInteger('spaceBetweenLines', hexview.spaceBetweenLines); reg.WriteBool('showStatusBar', hexview.statusbar.Visible); end; if reg.openkey('\Software\'+strCheatEngine+'\Hexview'+darkmodestring,true) then begin reg.{$ifdef windows}WriteBinaryData{$else}WriteString{$endif}('colors', {$ifndef windows}bintohexs({$endif}hexview.colors, sizeof(hexview.colors)){$ifndef windows}){$endif}; reg.WriteInteger('SeperaterColor', hexview.fseperatorColor); reg.WriteInteger('CursorColor', hexview.fcursorcolor); reg.WriteInteger('TopLineColor', hexview.ftoplinecolor); reg.WriteInteger('FadeColor', hexview.ffadeColor); end; if reg.OpenKey('\Software\'+strCheatEngine+'\Hexview '+inttostr(screen.PixelsPerInch)+'\Font'+darkmodestring,true) then SaveFontToRegistry(hexview.hexfont, reg); if reg.OpenKey('\Software\'+strCheatEngine+'\RegisterView '+inttostr(screen.PixelsPerInch)+'\Font'+darkmodestring,true) then SaveFontToRegistry(scrollbox1.Font, reg); finally reg.free; end; end; procedure TMemoryBrowser.FormShow(Sender: TObject); var w: integer; addressSize: integer; byteSize: integer; opcodeSize: integer; lineheight: integer; begin registerpanelfont.assign(scrollbox1.Font); if posloadedfromreg=false then begin autosize:=false; w:=0; addressSize:=canvas.TextWidth('XXXXXXXXXXXXXXXX '); //address byteSize:=canvas.TextWidth('XX XX XX XX XX XX XX XX '); ///bytes opcodeSize:=canvas.TextWidth('XXXX XXX,[XXXXXXXXXXXXXXXX+XXX*X] '); disassemblerview.setheaderWidth(0,addressSize); disassemblerview.setheaderWidth(1,byteSize); disassemblerview.setheaderWidth(2,opcodeSize); lineheight:=canvas.TextHeight('jxZyYqQ'); width:=max(mainform.width, addressSize+byteSize+opcodeSize+2*addressSize); height:=ScaleY(600,96); panel1.height:= clientheight div 2; disassemblerview.setheaderWidth(3,max(32,disassemblerview.width-(disassemblerview.getheaderWidth(0)+disassemblerview.getheaderWidth(1)+disassemblerview.getheaderWidth(2))-32)); position:=poDesigned; position:=poScreenCenter; posloadedfromreg:=true; end; if disassemblerview<>nil then disassemblerview.Update; Sericedescriptortable1.visible:=not Is64bitOS; GDTlist1.Visible:=not is64bitos; IDTlist1.Visible:=not is64bitos; scrollbox1.Font.Height:=GetFontData(font.handle).height; if scrollbox1.Font.Height>-13 then scrollbox1.Font.Height:=-13; if hexview<>nil then hexview.statusbar.Height:=Canvas.TextHeight('BLAy9qrSTt')+3+hexview.statusbar.BorderWidth; if adjustedsize=false then begin tbDebug.ButtonHeight:=scaley(tbDebug.ButtonHeight, DesignTimePPI); //tbDebug.ButtonHeight:=trunc(tbDebug.ButtonHeight*fontmultiplication); ////dpihelper.AdjustToolbar(tbDebug); adjustedsize:=true; end; {$ifdef darwin} //need to adjust the formsize to trigger a repaint BoundsRect:=BoundsRect; {$endif} HasBeenShown:=true; end; procedure TMemoryBrowser.disassemblerviewDblClick(Sender: TObject); var m: TPoint; a: ptruint; lni: PLineNumberInfo; f: TfrmSourceDisplay; begin //find what column is clicked m:=disassemblerview.ScreenToClient(mouse.cursorpos); a:=disassemblerview.getReferencedByLineAtPos(m); if a<>0 then begin disassemblerview.SelectedAddress:=a; exit; end; lni:=disassemblerview.getSourceCodeAtPos(m); if lni<>nil then begin f:=getSourceViewForm(lni); if f<>nil then f.show(); exit; end; if m.x>(disassemblerview.getheaderWidth(0)+disassemblerview.getheaderWidth(1)+disassemblerview.getheaderWidth(2)) then begin miUserdefinedComment.click; //comment click exit; end; assemble1.Click; end; procedure TMemoryBrowser.FormCreate(Sender: TObject); var x: array of integer; reg: tregistry; f: TFont; i: integer; c: tcolor; begin registerpanelfont:=tfont.Create; MemoryBrowsers.Add(self); bookmarks[0].setMi:=miSetBookmark0; bookmarks[1].setMi:=miSetBookmark1; bookmarks[2].setMi:=miSetBookmark2; bookmarks[3].setMi:=miSetBookmark3; bookmarks[4].setMi:=miSetBookmark4; bookmarks[5].setMi:=miSetBookmark5; bookmarks[6].setMi:=miSetBookmark6; bookmarks[7].setMi:=miSetBookmark7; bookmarks[8].setMi:=miSetBookmark8; bookmarks[9].setMi:=miSetBookmark9; bookmarks[0].gotoMi:=miGotoBookmark0; bookmarks[1].gotoMi:=miGotoBookmark1; bookmarks[2].gotoMi:=miGotoBookmark2; bookmarks[3].gotoMi:=miGotoBookmark3; bookmarks[4].gotoMi:=miGotoBookmark4; bookmarks[5].gotoMi:=miGotoBookmark5; bookmarks[6].gotoMi:=miGotoBookmark6; bookmarks[7].gotoMi:=miGotoBookmark7; bookmarks[8].gotoMi:=miGotoBookmark8; bookmarks[9].gotoMi:=miGotoBookmark9; scrollbox1.Font:=mainform.font; scrollbox1.Font.name:='Courier New'; scrollbox1.Font.Size:=13; displaytype:=dtByte; strace:=tstringlist.create; disassembler:=true; disassemblerview:=TDisassemblerview.Create(self); disassemblerview.font:=mainform.font; disassemblerview.Align:=alClient; disassemblerview.Parent:=panel5; disassemblerview.PopupMenu:=debuggerpopup; disassemblerview.OnKeyDown:=FControl1keydown; disassemblerview.OnDblClick:=disassemblerviewDblClick; disassemblerview.TopAddress:=$00400000; disassemblerview.name:='DisassemblerView'; if GetFontData(disassemblerview.font.handle).height>-13 then disassemblerview.font.height:=-13; hexview:=THexview.create(self); hexview.Align:=alClient; hexview.parent:=panel3; hexview.popupmenu:=memorypopup; hexview.OnKeyDown:=hexviewKeyDown; hexview.Name:='HexadecimalView'; //load from the registry {$ifdef USELAZFREETYPE}; UseOriginalRenderingSystem:=cereg.readBool('OriginalRenderingSystem'); {$endif} f:=TFont.create; reg:=Tregistry.Create; try if reg.OpenKey('\Software\'+strCheatEngine+'\Disassemblerview '+inttostr(screen.PixelsPerInch)+'\Font'+darkmodestring,false) then begin LoadFontFromRegistry(f, reg); disassemblerview.font:=f; end; if reg.OpenKey('\Software\'+strCheatEngine+'\Disassemblerview '+inttostr(screen.PixelsPerInch)+darkmodestring+'\',false) then begin if reg.ValueExists('colors') then begin {$ifdef windows} reg.ReadBinaryData('colors', disassemblerview.colors, sizeof(disassemblerview.colors)); {$else} HexToBin(pchar(reg.ReadString('colors')),pchar(@disassemblerview.colors),sizeof(disassemblerview.colors)); {$endif} end; if reg.ValueExists('AccessedRegisterColor') then fAccessedRegisterColor:=tcolor(reg.ReadInteger('AccessedRegisterColor')); if reg.ValueExists('ChangedRegisterColor') then fChangedRegisterColor:=tcolor(reg.ReadInteger('ChangedRegisterColor')); if reg.ValueExists('jlCallColor') then disassemblerview.jlCallColor:=tcolor(reg.ReadInteger('jlCallColor')); if reg.ValueExists('jlUnconditionalJumpColor') then disassemblerview.jlUnconditionalJumpColor:=tcolor(reg.ReadInteger('jlUnconditionalJumpColor')); if reg.ValueExists('jlConditionalJumpColor') then disassemblerview.jlConditionalJumpColor:=tcolor(reg.ReadInteger('jlConditionalJumpColor')); if reg.ValueExists('spaceAboveLines') then disassemblerview.spaceAboveLines:=reg.ReadInteger('spaceAboveLines'); if reg.ValueExists('spaceBelowLines') then disassemblerview.spaceBelowLines:=reg.ReadInteger('spaceBelowLines'); if reg.ValueExists('jlThickness') then disassemblerview.jlThickness:=reg.ReadInteger('jlThickness'); if reg.ValueExists('jlSpacing') then disassemblerview.jlSpacing:=reg.ReadInteger('jlSpacing'); if reg.ValueExists('CenterOnAddressChangeOutsideView') then disassemblerview.CenterOnAddressChangeOutsideView:=reg.ReadBool('CenterOnAddressChangeOutsideView'); disassemblerview.reinitialize; end; if reg.OpenKey('\Software\'+strCheatEngine+'\Hexview '+inttostr(screen.PixelsPerInch),false) then begin if reg.ValueExists('spaceBetweenLines') then hexview.spaceBetweenLines:=reg.ReadInteger('spaceBetweenLines'); if reg.ValueExists('showStatusBar') then hexview.statusbar.Visible:=reg.ReadBool('showStatusBar'); end; if reg.openkey('\Software\'+strCheatEngine+'\Hexview'+darkmodestring,true) then begin if reg.ValueExists('colors') then begin {$ifdef windows} reg.ReadBinaryData('colors', hexview.colors, sizeof(hexview.colors)); {$else} HexToBin(pchar(reg.ReadString('colors')),pchar(@hexview.colors),sizeof(hexview.colors)); {$endif} end; if reg.ValueExists('SeperaterColor') then hexview.fseperatorColor:=reg.ReadInteger('SeperaterColor'); if reg.ValueExists('CursorColor') then hexview.fcursorcolor:=reg.ReadInteger('CursorColor'); if reg.ValueExists('TopLineColor') then hexview.ftoplinecolor:=reg.ReadInteger('TopLineColor'); if reg.ValueExists('FadeColor') then hexview.ffadeColor:=reg.ReadInteger('FadeColor'); end; if reg.OpenKey('\Software\'+strCheatEngine+'\Hexview '+inttostr(screen.PixelsPerInch)+'\Font'+darkmodestring,false) then begin LoadFontFromRegistry(f, reg); hexview.hexfont:=f; end; if reg.OpenKey('\Software\'+strCheatEngine+'\RegisterView '+inttostr(screen.PixelsPerInch)+'\Font'+darkmodestring,false) then begin LoadFontFromRegistry(f, reg); // scrollbox1.Font:=f; setRegisterPanelFont(f); end else begin f.assign(scrollbox1.font); f.size:=12; setRegisterPanelFont(f); end; finally f.free; reg.free; end; memoryaddress:=$00400000; memorylabelcount:=0; Highlightcolor:=clHighlight; disassemblerHistory:=TStringList.create; memorybrowserHistory:=TStringList.create; assemblerHistory:=TStringList.create; showvalues:=true; sbShowFloats.left:=scrollbox1.Clientwidth-sbShowFloats.width; FStacktraceSize:=4096; setlength(x, 0); if loadformposition(self,x) then begin disassemblerview.setheaderWidth(0,x[0]); disassemblerview.setheaderWidth(1,x[1]); disassemblerview.setheaderWidth(2,x[2]); disassemblerview.setheaderWidth(3,x[3]); if length(x)>=6 then begin panel1.height:=x[4]; registerview.width:=x[5]; end; if length(x)>=8 then begin miShowSymbols.checked:=x[6]=1; miShowModuleAddresses.checked:=(x[7] and 1)=1; miShowSectionAddresses.checked:=(x[7] and 2)=2; symhandler.showsymbols:=miShowSymbols.Checked; symhandler.showmodules:=miShowModuleAddresses.Checked; symhandler.showsections:=miShowSectionAddresses.checked; end; if length(x)>=10 then begin if x[9]<>0 then hexview.LockedRowSize:=x[9]; end; if length(x)>=11 then begin miKernelmodeSymbols.checked:=x[10]=1; symhandler.kernelsymbols:=miKernelmodeSymbols.Checked; end; if length(x)>=12 then pnlStacktrace.Width:=x[11]; setlength(x,0); posloadedfromreg:=true; end; scrollbox1.OnVScroll:=Scrollboxscroll; disassemblerview.reinitialize; followRegister:=nil; {$ifdef darwin} InjectDLL1.Caption:=rsInjectDYLIB; miChangeProtectionRWE.enabled:=false; //impossible to set , execute can not go together with write miChangeProtectionRWE.visible:=false; {$endif} if ShouldAppsUseDarkMode() then begin fAccessedRegisterColor:=clBlue; fChangedRegisterColor:=clred; end else begin fAccessedRegisterColor:=clAqua; fChangedRegisterColor:=clred; end; lblRegisters.font.color:=clWindowtext; sRegisters.pen.color:=clWindowtext; lblFlags.font.color:=clWindowtext; sFlags.pen.color:=clWindowtext; lblSpecial.font.color:=clWindowtext; sSpecial.Pen.color:=clWindowtext; end; procedure TMemoryBrowser.Scrollboxscroll(sender: TObject); begin end; procedure TMemoryBrowser.Goto1Click(Sender: TObject); var newaddress: string; canceled: boolean; old: ptruint; begin old:=hexview.SelectionStart; if old=0 then old:=memoryaddress; newaddress:=inputboxtop(rsGotoAddress, rsFillInTheAddressYouWantToGoTo, IntTohex(old, 8), true, canceled, memorybrowserHistory); if(canceled)then exit; try hexview.address:=getaddress(newaddress); except try hexview.address:=symhandler.getAddressFromName(newaddress); except on e: exception do begin MessageDlg(e.message, mtError,[mbok],0); exit; end end; end; if old<>hexview.address then hexview.history.Push(pointer(old)); hexview.SetFocus; end; procedure TMemoryBrowser.FormResize(Sender: TObject); begin if disassemblerview<>nil then disassemblerview.Update; end; procedure TMemoryBrowser.Splitter2Moved(Sender: TObject); begin //caption:=inttostr(registerview.width); end; procedure TMemoryBrowser.Timer2Timer(Sender: TObject); var mm: TMemoryManager; h: THeapStatus; rollover: integer; timetaken: qword; before, after,diff: int64; begin if Visible then begin try GetMemoryManager(mm); timetaken:=GetTickCount64; if hexview<>nil then begin //before:=mm.GetHeapStatus().TotalAllocated; hexview.update; // after:=mm.GetHeapStatus().TotalAllocated; // diff:=after-before; // outputdebugstring(gettickcount64.tostring+':hexview.update: before='+before.ToHexString(1)+' after='+after.ToHexString(1)+' diff='+diff.tostring); end; if disassemblerview<>nil then begin // before:=mm.GetHeapStatus().TotalAllocated; disassemblerview.Update; // after:=mm.GetHeapStatus().TotalAllocated; // diff:=after-before; // outputdebugstring(gettickcount64.tostring+':disassemblerview.update: before='+before.ToHexString(1)+' after='+after.ToHexString(1)+' diff='+diff.tostring); end; //refresh the modulelist if processhandler.isNetwork then rollover:=250 else rollover:=50; lastmodulelistupdate:=(lastmodulelistupdate+1) mod rollover; if lastmodulelistupdate=0 then if symhandler<>nil then begin //before:=mm.GetHeapStatus().TotalAllocated; symhandler.loadmodulelist; //after:=mm.GetHeapStatus().TotalAllocated; //diff:=after-before; //outputdebugstring(gettickcount64.tostring+':symhandler.loadmodulelist: before='+before.ToHexString(1)+' after='+after.ToHexString(1)+' diff='+diff.tostring); end; timetaken:=GetTickCount64-timetaken; if (timetaken>timer2.interval) and (timer2.interval<5000) then begin timer2.enabled:=false; timer2.interval:=timer2.interval+100; //this system can't handle the current speed timer2.enabled:=true; end; if (timetaken200) then timer2.interval:=max(250,timer2.interval-100); except on e:exception do begin outputdebugstring('memorybrowser timer2 error: '+e.message); timer2.enabled:=false; MessageDlg('Error in memview update timer:'+e.message, mtError,[mbok],0); end; end; end; end; procedure TMemoryBrowser.miReplacewithnopsClick(Sender: TObject); var codelength: dword; written: dword; bla:string; i,j: integer; nops: array of byte; a,a2: ptrUint; original: dword; mbi : _MEMORY_BASIC_INFORMATION; //set the protectionlabel e: boolean; begin a:=disassemblerview.SelectedAddress; for i:=0 to AdvancedOptions.count-1 do begin if AdvancedOptions.code[i]<>nil then begin a2:=symhandler.getAddressFromName(AdvancedOptions.code[i].symbolname,false,e); if not e then begin if InRangeX(disassemblerview.SelectedAddress, a2, a2+length(AdvancedOptions.code[i].actualopcode)-1 ) then begin for j:=0 to AdvancedOptions.count-1 do AdvancedOptions.Selected[j]:=false; AdvancedOptions.Selected[i]:=true; AdvancedOptions.lvCodelist.ItemIndex:=i; if AdvancedOptions.code[i].changed then AdvancedOptions.miRestoreWithOriginal.OnClick(AdvancedOptions.miRestoreWithOriginal) else AdvancedOptions.miReplaceWithNops.onclick(AdvancedOptions.miReplaceWithNops); exit; end; end; end; end; //still here so add it to the codelist disassemble(a,bla); codelength:=a-disassemblerview.SelectedAddress; if advancedoptions.AddToCodeList(disassemblerview.SelectedAddress,codelength,true) then begin setlength(nops,codelength); for i:=0 to codelength-1 do nops[i]:=$90; // $90=nop zeromemory(@mbi,sizeof(mbi)); Virtualqueryex(processhandle,pointer(disassemblerview.SelectedAddress),mbi,sizeof(mbi)); // get old security and set new security (not needed in win9x but nt doesnt even allow writeprocessmemory to do this original:=0; RewriteCode(processhandle,disassemblerview.SelectedAddress,@nops[0],codelength); hexview.update; disassemblerview.Update;; end; end; procedure TMemoryBrowser.hexviewKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var a: qword; psize: integer; gotoaddress: qword; x: ptruint; begin if shift=[ssCtrl] then begin case key of vk_space: //ctrl+space begin if hexview.HasSelection then begin psize:=1+hexview.SelectionStop-hexview.selectionstart; if psize>=4 then begin key:=0; if psize>8 then psize:=8; if ReadProcessMemory(processhandle, pointer(hexview.SelectionStart), @gotoaddress, processhandler.pointersize,x) then disassemblerview.SelectedAddress:=gotoaddress; exit; end; end; disassemblerview.SelectedAddress:=memoryaddress; key:=0; end; ord('G'): begin goto1.click; //ctrl+g key:=0; end; ord('C'): begin Cut1.OnClick(Cut1); //ctrl+c key:=0; end; ord('V'): begin Pastefromclipboard1.OnClick(Pastefromclipboard1); //ctrl+v key:=0; end; ord('F'): begin search1.OnClick(self); end; end; end else if shift=[] then begin if key=vk_f3 then begin if findwindow<>nil then //easy way to find out if there was a scan before begin findwindow.editStart.Text:=inttohex(memoryaddress+1,8); findwindow.firstscan:=false; findwindow.btnOK.Click; end else begin search1.OnClick(self); end; end; end; end; //key control for the disassembler procedure TMemoryBrowser.FControl1KeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); var rct: trect; ignore: string; i: integer; a,b: ptrUint; begin //if shift is not pressed and it's a up,down,left or right, then disable multiline section case key of vk_delete: miReplacewithnops.Click; vk_return: begin //assembler input if shift = [] then assemble1.Click; end; vk_space: begin key:=0; if shift=[] then follow1.Click else if shift = [ssShift] then back1.click else if shift = [ssCtrl] then memoryaddress:=disassemblerview.SelectedAddress; end; VK_BACK: begin key:=0; back1.click; //backspace and shift+space end; ORD('A')..ORD('Z') , ORD('0')..ORD('9'): begin if key=ORD('C') then begin if shift = [ssCtrl] then //ctrl C begin //open the copy window asking what exactly to copy with tfrmSavedisassembly.create(self) do begin a:=minX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2); b:=maxX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2); disassemble(b); //b gets increased with size of selected instruction edit1.Text:=inttohex(a,8); edit2.Text:=inttohex(b-1,8); copymode:=true; showmodal; free; exit; end; end; end; if key=ORD('G') then begin if ssCtrl in shift then begin gotoaddress1.Click; disassemblerview.Update; exit; end; end; if (key=ORD('Z')) and (ssCtrl in shift) then undoLastWrite; if (ssalt in shift) or (ssctrl in shift) then exit; try assemblepopup(lowercase(chr(key))); except on e:exception do begin MessageDlg(e.message, mtError,[mbok],0); exit; end; end; end; end; disassemblerview.Update; //key:=0; end; procedure TMemoryBrowser.FControl1KeyPress(Sender: TObject; var Key: Char); begin //key:=chr(0); end; procedure TMemoryBrowser.Gotoaddress1Click(Sender: TObject); var newaddress: string; oldoptions: dword; canceled: boolean; oldAddress: ptrUint; begin newaddress:=InputBoxTop(rsGotoAddress, rsFillInTheAddressYouWantToGoTo, IntTohex(disassemblerview.SelectedAddress, 8), true, canceled, memorybrowserHistory); if(canceled)then exit; try try disassemblerview.SelectedAddress:=symhandler.getaddressfromname(newaddress); except disassemblerview.SelectedAddress:=getaddress(newaddress); end; except on e:exception do MessageDlg(e.Message,mtError,[mbok],0); end; end; procedure TMemoryBrowser.Search1Click(Sender: TObject); begin if findwindow=nil then findwindow:=TFindwindow.create(self); findwindow.firstscan:=true; findwindow.editStart.text:=inttohex(hexview.SelectionStart,8); findwindow.ShowModal; end; procedure TMemoryBrowser.Change1Click(Sender: TObject); begin hexview.changeSelected; end; procedure TMemoryBrowser.Addthisaddresstothelist1Click(Sender: TObject); var i: integer; ad: ptrUint; begin //this will add the selected recdord to the list hexview.AddSelectedAddressToCheatTable; end; procedure TMemoryBrowser.miAddToTheCodelistClick(Sender: TObject); var {start,stop: string; a,b: dword; i: integer;} desc: string; begin frmAddToCodeList:=TfrmAddToCodeList.create(self); frmAddToCodeList.addtocodelist:=true; frmAddToCodeList.fromaddress:=disassemblerview.SelectedAddress; frmAddToCodeList.toaddress:=disassemblerview.SelectedAddress; disassemble(frmAddToCodeList.toaddress,desc); dec(frmAddToCodeList.toaddress); frmAddToCodeList.showmodal; end; procedure TMemoryBrowser.Splitter1CanResize(Sender: TObject; var NewSize: Integer; var Accept: Boolean); begin if newsize<80 then begin newsize:=80; accept:=false; end; if newsize>memorybrowser.Height-80 then begin newsize:=memorybrowser.Height-80; accept:=false; end; accept:=true; end; procedure TMemoryBrowser.ScrollBar2Scroll(Sender: TObject; ScrollCode: TScrollCode; var ScrollPos: Integer); begin end; procedure TMemoryBrowser.FormClose(Sender: TObject; var Action: TCloseAction); begin if ischild then begin //do stuff particulary for the children action:=cafree; end else begin //do stuff for the main debugger if (debuggerthread<>nil) and (miDebugRun.enabled) then miDebugRun.click; //run if it was paused if frmFloatingPointPanel<>nil then frmFloatingPointPanel.Visible:=false; if WindowState=wsMinimized then //for an unknown reason, the memoryview window can't be shown again if it was hidden minized WindowState:=wsNormal; end; end; procedure TMemoryBrowser.miDebugRunClick(Sender: TObject); begin if miDebugRun.Enabled then begin if debuggerthread<>nil then debuggerthread.ContinueDebugging(co_run); OnMemoryViewerRunning; caption:=rsMemoryViewerRunning; reloadstacktrace; end; end; procedure TMemoryBrowser.miDebugStepClick(Sender: TObject); begin begin if debuggerthread<>nil then debuggerthread.ContinueDebugging(co_stepinto); OnMemoryViewerRunning; caption:=rsMemoryViewerRunning; reloadstacktrace; end; end; procedure TMemoryBrowser.miDebugStepOverClick(Sender: TObject); var x: ptrUint; i,j: integer; s,s1,s2,temp:string; int3: byte; original,a,written:dword; begin debuggerthread.continueDebugging(co_stepover); reloadstacktrace; OnMemoryViewerRunning; caption:=rsMemoryViewerRunning; end; procedure TMemoryBrowser.miDebugRunTillClick(Sender: TObject); var x: ptrUint; i: integer; temp:string; int3: byte; original,a,written:dword; begin begin if debuggerthread<>nil then debuggerthread.ContinueDebugging(co_runtill, disassemblerview.SelectedAddress); OnMemoryViewerRunning; caption:=rsMemoryViewerRunning; end; end; procedure TMemoryBrowser.Stacktrace1Click(Sender: TObject); begin if frmstacktrace=nil then frmstacktrace:=tfrmstacktrace.create(application); frmstacktrace.Show; end; procedure TMemoryBrowser.Threadlist1Click(Sender: TObject); begin if frmThreadlist=nil then frmThreadlist:=tfrmthreadlist.create(self); frmThreadlist.show; end; procedure TMemoryBrowser.AssemblePopup(x:string); var assemblercode,desc,s: string; totalbytes: TAssemblerBytes; bytes: tassemblerbytes; a,b,original,written:ptrUint; originalsize:ptrUint; replace: boolean; c: word; res: word; i: integer; canceled: boolean; localdisassembler: TDisassembler; bytelength: dword; p: dword; gnascript: tstringlist; vpe: boolean; address: ptruint; oldbp: PBreakpoint=nil; {$ifdef ONEBYTEJUMPS} isjmp1: boolean; jmp1target: ptruint; {$endif} begin //make sure it doesnt have a breakpoint address:=disassemblerview.SelectedAddress; try if debuggerthread<>nil then begin debuggerthread.lockbplist; oldbp:=debuggerthread.isBreakpoint(Address); if (oldbp<>nil) and (oldbp^.breakpointMethod<>bpmInt3) then oldbp:=nil; if oldbp=nil then debuggerthread.unlockbplist; //no need to keep this lock end; originalsize:=Address; localdisassembler:=TDisassembler.Create; try localdisassembler.disassemble(originalsize,desc); assemblercode:=localdisassembler.LastDisassembleData.prefix+localdisassembler.LastDisassembleData.opcode+' '+localdisassembler.LastDisassembleData.parameters; finally localdisassembler.free; end; dec(originalsize,Address); if x<>'' then assemblercode:=x; // copy assemblercode:=InputboxTop(rsCheatEngineSingleLingeAssembler, Format(rsTypeYourAssemblerCodeHereAddress, [inttohex(Address, 8)]), assemblercode, x='', canceled{$ifndef darwin},assemblerHistory{$endif}); if not canceled then begin if defaultBinutils<>nil then begin //use the gnuassembler for this gnascript:=TStringList.create; try gnascript.add('.msection sline 0x'+inttohex(Address,8)); gnascript.Add(assemblercode); gnuassemble(gnascript); finally gnascript.free; end; exit; end; {$ifdef ONEBYTEJUMPS} s:=lowercase(trim(assemblercode)); if s.StartsWith('jmp1 ') then begin isjmp1:=true; s:=copy(s,6); jmp1target:=symhandler.getAddressFromName(s); //still here, so the address is valid assemblercode:='db cc'; end else isjmp1:=false; {$endif} if Assemble(assemblercode,Address,bytes) then begin if originalsize<>length(bytes) then begin if formsettings.replacewithnops.checked then begin if formsettings.askforreplacewithnops.checked then begin c:=messagedlg(Format(rsTheGeneratedCodeIsByteSLongButTheSelectedOpcodeIsB, [IntToStr(length(bytes)), IntToStr(originalsize)]), mtConfirmation, mbYesNoCancel, 0); replace:=c=mryes; if c=mrCancel then exit; end else replace:=true; if replace then begin while originalsize>length(bytes) do begin setlength(bytes,length(bytes)+1); bytes[length(bytes)-1]:=$90; end; a:=Address+length(bytes); b:=Address; while bnil then debuggerthread.UnsetBreakpoint(oldbp); a:=0; if fcr3=0 then begin if SystemSupportsWritableExecutableMemory or SkipVirtualProtectEx then vpe:=(SkipVirtualProtectEx=false) and VirtualProtectEx(processhandle, pointer(Address),bytelength,PAGE_EXECUTE_READWRITE,p) else begin outputdebugstring('First making memory writable'); if processid<>GetCurrentProcessId then begin if (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then TGDBServerDebuggerInterface(CurrentDebuggerInterface).suspendProcess else ntsuspendProcess(processhandle); end; vpe:=(SkipVirtualProtectEx=false) and VirtualProtectEx(processhandle, pointer(Address),bytelength,PAGE_READWRITE,p) end; if (CurrentDebuggerInterface is TGDBServerDebuggerInterface) and GDBWriteProcessMemoryCodeOnly then TGDBServerDebuggerInterface(CurrentDebuggerInterface).writeBytes(address, @bytes[0],bytelength) else WriteProcessMemoryWithCloakSupport(processhandle,pointer(Address),@bytes[0],bytelength,a); if vpe then begin VirtualProtectEx(processhandle,pointer(Address),bytelength,p,p); outputdebugstring('restoring back to the original protection: '+p.ToString); end; if (not (SystemSupportsWritableExecutableMemory or SkipVirtualProtectEx)) and (processid<>GetCurrentProcessId) then begin if (CurrentDebuggerInterface is TGDBServerDebuggerInterface) then TGDBServerDebuggerInterface(CurrentDebuggerInterface).resumeProcess else ntresumeProcess(processhandle); end; end else begin {$ifdef windows} WriteProcessMemoryCR3(fcr3, pointer(address),@bytes[0], bytelength,a); {$endif} end; if (a>0) and (oldbp<>nil) then begin oldbp^.originalbyte:=bytes[0]; debuggerthread.SetBreakpoint(oldbp); end; hexview.update; disassemblerview.Update; {$ifdef darwin} SetFocus; disassemblerview.SetFocus; {$endif} end else raise exception.create(Format(rsIDonTUnderstandWhatYouMeanWith, [assemblercode])); end; finally if oldbp<>nil then //still needs to be unlocked debuggerthread.unlockbplist; end; end; procedure TMemoryBrowser.Assemble1Click(Sender: TObject); begin try AssemblePopup(''); except on e: exception do MessageDlg(e.message, mtError, [mbok],0); end; end; procedure TMemoryBrowser.HexEditKeyPress(Sender: TObject; var Key: Char); begin case key of chr(8) : ; chr(16) : ; 'A'..'F' : ; 'a'..'f' : key:=uppercase(key)[1]; '0'..'9' : ; else key:=chr(0); end; if editing then key:=#0; editing:=false; end; procedure TMemoryBrowser.HexEditExit(Sender: TObject); begin end; procedure TMemoryBrowser.HexEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin end; procedure TMemoryBrowser.miShowIndisassemblerClick(Sender: TObject); begin if context<>nil then disassemblerview.SelectedAddress:=PContextElement_register(pmRegisters.PopupComponent.Tag)^.getValue(context); end; procedure TMemoryBrowser.RegisterLabelDblClick(Sender: TObject); var x: dword; i: integer; regname,input: string; value: qword; rbase: string; context: PContext; labeltext: string; r: PContextElement_register; begin regname:=''; labeltext:=tlabel(sender).Caption; if (debuggerthread<>nil) and (debuggerthread.isWaitingToContinue) then begin r:=PContextElement_register(tlabel(Sender).Tag); regname:=r^.name; input:=r^.getValueString(debuggerthread.CurrentThread.context); if inputquery(rsChangeRegister, Format(rsWhatIsTheNewValueOf, [regname]), input) then begin if debuggerthread.CurrentThread<>nil then begin r^.setValue(debuggerthread.CurrentThread.context, input); tlabel(Sender).caption:=padleft(regname, contexthandler.GeneralPurposeRegisterMaxCharCount)+' '+r^.getFullValueString(debuggerthread.CurrentThread.context); end; end; end; end; procedure TMemoryBrowser.miDebugBreakClick(Sender: TObject); //var threadhandle: thandle; var threadlist: TList; needform: boolean; threadhandle: thandle; i: integer; begin if not startdebuggerifneeded then exit; threadhandle:=0; needform:=false; threadlist:=debuggerthread.lockThreadlist; try if threadlist.count=1 then begin threadhandle:=TDebugThreadHandler(threadlist[0]).handle; end else if threadlist.count>1 then needform:=true else exit; //no threads finally debuggerthread.unlockThreadlist; end; if needform then begin //multiple threads!!! Ask user which one frmbreakthread:=tfrmbreakthread.create(self); if frmbreakthread.showmodal=mrOK then threadhandle:=frmbreakthread.threadhandle else begin frmbreakthread.free; frmbreakthread:=nil; exit; end; frmbreakthread.free; frmbreakthread:=nil; end; if threadhandle<>0 then begin threadlist:=debuggerthread.lockThreadlist; try //find the thread with this handle and tell it to break for i:=0 to threadlist.count-1 do if TDebugThreadHandler(threadlist[i]).handle=threadhandle then begin TDebugThreadHandler(threadlist[i]).BreakThread; exit; end; finally debuggerthread.unlockThreadlist; end; end; end; procedure TMemoryBrowser.Reservememory1Click(Sender: TObject); var count: string; memsize: dword; baseaddress: pointer; x: dword; s: string; begin {$ifdef darwin} count:=getPageSize.ToString; {$else} count:='4096'; {$endif} try if inputquery(rsAllocateMemory, rsHowMuchMemoryDoYouWantToAddToThisProcess, count) then begin try memsize:=StrToInt(count); except raise exception.Create(Format(rsHowMuchIs, [count])); end; baseaddress:=nil; if not SystemSupportsWritableExecutableMemory then baseaddress:=VirtualAllocEx(processhandle,nil,memsize,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE) else baseaddress:=VirtualAllocEx(processhandle,nil,memsize,MEM_COMMIT or MEM_RESERVE,PAGE_EXECUTE_READWRITE); if baseaddress=nil then raise exception.Create(rsErrorAllocatingMemory); if allocsAddToUnexpectedExceptionList then AddUnexpectedExceptionRegion(ptruint(baseaddress),memsize); if (disassemblerview.SelectedAddress<>0) and (memsize>7) and (messagedlg(Format(rsAtLeastBytesHaveBeenAllocatedAtDoYouWantToGoThereN, [IntToStr(memsize), IntToHex(ptrUint(baseaddress), 8), #13 +#10]), mtConfirmation, [mbyes, mbno], 0)=mryes) then disassemblerview.SelectedAddress:=ptrUint(baseaddress); end; except on e: exception do MessageDlg(e.message, mtError,[mbok],0); end; end; procedure TMemoryBrowser.Savememoryregion1Click(Sender: TObject); {will save a cheat engine memory region file .CEM} begin if frmSaveMemoryRegion=nil then frmSaveMemoryRegion:=TFrmSaveMemoryRegion.create(self); if (disassemblerview.SelectedAddress <> disassemblerview.SelectedAddress2) then //disassembler view selection takes priority begin frmSaveMemoryRegion.editFrom.Text:=inttohex(minX(disassemblerview.SelectedAddress,disassemblerview.SelectedAddress2),8); frmSaveMemoryRegion.editTo.Text:=inttohex(maxX(disassemblerview.SelectedAddress,disassemblerview.SelectedAddress2),8); end else if (hexview.SelectionStart <> hexview.SelectionStop) then begin frmSaveMemoryRegion.editFrom.Text:=inttohex(minX(hexview.SelectionStart,hexview.SelectionStop),8); frmSaveMemoryRegion.editTo.Text:=inttohex(maxX(hexview.SelectionStart,hexview.SelectionStop),8); end else begin //leave blank end; frmSaveMemoryRegion.show; end; procedure TMemoryBrowser.Loadmemolryregion1Click(Sender: TObject); begin if openmemory.Execute then begin tfrmloadmemory.Create(self).Showmodal(openmemory.filename); end; end; procedure TMemoryBrowser.HexEditDblClick(Sender: TObject); begin change1.Click; end; procedure TMemoryBrowser.Debugstrings1Click(Sender: TObject); begin {$ifndef net} if startdebuggerifneeded then formdebugstrings.show; {$endif} end; procedure TMemoryBrowser.TextEditExit(Sender: TObject); var bt: byte; aw: dword; begin end; procedure TMemoryBrowser.TextEditKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin end; procedure TMemoryBrowser.CreateThread1Click(Sender: TObject); var startaddress: ptrUint; parameter: ptrUint; ThreadID: dword; start:string; param:string; begin start:=IntToHex(disassemblerview.SelectedAddress,8); param:='0'; if not InputQuery(rsCreateRemoteThread, rsWhatWillBeTheStartaddressOfThisThread, start) then exit; try startaddress:=StrToQWordEx('$'+start); except raise exception.Create(rsPleaseEnterAValidHexadecimalAddres); end; if not InputQuery(rsCreateRemoteThread, rsYouWantToGiveAnAdditional32BitParameterWillShowUpI, param) then exit; try parameter:=StrToInt('$'+param); except raise exception.Create(rsPleaseEnterAValidHexadecimalValue); end; if CreateRemoteThread(processhandle,nil,0,pointer(startaddress),pointer(parameter),0,threadid)=0 then MessageDlg(rsMBCreationOfTheRemoteThreadFailed, mterror,[mbok],0) else showmessage(rsMBThreadCreated); end; procedure TMemoryBrowser.MemoryRegions1Click(Sender: TObject); begin formmemoryregions:=tformmemoryregions.Create(self); formmemoryregions.show; end; procedure TMemoryBrowser.TextEditKeyPress(Sender: TObject; var Key: Char); begin end; procedure TMemoryBrowser.FillMemory1Click(Sender: TObject); begin frmFillMemory:=TFrmFillMemory.create(self); with frmFillMemory do begin edit1.Text:=IntToHex(disassemblerview.SelectedAddress,8); edit2.Text:=IntToHex(disassemblerview.SelectedAddress+1,8); frmFillMemory.showmodal; end; end; procedure TMemoryBrowser.Disectwindow1Click(Sender: TObject); begin {$ifndef net} frmdissectWindow:=tfrmdissectWindow.create(self); frmdissectWindow.showmodal; {$endif} end; procedure TMemoryBrowser.Savedisassemledoutput1Click(Sender: TObject); var x,y: string; start,stop: ptrUint; output: textfile; begin with tfrmSavedisassembly.create(self) do begin start:=minX(disassemblerview.SelectedAddress,disassemblerview.SelectedAddress2); stop:=maxX(disassemblerview.SelectedAddress,disassemblerview.SelectedAddress2); disassemble(stop); edit1.Text:=inttohex(start,8); edit2.Text:=inttohex(stop,8); show; end; end; procedure TMemoryBrowser.Heaps1Click(Sender: TObject); begin if processid=0 then begin messagedlg(rsPleaseTargetAProcessFirst, mterror, [mbOK], 0); exit; end; if processid=GetCurrentProcessId then begin messagedlg(rsPleaseTargetAnotherProcess, mterror, [mbOK], 0); exit; end; if (frmMemoryAllocHandler<>nil) and (frmMemoryAllocHandler.hookedprocessid<>processid) then freeandnil(frmMemoryAllocHandler); if frmheaps=nil then frmheaps:=tfrmheaps.create(self); frmheaps.show; end; procedure TMemoryBrowser.EnumeratedllsandSymbols1Click(Sender: TObject); begin symhandler.reinitialize; if frmEnumerateDLLs=nil then frmEnumerateDLLs:=tfrmEnumerateDLLs.create(application); frmEnumerateDLLs.show; frmEnumerateDLLs.enumerate; end; procedure TMemoryBrowser.InjectDLL1Click(Sender: TObject); var dll: string; functionname: string; dllList: tstringlist; begin functionname:=''; dll:=''; {$ifdef darwin} OpenDllDialog.DefaultExt:='.dylib'; OpenDllDialog.Filter:='Dylib-files (*.dylib)|*.dylib|All files (*.*)|*.*'; {$endif} if opendlldialog.Execute then begin dll:=utf8toansi(opendlldialog.Filename); {$ifdef windows} if MessageDlg(rsDoYouWantToExecuteAFunctionOfTheDll, mtConfirmation , [mbyes, mbno], 0)=mryes then begin dllList:=tstringlist.Create; try try peinfo_getExportList(opendlldialog.filename, dllList); with TfrmSelectionList.create(self,dllList) do begin caption:=rsInjectDll; label1.caption:=rsSelectTheFunctionYouWantToExecute; if showmodal=mrok then if itemindex<>-1 then functionname:=selected; free; end; except end; finally dllList.free; end; end; {$else} functionname:=''; {$endif} try InjectDll(dll,functionname); symhandler.reinitialize(true); showmessage(rsDLLInjected); except on e:exception do MessageDlg(e.message,mtError,[mbok],0); end; end; end; procedure TMemoryBrowser.AutoInject1Click(Sender: TObject); begin tfrmautoinject.create(self).show; end; procedure TMemoryBrowser.Dissectcode1Click(Sender: TObject); begin {$ifndef net} if frmdissectcode=nil then frmdissectcode:=tfrmDissectcode.create(self); if disassemblerview.SelectedAddress2<>disassemblerview.SelectedAddress then begin frmDissectCode.edtCustomRangeStart.text:=inttohex(MinX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2),8); frmDissectCode.edtCustomRangeStop.text:=inttohex(MaxX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2),8); end else begin frmDissectCode.edtCustomRangeStart.text:=''; frmDissectCode.edtCustomRangeStop.text:=''; end; frmdissectcode.Show; {$endif} end; procedure TMemoryBrowser.Createjumptocodecave1Click(Sender: TObject); begin end; procedure TMemoryBrowser.Findstaticpointers1Click(Sender: TObject); begin {$ifndef net} if frmfindstatics=nil then frmfindstatics:=tfrmfindstatics.create(self); frmfindstatics.show; {$endif} end; procedure TMemoryBrowser.Scanforcodecaves1Click(Sender: TObject); begin if frmcodecavescanner=nil then frmcodecavescanner:=tfrmCodecaveScanner.create(self); frmCodecavescanner.show; end; procedure TMemoryBrowser.Changestateofregisteratthislocation1Click( Sender: TObject); begin tfrmModifyRegisters.create(self,disassemblerview.SelectedAddress).showmodal; end; procedure TMemoryBrowser.miTogglebreakpointClick(Sender: TObject); var bpm: TBreakpointMethod; b: byte; PA: qword; bo: integer; begin //first check if it's a cloaked dbvm bp, and if so, disable it if dbvm_isBreakpoint(disassemblerview.SelectedAddress, PA, BO, b) then begin if bo=1 then //changeregonbp begin dbvm_cloak_removechangeregonbp(PA); disassemblerview.Update; exit; end; if bo=4 then //break and trace begin dbvm_cloak_traceonbp_remove(PA); disassemblerview.Update; exit; end; end; try if startdebuggerifneeded(true) then begin if overridebreakpointmethod then bpm:=preferedF5BreakpointMethod else bpm:=preferedBreakpointMethod; DebuggerThread.ToggleOnExecuteBreakpoint(disassemblerview.SelectedAddress,bpm); disassemblerview.Update; ApplySourceCodeDebugUpdate; end; except on e:exception do MessageDlg(e.message,mtError,[mbok],0); end; end; procedure TMemoryBrowser.Breakpointlist1Click(Sender: TObject); begin if frmbreakpointlist=nil then begin frmbreakpointlist:=tfrmBreakpointlist.create(self); frmBreakpointlist.show; end else frmbreakpointlist.bringtofront; end; procedure TMemoryBrowser.Dissectdata1Click(Sender: TObject); begin {$ifndef net} with tfrmpointerscanner.create(self) do show; {$endif} end; procedure TMemoryBrowser.miShowSymbolsClick(Sender: TObject); begin symhandler.showsymbols:=miShowSymbols.Checked; disassemblerview.Update; end; procedure TMemoryBrowser.miShowModuleAddressesClick(Sender: TObject); begin symhandler.showmodules:=miShowModuleAddresses.Checked; disassemblerview.Update; end; procedure TMemoryBrowser.miShowSectionAddressesClick(Sender: TObject); begin symhandler.showsections:=miShowSectionAddresses.checked; disassemblerview.Update; end; procedure TMemoryBrowser.miDissectDataClick(Sender: TObject); begin { if length(frmStructures)>0 then begin frmStructures[0].edtAddress.Text:=inttohex(memorybrowser.memoryaddress,8); frmStructures[0].Show; end else begin //create it with tfrmstructures.create(self) do begin edtAddress.Text:=inttohex(memoryaddress,8); applychanges(false); show; end; end; } end; procedure TMemoryBrowser.miUserdefinedSymbolsClick(Sender: TObject); begin if frmSymbolhandler=nil then frmSymbolhandler:=TfrmSymbolhandler.create(self); frmSymbolhandler.show; end; procedure TMemoryBrowser.Allocatenonpagedmemory1Click(Sender: TObject); var count: string; memsize: integer; baseaddress: pointer; x: dword; s: string; begin {$ifdef windows} {$ifndef net} count:='4096'; if inputquery(rsAllocateMemory, rsHowMuchMemoryDoYouWishToAllocate, count) then begin try memsize:=StrToInt(count); except raise exception.Create(Format(rsHowMuchIs, [count])); end; baseaddress:=nil; baseaddress:=KernelAlloc(memsize); if baseaddress=nil then raise exception.Create(rsErrorAllocatingMemory); if messagedlg(Format(rsAtLeastBytesHaveBeenAllocatedAtGoThereNow, [IntToStr(memsize), IntToHex(ptrUint(baseaddress), 8)]), mtinformation, [mbyes, mbno], 0) = mryes then disassemblerview.SelectedAddress:=ptrUint(baseaddress); end; {$endif} {$endif} end; procedure TMemoryBrowser.Getaddress1Click(Sender: TObject); var p: pointer; s: string; ws: widestring; pws: pwidechar; begin {$ifdef windows} if inputquery(rsGetKernelAddress, rsGiveTheNameOfTheFunctionYouWantToFindCaseSensitive, s) then begin ws:=s; pws:=@ws[1]; p:=GetKProcAddress(pws); disassemblerview.SelectedAddress:=ptrUint(p); end; {$endif} end; procedure TMemoryBrowser.Findmemory1Click(Sender: TObject); begin search1.Click; end; procedure TMemoryBrowser.Assemblycode1Click(Sender: TObject); var fromaddress: ptruint; toaddress: ptruint; begin if frmAssemblyScan=nil then frmAssemblyScan:=tfrmassemblyscan.create(self); frmAssemblyScan.edtFrom.text:=inttohex(disassemblerview.TopAddress,8); if processhandler.is64Bit then frmAssemblyScan.edtTo.text:='FFFFFFFFFFFFFFFF' else frmAssemblyScan.edtTo.text:='FFFFFFFF'; if frmAssemblyScan.ShowModal=mrok then begin if frmAssemblyScan.mAssemblerSearch.lines.Count=0 then exit; with TfrmDisassemblyscan.create(self) do begin startaddress:=frmAssemblyScan.startaddress; stopaddress:=frmAssemblyScan.stopaddress; stringstofind:=frmAssemblyScan.mAssemblerSearch.lines; show; end; end; end; procedure TMemoryBrowser.Driverlist1Click(Sender: TObject); begin {$ifndef net} with tfrmdriverlist.create(self) do show; {$endif} end; procedure TMemoryBrowser.plugintype6click(sender:tobject); var x: TPluginfunctionType6; selectedaddress: ptrUint; begin x:=TPluginfunctionType6(tmenuitem(sender).Tag); if x<>nil then begin selectedaddress:=disassemblerview.SelectedAddress; x.callback(@selectedaddress); disassemblerview.SelectedAddress:=selectedaddress; end; end; procedure TMemoryBrowser.plugintype1click(sender:tobject); var x: TPluginfunctionType1; address: ptrUint; hexviewaddress: ptrUint; seladdress: ptruint; begin x:=TPluginfunctionType1(tmenuitem(sender).Tag); if x<>nil then begin address:=disassemblerview.TopAddress; hexviewaddress:=memoryaddress; seladdress:=disassemblerview.SelectedAddress; if x.callback(@address,@seladdress,@hexviewaddress) then begin disassemblerview.TopAddress:=address; disassemblerview.selectedaddress:=seladdress; memoryaddress:=hexviewaddress; end; end; end; procedure TMemoryBrowser.Sericedescriptortable1Click(Sender: TObject); begin {$ifndef net} if frmServiceDescriptorTables=nil then frmServiceDescriptorTables:=TfrmServiceDescriptorTables.create(self); frmServiceDescriptorTables.show; {$endif} end; procedure TMemoryBrowser.MBCanvasMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); begin end; procedure TMemoryBrowser.Cut1Click(Sender: TObject); begin hexview.CopySelectionToClipboard; end; procedure TMemoryBrowser.Pastefromclipboard1Click(Sender: TObject); begin hexview.PasteFromClipboard; end; procedure TMemoryBrowser.Setsymbolsearchpath1Click(Sender: TObject); var searchpath: string; begin searchpath:=symhandler.getsearchpath; if inputquery(rsSymbolHandler, rsPleaseSpecifyTheNewSymbolSearchpathSeperatesPaths, searchpath) then begin symhandler.setsearchpath(searchpath); symhandler.reinitialize(true); end; end; procedure TMemoryBrowser.miKernelmodeSymbolsClick(Sender: TObject); begin {$ifndef net} miKernelmodeSymbols.Checked:=not miKernelmodeSymbols.Checked; symhandler.kernelsymbols:=miKernelmodeSymbols.Checked; symhandler.reinitialize(true); //symhandler.waitforsymbolsloaded(false); {$endif} end; procedure TMemoryBrowser.Breakandtraceinstructions1Click(Sender: TObject); var f: TFrmTracer; begin f:=TFrmTracer.create(self); f.show; f.miNewTrace.Click; end; procedure TMemoryBrowser.debuggerpopupPopup(Sender: TObject); var x: ptrUint; i: integer; a,a2: ptruint; inadvancedoptions: boolean; e: boolean; VA,PA: QWORD; BO: integer; bpm: TBreakpointMethod; b: byte; dbvmbp: boolean; bp: PBreakpoint=nil; begin Breakandtraceinstructions1.Enabled:=processhandle<>0; miTogglebreakpoint.Enabled:=processhandle<>0; Changestateofregisteratthislocation1.Enabled:=processhandle<>0; Findoutwhataddressesthisinstructionaccesses1.enabled:=processhandle<>0; follow1.visible:=isjumporcall(disassemblerview.SelectedAddress,x); back1.Visible:=disassemblerview.hasbacklist; pluginhandler.handledisassemblerContextPopup(disassemblerview.SelectedAddress); miConditionalBreak.enabled:=(debuggerthread<>nil) and (debuggerthread.isBreakpoint(disassemblerview.SelectedAddress)<>nil); miConditionalBreak.visible:=miConditionalBreak.enabled; miDBVMActivateCloak.visible:={$ifdef windows}isRunningDBVM and hasEPTSupport and (not hasCloakedRegionInRange(disassemblerview.SelectedAddress, 1, VA,PA)){$else}false{$endif}; miDBVMActivateCloak.enabled:=miDBVMActivateCloak.visible; miDBVMDisableCloak.visible:={$ifdef windows}isRunningDBVM and hasEPTSupport and (hasCloakedRegionInRange(disassemblerview.SelectedAddress, 1, VA,PA)){$else}false{$endif}; miDBVMDisableCloak.enabled:=miDBVMDisableCloak.visible; miTogglebreakpoint.visible:=(not ischild); if miTogglebreakpoint.visible then begin dbvmbp:=dbvm_isBreakpoint(disassemblerview.SelectedAddress,PA,BO,b); if dbvmbp then outputdebugstring('DBVMBP=true') else outputdebugstring('DBVMBP=false'); if (debuggerthread<>nil) then bp:=debuggerthread.isBreakpoint(disassemblerview.SelectedAddress); if ((debuggerthread=nil) or (bp=nil)) and (not dbvmbp) then begin if overridebreakpointmethod then bpm:=preferedF5BreakpointMethod else bpm:=preferedBreakpointMethod; miTogglebreakpoint.caption:=rsSetBreakpoint+' ('+breakpointMethodToString(bpm)+')'; Changestateofregisteratthislocation1.visible:=true; //setting of bp's is OK miSetSpecificBreakpoint.visible:=true; Breakandtraceinstructions1.visible:=true; Findoutwhataddressesthisinstructionaccesses1.visible:=true; end else begin miTogglebreakpoint.caption:=rsRemoveBreakpoint; Changestateofregisteratthislocation1.visible:=(bp<>nil) and (bp^.breakpointAction=bo_ChangeRegister); miSetSpecificBreakpoint.visible:=false; Breakandtraceinstructions1.visible:=false; Findoutwhataddressesthisinstructionaccesses1.visible:=false; end; end else begin Changestateofregisteratthislocation1.visible:=false; miSetSpecificBreakpoint.visible:=false; Breakandtraceinstructions1.visible:=false; Findoutwhataddressesthisinstructionaccesses1.visible:=false; end; Changestateofregisteratthislocation1.enabled:=Changestateofregisteratthislocation1.visible; inadvancedoptions:=false; for i:=0 to AdvancedOptions.count-1 do begin if AdvancedOptions.code[i]<>nil then begin a:=symhandler.getAddressFromName(AdvancedOptions.code[i].symbolname,false,e); if not e then begin if InRangeX(disassemblerview.SelectedAddress, a, a+length(AdvancedOptions.code[i].actualopcode)-1 ) then begin inadvancedoptions:=true; if AdvancedOptions.code[i].changed then begin miReplacewithnops.caption:=rsRestoreWithOrginalCode; miReplacewithnops.imageindex:=44; end else begin miReplacewithnops.caption:=rsReplaceWithCodeThatDoesNothing; miReplacewithnops.imageindex:=42; end; break; end; end; end; end; if not inadvancedoptions then miReplacewithnops.caption:=rsReplaceWithCodeThatDoesNothing; miAddToTheCodelist.visible:=not inadvancedoptions; miDBVMFindoutwhataddressesthisinstructionaccesses.visible:={$ifdef windows}isDBVMCapable and miSetSpecificBreakpoint.visible{$else}false{$endif}; miDBVMFindoutwhataddressesthisinstructionaccesses.enabled:=miDBVMFindoutwhataddressesthisinstructionaccesses.visible; menuitem5.visible:=miDBVMFindoutwhataddressesthisinstructionaccesses.visible; menuitem6.visible:=miDBVMFindoutwhataddressesthisinstructionaccesses.visible; // miSetBreakpointHW.enabled:=(CurrentDebuggerInterface=nil) or (dbcHardwareBreakpoint in CurrentDebuggerInterface.DebuggerCapabilities); miSetBreakpointSW.enabled:=((CurrentDebuggerInterface=nil) and (not formsettings.cbKDebug.Checked)) or ((CurrentDebuggerInterface<>nil) and (dbcSoftwareBreakpoint in CurrentDebuggerInterface.DebuggerCapabilities)); miSetBreakpointPE.enabled:=((CurrentDebuggerInterface=nil) and (not formsettings.cbKDebug.Checked)) or ((CurrentDebuggerInterface<>nil) and (dbcExceptionBreakpoint in CurrentDebuggerInterface.DebuggerCapabilities)); miSetBreakpointDBVMExec.enabled:=((CurrentDebuggerInterface=nil) and (formsettings.cbKDebug.Checked)) or ((CurrentDebuggerInterface<>nil) and (dbcDBVMBreakpoint in CurrentDebuggerInterface.DebuggerCapabilities)); miSetBreakpointDBVMExec.visible:={$ifdef windows}hasEPTSupport{$else}false{$endif}; if logWrites then begin a:=minX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2); a2:=maxX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2); if a2=a then disassemble(a2); miUndoLastEdit.visible:=hasAddressBeenChangedRange(a,a2); end else miUndoLastEdit.visible:=false; end; procedure TMemoryBrowser.GDTlist1Click(Sender: TObject); begin Tfrmgdtinfo.create(self).show; end; procedure TMemoryBrowser.IDTlist1Click(Sender: TObject); begin TfrmIDT.create(self).show; end; procedure TMemoryBrowser.FormDestroy(Sender: TObject); var h0,h1,h2,h3: integer; params: array of integer; reg: TRegistry; v: integer; begin MemoryBrowsers.Remove(self); if strace<>nil then strace.free; if disassemblerHistory<>nil then freeandnil(disassemblerHistory); if memorybrowserhistory<>nil then freeandnil(memorybrowserHistory); if assemblerHistory<>nil then freeandnil(assemblerHistory); //save position of window and other stuff //membrowser comes after formsettings so is destroyed before formsettings, so valid if hasBeenShown then begin if self.disassemblerview<>nil then begin setlength(params,12); //don't use [xx,xx,xx] crash params[0]:=self.disassemblerview.getheaderwidth(0); params[1]:=self.disassemblerview.getheaderwidth(1); params[2]:=self.disassemblerview.getheaderwidth(2); params[3]:=self.disassemblerview.getheaderwidth(3); params[4]:=self.panel1.height; params[5]:=self.registerview.width; params[6]:=strtoint(BoolToStr(self.miShowSymbols.checked,'1','0')); v:=0; if self.miShowModuleAddresses.checked then v:=v or 1; if self.miShowSectionAddresses.checked then v:=v or 2; params[7]:=v; //params[8]:=strtoint(BoolToStr(self.miLockRowsize.Checked,'1','0')); 7.4: obsolete params[9]:=self.hexview.LockedRowSize; params[10]:=strtoint(BoolToStr(self.Kernelmodesymbols1.checked,'1','0')); params[11]:=pnlStacktrace.Width; saveformposition(self,params); end; end; if self.disassemblerview<>nil then freeandnil(self.disassemblerview); if self.hexview<>nil then freeandnil(self.hexview); end; procedure TMemoryBrowser.Newwindow1Click(Sender: TObject); var s: string; ns: string; i: integer; begin with tmemorybrowser.create(application) do begin inc(mbchildcount); //name:=rsMemoryBrowser+inttostr(mbchildcount); debug1.Visible:=false; debug1.enabled:=false; //registerview.Visible:=false; //splitter2.Visible:=false; sbShowFloats.Visible:=false; miDebugToggleBreakpoint.visible:=false; s:=name; ns:=''; for i:=length(s) downto 1 do begin if s[i] in ['0'..'9'] then ns:=s[i]+ns else break; end; caption:=caption+'* ('+ns+')'; Kerneltools1.enabled:=memorybrowser.Kerneltools1.enabled; miCR3Switcher.visible:=Kerneltools1.Enabled; ischild:=true; show; end; end; procedure TMemoryBrowser.Follow1Click(Sender: TObject); { will change the selected disassembler address to the address this instructions jump so if it is an jump instruction } var address: ptrUint; begin if isjumporcall(disassemblerview.SelectedAddress,address) then disassemblerview.SelectedAddress:=address; end; procedure TMemoryBrowser.copyBytesAndOpcodesClick(Sender: TObject); var a,b: ptrUint; _tag: integer; begin _tag:=(sender as tmenuitem).Tag; if _tag=0 then raise exception.create('Build environment corrupted'); with tfrmSavedisassembly.create(self) do begin a:=minX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2); b:=maxX(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2); disassemble(b); //b gets increased with size of selected instruction edit1.Text:=inttohex(a,8); edit2.Text:=inttohex(b-1,8); copymode:=true; cbAddress.checked:=not (_tag in [4,7]); cbBytes.checked:=_tag in [1,2,4,6]; cbOpcode.checked:=_tag in [1,3,6,7]; cbComment.checked:=(_tag=1); button1.click; waittilldone; free; end; end; procedure TMemoryBrowser.DissectPEheaders1Click(Sender: TObject); begin with TfrmPEInfo.create(self) do show; end; procedure TMemoryBrowser.GetEntryPointAndDataBase(var code: ptrUint; var data: ptrUint); var modulelist: tstringlist=nil; base: ptrUint; header: pointer=nil; headersize: dword; br: ptrUint; d: ptruint; sectionlist: Tstringlist; i: integer; begin code:=$00400000; data:=$00400000; //on failure modulelist:=tstringlist.Create; symhandler.getModuleList(modulelist); outputdebugstring('Retrieved the module list'); if modulelist.Count>0 then begin base:=ptrUint(modulelist.Objects[0]); data:=base; code:=base; outputdebugstring('Base='+inttohex(base,8)); getmem(header,4096); try if readprocessmemory(processhandle,pointer(base),header,4096,br) then begin headersize:=peinfo_getheadersize(header); if headersize>0 then begin OutputDebugString('headersize='+inttostr(headersize)); if headersize>1024*512 then exit; freememandnil(header); getmem(header,headersize); if not readprocessmemory(processhandle,pointer(base),header,headersize,br) then exit; Outputdebugstring('calling peinfo_getEntryPoint'); code:=base+peinfo_getEntryPoint(header, headersize); OutputDebugString('calling peinfo_getdatabase'); d:=peinfo_getdatabase(header, headersize); if d=0 then begin {$ifndef darwin} sectionlist:=TStringList.Create; if peinfo_getSectionList(base,sectionList) then begin for i:=0 to sectionlist.count-1 do begin if sectionlist[i]='.data' then data:=TSectionInfo(sectionlist.Objects[i]).virtualAddress; TSectionInfo(sectionlist.Objects[i]).free; end; end; sectionlist.free; {$endif} end else data:=base+d; end; end; finally if header<>nil then freememandnil(header); header:=nil; end; end; modulelist.free; end; procedure TMemoryBrowser.setcodeanddatabase; var code,data: ptrUint; begin if processid=$ffffffff then //file instead of process begin code:=0; data:=0; end else GetEntryPointAndDataBase(code,data); disassemblerview.SelectedAddress:=code; memoryaddress:=data; end; procedure TMemoryBrowser.Back1Click(Sender: TObject); begin disassemblerview.GoBack; end; procedure TMemoryBrowser.Showvaluesofstaticaddresses1Click( Sender: TObject); begin showvalues:=not showvalues; end; procedure TMemoryBrowser.FindwhatThiscodeAccesses(address: ptrUint); begin if not startdebuggerifneeded then exit; if debuggerthread<>nil then debuggerthread.FindWhatCodeAccesses(address); end; procedure TMemoryBrowser.DBVMFindwhatThiscodeAccesses(address: ptruint); const IA32_VMX_BASIC_MSR=$480; IA32_VMX_TRUE_PROCBASED_CTLS_MSR=$48e; IA32_VMX_PROCBASED_CTLS_MSR=$482; IA32_VMX_PROCBASED_CTLS2_MSR=$48b; var address2: ptrUint; res: word; id: integer; frmchangedaddresses: tfrmchangedaddresses; unlockaddress: qword; canuseept: boolean; s: string; procbased1flags: dword; i: integer; begin {$ifdef windows} LoadDBK32; canuseept:=hasEPTSupport; if canuseept=false then begin messagedlg('This function requires that your CPU supports ''Extended Page Table (EPT)'' which your CPU lacks', mtError,[mbok],0); exit; end; if loaddbvmifneeded('DBVM find routines needs DBVM for EPT page hooking. Loading DBVM can potentially cause a system freeze. Are you sure?') then begin if not loaddbvmifneeded then exit; address2:=address; s:=disassemble(address2); //spawn a DBVM watch config screen where the user can select options like lock memory if frmDBVMWatchConfigFindWhatCodeAccesses=nil then frmDBVMWatchConfigFindWhatCodeAccesses:=TfrmDBVMExecuteWatchConfig.create(self); frmDBVMWatchConfigFindWhatCodeAccesses.address:=address; frmDBVMWatchConfigFindWhatCodeAccesses.rbExecuteAccess.checked:=true; frmDBVMWatchConfigFindWhatCodeAccesses.gbAccessType.visible:=false; frmDBVMWatchConfigFindWhatCodeAccesses.cbMultipleRIP.checked:=true; frmDBVMWatchConfigFindWhatCodeAccesses.cbMultipleRIP.Visible:=false; frmDBVMWatchConfigFindWhatCodeAccesses.cbWholePage.Visible:=false; if frmDBVMWatchConfigFindWhatCodeAccesses.showmodal=mrok then begin if frmDBVMWatchConfigFindWhatCodeAccesses.LockPage then unlockaddress:=LockMemory(processid, address and QWORD($fffffffffffff000),4096) else unlockaddress:=0; id:=dbvm_watch_executes(frmDBVMWatchConfigFindWhatCodeAccesses.PhysicalAddress, address2-address, frmDBVMWatchConfigFindWhatCodeAccesses.Options, frmDBVMWatchConfigFindWhatCodeAccesses.MaxEntries); if (id<>-1) then begin //spawn a frmchangedaddresses frmchangedaddresses:=tfrmChangedAddresses.Create(application); if frmDBVMWatchConfigFindWhatCodeAccesses.LockPage then unlockaddress:=LockMemory(processid, address and QWORD($fffffffffffff000),4096) else unlockaddress:=0; frmchangedaddresses.address:=address; frmchangedaddresses.debuggerinterfacewatchid:=id; frmchangedaddresses.dbvmwatch_unlock:=unlockaddress; if defaultDisassembler.LastDisassembleData.isfloat then frmchangedaddresses.cbDisplayType.ItemIndex:=3; if uppercase(defaultDisassembler.LastDisassembleData.opcode)='RET' then begin if processhandler.is64Bit then s:='[RSP]' else s:='[ESP]'; end else begin i:=pos('[',s)+1; if i<>0 then s:=copy(s,i,pos(']',s)-i) else begin //no [ ] part if processhandler.is64Bit then s:='RDI' else s:='EDI'; end; end; frmchangedaddresses.equation:=s; frmchangedaddresses.show; end else MessageDlg('dbvm_watch failed', mtError, [mbok],0); end; end; {$endif} end; procedure TMemoryBrowser.Findoutwhataddressesthisinstructionaccesses1Click( Sender: TObject); begin try findWhatthisCodeAccesses(disassemblerview.SelectedAddress); except on e: Exception do begin MessageDlg(e.message, mtError, [mbOK], 0); end; end; end; procedure TMemoryBrowser.sbShowFloatsClick(Sender: TObject); var x: tpoint; z: trect; newleft: integer; begin if frmFloatingPointPanel=nil then frmFloatingPointPanel:=TfrmFloatingPointPanel.create(self); newleft:=left+Width; if newleft+frmFloatingPointPanel.Width>screen.Width then newleft:=screen.width-frmFloatingPointPanel.width; frmFloatingPointPanel.Left:=newleft; frmFloatingPointPanel.Top:=self.top+(self.ClientOrigin.y-self.top)-(frmFloatingPointPanel.ClientOrigin.y-frmFloatingPointPanel.top); frmFloatingPointPanel.ClientHeight:=scrollbox1.Height; frmFloatingPointPanel.SetContextPointer(debuggerthread.CurrentThread.context); frmFloatingPointPanel.show;//pop to foreground end; procedure TMemoryBrowser.ScriptConsole1Click(Sender: TObject); begin end; procedure TMemoryBrowser.DisplayTypeClick(Sender: TObject); var x: tmenuitem; begin //vtByte, vtWord, vtDword, vtDwordDec, vtSingle, vtDouble if (sender is TMenuItem) then begin x:=TMenuItem(sender); case x.tag of 0: hexview.DisplayType:=dtByte; 1: hexview.DisplayType:=dtByteDec; 2: hexview.DisplayType:=dtWord; 3: hexview.DisplayType:=dtWordDec; 4: hexview.DisplayType:=dtDword; 5: hexview.DisplayType:=dtDwordDec; 6: hexview.DisplayType:=dtQword; 7: hexview.DisplayType:=dtQwordDec; 8: hexview.DisplayType:=dtsingle; 9: hexview.DisplayType:=dtDouble; else begin if x.tag>=$1000 then begin hexview.CustomType:=TCustomType(customtypes[x.tag-$1000]); //always set first hexview.DisplayType:=dtCustom; end; end; end; end; end; procedure TMemoryBrowser.Showjumplines1Click(Sender: TObject); begin showjumplines1.checked:=not showjumplines1.checked; disassemblerview.showjumplines:=showjumplines1.checked; Onlyshowjumplineswithinrange1.Enabled:=showjumplines1.checked; end; procedure TMemoryBrowser.Onlyshowjumplineswithinrange1Click( Sender: TObject); begin Onlyshowjumplineswithinrange1.checked:=not Onlyshowjumplineswithinrange1.checked; if Onlyshowjumplineswithinrange1.checked then disassemblerview.ShowJumplineState:=jlsOnlyWithinRange else disassemblerview.ShowJumplineState:=jlsAll; end; procedure TMemoryBrowser.View1Click(Sender: TObject); begin miIPTLog.visible:=systemSupportsIntelPT and not hideiptcapability; miIPTLog.enabled:=debuggerthread<>nil; end; procedure TMemoryBrowser.Watchmemoryallocations1Click(Sender: TObject); begin if processid=0 then begin MessageDlg(rsPleaseTargetAProcessFirst, mtError,[mbok], 0); exit; end; if processid=GetCurrentProcessId then begin MessageDlg(rsPleaseTargetAnotherProcess, mtError,[mbok], 0); exit; end; if (frmMemoryAllocHandler<>nil) and (frmMemoryAllocHandler.hookedprocessid<>processid) then freeandnil(frmMemoryAllocHandler); if frmMemoryAllocHandler=nil then frmMemoryAllocHandler:=TfrmMemoryAllocHandler.Create(self); frmMemoryAllocHandler.Show; end; procedure TMemoryBrowser.reloadStacktrace; var s: pptrUintarray; x: ptrUint; i: integer; address, bytes, details: string; li: tlistitem; c: TListcolumn; refname: string; refaddress: ptruint; begin lvStacktraceData.Items.BeginUpdate; try if stacktrace2.Checked then begin //setup view for stacktrace if it isn't setup yet if lvStacktraceData.columns.Count=3 then begin lvstacktracedata.Columns.BeginUpdate; try lvstacktracedata.Columns.Clear; c:=lvstacktracedata.Columns.Add; c.Caption:=rsReturnAddress; c.Width:=lvstacktracedata.Canvas.TextWidth('DDDDDDDD'); c.AutoSize:=true; c:=lvstacktracedata.Columns.Add; c.Caption:=rsParameters; c.Width:=200; c.AutoSize:=true; finally lvstacktracedata.Columns.EndUpdate; end; end; if frmstacktrace=nil then frmstacktrace:=tfrmstacktrace.create(self); lvstacktracedata.Items.Count:=frmstacktrace.ListView1.Items.Count; end else begin //setup view for stackview if it isn't setup yet if lvStacktraceData.columns.Count<>3 then begin lvstacktracedata.Columns.BeginUpdate; try lvstacktracedata.Columns.Clear; c:=lvstacktracedata.Columns.Add; c.Caption:=rsAddress; c.Width:=80; c:=lvstacktracedata.Columns.Add; if processhandler.is64bit then begin c.Caption:='QWORD'; c.width:=160; end else begin c.Caption:='DWORD'; c.Width:=80; end; c:=lvstacktracedata.Columns.Add; c.Caption:=rsValue; c.Width:=100; c.AutoSize:=true; finally lvstacktracedata.Columns.EndUpdate; end; end; if all1.checked =false then begin //just get the list getmem(s,FStacktraceSize); try readprocessmemory(processhandle, pointer(contexthandler.StackPointerRegister^.getValue(context)),s, FStacktraceSize,x); strace.Clear; if miAddESP.checked then begin refname:=lowercase(contexthandler.StackPointerRegister^.name); refaddress:=contexthandler.StackPointerRegister^.getValue(context); end else if (processhandler.SystemArchitecture=archX86) and miAddEBP.checked then begin refname:='rbp'; if not processhandler.is64Bit then refname[1]:='e'; refaddress:=contexthandler.getRegister(refname)^.getValue(context); end else if miAddRef.checked then begin refname:=' '; refaddress:=StackReference; end; if processhandler.SystemArchitecture=archX86 then ce_stacktrace(contexthandler.StackPointerRegister^.getValue(context), pcontext(context)^.{$ifdef cpu64}rbp{$else}ebp{$endif}, contexthandler.InstructionPointerRegister^.getValue(context), pbytearray(s),x, strace,false,Nonsystemmodulesonly1.checked or modulesonly1.Checked,Nonsystemmodulesonly1.checked,0,refaddress,refname); lvstacktracedata.Items.Count:=strace.Count; finally freememandnil(s); end; end else begin lvstacktracedata.Items.Count:=(FStacktraceSize div processhandler.pointersize)-1; end; end; finally lvStacktraceData.Refresh; lvStacktraceData.Items.EndUpdate; end; end; procedure TMemoryBrowser.Maxstacktracesize1Click(Sender: TObject); var s: string; begin s:=inttostr(stacktraceSize); InputQuery(rsStacktrace, rsNewSize+':', s); try stacktraceSize:=strtoint(s); Maxstacktracesize1.Caption:=rsMaxStacktraceSize+': '+inttostr(stacktracesize); except end; end; procedure TMemoryBrowser.All1Click(Sender: TObject); begin all1.checked:=true; Modulesonly1.Checked:=false; Nonsystemmodulesonly1.Checked:=false; stacktrace2.Checked:=false; reloadstacktrace; end; procedure TMemoryBrowser.Modulesonly1Click(Sender: TObject); begin all1.checked:=false; Modulesonly1.Checked:=true; Nonsystemmodulesonly1.Checked:=false; stacktrace2.Checked:=false; reloadstacktrace; end; procedure TMemoryBrowser.Nonsystemmodulesonly1Click(Sender: TObject); begin all1.checked:=false; Modulesonly1.Checked:=false; Nonsystemmodulesonly1.Checked:=true; stacktrace2.Checked:=false; reloadstacktrace; end; procedure TMemoryBrowser.stacktrace2Click(Sender: TObject); begin all1.checked:=false; Modulesonly1.Checked:=false; Nonsystemmodulesonly1.Checked:=false; stacktrace2.Checked:=true; reloadstacktrace; end; procedure TMemoryBrowser.miReferencedFunctionsClick(Sender: TObject); begin if (dissectcode=nil) then begin if MessageDlg(rsNeedToRunDissectCode, mtConfirmation, [mbyes, mbno], 0)=mryes then begin Dissectcode1Click(sender); frmDissectCode.ondone:=odOpenReferedFunctionsList; frmDissectCode.btnStart.click; end; end else begin if frmReferencedFunctions=nil then frmReferencedFunctions:=tfrmReferencedFunctions.Create(self); frmReferencedFunctions.Show; end; end; procedure TMemoryBrowser.Referencedstrings1Click(Sender: TObject); begin if (dissectcode=nil) then begin if MessageDlg(rsNeedToRunDissectCode, mtConfirmation, [mbyes, mbno], 0)=mryes then begin Dissectcode1Click(sender); frmDissectCode.ondone:=odOpenReferedStringList; frmDissectCode.btnStart.click; end; end else begin if frmReferencedStrings=nil then frmReferencedStrings:=tfrmReferencedStrings.Create(self); frmReferencedStrings.Show; end; end; function TMemoryBrowser.GetReturnaddress: ptrUint; var haserror: boolean; stack: array [0..1023] of ptrUint; x: ptrUint; i: integer; begin result:=0; //do a stacktrace and find the return address if frmstacktrace=nil then frmstacktrace:=tfrmstacktrace.create(self); if frmStacktrace.ListView1.Items.Count>0 then begin result:=symhandler.getAddressFromName(frmStacktrace.ListView1.Items[0].SubItems[2], false,haserror); if haserror then result:=0; end; if result=0 then begin //go through the stack and find a entry that falls in executable memory ReadProcessMemory(processhandle, pointer(contexthandler.StackPointerRegister^.getValue(context)), @stack[0], 4096, x); for i:=0 to (x div processhandler.pointersize) do begin if symhandler.inModule(stack[i]) and isExecutableAddress(stack[i]) then begin result:=stack[i]; //best guess, it's an address specifier, it falls inside a module, and it's executable exit; end; end; end; end; procedure TMemoryBrowser.miDebugExecuteTillReturnClick(Sender: TObject); var x: ptrUint; begin begin x:=getreturnaddress; if x>0 then begin disassemblerview.SelectedAddress:=x; miDebugRunTill.Click; end else beep; //not possible end; end; procedure TMemoryBrowser.lvStacktraceDataData(Sender: TObject; Item: TListItem); var x: dword; value: ptrUint; a: ptrUint; address,bytes,details: string; v: TVariableType; pref: string; offset: ptrint; offsetstring: string; refname: string; begin if stacktrace2.checked then begin //show frmstacktrace if frmStacktrace=nil then begin frmstacktrace:=TfrmStacktrace.Create(self); //should never happen end; if item.Indexnil then begin if processhandler.is64bit then begin pref:='r'; value:=ptruint(pqword(ptruint(laststack)+item.Index*processhandler.pointersize)^); item.SubItems.Add(inttohex(value,16)); end else begin pref:='e'; value:=ptruint(pdword(ptruint(laststack)+item.Index*processhandler.pointersize)^); item.SubItems.Add(inttohex(value,8)); end; if miAddESP.checked then offsetstring:='('+pref+'sp+'+inttohex(item.Index*processhandler.pointersize,1)+')' else begin if miAddRef.checked then begin offset:=a-StackReference; refname:=' '; end else begin if processhandler.SystemArchitecture=archX86 then begin offset:=a-PCONTEXT(context)^.{$ifdef cpu64}rbp{$else}Ebp{$endif}; refname:=pref+'bp'; end else begin offset:=a-StackReference; refname:=' '; end; end; if offset<0 then offsetstring:='('+refname+'-'+inttohex(-offset,1)+')' else offsetstring:='('+refname+'+'+inttohex(offset,1)+')'; end; item.Caption:=inttohex(a,8)+offsetstring; v:=FindTypeOfData(a,pointer(ptruint(laststack)+item.Index*processhandler.pointersize),StacktraceSize-item.Index*processhandler.pointersize); if v in [vtbyte..vtQword] then begin //override into pointersize type if processhandler.is64bit then v:=vtQword else v:=vtDword; end; item.SubItems.Add(DataToString(pbytearray(ptruint(laststack)+item.Index*processhandler.pointersize),processhandler.pointersize, v)); end; end else begin //show strace if strace<>nil then begin if item.indexcurrentleft) and (cursorpos.X<(currentleft+lvStacktraceData.Columns[i].width)) then begin column:=i; break; end; inc(currentleft, lvStacktraceData.Columns[i].width); end; if column=0 then begin s:=pointed.Caption; i:=pos('(', s); if i>0 then s:=copy(s,1,i-1); end else s:=pointed.SubItems[column-1]; x:=symhandler.getAddressFromName(s,false,haserror); if not haserror then begin ksh:=GetKeyShiftState; if ssShift in ksh then begin disassemblerview.SelectedAddress:=x end else if ssCtrl in ksh then begin hexview.AddToBackList(pointer(memoryaddress)); memoryaddress:=x; end else if isExecutableAddress(x) then begin disassemblerview.SelectedAddress:=x end else begin hexview.AddToBackList(pointer(memoryaddress)); memoryaddress:=x; end; end; end; end; procedure TMemoryBrowser.setHexviewAddress(a: ptrUint); begin if hexview<>nil then hexview.address:=a; end; function TMemoryBrowser.getHexviewAddress:ptrUint; begin if hexview<>nil then result:=hexview.address else result:=0; end; procedure TMemoryBrowser.OnMemoryViewerRunning; begin {Disable debug functions & toolbar} //tbDebug.enabled:=false; //disable toolbar tbRun.Enabled:=false; //disable toolbar run button tbStepInto.Enabled:=false; //disable toolbar step into button tbStepOver.Enabled:=false; //disable toolbar step over button tbStepOut.Enabled:=false; //disable toolbar step out button tbRunTill.Enabled:=false; miDebugRun.Enabled:=false; miRunUnhandled.Enabled:=false; miRunUnhandled.Visible:=false; miDebugStep.Enabled:=false; miDebugStepOver.Enabled:=false; miDebugRunTill.Enabled:=false; miDebugSetAddress.enabled:=false; stacktrace1.Enabled:=false; miDebugExecuteTillReturn.Enabled:=false; ApplySourceCodeDebugUpdate; {Other tasks} //... end; procedure setControlFontKeepColor(c: TWinControl; f: TFont); var i: integer; oldc: tcolor; tc: TControl; tw: TWinControl absolute tc; begin oldc:=c.font.color; c.Font.assign(f); c.font.color:=oldc; for i:=0 to c.ControlCount-1 do begin tc:=c.Controls[i]; if (tc is TWinControl) and (tw.Controlcount>0) then setControlFontKeepColor(tw,f); if tc is TControl then begin oldc:=tc.font.color; tc.Font.assign(f); tc.font.color:=oldc; end; end; end; procedure TMemoryBrowser.setRegisterPanelFont(f: TFont); begin registerpanelfont.Assign(f); scrollbox1.ControlCount; setControlFontKeepColor(scrollbox1,f); end; procedure TMemoryBrowser.showDebugPaneltimertimer(sender: tobject); begin showdebugpaneltimer.enabled:=false; showDebugPanels:=true; registerview.ClientWidth:=lblFlags.left+lblFlags.width+16+scrollbox1.VertScrollBar.Size; scrollbox1.HorzScrollBar.Visible:=false; scrollbox1.Invalidate; end; procedure TMemoryBrowser.UpdateDebugContext(threadhandle: THandle; threadid: dword; changeselection: boolean=true; _debuggerthread: TDebuggerThread=nil); var temp: string=''; temp2: string; Regstart: string=''; charcount: integer=8; bs: dword; x: ptrUint; stackaddress: PtrUInt; i: integer=0; a: ptruint; a64: int64; d: TDisassembler; params: string; accessedreglist: tstringlist=nil; oldcontexthandler: TContextInfo; l: TLabel; gprlist, flaglist, speciallist: PContextElementRegisterList; cer: PContextElement_register; iptlog: pointer; iptlogsize: integer; begin if _debuggerthread<>nil then debuggerthread.execlocation:=41301; oldcontexthandler:=contexthandler; contexthandler:=getBestContextHandler; if processhandler.SystemArchitecture=archX86 then begin a:=contexthandler.InstructionPointerRegister^.getValue(context); d:=TDisassembler.create; d.disassemble(a, temp); params:=d.LastDisassembleData.parameters; accessedreglist:=tstringlist.create; accessedreglist.Sorted:=true; accessedreglist.Duplicates:=dupIgnore; getRegisterListFromParams(params, accessedreglist); //todo: get more data when disassembling d.free; d:=nil; end; if frmThreadlist<>nil then frmThreadlist.FillThreadlist; if _debuggerthread<>nil then _debuggerthread.execlocation:=41302; if contexthandler<>oldcontexthandler then begin //rebuild the registerlist self.BeginFormUpdate; try while pnlGeneralRegisters.ControlCount>0 do pnlGeneralRegisters.Controls[0].Free; while pnlFlags.ControlCount>0 do pnlFlags.Controls[0].Free; while pnlExtraRegisters.ControlCount>0 do pnlExtraRegisters.Controls[0].Free; gprlist:=contexthandler.getGeneralPurposeRegisters; if gprlist<>nil then begin lblRegisters.visible:=true; sRegisters.visible:=true; pnlGeneralRegisters.visible:=true; for i:=0 to length(gprlist^)-1 do begin l:=tlabel.create(self); l.Caption:=gprlist^[i].name; l.parent:=pnlGeneralRegisters; l.Cursor:=crHandPoint; l.Tag:=ptruint(@gprlist^[i]); l.PopupMenu:=pmRegisters; l.onclick:=RegisterLabelDblClick; l.OnMouseDown:=RegisterMouseDown; end; end else begin lblRegisters.visible:=false; sRegisters.visible:=false; pnlGeneralRegisters.visible:=false; end; flaglist:=contexthandler.getGeneralPurposeFlags; if flaglist<>nil then begin lblFlags.visible:=true; sflags.visible:=true; pnlFlags.visible:=true; for i:=0 to length(flaglist^)-1 do begin l:=tlabel.create(self); l.Caption:=flaglist^[i].name; l.parent:=pnlFlags; l.Cursor:=crHandPoint; l.Tag:=ptruint(@flaglist^[i]); l.PopupMenu:=pmRegisters; l.onclick:=RegisterLabelDblClick; l.OnMouseDown:=RegisterMouseDown; end; end else begin lblFlags.visible:=false; sflags.visible:=false; pnlFlags.visible:=false; end; speciallist:=contexthandler.getSpecializedRegisters; if speciallist<>nil then begin lblSpecial.visible:=true; sSpecial.visible:=true; pnlExtraRegisters.visible:=true; for i:=0 to length(speciallist^)-1 do begin l:=tlabel.create(self); l.Caption:=flaglist^[i].name; l.parent:=pnlExtraRegisters; l.Cursor:=crHandPoint; l.Tag:=ptruint(@speciallist^[i]); l.PopupMenu:=pmRegisters; l.onclick:=RegisterLabelDblClick; l.OnMouseDown:=RegisterMouseDown; end; end else begin lblSpecial.visible:=false; sSpecial.visible:=false; pnlExtraRegisters.visible:=false; end; finally EndFormUpdate; end; end; if _debuggerthread<>nil then _debuggerthread.execlocation:=41303; {} if (accessedreglist<>nil) then begin for i:=0 to pnlGeneralRegisters.ControlCount-1 do begin l:=tlabel(pnlGeneralRegisters.Controls[i]); if accessedreglist.IndexOf(PContextElement_register(l.Tag).name)>=0 then l.color:=fAccessedRegisterColor else l.color:=clNone; end; end; if _debuggerthread<>nil then _debuggerthread.execlocation:=41304; //tbDebug.enabled:=true; if (tbDebug.visible=false) and (tbDebug.Tag<>-1) then ShowDebugToolbar; //show toolbar miDebugRun.Enabled:=true; tbRun.Enabled:=true; //enable toolbar run button if debuggerthread=nil then exit; miRunUnhandled.Enabled:=(debuggerthread.CurrentThread<>nil) and debuggerthread.CurrentThread.isUnhandledException; if _debuggerthread<>nil then _debuggerthread.execlocation:=41305; miRunUnhandled.Visible:=miRunUnhandled.Enabled; tbRunUnhandled.enabled:=miRunUnhandled.enabled; tbRunUnhandled.visible:=miRunUnhandled.enabled; miDebugStep.Enabled:=true; tbStepInto.Enabled:=true; //enable toolbar step into button miDebugStepOver.Enabled:=true; tbStepOver.Enabled:=true; //enable toolbar step over button miDebugRunTill.Enabled:=true; tbRunTill.Enabled:=true; tbStepOut.Enabled:=true; //enable toolbar step out button miDebugSetAddress.enabled:=true; stacktrace1.Enabled:=true; miDebugExecuteTillReturn.Enabled:=true; if threadid<>0 then caption:=Format(rsMemoryViewerCurrentlyDebuggingThread, [inttohex(threadid, 1)]); if (debuggerthread.CurrentThread<>nil) and debuggerthread.CurrentThread.isUnhandledException then caption:=caption+' '+format(rsBecauseOfUnhandledExeption, [ExceptionCodeToString(debuggerthread.CurrentThread.lastUnhandledExceptionCode)]); if (frmstacktrace<>nil) then begin if (threadhandle=0) and (debuggerthread<>nil) and (debuggerthread.CurrentThread<>nil) then threadhandle:=debuggerthread.CurrentThread.handle; frmstacktrace.stacktrace(threadhandle, context); end; if changeselection then begin disassemblerview.SelectedAddress:=contexthandler.InstructionPointerRegister^.getValue(context); end; {} //apply the values if pnlGeneralRegisters.visible then begin for i:=0 to pnlGeneralRegisters.ControlCount-1 do begin l:=tlabel(pnlGeneralRegisters.controls[i]); cer:=PContextElement_register(l.tag); temp:=padleft(cer^.name, contexthandler.GeneralPurposeRegisterMaxCharCount)+' '+cer^.getFullValueString(context); if temp<>l.caption then begin l.Font.Color:=fChangedRegisterColor; l.Caption:=temp; end else l.Font.Color:=clWindowText; end; end; if pnlFlags.visible then begin for i:=0 to pnlFlags.ControlCount-1 do begin l:=tlabel(pnlFlags.controls[i]); cer:=PContextElement_register(l.tag); temp:=padleft(cer^.name, contexthandler.GeneralPurposeFlagMaxCharCount)+' '+cer^.getFlag(context).ToString; if temp<>l.caption then begin l.Font.Color:=fChangedRegisterColor; l.Caption:=temp; end else l.Font.Color:=clWindowText; end; end; if pnlExtraRegisters.Visible then begin for i:=0 to pnlExtraRegisters.ControlCount-1 do begin l:=tlabel(pnlExtraRegisters.controls[i]); cer:=PContextElement_register(l.tag); temp:=padleft(cer^.name, contexthandler.GeneralPurposeRegisterMaxCharCount)+' '+cer^.getValueString(context); if temp<>l.caption then begin l.Font.Color:=fChangedRegisterColor; l.Caption:=temp; end else l.Font.Color:=clWindowText; end; end; if _debuggerthread<>nil then _debuggerthread.execlocation:=41308; {} sbShowFloats.BringToFront; //sbShowFloats.visible:=true; if not registerview.visible then begin showdebugpaneltimer:=ttimer.Create(self); showDebugPaneltimer.interval:=1; showDebugPaneltimer.OnTimer:=showDebugPaneltimertimer; showDebugPaneltimer.enabled:=true; //tthread.Queue(nil, doshowdebugpanels); end; if _debuggerthread<>nil then _debuggerthread.execlocation:=41309; if laststack=nil then getmem(laststack,stacktraceSize+64); //get a stackview i:=0; stackaddress:=contexthandler.StackPointerRegister^.getValue(context); while inil then _debuggerthread.execlocation:=41310; reloadStacktrace; if _debuggerthread<>nil then _debuggerthread.execlocation:=41311; if frmFloatingPointPanel<>nil then frmFloatingPointPanel.SetContextPointer(context); if not memorybrowser.Visible then memorybrowser.show; if _debuggerthread<>nil then _debuggerthread.execlocation:=41312; if (frmWatchlist<>nil) and (frmWatchlist.Visible) then frmWatchlist.UpdateContext(context); if accessedreglist<>nil then freeandnil(accessedreglist); if _debuggerthread<>nil then _debuggerthread.execlocation:=41313; {$IFDEF WINDOWS} if (debuggerthread<>nil) and debuggerthread.usingIPT and (frmiptlog<>nil) and (frmiptlog.visible) and (debuggerthread.CurrentThread<>nil) then begin debuggerthread.CurrentThread.getLastIPTLog(iptlog,iptlogsize); frmiptlog.loadlog('',iptlog, iptlogsize); freemem(iptlog); end; {$ENDIF} registerview.OnResize(registerview); ApplyFollowRegister; ApplySourceCodeDebugUpdate; end; initialization MemoryBrowsers:=TList.Create; {$i MemoryBrowserFormUnit.lrs} finalization if MemoryBrowsers<>nil then FreeAndNil(MemoryBrowsers); end.