📄 memorybrowserformunit.pas.svn-base
字号:
repaintornot: boolean;
{$ifndef net}addresses: tdissectarray;{$endif}
symbol: PImagehlpSymbol;
sn: pchar;
ok: boolean;
x:dword;
y,z:string;
mi: TModuleInfo;
function truncatestring(s: string; maxwidth: integer): string;
var dotsize: integer;
begin
if disimage.Canvas.TextWidth(s)>maxwidth then
begin
dotsize:=disimage.Canvas.TextWidth('...');
maxwidth:=maxwidth-dotsize;
if maxwidth<=0 then
begin
result:=''; //it's too small for '...'
exit;
end;
while disimage.Canvas.TextWidth(s)>maxwidth do
s:=copy(s,1,length(s)-1);
result:=s+'...';
end else result:=s; //it fits
end;
procedure addline(i:integer);
var j: integer;
offset: integer;
begin
rct.Top:=i*(textheight+2);
rct.Bottom:=rct.top+textheight+2;
{$ifndef net}
if (dselected2<>$ffffffff) then
begin
//check if this falls in the selected region
offset:=integer(dselected2-dselected);
if ((offset>0) and (address<=dselected2) and (address>=dselected)) or
((offset<0) and (address>=dselected2) and (address<=dselected)) then
begin
disimage.Canvas.Brush.Color:=clGradientActiveCaption;
disimage.Canvas.font.Color:=clBlack;
end;
end;
if (debuggerthread2<>nil) and (address<>0) then
begin
for j:=0 to 3 do
if address=debuggerthread2.breakpoints[j] then
begin
disimage.Canvas.Brush.Color:=clRed;
disimage.Canvas.font.Color:=clBlack;
break; //get out of this for loop
end;
end;
if (debuggerthread<>nil) and (debuggerthread.userisdebugging) then
begin
for j:=0 to length(debuggerthread.userbreakpoints)-1 do
if address=debuggerthread.userbreakpoints[j] then
begin
disimage.Canvas.Brush.Color:=clRed;
disimage.Canvas.font.Color:=clBlack;
break; //get out of this for loop
end;
for j:=0 to length(debuggerthread.int3userbreakpoints)-1 do
if address=debuggerthread.int3userbreakpoints[j].address then
begin
disimage.Canvas.Brush.Color:=clRed;
disimage.Canvas.font.Color:=clBlack;
break; //get out of this for loop
end;
end;
{$endif}
if dselected=address then
begin
disimage.Canvas.Brush.Color:=clHighlight;
disimage.Canvas.font.Color:=clHighlightText;
{$ifndef net}
if (debuggerthread2<>nil) and (address<>0) then
begin
for j:=0 to 3 do
if address=debuggerthread2.breakpoints[j] then
begin
disimage.Canvas.Brush.Color:=clGreen;
disimage.Canvas.font.Color:=clWhite;
break; //get out of this for loop
end;
end;
if debuggerthread<>nil then
begin
for j:=0 to length(debuggerthread.userbreakpoints)-1 do
if address=debuggerthread.userbreakpoints[j] then
begin
disimage.Canvas.Brush.Color:=clGreen;
disimage.Canvas.font.Color:=clWhite;
break; //get out of this for loop
end;
for j:=0 to length(debuggerthread.int3userbreakpoints)-1 do
if address=debuggerthread.int3userbreakpoints[j].address then
begin
disimage.Canvas.Brush.Color:=clGreen;
disimage.Canvas.font.Color:=clWhite;
break; //get out of this for loop
end;
end;
{$endif}
if PANEL6.caption<>disassemblerlines[i].description then panel6.Caption:=disassemblerlines[i].description;
end;
disimage.Canvas.FillRect(rct);
addressstring:=truncatestring(addressstring,disassemblerheader.Sections[0].width);
bytesstring:=truncatestring(bytesstring,disassemblerheader.Sections[1].width);
opcodestring:=truncatestring(opcodestring,disassemblerheader.Sections[2].width);
specialstring:=truncatestring(specialstring,disassemblerheader.Sections[3].width);
disimage.Canvas.TextOut(0,i*(textHeight+2),addressstring);
disimage.Canvas.TextOut(disassemblerheader.Sections[1].left,i*(textHeight+2),bytesstring);
disimage.Canvas.TextOut(disassemblerheader.Sections[2].left,i*(textHeight+2),opcodestring);
disimage.Canvas.TextOut(disassemblerheader.Sections[3].left,i*(textHeight+2),specialstring);
disimage.Canvas.Brush.color:=clBtnFace;
disimage.Canvas.font.color:=clWindowText;
disassemblerlines[i].disassembled:=disassembled;
disassemblerlines[i].address:=address;
disassemblerlines[i].addresspart:=addressstring;
disassemblerlines[i].bytespart:=bytesstring;
disassemblerlines[i].opcodepart:=opcodestring;
disassemblerlines[i].specialpart:=specialstring;
end;
begin
if not disassembler then exit;
try
try
getmem(symbol,sizeof(_Imagehlp_symbol)+100);
symbol.SizeOfStruct:=sizeof(_Imagehlp_symbol)+100;
symbol.MaxNameLength:=100;
if not symhandler.isloaded then
label1.Caption:='Symbols are being loaded'
else
begin
label1.Caption:=symhandler.getnamefromaddress(disassembleraddress);
end;
rct.Left:=0;
rct.Right:=discanvas.Width;
disimage.Width:=0;
disimage.width:=discanvas.Width;
disimage.Height:=discanvas.Height;
DisCanvas.Canvas.Font:=DisImage.Canvas.Font;
lines:=(Discanvas.Height) div (textheight+2);
if numberofaddresses<>lines then
begin
setlength(disassemblerlines,0); //freemem
setlength(disassemblerlines,lines+1);
end;
numberofaddresses:=lines;
maddress:=disassembleraddress;
i:=0;
while i<=lines do
begin
ok:=false;
if SymGetSymFromAddr(processhandle,maddress,0,symbol^) then
begin
if symbol.Address=maddress then
begin
if ((i>0) and (disassemblerlines[i-1].address<>maddress)) then
begin
disassemblerlines[i].description:='';
disassembled:=pchar(@symbol.Name[0]);
addresS:=maddress;
ok:=true;
addline(i);
inc(i);
continue;
end;
end;
end;
{$ifndef net}
if dissectcode<>nil then
begin
setlength(addresses,0);
if dissectcode.checkaddress(maddress,addresses) then
begin
disassembled:='Referenced by ';
for k:=0 to length(addresses)-1 do
begin
if i>lines then break;
disassemblerlines[i].description:='';
x:=addresses[k].address;
for j:=0 to dissectcode.accuracy-1 do
x:=previousopcode(x);
for j:=0 to dissectcode.accuracy-1 do
disassemble(x);
if x=addresses[k].address then
begin
if disassembled[length(disassembled)]=')' then disassembled:=disassembled+', ';
case addresses[k].jumptype of
jtUnconditional: disassembled:=disassembled+inttohex(addresses[k].address,8)+'(U)';
jtConditional: disassembled:=disassembled+inttohex(addresses[k].address,8)+'(C)';
jtCall: disassembled:=disassembled+inttohex(addresses[k].address,8)+'(Call)';
end;
if length(disassembled)>50 then
begin
//disassembled:=disassembled+
address:=maddress;
addline(i);
inc(i);
disassembled:='Referenced by ';
end;
end;
end;
if disassembled<>'Referenced by ' then
begin
addresS:=maddress;
addline(i);
inc(i);
end;
if i<=lines then
begin
disassembled:=translatestring(disassemble(maddress,disassemblerlines[i].description),bytestoshow-1, showvalues, addressstring, bytesstring, opcodestring, specialstring);
addline(i);
inc(i);
end;
setlength(addresses,0);
continue;
end;
end;
{$endif}
if not ok then
begin
address:=maddress;
disassembled:=translatestring(disassemble(maddress,disassemblerlines[i].description),bytestoshow-1, showvalues, addressstring, bytesstring, opcodestring, specialstring);
if Showmoduleaddresses1.Checked then
begin
//replace the address part with a modulename+offset when possible
if symhandler.getmodulebyaddress(address,mi) then
begin
y:=inttohex(address,8);
z:=mi.modulename+'+'+inttohex(address-mi.baseaddress,4);
//disassembled:=stringreplace(disassembled,y,z,[rfReplaceAll]);
opcodestring:=stringreplace(opcodestring,y,z,[rfReplaceAll]);
addressstring:=stringreplace(addressstring,y,z,[rfReplaceAll]);
end;
end;
end;
addline(i);
inc(i);
end;
rct.Top:=0;
rct.Bottom:=disimage.Height;
discanvas.Canvas.CopyRect(rct,disimage.Canvas,rct);
finally
freemem(symbol);
end;
except
;//
end;
end;
procedure TMemoryBrowser.DisCanvasPaint(Sender: TObject);
var cr: Trect;
begin
cr:=discanvas.Canvas.ClipRect;
discanvas.Canvas.CopyRect(cr,disimage.Canvas,cr);
end;
procedure TMemoryBrowser.DisCanvasMouseDown(Sender: TObject;
Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
var i,j,line: integer;
rct: trect;
disassembled: string;
begin
if button=mbleft then
begin
if (not (ssShift in shift)) then
dselected2:=$ffffffff
else
if dselected2=$ffffffff then
dselected2:=dselected; //dslected 2 now contains the start
end;
if not fcontrol1.Focused then fcontrol1.SetFocus;
discanvas.Canvas.font.Name:='Courier';
disimage.Canvas.Font.Name:='Courier';
line:=y div (textheight+2);
if (line<0) or (line>=length(disassemblerlines)) then exit; //mouse drag overflow
if disassemblerlines[line].address<>dselected then
begin
if panel6.caption<>disassemblerlines[line].description then panel6.caption:=disassemblerlines[line].description;
if (disassembleraddress+line)>$FFFFFFFF then exit;
{ for i:=0 to numberofaddresses do
begin
if disassemblerlines[i].address=dselected then
begin
{$ifndef net}
{ if (debuggerthread2<>nil) and (disassemblerlines[i].address<>0) then
begin
for j:=0 to 3 do
if disassemblerlines[i].address=debuggerthread2.breakpoints[j] then
begin
disimage.Canvas.Brush.Color:=clRed;
discanvas.Canvas.Brush.Color:=clRed;
disimage.Canvas.font.Color:=clBlack;
discanvas.Canvas.font.Color:=clBlack;
break; //get out of this for loop
end;
end; }
{if (debuggerthread<>nil) and (debuggerthread.userisdebugging) then
begin
for j:=0 to length(debuggerthread.userbreakpoints)-1 do
if disassemblerlines[i].address=debuggerthread.userbreakpoints[j] then
begin
disimage.Canvas.Brush.Color:=clRed;
discanvas.Canvas.Brush.Color:=clRed;
disimage.Canvas.font.Color:=clBlack;
discanvas.Canvas.font.Color:=clBlack;
break; //get out of this for loop
end;
for j:=0 to length(debuggerthread.int3userbreakpoints)-1 do
if disassemblerlines[i].address=debuggerthread.int3userbreakpoints[j].address then
begin
disimage.Canvas.Brush.Color:=clRed;
discanvas.Canvas.Brush.Color:=clRed;
disimage.Canvas.font.Color:=clBlack;
discanvas.Canvas.font.Color:=clBlack;
break; //get out of this for loop
end;
end;
{$endif}
{
rct.Left:=0;
rct.Right:=discanvas.Width;
rct.Top:=i*(textheight+2);
rct.Bottom:=rct.top+textheight+1;
discanvas.Canvas.FillRect(rct);
disimage.Canvas.FillRect(rct);
discanvas.Canvas.TextOut(8,i*(textHeight+2),disassemblerlines[i].disassembled);
disimage.Canvas.TextOut(8,i*(textHeight+2),disassemblerlines[i].disassembled);
discanvas.Canvas.font.color:=clWindowText;
disimage.Canvas.font.Color:=clWindowText;
discanvas.Canvas.Brush.color:=clBtnFace;
disimage.Canvas.Brush.color:=clBtnFace; }
{
break;
end;
end;
}
//if it isn't found it propably has already been overwritten (and a big bug btw...)
dselected:=disassemblerlines[line].address;
{discanvas.Canvas.Brush.Color:=Highlightcolor;
disimage.Canvas.Brush.Color:=Highlightcolor;
discanvas.Canvas.font.color:=clHighlightText;
disimage.Canvas.font.Color:=clHighlightText;
rct.Left:=0;
rct.Right:=discanvas.Width;
rct.Top:=line*(textheight+2);
rct.Bottom:=rct.top+textheight+1; }
{$ifndef net}
{if (debuggerthread2<>nil) and (disassemblerlines[i].address<>0) then
begin
for j:=0 to 3 do
if disassemblerlines[line].address=debuggerthread2.breakpoints[j] then
begin
disimage.Canvas.Brush.Color:=clRed;
discanvas.Canvas.Brush.Color:=clRed;
disimage.Canvas.font.Color:=clBlack;
discanvas.Canvas.font.Color:=clBlack;
break; //get out of this for loop
end;
end; }
{
if (debuggerthread<>nil) and (debuggerthread.userisdebugging) then
begin
for j:=0 to length(debuggerthread.userbreakpoints)-1 do
if disassemblerlines[line].address=debuggerthread.userbreakpoints[j] then
begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -