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

📄 dededisasm.pas

📁 dede 的源代码 3.10b
💻 PAS
📖 第 1 页 / 共 4 页
字号:

      // Initialize the number of found TRY blocks to 0
      // (this is used for the both try_finally and
      // for try_except blocks)
      bTryExcept:=0;

      // Clears the list with END_try and END_fynally offsets
      ENDPtrList.Clear;

      // Initialize the last short jump otside the current RVA
      // to 'not present'
      LastJump:=0;

      // Inititaliza the size of the last instruction in bytes to 0
      sz:=0;

      Repeat
        Repeat
          // Sets lenth in bytes of the largest instruction
          SetLength(pc,17);
          // Reads next byets
          PEStream.ReadBuffer(pc[1],16);
          // Disassembels them
          ss:=DASM.GetInstruction(PChar(pc),sz);
          Inc(InstrId);

          // If the current instruction is a short jump ahead
          // then sets the LastJump
          If (ORD(pc[1]) in [$70..$7F,$EB]) and
             (ORD(pc[2])<$7F) Then
             if LastJump<rva+2+ORD(pc[2])
                then LastJump:=rva+2+ORD(pc[2]);

          // If the last short jump ahead is passed
          // sets the last jump to zero
          If LastJump<=rva Then LastJump:=0;

          // Finds all kind of references and attches them before
          // the disassembeld instruction
          bControlRef:=False;

            srf:=ReplaseReferences(ss);

            // More references !!!
            if     (GlobBEmulation)
               // if control reference is found then skip emulation
               and (not bControlRef) then
             begin
                EmulateInstruction(pc,sz,ss,ss);
                If bReference then
                  begin
                    if srf='' then srf:=#13#10;
                    ///////////////////////////////////////////////////////
                    // srf:=srf+'* '+sReference+#13#10+'|'#13#10;
                    // '* ' was removed when made references texts standart
                    ///////////////////////////////////////////////////////
                    srf:=srf+sReference+#13#10+'|'#13#10;
                  end;
             end;


            //Gets Local Var References
            locpos:=Pos('[ebp-$',ss);
            if locpos=0 then locpos:=Pos('[ebp+$FFFF',ss);
            if locpos<>0 then
              begin
                locvar:=Copy(ss,locpos,locpos+10);
                locpos:=Pos(']',locvar);
                locvar:=Copy(locvar,1,locpos);
                AddNewExpression(ProcRVA,locvar,'');
              end;

            // Gets the string representation of OPCODEs
            op:='';
            For k:=1 To sz Do op:=op+Byte2HEX(ORD(pc[k]));
            While Length(op)<20 Do op:=op+' ';

            // Adds the current instruction and references to the
            // result StringList
            if not EmulateOnly then
               DasmList.Add(srf+DWord2HEX(rva)+'   '+op+'   '+ss);

          // Calculates the RVA address of the next instruction
          rva:=rva+sz;

          // If it is emulation and end offset is reached then exit proc
          if (EmulateOnly) and (rva>=dwEmulateToOffset) then exit;

          // Moves the pointer in the stream at the beginning
          // of the next instruction according to the last
          // instruction size in bytes. 16 is the max length of
          // an instruction
          PEStream.Seek(sz-16,soFromCurrent);

          // This is especially for the Delphi compiler
          // This can be and of a procedure. This is
          // used to find the end of the DPR code and
          // in some other special cases
          if (ss='add     [eax], al') and (SEHPtrList.Count=0) then
              break;

          // This is the first instruction and it is jump to offset. Probably
          // from import section. Stop Disassembly after.
          If (ORD(pc[1])=$FF) and (ORD(pc[2])=$25) and (InstrId=1)
             Then iStopIndex:=2;

          // If we should stop then exit
          if InstrId=iStopIndex then exit;

        // Repeats disassembly until a 'RET' has been reached
        Until copy(ss,1,3)='ret';

        // Decreases the number of try blocks
        Dec(bTryExcept);

        // Adds an empty line to the result StringList
        DasmList.Add('');

      // Repeats until all try blocks has been closed
      Until (SEHPtrList.Count=0) and (bTryExcept<0) and (LastJump=0);

     Except
      // On exception shows the error
      On E:Exception Do
      if not bErrorsAsFile then
          MessageBox(0,PChar(
            'Exception: '+E.Message+#13#10+
            'Proc Name: '+NameP+'.'+s+#13#10+
            'Last Instruction: '+DWord2HEX(rva)+'   '+op+'   '+ss+#13#10+
            'Current Position: '+IntToHex(PEStream.Position,8)),
            PChar(err_dasm_err),0)
       else sDisAsmErrors:=sDisAsmErrors+#13#10+
            'Exception: '+E.Message+#13#10+
            'Proc Name: '+NameP+'.'+s+#13#10+
            'Last Instruction: '+DWord2HEX(rva)+'   '+op+'   '+ss+#13#10+
            'Current Position: '+IntToHex(PEStream.Position,8)+
            #13#10;
     End;
    Finally
      // Frees the TDASM object
      DASM.Free;

      // Restore Disassembly Options. They should be set before every call to DiassembleProc!!
      DisassemblerOptions.Imports:=True;
      DisassemblerOptions.EnglishStrings:=True;
      DisassemblerOptions.NonEnglishStrings:=True;
    End;
    
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
//////////// End Of The Main Diassembly Loop //////////////
///////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////
end;


function GetNextProcRVA(dwRVA : DWORD; var bFound : Boolean; bSkipBetweenCodeFillRecognition : Boolean = False) : DWORD;
var  DASM : TDisAsm;
     phys : DWORD;
     pc,ss : String;
     sz{,i} : LongInt;
begin
   DASM:=TDisAsm.Create;

   try
     phys:=RVAConverter.GetPhys(dwRVA);
     PEStream.Seek(phys,soFromBeginning);
     rva:=dwRVA;

     Result:=0;
     if (phys<=0) then Exit;
     if (phys>=PEStream.Size) then Exit; 

     SEHPtrList.Clear;
     bTryExcept:=0;
     ENDPtrList.Clear;
     LastJump:=0;
     sz:=0;
     Repeat
       Repeat
          SetLength(pc,17);
          PEStream.ReadBuffer(pc[1],16);
          ss:=DASM.GetInstruction(PChar(pc),sz);

          If (ORD(pc[1]) in [$70..$7F,$EB]) and
             (ORD(pc[2])<$7F) Then
             if LastJump<rva+2+ORD(pc[2])
                then LastJump:=rva+2+ORD(pc[2]);
          If LastJump<=rva Then LastJump:=0;

          If ENDPtrList.Count<>0 Then ReachedEND;
          If SEHPtrList.Count<>0 Then ReachedExcept;

          If ORD(pc[1])=$68 then LastPush:=ORD(pc[2])+ORD(pc[3])*256+(ORD(pc[4])+ORD(pc[5])*256)*256*256;
          bTryBlockFound:=False;
          If Copy(pc,1,6)=#$64#$FF#$30#$64#$89#$20 Then
              Begin
                 SEHPtrList.Add(IntToStr(LastPush));
                 bTryBlockFound:=True;
              End;

          If Copy(pc,1,3)=#$64#$89#$10
             Then Begin
               If pc[4]=#$EB Then ENDPtrList.Add(IntToStr(LastPush));
               If pc[4]=#$68 Then
                  Begin
                    If SEHPtrList.Count<>0 Then SEHPtrList.Delete(SEHPtrList.Count-1);
                    ENDPtrList.Add(IntToStr(LastPush));
                    Inc(bTryExcept);
                   End;
             End;

           rva:=rva+sz;
           PEStream.Seek(sz-16,soFromCurrent);

           if (ORD(pc[1])=0) and (ORD(pc[2])=0) then break;
        Until Copy(ss,1,3)='ret';

        Dec(bTryExcept);
      Until (SEHPtrList.Count=0) and (bTryExcept<0) and (LastJump=0);

      Result:=rva;
      If bSkipBetweenCodeFillRecognition then Exit;


      //Result:=0;


      // separators
      // 1 byte : 90       nop
      // 2 byte : 8BC0     mov eax, eax
      // 3 byte : 8D4000   lea eax, [eax+00]
      // end_of_procs = 0000, 00FFFFFF
     bFound:=True;
     If (pc[sz+1]=#$90) then Inc(rva,1) else
     If (pc[sz+1]=#$8B) and (pc[sz+2]=#$C0) then Inc(rva,2) else
     If (pc[sz+1]=#$8D) and (pc[sz+2]=#$40) and (pc[sz+3]=#$00) then Inc(rva,3) else

     If (pc[sz+1] in [#$55,#$83]) then asm NOP end else
       begin
         //bFound:=False;
         //procs starting with 00 or FF are not procs
         If (pc[sz+1]=#$FF) then bFound:=False;
         if (pc[sz+1]=#$00) and (pc[sz+2] in [#$00,#$FF]) then bFound:=False;
         //procs finishing with 0000 are not procs
         if (ORD(pc[1])=0) and (ORD(pc[2])=0) then bFound:=False;

         if not bFound then
          begin
           repeat
             PEStream.ReadBuffer(pc[1],1);
             Inc(rva);
           until pc[1] in [#$55,#$83];
           bFound:=pc[1] in [#$55,#$83]
         end;

       end;

     Result:=rva;

  Finally
    DASM.Free;
  End;
end;

//////////////////////////////////////////////////////
//   Seeks InitUnits routine from system.pas
// and returns its phisical offset
/////////////////////////////////////////////////////
Function GetInitUnitsProcRVA : DWORD;
var l, iiDW : DWORD;
    buff : TSymBuffer;
begin
  iiDW:=0;
  PEFile.PEStream.BeginSearch;
  Try
    For l:=0 to PEFile.PEStream.Size-sizeOf(buff)-1 Do
      begin
        PEFile.PEStream.Seek(l,soFromBeginning);
        PEFile.PEStream.ReadBuffer(buff,sizeof(buff));

        If DelphiVersion='D2' then
         begin
            If (buff[1]=$55) and (buff[12]=$85) and (buff[13]=$C0) and (buff[14]=$74) and (buff[15]=$4B)
             then begin
                UnlinkCalls(buff);
                if CompareMem(@buff[1], @D2_InitUnitsIdent[1], 49) then
                  begin
                    // InitInstance Procedure Found
                    iiDW:=l;
                    break;
                  end;
             end;
         end; {Delphi5 Recognition}

        If DelphiVersion='D3' then
         begin
            If (buff[1]=$55) and (buff[12]=$85) and (buff[13]=$C0) and (buff[14]=$74) and (buff[15]=$4B)
             then begin
                UnlinkCalls(buff);
                if CompareMem(@buff[1], @D3_InitUnitsIdent[1], 49) then
                  begin
                    // InitInstance Procedure Found
                    iiDW:=l;
                    break;
                  end;
             end;
         end; {Delphi5 Recognition}

        If DelphiVersion='D4' then
         begin
            If (buff[1]=$55) and (buff[12]=$85) and (buff[13]=$C0) and (buff[14]=$74) and (buff[15]=$4B)
             then begin
                UnlinkCalls(buff);
                if CompareMem(@buff[1], @D4_InitUnitsIdent[1], 49) then
                  begin
                    // InitInstance Procedure Found
                    iiDW:=l;
                    break;
                  end;
             end;
         end; {Delphi4 Recognition}

        If DelphiVersion='D5' then
         begin
            If (buff[1]=$55) and (buff[12]=$85) and (buff[13]=$C0) and (buff[14]=$74) and (buff[15]=$4B)
             then begin
                UnlinkCalls(buff);
                if CompareMem(@buff[1], @D4_InitUnitsIdent[1], 49) then
                  begin
                    // InitInstance Procedure Found
                    iiDW:=l;
                    break;
                  end;
             end;
         end; {Delphi5 Recognition}

        If (DelphiVersion='D6') or (DelphiVersion='D6 CLX') then
         begin
            If (buff[1]=$55) and (buff[12]=$85) and (buff[13]=$C0) and (buff[14]=$74) and (buff[15]=$4B)
             then begin
                UnlinkCalls(buff);
                if CompareMem(@buff[1], @D6_InitUnitsIdent[1], 49) then
                  begin
                    // InitInstance Procedure Found
                    iiDW:=l;
                    break;
                  end;
             end;
         end; {Delphi6 Recognition}

        If DelphiVersion='DConsole' then
         begin
            If (buff[1]=$55) and (buff[12]=$85) and (buff[13]=$C0) and (buff[14]=$74) and (buff[15]=$4B)
             then begin
                UnlinkCalls(buff);
                if CompareMem(@buff[1], @D6_InitUnitsIdent[1], 49) then
                  begin
                    // InitInstance Procedure Found
                    iiDW:=l;
                    break;
                  end;
             end;
         end; {Delphi6 Recognition}

      end;
  Finally
    PEFile.PEStream.EndSearch;
  End;

  Result:=iiDW;
End;

initialization
  UnitList:=TStringList.Create;
  SEHPtrList:=TStringList.Create;
  ENDPtrList:=TStringList.Create;
  DFMText:=TStringList.Create;
  ControlNames:=TStringList.Create;
  ControlIds:=TStringList.Create;
  DisassemblerOptions.Imports:=True;
  DisassemblerOptions.EnglishStrings:=True;
  DisassemblerOptions.NonEnglishStrings:=True;

finalization
  UnitList.Free;
  SEHPtrList.Free;
  ENDPtrList.Free;
  DFMText.Free;
  ControlNames.Free;
  ControlIDs.Free;

end.

⌨️ 快捷键说明

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