keystone_assembler.cpp 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. #include "keystone_assembler.hpp"
  2. #include "resource_traits/keystone/keystone_alloc.hpp"
  3. #define NKG_CURRENT_SOURCE_FILE() u8".\\navicat-patcher\\keystone_assembler.cpp"
  4. #define NKG_CURRENT_SOURCE_LINE() __LINE__
  5. namespace nkg {
  6. keystone_assembler::keystone_assembler(ks_arch architecture, ks_mode mode) {
  7. auto err = ks_open(architecture, mode, m_keystone_engine.unsafe_addressof());
  8. if (err != KS_ERR_OK) {
  9. throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"ks_open failed.");
  10. }
  11. }
  12. void keystone_assembler::option(ks_opt_type option_type, size_t option_value) {
  13. auto err = ks_option(m_keystone_engine.get(), option_type, option_value);
  14. if (err != KS_ERR_OK) {
  15. throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"ks_option failed.");
  16. }
  17. }
  18. [[nodiscard]]
  19. std::vector<uint8_t> keystone_assembler::assemble(std::string_view asm_string, uint64_t asm_address) const {
  20. resource_wrapper machine_code{ resource_traits::keystone::keystone_alloc{} };
  21. size_t machine_code_size = 0;
  22. size_t stat_count = 0;
  23. if (ks_asm(m_keystone_engine.get(), asm_string.data(), asm_address, machine_code.unsafe_addressof(), &machine_code_size, &stat_count) < 0) {
  24. auto err = ks_errno(m_keystone_engine.get());
  25. throw backend_error(NKG_CURRENT_SOURCE_FILE(), NKG_CURRENT_SOURCE_LINE(), err, u8"ks_asm failed.");
  26. }
  27. return std::vector<uint8_t>(machine_code.get(), machine_code.get() + machine_code_size);
  28. }
  29. }
  30. #undef NKG_CURRENT_SOURCE_LINE
  31. #undef NKG_CURRENT_SOURCE_FILE