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

📄 dededisasm.pas

📁 dede 的源代码 3.10b
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    t_e_str : String;
Begin
   // sTRY_1e = '64FF30648920';// push dword ptr fs:[eax]; mov fs:[eax], esp
   // sTRY_2e = '64FF32648922';// push dword ptr fs:[edx]; mov fs:[edx], esp
   // sTRY_3e = '64FF31648921';// push dword ptr fs:[ecx]; mov fs:[ecx], esp
   bk:=PEStream.Position;
   Try
     ph:=RVAConverter.GetPhys(RVA);
     PEStream.Seek(ph,soFromBeginning);
     SetLength(t_e_str,6);
     PEStream.ReadBuffer(t_e_str[1],6);
     Result:=   (t_e_str=#$64#$FF#$30#$64#$89#$20)
             or (t_e_str=#$64#$FF#$32#$64#$89#$22)
             or (t_e_str=#$64#$FF#$31#$64#$89#$21);
   Finally
     PEStream.Seek(bk,soFromBeginning);
   End;
End;

// Returns true if the current instruction is
// the beginning of a EXCEPT-END block
Function IsExceptBlock : Boolean;
var bk : DWORD;
    ph : DWORD;
    b : Byte;
    t_e_str : String;
Begin
   bk:=PEStream.Position;
   Try
     ph:=RVAConverter.GetPhys(RVA);
     PEStream.Seek(ph+3,soFromBeginning);
     SetLength(t_e_str,1);
     PEStream.ReadBuffer(t_e_str[1],1);
     Result:=t_e_str[1]=#$EB;
     If Result Then Begin
       PEStream.ReadBuffer(b,1);
       LastPush:=rva+b+5;
     End;
   Finally
     PEStream.Seek(bk,soFromBeginning);
   End;
End;


// Returns true if the current instruction is
// the beginning of a FINALLY-END block
Function IsFinallyBlock : Boolean;
var bk : DWORD;
    ph,dw : DWORD;
    t_e_str : String;
Begin
   bk:=PEStream.Position;
   Try
     ph:=RVAConverter.GetPhys(RVA);
     PEStream.Seek(ph+3,soFromBeginning);
     SetLength(t_e_str,1);
     PEStream.ReadBuffer(t_e_str[1],1);
     Result:=t_e_str[1]=#$68;
     If Result Then Begin
       PEStream.ReadBuffer(dw,4);
       LastPush:=dw;
     End;
   Finally
     PEStream.Seek(bk,soFromBeginning);
   End;
End;

// If the current RVA is the END rva of a
// try-except or try-finally block then
// the reference is attached
function ReachedEND : String;
var i : Integer;
Begin
 Result:='';
 For i:=ENDPtrList.Count-1 DownTo 0 Do
   If StrToInt64(ENDPtrList[i])=rva
     Then Begin
       ENDPtrList.Delete(i);
       Result:=#13#10+sREF_TEXT_END+#13#10+'|'#13#10;
     End;
End;


// If the current RVA is the EXCEPT rva of a
// try-except block then the reference is attached
Function ReachedExcept : String;
var i : Integer;
Begin
 Result:='';
 For i:=SEHPtrList.Count-1 DownTo 0 Do
   If StrToInt(SEHPtrList[i])=rva
     Then Begin
       SEHPtrList.Delete(i);
       Result:=#13#10+sREF_TEXT_EXCEPT+#13#10+'|'#13#10;
     End;
End;

// Here different references are find
// and comments are glued to the code
// ss is the ASM line
function ReplaseReferences(var ss : String) : String;
Var ins1,dta, sof, ofs  : String;
    i,ps : Integer;
    idx : ShortInt;
    dwdta,bk : Cardinal;
Begin
   Result:='';
   // Finds the firts space in the string
   i:=Pos(#32,ss);
   // Gets the instruction
   ins1:=Copy(ss,1,i-1);
   // Gets the operands
   dta:=Copy(ss,i+1,Length(ss)-i);
   // Removes spaces at the beginning and at the and
   TruncAll(dta);
   // If not operands then nothing to handle
   If dta='' Then Exit;


   ///////////////////////////////////////////////
   //// try-finally and try-except references ////
   ///////////////////////////////////////////////

   // Put END if needed
   If ENDPtrList.Count<>0 Then
      Result:=ReachedEND;

   // Put EXCEPT if needed
   If SEHPtrList.Count<>0
      Then Result:=Result+ReachedExcept;

   If bCommentNext Then
     Begin
       // the instruction after the next push should be marked as FINALY
       Result:=Result+#13#10+sREF_TEXT_FINALLY+#13#10+'|'#13#10;
       bCommentNext:=False;
     End;

   // saves last push - to be proceeded if try is detected
   If (ins1='push') and (Copy(dta,1,1)='$') then LastPush:=HEX2DWORD(Copy(dta,2,Length(dta)-1));
   // Check For TRY
   bTryBlockFound:=False;
   If    (ss='push    dword ptr fs:[eax]')
      or (ss='push    dword ptr fs:[ecx]')
      or (ss='push    dword ptr fs:[edx]')
      Then Begin
        // Try-Exept-Finally Detected
        If (IsTryExceptBlock) Then
           Begin
            SEHPtrList.Add(IntToStr(LastPush));
            Result:=#13#10+sREF_TEXT_TRY+#13#10+'|'#13#10;
            bTryBlockFound:=True;
           End;
      End;

   // Check For EXCEPT or FINALLY
   If    (ss='mov     fs:[eax], edx')
      Then Begin
        // Try-Exept-Finally Detected
        If (IsExceptBlock) Then
           Begin
            // pushed the END offset
            ENDPtrList.Add(IntToStr(LastPush));
           End;
        If (IsFinallyBlock) Then
           Begin
             // removes the try pushed offset
             If SEHPtrList.Count<>0 Then SEHPtrList.Delete(SEHPtrList.Count-1);
             // pushed the END offset
             ENDPtrList.Add(IntToStr(LastPush));
             // one ret should be skiped
             Inc(bTryExcept);
             // next instruction should be commented with FINALLY
             bCommentNext:=True;
           End;
      End;


   ///////////////////////////////////////////////
   ///////////// Control References //////////////
   ///////////////////////////////////////////////
   //
   // normaly they are : mov eax, [eax+$xxxx]
   //               or : mov eax, [ebx+$xxxx]
   //               or : mov eax, [esi+$xxxx]
   //               or : mov edx, [eax+$xxxx]
   //
   // $xxxx is the control ID, specified in the ClassInfo block
   //
{   ps:=Pos(', [eax+$',dta);
   if ps=0 then ps:=Pos(', [ebx+$',dta);
   if ps=0 then ps:=Pos(', [esi+$',dta);
   if ps=0 then ps:=Pos(', [edx+$',dta);}
   ps:=Pos('[eax+$',dta);
   if ps=0 then ps:=Pos('[ebx+$',dta);
   if ps=0 then ps:=Pos('[esi+$',dta);
   if ps=0 then ps:=Pos('[edx+$',dta);
   If (ps<>0) and ((ins1='mov') or (ins1='lea') or (ins1='cmp')) Then
      Begin
        Dec(ps,2); //Correction for ', '
        sof:=ControlRef(Copy(dta,ps+8,4),Copy(dta,ps+3,3),Copy(dta,ps-3,3));
        If sof<>'' Then
          Begin
            Result:=Result+sof;
            Exit;
          End;
      End;


   ///////////////////////////////////////////////
   ///////////// String References ///////////////
   ///////////////////////////////////////////////
   //
   // if a 'push offset' or 'mov register, offset'
   // and this offset is in the CODE section it
   // can contain a string. Check this
   //
   If (ins1='push') or (ins1='mov') Then
     Begin
       ofs:=OffsetMightBeString(ins1,dta);
       If ofs<>''
         Then Begin
           bk:=PEStream.Position;
           Try
             If not bTryBlockFound Then
              begin
               sof:=GetStringReference(ofs);
               If sof<>'' Then
                   Result:=Result+#13#10+sREF_TEXT_REF_STRING+' '''+sof+''''#13#10+'|'#13#10;
              end;     
           Finally
             PEStream.Seek(bk,soFromBeginning);
           End;
           Exit;
         End
         Else Begin
           // It could be mov eax, dword ptr [$offset]
           // and this can be a handle to a form or also
           // it can be a Constant Reference
           // this can be imroved in future
         End;
       End;

   ///////////////////////////////////////////////
   ////////////// Call References ////////////////
   ///////////////////////////////////////////////
   //
   // First of all it the instruction is a relative
   // jump or call then the real RVA should be shown !
   //
   If OffsetShouldCorrect(ins1) Then
     Begin
       Case dta[1] of
         '-' : idx:=-1;
         '+' : idx:=1
         else Exit;
       End;
       sof:=Copy(dta,3,Length(dta)-2);
       dwdta:=idx*HEX2DWORD(sof);
       dwdta:=dwdta+rva+sz;
       while Length(ins1)<8 do ins1:=ins1+' ';
       ss:=ins1+DWORD2HEX(dwdta);

       // This finds all the call references
       if ins1='call    ' then
          Result:=RefCall(ss,dwdta);
       exit;
     End;
End;

// procedure DisassembleProc(NameP,S : String; var DasmList : TStringList; bNotClearText : Boolean = True; Custom : Boolean = False);
//
// Description : Disaasembles procedure.
//
//     DeDeDisAsm.PEStream, PEHeader, RVAConverter, DFMText,
//               , ControlIDs, ControlNames, ClsDmp and SymbolList
//     should be set before calling this procedure. Their meaning is
//     the following:
//
//       *) PEStream is the file, if not set exception will occure
//       *) PEHeader is the PE header of the file, if not set exception will occure
//       *) RVAConverter is used to convert RVAs to Physical offsets, if not set exception will occure
//       *) DFMText is the text representation of the DFM resources of the current form.
//           if not set control references will not have the class names of controls
//       *) ControlIDs and ControlNames are the IDs and names of the controls in the form
//           if not set no control references will be found
//       *) ClsDmp is the TClassDumper object of the current class
//           if not set no published/VIRT/USER proc references will be found
//       *) SymbolList is a TList with loaded TDeDeSymbol objects
//           if not set no calls to VCL and other BPLs will be found
//
//    Parameter Description:
//       NameP         : Unit name
//       S             : Procedure Name
//       DasmList      : A TStringList that will contain the result
//                       of disassembling. This object should not be
//                       created before calling the DisassembleProc().
//                       If is created from the procedure itself. The
//                       calling procedure should free this object after
//                       assign the lines to another TStringList or after
//                       saving it to a file. 
//       bNotClearText : If Flase then NameP is the unit name and
//                       S is the rocedure name, that should exist in the
//                       ClsDmp object MethodList.
//                       If True then NameP is the unit name, ending with
//                       '.pas' and S is the full name of the procedure
//                       like in pascal implementation part. For example:
//                       NameP = Unit11.pas
//                       s     = procedure TForm11.CaptionMaskMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X: Integer; Y: Integer);
//                       (NOTE: this flag is used to differ normal disassembly from
//                        saving a Delphi project space. There is no special reason of
//                        having this parameter and DisassemblerProc() does the same
//                        things in the both cases. The default value is TRUE)
//       Custom        : If TRUE then the DisassembleProc will not seek for the
//                       proc RVA addres and will start to dissasebmle from the current
//                       position of the PEStream. If this parameter is not specified then
//                        the default value is FALSE
//
//       EmulateOnly   : If TRUE then ptocedure is only emulated to dwEmulateToOffset offset.
//                       This is used to initialize registes when disassembling subprocedures
//
//      dwEmulateToOffset : The end offset (excluding it) to where the procedure should be
//                       emulated. If this offset is beyond the end of the procedure emulation
//                       ends with the end of the procedure. If it is zero then no emulation is
//                       done at all.
//
// Last Modified : 11.I.2001
//
procedure DisassembleProc(NameP,S : String; var DasmList : TStringList; bNotClearText : Boolean = True; Custom : Boolean = False; EmulateOnly : Boolean = False; dwEmulateToOffset : DWORD = 0);
var iStopIndex, i,k,locpos, InstrId : Integer;
    ss : String;
    DASM : TDisAsm;
    pc,op,srf, locvar : String;

begin
  // Creates The Result
  DasmList:=TStringList.Create;

  if not Custom then
    if GlobBEmulation then
      if not GlobCustomEmulInit
          then InitNewEmulation('','','','');

  rva:=0;
  If Not Custom Then
  Begin
  // This retreives the RVA offsets of the first instruction
  // and moves the steram pointer to this offset
   If bNotClearText Then
     Begin
       i:=Pos('.',NameP);
       NameP:=Copy(NameP,1,i-1);
     End;

    If bNotClearText Then
     Begin
      i:=Pos('.',S);
      s:=Copy(s,i+1,Length(s)-i);
      i:=Pos('(',s);
      s:=Copy(s,1,i-1);
     End;

    rva:=ClsDmp.GetMethodRVA(s);

    if GlobBEmulation then
      if not GlobCustomEmulInit then
         InitNewEmulation(ClsDmp.FsClassName,'','','');

    ss:=DWORD2HEX(RVAConverter.GetPhys(rva));
    PEStream.Seek(HEX2DWORD(ss),soFromBeginning);
  End
  // Else if bCustom=True, the Stream is set to this first
  // instruction and need just to get its RVA address
  Else rva:=RVAConverter.GetRVA(PEStream.Position);

  If rva=0 then Exit;
  ProcRva:=rva;

///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//////////// The Main Diassembly Loop /////////////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////

   // Creates the OPCODE_to_ASM disassembler object
   DASM:=TDisAsm.Create;

   // The number of the current instruction
   InstrId:=0;
   // Stop if this insruction number is reached.
   iStopIndex:=-1;

    Try
     Try
      // Clears SEH List (try_except and try_finally blocks)
      SEHPtrList.Clear;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -