📄 asmshow.pas
字号:
unit ASMShow;
//////////////////////////
// Last Change: 4-11-2001
//////////////////////////
interface
uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ExtCtrls, Buttons, ComCtrls, ImgList, Menus, DeDe_SDK, Placemnt;
type
TASMShowForm = class(TForm)
Panel1: TPanel;
MainPanel: TPanel;
ASMList: TListBox;
PrevBtn: TSpeedButton;
NextBtn: TSpeedButton;
ProcCB: TComboBox;
ProcRVA: TComboBox;
Panel3: TPanel;
Splitter1: TSplitter;
ProcTree: TTreeView;
ImageList1: TImageList;
CopyBtn: TSpeedButton;
FindTxtBtn: TSpeedButton;
FindDlg: TFindDialog;
DoubleRightClickTimer: TTimer;
MainMenu1: TMainMenu;
Navigation1: TMenuItem;
Next1: TMenuItem;
Previous1: TMenuItem;
N1: TMenuItem;
Disassemble1: TMenuItem;
N2: TMenuItem;
Close1: TMenuItem;
Edit1: TMenuItem;
Copy1: TMenuItem;
SelectAll1: TMenuItem;
N3: TMenuItem;
FindText1: TMenuItem;
miPlugins: TMenuItem;
N4: TMenuItem;
ChangeFont1: TMenuItem;
FontDlg: TFontDialog;
A1: TMenuItem;
SBar: TStatusBar;
PopupMenu1: TPopupMenu;
Copy2: TMenuItem;
FP: TFormPlacement;
VarsPanel: TPanel;
Splitter2: TSplitter;
CommentBtn: TSpeedButton;
VarBtn: TSpeedButton;
PageControl1: TPageControl;
TabSheet1: TTabSheet;
TabSheet2: TTabSheet;
VarLV: TListView;
GroupBox1: TGroupBox;
LocRB: TRadioButton;
GlobRB: TRadioButton;
InitRegGrp: TGroupBox;
Label1: TLabel;
Label2: TLabel;
edxEdit: TEdit;
eaxEdit: TEdit;
Label3: TLabel;
ecxEdit: TEdit;
Label4: TLabel;
ebxEdit: TEdit;
Label6: TLabel;
Label5: TLabel;
esiEdit: TEdit;
ediEdit: TEdit;
SaveBtn: TSpeedButton;
LoadBtn: TSpeedButton;
OpenDlg: TOpenDialog;
TabSheet3: TTabSheet;
ListBox1: TListBox;
SaveDlg: TSaveDialog;
procedure ASMListDblClick(Sender: TObject);
procedure PrevBtnClick(Sender: TObject);
procedure ProcCBChange(Sender: TObject);
procedure NextBtnClick(Sender: TObject);
procedure ProcTreeChange(Sender: TObject; Node: TTreeNode);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure ProcTreeClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure CopyBtnClick(Sender: TObject);
procedure ASMListDrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
procedure FindTxtBtnClick(Sender: TObject);
procedure ASMListMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure DoubleRightClickTimerTimer(Sender: TObject);
procedure Close1Click(Sender: TObject);
procedure SelectAll1Click(Sender: TObject);
procedure FindDlgFind(Sender: TObject);
procedure miPluginsClick(Sender: TObject);
procedure Disassemble1Click(Sender: TObject);
procedure ChangeFont1Click(Sender: TObject);
procedure ASMListKeyPress(Sender: TObject; var Key: Char);
procedure A1Click(Sender: TObject);
procedure ASMListClick(Sender: TObject);
procedure CommentBtnClick(Sender: TObject);
procedure LocRBClick(Sender: TObject);
procedure GlobRBClick(Sender: TObject);
procedure VarLVDblClick(Sender: TObject);
procedure VarBtnClick(Sender: TObject);
procedure ASMListKeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
procedure eaxEditKeyPress(Sender: TObject; var Key: Char);
procedure SaveBtnClick(Sender: TObject);
procedure LoadBtnClick(Sender: TObject);
private
{ Private declarations }
DASMListings : TList;
DASMIndex : TStringList;
DASMInitEmulData : TStringList;
FbDRCH : Boolean;
FsTextToFind, FsAdvMore, FsAdvRegs : String;
procedure ClearDASMListings;
Function OffsetInSameProc(sOffs : String) : Boolean;
Procedure _GotoLine(sOffs : String; bSaveJump : Boolean = True); overload;
Procedure _GotoLine(wLine : LongInt; bSaveJump : Boolean = True); overload;
Procedure PlugInClick(Sender : TObject);
Procedure ShowDSFPattern(rva : String);
public
{ Public declarations }
procedure SelectNode;
function GetNodeWithCaption(sCap : String) : TTreeNode;
procedure HandleDoubleRightClick;
procedure UpdatePlugInData;
procedure InitEmul;
procedure InitEmulationUsingRegisterString(sRegStr : String; sMoreOptions : String);
procedure EditASMComment(rva : Longint);
procedure SetEmulParams(sData : String);
end;
var
ASMShowForm: TASMShowForm;
Function _GetCallReference(dwVirtOffset : DWORD; var sReference : String; var btRefType : Byte; btMode : Byte = 0) : Boolean;
Function _GetObjectName(dwVirtOffset : DWORD; var sObjName : String) : Boolean;
Function _GetFieldReference(dwVirtOffset : DWORD; var sReference : String) : Boolean;
Function GetCurrFirstRVA : String;
procedure AddCommentsToListing(aDasmList : TStringList; ProcRVA : DWORD);
implementation
{$R *.DFM}
Uses DeDeDisASM, HEXTools, ClipBrd, DeDeClassEmulator,
MainUnit, ShowPluginUnit, DeDeConstants, DeDeClasses, DeDeSym, DeDeReg,
DeDeExpressions,
// [ LC ]
DeDeEditText, Asm2Pas, EditExprUnit, DeDeDUF;
var wLineNum : LongInt;
LastColor: DWORD;
sLastJumpRva : LongInt;
FbShowDSFPattern : Boolean;
Procedure TruncAll(Var s : String);
Begin
While Copy(s,1,1)=' ' Do s:=Copy(s,2,Length(s)-1);
While Copy(s,Length(s),1)=' ' Do s:=Copy(s,1,Length(s)-1);
End;
Function GetCurrFirstRVA : String;
var i{, j} : Integer;
Begin
With ASMShowForm.ASMList Do
Begin
For i:=0 to Items.Count-1 Do
begin
Result:=Copy(Items[i],1,8);
if Length(Result)<>8 then continue;
//Skip commented lines
If Pos(Result[1],'1234567890ABCDEF')=0 then continue;
if not IsInSection(HEX2DWORD(Result),'CODE') then continue;
break;
end;
End;
End;
procedure AddCommentsToListing(aDasmList : TStringList; ProcRVA : DWORD);
var
cmt, s, q, vars : string;
i, j, k , l: integer;
RVA : longword;
procedure a;
begin
cmt := '';
if Copy(s, 9, 2) = ' ' then begin
RVA := HEX2DWORD(Copy(s, 1, 8));
GetComment(RVA, k, cmt);
end; { if }
end;
begin
for i:=0 to aDasmList.Count-1 do begin
s := aDasmList[i];
j := Pos(#13#10, s);
while j <> 0 do begin
a;
q := Copy(s, 1, j - 1);
k := Pos('{ ', q);
if k > 0 then q := Trim(Copy(q, 1, k - 1));
// Seek variables
vars:='';
for l:=0 to ExpressionCount-1 do
if (Expressions[l].RVA=ProcRVA) or (Expressions[l].RVA=0) then
if (Expressions[l].Comment<>'') and (Pos(Expressions[l].Name,q)<>0)
then vars:=Expressions[l].Comment+'; '+vars;
if Trim(cmt) <> '' then
ASMShowForm.ASMList.Items.Add(q+' { '+vars+cmt+' } ')
else
if vars<>'' then ASMShowForm.ASMList.Items.Add(q+' { '+vars+' } ')
else ASMShowForm.ASMList.Items.Add(q);
s := Copy(s, j + 2, Length(s) - j);
j := Pos(#13#10, s);
end; { while }
a;
k := Pos('{ ', s);
if k > 0 then s := Trim(Copy(s, 1, k - 1));
// Seek variables
vars:='';
for l:=0 to ExpressionCount-1 do
if (Expressions[l].RVA=ProcRVA)or (Expressions[l].RVA=0) then
if (Expressions[l].Comment<>'') and (Pos(Expressions[l].Name,s)<>0)
then vars:=Expressions[l].Comment+'; '+vars;
if Trim(cmt) <> '' then
ASMShowForm.ASMList.Items.Add(s +' { '+vars+cmt+' } ')
else
if vars<>'' then ASMShowForm.ASMList.Items.Add(s+' { '+vars+' } ')
else ASMShowForm.ASMList.Items.Add(s);
end; { for }
ASMShowForm.LocRBClick(ASMShowForm);
end;
procedure DisAsm(s : String; bBack : Boolean = True);
var
ss, sEmulResult : String;
DasmList : TStringList;
i : Integer;
begin
if bBack then begin
i:=ASMShowForm.DASMIndex.IndexOf(s);
if i=-1 then bBack:=False
else begin
DasmList:=TStringList(ASMShowForm.DASMListings[i]);
ASMShowForm.SetEmulParams(ASMShowForm.DASMInitEmulData[i]);
ASMShowForm.InitRegGrp.Tag:=i;
end;
end; { if }
if not bBack then begin
////////////////////////////////////////////////////////////////////////////////////
// Emulate the last procedure till the new call in order to init registers
// for the new emulation properly
ss:=DWORD2HEX(RVAConverter.GetPhys(HEX2DWORD(GetCurrFirstRVA)));
PEStream.Seek(HEX2DWORD(ss),soFromBeginning);
// Initialize emulation of the previous proc from the saved
// in DASMInitEmulData register data string
GlobCustomEmulInit:=True;
i:=ASMShowForm.DASMIndex.IndexOf(GetCurrFirstRVA);
if i<>-1 then
begin
sEmulResult:=ASMShowForm.DASMInitEmulData[i];
ASMShowForm.InitEmulationUsingRegisterString(sEmulResult,sEmulResult+',TTL=100');
end;
// Emulate to the RVA from where our new proc is called
DisassembleProc('','',DasmList,False,True,True,HEX2DWORD(ASMShowForm.ASMList.Items[ASMShowForm.ASMList.Itemindex]));
// Prepare the emulation resulting register data string for later use
sEmulResult:=Format('EAX=%s,ECX=%s,EDX=%s,EBX=%s,ESI=%s,EDI=%s',
[GetRegVal(rgEAX),GetRegVal(rgECX),GetRegVal(rgEDX),GetRegVal(rgEBX),GetRegVal(rgESI),GetRegVal(rgEDI)]);
// And clear the stack
DeDeClassEmulator.ClearStack;
//
/////////////////////////////////////////////////////////////////////////////////////
ss:=DWORD2HEX(RVAConverter.GetPhys(HEX2DWORD(s)));
If RVAConverter.GetPhys(HEX2DWORD(s))>PEStream.Size Then Exit;
PEStream.Seek(HEX2DWORD(ss),soFromBeginning);
DisassembleProc('','',DasmList,False,True);
GlobCustomEmulInit:=False;
// Add disassembly listing RVA/Name
ASMShowForm.DASMIndex.Add(s);
// Add Initial Emulation Values String
ASMShowForm.DASMInitEmulData.Add(sEmulResult);
ASMShowForm.SetEmulParams(sEmulResult);
ASMShowForm.InitRegGrp.Tag:=ASMShowForm.DASMInitEmulData.Count-1;
end; { if }
ASMShowForm.ASMList.Items.BeginUpdate;
ASMShowForm.ASMList.Clear;
ASMShowForm.Caption:='Proc_'+s;
AddCommentsToListing(DasmList,HEX2DWORD(s));
ASMShowForm.ASMList.Items.EndUpdate;
If (bBack) and (wLineNum>0) Then begin
SendMessage(ASMShowForm.ASMList.Handle,WM_VSCROLL,MakeLong(SB_THUMBPOSITION,wLineNum div MaxWord),0);
ASMShowForm.ASMList.ItemIndex:=Word(wLineNum);
ASMShowForm.ASMList.Selected[Word(wLineNum)]:=True;
end; { if }
ASMShowForm.ASMList.SetFocus;
// Instead of Freeing Disaasembly Result String List (DasmList.Free)
// It is added in DASMListings TList. Will be freed OnFormClose
if not bBack then ASMShowForm.DASMListings.Add(DasmList);
end;
procedure TASMShowForm.Disassemble1Click(Sender: TObject);
var
ss, s, sEmulResult : String;
DasmList : TStringList;
i, idx : Integer;
begin
s:=Copy(ASMList.Items[0],1,8);
idx:=ASMShowForm.DASMIndex.IndexOf(s);
if idx=-1 then exit;
ss:=DWORD2HEX(RVAConverter.GetPhys(HEX2DWORD(s)));
If RVAConverter.GetPhys(HEX2DWORD(s))>PEStream.Size Then Exit;
PEStream.Seek(HEX2DWORD(ss),soFromBeginning);
// Initialize emulation of the previous proc from the saved
// in DASMInitEmulData register data string
//GlobCustomEmulInit:=True;
// ITS NOT NEEDED ANY MORE BECASUE EMULO STTINGS ARE LOADED FROM InitEmul
{ i:=ASMShowForm.DASMIndex.IndexOf(GetCurrFirstRVA);
if i<>-1 then
begin
sEmulResult:=ASMShowForm.DASMInitEmulData[i];
ASMShowForm.InitEmulationUsingRegisterString(sEmulResult,sEmulResult+',TTL=100');
end;
}
ASMShowForm.InitEmul;
Screen.Cursor:=crHourGlass;
Try
DisassembleProc('','',DasmList,False,True);
ASMShowForm.ASMList.Items.BeginUpdate;
ASMShowForm.ASMList.Clear;
ASMShowForm.Caption:='Proc_'+s;
AddCommentsToListing(DasmList,HEX2DWORD(s));
ASMShowForm.ASMList.Items.EndUpdate;
ASMShowForm.ASMList.SetFocus;
Finally
Screen.Cursor:=crDefault;
End;
// Update the DASMListings TList.
TStringList(ASMShowForm.DASMListings.Items[idx]).Free;
ASMShowForm.DASMListings.Items[idx]:=DasmList;
end;
Function IsJumpInstruction(ins1 : String) : Boolean;
Begin
Result:=
(ins1='jmp') or
(ins1='jo') or
(ins1='jno') or
(ins1='jb') or
(ins1='jnb') or
(ins1='je') or
(ins1='jne') or
(ins1='jbe') or
(ins1='jnbe') or
(ins1='js') or
(ins1='jns') or
(ins1='jp') or
(ins1='jnp') or
(ins1='jl') or
(ins1='jnl') or
(ins1='jle') or
(ins1='jnle') or
(ins1='jz') or
(ins1='jnz');
End;
procedure TASMShowForm.ASMListDblClick(Sender: TObject);
var s, rva : string;
node : TTreeNode;
begin
s:=Trim(ASMList.Items[ASMList.ItemIndex]);
if s='' then exit;
If Pos('call',s)<>0 Then
Begin
wLineNum:=MakeLong(ASMList.ItemIndex,ASMList.TopIndex);
rva:=Copy(s,Pos('call',s)+4,Length(s)-Pos('call',s));
TruncAll(rva);
If (Length(rva)>1) and (rva[1] in ['0'..'9']) Then
Begin
// If Ctrl+Alt+Shift Pressed then Only show the DSF Pattern
if FbShowDSFPattern then
begin
ShowDSFPattern(rva);
Exit;
end;
Screen.Cursor:=crHourGlass;
Try
DisAsm(rva, False);
Finally
Screen.Cursor:=crDefault;
End;
If ProcCB.Items.IndexOf('Proc_'+rva)=-1
Then Begin
ProcCB.Items.Add('Proc_'+rva);
ProcRVA.Items.Add(rva);
Caption:='Proc_'+rva;
ProcCB.ItemIndex:=ProcCB.Items.IndexOf('Proc_'+rva);
node:=ProcTree.Items.AddChild(ProcTree.Selected,'Proc_'+rva);
node.ImageIndex:=1;
node.Parent.Expand(False);
node.Data:=Pointer(0);
ProcTree.Selected.Data:=Pointer(wLineNum);
sLastJumpRva:=0;
ProcTree.OnChange:=nil;
Try
ProcTree.Selected:=node;
Finally
ProcTree.OnChange:=ProcTreeChange;
End;
End
Else Begin
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -