root/Cheat Engine/MemoryBrowserFormUnit.pas @ 308

Revision 308, 114.1 kB (checked in by dark_byte, 8 months ago)

fix setup
fix disassembly saving
fix memory dissect rightclick

Line 
1unit MemoryBrowserFormUnit;
2
3interface
4
5uses
6  Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,tlhelp32, frmMemoryAllocHandlerUnit,
7  math, StdCtrls, Spin, ExtCtrls,CEFuncProc,symbolhandler,Clipbrd, Menus,plugin,debugger,kerneldebugger, assemblerunit,disassembler,addressparser,
8  Buttons,imagehlp, Contnrs, disassemblerviewunit, peinfofunctions ,dissectcodethread
9  ,stacktrace2, NewKernelHandler, ComCtrls,FormsExtra, frmCScriptUnit , byteinterpreter, StrUtils;
10
11
12type
13  TEdit2= class( TEdit)
14  private
15  public
16    procedure wmMouseWheel (var Msg : TWMMouseWheel); message wm_MouseWheel;
17
18  end;
19
20  TDisplayType = (dtByte, dtWord, dtDword, dtDwordDec, dtSingle, dtDouble);
21
22  TMemoryBrowser = class(TForm)
23    memorypopup: TPopupMenu;
24    Goto1: TMenuItem;
25    debuggerpopup: TPopupMenu;
26    Timer2: TTimer;
27    Panel1: TPanel;
28    Panel4: TPanel;
29    Replacewithnops1: TMenuItem;
30    Gotoaddress1: TMenuItem;
31    Search1: TMenuItem;
32    Change1: TMenuItem;
33    Addthisaddresstothelist1: TMenuItem;
34    Addthisopcodetothecodelist1: TMenuItem;
35    N1: TMenuItem;
36    N2: TMenuItem;
37    Splitter1: TSplitter;
38    Panel5: TPanel;
39    RegisterView: TPanel;
40    MainMenu1: TMainMenu;
41    File1: TMenuItem;
42    Loadsymbolfile1: TMenuItem;
43    Debug1: TMenuItem;
44    Step1: TMenuItem;
45    StepOver1: TMenuItem;
46    Runtill1: TMenuItem;
47    Setbreakpoint1: TMenuItem;
48    View1: TMenuItem;
49    Stacktrace1: TMenuItem;
50    ScrollBox1: TScrollBox;
51    EAXLabel: TLabel;
52    EBXlabel: TLabel;
53    ECXlabel: TLabel;
54    EDXlabel: TLabel;
55    ESIlabel: TLabel;
56    EDIlabel: TLabel;
57    EBPlabel: TLabel;
58    ESPlabel: TLabel;
59    EIPlabel: TLabel;
60    CSLabel: TLabel;
61    DSLabel: TLabel;
62    SSlabel: TLabel;
63    ESlabel: TLabel;
64    FSlabel: TLabel;
65    GSlabel: TLabel;
66    cflabel: TLabel;
67    pflabel: TLabel;
68    aflabel: TLabel;
69    zflabel: TLabel;
70    sflabel: TLabel;
71    oflabel: TLabel;
72    Label14: TLabel;
73    Shape1: TShape;
74    Label15: TLabel;
75    Shape2: TShape;
76    Label16: TLabel;
77    Shape3: TShape;
78    Run1: TMenuItem;
79    Threadlist1: TMenuItem;
80    Assemble1: TMenuItem;
81    N3: TMenuItem;
82    Break1: TMenuItem;
83    Extra1: TMenuItem;
84    Reservememory1: TMenuItem;
85    Savedisassemledoutput1: TMenuItem;
86    Savememoryregion1: TMenuItem;
87    Loadmemolryregion1: TMenuItem;
88    N4: TMenuItem;
89    OpenMemory: TOpenDialog;
90    Debugstrings1: TMenuItem;
91    CreateThread1: TMenuItem;
92    MemoryRegions1: TMenuItem;
93    FillMemory1: TMenuItem;
94    Disectwindow1: TMenuItem;
95    SaveDialog1: TSaveDialog;
96    Heaps1: TMenuItem;
97    N5: TMenuItem;
98    N6: TMenuItem;
99    EnumeratedllsandSymbols1: TMenuItem;
100    InjectDLL1: TMenuItem;
101    OpenDllDialog: TOpenDialog;
102    AutoInject1: TMenuItem;
103    Dissectcode1: TMenuItem;
104    Createjumptocodecave1: TMenuItem;
105    N7: TMenuItem;
106    N8: TMenuItem;
107    Findstaticpointers1: TMenuItem;
108    Scanforcodecaves1: TMenuItem;
109    Changestateofregisteratthislocation1: TMenuItem;
110    ogglebreakpoint1: TMenuItem;
111    N9: TMenuItem;
112    Breakpointlist1: TMenuItem;
113    Makepagewritable1: TMenuItem;
114    Dissectdata1: TMenuItem;
115    N10: TMenuItem;
116    Showsymbols1: TMenuItem;
117    Dissectdata2: TMenuItem;
118    N11: TMenuItem;
119    N12: TMenuItem;
120    Showmoduleaddresses1: TMenuItem;
121    Symbolhandler1: TMenuItem;
122    Kerneltools1: TMenuItem;
123    Allocatenonpagedmemory1: TMenuItem;
124    Getaddress1: TMenuItem;
125    Search2: TMenuItem;
126    Assemblycode1: TMenuItem;
127    Findmemory1: TMenuItem;
128    Driverlist1: TMenuItem;
129    Plugins1: TMenuItem;
130    Sericedescriptortable1: TMenuItem;
131    N13: TMenuItem;
132    Cut1: TMenuItem;
133    Pastefromclipboard1: TMenuItem;
134    N14: TMenuItem;
135    Setsymbolsearchpath1: TMenuItem;
136    Kernelmodesymbols1: TMenuItem;
137    Breakandtraceinstructions1: TMenuItem;
138    GDTlist1: TMenuItem;
139    IDTlist1: TMenuItem;
140    ScriptEngine1: TMenuItem;
141    Newwindow1: TMenuItem;
142    Follow1: TMenuItem;
143    dflabel: TLabel;
144    Copytoclipboard1: TMenuItem;
145    copyBytes: TMenuItem;
146    copyOpcodes: TMenuItem;
147    CopyBytesAndOpcodes: TMenuItem;
148    DissectPEheaders1: TMenuItem;
149    Back1: TMenuItem;
150    Showvaluesofstaticaddresses1: TMenuItem;
151    Findoutwhataddressesthisinstructionaccesses1: TMenuItem;
152    ScriptConsole1: TMenuItem;
153    DisplayType1: TMenuItem;
154    N15: TMenuItem;
155    dispBytes: TMenuItem;
156    dispWords: TMenuItem;
157    dispDwords: TMenuItem;
158    dispFloat: TMenuItem;
159    dispDouble: TMenuItem;
160    dispInts: TMenuItem;
161    Jumplines1: TMenuItem;
162    Showjumplines1: TMenuItem;
163    Onlyshowjumplineswithinrange1: TMenuItem;
164    Watchmemoryallocations1: TMenuItem;
165    Continueanddetachdebugger1: TMenuItem;
166    N16: TMenuItem;
167    Panel3: TPanel;
168    Panel2: TPanel;
169    Protectlabel: TLabel;
170    MBCanvas: TPaintBox;
171    HexEdit: TEdit;
172    TextEdit: TEdit;
173    ScrollBar2: TScrollBar;
174    Splitter3: TSplitter;
175    pnlStacktrace: TPanel;
176    sbShowFloats: TSpeedButton;
177    pmStacktrace: TPopupMenu;
178    All1: TMenuItem;
179    Modulesonly1: TMenuItem;
180    Nonsystemmodulesonly1: TMenuItem;
181    lvStacktraceData: TListView;
182    N17: TMenuItem;
183    Maxstacktracesize1: TMenuItem;
184    Splitter2: TSplitter;
185    Referencedstrings1: TMenuItem;
186    N18: TMenuItem;
187    stacktrace2: TMenuItem;
188    Executetillreturn1: TMenuItem;
189    procedure Button4Click(Sender: TObject);
190    procedure Button2Click(Sender: TObject);
191    procedure Splitter1Moved(Sender: TObject);
192    procedure FormShow(Sender: TObject);
193    procedure FormCreate(Sender: TObject);
194    procedure Goto1Click(Sender: TObject);
195    procedure FormResize(Sender: TObject);
196    procedure MemoryLabelClick(Sender: TObject);
197    procedure MBCanvasPaint(Sender: TObject);
198    procedure Timer2Timer(Sender: TObject);
199    procedure MBCanvasMouseUp(Sender: TObject; Button: TMouseButton;
200      Shift: TShiftState; X, Y: Integer);
201    procedure MBCanvasMouseMove(Sender: TObject; Shift: TShiftState; X,
202      Y: Integer);
203    procedure MBCanvasDblClick(Sender: TObject);
204    procedure memorypopupPopup(Sender: TObject);
205    procedure Replacewithnops1Click(Sender: TObject);
206    procedure FControl2KeyDown(Sender: TObject; var Key: Word;
207      Shift: TShiftState);
208    procedure FControl2KeyPress(Sender: TObject; var Key: Char);
209    procedure FControl2Enter(Sender: TObject);
210    procedure FControl2Exit(Sender: TObject);
211    procedure FControl1Exit(Sender: TObject);
212
213    procedure FControl1KeyDown(Sender: TObject; var Key: Word;
214      Shift: TShiftState);
215    procedure FControl1KeyPress(Sender: TObject; var Key: Char);
216    procedure Gotoaddress1Click(Sender: TObject);
217    procedure Search1Click(Sender: TObject);
218    procedure Change1Click(Sender: TObject);
219    procedure Addthisaddresstothelist1Click(Sender: TObject);
220    procedure Addthisopcodetothecodelist1Click(Sender: TObject);
221    procedure Splitter1CanResize(Sender: TObject; var NewSize: Integer;
222      var Accept: Boolean);
223    procedure ScrollBar2Scroll(Sender: TObject; ScrollCode: TScrollCode;
224      var ScrollPos: Integer);
225    procedure FormClose(Sender: TObject; var Action: TCloseAction);
226    procedure Run1Click(Sender: TObject);
227    procedure Step1Click(Sender: TObject);
228    procedure StepOver1Click(Sender: TObject);
229    procedure Runtill1Click(Sender: TObject);
230    procedure Stacktrace1Click(Sender: TObject);
231    procedure Threadlist1Click(Sender: TObject);
232    procedure Assemble1Click(Sender: TObject);
233    procedure HexEditKeyPress(Sender: TObject; var Key: Char);
234    procedure HexEditExit(Sender: TObject);
235    procedure HexEditKeyDown(Sender: TObject; var Key: Word;
236      Shift: TShiftState);
237    procedure EAXLabelDblClick(Sender: TObject);
238    procedure Break1Click(Sender: TObject);
239    procedure Reservememory1Click(Sender: TObject);
240    procedure Savememoryregion1Click(Sender: TObject);
241    procedure Loadmemolryregion1Click(Sender: TObject);
242    procedure HexEditDblClick(Sender: TObject);
243    procedure Debugstrings1Click(Sender: TObject);
244    procedure TextEditExit(Sender: TObject);
245    procedure TextEditKeyDown(Sender: TObject; var Key: Word;
246      Shift: TShiftState);
247    procedure CreateThread1Click(Sender: TObject);
248    procedure MemoryRegions1Click(Sender: TObject);
249    procedure TextEditKeyPress(Sender: TObject; var Key: Char);
250    procedure FillMemory1Click(Sender: TObject);
251    procedure Disectwindow1Click(Sender: TObject);
252    procedure Savedisassemledoutput1Click(Sender: TObject);
253    procedure Heaps1Click(Sender: TObject);
254    procedure EnumeratedllsandSymbols1Click(Sender: TObject);
255    procedure InjectDLL1Click(Sender: TObject);
256    procedure AutoInject1Click(Sender: TObject);
257    procedure Dissectcode1Click(Sender: TObject);
258    procedure Createjumptocodecave1Click(Sender: TObject);
259    procedure Findstaticpointers1Click(Sender: TObject);
260    procedure Scanforcodecaves1Click(Sender: TObject);
261    procedure Changestateofregisteratthislocation1Click(Sender: TObject);
262    procedure ogglebreakpoint1Click(Sender: TObject);
263    procedure Breakpointlist1Click(Sender: TObject);
264    procedure Makepagewritable1Click(Sender: TObject);
265    procedure Dissectdata1Click(Sender: TObject);
266    procedure Showsymbols1Click(Sender: TObject);
267    procedure Dissectdata2Click(Sender: TObject);
268    procedure Showmoduleaddresses1Click(Sender: TObject);
269    procedure Symbolhandler1Click(Sender: TObject);
270    procedure Allocatenonpagedmemory1Click(Sender: TObject);
271    procedure Getaddress1Click(Sender: TObject);
272    procedure Findmemory1Click(Sender: TObject);
273    procedure Assemblycode1Click(Sender: TObject);
274    procedure Driverlist1Click(Sender: TObject);
275    procedure Sericedescriptortable1Click(Sender: TObject);
276    procedure MBCanvasMouseDown(Sender: TObject; Button: TMouseButton;
277      Shift: TShiftState; X, Y: Integer);
278    procedure Cut1Click(Sender: TObject);
279    procedure Pastefromclipboard1Click(Sender: TObject);
280    procedure Setsymbolsearchpath1Click(Sender: TObject);
281    procedure Kernelmodesymbols1Click(Sender: TObject);
282    procedure Breakandtraceinstructions1Click(Sender: TObject);
283    procedure debuggerpopupPopup(Sender: TObject);
284    procedure GDTlist1Click(Sender: TObject);
285    procedure IDTlist1Click(Sender: TObject);
286    procedure ScriptEngine1Click(Sender: TObject);
287    procedure FormDestroy(Sender: TObject);
288    procedure Newwindow1Click(Sender: TObject);
289    procedure Follow1Click(Sender: TObject);
290    procedure CopyBytesAndOpcodesClick(Sender: TObject);
291    procedure DissectPEheaders1Click(Sender: TObject);
292    procedure Back1Click(Sender: TObject);
293    procedure Showvaluesofstaticaddresses1Click(Sender: TObject);
294    procedure Findoutwhataddressesthisinstructionaccesses1Click(
295      Sender: TObject);
296    procedure sbShowFloatsClick(Sender: TObject);
297    procedure ScriptConsole1Click(Sender: TObject);
298    procedure DisplayTypeClick(Sender: TObject);
299    procedure Showjumplines1Click(Sender: TObject);
300    procedure Onlyshowjumplineswithinrange1Click(Sender: TObject);
301    procedure Watchmemoryallocations1Click(Sender: TObject);
302    procedure Continueanddetachdebugger1Click(Sender: TObject);
303    procedure Panel2Resize(Sender: TObject);
304    procedure Panel2MouseDown(Sender: TObject; Button: TMouseButton;
305      Shift: TShiftState; X, Y: Integer);
306    procedure ScrollBox1Resize(Sender: TObject);
307    procedure Maxstacktracesize1Click(Sender: TObject);
308    procedure All1Click(Sender: TObject);
309    procedure Modulesonly1Click(Sender: TObject);
310    procedure Nonsystemmodulesonly1Click(Sender: TObject);
311    procedure Referencedstrings1Click(Sender: TObject);
312    procedure stacktrace2Click(Sender: TObject);
313    procedure Executetillreturn1Click(Sender: TObject);
314    procedure lvStacktraceDataData(Sender: TObject; Item: TListItem);
315  private
316    { Private declarations }
317    posloadedfromreg: boolean;
318    displaytype: TDisplayType;
319
320
321    editing: boolean;
322    editing2: boolean;
323
324    srow,scolumn: integer;
325
326    bytelength: integer;
327    chrlength: integer;
328
329    MBImage: TBitmap;
330    memorylabelcount: integer;
331    addresslabelcount: integer;
332    addresslabel: array of TLabel;
333    memorylabel: array of TLabel; //hex
334    memoryLabelA: array of TLabel; //ascii
335    MemoryLabelVerticalLines: integer;  //number of rows
336    MemoryLabelHorizontalLines: Integer;  //the number of lines
337
338    addressestext: array of string[8];
339    memorytext: array of string[2];
340    memorystring: array of string;
341    lengthof8bytes: Integer;
342    textheight: integer;
343
344
345    lines: integer;
346    oldlines: integer;
347    Highlightcolor: Tcolor;
348
349    numberofaddresses: integer;
350
351
352    part: integer;
353
354    {$ifndef net}
355
356    {$endif}
357
358
359    lastmodulelistupdate: integer;
360
361    disassemblerHistory: TStringList;
362    memorybrowserHistory: TStringList;
363    assemblerHistory: TStringList;
364
365    backlist: TStack;
366
367    lastspecialwidth: integer;
368    FShowValues: boolean;
369    FShowDebugPanels: boolean;
370    FStacktraceSize: integer;
371
372    strace: Tstringlist;
373
374    procedure SetStacktraceSize(size: integer);
375    procedure setShowDebugPanels(state: boolean);
376    procedure UpdateRWAddress(disasm: string);
377    procedure WMGetMinMaxInfo(var Message: TMessage); message WM_GETMINMAXINFO;
378    function getShowValues: boolean;
379    procedure setShowValues(newstate: boolean);
380
381
382    procedure disassemblerviewDblClick(Sender: TObject);
383  public
384    { Public declarations }
385    FSymbolsLoaded: Boolean;
386    memoryaddress: dword;
387    thhandle: Thandle;
388
389    disassemblerview: TDisassemblerview;
390
391    lastdebugcontext: _Context;
392    //EAXv: dword;
393    //EBXv: dword;
394    //ECXv: dword;
395    //EDXv: dword;
396    //ESIv: dword;
397    //EDIv: dword;
398    //EBPv: dword;
399    //ESPv: dword;
400    //EIPv: dword;
401    FControl2:Tedit2;
402    rows8: integer;
403    disassembler: boolean;
404    selecting,selectionmade: boolean;
405    selected,selected2: dword;
406    cancelsearch: boolean;
407
408    ischild: boolean; //determines if it's the main memorybrowser or a child
409
410    procedure FindwhatThiscodeAccesses(address: dword);
411    procedure UpdateBPlist;
412    procedure UpdateRegisterview;
413    procedure RefreshMB;
414    procedure AssemblePopup(x: string);
415
416    procedure plugintype1click(sender:tobject);
417    procedure plugintype6click(sender:tobject);
418    procedure setcodeanddatabase;
419    property showvalues: boolean read getShowValues write setShowValues;
420    property showDebugPanels: boolean read fShowDebugPanels write setShowDebugPanels;
421    property stacktraceSize: integer read FStacktraceSize write SetStacktraceSize;
422    procedure reloadStacktrace;
423    function GetReturnaddress: dword;
424  end;
425
426var
427  MemoryBrowser: TMemoryBrowser;
428  mbchildcount: integer; //global so all other children can increase it as well
429
430 
431implementation
432
433uses Valuechange,
434  {$ifdef net}
435  unit2,
436  addformunit,
437  {$else}
438  Mainunit,
439  {$endif}
440
441  {$ifndef net}
442  AddAddress,
443  findwindowunit,
444  frmstacktraceunit,
445  frmBreakThreadUnit,
446  FormDebugStringsUnit,
447  frmDissectWindowUnit,
448  frmEnumerateDLLsUnit,
449  frmThreadlistunit,
450  formmemoryregionsunit,
451  frmHeapsUnit,
452  frmFindstaticsUnit,
453  frmModifyRegistersUnit,
454  frmBreakpointlistunit,
455  savedisassemblyfrm,
456  {$endif}
457  advancedoptionsunit,
458  frmautoinjectunit,
459  formsettingsunit,
460  frmSaveMemoryRegionUnit,
461  frmLoadMemoryunit,
462  inputboxtopunit,
463  formAddToCodeList,
464  frmFillMemoryUnit,
465  frmCodecaveScannerUnit,
466  FoundCodeUnit,
467  frmFunctionListUnit,
468
469
470
471
472  {$ifndef net}symbolconfigunit,frmTracerUnit,Structuresfrm,dissectcodeunit,pointerscannerfrm,driverlist,ServiceDescriptorTables,{$endif}
473  frmDisassemblyscanunit, frmGDTunit, frmIDTunit, peINFOunit,
474  formChangedAddresses, frmFloatingPointPanelUnit,
475  frmReferencedStringsUnit;
476
477
478
479{$R *.DFM}
480
481
482procedure TEdit2.wmMouseWheel (var Msg : TWMMouseWheel);
483begin
484  with (parent as TMemorybrowser) do
485  begin
486    if msg.WheelDelta>0 then
487      memoryaddress:=memoryaddress-(8*rows8*4)
488    else
489      memoryaddress:=memoryaddress+(8*rows8*4);
490
491    refreshMB;
492  end;
493end;
494
495//property functions:
496function TMemoryBrowser.getShowValues: boolean;
497begin
498  result:=FShowValues;
499end;
500
501procedure TMemoryBrowser.setShowValues(newstate: boolean);
502begin
503  Showvaluesofstaticaddresses1.checked:=newstate;
504  FShowValues:=newstate;
505  disassemblerview.setCommentsTab(FShowValues);
506end;
507
508procedure TMemoryBrowser.setShowDebugPanels(state: boolean);
509begin
510  FShowDebugPanels:=state;
511  registerview.Visible:=state;
512  pnlStacktrace.Visible:=state;
513  splitter2.Visible:=state;
514  splitter3.Visible:=state;
515end;
516
517procedure TMemoryBrowser.SetStacktraceSize(size: integer);
518begin
519  FStacktraceSize:=size;
520  reloadStacktrace;
521end;
522
523//^^^^
524
525
526procedure TMemoryBrowser.WMGetMinMaxInfo(var Message: TMessage);
527var MMInfo: ^MINMAXINFO;
528begin
529  if panel1.visible then
530  begin
531    MMInfo:=ptr(message.LParam);
532    MMInfo.ptMinTrackSize:=point(340,panel1.Height+100);
533  end
534  else
535  begin
536    MMInfo:=ptr(message.LParam);
537    MMInfo.ptMinTrackSize:=point(340,100);
538  end;
539end;
540
541procedure TMemoryBrowser.UpdateBPlist;
542begin
543  {$ifndef net}
544  if frmBreakpointlist<>nil then
545    frmBreakpointlist.updatebplist;
546  {$endif}
547end;
548
549
550procedure TMemoryBrowser.UpdateRegisterview;
551begin
552//removed till 3.3
553end;
554
555
556
557procedure TMemoryBrowser.UpdateRWAddress(disasm: string);
558var seperator: integer;
559    fb: integer;
560    nb: integer;
561    address: string;
562    offset:dword;
563begin
564  //temporaryily obsolete
565 
566{  seperator:=pos(',',disasm);
567  if seperator>0 then
568  begin
569    fb:=pos('[',disasm);
570    nb:=pos(']',disasm);
571
572    if nb>fb then
573    begin
574      //if fb<seperator then label1.Font.Color:=clRed //write
575      //                else label1.font.color:=clGreen; //read
576      address:=copy(disasm,fb+1,nb-fb-1);
577
578      try
579        offset:=getaddress(address);
580      except
581
582      end;
583      //label1.Caption:=IntToHex(offset,8);
584    end;
585  end; }
586end;
587
588procedure TMemoryBrowser.Button4Click(Sender: TObject);
589begin
590  {$ifndef net}
591  debuggerthread.howtocontinue:=1;
592  debuggerthread.stepping:=false;
593  memorybrowser.Caption:='Advanced - Debug:Stepping';
594  {$endif}
595end;
596
597procedure TMemoryBrowser.Button2Click(Sender: TObject);
598begin
599  {$ifndef net}
600  debuggerthread.howtocontinue:=0;
601  debuggerthread.stepping:=false;
602  memorybrowser.Caption:='Advanced - Debug:Running';
603  {$endif}
604end;
605
606procedure TMemoryBrowser.Splitter1Moved(Sender: TObject);
607begin
608  disassemblerview.Update;
609end;
610
611procedure TMemoryBrowser.FormShow(Sender: TObject);
612var x: array of integer;
613
614begin
615  disassemblerview.Update;;
616  mbimage.Width:=0;  //clear the image
617  mbimage.Width:=clientwidth;
618
619  RefreshMB;
620
621  {$ifdef net}
622  registerview.Visible:=false;
623  stacktrace1.Visible:=false;
624  breakpointlist1.Visible:=false;
625  threadlist1.Visible:=false;
626  debugstrings1.Visible:=false;
627  n5.Visible:=false;
628  memoryregions1.Visible:=false;
629  heaps1.Visible:=false;
630  n6.Visible:=false;
631  enumeratedllsandsymbols1.Visible:=false;
632  n10.visible:=false;
633  showsymbols1.Visible:=false;
634  showmoduleaddresses1.Visible:=false;
635  symbolhandler1.Visible:=false;
636  debug1.Visible:=false;
637  view1.Visible:=false;
638
639  scanforcodecaves1.Visible:=false;
640  reservememory1.Visible:=false;
641  fillmemory1.Visible:=false;
642  createthread1.Visible:=false;
643  n8.visible:=false;
644  injectdll1.visible:=false;
645
646  search1.Visible:=false;
647  Changestateofregisteratthislocation1.Visible:=false;
648  ogglebreakpoint1.Visible:=false;
649  n9.Visible:=false;
650
651  dissectcode1.Visible:=false;
652  dissectdata2.visible:=false;
653  disectwindow1.visible:=false;
654
655  n12.visible:=false;
656  dissectdata1.Visible:=false;
657  findstaticpointers1.Visible:=false;
658  n11.Visible:=true;
659  injectdll1.Visible:=false;
660  autoinject1.Visible:=true;
661  {$endif}
662
663
664
665  Sericedescriptortable1.visible:=not Is64bitOS;
666  GDTlist1.Visible:=not is64bitos;
667  IDTlist1.Visible:=not is64bitos;
668
669
670end;
671
672procedure TMemoryBrowser.disassemblerviewDblClick(Sender: TObject);
673begin
674  assemble1.Click;
675end;
676
677procedure TMemoryBrowser.FormCreate(Sender: TObject);
678var x: array of integer;
679begin
680  displaytype:=dtByte;
681  scriptconsole1.ShortCut:=TextToShortCut('Ctrl+Shift+C');
682
683  strace:=tstringlist.create;
684
685
686{
687not enough time to add header supports
688
689
690}
691 { disassemblerheader.Visible:=false;
692  discanvas.Top:=discanvas.top-disassemblerheader.Height;
693  discanvas.Height:=discanvas.Height+disassemblerheader.Height;
694  //ronresize isn't repainting correctly   }
695{^^^^}
696
697  disassembler:=true;
698
699  disassemblerview:=TDisassemblerview.Create(self);
700  disassemblerview.Align:=alClient;
701  disassemblerview.Parent:=panel5;
702  disassemblerview.PopupMenu:=debuggerpopup;
703  disassemblerview.OnKeyDown:=FControl1keydown;
704  disassemblerview.OnDblClick:=disassemblerviewDblClick;
705
706  disassemblerview.TopAddress:=$00400000;
707   
708
709  fcontrol2:=tedit2.create(self);
710  fcontrol2.Width:=0;
711  fcontrol2.Height:=0;
712  fcontrol2.parent:=self;
713  fcontrol2.OnEnter:=FControl2Enter;
714  fcontrol2.onexit:=FControl2Exit;
715  fcontrol2.onKeydown:=FControl2keydown;
716  fcontrol2.onkeypress:=FControl2keypress;
717  fcontrol2.PopupMenu:=mainform.emptypopup;
718  fcontrol2.SendToBack;
719
720
721  MBImage:=TBitmap.Create;
722  MBImage.Canvas.Brush.Color:=clBtnFace;
723  MBImage.Width:=mbcanvas.Width*3;
724  MBImage.Height:=MBCanvas.Height*3;
725  MBImage.Canvas.Font.Name:='Courier';
726
727  textheight:=MBImage.Canvas.TextHeight('||||');
728  bytelength:=MBImage.Canvas.TextWidth('   ');
729  chrlength:=MBImage.Canvas.TextWidth(' ');
730
731  hexedit.Height:=textheight;
732  hexedit.Width:=chrlength*2;
733  textedit.Height:=hexedit.Height;
734  textedit.Width:=chrlength;
735
736  memoryaddress:=$00400000;
737  memorylabelcount:=0;
738
739  Highlightcolor:=clHighlight;
740
741  disassemblerHistory:=TStringList.create;
742  memorybrowserHistory:=TStringList.create;
743  assemblerHistory:=TStringList.create;
744
745  backlist:=TStack.create;
746
747  showvalues:=true;
748  sbShowFloats.left:=scrollbox1.Clientwidth-sbShowFloats.width;
749
750  FStacktraceSize:=4096;
751 
752
753  setlength(x, 6);
754
755  if loadformposition(self,x) then
756  begin
757    disassemblerview.setheaderWidth(0,x[0]);
758    disassemblerview.setheaderWidth(1,x[1]);
759    disassemblerview.setheaderWidth(2,x[2]);
760    disassemblerview.setheaderWidth(3,x[3]);
761
762    panel1.height:=x[4];
763    registerview.width:=x[5];
764
765    setlength(x,0);
766    posloadedfromreg:=true;
767  end;
768
769end;
770
771procedure TMemoryBrowser.Goto1Click(Sender: TObject);
772var newaddress: string;
773    canceled: boolean;
774begin
775  panel4.setfocus;
776  newaddress:=inputboxtop('Goto Address','Fill in the address you want to go to',IntTohex(memoryaddress,8),true,canceled,memorybrowserHistory);
777
778  memoryaddress:=getaddress(newaddress);
779
780  fcontrol2.SetFocus;
781
782  RefreshMB;
783end;
784
785procedure TMemoryBrowser.FormResize(Sender: TObject);
786begin
787  mbimage.Width:=0;
788  mbimage.height:=0;
789  mbimage.Width:=mbcanvas.Width;
790  mbimage.Height:=mbcanvas.Height;
791  refreshmb;
792  disassemblerview.Update;;
793end;
794
795procedure TMemoryBrowser.MemoryLabelClick(Sender: TObject);
796var address: dword;
797begin
798  address:=memoryaddress+(sender as TLabel).Tag;
799  showmessage(inttohex(address,8));
800
801end;
802
803procedure TMemoryBrowser.MBCanvasPaint(Sender: TObject);
804var cr: Trect;
805begin
806  cr:=mbcanvas.Canvas.ClipRect;
807  mbcanvas.Canvas.CopyRect(cr,mbimage.Canvas,cr);
808end;
809
810
811procedure TMemoryBrowser.Timer2Timer(Sender: TObject);
812begin
813  if Visible then
814  begin
815    refreshMB;
816    disassemblerview.Update;
817
818    //refresh the modulelist
819    lastmodulelistupdate:=(lastmodulelistupdate+1) mod 10;
820    if lastmodulelistupdate=0 then
821      symhandler.loadmodulelist;
822  end;
823end;
824
825
826procedure TMemoryBrowser.RefreshMB;
827var i: integer;
828    j,k: integer;
829    currentaddress: string[8];
830    bts: string[20];
831
832    start: integer;
833    stop: integer;
834    needed: integer;
835    available: integer;
836    rowsof8: integer;
837    teststr: string;
838
839    p: pchar;
840    a: int64;
841
842    range1ok: boolean;
843    range1start: dword;
844    range1length: dword;
845
846    range2ok: boolean;
847    range2start: dword;
848    range2length: dword;
849
850
851    buffer: array of byte;
852    bt: byte;
853    bytesread: dword;
854
855
856    rct: Trect;
857
858    mbi : _MEMORY_BASIC_INFORMATION;
859
860    range1module: tmoduleinfo;
861    range2module: tmoduleinfo;
862    module1ok,module2ok: boolean;
863    s: string;
864    selstart,selstop: integer;
865  procedure getBTSString(unreadable: boolean);
866  {
867  Because this same code snippet is used in range1 AND range 2 it's betetr to make it a subfunction
868  }
869  var x: string;
870  begin
871    bts:='';
872    case displayType of
873      dtByte:
874      begin
875        if unreadable then
876          bts:='??'
877        else
878          bts:=IntToHex(buffer[j+(i*8*rowsof8)],2);
879      end;
880
881      dtWord:
882      begin
883        if j mod 2 = 0 then
884        begin
885          if unreadable then
886            bts:='????'
887          else
888            bts:=IntToHex(pword(@buffer[j+(i*8*rowsof8)])^,4);
889           
890          while length(bts)<5 do
891            bts:=bts+' ';
892        end;
893      end;
894
895      dtDWord:
896      begin
897        if j mod 4 = 0 then
898        begin
899          if unreadable then
900            bts:='????????'
901          else
902            bts:=IntToHex(pdword(@buffer[j+(i*8*rowsof8)])^,8);
903           
904          while length(bts)<10 do
905            bts:=bts+' ';
906        end;
907      end;
908
909      dtDwordDec:
910      begin
911        if j mod 4 = 0 then
912        begin
913          if unreadable then
914            bts:='?????'
915          else
916            bts:=IntToStr(pinteger(@buffer[j+(i*8*rowsof8)])^);
917
918          if length(bts)>9 then
919            bts:=copy(bts,1,6)+'...';
920           
921          while length(bts)<10 do
922            bts:=bts+' ';
923        end;
924      end;
925
926      dtSingle:
927      begin
928        if j mod 4 = 0 then
929        begin
930          if unreadable then
931            bts:='???'
932          else
933            bts:=format('%f',[psingle(@buffer[j+(i*8*rowsof8)])^]);
934           
935          if length(bts)>9 then
936            bts:=copy(bts,1,6)+'...';
937
938          while length(bts)<10 do
939            bts:=bts+' ';
940        end;
941      end;
942
943      dtDouble:
944      begin
945        if j mod 8 = 0 then
946        begin
947          if unreadable then
948            bts:='???'
949          else
950            bts:=format('%f',[pDouble(@buffer[j+(i*8*rowsof8)])^]);
951           
952          if length(bts)>18 then
953            bts:=copy(bts,1,16)+'...';
954
955          while length(bts)<19 do
956            bts:=bts+' ';
957        end;
958      end;
959    end;
960  end;
961begin
962  //find the address in the module list
963
964  if selected<=selected2 then
965  begin
966    selstart:=selected;
967    selstop:=selected2;
968  end
969  else
970  begin
971    selstart:=selected2;
972    selstop:=selected;
973  end;
974
975
976  k:=0;
977  MBCanvas.Canvas.Font:=MBImage.Canvas.Font;
978
979  if length(addressestext)<((mbcanvas.Height) div (TextHeight))+2 then //resync
980  begin
981    setlength(addressestext,0);
982    setlength(addressestext,((mbcanvas.Height) div (TextHeight))+2);
983    setlength(memorystring,0);
984    setlength(memorystring,((mbcanvas.Height) div (TextHeight))+2);
985  end;
986
987  start:=20+mbimage.Canvas.TextWidth('00400000');
988  rowsof8:=0;
989
990  needed:=0;
991
992  available:=mbcanvas.Width-(start+20*rowsof8)-mbimage.Canvas.TextWidth('??');
993
994  while available>(needed) do
995  begin
996    inc(rowsof8);
997    teststr:='';
998    for i:=1 to rowsof8 do teststr:=teststr+'????????';
999    needed:=10+mbcanvas.Canvas.TextWidth(teststr);
1000
1001    available:=mbcanvas.Width-(start+20*((8*rowsof8)-1))-mbcanvas.Canvas.TextWidth('??');
1002  end;
1003
1004  dec(rowsof8);
1005
1006  if rowsof8=0 then rowsof8:=1;
1007 
1008  rows8:=rowsof8;
1009
1010  if length(memorytext)<8*rowsof8 then
1011  begin
1012    setlength(memorytext,0);
1013    setlength(memorytext,8*rowsof8+1);
1014  end;
1015
1016   //fill local array
1017  setlength(buffer,(((mbcanvas.Height) div (TextHeight))+1)*(8*rowsof8)+257);
1018
1019  range1start:=memoryaddress;
1020  range1length:=2048-(range1start mod 2048);
1021  if range1length>((((mbcanvas.Height) div (TextHeight))+1)*(8*rowsof8)) then range1length:=((((mbcanvas.Height) div (TextHeight))+1)*(8*rowsof8));
1022
1023 // range1length:=(range1start+(((mbcanvas.Height-5) div (TextHeight))+1)*(8*rowsof8));// mod 2048;
1024
1025  range2start:=range1start+range1length;
1026  range2length:=((((mbcanvas.Height) div (TextHeight))+1)*(8*rowsof8))-range1length;
1027
1028  //get the modules (if they have any)
1029  module1ok:=symhandler.getmodulebyaddress(range1start,range1module);
1030  module2ok:=symhandler.getmodulebyaddress(range2start,range2module);
1031
1032
1033  zeromemory(@buffer[0],length(buffer));
1034  range1ok:=readprocessmemory(processhandle,pointer(range1start),@buffer[0],range1length,bytesread);
1035  if range2length>0 then range2ok:=readprocessmemory(processhandle,pointer(range2start),@buffer[range1length],range2length,bytesread) else range2ok:=false;
1036
1037  for i:=0 to ((mbcanvas.Height) div (TextHeight))+1 do
1038  begin
1039    //addresses
1040    mbcanvas.Canvas.font.Color:=clwindowtext;
1041    mbimage.Canvas.font.Color:=clwindowtext;
1042
1043    currentaddress:=IntToHex(dword(memoryaddress+i*8*rowsof8),8);
1044    mbcanvas.Canvas.TextOut(10,i*TextHeight+2,currentaddress);
1045    mbimage.Canvas.TextOut(10,i*TextHeight+2,currentaddress);
1046
1047    if addressestext[i]<>currentaddress then
1048    begin
1049
1050      addressestext[i]:=currentaddress;
1051    end;
1052
1053    //bytes
1054
1055    teststr:='';
1056
1057    p:=pointer(memoryaddress+i*8*rowsof8);
1058    a:=memoryaddress+i*8*rowsof8;
1059
1060    j:=0;
1061    while j<(8*rowsof8) do
1062    begin
1063      if a<int64(int64(range1start)+int64(range1length)) then
1064      begin
1065        if range1ok then
1066        begin
1067          //readable
1068          if (selecting or selectionmade) and (selstart<>selstop) and ((((memoryaddress+i*8*rowsof8)+j)>=selstart) and (((memoryaddress+i*8*rowsof8)+j)<=selstop)) then
1069          begin
1070            mbcanvas.Canvas.font.Color:=clred;
1071            mbimage.Canvas.font.Color:=clred;
1072          end
1073          else
1074          begin
1075            if (module1ok) then
1076            begin
1077              mbcanvas.Canvas.font.Color:=clgreen;
1078              mbimage.Canvas.font.Color:=clgreen;
1079            end
1080            else
1081            begin
1082              mbcanvas.Canvas.font.Color:=clwindowtext;
1083              mbimage.Canvas.font.Color:=clwindowtext;
1084            end;
1085          end;
1086
1087          GetBTSstring(false);
1088
1089
1090          mbcanvas.Canvas.TextOut(start+20*j,i*textHeight+2,bts);
1091          mbimage.Canvas.TextOut(start+20*j,i*textHeight+2,bts);
1092
1093          if buffer[j+(i*8*rowsof8)]<$20 then
1094          begin
1095            mbcanvas.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,' ');
1096            mbimage.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,' ');
1097          end else
1098          begin
1099            mbcanvas.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,chr(buffer[j+(i*8*rowsof8)]));
1100            mbimage.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,chr(buffer[j+(i*8*rowsof8)]));
1101          end;
1102        end
1103        else
1104        begin
1105          //unreadable
1106          if (selecting or selectionmade) and (selstart<>selstop) and ((((memoryaddress+i*8*rowsof8)+j)>=selstart) and (((memoryaddress+i*8*rowsof8)+j)<=selstop)) then
1107          begin
1108            mbcanvas.Canvas.font.Color:=clred;
1109            mbimage.Canvas.font.Color:=clred;
1110          end
1111          else
1112          begin
1113            mbcanvas.Canvas.font.Color:=clwindowtext;
1114            mbimage.Canvas.font.Color:=clwindowtext;
1115          end;
1116
1117          GetBTSstring(true);
1118          mbcanvas.Canvas.TextOut(start+20*j,i*textHeight+2,bts);
1119          mbimage.Canvas.TextOut(start+20*j,i*textHeight+2,bts);
1120
1121          mbcanvas.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,'?');
1122          mbimage.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,'?');
1123
1124//          teststr:=teststr+'?';
1125        end;
1126      end
1127      else
1128      begin
1129        //range 2
1130        if range2ok then
1131        begin
1132          if (selecting or selectionmade) and (selstart<>selstop) and ((((memoryaddress+i*8*rowsof8)+j)>=selstart) and (((memoryaddress+i*8*rowsof8)+j)<=selstop)) then
1133          begin
1134            mbcanvas.Canvas.font.Color:=clred;
1135            mbimage.Canvas.font.Color:=clred;
1136          end
1137          else
1138          begin
1139            if (module2ok) then
1140            begin
1141              mbcanvas.Canvas.font.Color:=clgreen;
1142              mbimage.Canvas.font.Color:=clgreen;
1143            end
1144            else
1145            begin
1146              mbcanvas.Canvas.font.Color:=clwindowtext;
1147              mbimage.Canvas.font.Color:=clwindowtext;
1148            end;
1149          end;
1150
1151          //readable
1152          //bts:=IntToHex(buffer[j+i*8*rowsof8],2);
1153          getBTSString(false);
1154          mbcanvas.Canvas.TextOut(start+20*j,i*textHeight+2,bts);
1155          mbimage.Canvas.TextOut(start+20*j,i*textHeight+2,bts);
1156
1157          if buffer[j+(i*8*rowsof8)]<$20 then
1158          begin
1159            mbcanvas.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,' ');
1160            mbimage.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,' ');
1161          end else
1162          begin
1163            mbcanvas.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,chr(buffer[j+(i*8*rowsof8)]));
1164            mbimage.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,chr(buffer[j+(i*8*rowsof8)]));
1165          end;
1166        end
1167        else
1168        begin
1169          //unreadable
1170          if (selecting or selectionmade) and (selstart<>selstop) and ((((memoryaddress+i*8*rowsof8)+j)>=selstart) and (((memoryaddress+i*8*rowsof8)+j)<=selstop)) then
1171          begin
1172            mbcanvas.Canvas.font.Color:=clred;
1173            mbimage.Canvas.font.Color:=clred;
1174          end
1175          else
1176          begin
1177            mbcanvas.Canvas.font.Color:=clwindowtext;
1178            mbimage.Canvas.font.Color:=clwindowtext;
1179          end;
1180
1181          GetBTSstring(true);
1182          mbcanvas.Canvas.TextOut(start+20*j,i*textHeight+2,bts);
1183          mbimage.Canvas.TextOut(start+20*j,i*textHeight+2,bts);
1184
1185          mbcanvas.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,'?');
1186          mbimage.Canvas.TextOut(start+20+20*((8*rowsof8)-1)+j*chrlength,i*textHeight+2,'?');
1187        end;
1188      end;
1189      inc(a);
1190      inc(j);
1191    end;
1192
1193
1194
1195  end;
1196
1197
1198  {$ifdef net}
1199  //no virtualquery, so no protectlabel
1200  protectlabel.Caption:='';
1201  {$else}
1202  //set the protectionlabel
1203  zeromemory(@mbi,sizeof(mbi));
1204  Virtualqueryex(processhandle,pointer(memoryaddress),mbi,sizeof(mbi));
1205  teststr:='AllocationProtect=';
1206
1207  if (mbi.AllocationProtect and PAGE_NOACCESS)>0 then teststr:=teststr+'No Access ';
1208  if (mbi.AllocationProtect and PAGE_READONLY)>0 then teststr:=teststr+'Read Only ';
1209  if (mbi.AllocationProtect and PAGE_READWRITE)>0 then teststr:=teststr+'Read/Write ';
1210  if (mbi.AllocationProtect and PAGE_WRITECOPY)>0 then teststr:=teststr+'Write Copy ';
1211  if (mbi.AllocationProtect and PAGE_EXECUTE)>0 then teststr:=teststr+'Execute ';
1212  if (mbi.AllocationProtect and PAGE_EXECUTE_READ)>0 then teststr:=teststr+'Execute/Read only ';
1213  if (mbi.AllocationProtect and PAGE_EXECUTE_READWRITE)>0 then teststr:=teststr+'Execute/Read/Write ';
1214  if (mbi.AllocationProtect and PAGE_EXECUTE_WRITECOPY)>0 then teststr:=teststr+'Execute/Write Copy ';
1215  if (mbi.AllocationProtect and PAGE_GUARD)>0 then teststr:=teststr+'Guarded ';
1216  if (mbi.AllocationProtect and PAGE_NOCACHE)>0 then teststr:=teststr+'Not Cached';
1217
1218  if (formsettings<>nil) and formsettings.cbKernelOpenProcess.checked and assigned(GetPhysicalAddress) and GetPhysicalAddress(processhandle,pointer(memoryaddress),a) then
1219    s:=teststr+' AllocationBase='+IntToHex(dword(mbi.AllocationBase),8)+' RegionSize='+IntTohex(mbi.RegionSize,1)+' Physical Address='+IntToHex(a,8)
1220  else
1221    s:=teststr+' AllocationBase='+IntToHex(dword(mbi.AllocationBase),8)+' RegionSize='+IntTohex(mbi.RegionSize,1);
1222
1223
1224  if module1ok then
1225    s:=s+' Module='+range1module.modulename;
1226
1227  protectlabel.caption:=s;
1228
1229  protectlabel.repaint;
1230  {$endif}
1231end;
1232
1233procedure TMemoryBrowser.MBCanvasMouseUp(Sender: TObject;
1234  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
1235var a: integer;
1236    i,j: integer;
1237    acr: dword;
1238    bt:byte;
1239
1240    temp:string;
1241begin
1242  if button=mbright then exit;
1243   
1244  selecting:=false;
1245
1246  if selected2<>selected then selectionmade:=true;
1247 
1248
1249  fcontrol2.SetFocus;
1250  hexedit.Visible:=false;
1251  textedit.Visible:=false;
1252
1253
1254
1255//find out if the user clicked on a byte, and if so which one
1256  a:=20+mbimage.Canvas.TextWidth('00400000');
1257  part:=0; //address
1258
1259  if x>a then
1260  begin  //didnt click on the address
1261    part:=2; //textfield ad the left side
1262    if x<(a+20*8*rows8) then //byteclick
1263    begin
1264      part:=1; //a byte
1265      srow:=y div textheight;
1266      scolumn:=(x-a) div 20;
1267
1268      i:=(srow*8*rows8)+scolumn;
1269      //caption:=Inttohex(memoryaddress+i,8);
1270      selected2:=memoryaddress+i;
1271
1272      if selected<>selected2 then exit;
1273
1274      //if ssLeft in shift then
1275      with HexEdit do
1276      begin
1277        if visible then
1278        begin
1279          if length(hexedit.text)=2 then
1280          begin
1281            bt:=strtoint('$'+hexedit.text);
1282            writeprocessmemory(processhandle,pointer(selected2),@bt,1,acr);
1283          end;
1284        end;
1285
1286        top:=(srow+1)*(textheight)+5;
1287        left:=1+a+20*(scolumn);
1288
1289        acr:=0;
1290        readprocessmemory(processhandle,pointer(selected2),@bt,1,acr);
1291
1292        if acr=1 then
1293        begin
1294          text:=IntToHex(bt,2);
1295          visible:=true;
1296          SelectAll;
1297          SetFocus;
1298        end else visible:=false;
1299      end;
1300    end
1301    else
1302    begin
1303      //not on a byte click
1304      for i:=1 to 8*rows8 do
1305        temp:=temp+'D';
1306
1307      srow:=((y-7) div textheight);
1308
1309
1310      i:=(x-(1+a+20*8*rows8));
1311
1312      scolumn:=i div mbcanvas.Canvas.TextWidth('D');
1313
1314      if scolumn<8*rows8 then
1315      begin
1316        i:=scolumn*mbcanvas.Canvas.TextWidth('D');
1317        selected2:=scolumn+memoryaddress+(8*rows8)*srow;
1318
1319        if selected<>selected2 then exit;
1320       
1321
1322        //if ssLeft in shift then
1323        with textedit do
1324        begin
1325          if visible then
1326          begin
1327            if length(textedit.Text)>0 then
1328            begin
1329              bt:=byte(textedit.Text[1]);
1330              if (editing2) and (bt>32) then
1331                writeprocessmemory(processhandle,pointer(selected2),@bt,1,acr);
1332            end;
1333          end;
1334
1335          textedit.top:=(srow+1)*(textheight)+3;
1336          textedit.Left:=1+a+20*8*rows8+i;   //  (1+(20+mbimage.Canvas.TextWidth('00400000'))+20*8*rows8+(scolumn*mbcanvas.Canvas.TextWidth('D'))  )
1337
1338          acr:=0;
1339          readprocessmemory(processhandle,pointer(selected2),@bt,1,acr);
1340
1341          if acr=1 then
1342          begin
1343            if bt>32 then text:=chr(bt) else text:='';
1344            visible:=true;
1345            editing2:=false;
1346            SelectAll;
1347            SetFocus;
1348          end else visible:=false;
1349        end;
1350      end;
1351    end;
1352  end;
1353
1354end;
1355
1356procedure TMemoryBrowser.MBCanvasMouseMove(Sender: TObject;
1357  Shift: TShiftState; X, Y: Integer);
1358var a,part,srow,scolumns,i: integer;
1359    temp: string;
1360begin
1361  a:=20+mbimage.Canvas.TextWidth('00400000');
1362
1363  if x>a then
1364  begin
1365    if x<(a+20*8*rows8) then //bytepoint
1366    begin
1367      mbcanvas.Cursor:=crHandpoint;
1368
1369      if selecting then
1370      begin
1371        part:=0; //address
1372        if x>a then
1373        begin  //didnt klick on the address
1374          part:=2; //textfield at the left side
1375          if x<(a+20*8*rows8) then //byteclick
1376          begin
1377            part:=1; //a byte
1378            srow:=((y-7) div textheight);
1379            scolumn:=(x-a) div 20;
1380
1381            i:=(srow*8*rows8)+scolumn;
1382
1383            if selected2<>memoryaddress+i then
1384            begin
1385              selected2:=memoryaddress+i;
1386
1387              //and repaint the selected region
1388              refreshmb;
1389            end;
1390          end;
1391        end;
1392      end;
1393    end else
1394    begin
1395      mbcanvas.Cursor:=crDefault;
1396      if selecting then
1397      begin
1398        //textclick?
1399        for i:=1 to 8*rows8 do
1400          temp:=temp+'D';
1401
1402        srow:=((y-7) div textheight);
1403
1404
1405        i:=(x-(1+a+20*8*rows8));
1406
1407        scolumn:=i div mbcanvas.Canvas.TextWidth('D');
1408
1409        if scolumn<8*rows8 then
1410        begin
1411          i:=scolumn*mbcanvas.Canvas.TextWidth('D');
1412          i:=scolumn+memoryaddress+(8*rows8)*srow;
1413          if selected2<>i then
1414          begin
1415            selected2:=i;
1416
1417            refreshmb;
1418          end;
1419        end;
1420      end;
1421
1422
1423    end;
1424
1425  end else mbcanvas.Cursor:=crdefault;
1426end;
1427
1428procedure TMemoryBrowser.MBCanvasDblClick(Sender: TObject);
1429begin
1430  if mbcanvas.Cursor=crHandpoint then
1431  begin
1432    if part=1 then
1433    begin
1434     //edit
1435      with Tvaluechangeform.Create(application) do
1436      begin
1437        address:=selected;
1438        ShowModal;
1439        refreshmb;
1440      end;
1441    end;
1442  end;
1443end;
1444
1445procedure TMemoryBrowser.memorypopupPopup(Sender: TObject);
1446begin
1447  goto1.Visible:=true;
1448  change1.Visible:=(mbcanvas.Cursor=crHandpoint);
1449
1450//  if part=0 then ...
1451end;
1452
1453procedure TMemoryBrowser.Replacewithnops1Click(Sender: TObject);
1454var codelength: integer;
1455    written: dword;
1456    bla:string;
1457    i: integer;
1458    nops: array of byte;
1459    a: dword;
1460    original: dword;
1461
1462    mbi : _MEMORY_BASIC_INFORMATION;
1463  //set the protectionlabel
1464begin
1465  //search dselected in the addresslist
1466
1467
1468  a:=disassemblerview.SelectedAddress;
1469
1470  disassemble(a,bla);
1471  codelength:=a-disassemblerview.SelectedAddress;
1472
1473  if advancedoptions.AddToCodeList(disassemblerview.SelectedAddress,codelength,true) then
1474  begin
1475    setlength(nops,codelength);
1476    for i:=0 to codelength-1 do
1477      nops[i]:=$90;  //$90=nop
1478
1479    zeromemory(@mbi,sizeof(mbi));
1480    Virtualqueryex(processhandle,pointer(disassemblerview.SelectedAddress),mbi,sizeof(mbi));
1481
1482   // get old security and set new security   (not needed in win9x but nt doesnt even allow writeprocessmemory to do this
1483    original:=0;
1484
1485    RewriteCode(processhandle,disassemblerview.SelectedAddress,@nops[0],codelength);
1486    refreshMB;
1487    disassemblerview.Update;;
1488  end;
1489end;
1490
1491procedure TMemoryBrowser.FControl2KeyDown(Sender: TObject; var Key: Word;
1492  Shift: TShiftState);
1493var i: short;
1494begin
1495  case key of
1496    vk_up       : begin
1497                    dec(memoryaddress,8*rows8);
1498                    refreshmb;
1499                  end;
1500
1501    vk_down     : begin
1502                    inc(memoryaddress,8*rows8);
1503                    refreshmb;
1504                  end;
1505
1506    vk_left     : begin
1507                    dec(memoryaddress);
1508                    refreshmb;
1509                  end;
1510    vk_right    : begin
1511                    inc(memoryaddress);
1512                    refreshmb;
1513                  end;
1514    vk_prior    : begin
1515                    dec(memoryaddress,8*rows8*((mbcanvas.Height) div (TextHeight)-1));
1516                    refreshMB;
1517                  end;
1518
1519    vk_next     : begin
1520                    inc(memoryaddress,8*rows8*((mbcanvas.Height) div (TextHeight)-1));
1521                    refreshMB;
1522                  end;
1523
1524    vk_space:
1525    begin
1526      if shift = [ssCtrl] then
1527        disassemblerview.SelectedAddress:=memoryaddress;
1528    end;
1529
1530    {$ifndef net}
1531    ord('F')    : begin
1532                    i:=getkeystate(vk_control);
1533                    if i<=-127 then search1.OnClick(self);
1534                  end;
1535    {$endif}
1536
1537    ord('1')    : if [ssCtrl] = shift then dispBytes.Click;
1538    ord('2')    : if [ssCtrl] = shift then dispWords.Click;
1539    ord('3')    : if [ssCtrl] = shift then dispDwords.Click;
1540    ord('4')    : if [ssCtrl] = shift then dispints.Click;
1541    ord('5')    : if [ssCtrl] = shift then dispFloat.Click;
1542    ord('6')    : if [ssCtrl] = shift then dispDouble.Click;
1543
1544    ord('G')    : begin
1545                    if ssCtrl in shift then goto1.click;
1546                  end;
1547
1548    ord('C')    : begin
1549                    if getkeystate(vk_control)<=-127 then
1550                      Cut1.OnClick(self);
1551                  end;
1552
1553    ord('V')    : begin
1554                    if getkeystate(vk_control)<=-127 then
1555                      Pastefromclipboard1.OnClick(self);
1556                  end;
1557
1558
1559    {$ifndef net}
1560    vk_f3       : begin
1561                    if findwindow<>nil then //easy way to find out if there was a scan before
1562                    begin
1563                      findwindow.editStart.Text:=inttohex(memoryaddress+1,8);
1564                      findwindow.firstscan:=false;
1565                    end;
1566                    findwindow.showmodal;
1567                  end;
1568    {$endif}
1569  end;
1570
1571  key:=0;
1572end;
1573
1574procedure TMemoryBrowser.FControl2KeyPress(Sender: TObject; var Key: Char);
1575begin
1576  key:=chr(0);
1577end;
1578
1579procedure TMemoryBrowser.FControl2Enter(Sender: TObject);
1580begin
1581//  panel4.bevelinner:=bvLowered;
1582//  mbcanvas.Canvas.DrawFocusRect(rect(0,0,100,100));
1583
1584end;
1585
1586procedure TMemoryBrowser.FControl2Exit(Sender: TObject);
1587begin
1588  panel4.BevelInner:=bvNone;
1589//  RefreshMB;
1590end;
1591
1592procedure TMemoryBrowser.FControl1Exit(Sender: TObject);
1593begin
1594
1595end;
1596
1597//key control for the disassembler
1598procedure TMemoryBrowser.FControl1KeyDown(Sender: TObject; var Key: Word;
1599  Shift: TShiftState);
1600var rct: trect;
1601    ignore: string;
1602    i: integer;
1603
1604    a,b: dword;
1605begin
1606  //if shift is not pressed and it's a up,down,left or right, then disable multiline section
1607  case key of
1608    vk_delete:
1609      Replacewithnops1.Click;
1610
1611
1612    vk_return:
1613    begin
1614      //assembler input
1615      assemble1.Click;
1616    end;
1617
1618    vk_space:
1619    begin
1620      if shift=[] then
1621        follow1.Click
1622      else
1623      if shift = [ssShift] then
1624        back1.click
1625      else
1626      if shift = [ssCtrl] then
1627      begin
1628        memoryaddress:=disassemblerview.SelectedAddress;
1629        RefreshMB;
1630      end;
1631    end;
1632
1633    VK_BACK:
1634    begin
1635      back1.click; //backspace and shift+space
1636    end;
1637
1638    ORD('A')..ORD('Z') , ORD('0')..ORD('9'):
1639    begin
1640      if key=ORD('C') then
1641      begin
1642        if shift = [ssCtrl] then //ctrl C
1643        begin
1644          //open the copy window asking what exactly to copy
1645          with tfrmSavedisassembly.create(self) do
1646          begin
1647            a:=min(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2);
1648            b:=max(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2);
1649
1650           
1651            disassemble(b); //b gets increased with size of selected instruction
1652            edit1.Text:=inttohex(a,8);
1653            edit2.Text:=inttohex(b,8);
1654            copymode:=true;
1655            showmodal;
1656            free;
1657            exit;
1658          end;
1659
1660        end;
1661      end;
1662
1663      if key=ORD('G') then
1664      begin
1665        if ssCtrl in shift then
1666        begin
1667          gotoaddress1.Click;
1668          disassemblerview.Update;
1669          exit;
1670        end;
1671      end;
1672
1673      if (ssalt in shift) or (ssctrl in shift) then exit;
1674
1675      assemblepopup(lowercase(chr(key)));
1676    end;
1677  end;
1678
1679  disassemblerview.Update;
1680
1681  key:=0;
1682end;
1683
1684procedure TMemoryBrowser.FControl1KeyPress(Sender: TObject; var Key: Char);
1685begin
1686  key:=chr(0);
1687end;
1688
1689procedure TMemoryBrowser.Gotoaddress1Click(Sender: TObject);
1690var newaddress: string;
1691    symbol :PImagehlpSymbol;
1692    oldoptions: dword;
1693    canceled: boolean;
1694begin
1695  newaddress:=InputBoxTop('Goto Address','Fill in the address you want to go to',IntTohex(disassemblerview.SelectedAddress,8),true,canceled,memorybrowserHistory);
1696
1697  try
1698    disassemblerview.SelectedAddress:=symhandler.getaddressfromname(newaddress);
1699  except
1700    disassemblerview.SelectedAddress:=getaddress(newaddress);
1701  end;
1702end;
1703
1704procedure TMemoryBrowser.Search1Click(Sender: TObject);
1705begin
1706  {$ifndef net}
1707  if findwindow=nil then findwindow:=TFindwindow.create(application);
1708  findwindow.firstscan:=true;
1709  findwindow.ShowModal;
1710  {$endif}
1711end;
1712
1713procedure TMemoryBrowser.Change1Click(Sender: TObject);
1714begin
1715  hexedit.Visible:=false;
1716  MBCanvasDblClick(MBCanvas);
1717end;
1718
1719procedure TMemoryBrowser.Addthisaddresstothelist1Click(Sender: TObject);
1720var i: integer;
1721    ad: dword;
1722begin
1723//this will add the selected recdord to the list
1724  if mbcanvas.Cursor=crHandpoint then
1725  begin
1726    //selected
1727    ad:=selected;
1728    if addform=nil then addform:=Taddform.create(self);
1729    addform.NewAddress.text:=inttohex(ad,8);
1730    addform.showmodal;
1731    //no free because it can be usefull the next time regarding the bits field
1732  end;
1733end;
1734
1735procedure TMemoryBrowser.Addthisopcodetothecodelist1Click(Sender: TObject);
1736var {start,stop: string;
1737    a,b: dword;
1738    i: integer;}
1739    desc: string;
1740begin
1741  frmAddToCodeList:=TfrmAddToCodeList.create(self);
1742  frmAddToCodeList.addtocodelist:=true;
1743  frmAddToCodeList.fromaddress:=disassemblerview.SelectedAddress;
1744  frmAddToCodeList.toaddress:=disassemblerview.SelectedAddress;
1745  disassemble(frmAddToCodeList.toaddress,desc);
1746  dec(frmAddToCodeList.toaddress);
1747  frmAddToCodeList.showmodal;
1748end;
1749
1750procedure TMemoryBrowser.Splitter1CanResize(Sender: TObject;
1751  var NewSize: Integer; var Accept: Boolean);
1752begin
1753  if newsize<80 then
1754  begin
1755    newsize:=80;
1756    accept:=false;
1757  end;
1758
1759  if newsize>memorybrowser.Height-80 then
1760  begin
1761    newsize:=memorybrowser.Height-80;
1762    accept:=false;
1763  end;
1764
1765end;
1766
1767procedure TMemoryBrowser.ScrollBar2Scroll(Sender: TObject;
1768  ScrollCode: TScrollCode; var ScrollPos: Integer);
1769var delta: integer;
1770begin
1771  fcontrol2.SetFocus;
1772  case scrollcode of
1773    scLineUp:   dec(memoryaddress,8*rows8);
1774    scLineDown: inc(memoryaddress,8*rows8);
1775    scPageDown: inc(memoryaddress,8*rows8*((mbcanvas.Height) div (TextHeight)-1));
1776    scPageUp:   dec(memoryaddress,8*rows8*((mbcanvas.Height) div (TextHeight)-1));
1777    sctrack:
1778    begin
1779      delta:=scrollpos-50;
1780      memoryaddress:=memoryaddress+(8*rows8)*delta;
1781     // if not formsettings.cbKernelReadWriteProcessMemory.checked then memoryaddress:=trunc(scrollpos/10000*$FFFFFFFF);
1782    end;
1783  end;
1784
1785  refreshmb;
1786  scrollpos:=50;
1787end;
1788
1789procedure TMemoryBrowser.FormClose(Sender: TObject;
1790  var Action: TCloseAction);
1791begin
1792  {$ifndef net}
1793  if (debuggerthread<>nil) and (debuggerthread.userisdebugging) then
1794  begin
1795    WaitForSingleObject(semaphore,infinite);
1796    debuggerthread.removebreakpoint;
1797    releasesemaphore(semaphore,1,nil);
1798
1799    debuggerthread.DRRegs.Dr0:=0;
1800    debuggerthread.DRRegs.Dr1:=0;
1801    debuggerthread.DRRegs.Dr2:=0;
1802    debuggerthread.DRRegs.Dr3:=0;
1803
1804    debuggerthread.continuehow:=wdco_run;
1805
1806    setlength(debuggerthread.userbreakpoints,0);
1807    setlength(debuggerthread.int3userbreakpoints,0);
1808    debuggerthread.int3CEBreakpoint.address:=0;
1809
1810    debuggerthread.continueprocess:=true;
1811    debuggerthread.userisdebugging:=false;
1812  end;
1813  {$endif}
1814
1815
1816  if ischild then
1817  begin
1818    //do stuff particulary for the children
1819    action:=cafree;
1820  end
1821  else
1822  begin
1823    //do stuff for the main debugger
1824    if frmFloatingPointPanel<>nil then
1825      frmFloatingPointPanel.Visible:=false;
1826
1827  end;
1828
1829end;
1830
1831procedure TMemoryBrowser.Run1Click(Sender: TObject);
1832begin
1833  {$ifndef net}
1834  if kdebugger.isactive then
1835  begin
1836    kdebugger.continue(co_run);
1837  end
1838  else
1839  if debuggerthread<>nil then
1840  begin
1841    debuggerthread.continuehow:=wdco_run;   //note: I could also have the debuggerthread suspend itself, and resume it here
1842    debuggerthread.continueprocess:=true;
1843    caption:='Memory Viewer - Running';
1844  end;
1845  {$endif}
1846end;
1847
1848procedure TMemoryBrowser.Step1Click(Sender: TObject);
1849begin
1850  {$ifndef net}
1851  if kdebugger.isactive then
1852  begin
1853    kdebugger.continue(co_stepinto);
1854  end
1855  else
1856  if debuggerthread<>nil then
1857  begin
1858    debuggerthread.continuehow:=wdco_stepinto; //single step
1859    debuggerthread.continueprocess:=true;
1860    caption:='Memory Viewer - Running';
1861  end;
1862
1863  {$endif}
1864end;
1865
1866procedure TMemoryBrowser.StepOver1Click(Sender: TObject);
1867var x: dword;
1868    i,j: integer;
1869    s,s1,s2,temp:string;
1870    int3: byte;
1871    original,a,written:dword;
1872
1873begin
1874  {$ifndef net}
1875  int3:=$cc;
1876  //place a invisble for the user breakpoint on the following upcode
1877
1878  x:=lastdebugcontext.Eip;
1879  s:=disassemble(x,temp);
1880  i:=posex('-',s);
1881  i:=posex('-',s,i+1);
1882  s:=copy(s,i+2,length(s));
1883
1884  i:=pos(' ',s);
1885  s1:=copy(s,1,i-1);
1886  s2:=copy(s,i+1,length(s));
1887
1888  if not ((s1='call') or (s1='loop')) then //not a call or loop
1889  begin
1890    Step1.Click;
1891    exit;
1892  end;
1893
1894  if kdebugger.isactive then
1895  begin
1896    kdebugger.continue(co_stepover);
1897  end
1898  else
1899  if debuggerthread<>nil then
1900  begin
1901    debuggerthread.continuehow:=wdco_stepOver; //step over
1902
1903
1904
1905    if formsettings.rbDebugAsBreakpoint.checked then
1906    begin
1907      debuggerthread.DRRegs.Dr3:=x;
1908
1909      with debuggerthread do
1910      for i:=0 to length(threadlist)-1 do
1911      begin
1912        suspendthread(debuggerthread.threadlist[i][1]);
1913        setthreadcontext(debuggerthread.threadlist[i][1],debuggerthread.DRRegs);
1914        resumethread(debuggerthread.threadlist[i][1]);
1915      end;
1916    end else
1917    begin
1918      // use the int3CEBreakpoint
1919      //see if there is already a Breakpoint with this address
1920      if debuggerthread.int3CEBreakpoint.address>0 then
1921        RewriteCode(processhandle,debuggerthread.int3CEBreakpoint.address,@debuggerthread.int3CEBreakpoint.originalbyte,1);
1922
1923      for i:=0 to length(debuggerthread.int3userbreakpoints)-1 do
1924        if debuggerthread.int3userbreakpoints[i].address=x then
1925        begin
1926          //dont need to set a breakpoint
1927          debuggerthread.continueprocess:=true;
1928          caption:='Memory Viewer - Running';
1929          exit;
1930        end;
1931
1932      debuggerthread.int3CEBreakpoint.address:=x;
1933      readprocessmemory(processhandle,pointer(x),@debuggerthread.int3CEBreakpoint.originalbyte,1,written);
1934
1935      Rewritecode(processhandle,x,@int3,1);
1936    end;
1937
1938    debuggerthread.continueprocess:=true;
1939    caption:='Memory Viewer - Running';
1940  end;
1941  {$endif}
1942end;
1943
1944procedure TMemoryBrowser.Runtill1Click(Sender: TObject);
1945var x: dword;
1946    i: integer;
1947    temp:string;
1948    int3: byte;
1949    original,a,written:dword;
1950begin
1951  {$ifndef net}
1952  int3:=$cc;
1953  //place a invisble for the user breakpoint on the following upcode
1954
1955  if kdebugger.isactive then
1956  begin
1957    kdebugger.continue(co_runtill);
1958  end
1959  else
1960  if debuggerthread<>nil then
1961  begin
1962    debuggerthread.continuehow:=wdco_stepOver; //step over
1963    x:=disassemblerview.SelectedAddress;
1964    disassemble(x,temp);
1965
1966    if formsettings.rbDebugAsBreakpoint.checked then
1967    begin
1968      debuggerthread.DRRegs.Dr3:=x;
1969
1970      with debuggerthread do
1971      for i:=0 to length(threadlist)-1 do
1972      begin
1973        suspendthread(debuggerthread.threadlist[i][1]);
1974        setthreadcontext(debuggerthread.threadlist[i][1],debuggerthread.DRRegs);
1975        resumethread(debuggerthread.threadlist[i][1]);
1976      end;
1977    end else
1978    begin
1979      if debuggerthread.int3CEBreakpoint.address>0 then
1980      begin
1981        //restore with original
1982        RewriteCode(processhandle,debuggerthread.int3CEBreakpoint.address,@debuggerthread.int3CEBreakpoint.originalbyte,1);
1983      end;
1984
1985      for i:=0 to length(debuggerthread.int3userbreakpoints)-1 do
1986        if debuggerthread.int3userbreakpoints[i].address=x then
1987        begin
1988          //dont need to set a breakpoint
1989          debuggerthread.continueprocess:=true;
1990          caption:='Memory Viewer - Running';
1991          exit;
1992        end;
1993
1994      debuggerthread.int3CEBreakpoint.address:=x;
1995      readprocessmemory(processhandle,pointer(x),@debuggerthread.int3CEBreakpoint.originalbyte,1,written);
1996
1997      Rewritecode(processhandle,x,@int3,1);
1998    end;
1999
2000    debuggerthread.continueprocess:=true;
2001    caption:='Memory Viewer - Running';
2002  end;
2003
2004  {$endif}
2005end;
2006
2007procedure TMemoryBrowser.Stacktrace1Click(Sender: TObject);
2008begin
2009  {$ifndef net}
2010  frmstacktrace:=tfrmstacktrace.create(self);
2011  frmstacktrace.Show;
2012  {$endif}
2013end;
2014
2015procedure TMemoryBrowser.Threadlist1Click(Sender: TObject);
2016begin
2017  {$ifndef net}
2018  if frmThreadlist<>nil then exit;
2019
2020  if not startdebuggerifneeded then exit;
2021  frmThreadlist:=tfrmthreadlist.create(self);
2022  frmThreadlist.show;
2023  {$endif}
2024
2025end;
2026
2027procedure TMemoryBrowser.AssemblePopup(x:string);
2028var assemblercode,desc: string;
2029    bytes: tassemblerbytes;
2030    a,b,original,written:dword;
2031    originalsize:dword;
2032    replace: boolean;
2033    c: word;
2034
2035    res: word;
2036    i: integer;
2037    canceled: boolean;
2038begin
2039  //make sure it doesnt have a breakpoint
2040  {$ifndef net}
2041  if debuggerthread<>nil then
2042  begin
2043    for i:=0 to length(debuggerthread.int3userbreakpoints)-1 do
2044      if debuggerthread.int3userbreakpoints[i].address=disassemblerview.SelectedAddress then
2045      begin
2046        beep; //Best sound effect cheat engine has
2047        exit;
2048      end;
2049  end;
2050  {$endif}
2051
2052  originalsize:=disassemblerview.SelectedAddress;
2053  assemblercode:=disassemble(originalsize,desc);
2054  dec(originalsize,disassemblerview.SelectedAddress);
2055
2056  if x<>'' then
2057    assemblercode:=x
2058  else
2059  begin
2060    assemblercode:=copy(assemblercode,pos('-',assemblercode)+2,length(assemblercode));
2061    assemblercode:=copy(assemblercode,pos('-',assemblercode)+2,length(assemblercode));
2062  end;
2063
2064
2065
2066//  copy
2067
2068  assemblercode:=InputboxTop('Cheat Engine single-linge assembler','Type your assembler code here: (address='+inttohex(disassemblerview.SelectedAddress,8)+')',assemblercode,x='', canceled, assemblerHistory);
2069  if not canceled then
2070  begin
2071
2072    try
2073      if Assemble(assemblercode,disassemblerview.SelectedAddress,bytes) then
2074      begin
2075        if originalsize<>length(bytes) then
2076        begin
2077          if formsettings.replacewithnops.checked then
2078          begin
2079            if formsettings.askforreplacewithnops.checked then
2080            begin
2081              c:=messagedlg('The generated code is '+IntToStr(length(bytes))+' byte(s) long, but the selected opcode is '+IntToStr(originalsize)+' byte(s) long! Do you want to replace the incomplete opcode(s) with NOP''s?',mtConfirmation,mbYesNoCancel,0);
2082              replace:=c=mryes;
2083              if c=mrCancel then exit;
2084            end else replace:=true;
2085
2086            if replace then
2087            begin
2088              while originalsize>length(bytes) do
2089              begin
2090                setlength(bytes,length(bytes)+1);
2091                bytes[length(bytes)-1]:=$90;
2092              end;
2093
2094              a:=disassemblerview.SelectedAddress+length(bytes);
2095
2096              b:=disassemblerview.SelectedAddress;
2097              while b<a do disassemble(b,desc);
2098
2099              a:=b-disassemblerview.SelectedAddress;
2100              while length(bytes)<a do
2101              begin
2102                setlength(bytes,length(bytes)+1);
2103                bytes[length(bytes)-1]:=$90;
2104              end;
2105            end;
2106
2107
2108          end;
2109        end;
2110
2111        //note to self, check the size of the current opcode and give the option to replace the missing or too many bytes with nops
2112        //and put in a option to disable showing that message, and use a default action
2113
2114        // get old security and set new security   (not needed in win9x but nt doesnt even allow writeprocessmemory to do this
2115        original:=0;
2116
2117        RewriteCode(processhandle,disassemblerview.SelectedAddress,@bytes[0],length(bytes));
2118        refreshMB;
2119        disassemblerview.Update;
2120      end else raise exception.create('I don''t understand what you mean with '+assemblercode);
2121    except
2122      raise exception.create('I don''t understand what you mean with '+assemblercode);
2123    end;
2124
2125  end;
2126
2127end;
2128
2129procedure TMemoryBrowser.Assemble1Click(Sender: TObject);
2130begin
2131  AssemblePopup('');
2132end;
2133
2134procedure TMemoryBrowser.HexEditKeyPress(Sender: TObject; var Key: Char);
2135begin
2136  case key of
2137    chr(8)   : ;
2138    chr(16)  : ;
2139    'A'..'F' : ;
2140    'a'..'f' : key:=uppercase(key)[1];
2141    '0'..'9' : ;
2142    else key:=chr(0);
2143  end;
2144
2145  if editing then key:=#0;
2146  editing:=false;
2147end;
2148
2149procedure TMemoryBrowser.HexEditExit(Sender: TObject);
2150var bt: byte;
2151    aw: dword;
2152begin
2153//change
2154  if not hexedit.Visible then exit;
2155
2156  if length(hexedit.Text)<2 then
2157  begin
2158    hexedit.Visible:=false;
2159    beep;
2160    exit;
2161  end;
2162
2163  bt:=strtoint('$'+hexedit.text);
2164
2165  writeprocessmemory(processhandle,pointer(selected),@bt,1,aw);
2166  refreshmb;
2167
2168  hexedit.Visible:=false;
2169end;
2170
2171procedure TMemoryBrowser.HexEditKeyDown(Sender: TObject; var Key: Word;
2172  Shift: TShiftState);
2173var  a: integer;
2174     bt: byte;
2175     acr: dword;
2176procedure handleright;
2177begin
2178  if (length(hexedit.text)<2) and (key in [vk_right and vk_space] ) then
2179  begin
2180    if key=vk_right then exit;
2181    beep;
2182    key:=0;
2183    exit;
2184  end;
2185
2186  if key=vk_right then
2187    if (hexedit.SelStart<>2) and (hexedit.SelLength<>2) then exit;
2188
2189  bt:=strtoint('$'+hexedit.text);
2190  writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2191  refreshmb;
2192
2193  inc(scolumn);
2194  scolumn:=scolumn mod (8*rows8);
2195  if (scolumn)=0 then
2196  begin
2197    //move down
2198    inc(srow);
2199
2200    if (((srow+1)*(textheight)+3)+hexedit.Height)>panel4.Height then
2201    begin
2202      dec(srow);
2203      hexedit.top:=(srow+1)*(textheight)+3;
2204      inc(memoryaddress,8*rows8);
2205      refreshmb;
2206    end else hexedit.Top:=(srow+1)*(textheight)+3;
2207  end;
2208
2209  hexedit.left:=1+a+20*(scolumn);
2210  inc(selected);
2211
2212  acr:=0;
2213  readprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2214
2215  if acr=1 then
2216  begin
2217    hexedit.text:=IntToHex(bt,2);
2218    hexedit.visible:=true;
2219    hexedit.SelectAll;
2220    hexedit.SetFocus;
2221  end else hexedit.visible:=false;
2222  key:=0;
2223  editing:=false;
2224end;
2225begin
2226  selecting:=false;
2227  selectionmade:=false;
2228  selected2:=selected;
2229 
2230  a:=20+mbimage.Canvas.TextWidth('00400000');
2231  case key of
2232    ord('C')    : begin
2233                    if (getkeystate(vk_control) shr 15) and 1 = 1 then
2234                    begin
2235                      editing:=false;
2236                      key:=0;
2237                      hexedit.Visible:=false;
2238                      fcontrol2.SetFocus;
2239                      Cut1.OnClick(self);
2240                    end
2241                    else
2242                    begin
2243                      if (length(hexedit.text)=1) and (hexedit.SelLength=0) then
2244                      begin
2245                        hexedit.text:=hexedit.Text+char(key);
2246                        handleright;
2247                        editing:=true;
2248                      end;
2249                    end;
2250                  end;
2251
2252    ord('V')    : begin
2253                    if (getkeystate(vk_control) shr 15) and 1= 1 then
2254                    begin
2255                      editing:=false;
2256                      key:=0;
2257                      hexedit.Visible:=false;
2258                      fcontrol2.SetFocus;
2259                      Pastefromclipboard1.OnClick(self);
2260                    end;
2261                  end;
2262                 
2263
2264    vk_add:   begin
2265                 acr:=0;
2266                 if readprocessmemory(processhandle,pointer(selected),@bt,1,acr) then
2267                 begin
2268                   inc(bt);
2269                   if writeprocessmemory(processhandle,pointeR(selected),@bt,1,acr) then
2270                   begin
2271                     hexedit.Text:=IntToHex(bt,2);
2272                     hexedit.SelectAll;
2273                   end;
2274                 end;
2275                 editing:=true;
2276                 key:=0;
2277                 disassemblerview.Update;
2278               end;
2279
2280    vk_subtract:begin
2281                 acr:=0;
2282                 if readprocessmemory(processhandle,pointer(selected),@bt,1,acr) then
2283                 begin
2284                   dec(bt);
2285                   if writeprocessmemory(processhandle,pointeR(selected),@bt,1,acr) then
2286                   begin
2287                     hexedit.Text:=IntToHex(bt,2);
2288                     hexedit.SelectAll;
2289                   end;
2290                 end;
2291                 editing:=true;
2292                 key:=0;
2293                 disassemblerview.Update;
2294               end;
2295
2296    vk_escape: begin
2297                 hexedit.Visible:=false;
2298                 fcontrol2.SetFocus;
2299               end;
2300
2301    vk_return: begin
2302                 if length(hexedit.Text)<2 then
2303                 begin
2304                   beep;
2305                   key:=0;
2306                   exit;
2307                 end;
2308
2309                 hexedit.Visible:=false;
2310                 bt:=strtoint('$'+hexedit.text);
2311                 writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2312                 refreshmb;
2313                 key:=0;
2314               end;
2315
2316    vk_up:     begin
2317                 if length(hexedit.text)<2 then
2318                 begin
2319                   beep;
2320                   exit;
2321                 end;
2322
2323                 dec(srow);
2324                 if srow<0 then
2325                 begin
2326                   srow:=0;
2327                   hexedit.Top:=(srow+1)*(textheight)+3;
2328
2329                   dec(memoryaddress,8*rows8);
2330                   refreshmb;
2331                 end else hexedit.Top:=(srow+1)*(textheight)+3;
2332
2333                 bt:=strtoint('$'+hexedit.text);
2334                 writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2335                 refreshmb;
2336
2337
2338                 dec(selected,8*rows8);
2339
2340                 acr:=0;
2341                 readprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2342
2343                 if acr=1 then
2344                 begin
2345                   hexedit.text:=IntToHex(bt,2);
2346                   hexedit.visible:=true;
2347                   hexedit.SelectAll;
2348                   hexedit.SetFocus;
2349                 end else hexedit.visible:=false;
2350                 key:=0;
2351
2352               end;
2353
2354    vk_down:   begin
2355                 if length(hexedit.text)<2 then
2356                 begin
2357                   beep;
2358                   exit;
2359                 end;
2360
2361                 inc(srow);
2362                 if (((srow+1)*(textheight)+3)+hexedit.Height)>panel4.Height then
2363                 begin
2364                   dec(srow);
2365                   hexedit.top:=(srow+1)*(textheight)+3;
2366                   inc(memoryaddress,8*rows8);
2367                   refreshmb;
2368                 end else hexedit.Top:=(srow+1)*(textheight)+3;
2369
2370                 bt:=strtoint('$'+hexedit.text);
2371                 writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2372                 refreshmb;
2373
2374
2375                 inc(selected,8*rows8);
2376
2377                 acr:=0;
2378                 readprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2379
2380                 if acr=1 then
2381                 begin
2382                   hexedit.text:=IntToHex(bt,2);
2383                   hexedit.visible:=true;
2384                   hexedit.SelectAll;
2385                   hexedit.SetFocus;
2386                 end else hexedit.visible:=false;
2387                 key:=0;
2388
2389               end;
2390
2391
2392    vk_left:   begin
2393                 if length(hexedit.Text)<2 then
2394                 begin
2395                   if (hexedit.selstart=0) then beep;
2396                   exit;
2397                 end;
2398
2399                 if hexedit.SelStart>0 then exit;
2400
2401                 bt:=strtoint('$'+hexedit.text);
2402                 writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2403                 refreshmb;
2404
2405                 dec(scolumn);
2406                 if scolumn=-1 then scolumn:=8*rows8-1;
2407                 if scolumn=8*rows8-1 then
2408                 begin
2409                   //move up
2410                   dec(srow);
2411                   if srow<0 then
2412                   begin
2413                     srow:=0;
2414                     hexedit.Top:=(srow+1)*(textheight)+3;
2415
2416                     dec(memoryaddress,8*rows8);
2417                     refreshmb;
2418                   end else hexedit.Top:=(srow+1)*(textheight)+3;
2419
2420                 end;
2421
2422                 hexedit.left:=1+a+20*(scolumn);
2423                 dec(selected);
2424
2425                 acr:=0;
2426                 readprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2427
2428                 if acr=1 then
2429                 begin
2430                   hexedit.text:=IntToHex(bt,2);
2431                   hexedit.visible:=true;
2432                   hexedit.SelectAll;
2433                   hexedit.SetFocus;
2434                 end else hexedit.visible:=false;
2435                 key:=0;
2436               end;
2437
2438
2439    vk_space,vk_right:
2440    begin
2441      handleright;
2442    end;
2443
2444    else
2445    begin
2446      if key in [ord('0')..ord('9'),ord('A')..ord('F'),96..105] then
2447      begin
2448        if key in [96..105] then ///numpad fix
2449          key:=key-96+ord('0');
2450         
2451        if (length(hexedit.text)=1) and (hexedit.SelLength=0) then
2452        begin
2453          hexedit.text:=hexedit.Text+char(key);
2454          handleright;
2455          editing:=true;
2456
2457        end;
2458      end
2459      else
2460      key:=0;
2461    end;
2462  end;
2463end;
2464
2465procedure TMemoryBrowser.EAXLabelDblClick(Sender: TObject);
2466var x: dword;
2467    i: integer;
2468    regname,input: string;
2469    value: dword;
2470
2471begin
2472  //edit the selected register
2473  {$ifndef net}
2474  if (debuggerthread<>nil) and (not debuggerthread.running) then
2475  begin
2476    with debuggerthread do
2477    begin
2478      i:=tlabel(sender).Tag;
2479      case i of
2480      0: regname:='EAX';
2481      1: regname:='EBX';
2482      2: regname:='ECX';
2483      3: regname:='EDX';
2484      4: regname:='ESI';
2485      5: regname:='EDI';
2486      6: regname:='EBP';
2487      7: regname:='ESP';
2488      8: regname:='EIP';
2489      9: regname:='CS';
2490      10: regname:='SS';
2491      11: regname:='DS';
2492      12: regname:='ES';
2493      13: regname:='FS';
2494      14: regname:='GS';
2495      20: regname:='CF';
2496      21: regname:='PF';
2497      22: regname:='AF';
2498      23: regname:='ZF';
2499      24: regname:='SF';
2500      25: regname:='DF';
2501      end;
2502
2503      input:=copy(tlabel(sender).Caption,pos(' ',tlabel(sender).Caption)+1,8);
2504      if i<20 then
2505      begin
2506        if not inputquery('Change register','What is the new value of '+regname+'?',input) then exit;
2507      end
2508      else
2509      begin
2510        if not inputquery('Change register','What is the new value of '+regname+'? (0 or 1)',input) then exit;
2511        input:=trim(input);
2512        if (input<>'0') and (input<>'1') then
2513          raise exception.create(input+' is not a valid value');
2514
2515      end;
2516
2517      value:=StrToInt('$'+input);
2518
2519
2520      context.ContextFlags:=CONTEXT_FULL; //
2521      getthreadcontext(pausedthreadhandle,context);
2522      case tlabel(sendeR).Tag of
2523        0: context.Eax:=value;    //eax
2524        1: context.Ebx:=value;    //ebx
2525        2: context.Ecx:=value;    //ecx
2526        3: context.Edx:=value;    //edx
2527        4: context.Esi:=value;    //esi
2528        5: context.Edi:=value;    //edi
2529        6: context.Ebp:=value;    //ebp
2530        7: context.Esp:=value;    //esp
2531        8: context.Eip:=value;    //eip
2532        9: context.segcs:=value;    //cs
2533        10: context.segss:=value;    //ss
2534        11: context.segds:=value;    //ds
2535        12: context.seges:=value;    //es
2536        13: context.segfs:=value;    //fs
2537        14: context.seggs:=value;    //gs
2538
2539        20: setbit(0,context.eflags,value); //0=cf
2540        21: setbit(2,context.eflags,value); //2=pf
2541        22: setbit(4,context.eflags,value); //4=af
2542        23: setbit(6,context.eflags,value); //6=zf
2543        24: setbit(7,context.eflags,value); //7=sf
2544        25: setbit(10,context.eflags,value); //10=df
2545        26: setbit(11,context.eflags,value); //11=of
2546      end;
2547
2548      if setthreadcontext(pausedthreadhandle,context) then
2549      begin
2550        if tlabel(sender).Tag>=9 then
2551          tlabel(sender).Caption:=regname+' '+inttohex(value,4)
2552        else
2553          tlabel(sender).Caption:=regname+' '+inttohex(value,8)
2554      end;
2555    end;
2556
2557  end;
2558  {$endif}
2559end;
2560
2561procedure TMemoryBrowser.Break1Click(Sender: TObject);
2562var threadhandle: thandle;
2563begin
2564  {$ifndef net}
2565  if not startdebuggerifneeded then exit;
2566
2567  threadhandle:=debuggerthread.threadlist[0,1];
2568
2569  if length(debuggerthread.threadlist)>=1 then
2570  begin
2571    //multiple threads!!! Ask user which one
2572    frmbreakthread:=tfrmbreakthread.create(self);
2573    if frmbreakthread.showmodal=mrOK then  threadhandle:=frmbreakthread.threadhandle else
2574    begin
2575      frmbreakthread.free;
2576      frmbreakthread:=nil;
2577      exit;
2578    end;
2579
2580    frmbreakthread.free;
2581    frmbreakthread:=nil;
2582
2583  end;
2584
2585  if not breakthread(threadhandle) then raise exception.Create('Can''t set breakpoint');
2586
2587  {$endif}
2588end;
2589
2590procedure TMemoryBrowser.Reservememory1Click(Sender: TObject);
2591var count: string;
2592    memsize: integer;
2593    baseaddress: pointer;
2594    x: dword;
2595    s: string;
2596begin
2597{$ifndef net}
2598  count:='4096';
2599  if inputquery('Allocate memory','How much memory do you want to add to this process. ',count) then
2600  begin
2601    try
2602      memsize:=StrToInt(count);
2603    except
2604      raise exception.Create('How much is '+count+'?');
2605    end;
2606
2607    baseaddress:=nil;
2608    baseaddress:=VirtualAllocEx(processhandle,nil,memsize,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
2609    if baseaddress<>nil then
2610    begin
2611
2612
2613      if (disassemblerview.SelectedAddress<>0) and (memsize>7) and (messagedlg('At least '+IntToStr(memsize)+' bytes have been allocated at '+IntToHex(dword(baseaddress),8)+#13#10+'Do you want replace the currently selected address with a jump to that address, and copy the overwritten instructions to there?',mtConfirmation,[mbyes,mbno],0)=mryes) then
2614        CreateCodecave(dword(baseaddress),disassemblerview.SelectedAddress,memsize)
2615      else
2616        messagedlg('At least '+IntToStr(memsize)+' bytes have been allocated at '+IntToHex(dword(baseaddress),8),mtinformation,[mbok],0);
2617
2618
2619      if messagedlg('Do you want to go there now?',mtConfirmation,[mbyes,mbno],0) = mryes then
2620        disassemblerview.SelectedAddress:=dword(baseaddress);
2621
2622
2623    end else raise exception.Create('Error allocating memory!');
2624
2625
2626  end;
2627  {$endif}
2628end;
2629
2630procedure TMemoryBrowser.Savememoryregion1Click(Sender: TObject);
2631begin
2632//will save a cheat engine memory region file .CEM
2633//header:
2634//'CHEATENGINE'
2635//4 bytes:Version
2636//4 bytes:beginaddress
2637//4 bytes:size
2638  TFrmSaveMemoryRegion.create(self).showmodal;
2639end;
2640
2641procedure TMemoryBrowser.Loadmemolryregion1Click(Sender: TObject);
2642begin
2643  if openmemory.Execute then
2644  begin
2645    tfrmloadmemory.Create(self).Showmodal(openmemory.filename);
2646  end;
2647end;
2648
2649procedure TMemoryBrowser.HexEditDblClick(Sender: TObject);
2650begin
2651  change1.Click;
2652end;
2653
2654procedure TMemoryBrowser.Debugstrings1Click(Sender: TObject);
2655begin
2656  {$ifndef net}
2657  startdebuggerifneeded;
2658
2659  formdebugstrings.show;
2660  {$endif}
2661end;
2662
2663procedure TMemoryBrowser.TextEditExit(Sender: TObject);
2664var bt: byte;
2665    aw: dword;
2666begin
2667//change
2668  if not textedit.Visible then exit;
2669
2670  if length(hexedit.Text)<2 then
2671  begin
2672    hexedit.Visible:=false;
2673    beep;
2674    exit;
2675  end;
2676
2677  if length(textedit.text)=1 then
2678  begin
2679    bt:=byte(textedit.text[1]);
2680    if bt>32 then
2681      writeprocessmemory(processhandle,pointer(selected),@bt,1,aw);
2682  end;
2683
2684  refreshmb;
2685
2686  textedit.Visible:=false;
2687end;
2688
2689procedure TMemoryBrowser.TextEditKeyDown(Sender: TObject; var Key: Word;
2690  Shift: TShiftState);
2691var bt: byte;
2692    acr: dword;
2693    a: integer;
2694procedure handleright;
2695begin
2696  if (length(textedit.text)=0) then
2697  begin
2698    if key=vk_right then exit;
2699    beep;
2700    key:=0;
2701    exit;
2702  end;
2703
2704  if editing2 then
2705  begin
2706    bt:=byte(textedit.text[1]);
2707    if bt>32 then
2708      writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2709    refreshmb;
2710  end;
2711
2712  inc(scolumn);
2713  scolumn:=scolumn mod (8*rows8);
2714  if (scolumn)=0 then
2715  begin
2716    //move down
2717    inc(srow);
2718
2719    if (((srow+1)*(textheight)+3)+textedit.Height)>panel4.Height then
2720    begin
2721      dec(srow);
2722      textedit.top:=(srow+1)*(textheight)+3;
2723      inc(memoryaddress,8*rows8);
2724      refreshmb;
2725    end else textedit.Top:=(srow+1)*(textheight)+3;
2726  end;
2727
2728  textedit.left:=(1+a+20*8*rows8+(scolumn*mbcanvas.Canvas.TextWidth('D')));
2729  inc(selected);
2730
2731  acr:=0;
2732  readprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2733
2734  if acr=1 then
2735  begin
2736    if bt>32 then textedit.text:=chr(bt) else textedit.text:=' ';
2737    editing2:=false;
2738    textedit.visible:=true;
2739    textedit.SelectAll;
2740    textedit.SetFocus;
2741  end else hexedit.visible:=false;
2742  key:=0;
2743end;
2744begin
2745  a:=20+mbimage.Canvas.TextWidth('00400000');
2746
2747  case key of
2748    ord('C'):
2749    begin
2750      if getkeystate(vk_control)<=-127 then
2751      begin
2752        editing:=false;
2753        key:=0;
2754        hexedit.Visible:=false;
2755        fcontrol2.SetFocus;
2756
2757        Cut1.OnClick(self);
2758      end else editing2:=true;
2759    end;
2760
2761    ord('V'):
2762    begin
2763      if getkeystate(vk_control)<=-127 then
2764      begin
2765        editing:=false;
2766        key:=0;
2767        hexedit.Visible:=false;
2768        fcontrol2.SetFocus;
2769        Pastefromclipboard1.OnClick(self);
2770      end else editing2:=true;
2771    end;
2772
2773    vk_escape:
2774    begin
2775      textedit.Visible:=false;
2776      fcontrol2.SetFocus;
2777    end;
2778
2779    vk_return:
2780    begin
2781      if length(textedit.Text)<1 then
2782      begin
2783        beep;
2784        key:=0;
2785        exit;
2786      end;
2787
2788      textedit.Visible:=false;
2789      bt:=byte(textedit.text[1]);
2790      writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2791      refreshmb;
2792      key:=0;
2793    end;
2794
2795
2796    vk_up:
2797    begin
2798      if length(textedit.text)<1 then
2799      begin
2800        beep;
2801        exit;
2802      end;
2803
2804      dec(srow);
2805      if srow<0 then
2806      begin
2807        srow:=0;
2808        textedit.Top:=(srow+1)*(textheight)+3;
2809        dec(memoryaddress,8*rows8);
2810        refreshmb;
2811      end
2812      else textedit.Top:=(srow+1)*(textheight)+3;
2813
2814      if editing2 then
2815      begin
2816        bt:=byte(textedit.text[1]);
2817        if bt>32 then
2818          writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2819      end;
2820
2821      refreshmb;
2822
2823      dec(selected,8*rows8);
2824
2825      acr:=0;
2826      readprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2827
2828      if acr=1 then
2829      begin
2830        if bt>32 then textedit.text:=chr(bt) else textedit.text:=' ';
2831        editing2:=false;
2832        textedit.visible:=true;
2833        textedit.SelectAll;
2834        textedit.SetFocus;
2835      end else textedit.visible:=false;
2836      key:=0;
2837    end;
2838
2839    vk_down:
2840    begin
2841      if length(textedit.text)=0 then
2842      begin
2843        beep;
2844        exit;
2845      end;
2846
2847      inc(srow);
2848      if (((srow+1)*(textheight)+3)+textedit.Height)>panel4.Height then
2849      begin
2850        dec(srow);
2851        textedit.top:=(srow+1)*(textheight)+3;
2852        inc(memoryaddress,8*rows8);
2853        refreshmb;
2854      end else textedit.Top:=(srow+1)*(textheight)+3;
2855
2856      if editing2 then
2857      begin
2858        bt:=byte(textedit.text[1]);
2859        if bt>32 then
2860          writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2861        refreshmb;
2862      end;
2863
2864      inc(selected,8*rows8);
2865
2866      acr:=0;
2867      readprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2868
2869      if acr=1 then
2870      begin
2871        if bt>32 then textedit.text:=chr(bt) else textedit.Text:=' ';
2872        editing2:=false;
2873        textedit.visible:=true;
2874        textedit.SelectAll;
2875        textedit.SetFocus;
2876      end else textedit.visible:=false;
2877      key:=0;
2878
2879    end;
2880
2881
2882    vk_left:
2883    begin
2884      if length(textedit.Text)<1 then
2885      begin
2886        beep;
2887        exit;
2888      end;
2889
2890      bt:=byte(textedit.text[1]);
2891      if editing2 then
2892      if bt>32 then
2893        writeprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2894
2895      refreshmb;
2896
2897      dec(scolumn);
2898      if scolumn=-1 then scolumn:=8*rows8-1;
2899
2900      if scolumn=8*rows8-1 then
2901      begin
2902        //move up
2903        dec(srow);
2904        if srow<0 then
2905        begin
2906          srow:=0;
2907          textedit.Top:=(srow+1)*(textheight)+3;
2908
2909          dec(memoryaddress,8*rows8);
2910          refreshmb;
2911        end else textedit.Top:=(srow+1)*(textheight)+3;
2912      end;
2913
2914      textedit.left:=(1+a+20*8*rows8+(scolumn*mbcanvas.Canvas.TextWidth('D')));            //1+a+20*(scolumn);
2915      dec(selected);
2916
2917      acr:=0;
2918      readprocessmemory(processhandle,pointer(selected),@bt,1,acr);
2919
2920      if acr=1 then
2921      begin
2922        if bt>32 then textedit.text:=chr(bt) else textedit.text:=' ';
2923        editing2:=false;
2924        textedit.visible:=true;
2925        textedit.SelectAll;
2926        textedit.SetFocus;
2927      end else textedit.visible:=false;
2928      key:=0;
2929    end;
2930
2931    vk_right:
2932    begin
2933      handleright;
2934    end;
2935
2936    else begin
2937           editing2:=true;
2938         end;
2939  end;
2940end;
2941
2942procedure TMemoryBrowser.CreateThread1Click(Sender: TObject);
2943var startaddress,parameter: dword;
2944    ThreadID: dword;
2945    start:string;
2946    param:string;
2947begin
2948  start:=IntToHex(disassemblerview.SelectedAddress,8);
2949  param:='0';
2950  if not InputQuery('Create remote thread','What will be the startaddress of this thread?',start) then exit;
2951  try
2952    startaddress:=StrToInt('$'+start);
2953  except
2954    raise exception.Create('Please enter a valid hexadecimal addres');
2955  end;
2956
2957  if not InputQuery('Create remote thread','You want to give an additional 32-bit parameter? (Will show up in EBX)',param) then exit;
2958  try
2959    parameter:=StrToInt('$'+param);
2960  except
2961    raise exception.Create('Please enter a valid hexadecimal value');
2962  end;
2963
2964  if CreateRemoteThread(processhandle,nil,0,pointer(startaddress),pointer(parameter),0,threadid)=0 then raise exception.Create('Creation of the remote thread failed') else showmessage('Thread Created');
2965end;
2966
2967procedure TMemoryBrowser.MemoryRegions1Click(Sender: TObject);
2968begin
2969  {$ifndef net}
2970  formmemoryregions:=tformmemoryregions.Create(self);
2971  formmemoryregions.show;
2972  {$endif}
2973end;
2974
2975procedure TMemoryBrowser.TextEditKeyPress(Sender: TObject; var Key: Char);
2976var bt: byte;
2977acr:dword;
2978a:integer;
2979begin
2980  a:=20+mbimage.Canvas.TextWidth('00400000');
2981  if editing2 then
2982  begin
2983    bt:=byte(key);
2984    if bt>=32 then
2985      writeprocessmemory(processhandle,pointer(selected),@bt,1,acr)
2986    else
2987    begin
2988      key:=#0;
2989      exit;
2990    end;
2991
2992    inc(scolumn);
2993    scolumn:=scolumn mod (8*rows8);
2994    if (scolumn)=0 then
2995    begin
2996      //move down
2997      inc(srow);
2998
2999      if (((srow+1)*(textheight)+3)+textedit.Height)>panel4.Height then
3000      begin
3001        dec(srow);
3002        textedit.top:=(srow+1)*(textheight)+3;
3003        inc(memoryaddress,8*rows8);
3004        refreshmb;
3005      end else textedit.Top:=(srow+1)*(textheight)+3;
3006    end;
3007
3008    textedit.left:=(1+a+20*8*rows8+(scolumn*mbcanvas.Canvas.TextWidth('D')));
3009    inc(selected);
3010
3011    acr:=0;
3012    readprocessmemory(processhandle,pointer(selected),@bt,1,acr);
3013
3014    if acr=1 then
3015    begin
3016      if bt>32 then textedit.text:=chr(bt) else textedit.text:=' ';
3017      editing2:=false;
3018      textedit.visible:=true;
3019      textedit.SelectAll;
3020      textedit.SetFocus;
3021    end else hexedit.visible:=false;
3022    key:=#0;
3023  end;
3024
3025  refreshmb;
3026end;
3027
3028procedure TMemoryBrowser.FillMemory1Click(Sender: TObject);
3029begin
3030  frmFillMemory:=TFrmFillMemory.create(self);
3031  with frmFillMemory do
3032  begin
3033    edit1.Text:=IntToHex(disassemblerview.SelectedAddress,8);
3034    edit2.Text:=IntToHex(disassemblerview.SelectedAddress+1,8);
3035    frmFillMemory.showmodal;
3036  end;
3037
3038end;
3039
3040procedure TMemoryBrowser.Disectwindow1Click(Sender: TObject);
3041begin
3042  {$ifndef net}
3043  frmdissectWindow:=tfrmdissectWindow.create(self);
3044  frmdissectWindow.showmodal;
3045  {$endif}
3046end;
3047
3048procedure TMemoryBrowser.Savedisassemledoutput1Click(Sender: TObject);
3049var x,y: string;
3050    start,stop: dword;
3051    output: textfile;
3052
3053begin
3054  with tfrmSavedisassembly.create(self) do
3055  begin
3056    start:=min(disassemblerview.SelectedAddress,disassemblerview.SelectedAddress2);
3057    stop:=max(disassemblerview.SelectedAddress,disassemblerview.SelectedAddress2);
3058    disassemble(stop);
3059    edit1.Text:=inttohex(start,8);
3060    edit2.Text:=inttohex(stop,8);
3061    show;
3062  end;
3063end;
3064
3065procedure TMemoryBrowser.Heaps1Click(Sender: TObject);
3066begin
3067  {$ifndef net}
3068  if processid=0 then raise exception.Create('Please target a process first');
3069  if (frmMemoryAllocHandler<>nil) and (frmMemoryAllocHandler.hookedprocessid<>processid) then
3070    freeandnil(frmMemoryAllocHandler);
3071
3072  if frmheaps=nil then
3073    frmheaps:=tfrmheaps.create(self);
3074
3075  frmheaps.show;
3076  {$endif}
3077
3078end;
3079
3080procedure TMemoryBrowser.EnumeratedllsandSymbols1Click(Sender: TObject);
3081begin
3082  {$ifndef net}
3083  symhandler.reinitialize;
3084 
3085  if frmEnumerateDLLs=nil then
3086  begin
3087    frmEnumerateDLLs:=tfrmEnumerateDLLs.create(self);
3088    frmEnumerateDLLs.Show;
3089  end
3090  else frmEnumerateDLLs.enumerate;
3091  {$endif}
3092end;
3093
3094procedure TMemoryBrowser.InjectDLL1Click(Sender: TObject);
3095var dll: string;
3096    functionname: string;
3097    dllList: tstringlist;
3098begin
3099  functionname:='';
3100  dll:='';
3101
3102  if opendlldialog.Execute then
3103  begin
3104    dll:=opendlldialog.Filename;
3105    if MessageDlg('Do you want to execute a function of the dll?',mtConfirmation        ,[mbyes,mbno],0)=mryes then
3106    begin
3107      dllList:=tstringlist.Create;
3108
3109      try
3110        peinfo_getExportList(opendlldialog.filename, dllList);
3111        with TfrmFunctionList.create(self,dllList) do
3112        begin
3113          if showmodal=mrok then
3114            if itemindex<>-1 then
3115              functionname:=functions[itemindex];
3116
3117          free;
3118        end;
3119      finally
3120        dllList.free;
3121      end;
3122    end;
3123
3124    InjectDll(dll,functionname);
3125    symhandler.reinitialize;
3126    showmessage('DLL Injected');
3127  end;
3128end;
3129
3130procedure TMemoryBrowser.AutoInject1Click(Sender: TObject);
3131begin
3132  tfrmautoinject.create(self).show;
3133end;
3134
3135procedure TMemoryBrowser.Dissectcode1Click(Sender: TObject);
3136begin
3137  {$ifndef net}
3138  if frmdissectcode=nil then
3139    frmdissectcode:=tfrmDissectcode.create(self);
3140
3141  frmdissectcode.Show;
3142  {$endif}
3143end;
3144
3145procedure TMemoryBrowser.Createjumptocodecave1Click(Sender: TObject);
3146var x: string;
3147    codecaveaddress: dword;
3148    size: dword;
3149begin
3150  x:='';
3151  if inputquery('Create Code-Cave','Give the address of the code-cave you want to use. (Use allocate memory if you couldn''t find one)',x) then
3152  begin
3153    try
3154      codecaveaddress:=StrToInt('$'+x);
3155    except
3156      raise exception.Create('Please give me a valid address');
3157    end;
3158
3159    x:='40';
3160    if inputquery('Create Code-Cave','How big is the code-cave (or how much do you think you''ll use?)',x) then
3161    begin
3162      try
3163        size:=StrToInt(x);
3164      except
3165        raise exception.Create('And how many bytes are that?');
3166      end;
3167
3168      CreateCodecave(codecaveaddress,disassemblerview.SelectedAddress,size);
3169
3170    end;
3171
3172
3173  end;
3174end;
3175
3176procedure TMemoryBrowser.Findstaticpointers1Click(Sender: TObject);
3177begin
3178{$ifndef net}
3179  if frmfindstatics=nil then
3180    frmfindstatics:=tfrmfindstatics.create(self);
3181
3182  frmfindstatics.show;
3183{$endif}
3184end;
3185
3186procedure TMemoryBrowser.Scanforcodecaves1Click(Sender: TObject);
3187begin
3188  if frmcodecavescanner=nil then
3189    frmcodecavescanner:=tfrmCodecaveScanner.create(self);
3190
3191  frmCodecavescanner.show;
3192end;
3193
3194procedure TMemoryBrowser.Changestateofregisteratthislocation1Click(
3195  Sender: TObject);
3196begin
3197{$ifndef net}
3198  if foundcodedialog<>nil then
3199    raise exception.Create('I can''t do that! You are currently using one of the code finder options, please, stop it first');
3200
3201  if (formsettings.cbKdebug.checked) and (kdebugger.isactive) and (kdebugger.nrofbreakpoints=4) then raise exception.Create('You have reached the maximum of 4 debugregs. Disable at least one breakpoint first'); //all spots filled up
3202
3203  if (not formsettings.cbKdebug.checked) then
3204    if (not startdebuggerifneeded) then exit;
3205
3206  tfrmModifyRegisters.create(self,disassemblerview.SelectedAddress).showmodal;
3207{$endif}
3208end;
3209
3210procedure TMemoryBrowser.ogglebreakpoint1Click(Sender: TObject);
3211begin
3212{$ifndef net}
3213  if (formsettings.cbKdebug.checked) and (debuggerthread=nil) then
3214  begin
3215    KDebugger.StartDebugger;
3216    KDebugger.ToggleBreakpoint(disassemblerview.SelectedAddress);
3217  end
3218  else
3219  begin
3220    //normal debugger
3221    togglebreakpoint(disassemblerview.SelectedAddress);
3222    disassemblerview.Update;
3223  end;
3224
3225
3226{$endif}
3227end;
3228
3229procedure TMemoryBrowser.Breakpointlist1Click(Sender: TObject);
3230begin
3231{$ifndef net}
3232  if frmbreakpointlist=nil then
3233  begin
3234    frmbreakpointlist:=tfrmBreakpointlist.create(self);
3235    frmBreakpointlist.show;
3236  end
3237  else
3238    frmbreakpointlist.bringtofront;
3239{$endif}
3240end;
3241
3242
3243procedure TMemoryBrowser.Makepagewritable1Click(Sender: TObject);
3244var x: dword;
3245begin
3246{$ifndef net}
3247  VirtualProtectEx(processhandle,pointer(memoryaddress),4096,PAGE_EXECUTE_READWRITE,x);
3248//  if (memoryaddress>80000000) and (DarkByteKernel<>0) then
3249//    MakeWritableEx(processhandle,memoryaddress,4096,false);
3250{$endif}
3251end;
3252
3253procedure TMemoryBrowser.Dissectdata1Click(Sender: TObject);
3254begin
3255{$ifndef net}
3256  with tfrmpointerscanner.create(self) do
3257    show;
3258{$endif}
3259end;
3260
3261procedure TMemoryBrowser.Showsymbols1Click(Sender: TObject);
3262begin
3263  showsymbols1.Checked:=not showsymbols1.Checked;
3264  symhandler.showsymbols:=showsymbols1.Checked;
3265  disassemblerview.Update;
3266end;
3267
3268procedure TMemoryBrowser.Showmoduleaddresses1Click(Sender: TObject);
3269begin
3270  Showmoduleaddresses1.Checked:=not Showmoduleaddresses1.checked;
3271  symhandler.showmodules:=Showmoduleaddresses1.Checked;
3272  disassemblerview.Update;
3273end;
3274
3275
3276procedure TMemoryBrowser.Dissectdata2Click(Sender: TObject);
3277begin
3278{$ifndef net}
3279  if length(frmStructures)>0 then
3280  begin
3281    frmStructures[0].edtAddress.Text:=inttohex(memorybrowser.memoryaddress,8);
3282    frmStructures[0].Show;
3283  end
3284  else
3285  begin
3286    //create it
3287    with tfrmstructures.create(self) do
3288    begin
3289      edtAddress.Text:=inttohex(memoryaddress,8);
3290      update(false);
3291      show;
3292    end;
3293  end;
3294
3295
3296
3297{$endif}
3298end;
3299
3300procedure TMemoryBrowser.Symbolhandler1Click(Sender: TObject);
3301begin
3302{$ifndef net}
3303  if frmSymbolhandler=nil then
3304    frmSymbolhandler:=TfrmSymbolhandler.create(self);
3305
3306  frmSymbolhandler.show;
3307{$endif}
3308end;
3309
3310procedure TMemoryBrowser.Allocatenonpagedmemory1Click(Sender: TObject);
3311var count: string;
3312    memsize: integer;
3313    baseaddress: pointer;
3314    x: dword;
3315    s: string;
3316begin
3317{$ifndef net}
3318  count:='4096';
3319  if inputquery('Allocate memory','How much memory do you wish to allocate?. ',count) then
3320  begin
3321    try
3322      memsize:=StrToInt(count);
3323    except
3324      raise exception.Create('How much is '+count+'?');
3325    end;
3326
3327    baseaddress:=nil;
3328    baseaddress:=KernelAlloc(memsize);
3329    if baseaddress<>nil then
3330    begin
3331      if (disassemblerview.SelectedAddress<>0) and (memsize>7) and (messagedlg('At least '+IntToStr(memsize)+' bytes have been allocated at '+IntToHex(dword(baseaddress),8)+#13#10+'Do you want replace the currently selected address with a jump to that address, and copy the overwritten instructions to there?',mtConfirmation,[mbyes,mbno],0)=mryes) then
3332        CreateCodecave(dword(baseaddress),disassemblerview.SelectedAddress,memsize)
3333      else
3334        messagedlg('At least '+IntToStr(memsize)+' bytes have been allocated at '+IntToHex(dword(baseaddress),8),mtinformation,[mbok],0);
3335
3336
3337      if messagedlg('Do you want to go there now?',mtConfirmation,[mbyes,mbno],0) = mryes then
3338        disassemblerview.SelectedAddress:=dword(baseaddress);
3339    end else raise exception.Create('Error allocating memory!');
3340  end;
3341  {$endif}
3342end;
3343
3344procedure TMemoryBrowser.Getaddress1Click(Sender: TObject);
3345var p: pointer;
3346    s: string;
3347    ws: widestring;
3348    pws: pwidechar;
3349begin
3350  if inputquery('Get kernel address','Give the name of the function you want to find (Case sensitive,certain words can cause blue screens)',s) then
3351  begin
3352    ws:=s;
3353    pws:=@ws[1];
3354    p:=GetKProcAddress(pws);
3355
3356    disassemblerview.SelectedAddress:=dword(p);
3357  end;
3358end;
3359
3360procedure TMemoryBrowser.Findmemory1Click(Sender: TObject);
3361begin
3362  search1.Click;
3363end;
3364
3365procedure TMemoryBrowser.Assemblycode1Click(Sender: TObject);
3366var s:string;
3367
3368begin
3369  s:='';
3370  if inputquery('Assembly scan','Input the assembly code to find. wilcards(*) supported.',s) then
3371  begin
3372    if s='' then exit;
3373    with TfrmDisassemblyscan.create(self) do
3374    begin
3375      startaddress:=disassemblerview.SelectedAddress;
3376      stringtofind:=s;
3377      show;
3378    end;
3379
3380  end;
3381end;
3382
3383procedure TMemoryBrowser.Driverlist1Click(Sender: TObject);
3384begin
3385  {$ifndef net}
3386  with tfrmdriverlist.create(self) do
3387    show;
3388  {$endif}
3389end;
3390
3391procedure TMemoryBrowser.plugintype6click(sender:tobject);
3392var
3393  x: TPluginfunctionType6;
3394  selectedaddress: dword;
3395begin
3396  x:=TPluginfunctionType6(tmenuitem(sender).Tag);
3397  if x<>nil then
3398  begin
3399    selectedaddress:=disassemblerview.SelectedAddress;
3400    x.callback(@selectedaddress);
3401    disassemblerview.SelectedAddress:=selectedaddress;
3402  end;
3403end;
3404
3405procedure TMemoryBrowser.plugintype1click(sender:tobject);
3406{$ifndef net}
3407var x: TPluginfunctionType1;
3408address: dword;
3409{$endif}
3410begin
3411{$ifndef net}
3412  x:=TPluginfunctionType1(tmenuitem(sender).Tag);
3413  if x<>nil then
3414  begin
3415    address:=disassemblerview.TopAddress;
3416    x.callback(@address,@disassemblerview.SelectedAddress,@memoryaddress);
3417    disassemblerview.TopAddress:=address;
3418    refreshmb;
3419  end;
3420{$endif}
3421end;
3422
3423procedure TMemoryBrowser.Sericedescriptortable1Click(Sender: TObject);
3424begin
3425{$ifndef net}
3426  if frmServiceDescriptorTables=nil then
3427    frmServiceDescriptorTables:=TfrmServiceDescriptorTables.create(self);
3428
3429  frmServiceDescriptorTables.show;
3430{$endif}
3431end;
3432
3433procedure TMemoryBrowser.MBCanvasMouseDown(Sender: TObject;
3434  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
3435var a: integer;
3436    i,j: integer;
3437    acr: dword;
3438    bt:byte;
3439
3440    temp:string;
3441    hadselection: boolean;
3442begin
3443  if button=mbright then
3444  begin
3445    if selecting or selectionmade then exit;
3446  end;
3447
3448  selecting:=button=mbleft;
3449
3450  hadselection:=selectionmade;
3451  selectionmade:=false;
3452
3453  fcontrol2.SetFocus;
3454  hexedit.Visible:=false;
3455  textedit.Visible:=false;
3456
3457//find out if the user clicked on a byte, and if so which one
3458  a:=20+mbimage.Canvas.TextWidth('00400000');
3459  part:=0; //address
3460
3461  if x>a then
3462  begin  //didnt click on the address
3463    part:=2; //textfield ad the left side
3464    if x<(a+20*8*rows8) then //byteclick
3465    begin
3466      if displaytype<>dtByte then
3467      begin
3468        selecting:=false; //not for this type
3469        exit;
3470      end;
3471     
3472      part:=1; //a byte
3473      srow:=(y div textheight);
3474      scolumn:=(x-a) div 20;
3475
3476      i:=(srow*8*rows8)+scolumn;
3477      //caption:=Inttohex(memoryaddress+i,8);
3478      selected:=memoryaddress+i;
3479
3480    end
3481    else
3482    begin
3483      //not on a byte click
3484      for i:=1 to 8*rows8 do
3485        temp:=temp+'D';
3486
3487      srow:=y div textheight;
3488
3489
3490      i:=(x-(1+a+20*8*rows8));
3491
3492      scolumn:=i div mbcanvas.Canvas.TextWidth('D');
3493
3494      if scolumn<8*rows8 then
3495      begin
3496        i:=scolumn*mbcanvas.Canvas.TextWidth('D');
3497        selected:=scolumn+memoryaddress+(8*rows8)*srow;
3498
3499      end;
3500    end;
3501  end;
3502
3503  selected2:=selected;
3504
3505  if hadselection then RefreshMB;
3506end;
3507
3508procedure TMemoryBrowser.Cut1Click(Sender: TObject);
3509var i: dword;
3510    start,stop: dword;
3511    x: byte;
3512    br: dword;
3513    s: string;
3514
3515    cl: tclipboard;
3516begin
3517  if selected>selected2 then
3518  begin
3519    start:=selected2;
3520    stop:=selected;
3521  end
3522  else
3523  begin
3524    start:=selected;
3525    stop:=selected2;
3526  end;
3527
3528  s:='';
3529  for i:=start to stop do
3530  begin
3531    if readprocessmemory(processhandle,pointer(i),@x,1,br) then
3532    begin
3533      s:=s+inttohex(x,2)+' ';
3534    end
3535    else s:=s+'?? ';
3536  end;
3537
3538  if s<>'' then
3539    s:=copy(s,1,length(s)-1);
3540
3541  cl:=tclipboard.Create;
3542  cl.AsText:=s;
3543  cl.Free;
3544end;
3545
3546procedure TMemoryBrowser.Pastefromclipboard1Click(Sender: TObject);
3547var cl: tclipboard;
3548    s: string;
3549    i: integer;
3550    x,bw: dword;
3551    b: tbytes;
3552begin
3553  cl:=tclipboard.Create;
3554  s:=cl.AsText;
3555  cl.free;
3556
3557
3558  setlength(b,0);
3559  try
3560    ConvertStringToBytes(s,true,b);
3561    x:=selected;
3562    for i:=0 to length(b)-1 do
3563    begin
3564      if b[i]<>-1 then
3565        writeprocessmemory(processhandle,pointer(x),@b[i],1,bw);
3566
3567      inc(x);
3568    end;
3569  except
3570
3571  end;
3572
3573  setlength(b,0);
3574  refreshmb;
3575end;
3576
3577procedure TMemoryBrowser.Setsymbolsearchpath1Click(Sender: TObject);
3578var searchpath: string;
3579begin
3580{$ifndef net}
3581  if symhandler.isloaded then
3582  begin
3583    searchpath:=symhandler.getsearchpath;
3584    if inputquery('Symbol handler','Please specify the new symbol searchpath (; seperates paths)',searchpath) then
3585    begin
3586      symhandler.setsearchpath(searchpath);
3587
3588      symhandler.reinitialize;
3589
3590      symhandler.waitforsymbolsloaded;
3591
3592    end;
3593  end;
3594{$endif}
3595end;
3596
3597procedure TMemoryBrowser.Kernelmodesymbols1Click(Sender: TObject);
3598begin
3599{$ifndef net}
3600
3601  Kernelmodesymbols1.Checked:=not Kernelmodesymbols1.Checked;
3602
3603  symhandler.kernelsymbols:=Kernelmodesymbols1.Checked;
3604  symhandler.reinitialize;
3605  symhandler.waitforsymbolsloaded;
3606{$endif}
3607end;
3608
3609procedure TMemoryBrowser.Breakandtraceinstructions1Click(Sender: TObject);
3610begin
3611//  if debugger<>nil then
3612{$ifndef net}
3613
3614  frmtracer:=TFrmTracer.create(self);
3615  frmtracer.show;
3616{$endif}
3617end;
3618
3619procedure TMemoryBrowser.debuggerpopupPopup(Sender: TObject);
3620var x: dword;
3621begin
3622  Breakandtraceinstructions1.Enabled:=processhandle<>0;
3623  ogglebreakpoint1.Enabled:=processhandle<>0;
3624  Changestateofregisteratthislocation1.Enabled:=processhandle<>0;
3625  follow1.visible:=isjumporcall(disassemblerview.SelectedAddress,x);
3626  back1.Visible:=backlist.Count>0;
3627
3628  pluginhandler.handledisassemblerContextPopup(disassemblerview.SelectedAddress);
3629end;
3630
3631procedure TMemoryBrowser.GDTlist1Click(Sender: TObject);
3632begin
3633  Tfrmgdtinfo.create(self).show;
3634end;
3635
3636procedure TMemoryBrowser.IDTlist1Click(Sender: TObject);
3637begin
3638  TfrmIDT.create(self).show;
3639end;
3640
3641procedure TMemoryBrowser.ScriptEngine1Click(Sender: TObject);
3642var x: tfrmautoinject;
3643begin
3644  x:=tfrmautoinject.create(self);
3645  x.cplusplus:=true;
3646  x.show;
3647end;
3648
3649procedure TMemoryBrowser.FormDestroy(Sender: TObject);
3650var h0,h1,h2,h3: integer;
3651begin
3652  if strace<>nil then
3653    strace.free;
3654
3655  disassemblerHistory.free;
3656  memorybrowserHistory.free;
3657  assemblerHistory.free;
3658
3659  //save position of window and other stuff
3660  //membrowser comes after formsettings so is destroyed before formsettings, so valid
3661  if (not ischild) then
3662  begin
3663    saveformposition(self,[
3664                            disassemblerview.getheaderwidth(0),
3665                            disassemblerview.getheaderwidth(1),
3666                            disassemblerview.getheaderwidth(2),
3667                            disassemblerview.getheaderwidth(3),
3668                            panel1.height,
3669                            registerview.width
3670                    ]);   
3671  end;
3672
3673end;
3674
3675procedure TMemoryBrowser.Newwindow1Click(Sender: TObject);
3676begin
3677  with tmemorybrowser.create(nil) do
3678  begin
3679    inc(mbchildcount);
3680    name:='MemoryBrowser'+inttostr(mbchildcount);
3681    debug1.Visible:=false;
3682    //registerview.Visible:=false;
3683    //splitter2.Visible:=false;
3684    sbShowFloats.Visible:=false;
3685    caption:=caption+'* ('+inttostr(mbchildcount)+')';
3686
3687    ischild:=true;
3688    show;
3689  end;
3690end;
3691
3692
3693procedure TMemoryBrowser.Follow1Click(Sender: TObject);
3694{
3695will change the selected disassembler address to the address this instructions jump so if it is an jump instruction
3696}
3697var address: dword;
3698begin
3699  if isjumporcall(disassemblerview.SelectedAddress,address) then
3700  begin
3701    backlist.Push(pointer(disassemblerview.SelectedAddress));
3702    disassemblerview.SelectedAddress:=address;
3703  end;
3704end;
3705
3706
3707
3708procedure TMemoryBrowser.CopyBytesAndOpcodesClick(Sender: TObject);
3709var a,b: dword;
3710    _tag: integer;
3711begin
3712  _tag:=(sender as tmenuitem).Tag;
3713
3714  with tfrmSavedisassembly.create(self) do
3715  begin
3716
3717    a:=min(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2);
3718    b:=max(disassemblerview.SelectedAddress, disassemblerview.SelectedAddress2);
3719   
3720    disassemble(b); //b gets increased with size of selected instruction
3721    edit1.Text:=inttohex(a,8);
3722    edit2.Text:=inttohex(b,8);
3723    copymode:=true;
3724
3725    checkbox1.checked:=true;
3726    checkbox2.checked:=(_tag=0) or (_tag=1);
3727    checkbox3.checked:=(_tag=0) or (_tag=2);
3728   
3729    button1.click;
3730    waittilldone;
3731
3732    free;
3733  end;
3734
3735
3736end;
3737
3738procedure TMemoryBrowser.DissectPEheaders1Click(Sender: TObject);
3739begin
3740  with TfrmPEInfo.create(self) do
3741    show;
3742end;
3743
3744procedure TMemoryBrowser.SetCodeAndDataBase;
3745var modulelist: tstringlist;
3746    base: dword;
3747    header: pointer;
3748    headersize: dword;
3749    br: dword;
3750begin
3751  modulelist:=tstringlist.Create;
3752  symhandler.getModuleList(modulelist);
3753
3754  if modulelist.Count>0 then
3755  begin
3756    base:=dword(modulelist.Objects[0]);
3757    getmem(header,4096);
3758    try
3759      if readprocessmemory(processhandle,pointer(base),header,4096,br) then
3760      begin
3761        headersize:=peinfo_getheadersize(header);
3762        if headersize=0 then exit;
3763       
3764        if headersize>4096 then
3765        begin
3766          if headersize>1024*512 then exit;
3767
3768          freemem(header);
3769          getmem(header,headersize);
3770          if not readprocessmemory(processhandle,pointer(base),header,headersize,br) then exit;
3771        end;
3772
3773        disassemblerview.SelectedAddress:=base+peinfo_getEntryPoint(header);
3774
3775        memoryaddress:=base+peinfo_getdatabase(header);
3776      end;
3777    finally
3778      freemem(header);
3779    end;
3780  end;
3781  modulelist.free;
3782end;
3783
3784procedure TMemoryBrowser.Back1Click(Sender: TObject);
3785begin
3786  if backlist.Count>0 then
3787    disassemblerview.SelectedAddress:=dword(backlist.pop);
3788end;
3789
3790procedure TMemoryBrowser.Showvaluesofstaticaddresses1Click(
3791  Sender: TObject);
3792begin
3793  showvalues:=not showvalues;
3794end;
3795
3796procedure TMemoryBrowser.FindwhatThiscodeAccesses(address: dword);
3797var i: integer;
3798begin
3799  //check if the old window exists, if so, mark it as deactivated
3800  if frmChangedAddresses<>nil then
3801    frmChangedAddresses.changedlist.color:=clGray;
3802
3803  //create new window, and leave the old one alive
3804  frmChangedAddresses:=TfrmChangedAddresses.Create(self);
3805 
3806  if (formsettings.cbKdebug.checked) and (debuggerthread=nil) then
3807  begin
3808    KDebugger.StartDebugger;  //if it wasn't enabled yet
3809    try
3810      KDebugger.SetBreakpoint(address, bt_OnInstruction, 1, bo_FindWhatCodeAccesses);
3811    except
3812      on e: exception do
3813      begin
3814        freeandnil(frmChangedAddresses);
3815        raise e;
3816      end;
3817    end;
3818  end
3819  else
3820  begin
3821    //New method:
3822    if not startdebuggerifneeded then exit;
3823    if debuggerthread.userisdebugging then raise exception.create('You can''t use this function while you are debugging the application yourself. (Close the memory view window forces a close of manual debugging)');
3824
3825    if frmChangedAddresses<>nil then
3826      frmChangedAddresses.changedlist.color:=clGray;
3827
3828    frmChangedAddresses:=TfrmChangedAddresses.Create(self);
3829
3830    debuggerthread.Suspend;
3831
3832    debuggerthread.DRRegs.ContextFlags:=CONTEXT_DEBUG_REGISTERS;
3833    debuggerthread.DRRegs.Dr0:=address;
3834    debuggerthread.DRRegs.Dr7:=reg0set or reg1set or reg2set or reg3set;
3835
3836    for i:=0 to length(debuggerthread.threadlist)-1 do
3837    begin
3838      suspendthread(debuggerthread.threadlist[i][1]);
3839      if not setthreadcontext(debuggerthread.threadlist[i][1],debuggerthread.DRRegs) then showmessage('failed 1');
3840      resumethread(debuggerthread.threadlist[i][1]);
3841    end;
3842
3843
3844    debuggerthread.breakpointaddress:=address;
3845    debuggerthread.breakpointset:=true;
3846
3847    debuggerthread.Resume;
3848  end;
3849  frmChangedAddresses.show;
3850end;
3851
3852procedure TMemoryBrowser.Findoutwhataddressesthisinstructionaccesses1Click(
3853  Sender: TObject);
3854begin
3855  findWhatthisCodeAccesses(disassemblerview.SelectedAddress);
3856end;
3857
3858procedure TMemoryBrowser.sbShowFloatsClick(Sender: TObject);
3859var x: tpoint;
3860z: trect;
3861begin
3862  if frmFloatingPointPanel=nil then
3863    frmFloatingPointPanel:=TfrmFloatingPointPanel.create(self);
3864
3865  frmFloatingPointPanel.Left:=self.left+self.Width;
3866  frmFloatingPointPanel.Top:=self.top+(self.ClientOrigin.y-self.top)-(frmFloatingPointPanel.ClientOrigin.y-frmFloatingPointPanel.top);
3867  frmFloatingPointPanel.ClientHeight:=scrollbox1.Height;
3868  frmFloatingPointPanel.show;//pop to foreground
3869end;
3870
3871procedure TMemoryBrowser.ScriptConsole1Click(Sender: TObject);
3872begin
3873  with TfrmCScript.create(self) do
3874    show;
3875end;
3876
3877procedure TMemoryBrowser.DisplayTypeClick(Sender: TObject);
3878var x: tmenuitem;
3879begin
3880//vtByte, vtWord, vtDword, vtDwordDec, vtSingle, vtDouble
3881  if (sender is TMenuItem) then
3882  begin
3883    x:=TMenuItem(sender);
3884    case x.tag of
3885      0: DisplayType:=dtByte;
3886      1: DisplayType:=dtWord;
3887      2: DisplayType:=dtDword;
3888      3: DisplayType:=dtDwordDec;
3889      4: DisplayType:=dtsingle;
3890      5: DisplayType:=dtDouble;
3891    end;
3892
3893
3894    mbimage.Canvas.FillRect(rect(0,0,mbimage.Width,mbimage.Height));
3895    MBCanvas.Invalidate;
3896    MBCanvas.Repaint;
3897    refreshMB;
3898  end;
3899end;
3900
3901procedure TMemoryBrowser.Showjumplines1Click(Sender: TObject);
3902begin
3903  showjumplines1.checked:=not showjumplines1.checked;
3904  disassemblerview.showjumplines:=showjumplines1.checked;
3905
3906  Onlyshowjumplineswithinrange1.Enabled:=showjumplines1.checked;
3907end;
3908
3909procedure TMemoryBrowser.Onlyshowjumplineswithinrange1Click(
3910  Sender: TObject);
3911begin
3912  Onlyshowjumplineswithinrange1.checked:=not Onlyshowjumplineswithinrange1.checked;
3913  if Onlyshowjumplineswithinrange1.checked then
3914    disassemblerview.ShowJumplineState:=jlsOnlyWithinRange
3915  else
3916    disassemblerview.ShowJumplineState:=jlsAll;
3917
3918end;
3919
3920procedure TMemoryBrowser.Watchmemoryallocations1Click(Sender: TObject);
3921begin
3922  if processid=0 then raise exception.Create('Please target a process first');
3923  if (frmMemoryAllocHandler<>nil) and (frmMemoryAllocHandler.hookedprocessid<>processid) then
3924    freeandnil(frmMemoryAllocHandler);
3925
3926
3927  if frmMemoryAllocHandler=nil then
3928  begin
3929    {if MessageDlg('This function will inject a dll into the target process and hook some memory allocation/free routines. Continue?',mtConfirmation, [mbyes,mbno],0)<>mryes then exit;
3930
3931    }
3932    frmMemoryAllocHandler:=TfrmMemoryAllocHandler.Create(self);
3933  end;
3934
3935  frmMemoryAllocHandler.Show;
3936end;
3937
3938procedure TMemoryBrowser.Continueanddetachdebugger1Click(Sender: TObject);
3939begin
3940  if debuggerthread<>nil then
3941  begin
3942    debuggerthread.Terminate;
3943    debuggerthread.continuehow:=wdco_run;   //note: I could also have the debuggerthread suspend itself, and resume it here
3944    debuggerthread.continueprocess:=true;
3945    caption:='Memory Viewer - Detaching';
3946    debuggerthread.WaitFor;
3947    open_process;
3948    caption:='Memory Viewer - Detached';
3949  end;
3950end;
3951
3952procedure TMemoryBrowser.Panel2Resize(Sender: TObject);
3953begin
3954  mbcanvas.Height:=panel4.Height-2-9;
3955  mbcanvas.Width:=panel4.Width;
3956
3957  mbimage.Width:=mbcanvas.Width;
3958  mbimage.Height:=mbcanvas.Height;
3959
3960  mbimage.Canvas.FillRect(rect(0,0,mbimage.Width,mbimage.Height));
3961  MBCanvas.Invalidate;
3962  MBCanvas.Repaint;
3963  refreshMB;
3964
3965  if hexedit.visible or textedit.visible then fcontrol2.SetFocus;
3966end;
3967
3968procedure TMemoryBrowser.Panel2MouseDown(Sender: TObject;
3969  Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
3970begin
3971  fcontrol2.SetFocus;
3972end;
3973
3974procedure TMemoryBrowser.ScrollBox1Resize(Sender: TObject);
3975begin
3976  sbShowFloats.Top:=scrollbox1.ClientHeight div 2-sbShowFloats.Height div 2;
3977end;
3978
3979procedure TMemoryBrowser.reloadStacktrace;
3980var s: pdwordarray;
3981    x: dword;
3982   
3983    i: integer;
3984    address, bytes, details: string;
3985    li: tlistitem;
3986    c: TListcolumn;
3987begin
3988  lvStacktraceData.Items.BeginUpdate;
3989  try
3990    if stacktrace2.Checked then
3991    begin
3992      //setup view for stacktrace if it isn't setup yet
3993      if lvStacktraceData.columns.Count=3 then
3994      begin
3995        lvstacktracedata.Columns.BeginUpdate;
3996        try
3997          lvstacktracedata.Columns.Clear;
3998          c:=lvstacktracedata.Columns.Add;
3999          c.Caption:='Return Address';
4000          c.Width:=120;
4001
4002          c:=lvstacktracedata.Columns.Add;
4003          c.Caption:='Parameters';
4004          c.Width:=200;
4005          c.AutoSize:=true;
4006
4007        finally
4008          lvstacktracedata.Columns.EndUpdate;
4009        end;
4010      end;
4011
4012      if frmstacktrace=nil then
4013        frmstacktrace:=tfrmstacktrace.create(self);
4014
4015
4016      lvstacktracedata.Items.Count:=frmstacktrace.ListView1.Items.Count;
4017    end
4018    else
4019    begin
4020      //setup view for stackview if it isn't setup yet
4021      if lvStacktraceData.columns.Count<>3 then
4022      begin
4023        lvstacktracedata.Columns.BeginUpdate;
4024        try
4025          lvstacktracedata.Columns.Clear;
4026          c:=lvstacktracedata.Columns.Add;
4027          c.Caption:='Address';
4028          c.Width:=80;
4029          c:=lvstacktracedata.Columns.Add;
4030          c.Caption:='DWORD';
4031          c.Width:=80;
4032          c:=lvstacktracedata.Columns.Add;
4033          c.Caption:='Value';
4034          c.Width:=100;
4035          c.AutoSize:=true;
4036        finally
4037          lvstacktracedata.Columns.EndUpdate;
4038        end;
4039      end;
4040
4041      if all1.checked =false then
4042      begin
4043        //just get the list
4044        getmem(s,FStacktraceSize);
4045        try
4046          readprocessmemory(processhandle, pointer(lastdebugcontext.Esp),s, FStacktraceSize,x);
4047          strace.Clear;
4048          ce_stacktrace(lastdebugcontext.esp, lastdebugcontext.ebp, lastdebugcontext.eip, s,x, strace,false,Nonsystemmodulesonly1.checked or modulesonly1.Checked,Nonsystemmodulesonly1.checked,0);
4049
4050          lvstacktracedata.Items.Count:=strace.Count;
4051        finally
4052          freemem(s);
4053        end;
4054      end else
4055      begin
4056        lvstacktracedata.Items.Count:=4096 div 4;
4057      end;
4058
4059    end;
4060  finally
4061    lvStacktraceData.Items.EndUpdate;
4062  end;
4063{
4064  lvStacktraceData.Items.BeginUpdate;
4065  lvStacktraceData.count:=0;
4066
4067  lvStacktraceData.Items.EndUpdate;
4068
4069  trace:=tstringlist.Create;
4070  getmem(s,FStacktraceSize);
4071  try
4072    readprocessmemory(processhandle, pointer(lastdebugcontext.Esp),s, FStacktraceSize,x);
4073    ce_stacktrace(lastdebugcontext.esp, lastdebugcontext.ebp, lastdebugcontext.eip, s,x, trace,false,Nonsystemmodulesonly1.checked or modulesonly1.Checked,Nonsystemmodulesonly1.checked,0);
4074
4075    for i:=0 to trace.count-1 do
4076    begin
4077      seperatestacktraceline(trace[i], address,bytes,details);
4078      li:=lvStacktrace.Items.Add;
4079      li.Caption:=address;
4080      li.SubItems.Add(bytes);
4081      li.SubItems.Add(details);
4082    end;
4083  finally
4084    freemem(s);
4085    trace.free;
4086  end;}
4087
4088end;
4089
4090procedure TMemoryBrowser.Maxstacktracesize1Click(Sender: TObject);
4091var
4092  s: string;
4093begin
4094  s:=inttostr(stacktraceSize);
4095  InputQuery('Stacktrace','New size:',s);
4096  try
4097    stacktraceSize:=strtoint(s);
4098    Maxstacktracesize1.Caption:='Max stacktrace size: '+inttostr(stacktracesize);
4099  except
4100  end;
4101end;
4102
4103procedure TMemoryBrowser.All1Click(Sender: TObject);
4104begin
4105  all1.checked:=true;
4106  Modulesonly1.Checked:=false;
4107  Nonsystemmodulesonly1.Checked:=false;
4108  stacktrace2.Checked:=false;
4109  reloadstacktrace;
4110end;
4111
4112procedure TMemoryBrowser.Modulesonly1Click(Sender: TObject);
4113begin
4114  all1.checked:=false;
4115  Modulesonly1.Checked:=true;
4116  Nonsystemmodulesonly1.Checked:=false;
4117  stacktrace2.Checked:=false;
4118  reloadstacktrace;
4119end;
4120
4121procedure TMemoryBrowser.Nonsystemmodulesonly1Click(Sender: TObject);
4122begin
4123  all1.checked:=false;
4124  Modulesonly1.Checked:=false;
4125  Nonsystemmodulesonly1.Checked:=true;
4126  stacktrace2.Checked:=false;
4127  reloadstacktrace;
4128end;
4129
4130procedure TMemoryBrowser.stacktrace2Click(Sender: TObject);
4131begin
4132  all1.checked:=false;
4133  Modulesonly1.Checked:=false;
4134  Nonsystemmodulesonly1.Checked:=false;
4135  stacktrace2.Checked:=true;
4136  reloadstacktrace;
4137end;
4138
4139procedure TMemoryBrowser.Referencedstrings1Click(Sender: TObject);
4140begin
4141  if (frmDissectCode=nil) or (frmDissectCode.dissectcode=nil) then
4142  begin
4143    if MessageDlg('You will need to run the dissect code routine first before this window is usable. Run it now?', mtConfirmation, [mbyes, mbno], 0)=mryes then
4144    begin
4145      Dissectcode1Click(sender);
4146      frmDissectCode.ondone:=odOpenReferedStringList;
4147      frmDissectCode.btnStart.click;
4148    end;
4149  end else
4150  begin
4151    if frmReferencedStrings=nil then
4152      frmReferencedStrings:=tfrmReferencedStrings.Create(self);
4153
4154    frmReferencedStrings.Show;
4155  end;
4156end;
4157
4158
4159function TMemoryBrowser.GetReturnaddress: dword;
4160var haserror: boolean;
4161begin
4162  result:=0;
4163
4164  //do a stacktrace and find the return address
4165  if frmstacktrace=nil then
4166    frmstacktrace:=tfrmstacktrace.create(self);
4167
4168  if frmStacktrace.ListView1.Items.Count>0 then
4169  begin
4170    result:=symhandler.getAddressFromName(frmStacktrace.ListView1.Items[0].SubItems[2], false,haserror);
4171    if haserror then result:=0;
4172  end;
4173
4174end;
4175
4176procedure TMemoryBrowser.Executetillreturn1Click(Sender: TObject);
4177var x: dword;
4178begin
4179  x:=getreturnaddress;
4180  if x>0 then
4181  begin
4182    disassemblerview.SelectedAddress:=x;
4183    Runtill1.Click;
4184  end else beep; //not possible
4185end;
4186
4187procedure TMemoryBrowser.lvStacktraceDataData(Sender: TObject; Item: TListItem);
4188var
4189  value,x: dword;
4190  a: dword;
4191  address,bytes,details: string;
4192  v: TVariableType;
4193begin
4194  if stacktrace2.checked then
4195  begin
4196    //show frmstacktrace
4197    if frmStacktrace=nil then
4198      frmstacktrace:=TfrmStacktrace.Create(self); //should never happen
4199
4200    if item.Index<frmStacktrace.ListView1.Items.Count then
4201    begin
4202      item.Caption:=frmStacktrace.ListView1.Items[item.index].SubItems[2]; //returnaddress
4203      item.SubItems.Add(frmStacktrace.ListView1.Items[item.index].SubItems[3]); //subitems address
4204    end;
4205  end
4206  else
4207  if all1.checked then
4208  begin
4209    //show for each dword what it is
4210    a:=lastdebugcontext.Esp+item.Index*4;
4211    item.Caption:=inttohex(a,8);
4212    if readprocessmemory(processhandle, pointer(a), @value, sizeof(value),x) then
4213    begin
4214      item.SubItems.Add(inttohex(value,8));
4215      v:=FindTypeOfData(a,@value,sizeof(value));
4216      case v of
4217        vtSingle:
4218          item.SubItems.Add(format('%.4f',[psingle(@value)^]));
4219
4220        vtPointer:
4221        begin
4222          item.SubItems.Add(symhandler.getNameFromAddress(value));
4223        end;
4224
4225        else
4226          item.SubItems.Add(inttostr(value));
4227
4228      end;
4229    end;
4230  end else
4231  begin
4232    //show strace
4233    if strace<>nil then
4234    begin
4235      if item.index<strace.count then
4236      begin
4237        seperatestacktraceline(strace[item.index], address,bytes,details);
4238        item.Caption:=address;
4239        item.SubItems.Add(bytes);
4240        item.SubItems.Add(details);
4241      end;
4242    end;
4243  end;
4244end;
4245
4246end.
Note: See TracBrowser for help on using the browser.