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

📄 disasm.pas

📁 用delphi实现反汇编测控专家 用于各个行业的高技术仪表
💻 PAS
📖 第 1 页 / 共 2 页
字号:
                1: Result := Result + '[bx+di';
                2: Result := Result + '[bp+si';
                3: Result := Result + '[bp+di';
                4: Result := Result + '[si';
                5: Result := Result + '[di';
                6: Result := Result + '[bp';
                7: Result := Result + '[bx';
              end
              else
              begin
                   Case RM of
                     0: Result := Result + '[eax';
                     1: Result := Result + '[ecx';
                     2: Result := Result + '[edx';
                     3: Result := Result + '[ebx';
                     4: Result := Result + ReadSib;
                     5: Result := Result + '[ebp';
                     6: Result := Result + '[esi';
                     7: Result := Result + '[edi';
                   end;
                   if RM <> 4 then
                      begin
                           Ref.ARegister1 := TRegister(RM);
                           Ref.MultiplyReg1 := 1;
                      end;
              end;
           Case AMod of
             0: Result := Result + ']';
             1: begin
                     I := ShortInt(ReadByte);
                     Result := Result + SignedIntToHex(I, 2) + ']';
                     Inc(Ref.Immidiate, I);
                end;
             2: Result := Result + '+' + GetRefAddress + ']';
           end;
           if Assigned(OnRef) then OnRef(Param, Ref, OperandSize, Result);
      end;

   var
      I: Integer;
   begin
        Result := '';
        Case OperandType of
          'a': if DeffOperandSize = 2 then OperandSize := 4
                                      else OperandSize := 8;
          'b': OperandSize := 1;
          'c': if DeffOperandSize = 2 then OperandSize := 1
                                      else OperandSize := 2;
          'd': OperandSize := 4;
          'p': OperandSize := AddressSize + 2;
          'q': OperandSize := 8;
          's': OperandSize := 6;
          'v': OperandSize := DeffOperandSize;
          'w': OperandSize := 2;
          't': OperandSize := 10;
        end;
        Case AddrMethod of
          'A': if OperandType = 'p' then
                  begin
                       if SegOverride then Result := SegName + ':'
                                      else Result := '';
                       if AddressSize = 4 then Result := Result + GetRefAddress
                                          else Result := Result + '$' + IntToHex(ReadWord, 2);
                  end
                  else
                  Raise EDisAsmError.Create(ERROR_INVALID_OPERAND);
          'C': if OperandType = 'd' then
                  begin
                       Result := Format('C%d', [(ModRM and ModRMReg) div 8]);
                       MustHaveSize := False;
                  end
                  else
                  Raise EDisAsmError.Create(ERROR_INVALID_OPERAND);
          'D': if OperandType = 'd' then
                  begin
                       Result := Format('D%d', [(ModRM and ModRMReg) div 8]);
                       MustHaveSize := False;
                  end
                  else
                  Raise EDisAsmError.Create(ERROR_INVALID_OPERAND);
          'E', 'M', 'R': Result := GetEffectiveAddress(False);
          'F': ;
          'G': begin
                    Result := GetRegName((ModRM and ModRMReg) div 8);
                    MustHaveSize := False;
               end;
          'H': begin
                    Case OperandSize of
                      1: I := ShortInt(ReadByte);
                      2: I := SmallInt(ReadWord);
                      4: I := Integer(ReadDWord);
                      else Raise EDisAsmError.Create(ERROR_INVALID_OPERAND_SIZE);
                    end;
                    Result := SignedIntToHex(I, OperandSize * 2);
                    if Assigned(OnImmidiateData) then
                       OnImmidiateData(Param, Address + Size - OperandSize, OperandSize, True, Result);
                    Result := '^' + Chr(Length(Result)) + Result;
               end;
          'I': begin
                    Result := '';
                    For I := OperandSize downto 1 do
                        Result := IntToHex(ReadByte, 2) + Result;
                    Result := '$' + Result;
                    if Assigned(OnImmidiateData) then
                       OnImmidiateData(Param, Address + Size - OperandSize, OperandSize, False, Result);
                    Result := '^' + Chr(Length(Result)) + Result;
               end;
          'J': begin
                    Case OperandSize of
                      1: I := ShortInt(ReadByte);
                      2: I := SmallInt(ReadWord);
                      4: I := Integer(ReadDWord);
                      else Raise EDisAsmError.Create(ERROR_INVALID_OPERAND_SIZE);
                    end;
                    Result := SignedIntToHex(I, OperandSize * 2);
                    if (EnhOperandType = 'j') and Assigned(OnJumpInstr) then
                       begin
                            OnJumpInstr(Param, Address + Size - OperandSize, Address + Size + I, Result);
                            Result := '^' + Chr(Length(Result)) + Result;
                       end;
                    if (EnhOperandType = 'c') and Assigned(OnCallInstr) then
                       begin
                            OnCallInstr(Param, Address + Size - OperandSize, Address + Size + I, Result);
                            Result := '^' + Chr(Length(Result)) + Result;
                       end;
               end;
          'O': if AddressSize = 2 then
                  Result := '%s' + Chr(OperandSize) + '[$' + IntToHex(ReadWord, 4) + ']'
                  else
                  begin
                       Result := '%s' + Chr(OperandSize) + '[' + GetRefAddress + ']';
                       if Assigned(OnRef) then
                          OnRef(Param, Ref, OperandSize, Result);
                  end;
          'P': begin
                    Result := Format('MM%d', [(ModRM and ModRMReg) div 8]);
                    MustHaveSize := False;
               end;
          'Q': if (ModRM and ModRMMod) = $C0 then
                  begin
                       Result := Format('MM%d', [(ModRM and ModRMReg) div 8]);
                       MustHaveSize := False;
                  end
                  else
                  Result := GetEffectiveAddress(False);
          'S': Case (ModRM and ModRMReg) div 8 of
                 0: Result := 'es';
                 1: Result := 'cs';
                 2: Result := 'ss';
                 3: Result := 'ds';
                 4: Result := 'fs';
                 5: Result := 'gs';
               end;
          'T': begin
                    Result := Format('T%d', [(ModRM and ModRMReg) div 8]);
                    MustHaveSize := False;
               end;
        end;
   end;

   function Replacer(FirstChar, SecondChar: Char): String;
   begin
        Case FirstChar of
          'c': if SecondChar = '2' then
                  Result := TwoByteOpCodes[Char(ReadByte)]
                  else
                      if ModRm <= $BF then
                         Result := FloatingPointOpCodes[SecondChar, (ModRM and ModRMReg) div 8 + $B8]
                         else
                         Result := FloatingPointOpCodes[SecondChar, ModRm];
          'e': if DeffOperandSize = 4 then Result := 'e' + SecondChar
                                      else Result := SecondChar;
          'p': begin
                    SegOverride := True;
                    SegName := SecondChar + 's';
                    Result := OneByteOpCodes[Char(ReadByte)];
               end;
          's': begin
                    Case SecondChar of
                      'o': DeffOperandSize := 2;
                      'a': AddressSize := 2;
                    end;
                    Result := OneByteOpCodes[Char(ReadByte)];
               end;
          'o': if DeffOperandSize = 4 then
                  Case SecondChar of
                    '2': Result := 'w';
                    '4': Result := 'd';
                    '8': Result := 'q';
                  end
                  else
                  Case SecondChar of
                    '2': Result := 'b';
                    '4': Result := 'w';
                    '8': Result := 'd';
                  end;
          'm': begin
                    Result := '';
                    MustHaveSize := True;
               end;
          'g': Result := GroupsOpCodes[SecondChar, (ModRM and ModRMReg) div 8];
          'h': Result := GroupsOperands[SecondChar, (ModRM and ModRMReg) div 8];
        end;
   end;

var
   I, J, K, SPos, EPos : Integer;
begin
     DeffOperandSize := 4;
     AddressSize := 4;
     SegOverride := False;
     Size := 0;
     XHasSib := False;
     XHasModRM := False;
     MustHaveSize := True;
     Ref.MultiplyReg1 := 0;
     Ref.MultiplyReg2 := 0;
     Ref.Immidiate := nil;
     Result := OneByteOpCodes[Char(ReadByte)];
     I := 1;
     While I < Length(Result) -1  do
           Case Result[I] of
             '#': begin
                       Insert(Operand(Result[I + 1], Result[I + 2], Result[I + 3]), Result, I + 4);
                       Delete(Result, I, 4);
                  end;
             '@': begin
                       Insert(Replacer(Result[I + 1], Result[I + 2]), Result, I + 3);
                       Delete(Result, I, 3);
                  end;
             '^': begin
                       J := I;
                       Inc(I, Ord(Result[I + 1]));
                       Delete(Result, J, 2);
                  end;
             else Inc(I);
           end;
     I := 1;
     While I < Length(Result) - 1  do
           Case Result[I] of
                '%': begin
                         Case Result[I + 1] of
                           's': if MustHaveSize then
                                   Case Result[I + 2] of
                                     #1: Insert('byte ptr ', Result, I + 3);
                                     #2: Insert('word ptr ', Result, I + 3);
                                     #4: Insert('dword ptr ', Result, I + 3);
                                     #6: ;
                                     #8: Insert('qword ptr ', Result, I + 3);
                                     #10: Insert('tbyte ptr ', Result, I + 3);
                                     else Insert('???? ptr ', Result, I + 3);
                                   end;
                           'c': begin
                                     Insert('  //', Result, I + 3);
                                     For J := Size - 1 downto 1 do
                                     Insert(', $' + IntToHex(PByte(Address + J)^, 2), Result, I + 3);
                                     Insert('DB  $' + IntToHex(PByte(Address)^, 2), Result, I + 3);
                                end;
                         end;
                         Delete(Result, I, 3);
                     end;
                else Inc(I);
           end;
    SPos := Pos('[$', Result);
    if SPos <> 0 then
       begin
            EPos := Pos(']', Result);
            if EPos - SPos < 10 then
               For K := EPos - SPos to 9 do Insert('0', Result, SPos + 2);
       end;
end;

end.

⌨️ 快捷键说明

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