CapstoneDisassembler.cpp 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #include "CapstoneDisassembler.hpp"
  2. namespace nkg {
  3. CapstoneDisassembler::CapstoneDisassembler(const CapstoneEngine& Engine) :
  4. ARL::ResourceWrapper<ARL::ResourceTraits::CapstoneInsn>(cs_malloc(Engine)),
  5. m_Engine(Engine),
  6. m_CurrentState{},
  7. m_NextState{},
  8. m_lpCurrentInsn(nullptr)
  9. {
  10. if (IsValid() == false) {
  11. throw ARL::CapstoneError(__BASE_FILE__, __LINE__, cs_errno(Engine), "cs_malloc failed.");
  12. }
  13. }
  14. CapstoneDisassembler& CapstoneDisassembler::SetContext(const CapstoneContext& Ctx) noexcept {
  15. m_lpCurrentInsn = nullptr;
  16. m_CurrentState.lpMachineCode = nullptr;
  17. m_CurrentState.cbMachineCode = 0;
  18. m_CurrentState.Address = 0;
  19. m_NextState = Ctx;
  20. return *this;
  21. }
  22. [[nodiscard]]
  23. const CapstoneContext& CapstoneDisassembler::GetContext() const noexcept {
  24. return m_NextState;
  25. }
  26. [[nodiscard]]
  27. bool CapstoneDisassembler::Next() noexcept {
  28. bool bSucceed;
  29. CapstoneContext backup = m_NextState;
  30. bSucceed = cs_disasm_iter(m_Engine.Get(), reinterpret_cast<const uint8_t**>(&m_NextState.lpMachineCode), &m_NextState.cbMachineCode, &m_NextState.Address, Get());
  31. if (bSucceed) {
  32. if (m_lpCurrentInsn == nullptr) {
  33. m_lpCurrentInsn = Get();
  34. }
  35. m_CurrentState = backup;
  36. } else {
  37. m_lpCurrentInsn = nullptr;
  38. }
  39. return bSucceed;
  40. }
  41. [[nodiscard]]
  42. const cs_insn* CapstoneDisassembler::GetInstruction() const noexcept {
  43. return m_lpCurrentInsn;
  44. }
  45. [[nodiscard]]
  46. const CapstoneContext& CapstoneDisassembler::GetInstructionContext() const noexcept {
  47. return m_CurrentState;
  48. }
  49. CapstoneEngine::CapstoneEngine(cs_arch ArchType, cs_mode Mode) {
  50. auto err = cs_open(ArchType, Mode, GetAddressOf());
  51. if (err != CS_ERR_OK) {
  52. throw ARL::CapstoneError(__BASE_FILE__, __LINE__, err, "cs_open failed.");
  53. }
  54. }
  55. void CapstoneEngine::Option(cs_opt_type Type, cs_opt_value Value) {
  56. auto err = cs_option(Get(), Type, Value);
  57. if (err != CS_ERR_OK) {
  58. throw ARL::CapstoneError(__BASE_FILE__, __LINE__, err, "cs_option failed.");
  59. }
  60. }
  61. const char* CapstoneEngine::GetGroupName(unsigned int group_id) const noexcept {
  62. return cs_group_name(Get(), group_id);
  63. }
  64. const char* CapstoneEngine::GetInstructionName(unsigned int instruction_id) const noexcept {
  65. return cs_insn_name(Get(), instruction_id);
  66. }
  67. const char* CapstoneEngine::GetRegisterName(unsigned int register_id) const noexcept {
  68. return cs_reg_name(Get(), register_id);
  69. }
  70. [[nodiscard]]
  71. CapstoneDisassembler CapstoneEngine::CreateDisassembler() const {
  72. return CapstoneDisassembler(*this);
  73. }
  74. }