📄 mainunit.pas
字号:
i: integer;
tmp:byte;
rD:dword;
resourcestring strOpcodeRead='The following opcodes read from the selected address';
begin
readprocessmemory(processhandle,pointer(address),@tmp,1,rd);
if rd<>1 then raise exception.Create(strAddressHasToBeReadable);
if foundcodedialog<>nil then raise exception.Create('The debugger is already trying to find out what reads,writes or accesses a certain address. First close the other window');
foundcodedialog:=TFoundcodedialog.create(self);
foundcodedialog.Caption:=strOpcodeRead;
foundcodedialog.useexceptions:=true;
foundcodedialog.btnOK.caption:=strStop;
virtualqueryEx(processhandle,pointer(address),mbi,sizeof(mbi));
debugger.DebuggerThread.findreader.pagebase:=dword(mbi.BaseAddress);
debugger.DebuggerThread.findreader.pagesize:=dword(mbi.RegionSize);
debugger.DebuggerThread.findreader.Address:=address;
debugger.DebuggerThread.findreader.size:=size;
DebuggerThread.findreaderset:=true;
VirtualProtectEx(processhandle,pointer(address),size,PAGE_NOACCESS,debugger.DebuggerThread.findreader.originalprotection);
foundcodedialog.show;
end;
procedure TMainform.SetWriteBreakpoint(address: dword; size: dword);
var mbi: _Memory_Basic_Information;
i: integer;
ct: _context;
regsinuse: integer;
olda,olds: dword;
dr: dword;
procedure Set4bytebreak;
begin
case regsinuse of
0: begin
ct.dr0:=address;
ct.dr7:=ct.dr7 or reg0set or reg0w or debugexact or reg0len4;
end;
1: begin
ct.dr1:=address;
ct.dr7:=ct.Dr7 or reg1set or reg1w or debugexact or reg1len4;
end;
2: begin
ct.Dr2:=address;
ct.dr7:=ct.dr7 or reg2set or reg2w or debugexact or reg2len4;
end;
3: begin
ct.Dr3:=address;
ct.dr7:=ct.dr7 or reg3set or reg3w or debugexact or reg3len4;
end;
end;
inc(address,4);
dec(size,4);
inc(regsinuse);
end;
procedure Set2bytebreak;
begin
case regsinuse of
0: begin
ct.dr0:=address;
ct.dr7:=ct.dr7 or reg0set or reg0w or debugexact or reg0len2;
end;
1: begin
ct.dr1:=address;
ct.dr7:=ct.Dr7 or reg1set or reg1w or debugexact or reg1len2;
end;
2: begin
ct.Dr2:=address;
ct.dr7:=ct.dr7 or reg2set or reg2w or debugexact or reg2len2;
end;
3: begin
ct.Dr3:=address;
ct.dr7:=ct.dr7 or reg3set or reg3w or debugexact or reg3len2;
end;
end;
inc(address,2);
dec(size,2);
inc(regsinuse);
end;
procedure Set1bytebreak;
begin
case regsinuse of
0: begin
ct.dr0:=address;
ct.dr7:=ct.dr7 or reg0set or reg0w or debugexact;
end;
1: begin
ct.dr1:=address;
ct.dr7:=ct.Dr7 or reg1set or reg1w or debugexact;
end;
2: begin
ct.Dr2:=address;
ct.dr7:=ct.dr7 or reg2set or reg2w or debugexact;
end;
3: begin
ct.Dr3:=address;
ct.dr7:=ct.dr7 or reg3set or reg3w or debugexact;
end;
end;
inc(address);
dec(size);
inc(regsinuse);
end;
var rd: dword;
tmp: byte;
resourcestring strOpcodeChanged='The following opcodes changed the selected address';
begin
//check if you can read address to address+size
if not (formsettings.rbDebugRegisters.checked or formsettings.cbKDebug.checked) then
begin
readprocessmemory(processhandle,pointer(address),@tmp,1,rd);
if rd<>1 then raise exception.Create(strAddressHasToBeReadable);
end;
if foundcodedialog<>nil then raise exception.Create('The debugger is already trying to find out what reads,writes or accesses a certain address. First close the other window');
if debuggerthread2<>nil then raise exception.create('Please stop any other debugger option before enabling this option');
foundcodedialog:=TFoundcodedialog.create(self);
foundcodedialog.Caption:=strOpcodeChanged;
foundcodedialog.btnOK.caption:=strstop;
if formsettings.cbKdebug.checked and (debuggerthread=nil) then
if not DebugProcess(processid,address,size,2) then raise exception.Create(strFailedToInitialize);
olda:=address;
olds:=size;
zeromemory(@ct,sizeof(ct));
ct.ContextFlags:=CONTEXT_DEBUG_REGISTERS;
if formsettings.rbDebugRegisters.checked then
begin
foundcodedialog.useexceptions:=false;
regsinuse:=0;
ct.dr7:=0;
while (regsinuse<4) and (size>0) do
begin
if size>=4 then
begin
if (address mod 4)>0 then
begin
if (address mod 2)>0 then
begin
set1bytebreak; //watch on a byte
continue;
end
else
begin
set2bytebreak;
continue;
end;
end
else
begin
set4bytebreak;
continue;
end;
end;
if size>=2 then
begin
if (address mod 2)>0 then
begin
set1bytebreak; //watch on a byte
continue;
end
else
begin
set2bytebreak;
continue;
end;
end;
if size=1 then
set1bytebreak;
end;
// ct.dr7:=$D0303;
if formsettings.cbKdebug.Checked and (debuggerthread=nil) then
begin
DebuggerThread2:=TDebugEvents.Create(true);
debuggerthread2.debugregs:=ct;
for i:=0 to length(debuggerthread2.threadlist)-1 do
begin
suspendthread(debuggerthread2.threadlist[i]);
SetThreadContext(debuggerthread2.threadlist[i],debuggerthread2.debugregs);
resumethread(debuggerthread2.threadlist[i]);
end;
debuggerthread2.Resume;
end
else
begin
debuggerthread.DRRegs:=ct;
debuggerthread.Suspend;
for i:=0 to length(debuggerthread.threadlist)-1 do
begin
suspendthread(debuggerthread.threadlist[i][1]);
SetThreadContext(debuggerthread.threadlist[i][1],debuggerthread.DRRegs);
resumethread(debuggerthread.threadlist[i][1]);
end;
debuggerthread.FindWriter2:=true;
debuggerthread.Resume;
end;
end
else
begin
foundcodedialog.useexceptions:=true;
virtualqueryEx(processhandle,pointer(olda),mbi,sizeof(mbi));
debugger.DebuggerThread.readonly.pagebase:=dword(mbi.BaseAddress);
debugger.DebuggerThread.readonly.pagesize:=dword(mbi.RegionSize);
debugger.DebuggerThread.readonly.Address:=olda;
debugger.DebuggerThread.readonly.size:=olds;
DebuggerThread.readonlyset:=true;
VirtualProtectEx(processhandle,pointer(olda),olds,PAGE_EXECUTE_READ,debugger.DebuggerThread.readonly.originalprotection);
end;
foundcodedialog.show;
end;
procedure TMainform.Deletegroups(groups: grouptype);
var i: integer;
begin
for i:=0 to numberofrecords-1 do
begin
if groups[1] and (memrec[i].Group=1) then selected[i]:=true else
if groups[2] and (memrec[i].Group=2) then selected[i]:=true else
if groups[3] and (memrec[i].Group=3) then selected[i]:=true else
if groups[4] and (memrec[i].Group=4) then selected[i]:=true else
if groups[5] and (memrec[i].Group=5) then selected[i]:=true else
if groups[6] and (memrec[i].Group=6) then selected[i]:=true else
selected[i]:=false;
end;
deleterecords;
end;
procedure TMainForm.DeleteRecords;
var i,j: Integer;
begin
i:=0;
while i<numberofrecords do
begin
if selected[i] then
begin
unregisterhotkey(handle,hotkeys[i]);
hotkeys[i]:=-1;
setlength(frozenbytes[i],0);
for j:=i to numberofrecords-2 do
begin
memrec[j]:=memrec[j+1];
frozenfvalue[j]:=frozenfvalue[j+1];
frozenstrings[j]:=frozenstrings[j+1];
frozenbytes[j]:=frozenbytes[j+1];
selected[j]:=selected[j+1];
hotkeystrings[j]:=hotkeystrings[j+1];
hotkeys[j]:=hotkeys[j+1];
end;
dec(numberofrecords);
dec(i);
reservemem;
if firstshiftselected>numberofrecords-1 then firstshiftselected:=-1;
end;
inc(i);
end;
If lastselected>numberofrecords-1 then lastselected:=numberofrecords-1;
if lastselected>-1 then selected[lastselected]:=true;
Updatescreen;
Updatelist;
end;
Procedure TMainForm.UpdateScreen;
var rec,i,j: Integer;
temp:string;
col: tcolor;
realaddress,realaddress2,count:dword;
error: boolean;
check: boolean;
resourcestring
strAllowNegative='Allow negative changes';
strAllowPositive='Allow positive changes';
strNormalFreeze='Don''t allow any change';
begin
if numberofrecords>=numberoflines then
begin
if not scrollbar1.Enabled then
scrollbar1.enabled:=true;
if scrollbar1.max<>numberofrecords-1 then
scrollbar1.max:=numberofrecords-1;
if scrollbar1.PageSize<>scrollbar1.PageSize then
scrollbar1.pagesize:=numberoflines-1;
if scrollbar1.LargeChange<>numberoflines-1 then
scrollbar1.LargeChange:=numberoflines-1;
end else
begin
if scrollbar1.Enabled then
scrollbar1.enabled:=false;
if scrollbar1.Position<>0 then
scrollbar1.position:=0;
end;
for i:=0 to numberoflines-1 do
begin
rec:=scrollbar1.Position+i;
if rec<numberofrecords then
begin
if ((memrec[rec].Frozen) or (hotkeys[rec]<>-1)) and (memrec[rec].VarType in [0,1,2,3,4,6]) then
begin
case memrec[rec].Frozendirection of
0:
begin
col:=clBlue;
temp:='=';
end;
1:
begin
temp:='-';
col:=clRed;
end;
2:
begin
temp:='+';
col:=clGreen;
end;
end;
if selected[rec] then col:=ClWhite;
if freezedirection[i].Font.Color<>col then
freezedirection[i].Font.Color:=col;
if temp<>freezedirection[i].Caption then
begin
freezedirection[i].Caption:=temp;
if temp='-' then freezedirection[i].Hint:=strAllowNegative;//'Allow negative changes';
if temp='+' then freezedirection[i].Hint:=strAllowPositive;//'Allow positive changes';
if temp='=' then freezedirection[i].Hint:=strNormalFreeze; //'Don''t allow any change';
freezedirection[i].ShowHint:=true;
end;
freezedirection[i].visible:=true;
end
else
begin
freezedirection[i].visible:=false;
end;
frozenbox[i].checked:=memrec[rec].Frozen;
if hotkeys[rec]<>-1 then
frozenbox[i].Enabled:=false
else
frozenbox[i].Enabled:=true;
description[i].Caption:=memrec[rec].Description;
if memrec[rec].IsPointer then
begin
error:=false;
//find the real address
realaddress2:=memrec[rec].pointers[length(memrec[rec].pointers)-1].Address;
for j:=length(memrec[rec].pointers)-1 downto 0 do
begin
check:=(readprocessmemory(processhandle,pointer(realaddress2),@realaddress,4,count));
if check and (count=4) then
realaddress2:=realaddress+memrec[rec].pointers[j].offset
else
begin
error:=true;
break;
end;
end;
realaddress:=realaddress2;
if not error then
address[i].Caption:='P->'+IntToHex(realaddress,8)
else
address[i].Caption:='P->????????';
end
else
address[i].caption:=IntTohex(memrec[rec].address,8);
// if not frozenbox[i].visible then //if it's not yet visible, make it visible
begin
frozenbox[i].visible:=true;
description[i].visible:=true;
if memrec[rec].VarType<>255 then
begin
address[i].visible:=true;
valtype[i].visible:=true;
value[i].visible:=true;
end
else
begin
address[i].visible:=false;
valtype[i].visible:=false;
value[i].visible:=false;
end;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -