keystone_assembler.cpp 1.6 KB

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