CapstoneDisassembler.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. #include "CapstoneDisassembler.hpp"
  2. #include <memory.h>
  3. // libs required by capstone
  4. #pragma comment(lib, "legacy_stdio_definitions.lib")
  5. #if defined(_M_AMD64)
  6. #pragma comment(lib, "capstone_static.lib")
  7. #else
  8. #pragma comment(lib, "capstone.lib")
  9. #endif
  10. // ----------- avoid link error caused by capstone_static.lib
  11. #define stdin (__acrt_iob_func(0))
  12. #define stdout (__acrt_iob_func(1))
  13. #define stderr (__acrt_iob_func(2))
  14. FILE _iob[] = { *stdin, *stdout, *stderr };
  15. extern "C" FILE* __cdecl __iob_func(void) {
  16. return _iob;
  17. }
  18. // ------------
  19. #undef __BASE_FILE__
  20. #define __BASE_FILE__ TEXT("CapstoneDisassembler.cpp")
  21. bool CapstoneDisassembler::Context::operator==(const CapstoneDisassembler::Context& Other) const noexcept {
  22. return memcmp(this, &Other, sizeof(Context)) == 0;
  23. }
  24. bool CapstoneDisassembler::Context::operator!=(const CapstoneDisassembler::Context& Other) const noexcept {
  25. return memcmp(this, &Other, sizeof(Context)) != 0;
  26. }
  27. CapstoneDisassembler::CapstoneDisassembler(const CapstoneEngine& Engine) :
  28. _EngineRef(Engine),
  29. _Context(InvalidContext),
  30. _InsnPtr(nullptr)
  31. {
  32. cs_insn* insn;
  33. insn = cs_malloc(_EngineRef);
  34. if (insn == nullptr)
  35. throw CapstoneException(__BASE_FILE__, __LINE__, cs_errno(_EngineRef),
  36. TEXT("cs_malloc failed."));
  37. else
  38. _InsnObj.TakeOver(insn);
  39. }
  40. void CapstoneDisassembler::SetContext(const uint8_t* Opcodes, size_t Size, uint64_t Address) noexcept {
  41. _Context.Opcode.ConstPtr = Opcodes;
  42. _Context.OpcodesSize = Size;
  43. _Context.Address = Address;
  44. _InsnPtr = nullptr;
  45. }
  46. void CapstoneDisassembler::SetContext(const CapstoneDisassembler::Context& Context) noexcept {
  47. _Context = Context;
  48. _InsnPtr = nullptr;
  49. }
  50. const CapstoneDisassembler::Context& CapstoneDisassembler::GetContext() const noexcept {
  51. return _Context;
  52. }
  53. bool CapstoneDisassembler::Next() noexcept {
  54. bool bOk = cs_disasm_iter(_EngineRef,
  55. &_Context.Opcode.ConstPtr,
  56. &_Context.OpcodesSize,
  57. &_Context.Address,
  58. _InsnObj);
  59. if (bOk) {
  60. if (_InsnPtr == nullptr)
  61. _InsnPtr = _InsnObj;
  62. } else {
  63. _InsnPtr = nullptr;
  64. }
  65. return bOk;
  66. }
  67. cs_insn* CapstoneDisassembler::Instruction() const noexcept {
  68. return _InsnPtr;
  69. }
  70. CapstoneDisassembler::Context CapstoneDisassembler::InstructionContext() const noexcept {
  71. Context ContextOfInsn;
  72. ContextOfInsn.Opcode.Ptr = _Context.Opcode.Ptr - _InsnPtr->size;
  73. ContextOfInsn.OpcodesSize = _Context.OpcodesSize + _InsnPtr->size;
  74. ContextOfInsn.Address = _Context.Address - _InsnPtr->size;
  75. return ContextOfInsn;
  76. }
  77. CapstoneEngine::CapstoneEngine(cs_arch ArchType, cs_mode Mode) {
  78. cs_err status;
  79. csh handle;
  80. status = cs_open(ArchType, Mode, &handle);
  81. if (status != CS_ERR_OK)
  82. throw CapstoneException(__BASE_FILE__, __LINE__, status,
  83. TEXT("cs_open failed."));
  84. else
  85. _EngineObj.TakeOver(handle);
  86. }
  87. CapstoneEngine::operator csh() const noexcept {
  88. return _EngineObj.Get();
  89. }
  90. void CapstoneEngine::Option(cs_opt_type Type, size_t Value) {
  91. cs_err status;
  92. status = cs_option(_EngineObj, Type, Value);
  93. if (status != CS_ERR_OK)
  94. throw CapstoneException(__BASE_FILE__, __LINE__, status,
  95. TEXT("cs_open failed."));
  96. }
  97. CapstoneDisassembler CapstoneEngine::CreateDisassembler() const {
  98. return CapstoneDisassembler(*this);
  99. }