📄 dededisasm.pas
字号:
unit DeDeDisAsm;
//////////////////////////
// Last Change: 11.I.2001
//////////////////////////
interface
uses Windows,Classes, DeDeClasses, DeDeSym, MainUnit;
type DWORD = LongWord;
const IMPORT_REF_BEG = 'FF25';
IMPORT_REF_END = '8BC0';
procedure DisassembleProc(NameP,S : String; var DasmList : TStringList; bNotClearText : Boolean = True; Custom : Boolean = False; EmulateOnly : Boolean = False; dwEmulateToOffset : DWORD = 0);
function OffsetInSegment(Offset : DWORD; Segment : String) : boolean;
function GetNextProcRVA(dwRVA : DWORD; var bFound : Boolean; bSkipBetweenCodeFillRecognition : Boolean = False) : DWORD;
Function OffsetShouldCorrect(ins1 : String) : Boolean;
Type TDisassemblerOptions = record
Imports : Boolean;
EnglishStrings : Boolean;
NonEnglishStrings : Boolean;
end;
var DFMNameList : TStringList;
PASNameList : TStringList;
UnitList : TStringList;
ControlNames, ControlIDs, DFMText : TStringList;
FOpCodeList : TList;
PEStream : TPEStream;
RVAConverter : TRVAConverter;
bTryExcept : Integer;
SymbolsList : TList;
SEHPtrList,ENDPtrList : TStringList;
ClsDmp : TClassDumper;
GlobGetImports :Boolean;
GlobBEmulation : Boolean;
GlobCustomEmulInit : Boolean;
GlobMORE : Boolean;
GlobDontCutStringReferences : Boolean;
DisassemblerOptions : TDisassemblerOptions;
bErrorsAsFile : Boolean;
sDisAsmErrors : String;
ProcRva : DWORD;
Function GetSymbolReference(AwdOffset : DWORD) : String;
function GetImportReference(AsOffset : String) : String;
Function GetControlClassEx(sClassName, sControlName : String) : String;
Function GetEventPrototype(sClassName, sHandlerName : String) : String;
///////////////////////////////////////////////////
// InitExe/InitUnits functions
///////////////////////////////////////////////////
Function GetInitUnitsProcRVA : DWORD;
implementation
uses DisAsm, DisAsmTables, Dialogs, HexTools, SysUtils, DeDeReg, DeDeConstants,
DeDeClassEmulator, DeDeRES, DeDeOffsInf, DeDeExpressions;
Var rva : DWORD;
Var LastPush : DWORD;
sz : Integer;
bCommentNext, bTryBlockFound, bControlRef : Boolean;
LastJump : DWORD;
Function UnitIncluded(s : String) : Boolean;
var sUnit : String;
i : Integer;
Begin
Result:=True;
If (UnitList=nil) or (UnitList.Count=0) Then Exit;
Result:=False;
i:=Pos('.',s);
sUnit:=AnsiUpperCase(Copy(s,1,i-1));
For i:=0 To UnitList.Count-1 Do
If AnsiUpperCase(UnitList[i])=sUnit
Then Begin
Result:=True;
Break;
End;
End;
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 OffsetInSegment(Offset : DWORD; Segment : String) : boolean;
var rva,size,ib : DWORD;
i : Integer;
begin
Result:=False;
i:=PEHeader.GetSectionIndexEx(Segment);
If i<1 Then
begin
// Correction due to the lame idea of finding sections by name!!!
if Segment='CODE' then i:=PEHeader.GetSectionIndexByRVA(PEHeader.BaseOfCode);
if i=-1 then Exit;
end;
rva:=PEHeader.Objects[i].RVA;
size:=PEHeader.Objects[i].VIRTUAL_SIZE;
ib:=PEHeader.IMAGE_BASE;
Result:=(Offset>=ib+rva) and (Offset<=ib+rva+size);
end;
// Reads a string according to the specified
// string references options
function GetStringReference(AsOffset : String) : String;
const sFILL = sREF_TEXT_REF_STRING_OR+' ';
var b : Byte;
dwOffset, rva : DWORD;
bOK : Boolean;
s : String;
i : Integer;
var idx : Integer;
begin
idx:=PEHeader.GetSectionIndexEx('DATA');
if (not DisassemblerOptions.EnglishStrings)
and (not DisassemblerOptions.NonEnglishStrings) then Exit;
rva:=HEX2DWORD(AsOffset);
if ((RVA-PEHeader.IMAGE_BASE)>=PEHeader.Objects[idx].RVA)
and ((RVA-PEHeader.IMAGE_BASE)<=PEHeader.Objects[idx].RVA+PEHeader.Objects[idx].VIRTUAL_SIZE)
then dwOffset:=rva-PEHeader.IMAGE_BASE-PEHeader.Objects[idx].RVA+PEHeader.Objects[idx].PHYSICAL_OFFSET
else dwOffset:=RVAConverter.GetPhys(rva);
PEStream.Seek(dwOffset,soFromBeginning);
PEStream.ReadBuffer(b,1);
bOK:=False;
While b in STRING_REF_CHARSET Do
Begin
If not (b in [10,13]) Then Result:=Result+CHR(b);
PEStream.ReadBuffer(b,1);
If b in (STRING_REF_CHARSET - [10,13]) then bOK:=True;
End;
// Check Disassembly Options
if (DisassemblerOptions.NonEnglishStrings)
and (not DisassemblerOptions.EnglishStrings) then
begin
bOK:=False;
for i:=1 to Length(Result) do
bOk:=bOK or (Result[i] in [#192..#255]);
end;
If (b<>0) or not (bOK)
Then Result:=''
Else Begin
If Length(Result)<35 Then Exit;
If GlobDontCutStringReferences then Exit;
s:=Result;
Result:=Copy(s,1,35);
s:=Copy(s,36,Length(s)-35);
While Length(s)>35 Do
Begin
Result:=Result+#13#10+sFILL+Copy(s,1,35);
s:=Copy(s,36,Length(s)-35);
End;
If s<>'' Then Result:=Result+#13#10+sFILL+s;
End;
end;
function GetDWORDConstantReference(AsOffset : String) : String;
var dw, dwOffset : DWORD;
begin
dwOffset:=RVAConverter.GetPhys(HEX2DWORD(AsOffset));
PEStream.Seek(dwOffset,soFromBeginning);
PEStream.ReadBuffer(dw,4);
Result:=IntToStr(dw);
end;
// Description : Finds the DLL name and Import name of
// a import call reference.
//
// Last Modified : N/A
//
function GetImportReference(AsOffset : String) : String;
var iRVA, iPhys, ProcOffset, DLLOffset : DWORD;
Delta1, Delta2: LongInt;
iIDX : Byte;
ImgBase : DWORD;
wdiRVA,itbl : LongInt;
{b1,b2,b3,b4,}b : Byte;
ProcName, DLLName : String;
// Pattern : TPaternQuery;
// i : Integer;
begin
Result:='';
DLLName:='';
ProcName:='';
if bELF then Exit;
// Skip import references if set
if not DisassemblerOptions.Imports then exit;
if not bImportReferences then Exit;
// Get the '.idata' section characteristics
if bElf then iIDX:=PEHeader.GetSectionIndexEx('.idata')
else begin
iIDX:=PEHeader.GetSectionIndex('.idata');
if iIDX=255 then iIDX:=PEHeader.GetSectionIndexByRVA(PEHEader.IMPORT_TABLE_RVA);
end;
iRVA:=PEHeader.Objects[iIDX].RVA;
iPhys:=PEHeader.Objects[iIDX].PHYSICAL_OFFSET;
// and some PE file characteristics
ImgBase:=PEHeader.IMAGE_BASE;
// Convert value for RVA to Phys
Delta1:=iPhys-iRVA-ImgBase;
// Convert value relative offsets in Import Tables
Delta2:=iPhys-iRVA;
wdiRVA:=HEX2DWORD(AsOffset);
// The physical offset of the imported proc entry
// in the DLL Import Lookup Table
itbl:=wdiRVA+Delta1;
// Goes there
PEStream.Seek(itbl,soFromBeginning);
// Reads the relative offset of the
// entry in the Import Hint/Name Table
PEStream.ReadBuffer(ProcOffset,4);
// Corrects the offset to physical
ProcOffset:=ProcOffset+Delta2;
// Finds the DLL string ossfet
Repeat
PEStream.Seek(-8,soFromCurrent);
PEStream.ReadBuffer(DLLOffset,4);
If DLLOffset=0 Then Break;
Until (PEStream.Position<=iPhys);
If DLLOffset<>0 Then
begin
Result:='';
Exit;
Raise Exception.Create(err_import_ref);
end;
// Reads the first value in the DLL Import Lookup Table
PEStream.ReadBuffer(DLLOffset,4);
// Corrects the offset to physical
DLLOffset:=DLLOffset+Delta2;
// Goes to the import name offset
PEStream.Seek(ProcOffset+2,soFromBeginning);
ProcName:='';
// Reads the import name
Try
PEStream.ReadBuffer(b,1);
While b<>0 Do
Begin
ProcName:=ProcName+Chr(b);
PEStream.ReadBuffer(b,1);
End;
Except
Exit;
End;
// Goes to the dll name offset
PEStream.Seek(DLLOffset,soFromBeginning);
DLLName:='';
Repeat
PEStream.ReadBuffer(b,1);
PEStream.Seek(-2,soFromCurrent);
Until b<>0;
DLLName:=Chr(b)+DLLName;
// Reads the dll name
PEStream.ReadBuffer(b,1);
While b<>0 Do
Begin
DLLName:=Chr(b)+DLLName;
PEStream.Seek(-2,soFromCurrent);
PEStream.ReadBuffer(b,1);
End;
b:=Pos('.',DLLName);
If b<>0 Then DLLName:=Copy(DLLName,1,b-1);
if GlobCBuilder then Result:=ProcName
else Result:=DLLName+'.'+ProcName;
end;
// Returns true is the instruction has a relative address
// operand, that should be set to the absolute RVA in CODE section
Function OffsetShouldCorrect(ins1 : String) : Boolean;
Begin
Result:=
(ins1='call') or
(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;
// Description : Returns NULL string if the offset
// specified in the operand is not in
// the code section. There are 2 different
// cases - PUSH and MOV.
//
// Last Modified : April 2000
//
function OffsetMightBeString(ins1,dta : String) : String;
var i : Integer;
ofs{, sgm }: String;
begin
Result:='';
If (ins1='push')
Then Begin
ofs:=Copy(dta,2,Length(dta)-1);
If (Copy(dta,1,1)='$') and (OffsetInSegment(HEX2DWORD(ofs),'CODE')) Then
Begin
Result:=ofs;
Exit;
End;
if GlobCBuilder then
If (Copy(dta,1,1)='$') and (OffsetInSegment(HEX2DWORD(ofs),'DATA')) Then
Begin
Result:=ofs;
Exit;
End;
End;
// all that is like mov %something%,$OFFSET%something%
// is a potential string reference
If ins1='mov' Then
Begin
i:=Pos(',',dta);
If i<>0 Then
Begin
ofs:=Copy(dta,i+1,Length(dta)-i);
TruncAll(ofs);
If (ofs<>'') and (ofs[1]='$') Then
Begin
ofs:=Copy(ofs,2,Length(ofs)-1);
If OffsetInSegment(HEX2DWORD(ofs),'CODE') Then
Begin
Result:=ofs;
Exit;
End;
if GlobCBuilder then
If OffsetInSegment(HEX2DWORD(ofs),'DATA') Then
Begin
Result:=ofs;
Exit;
End;
End;
End;
End;
end;
// Description : Finds Symbol CALL references
//
// Last Modified : April 2000
//
Function GetSymbolReference(AwdOffset : DWORD) : String;
Var buff,buff1 : TSymBuffer;
bk,phys : Cardinal;
i,j : Integer;
Sym : TDeDeSymbol;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -