⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dededisasm.pas

📁 dede 的源代码 3.10b
💻 PAS
📖 第 1 页 / 共 4 页
字号:
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 + -