CapstoneDisassembler.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. #include "CapstoneDisassembler.hpp"
  2. #undef NKG_CURRENT_SOURCE_FILE
  3. #undef NKG_CURRENT_SOURCE_LINE
  4. #define NKG_CURRENT_SOURCE_FILE() TEXT(".\\navicat-patcher\\CapstoneDisassembler.cpp")
  5. #define NKG_CURRENT_SOURCE_LINE() __LINE__
  6. namespace nkg {
  7. CapstoneDisassembler::CapstoneDisassembler(const CapstoneEngine& Engine) :
  8. ResourceOwned<CapstoneInsnTraits>(cs_malloc(Engine)),
  9. _Engine(Engine),
  10. _CurrentState{},
  11. _NextState{},
  12. _lpCurrentInsn(nullptr)
  13. {
  14. if (IsValid() == false) {
  15. throw CapstoneError(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), cs_errno(Engine), TEXT("cs_malloc failed."));
  16. }
  17. }
  18. CapstoneDisassembler::CapstoneDisassembler(CapstoneDisassembler&& Other) noexcept :
  19. ResourceOwned<CapstoneInsnTraits>(static_cast<ResourceOwned<CapstoneInsnTraits>&&>(Other)),
  20. _Engine(Other._Engine),
  21. _CurrentState(Other._CurrentState),
  22. _NextState(Other._NextState),
  23. _lpCurrentInsn(Other._lpCurrentInsn) {}
  24. CapstoneDisassembler& CapstoneDisassembler::SetContext(const CapstoneContext& Ctx) noexcept {
  25. _lpCurrentInsn = nullptr;
  26. _CurrentState.lpMachineCode = nullptr;
  27. _CurrentState.cbMachineCode = 0;
  28. _CurrentState.Address = 0;
  29. _NextState = Ctx;
  30. return *this;
  31. }
  32. [[nodiscard]]
  33. const CapstoneContext& CapstoneDisassembler::GetContext() const noexcept {
  34. return _NextState;
  35. }
  36. [[nodiscard]]
  37. bool CapstoneDisassembler::Next() noexcept {
  38. bool bSucceed;
  39. CapstoneContext backup = _NextState;
  40. bSucceed = cs_disasm_iter(_Engine.Get(), reinterpret_cast<const uint8_t**>(&_NextState.lpMachineCode), &_NextState.cbMachineCode, &_NextState.Address, Get());
  41. if (bSucceed) {
  42. if (_lpCurrentInsn == nullptr) {
  43. _lpCurrentInsn = Get();
  44. }
  45. _CurrentState = backup;
  46. } else {
  47. _lpCurrentInsn = nullptr;
  48. }
  49. return bSucceed;
  50. }
  51. [[nodiscard]]
  52. const cs_insn* CapstoneDisassembler::GetInstruction() const noexcept {
  53. return _lpCurrentInsn;
  54. }
  55. [[nodiscard]]
  56. const CapstoneContext& CapstoneDisassembler::GetInstructionContext() const noexcept {
  57. return _CurrentState;
  58. }
  59. CapstoneEngine::CapstoneEngine(cs_arch ArchType, cs_mode Mode) {
  60. auto err = cs_open(ArchType, Mode, GetAddressOf());
  61. if (err != CS_ERR_OK) {
  62. throw CapstoneError(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, TEXT("cs_open failed."));
  63. }
  64. }
  65. void CapstoneEngine::Option(cs_opt_type Type, cs_opt_value Value) {
  66. auto err = cs_option(Get(), Type, Value);
  67. if (err != CS_ERR_OK) {
  68. throw CapstoneError(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, TEXT("cs_option failed."));
  69. }
  70. }
  71. const char* CapstoneEngine::GetRegisterName(unsigned int reg_id) const noexcept {
  72. return cs_reg_name(Get(), reg_id);
  73. }
  74. [[nodiscard]]
  75. CapstoneDisassembler CapstoneEngine::CreateDisassembler() const {
  76. return CapstoneDisassembler(*this);
  77. }
  78. }