mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-20 12:13:57 +00:00
First step towards supporting icicle-emu (#175)
This PR aims to provide initial support for icicle-emu. It's not done yet, but things are making progress. As it contains interface adjustments and fixes for unicorn, merging the current state makes sense.
This commit is contained in:
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@@ -180,6 +180,7 @@ jobs:
|
||||
clang-version: 20
|
||||
- platform: iOS arm64
|
||||
runner: macos-latest
|
||||
rust-target: aarch64-apple-ios
|
||||
cmake-options: "-DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/cmake/toolchain/ios.cmake"
|
||||
- platform: macOS arm64
|
||||
runner: macos-latest
|
||||
@@ -188,10 +189,12 @@ jobs:
|
||||
- platform: Android x86_64
|
||||
runner: ubuntu-24.04
|
||||
abi: x86_64
|
||||
rust-target: x86_64-linux-android
|
||||
cmake-options: "-DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/cmake/toolchain/android-ndk.cmake"
|
||||
- platform: Android arm64-v8a
|
||||
runner: ubuntu-24.04
|
||||
abi: arm64-v8a
|
||||
rust-target: aarch64-linux-android
|
||||
cmake-options: "-DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/cmake/toolchain/android-ndk.cmake"
|
||||
steps:
|
||||
- name: Checkout Source
|
||||
@@ -202,6 +205,10 @@ jobs:
|
||||
- name: Install Ninja
|
||||
uses: seanmiddleditch/gha-setup-ninja@v6
|
||||
|
||||
- name: Install Rust Target
|
||||
if: "${{ matrix.rust-target }}"
|
||||
run: rustup target add ${{ matrix.rust-target }}
|
||||
|
||||
- name: Install Clang
|
||||
if: "${{ matrix.platform == 'Linux x86_64 Clang' }}"
|
||||
run: |
|
||||
|
||||
@@ -4,18 +4,13 @@ cmake_minimum_required(VERSION 3.26.4)
|
||||
|
||||
option(MOMO_ENABLE_SANITIZER "Enable sanitizer" OFF)
|
||||
option(MOMO_ENABLE_CLANG_TIDY "Enable clang-tidy checks" OFF)
|
||||
option(MOMO_ENABLE_RUST_CODE "Enable code parts written in rust" ON)
|
||||
option(MOMO_BUILD_AS_LIBRARY "Configure and Build the emulator as a shared library (without the samples and tests)" OFF)
|
||||
|
||||
set(MOMO_REFLECTION_LEVEL "0" CACHE STRING "Reflection level for the build")
|
||||
message(STATUS "Reflection level is set to: ${MOMO_REFLECTION_LEVEL}")
|
||||
add_compile_definitions(MOMO_REFLECTION_LEVEL=${MOMO_REFLECTION_LEVEL})
|
||||
|
||||
if(MOMO_BUILD_AS_LIBRARY)
|
||||
add_compile_definitions(MOMO_BUILD_AS_LIBRARY=1)
|
||||
else()
|
||||
add_compile_definitions(MOMO_BUILD_AS_LIBRARY=0)
|
||||
endif()
|
||||
|
||||
##########################################
|
||||
|
||||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON)
|
||||
|
||||
@@ -51,6 +51,7 @@ Click <a href="https://docs.google.com/presentation/d/1pha4tFfDMpVzJ_ehJJ21SA_HA
|
||||
* Windows 64-bit (click [here](https://github.com/momo5502/emulator/milestone/1) for cross-platform status)
|
||||
* CMake
|
||||
* Git
|
||||
* Rust (pass `-DMOMO_ENABLE_RUST_CODE=0` to cmake to disable requirement)
|
||||
|
||||
### Getting Started
|
||||
|
||||
|
||||
@@ -25,6 +25,22 @@ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
|
||||
|
||||
##########################################
|
||||
|
||||
if(MOMO_BUILD_AS_LIBRARY)
|
||||
add_compile_definitions(MOMO_BUILD_AS_LIBRARY=1)
|
||||
else()
|
||||
add_compile_definitions(MOMO_BUILD_AS_LIBRARY=0)
|
||||
endif()
|
||||
|
||||
##########################################
|
||||
|
||||
if(MOMO_ENABLE_RUST_CODE)
|
||||
add_compile_definitions(MOMO_ENABLE_RUST_CODE=1)
|
||||
else()
|
||||
add_compile_definitions(MOMO_ENABLE_RUST_CODE=0)
|
||||
endif()
|
||||
|
||||
##########################################
|
||||
|
||||
if(UNIX)
|
||||
momo_add_c_and_cxx_compile_options(
|
||||
-fvisibility=hidden
|
||||
|
||||
@@ -5,6 +5,11 @@ add_subdirectory(unicorn-emulator)
|
||||
add_subdirectory(windows-emulator)
|
||||
add_subdirectory(windows-gdb-stub)
|
||||
|
||||
if (MOMO_ENABLE_RUST_CODE)
|
||||
add_subdirectory(icicle-emulator)
|
||||
add_subdirectory(icicle)
|
||||
endif()
|
||||
|
||||
if (NOT MOMO_BUILD_AS_LIBRARY)
|
||||
add_subdirectory(analyzer)
|
||||
add_subdirectory(fuzzing-engine)
|
||||
|
||||
15
src/common/utils/object.hpp
Normal file
15
src/common/utils/object.hpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
namespace utils
|
||||
{
|
||||
struct object
|
||||
{
|
||||
object() = default;
|
||||
virtual ~object() = default;
|
||||
|
||||
object(object&&) = default;
|
||||
object(const object&) = default;
|
||||
object& operator=(object&&) = default;
|
||||
object& operator=(const object&) = default;
|
||||
};
|
||||
}
|
||||
@@ -11,5 +11,9 @@ enum class x64_hookable_instructions
|
||||
rdtscp,
|
||||
};
|
||||
|
||||
using x64_emulator =
|
||||
typed_emulator<uint64_t, x64_register, x64_register::rip, x64_register::rsp, x64_hookable_instructions>;
|
||||
struct x64_emulator
|
||||
: typed_emulator<uint64_t, x64_register, x64_register::rip, x64_register::rsp, x64_hookable_instructions>
|
||||
{
|
||||
virtual void set_segment_base(x64_register base, pointer_type value) = 0;
|
||||
virtual void load_gdt(pointer_type address, uint32_t limit) = 0;
|
||||
};
|
||||
|
||||
18
src/icicle-emulator/CMakeLists.txt
Normal file
18
src/icicle-emulator/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
|
||||
*.cpp
|
||||
*.hpp
|
||||
*.rc
|
||||
)
|
||||
|
||||
list(SORT SRC_FILES)
|
||||
|
||||
if(MOMO_BUILD_AS_LIBRARY)
|
||||
add_library(icicle-emulator STATIC ${SRC_FILES})
|
||||
else()
|
||||
add_library(icicle-emulator SHARED ${SRC_FILES})
|
||||
endif()
|
||||
|
||||
target_include_directories(icicle-emulator INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
target_link_libraries(icicle-emulator PUBLIC emulator)
|
||||
target_link_libraries(icicle-emulator PRIVATE emulator-common icicle)
|
||||
335
src/icicle-emulator/icicle_x64_emulator.cpp
Normal file
335
src/icicle-emulator/icicle_x64_emulator.cpp
Normal file
@@ -0,0 +1,335 @@
|
||||
#define ICICLE_EMULATOR_IMPL
|
||||
#include "icicle_x64_emulator.hpp"
|
||||
|
||||
#include <utils/object.hpp>
|
||||
|
||||
using icicle_emulator = struct icicle_emulator_;
|
||||
|
||||
extern "C"
|
||||
{
|
||||
using icicle_mmio_read_func = void(void* user, uint64_t address, size_t length, void* data);
|
||||
using icicle_mmio_write_func = void(void* user, uint64_t address, size_t length, const void* data);
|
||||
|
||||
using data_accessor_func = void(void* user, const void* data, size_t length);
|
||||
|
||||
icicle_emulator* icicle_create_emulator();
|
||||
int32_t icicle_protect_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions);
|
||||
int32_t icicle_map_memory(icicle_emulator*, uint64_t address, uint64_t length, uint8_t permissions);
|
||||
int32_t icicle_map_mmio(icicle_emulator*, uint64_t address, uint64_t length, icicle_mmio_read_func* read_callback,
|
||||
void* read_data, icicle_mmio_write_func* write_callback, void* write_data);
|
||||
int32_t icicle_unmap_memory(icicle_emulator*, uint64_t address, uint64_t length);
|
||||
int32_t icicle_read_memory(icicle_emulator*, uint64_t address, void* data, size_t length);
|
||||
int32_t icicle_write_memory(icicle_emulator*, uint64_t address, const void* data, size_t length);
|
||||
int32_t icicle_save_registers(icicle_emulator*, data_accessor_func* accessor, void* accessor_data);
|
||||
int32_t icicle_restore_registers(icicle_emulator*, const void* data, size_t length);
|
||||
uint32_t icicle_add_syscall_hook(icicle_emulator*, void (*callback)(void*), void* data);
|
||||
void icicle_remove_syscall_hook(icicle_emulator*, uint32_t id);
|
||||
size_t icicle_read_register(icicle_emulator*, int reg, void* data, size_t length);
|
||||
size_t icicle_write_register(icicle_emulator*, int reg, const void* data, size_t length);
|
||||
void icicle_start(icicle_emulator*);
|
||||
void icicle_destroy_emulator(icicle_emulator*);
|
||||
}
|
||||
|
||||
namespace icicle
|
||||
{
|
||||
namespace
|
||||
{
|
||||
void ice(const bool result, const std::string_view error)
|
||||
{
|
||||
if (!result)
|
||||
{
|
||||
throw std::runtime_error(std::string(error));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class icicle_x64_emulator : public x64_emulator
|
||||
{
|
||||
public:
|
||||
icicle_x64_emulator()
|
||||
: emu_(icicle_create_emulator())
|
||||
{
|
||||
if (!this->emu_)
|
||||
{
|
||||
throw std::runtime_error("Failed to create icicle emulator instance");
|
||||
}
|
||||
}
|
||||
|
||||
~icicle_x64_emulator() override
|
||||
{
|
||||
if (this->emu_)
|
||||
{
|
||||
icicle_destroy_emulator(this->emu_);
|
||||
this->emu_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void start(const uint64_t start, const uint64_t end, std::chrono::nanoseconds timeout,
|
||||
const size_t count) override
|
||||
{
|
||||
if (timeout.count() < 0)
|
||||
{
|
||||
timeout = {};
|
||||
}
|
||||
|
||||
(void)start;
|
||||
(void)end;
|
||||
(void)count;
|
||||
icicle_start(this->emu_);
|
||||
}
|
||||
|
||||
void stop() override
|
||||
{
|
||||
}
|
||||
|
||||
void load_gdt(const pointer_type address, const uint32_t limit) override
|
||||
{
|
||||
struct gdtr
|
||||
{
|
||||
uint32_t padding{};
|
||||
uint32_t limit{};
|
||||
uint64_t address{};
|
||||
};
|
||||
|
||||
const gdtr entry{.limit = limit, .address = address};
|
||||
static_assert(sizeof(gdtr) - offsetof(gdtr, limit) == 12);
|
||||
|
||||
this->write_register(x64_register::gdtr, &entry.limit, 12);
|
||||
}
|
||||
|
||||
void set_segment_base(const x64_register base, const pointer_type value) override
|
||||
{
|
||||
switch (base)
|
||||
{
|
||||
case x64_register::fs:
|
||||
case x64_register::fs_base:
|
||||
this->reg(x64_register::fs_base, value);
|
||||
break;
|
||||
case x64_register::gs:
|
||||
case x64_register::gs_base:
|
||||
this->reg(x64_register::gs_base, value);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
size_t write_raw_register(const int reg, const void* value, const size_t size) override
|
||||
{
|
||||
return icicle_write_register(this->emu_, reg, value, size);
|
||||
}
|
||||
|
||||
size_t read_raw_register(const int reg, void* value, const size_t size) override
|
||||
{
|
||||
return icicle_read_register(this->emu_, reg, value, size);
|
||||
}
|
||||
|
||||
void map_mmio(const uint64_t address, const size_t size, mmio_read_callback read_cb,
|
||||
mmio_write_callback write_cb) override
|
||||
{
|
||||
struct mmio_wrapper : utils::object
|
||||
{
|
||||
uint64_t base{};
|
||||
mmio_read_callback read_cb{};
|
||||
mmio_write_callback write_cb{};
|
||||
};
|
||||
|
||||
auto wrapper = std::make_unique<mmio_wrapper>();
|
||||
wrapper->base = address;
|
||||
wrapper->read_cb = std::move(read_cb);
|
||||
wrapper->write_cb = std::move(write_cb);
|
||||
|
||||
auto* ptr = wrapper.get();
|
||||
this->storage_.push_back(std::move(wrapper));
|
||||
|
||||
auto* read_wrapper = +[](void* user, const uint64_t address, const size_t length, void* data) {
|
||||
constexpr auto limit = sizeof(uint64_t);
|
||||
const auto* w = static_cast<mmio_wrapper*>(user);
|
||||
|
||||
for (size_t offset = 0; offset < length; offset += limit)
|
||||
{
|
||||
const auto max_read = std::min(limit, length - offset);
|
||||
const auto value = w->read_cb(address + offset - w->base, max_read);
|
||||
memcpy(static_cast<uint8_t*>(data) + offset, &value, max_read);
|
||||
}
|
||||
};
|
||||
|
||||
auto* write_wrapper = +[](void* user, const uint64_t address, const size_t length, const void* data) {
|
||||
constexpr auto limit = sizeof(uint64_t);
|
||||
const auto* w = static_cast<mmio_wrapper*>(user);
|
||||
|
||||
for (size_t offset = 0; offset < length; offset += limit)
|
||||
{
|
||||
uint64_t value{};
|
||||
const auto max_read = std::min(limit, length - offset);
|
||||
memcpy(&value, static_cast<const uint8_t*>(data) + offset, max_read);
|
||||
w->write_cb(address + offset - w->base, max_read, value);
|
||||
}
|
||||
};
|
||||
|
||||
icicle_map_mmio(this->emu_, address, size, read_wrapper, ptr, write_wrapper, ptr);
|
||||
}
|
||||
|
||||
void map_memory(const uint64_t address, const size_t size, memory_permission permissions) override
|
||||
{
|
||||
const auto res = icicle_map_memory(this->emu_, address, size, static_cast<uint8_t>(permissions));
|
||||
ice(res, "Failed to map memory");
|
||||
}
|
||||
|
||||
void unmap_memory(const uint64_t address, const size_t size) override
|
||||
{
|
||||
const auto res = icicle_unmap_memory(this->emu_, address, size);
|
||||
ice(res, "Failed to unmap memory");
|
||||
}
|
||||
|
||||
bool try_read_memory(const uint64_t address, void* data, const size_t size) const override
|
||||
{
|
||||
return icicle_read_memory(this->emu_, address, data, size);
|
||||
}
|
||||
|
||||
void read_memory(const uint64_t address, void* data, const size_t size) const override
|
||||
{
|
||||
const auto res = this->try_read_memory(address, data, size);
|
||||
ice(res, "Failed to read memory");
|
||||
}
|
||||
|
||||
void write_memory(const uint64_t address, const void* data, const size_t size) override
|
||||
{
|
||||
const auto res = icicle_write_memory(this->emu_, address, data, size);
|
||||
ice(res, "Failed to write memory");
|
||||
}
|
||||
|
||||
void apply_memory_protection(const uint64_t address, const size_t size, memory_permission permissions) override
|
||||
{
|
||||
const auto res = icicle_protect_memory(this->emu_, address, size, static_cast<uint8_t>(permissions));
|
||||
ice(res, "Failed to apply permissions");
|
||||
}
|
||||
|
||||
emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) override
|
||||
{
|
||||
if (static_cast<x64_hookable_instructions>(instruction_type) != x64_hookable_instructions::syscall)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto callback_store = std::make_unique<std::function<void()>>([c = std::move(callback)] {
|
||||
(void)c(); //
|
||||
});
|
||||
|
||||
const auto invoker = +[](void* cb) {
|
||||
(*static_cast<std::function<void()>*>(cb))(); //
|
||||
};
|
||||
|
||||
const auto id = icicle_add_syscall_hook(this->emu_, invoker, callback_store.get());
|
||||
this->syscall_hooks_[id] = std::move(callback_store);
|
||||
|
||||
return reinterpret_cast<emulator_hook*>(static_cast<size_t>(id));
|
||||
}
|
||||
|
||||
emulator_hook* hook_basic_block(basic_block_hook_callback callback) override
|
||||
{
|
||||
(void)callback;
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
emulator_hook* hook_edge_generation(edge_generation_hook_callback callback) override
|
||||
{
|
||||
(void)callback;
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
emulator_hook* hook_interrupt(interrupt_hook_callback callback) override
|
||||
{
|
||||
(void)callback;
|
||||
return nullptr;
|
||||
// throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_violation(uint64_t address, size_t size,
|
||||
memory_violation_hook_callback callback) override
|
||||
{
|
||||
(void)address;
|
||||
(void)size;
|
||||
(void)callback;
|
||||
return nullptr;
|
||||
// throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
emulator_hook* hook_memory_access(const uint64_t address, const size_t size, const memory_operation filter,
|
||||
complex_memory_hook_callback callback) override
|
||||
{
|
||||
if (filter == memory_permission::none)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
(void)address;
|
||||
(void)size;
|
||||
(void)callback;
|
||||
return nullptr;
|
||||
// throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
void delete_hook(emulator_hook* hook) override
|
||||
{
|
||||
const auto id = static_cast<uint32_t>(reinterpret_cast<size_t>(hook));
|
||||
const auto entry = this->syscall_hooks_.find(id);
|
||||
if (entry == this->syscall_hooks_.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
icicle_remove_syscall_hook(this->emu_, id);
|
||||
this->syscall_hooks_.erase(entry);
|
||||
}
|
||||
|
||||
void serialize_state(utils::buffer_serializer& buffer, const bool is_snapshot) const override
|
||||
{
|
||||
(void)buffer;
|
||||
(void)is_snapshot;
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
void deserialize_state(utils::buffer_deserializer& buffer, const bool is_snapshot) override
|
||||
{
|
||||
(void)buffer;
|
||||
(void)is_snapshot;
|
||||
throw std::runtime_error("Not implemented");
|
||||
}
|
||||
|
||||
std::vector<std::byte> save_registers() override
|
||||
{
|
||||
std::vector<std::byte> data{};
|
||||
auto* accessor = +[](void* user, const void* data, const size_t length) {
|
||||
auto& vec = *static_cast<std::vector<std::byte>*>(user);
|
||||
vec.resize(length);
|
||||
memcpy(vec.data(), data, length);
|
||||
};
|
||||
|
||||
icicle_save_registers(this->emu_, accessor, &data);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void restore_registers(const std::vector<std::byte>& register_data) override
|
||||
{
|
||||
icicle_restore_registers(this->emu_, register_data.data(), register_data.size());
|
||||
}
|
||||
|
||||
bool has_violation() const override
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::list<std::unique_ptr<utils::object>> storage_{};
|
||||
using syscall_hook_storage = std::unique_ptr<std::function<void()>>;
|
||||
std::unordered_map<uint32_t, syscall_hook_storage> syscall_hooks_{};
|
||||
icicle_emulator* emu_{};
|
||||
};
|
||||
|
||||
std::unique_ptr<x64_emulator> create_x64_emulator()
|
||||
{
|
||||
return std::make_unique<icicle_x64_emulator>();
|
||||
}
|
||||
}
|
||||
19
src/icicle-emulator/icicle_x64_emulator.hpp
Normal file
19
src/icicle-emulator/icicle_x64_emulator.hpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <x64_emulator.hpp>
|
||||
#include "platform/platform.hpp"
|
||||
|
||||
#ifdef ICICLE_EMULATOR_IMPL
|
||||
#define ICICLE_EMULATOR_DLL_STORAGE EXPORT_SYMBOL
|
||||
#else
|
||||
#define ICICLE_EMULATOR_DLL_STORAGE IMPORT_SYMBOL
|
||||
#endif
|
||||
|
||||
namespace icicle
|
||||
{
|
||||
#if !MOMO_BUILD_AS_LIBRARY
|
||||
ICICLE_EMULATOR_DLL_STORAGE
|
||||
#endif
|
||||
std::unique_ptr<x64_emulator> create_x64_emulator();
|
||||
}
|
||||
2
src/icicle/.gitignore
vendored
Normal file
2
src/icicle/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/target
|
||||
/Ghidra
|
||||
59
src/icicle/CMakeLists.txt
Normal file
59
src/icicle/CMakeLists.txt
Normal file
@@ -0,0 +1,59 @@
|
||||
include(ExternalProject)
|
||||
|
||||
set(ICICLE_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/cargo-build)
|
||||
set(ICICLE_ARTIFACT_DIR ${ICICLE_BUILD_DIR}/$<IF:$<CONFIG:Debug>,debug,release>)
|
||||
|
||||
set(ICICLE_RUST_PROJECT_NAME "icicle")
|
||||
set(ICICLE_RUST_LIBNAME "lib${ICICLE_RUST_PROJECT_NAME}.a")
|
||||
|
||||
if(MSVC)
|
||||
set(ICICLE_RUST_LIBNAME "${ICICLE_RUST_PROJECT_NAME}.lib")
|
||||
endif()
|
||||
|
||||
set(CARGO_TRIPLE)
|
||||
set(CARGO_OPTIONS)
|
||||
|
||||
if(CMAKE_SYSTEM_NAME STREQUAL "iOS")
|
||||
set(CARGO_TRIPLE "aarch64-apple-ios")
|
||||
elseif(CMAKE_SYSTEM_NAME STREQUAL "Android")
|
||||
if(CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a")
|
||||
set(CARGO_TRIPLE "aarch64-linux-android")
|
||||
else()
|
||||
set(CARGO_TRIPLE "${CMAKE_ANDROID_ARCH_ABI}-linux-android")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(CARGO_TRIPLE)
|
||||
set(CARGO_OPTIONS ${CARGO_OPTIONS} "--target=${CARGO_TRIPLE}")
|
||||
set(ICICLE_ARTIFACT_DIR ${ICICLE_BUILD_DIR}/${CARGO_TRIPLE}/$<IF:$<CONFIG:Debug>,debug,release>)
|
||||
endif()
|
||||
|
||||
|
||||
set(ICICLE_RUST_LIB ${ICICLE_ARTIFACT_DIR}/${ICICLE_RUST_LIBNAME})
|
||||
|
||||
ExternalProject_Add(
|
||||
icicle-rust-project
|
||||
PREFIX ${CMAKE_CURRENT_BINARY_DIR}
|
||||
SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}
|
||||
BINARY_DIR ${CMAKE_CURRENT_LIST_DIR}
|
||||
CONFIGURE_COMMAND ""
|
||||
BUILD_COMMAND ${CMAKE_COMMAND} -E env "CARGO_TARGET_DIR=${ICICLE_BUILD_DIR}" cargo build ${CARGO_OPTIONS} --lib --profile $<IF:$<CONFIG:Debug>,dev,release>
|
||||
INSTALL_COMMAND ""
|
||||
USES_TERMINAL_CONFIGURE 1
|
||||
USES_TERMINAL_BUILD 1
|
||||
BUILD_ALWAYS 1
|
||||
BUILD_BYPRODUCTS ${ICICLE_RUST_LIB}
|
||||
)
|
||||
|
||||
add_library(icicle INTERFACE)
|
||||
add_dependencies(icicle icicle-rust-project)
|
||||
target_link_libraries(icicle INTERFACE ${ICICLE_RUST_LIB})
|
||||
|
||||
if(MSVC)
|
||||
target_link_libraries(icicle INTERFACE
|
||||
ws2_32.lib
|
||||
Userenv.lib
|
||||
ntdll.lib
|
||||
Bcrypt.lib
|
||||
)
|
||||
endif()
|
||||
959
src/icicle/Cargo.lock
generated
Normal file
959
src/icicle/Cargo.lock
generated
Normal file
@@ -0,0 +1,959 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
dependencies = [
|
||||
"cpp_demangle",
|
||||
"fallible-iterator",
|
||||
"gimli",
|
||||
"memmap2",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"smallvec",
|
||||
"typed-arena",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||
|
||||
[[package]]
|
||||
name = "arbitrary"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c8214115b7bf84099f1309324e63141d4c5d7cc26862f97a0a857dbefe165bd"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "1.11.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "531a9155a481e2ee699d4f98f43c0ca4ff8ee1bfd55c31e9e98fb29d2b176fe0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.17.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
|
||||
|
||||
[[package]]
|
||||
name = "bytemuck"
|
||||
version = "1.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6b1fc10dbac614ebc03540c9dbd60e83887fda27794998c6528f1782047d540"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cpp_demangle"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96e58d342ad113c2b878f16d5d034c03be492ae460cdbc02b7f0f2284d310c7d"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27711210499725bafe52c320a988e27283e6cf477ee8edac57e8275bef8ea550"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"cranelift-frontend",
|
||||
"cranelift-module",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bforest"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "540b193ff98b825a1f250a75b3118911af918a734154c69d80bcfcf91e7e9522"
|
||||
dependencies = [
|
||||
"cranelift-entity",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-bitset"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7cb269598b9557ab942d687d3c1086d77c4b50dcf35813f3a65ba306fd42279"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46566d7c83a8bff4150748d66020f4c7224091952aa4b4df1ec4959c39d937a1"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"cranelift-bforest",
|
||||
"cranelift-bitset",
|
||||
"cranelift-codegen-meta",
|
||||
"cranelift-codegen-shared",
|
||||
"cranelift-control",
|
||||
"cranelift-entity",
|
||||
"cranelift-isle",
|
||||
"gimli",
|
||||
"hashbrown 0.14.5",
|
||||
"log",
|
||||
"regalloc2",
|
||||
"rustc-hash",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-meta"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2df8a86a34236cc75a8a6a271973da779c2aeb36c43b6e14da474cf931317082"
|
||||
dependencies = [
|
||||
"cranelift-codegen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-codegen-shared"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf75340b6a57b7c7c1b74f10d3d90883ee6d43a554be8131a4046c2ebcf5eb65"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-control"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e84495bc5d23d86aad8c86f8ade4af765b94882af60d60e271d3153942f1978"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-entity"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "963c17147b80df351965e57c04d20dbedc85bcaf44c3436780a59a3f1ff1b1c2"
|
||||
dependencies = [
|
||||
"cranelift-bitset",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-frontend"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "727f02acbc4b4cb2ba38a6637101d579db50190df1dd05168c68e762851a3dd5"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"log",
|
||||
"smallvec",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-isle"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32b00cc2e03c748f2531eea01c871f502b909d30295fdcad43aec7bf5c5b4667"
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-jit"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f74630af581f32b99c8f4e06ee45799383ecc0795e3ff8aa86b7584bb2d643fd"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
"cranelift-control",
|
||||
"cranelift-entity",
|
||||
"cranelift-module",
|
||||
"cranelift-native",
|
||||
"libc",
|
||||
"log",
|
||||
"region",
|
||||
"target-lexicon",
|
||||
"wasmtime-jit-icache-coherence",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-module"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6aaa16c4f18a15be310df221ea544f516acc42fc58ca96e09a3d08651744efa1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cranelift-codegen",
|
||||
"cranelift-control",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cranelift-native"
|
||||
version = "0.113.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbeaf978dc7c1a2de8bbb9162510ed218eb156697bc45590b8fbdd69bb08e8de"
|
||||
dependencies = [
|
||||
"cranelift-codegen",
|
||||
"libc",
|
||||
"target-lexicon",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crunchy"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
|
||||
|
||||
[[package]]
|
||||
name = "equivalent"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fallible-iterator"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foldhash"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
dependencies = [
|
||||
"fallible-iterator",
|
||||
"indexmap",
|
||||
"stable_deref_trait",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7db2ff139bba50379da6aa0766b52fdcb62cb5b263009b09ed58ba604e14bbd1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.15.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf151400ff0baff5465007dd2f3e717f3fe502074ca563069ce3a6629d07b289"
|
||||
dependencies = [
|
||||
"foldhash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"icicle-cpu",
|
||||
"icicle-vm",
|
||||
"pcode",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-cpu"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#6e9fd3e34aec440ac92c1f49f4a70fc288949de9"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"ahash",
|
||||
"anyhow",
|
||||
"bitflags 2.9.0",
|
||||
"bytemuck",
|
||||
"gimli",
|
||||
"half",
|
||||
"icicle-mem",
|
||||
"object",
|
||||
"pcode",
|
||||
"sleigh-runtime",
|
||||
"target-lexicon",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-jit"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#6e9fd3e34aec440ac92c1f49f4a70fc288949de9"
|
||||
dependencies = [
|
||||
"cranelift",
|
||||
"cranelift-codegen",
|
||||
"cranelift-jit",
|
||||
"cranelift-module",
|
||||
"cranelift-native",
|
||||
"icicle-cpu",
|
||||
"memoffset",
|
||||
"pcode",
|
||||
"target-lexicon",
|
||||
"tracing",
|
||||
"wasmtime-jit-debug",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-linux"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#6e9fd3e34aec440ac92c1f49f4a70fc288949de9"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"bstr",
|
||||
"bytemuck",
|
||||
"icicle-cpu",
|
||||
"object",
|
||||
"pcode",
|
||||
"sleigh-runtime",
|
||||
"target-lexicon",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-mem"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#6e9fd3e34aec440ac92c1f49f4a70fc288949de9"
|
||||
dependencies = [
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "icicle-vm"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#6e9fd3e34aec440ac92c1f49f4a70fc288949de9"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"icicle-cpu",
|
||||
"icicle-jit",
|
||||
"icicle-linux",
|
||||
"ihex",
|
||||
"object",
|
||||
"pcode",
|
||||
"ron",
|
||||
"serde",
|
||||
"serde-xml-rs",
|
||||
"sleigh-compile",
|
||||
"sleigh-runtime",
|
||||
"target-lexicon",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ihex"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "365a784774bb381e8c19edb91190a90d7f2625e057b55de2bc0f6b57bc779ff2"
|
||||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.15.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.171"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.4.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
||||
|
||||
[[package]]
|
||||
name = "mach2"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
|
||||
dependencies = [
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"flate2",
|
||||
"hashbrown 0.15.2",
|
||||
"indexmap",
|
||||
"memchr",
|
||||
"ruzstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc"
|
||||
|
||||
[[package]]
|
||||
name = "pcode"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#6e9fd3e34aec440ac92c1f49f4a70fc288949de9"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.94"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regalloc2"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0"
|
||||
dependencies = [
|
||||
"hashbrown 0.14.5",
|
||||
"log",
|
||||
"rustc-hash",
|
||||
"slice-group-by",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "region"
|
||||
version = "3.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"libc",
|
||||
"mach2",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ron"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"bitflags 2.9.0",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.38.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
|
||||
dependencies = [
|
||||
"bitflags 2.9.0",
|
||||
"errno",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruzstd"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fad02996bfc73da3e301efe90b1837be9ed8f4a462b6ed410aa35d00381de89f"
|
||||
dependencies = [
|
||||
"twox-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-xml-rs"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb3aa78ecda1ebc9ec9847d5d3aba7d618823446a049ba2491940506da6e2782"
|
||||
dependencies = [
|
||||
"log",
|
||||
"serde",
|
||||
"thiserror",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.219"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sleigh-compile"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#6e9fd3e34aec440ac92c1f49f4a70fc288949de9"
|
||||
dependencies = [
|
||||
"pcode",
|
||||
"serde",
|
||||
"serde-xml-rs",
|
||||
"serde_derive",
|
||||
"sleigh-parse",
|
||||
"sleigh-runtime",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sleigh-parse"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#6e9fd3e34aec440ac92c1f49f4a70fc288949de9"
|
||||
|
||||
[[package]]
|
||||
name = "sleigh-runtime"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/icicle-emu/icicle-emu#6e9fd3e34aec440ac92c1f49f4a70fc288949de9"
|
||||
dependencies = [
|
||||
"pcode",
|
||||
"sleigh-parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slice-group-by"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.100"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "target-lexicon"
|
||||
version = "0.12.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.69"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||
dependencies = [
|
||||
"pin-project-lite",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
|
||||
|
||||
[[package]]
|
||||
name = "twox-hash"
|
||||
version = "1.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97fee6b57c6a41524a810daee9286c02d7752c4253064d0b05472833a438f675"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typed-arena"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-jit-debug"
|
||||
version = "26.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f02a0118d471de665565ed200bc56673eaa10cc8e223dfe2cef5d50ed0d9d143"
|
||||
dependencies = [
|
||||
"object",
|
||||
"rustix",
|
||||
"wasmtime-versioned-export-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-jit-icache-coherence"
|
||||
version = "26.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da47fba49af72581bc0dc67c8faaf5ee550e6f106e285122a184a675193701a5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasmtime-versioned-export-macros"
|
||||
version = "26.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db8efb877c9e5e67239d4553bb44dd2a34ae5cfb728f3cf2c5e64439c6ca6ee7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-sys"
|
||||
version = "0.59.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
12
src/icicle/Cargo.toml
Normal file
12
src/icicle/Cargo.toml
Normal file
@@ -0,0 +1,12 @@
|
||||
[package]
|
||||
name = "icicle"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
icicle-vm = { git = "https://github.com/icicle-emu/icicle-emu" }
|
||||
icicle-cpu = { git = "https://github.com/icicle-emu/icicle-emu" }
|
||||
pcode = { git = "https://github.com/icicle-emu/icicle-emu" }
|
||||
367
src/icicle/src/icicle.rs
Normal file
367
src/icicle/src/icicle.rs
Normal file
@@ -0,0 +1,367 @@
|
||||
use icicle_cpu::ValueSource;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::registers;
|
||||
|
||||
fn create_x64_vm() -> icicle_vm::Vm {
|
||||
let mut cpu_config = icicle_vm::cpu::Config::from_target_triple("x86_64-none");
|
||||
cpu_config.enable_jit = true;
|
||||
cpu_config.enable_jit_mem = true;
|
||||
cpu_config.enable_shadow_stack = false;
|
||||
cpu_config.enable_recompilation = true;
|
||||
cpu_config.track_uninitialized = false;
|
||||
cpu_config.optimize_instructions = true;
|
||||
cpu_config.optimize_block = false;
|
||||
|
||||
return icicle_vm::build(&cpu_config).unwrap();
|
||||
}
|
||||
|
||||
fn map_permissions(foreign_permissions: u8) -> u8 {
|
||||
const FOREIGN_READ: u8 = 1 << 0;
|
||||
const FOREIGN_WRITE: u8 = 1 << 1;
|
||||
const FOREIGN_EXEC: u8 = 1 << 2;
|
||||
|
||||
let mut permissions: u8 = 0;
|
||||
|
||||
if (foreign_permissions & FOREIGN_READ) != 0 {
|
||||
permissions |= icicle_vm::cpu::mem::perm::READ;
|
||||
}
|
||||
|
||||
if (foreign_permissions & FOREIGN_WRITE) != 0 {
|
||||
permissions |= icicle_vm::cpu::mem::perm::WRITE;
|
||||
}
|
||||
|
||||
if (foreign_permissions & FOREIGN_EXEC) != 0 {
|
||||
permissions |= icicle_vm::cpu::mem::perm::EXEC;
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
#[repr(u8)]
|
||||
#[allow(dead_code)]
|
||||
#[derive(PartialEq)]
|
||||
enum HookType {
|
||||
Syscall = 1,
|
||||
Read,
|
||||
Write,
|
||||
Execute,
|
||||
Unknown,
|
||||
}
|
||||
|
||||
fn u8_to_hook_type_unsafe(value: u8) -> HookType {
|
||||
unsafe { std::mem::transmute(value) }
|
||||
}
|
||||
|
||||
fn split_hook_id(id: u32) -> (u32, HookType) {
|
||||
let hook_id = id & 0xFFFFFF;
|
||||
let hook_type = u8_to_hook_type_unsafe((id >> 24) as u8);
|
||||
|
||||
return (hook_id, hook_type);
|
||||
}
|
||||
|
||||
fn qualify_hook_id(hook_id: u32, hook_type: HookType) -> u32 {
|
||||
let hook_type: u32 = (hook_type as u8).into();
|
||||
let hook_type_mask: u32 = hook_type << 24;
|
||||
return (hook_id | hook_type_mask).into();
|
||||
}
|
||||
|
||||
pub struct HookContainer<Func: ?Sized> {
|
||||
hook_id: u32,
|
||||
hooks: HashMap<u32, Box<Func>>,
|
||||
}
|
||||
|
||||
impl<Func: ?Sized> HookContainer<Func> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
hook_id: 0,
|
||||
hooks: HashMap::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_hook(&mut self, callback: Box<Func>) -> u32 {
|
||||
self.hook_id += 1;
|
||||
let id = self.hook_id;
|
||||
self.hooks.insert(id, callback);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
pub fn get_hooks(&self) -> &HashMap<u32, Box<Func>> {
|
||||
return &self.hooks;
|
||||
}
|
||||
|
||||
pub fn remove_hook(&mut self, id: u32) {
|
||||
self.hooks.remove(&id);
|
||||
}
|
||||
}
|
||||
|
||||
pub struct IcicleEmulator {
|
||||
vm: icicle_vm::Vm,
|
||||
reg: registers::X64RegisterNodes,
|
||||
syscall_hooks: HookContainer<dyn Fn()>,
|
||||
}
|
||||
|
||||
pub struct MmioHandler {
|
||||
read_handler: Box<dyn Fn(u64, &mut [u8])>,
|
||||
write_handler: Box<dyn Fn(u64, &[u8])>,
|
||||
}
|
||||
|
||||
impl MmioHandler {
|
||||
pub fn new(
|
||||
read_function: Box<dyn Fn(u64, &mut [u8])>,
|
||||
write_function: Box<dyn Fn(u64, &[u8])>,
|
||||
) -> Self {
|
||||
Self {
|
||||
read_handler: read_function,
|
||||
write_handler: write_function,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl icicle_cpu::mem::IoMemory for MmioHandler {
|
||||
fn read(&mut self, addr: u64, buf: &mut [u8]) -> icicle_cpu::mem::MemResult<()> {
|
||||
(self.read_handler)(addr, buf);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
fn write(&mut self, addr: u64, value: &[u8]) -> icicle_cpu::mem::MemResult<()> {
|
||||
(self.write_handler)(addr, value);
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
impl IcicleEmulator {
|
||||
pub fn new() -> Self {
|
||||
let virtual_machine = create_x64_vm();
|
||||
Self {
|
||||
reg: registers::X64RegisterNodes::new(&virtual_machine.cpu.arch),
|
||||
vm: virtual_machine,
|
||||
syscall_hooks: HookContainer::new(),
|
||||
}
|
||||
}
|
||||
|
||||
fn get_mem(&mut self) -> &mut icicle_vm::cpu::Mmu {
|
||||
return &mut self.vm.cpu.mem;
|
||||
}
|
||||
|
||||
pub fn start(&mut self) {
|
||||
loop {
|
||||
let reason = self.vm.run();
|
||||
|
||||
let invoke_syscall = match reason {
|
||||
icicle_vm::VmExit::UnhandledException((code, _)) => {
|
||||
code == icicle_cpu::ExceptionCode::Syscall
|
||||
}
|
||||
_ => false,
|
||||
};
|
||||
|
||||
if !invoke_syscall {
|
||||
break;
|
||||
}
|
||||
|
||||
for (_key, func) in self.syscall_hooks.get_hooks() {
|
||||
func();
|
||||
}
|
||||
|
||||
self.vm.cpu.write_pc(self.vm.cpu.read_pc() + 2);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_syscall_hook(&mut self, callback: Box<dyn Fn()>) -> u32 {
|
||||
let hook_id = self.syscall_hooks.add_hook(callback);
|
||||
return qualify_hook_id(hook_id, HookType::Syscall);
|
||||
}
|
||||
|
||||
pub fn remove_hook(&mut self, id: u32) {
|
||||
let (hook_id, hook_type) = split_hook_id(id);
|
||||
|
||||
match hook_type {
|
||||
HookType::Syscall => self.syscall_hooks.remove_hook(hook_id),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_memory(&mut self, address: u64, length: u64, permissions: u8) -> bool {
|
||||
const MAPPING_PERMISSIONS: u8 = icicle_vm::cpu::mem::perm::MAP
|
||||
| icicle_vm::cpu::mem::perm::INIT
|
||||
| icicle_vm::cpu::mem::perm::IN_CODE_CACHE;
|
||||
|
||||
let native_permissions = map_permissions(permissions);
|
||||
|
||||
let mapping = icicle_vm::cpu::mem::Mapping {
|
||||
perm: native_permissions | MAPPING_PERMISSIONS,
|
||||
value: 0x0,
|
||||
};
|
||||
|
||||
let layout = icicle_vm::cpu::mem::AllocLayout {
|
||||
addr: Some(address),
|
||||
size: length,
|
||||
align: 0x1000,
|
||||
};
|
||||
|
||||
let res = self.get_mem().alloc_memory(layout, mapping);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn map_mmio(
|
||||
&mut self,
|
||||
address: u64,
|
||||
length: u64,
|
||||
read_function: Box<dyn Fn(u64, &mut [u8])>,
|
||||
write_function: Box<dyn Fn(u64, &[u8])>,
|
||||
) -> bool {
|
||||
let mem = self.get_mem();
|
||||
|
||||
let handler = MmioHandler::new(read_function, write_function);
|
||||
let handler_id = mem.register_io_handler(handler);
|
||||
|
||||
let layout = icicle_vm::cpu::mem::AllocLayout {
|
||||
addr: Some(address),
|
||||
size: length,
|
||||
align: 0x1000,
|
||||
};
|
||||
|
||||
let res = mem.alloc_memory(layout, handler_id);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn unmap_memory(&mut self, address: u64, length: u64) -> bool {
|
||||
return self.get_mem().unmap_memory_len(address, length);
|
||||
}
|
||||
|
||||
pub fn protect_memory(&mut self, address: u64, length: u64, permissions: u8) -> bool {
|
||||
let native_permissions = map_permissions(permissions);
|
||||
let res = self
|
||||
.get_mem()
|
||||
.update_perm(address, length, native_permissions);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn write_memory(&mut self, address: u64, data: &[u8]) -> bool {
|
||||
let res = self
|
||||
.get_mem()
|
||||
.write_bytes(address, data, icicle_vm::cpu::mem::perm::NONE);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn read_memory(&mut self, address: u64, data: &mut [u8]) -> bool {
|
||||
let res = self
|
||||
.get_mem()
|
||||
.read_bytes(address, data, icicle_vm::cpu::mem::perm::NONE);
|
||||
return res.is_ok();
|
||||
}
|
||||
|
||||
pub fn save_registers(&self) -> Vec<u8> {
|
||||
const REG_SIZE: usize = std::mem::size_of::<icicle_cpu::Regs>();
|
||||
unsafe {
|
||||
let data: [u8; REG_SIZE] = self.vm.cpu.regs.read_at(0);
|
||||
return data.to_vec();
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restore_registers(&mut self, data: &[u8]) {
|
||||
const REG_SIZE: usize = std::mem::size_of::<icicle_cpu::Regs>();
|
||||
|
||||
let mut buffer: [u8; REG_SIZE] = [0; REG_SIZE];
|
||||
let size = std::cmp::min(REG_SIZE, data.len());
|
||||
buffer.copy_from_slice(&data[..size]);
|
||||
|
||||
unsafe {
|
||||
self.vm.cpu.regs.write_at(0, buffer);
|
||||
};
|
||||
}
|
||||
|
||||
pub fn read_register(&mut self, reg: registers::X64Register, buffer: &mut [u8]) -> usize {
|
||||
let reg_node = self.reg.get_node(reg);
|
||||
|
||||
let res = self.vm.cpu.read_dynamic(pcode::Value::Var(reg_node));
|
||||
let bytes: [u8; 32] = res.zxt();
|
||||
|
||||
let len = std::cmp::min(bytes.len(), buffer.len());
|
||||
buffer[..len].copy_from_slice(&bytes[..len]);
|
||||
|
||||
return reg_node.size.into();
|
||||
}
|
||||
|
||||
pub fn write_register(&mut self, reg: registers::X64Register, data: &[u8]) -> usize {
|
||||
let reg_node = self.reg.get_node(reg);
|
||||
|
||||
let mut buffer = [0u8; 32];
|
||||
let len = std::cmp::min(data.len(), buffer.len());
|
||||
buffer[..len].copy_from_slice(&data[..len]);
|
||||
|
||||
//let value = icicle_cpu::regs::DynamicValue::new(buffer, reg_node.size.into());
|
||||
//self.vm.cpu.write_trunc(reg_node, value);
|
||||
|
||||
match reg_node.size {
|
||||
1 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 1]>(reg_node, buffer[..1].try_into().expect("")),
|
||||
2 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 2]>(reg_node, buffer[..2].try_into().expect("")),
|
||||
3 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 3]>(reg_node, buffer[..3].try_into().expect("")),
|
||||
4 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 4]>(reg_node, buffer[..4].try_into().expect("")),
|
||||
5 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 5]>(reg_node, buffer[..5].try_into().expect("")),
|
||||
6 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 6]>(reg_node, buffer[..6].try_into().expect("")),
|
||||
7 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 7]>(reg_node, buffer[..7].try_into().expect("")),
|
||||
8 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 8]>(reg_node, buffer[..8].try_into().expect("")),
|
||||
9 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 9]>(reg_node, buffer[..9].try_into().expect("")),
|
||||
10 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 10]>(reg_node, buffer[..10].try_into().expect("")),
|
||||
11 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 11]>(reg_node, buffer[..11].try_into().expect("")),
|
||||
12 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 12]>(reg_node, buffer[..12].try_into().expect("")),
|
||||
13 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 13]>(reg_node, buffer[..13].try_into().expect("")),
|
||||
14 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 14]>(reg_node, buffer[..14].try_into().expect("")),
|
||||
15 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 15]>(reg_node, buffer[..15].try_into().expect("")),
|
||||
16 => self
|
||||
.vm
|
||||
.cpu
|
||||
.write_var::<[u8; 16]>(reg_node, buffer[..16].try_into().expect("")),
|
||||
_ => panic!("invalid dynamic value size"),
|
||||
}
|
||||
|
||||
return reg_node.size.into();
|
||||
}
|
||||
}
|
||||
186
src/icicle/src/lib.rs
Normal file
186
src/icicle/src/lib.rs
Normal file
@@ -0,0 +1,186 @@
|
||||
mod icicle;
|
||||
mod registers;
|
||||
|
||||
use icicle::IcicleEmulator;
|
||||
use registers::X64Register;
|
||||
use std::os::raw::c_void;
|
||||
|
||||
fn to_cbool(value: bool) -> i32 {
|
||||
if value {
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_create_emulator() -> *mut c_void {
|
||||
let emulator = Box::new(IcicleEmulator::new());
|
||||
return Box::into_raw(emulator) as *mut c_void;
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_start(ptr: *mut c_void) {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
emulator.start();
|
||||
}
|
||||
}
|
||||
|
||||
type RawFunction = extern "C" fn(*mut c_void);
|
||||
type DataFunction = extern "C" fn(*mut c_void, *const c_void, usize);
|
||||
type MmioReadFunction = extern "C" fn(*mut c_void, u64, usize, *mut c_void);
|
||||
type MmioWriteFunction = extern "C" fn(*mut c_void, u64, usize, *const c_void);
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_map_mmio(
|
||||
ptr: *mut c_void,
|
||||
address: u64,
|
||||
length: u64,
|
||||
read_cb: MmioReadFunction,
|
||||
read_data: *mut c_void,
|
||||
write_cb: MmioWriteFunction,
|
||||
write_data: *mut c_void,
|
||||
) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
|
||||
let read_wrapper = Box::new(move |addr: u64, data: &mut [u8]| {
|
||||
let raw_pointer: *mut u8 = data.as_mut_ptr();
|
||||
read_cb(read_data, addr, data.len(), raw_pointer as *mut c_void);
|
||||
});
|
||||
|
||||
let write_wrapper = Box::new(move |addr: u64, data: &[u8]| {
|
||||
let raw_pointer: *const u8 = data.as_ptr();
|
||||
write_cb(write_data, addr, data.len(), raw_pointer as *const c_void);
|
||||
});
|
||||
|
||||
let res = emulator.map_mmio(address, length, read_wrapper, write_wrapper);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_map_memory(ptr: *mut c_void, address: u64, length: u64, permissions: u8) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let res = emulator.map_memory(address, length, permissions);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_unmap_memory(ptr: *mut c_void, address: u64, length: u64) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let res = emulator.unmap_memory(address, length);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_protect_memory(ptr: *mut c_void, address: u64, length: u64, permissions: u8) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let res = emulator.protect_memory(address, length, permissions);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_write_memory(
|
||||
ptr: *mut c_void,
|
||||
address: u64,
|
||||
data: *const c_void,
|
||||
size: usize,
|
||||
) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts(data as *const u8, size);
|
||||
let res = emulator.write_memory(address, u8_slice);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_save_registers(ptr: *mut c_void, accessor: DataFunction, accessor_data: *mut c_void) {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let registers = emulator.save_registers();
|
||||
accessor(accessor_data, registers.as_ptr() as *const c_void, registers.len());
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_restore_registers(ptr: *mut c_void, data: *const c_void, size: usize) {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts(data as *const u8, size);
|
||||
emulator.restore_registers(u8_slice);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_read_memory(ptr: *mut c_void, address: u64, data: *mut c_void, size: usize) -> i32 {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts_mut(data as *mut u8, size);
|
||||
let res = emulator.read_memory(address, u8_slice);
|
||||
return to_cbool(res);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_add_syscall_hook(ptr: *mut c_void, callback: RawFunction, data: *mut c_void) {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
emulator.add_syscall_hook(Box::new(move || callback(data)));
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_remove_syscall_hook(ptr: *mut c_void, id: u32) {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
emulator.remove_hook(id);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_read_register(
|
||||
ptr: *mut c_void,
|
||||
reg: X64Register,
|
||||
data: *mut c_void,
|
||||
size: usize,
|
||||
) -> usize {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts_mut(data as *mut u8, size);
|
||||
return emulator.read_register(reg, u8_slice);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_write_register(
|
||||
ptr: *mut c_void,
|
||||
reg: X64Register,
|
||||
data: *const c_void,
|
||||
size: usize,
|
||||
) -> usize {
|
||||
unsafe {
|
||||
let emulator = &mut *(ptr as *mut IcicleEmulator);
|
||||
let u8_slice = std::slice::from_raw_parts(data as *const u8, size);
|
||||
return emulator.write_register(reg, u8_slice);
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub fn icicle_destroy_emulator(ptr: *mut c_void) {
|
||||
if ptr.is_null() {
|
||||
return;
|
||||
}
|
||||
|
||||
unsafe {
|
||||
let _ = Box::from_raw(ptr as *mut IcicleEmulator);
|
||||
}
|
||||
}
|
||||
949
src/icicle/src/registers.rs
Normal file
949
src/icicle/src/registers.rs
Normal file
@@ -0,0 +1,949 @@
|
||||
#[repr(i32)]
|
||||
#[derive(PartialEq)]
|
||||
pub enum X64Register {
|
||||
Invalid = 0,
|
||||
Ah,
|
||||
Al,
|
||||
Ax,
|
||||
Bh,
|
||||
Bl,
|
||||
Bp,
|
||||
Bpl,
|
||||
Bx,
|
||||
Ch,
|
||||
Cl,
|
||||
Cs,
|
||||
Cx,
|
||||
Dh,
|
||||
Di,
|
||||
Dil,
|
||||
Dl,
|
||||
Ds,
|
||||
Dx,
|
||||
Eax,
|
||||
Ebp,
|
||||
Ebx,
|
||||
Ecx,
|
||||
Edi,
|
||||
Edx,
|
||||
Eflags,
|
||||
Eip,
|
||||
Es = 26 + 2,
|
||||
Esi,
|
||||
Esp,
|
||||
Fpsw,
|
||||
Fs,
|
||||
Gs,
|
||||
Ip,
|
||||
Rax,
|
||||
Rbp,
|
||||
Rbx,
|
||||
Rcx,
|
||||
Rdi,
|
||||
Rdx,
|
||||
Rip,
|
||||
Rsi = 41 + 2,
|
||||
Rsp,
|
||||
Si,
|
||||
Sil,
|
||||
Sp,
|
||||
Spl,
|
||||
Ss,
|
||||
Cr0,
|
||||
Cr1,
|
||||
Cr2,
|
||||
Cr3,
|
||||
Cr4,
|
||||
Cr8 = 54 + 4,
|
||||
Dr0 = 58 + 8,
|
||||
Dr1,
|
||||
Dr2,
|
||||
Dr3,
|
||||
Dr4,
|
||||
Dr5,
|
||||
Dr6,
|
||||
Dr7,
|
||||
Fp0 = 73 + 9,
|
||||
Fp1,
|
||||
Fp2,
|
||||
Fp3,
|
||||
Fp4,
|
||||
Fp5,
|
||||
Fp6,
|
||||
Fp7,
|
||||
K0,
|
||||
K1,
|
||||
K2,
|
||||
K3,
|
||||
K4,
|
||||
K5,
|
||||
K6,
|
||||
K7,
|
||||
Mm0,
|
||||
Mm1,
|
||||
Mm2,
|
||||
Mm3,
|
||||
Mm4,
|
||||
Mm5,
|
||||
Mm6,
|
||||
Mm7,
|
||||
R8,
|
||||
R9,
|
||||
R10,
|
||||
R11,
|
||||
R12,
|
||||
R13,
|
||||
R14,
|
||||
R15,
|
||||
St0,
|
||||
St1,
|
||||
St2,
|
||||
St3,
|
||||
St4,
|
||||
St5,
|
||||
St6,
|
||||
St7,
|
||||
Xmm0,
|
||||
Xmm1,
|
||||
Xmm2,
|
||||
Xmm3,
|
||||
Xmm4,
|
||||
Xmm5,
|
||||
Xmm6,
|
||||
Xmm7,
|
||||
Xmm8,
|
||||
Xmm9,
|
||||
Xmm10,
|
||||
Xmm11,
|
||||
Xmm12,
|
||||
Xmm13,
|
||||
Xmm14,
|
||||
Xmm15,
|
||||
Xmm16,
|
||||
Xmm17,
|
||||
Xmm18,
|
||||
Xmm19,
|
||||
Xmm20,
|
||||
Xmm21,
|
||||
Xmm22,
|
||||
Xmm23,
|
||||
Xmm24,
|
||||
Xmm25,
|
||||
Xmm26,
|
||||
Xmm27,
|
||||
Xmm28,
|
||||
Xmm29,
|
||||
Xmm30,
|
||||
Xmm31,
|
||||
Ymm0,
|
||||
Ymm1,
|
||||
Ymm2,
|
||||
Ymm3,
|
||||
Ymm4,
|
||||
Ymm5,
|
||||
Ymm6,
|
||||
Ymm7,
|
||||
Ymm8,
|
||||
Ymm9,
|
||||
Ymm10,
|
||||
Ymm11,
|
||||
Ymm12,
|
||||
Ymm13,
|
||||
Ymm14,
|
||||
Ymm15,
|
||||
Ymm16,
|
||||
Ymm17,
|
||||
Ymm18,
|
||||
Ymm19,
|
||||
Ymm20,
|
||||
Ymm21,
|
||||
Ymm22,
|
||||
Ymm23,
|
||||
Ymm24,
|
||||
Ymm25,
|
||||
Ymm26,
|
||||
Ymm27,
|
||||
Ymm28,
|
||||
Ymm29,
|
||||
Ymm30,
|
||||
Ymm31,
|
||||
Zmm0,
|
||||
Zmm1,
|
||||
Zmm2,
|
||||
Zmm3,
|
||||
Zmm4,
|
||||
Zmm5,
|
||||
Zmm6,
|
||||
Zmm7,
|
||||
Zmm8,
|
||||
Zmm9,
|
||||
Zmm10,
|
||||
Zmm11,
|
||||
Zmm12,
|
||||
Zmm13,
|
||||
Zmm14,
|
||||
Zmm15,
|
||||
Zmm16,
|
||||
Zmm17,
|
||||
Zmm18,
|
||||
Zmm19,
|
||||
Zmm20,
|
||||
Zmm21,
|
||||
Zmm22,
|
||||
Zmm23,
|
||||
Zmm24,
|
||||
Zmm25,
|
||||
Zmm26,
|
||||
Zmm27,
|
||||
Zmm28,
|
||||
Zmm29,
|
||||
Zmm30,
|
||||
Zmm31,
|
||||
R8b,
|
||||
R9b,
|
||||
R10b,
|
||||
R11b,
|
||||
R12b,
|
||||
R13b,
|
||||
R14b,
|
||||
R15b,
|
||||
R8d,
|
||||
R9d,
|
||||
R10d,
|
||||
R11d,
|
||||
R12d,
|
||||
R13d,
|
||||
R14d,
|
||||
R15d,
|
||||
R8w,
|
||||
R9w,
|
||||
R10w,
|
||||
R11w,
|
||||
R12w,
|
||||
R13w,
|
||||
R14w,
|
||||
R15w,
|
||||
Idtr,
|
||||
Gdtr,
|
||||
Ldtr,
|
||||
Tr,
|
||||
Fpcw,
|
||||
Fptag,
|
||||
Msr,
|
||||
Mxcsr,
|
||||
FsBase,
|
||||
GsBase,
|
||||
Flags,
|
||||
Rflags,
|
||||
Fip,
|
||||
Fcs,
|
||||
Fdp,
|
||||
Fds,
|
||||
Fop,
|
||||
End, // Must be last
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct X64RegisterNodes {
|
||||
rax: pcode::VarNode,
|
||||
rbx: pcode::VarNode,
|
||||
rcx: pcode::VarNode,
|
||||
rdx: pcode::VarNode,
|
||||
rsi: pcode::VarNode,
|
||||
rdi: pcode::VarNode,
|
||||
rbp: pcode::VarNode,
|
||||
rsp: pcode::VarNode,
|
||||
r8: pcode::VarNode,
|
||||
r9: pcode::VarNode,
|
||||
r10: pcode::VarNode,
|
||||
r11: pcode::VarNode,
|
||||
r12: pcode::VarNode,
|
||||
r13: pcode::VarNode,
|
||||
r14: pcode::VarNode,
|
||||
r15: pcode::VarNode,
|
||||
rip: pcode::VarNode,
|
||||
eflags: pcode::VarNode,
|
||||
cs: pcode::VarNode,
|
||||
ds: pcode::VarNode,
|
||||
es: pcode::VarNode,
|
||||
fs: pcode::VarNode,
|
||||
gs: pcode::VarNode,
|
||||
ss: pcode::VarNode,
|
||||
ah: pcode::VarNode,
|
||||
al: pcode::VarNode,
|
||||
ax: pcode::VarNode,
|
||||
bh: pcode::VarNode,
|
||||
bl: pcode::VarNode,
|
||||
bpl: pcode::VarNode,
|
||||
ch: pcode::VarNode,
|
||||
cl: pcode::VarNode,
|
||||
cx: pcode::VarNode,
|
||||
dh: pcode::VarNode,
|
||||
dil: pcode::VarNode,
|
||||
dl: pcode::VarNode,
|
||||
dx: pcode::VarNode,
|
||||
eax: pcode::VarNode,
|
||||
ebp: pcode::VarNode,
|
||||
ebx: pcode::VarNode,
|
||||
ecx: pcode::VarNode,
|
||||
edi: pcode::VarNode,
|
||||
edx: pcode::VarNode,
|
||||
esi: pcode::VarNode,
|
||||
esp: pcode::VarNode,
|
||||
fpsw: pcode::VarNode,
|
||||
gdtr: pcode::VarNode,
|
||||
idtr: pcode::VarNode,
|
||||
ldtr: pcode::VarNode,
|
||||
tr: pcode::VarNode,
|
||||
cr0: pcode::VarNode,
|
||||
cr1: pcode::VarNode,
|
||||
cr2: pcode::VarNode,
|
||||
cr3: pcode::VarNode,
|
||||
cr4: pcode::VarNode,
|
||||
cr8: pcode::VarNode,
|
||||
dr0: pcode::VarNode,
|
||||
dr1: pcode::VarNode,
|
||||
dr2: pcode::VarNode,
|
||||
dr3: pcode::VarNode,
|
||||
dr4: pcode::VarNode,
|
||||
dr5: pcode::VarNode,
|
||||
dr6: pcode::VarNode,
|
||||
dr7: pcode::VarNode,
|
||||
fp0: pcode::VarNode,
|
||||
fp1: pcode::VarNode,
|
||||
fp2: pcode::VarNode,
|
||||
fp3: pcode::VarNode,
|
||||
fp4: pcode::VarNode,
|
||||
fp5: pcode::VarNode,
|
||||
fp6: pcode::VarNode,
|
||||
fp7: pcode::VarNode,
|
||||
/*k0: pcode::VarNode,
|
||||
k1: pcode::VarNode,
|
||||
k2: pcode::VarNode,
|
||||
k3: pcode::VarNode,
|
||||
k4: pcode::VarNode,
|
||||
k5: pcode::VarNode,
|
||||
k6: pcode::VarNode,
|
||||
k7: pcode::VarNode,*/
|
||||
mm0: pcode::VarNode,
|
||||
mm1: pcode::VarNode,
|
||||
mm2: pcode::VarNode,
|
||||
mm3: pcode::VarNode,
|
||||
mm4: pcode::VarNode,
|
||||
mm5: pcode::VarNode,
|
||||
mm6: pcode::VarNode,
|
||||
mm7: pcode::VarNode,
|
||||
st0: pcode::VarNode,
|
||||
st1: pcode::VarNode,
|
||||
st2: pcode::VarNode,
|
||||
st3: pcode::VarNode,
|
||||
st4: pcode::VarNode,
|
||||
st5: pcode::VarNode,
|
||||
st6: pcode::VarNode,
|
||||
st7: pcode::VarNode,
|
||||
xmm0: pcode::VarNode,
|
||||
xmm1: pcode::VarNode,
|
||||
xmm2: pcode::VarNode,
|
||||
xmm3: pcode::VarNode,
|
||||
xmm4: pcode::VarNode,
|
||||
xmm5: pcode::VarNode,
|
||||
xmm6: pcode::VarNode,
|
||||
xmm7: pcode::VarNode,
|
||||
xmm8: pcode::VarNode,
|
||||
xmm9: pcode::VarNode,
|
||||
xmm10: pcode::VarNode,
|
||||
xmm11: pcode::VarNode,
|
||||
xmm12: pcode::VarNode,
|
||||
xmm13: pcode::VarNode,
|
||||
xmm14: pcode::VarNode,
|
||||
xmm15: pcode::VarNode,
|
||||
/*xmm16: pcode::VarNode,
|
||||
xmm17: pcode::VarNode,
|
||||
xmm18: pcode::VarNode,
|
||||
xmm19: pcode::VarNode,
|
||||
xmm20: pcode::VarNode,
|
||||
xmm21: pcode::VarNode,
|
||||
xmm22: pcode::VarNode,
|
||||
xmm23: pcode::VarNode,
|
||||
xmm24: pcode::VarNode,
|
||||
xmm25: pcode::VarNode,
|
||||
xmm26: pcode::VarNode,
|
||||
xmm27: pcode::VarNode,
|
||||
xmm28: pcode::VarNode,
|
||||
xmm29: pcode::VarNode,
|
||||
xmm30: pcode::VarNode,
|
||||
xmm31: pcode::VarNode,*/
|
||||
ymm0: pcode::VarNode,
|
||||
ymm1: pcode::VarNode,
|
||||
ymm2: pcode::VarNode,
|
||||
ymm3: pcode::VarNode,
|
||||
ymm4: pcode::VarNode,
|
||||
ymm5: pcode::VarNode,
|
||||
ymm6: pcode::VarNode,
|
||||
ymm7: pcode::VarNode,
|
||||
ymm8: pcode::VarNode,
|
||||
ymm9: pcode::VarNode,
|
||||
ymm10: pcode::VarNode,
|
||||
ymm11: pcode::VarNode,
|
||||
ymm12: pcode::VarNode,
|
||||
ymm13: pcode::VarNode,
|
||||
ymm14: pcode::VarNode,
|
||||
ymm15: pcode::VarNode,
|
||||
/*ymm16: pcode::VarNode,
|
||||
ymm17: pcode::VarNode,
|
||||
ymm18: pcode::VarNode,
|
||||
ymm19: pcode::VarNode,
|
||||
ymm20: pcode::VarNode,
|
||||
ymm21: pcode::VarNode,
|
||||
ymm22: pcode::VarNode,
|
||||
ymm23: pcode::VarNode,
|
||||
ymm24: pcode::VarNode,
|
||||
ymm25: pcode::VarNode,
|
||||
ymm26: pcode::VarNode,
|
||||
ymm27: pcode::VarNode,
|
||||
ymm28: pcode::VarNode,
|
||||
ymm29: pcode::VarNode,
|
||||
ymm30: pcode::VarNode,
|
||||
ymm31: pcode::VarNode,*/
|
||||
/*zmm0: pcode::VarNode,
|
||||
zmm1: pcode::VarNode,
|
||||
zmm2: pcode::VarNode,
|
||||
zmm3: pcode::VarNode,
|
||||
zmm4: pcode::VarNode,
|
||||
zmm5: pcode::VarNode,
|
||||
zmm6: pcode::VarNode,
|
||||
zmm7: pcode::VarNode,
|
||||
zmm8: pcode::VarNode,
|
||||
zmm9: pcode::VarNode,
|
||||
zmm10: pcode::VarNode,
|
||||
zmm11: pcode::VarNode,
|
||||
zmm12: pcode::VarNode,
|
||||
zmm13: pcode::VarNode,
|
||||
zmm14: pcode::VarNode,
|
||||
zmm15: pcode::VarNode,
|
||||
zmm16: pcode::VarNode,
|
||||
zmm17: pcode::VarNode,
|
||||
zmm18: pcode::VarNode,
|
||||
zmm19: pcode::VarNode,
|
||||
zmm20: pcode::VarNode,
|
||||
zmm21: pcode::VarNode,
|
||||
zmm22: pcode::VarNode,
|
||||
zmm23: pcode::VarNode,
|
||||
zmm24: pcode::VarNode,
|
||||
zmm25: pcode::VarNode,
|
||||
zmm26: pcode::VarNode,
|
||||
zmm27: pcode::VarNode,
|
||||
zmm28: pcode::VarNode,
|
||||
zmm29: pcode::VarNode,
|
||||
zmm30: pcode::VarNode,
|
||||
zmm31: pcode::VarNode,*/
|
||||
r8b: pcode::VarNode,
|
||||
r9b: pcode::VarNode,
|
||||
r10b: pcode::VarNode,
|
||||
r11b: pcode::VarNode,
|
||||
r12b: pcode::VarNode,
|
||||
r13b: pcode::VarNode,
|
||||
r14b: pcode::VarNode,
|
||||
r15b: pcode::VarNode,
|
||||
r8d: pcode::VarNode,
|
||||
r9d: pcode::VarNode,
|
||||
r10d: pcode::VarNode,
|
||||
r11d: pcode::VarNode,
|
||||
r12d: pcode::VarNode,
|
||||
r13d: pcode::VarNode,
|
||||
r14d: pcode::VarNode,
|
||||
r15d: pcode::VarNode,
|
||||
r8w: pcode::VarNode,
|
||||
r9w: pcode::VarNode,
|
||||
r10w: pcode::VarNode,
|
||||
r11w: pcode::VarNode,
|
||||
r12w: pcode::VarNode,
|
||||
r13w: pcode::VarNode,
|
||||
r14w: pcode::VarNode,
|
||||
r15w: pcode::VarNode,
|
||||
fpcw: pcode::VarNode,
|
||||
fptag: pcode::VarNode,
|
||||
//msr: pcode::VarNode,
|
||||
mxcsr: pcode::VarNode,
|
||||
fs_base: pcode::VarNode,
|
||||
gs_base: pcode::VarNode,
|
||||
flags: pcode::VarNode,
|
||||
rflags: pcode::VarNode,
|
||||
fip: pcode::VarNode,
|
||||
//fcs: pcode::VarNode,
|
||||
fdp: pcode::VarNode,
|
||||
//fds: pcode::VarNode,
|
||||
fop: pcode::VarNode,
|
||||
}
|
||||
|
||||
impl X64RegisterNodes {
|
||||
pub fn new(arch: &icicle_cpu::Arch) -> Self {
|
||||
let r = |name: &str| arch.sleigh.get_reg(name).unwrap().var;
|
||||
Self {
|
||||
rax: r("RAX"),
|
||||
rbx: r("RBX"),
|
||||
rcx: r("RCX"),
|
||||
rdx: r("RDX"),
|
||||
rsi: r("RSI"),
|
||||
rdi: r("RDI"),
|
||||
rbp: r("RBP"),
|
||||
rsp: r("RSP"),
|
||||
r8: r("R8"),
|
||||
r9: r("R9"),
|
||||
r10: r("R10"),
|
||||
r11: r("R11"),
|
||||
r12: r("R12"),
|
||||
r13: r("R13"),
|
||||
r14: r("R14"),
|
||||
r15: r("R15"),
|
||||
rip: r("RIP"),
|
||||
eflags: r("eflags"),
|
||||
cs: r("CS"),
|
||||
ds: r("DS"),
|
||||
es: r("ES"),
|
||||
fs: r("FS"),
|
||||
gs: r("GS"),
|
||||
ss: r("SS"),
|
||||
ah: r("AH"),
|
||||
al: r("AL"),
|
||||
ax: r("AX"),
|
||||
bh: r("BH"),
|
||||
bl: r("BL"),
|
||||
bpl: r("BPL"),
|
||||
ch: r("CH"),
|
||||
cl: r("CL"),
|
||||
cx: r("CX"),
|
||||
dh: r("DH"),
|
||||
dil: r("DIL"),
|
||||
dl: r("DL"),
|
||||
dx: r("DX"),
|
||||
eax: r("EAX"),
|
||||
ebp: r("EBP"),
|
||||
ebx: r("EBX"),
|
||||
ecx: r("ECX"),
|
||||
edi: r("EDI"),
|
||||
edx: r("EDX"),
|
||||
esi: r("ESI"),
|
||||
esp: r("ESP"),
|
||||
fpsw: r("FPUStatusWord"),
|
||||
gdtr: r("GDTR"),
|
||||
idtr: r("IDTR"),
|
||||
ldtr: r("LDTR"),
|
||||
tr: r("TR"),
|
||||
cr0: r("CR0"),
|
||||
cr1: r("CR1"),
|
||||
cr2: r("CR2"),
|
||||
cr3: r("CR3"),
|
||||
cr4: r("CR4"),
|
||||
cr8: r("CR8"),
|
||||
dr0: r("DR0"),
|
||||
dr1: r("DR1"),
|
||||
dr2: r("DR2"),
|
||||
dr3: r("DR3"),
|
||||
dr4: r("DR4"),
|
||||
dr5: r("DR5"),
|
||||
dr6: r("DR6"),
|
||||
dr7: r("DR7"),
|
||||
fp0: r("ST0"), // ??
|
||||
fp1: r("ST1"),
|
||||
fp2: r("ST2"),
|
||||
fp3: r("ST3"),
|
||||
fp4: r("ST4"),
|
||||
fp5: r("ST5"),
|
||||
fp6: r("ST6"),
|
||||
fp7: r("ST7"),
|
||||
/*k0: r("K0"),
|
||||
k1: r("K1"),
|
||||
k2: r("K2"),
|
||||
k3: r("K3"),
|
||||
k4: r("K4"),
|
||||
k5: r("K5"),
|
||||
k6: r("K6"),
|
||||
k7: r("K7"),*/
|
||||
mm0: r("MM0"),
|
||||
mm1: r("MM1"),
|
||||
mm2: r("MM2"),
|
||||
mm3: r("MM3"),
|
||||
mm4: r("MM4"),
|
||||
mm5: r("MM5"),
|
||||
mm6: r("MM6"),
|
||||
mm7: r("MM7"),
|
||||
st0: r("ST0"),
|
||||
st1: r("ST1"),
|
||||
st2: r("ST2"),
|
||||
st3: r("ST3"),
|
||||
st4: r("ST4"),
|
||||
st5: r("ST5"),
|
||||
st6: r("ST6"),
|
||||
st7: r("ST7"),
|
||||
xmm0: r("XMM0"),
|
||||
xmm1: r("XMM1"),
|
||||
xmm2: r("XMM2"),
|
||||
xmm3: r("XMM3"),
|
||||
xmm4: r("XMM4"),
|
||||
xmm5: r("XMM5"),
|
||||
xmm6: r("XMM6"),
|
||||
xmm7: r("XMM7"),
|
||||
xmm8: r("XMM8"),
|
||||
xmm9: r("XMM9"),
|
||||
xmm10: r("XMM10"),
|
||||
xmm11: r("XMM11"),
|
||||
xmm12: r("XMM12"),
|
||||
xmm13: r("XMM13"),
|
||||
xmm14: r("XMM14"),
|
||||
xmm15: r("XMM15"),
|
||||
/*xmm16: r("XMM16"),
|
||||
xmm17: r("XMM17"),
|
||||
xmm18: r("XMM18"),
|
||||
xmm19: r("XMM19"),
|
||||
xmm20: r("XMM20"),
|
||||
xmm21: r("XMM21"),
|
||||
xmm22: r("XMM22"),
|
||||
xmm23: r("XMM23"),
|
||||
xmm24: r("XMM24"),
|
||||
xmm25: r("XMM25"),
|
||||
xmm26: r("XMM26"),
|
||||
xmm27: r("XMM27"),
|
||||
xmm28: r("XMM28"),
|
||||
xmm29: r("XMM29"),
|
||||
xmm30: r("XMM30"),
|
||||
xmm31: r("XMM31"),*/
|
||||
ymm0: r("YMM0"),
|
||||
ymm1: r("YMM1"),
|
||||
ymm2: r("YMM2"),
|
||||
ymm3: r("YMM3"),
|
||||
ymm4: r("YMM4"),
|
||||
ymm5: r("YMM5"),
|
||||
ymm6: r("YMM6"),
|
||||
ymm7: r("YMM7"),
|
||||
ymm8: r("YMM8"),
|
||||
ymm9: r("YMM9"),
|
||||
ymm10: r("YMM10"),
|
||||
ymm11: r("YMM11"),
|
||||
ymm12: r("YMM12"),
|
||||
ymm13: r("YMM13"),
|
||||
ymm14: r("YMM14"),
|
||||
ymm15: r("YMM15"),
|
||||
/*ymm16: r("YMM16"),
|
||||
ymm17: r("YMM17"),
|
||||
ymm18: r("YMM18"),
|
||||
ymm19: r("YMM19"),
|
||||
ymm20: r("YMM20"),
|
||||
ymm21: r("YMM21"),
|
||||
ymm22: r("YMM22"),
|
||||
ymm23: r("YMM23"),
|
||||
ymm24: r("YMM24"),
|
||||
ymm25: r("YMM25"),
|
||||
ymm26: r("YMM26"),
|
||||
ymm27: r("YMM27"),
|
||||
ymm28: r("YMM28"),
|
||||
ymm29: r("YMM29"),
|
||||
ymm30: r("YMM30"),
|
||||
ymm31: r("YMM31"),*/
|
||||
/*zmm0: r("ZMM0"),
|
||||
zmm1: r("ZMM1"),
|
||||
zmm2: r("ZMM2"),
|
||||
zmm3: r("ZMM3"),
|
||||
zmm4: r("ZMM4"),
|
||||
zmm5: r("ZMM5"),
|
||||
zmm6: r("ZMM6"),
|
||||
zmm7: r("ZMM7"),
|
||||
zmm8: r("ZMM8"),
|
||||
zmm9: r("ZMM9"),
|
||||
zmm10: r("ZMM10"),
|
||||
zmm11: r("ZMM11"),
|
||||
zmm12: r("ZMM12"),
|
||||
zmm13: r("ZMM13"),
|
||||
zmm14: r("ZMM14"),
|
||||
zmm15: r("ZMM15"),
|
||||
zmm16: r("ZMM16"),
|
||||
zmm17: r("ZMM17"),
|
||||
zmm18: r("ZMM18"),
|
||||
zmm19: r("ZMM19"),
|
||||
zmm20: r("ZMM20"),
|
||||
zmm21: r("ZMM21"),
|
||||
zmm22: r("ZMM22"),
|
||||
zmm23: r("ZMM23"),
|
||||
zmm24: r("ZMM24"),
|
||||
zmm25: r("ZMM25"),
|
||||
zmm26: r("ZMM26"),
|
||||
zmm27: r("ZMM27"),
|
||||
zmm28: r("ZMM28"),
|
||||
zmm29: r("ZMM29"),
|
||||
zmm30: r("ZMM30"),
|
||||
zmm31: r("ZMM31"),*/
|
||||
r8b: r("R8B"),
|
||||
r9b: r("R9B"),
|
||||
r10b: r("R10B"),
|
||||
r11b: r("R11B"),
|
||||
r12b: r("R12B"),
|
||||
r13b: r("R13B"),
|
||||
r14b: r("R14B"),
|
||||
r15b: r("R15B"),
|
||||
r8d: r("R8D"),
|
||||
r9d: r("R9D"),
|
||||
r10d: r("R10D"),
|
||||
r11d: r("R11D"),
|
||||
r12d: r("R12D"),
|
||||
r13d: r("R13D"),
|
||||
r14d: r("R14D"),
|
||||
r15d: r("R15D"),
|
||||
r8w: r("R8W"),
|
||||
r9w: r("R9W"),
|
||||
r10w: r("R10W"),
|
||||
r11w: r("R11W"),
|
||||
r12w: r("R12W"),
|
||||
r13w: r("R13W"),
|
||||
r14w: r("R14W"),
|
||||
r15w: r("R15W"),
|
||||
fpcw: r("FPUControlWord"),
|
||||
fptag: r("FPUTagWord"),
|
||||
mxcsr: r("MXCSR"),
|
||||
flags: r("flags"),
|
||||
rflags: r("rflags"),
|
||||
fip: r("FPUInstructionPointer"),
|
||||
fdp: r("FPUDataPointer"),
|
||||
fop: r("FPULastInstructionOpcode"),
|
||||
/*fds: r("FDS"),
|
||||
msr: r("MSR"),
|
||||
fcs: r("FCS"),*/
|
||||
fs_base: r("FS_OFFSET"),
|
||||
gs_base: r("GS_OFFSET"),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_node(&self, reg: X64Register) -> pcode::VarNode {
|
||||
match reg {
|
||||
X64Register::Rax => self.rax,
|
||||
X64Register::Rbx => self.rbx,
|
||||
X64Register::Rcx => self.rcx,
|
||||
X64Register::Rdx => self.rdx,
|
||||
X64Register::Rsi => self.rsi,
|
||||
X64Register::Rdi => self.rdi,
|
||||
X64Register::Rbp => self.rbp,
|
||||
X64Register::Rsp => self.rsp,
|
||||
X64Register::R8 => self.r8,
|
||||
X64Register::R9 => self.r9,
|
||||
X64Register::R10 => self.r10,
|
||||
X64Register::R11 => self.r11,
|
||||
X64Register::R12 => self.r12,
|
||||
X64Register::R13 => self.r13,
|
||||
X64Register::R14 => self.r14,
|
||||
X64Register::R15 => self.r15,
|
||||
X64Register::Rip => self.rip,
|
||||
X64Register::Eflags => self.eflags,
|
||||
X64Register::Cs => self.cs,
|
||||
X64Register::Ds => self.ds,
|
||||
X64Register::Es => self.es,
|
||||
X64Register::Fs => self.fs,
|
||||
X64Register::Gs => self.gs,
|
||||
X64Register::Ss => self.ss,
|
||||
X64Register::Ah => self.ah,
|
||||
X64Register::Al => self.al,
|
||||
X64Register::Ax => self.ax,
|
||||
X64Register::Bh => self.bh,
|
||||
X64Register::Bl => self.bl,
|
||||
X64Register::Bpl => self.bpl,
|
||||
X64Register::Ch => self.ch,
|
||||
X64Register::Cl => self.cl,
|
||||
X64Register::Cx => self.cx,
|
||||
X64Register::Dh => self.dh,
|
||||
X64Register::Dil => self.dil,
|
||||
X64Register::Dl => self.dl,
|
||||
X64Register::Dx => self.dx,
|
||||
X64Register::Eax => self.eax,
|
||||
X64Register::Ebp => self.ebp,
|
||||
X64Register::Ebx => self.ebx,
|
||||
X64Register::Ecx => self.ecx,
|
||||
X64Register::Edi => self.edi,
|
||||
X64Register::Edx => self.edx,
|
||||
X64Register::Esi => self.esi,
|
||||
X64Register::Esp => self.esp,
|
||||
X64Register::Fpsw => self.fpsw,
|
||||
X64Register::Gdtr => self.gdtr,
|
||||
X64Register::Idtr => self.idtr,
|
||||
X64Register::Ldtr => self.ldtr,
|
||||
X64Register::Tr => self.tr,
|
||||
X64Register::Cr0 => self.cr0,
|
||||
X64Register::Cr1 => self.cr1,
|
||||
X64Register::Cr2 => self.cr2,
|
||||
X64Register::Cr3 => self.cr3,
|
||||
X64Register::Cr4 => self.cr4,
|
||||
X64Register::Cr8 => self.cr8,
|
||||
X64Register::Dr0 => self.dr0,
|
||||
X64Register::Dr1 => self.dr1,
|
||||
X64Register::Dr2 => self.dr2,
|
||||
X64Register::Dr3 => self.dr3,
|
||||
X64Register::Dr4 => self.dr4,
|
||||
X64Register::Dr5 => self.dr5,
|
||||
X64Register::Dr6 => self.dr6,
|
||||
X64Register::Dr7 => self.dr7,
|
||||
X64Register::Fp0 => self.fp0,
|
||||
X64Register::Fp1 => self.fp1,
|
||||
X64Register::Fp2 => self.fp2,
|
||||
X64Register::Fp3 => self.fp3,
|
||||
X64Register::Fp4 => self.fp4,
|
||||
X64Register::Fp5 => self.fp5,
|
||||
X64Register::Fp6 => self.fp6,
|
||||
X64Register::Fp7 => self.fp7,
|
||||
/*X64Register::K0 => self.k0,
|
||||
X64Register::K1 => self.k1,
|
||||
X64Register::K2 => self.k2,
|
||||
X64Register::K3 => self.k3,
|
||||
X64Register::K4 => self.k4,
|
||||
X64Register::K5 => self.k5,
|
||||
X64Register::K6 => self.k6,
|
||||
X64Register::K7 => self.k7,*/
|
||||
X64Register::Mm0 => self.mm0,
|
||||
X64Register::Mm1 => self.mm1,
|
||||
X64Register::Mm2 => self.mm2,
|
||||
X64Register::Mm3 => self.mm3,
|
||||
X64Register::Mm4 => self.mm4,
|
||||
X64Register::Mm5 => self.mm5,
|
||||
X64Register::Mm6 => self.mm6,
|
||||
X64Register::Mm7 => self.mm7,
|
||||
X64Register::St0 => self.st0,
|
||||
X64Register::St1 => self.st1,
|
||||
X64Register::St2 => self.st2,
|
||||
X64Register::St3 => self.st3,
|
||||
X64Register::St4 => self.st4,
|
||||
X64Register::St5 => self.st5,
|
||||
X64Register::St6 => self.st6,
|
||||
X64Register::St7 => self.st7,
|
||||
X64Register::Xmm0 => self.xmm0,
|
||||
X64Register::Xmm1 => self.xmm1,
|
||||
X64Register::Xmm2 => self.xmm2,
|
||||
X64Register::Xmm3 => self.xmm3,
|
||||
X64Register::Xmm4 => self.xmm4,
|
||||
X64Register::Xmm5 => self.xmm5,
|
||||
X64Register::Xmm6 => self.xmm6,
|
||||
X64Register::Xmm7 => self.xmm7,
|
||||
X64Register::Xmm8 => self.xmm8,
|
||||
X64Register::Xmm9 => self.xmm9,
|
||||
X64Register::Xmm10 => self.xmm10,
|
||||
X64Register::Xmm11 => self.xmm11,
|
||||
X64Register::Xmm12 => self.xmm12,
|
||||
X64Register::Xmm13 => self.xmm13,
|
||||
X64Register::Xmm14 => self.xmm14,
|
||||
X64Register::Xmm15 => self.xmm15,
|
||||
/*X64Register::Xmm16 => self.xmm16,
|
||||
X64Register::Xmm17 => self.xmm17,
|
||||
X64Register::Xmm18 => self.xmm18,
|
||||
X64Register::Xmm19 => self.xmm19,
|
||||
X64Register::Xmm20 => self.xmm20,
|
||||
X64Register::Xmm21 => self.xmm21,
|
||||
X64Register::Xmm22 => self.xmm22,
|
||||
X64Register::Xmm23 => self.xmm23,
|
||||
X64Register::Xmm24 => self.xmm24,
|
||||
X64Register::Xmm25 => self.xmm25,
|
||||
X64Register::Xmm26 => self.xmm26,
|
||||
X64Register::Xmm27 => self.xmm27,
|
||||
X64Register::Xmm28 => self.xmm28,
|
||||
X64Register::Xmm29 => self.xmm29,
|
||||
X64Register::Xmm30 => self.xmm30,
|
||||
X64Register::Xmm31 => self.xmm31,*/
|
||||
X64Register::Ymm0 => self.ymm0,
|
||||
X64Register::Ymm1 => self.ymm1,
|
||||
X64Register::Ymm2 => self.ymm2,
|
||||
X64Register::Ymm3 => self.ymm3,
|
||||
X64Register::Ymm4 => self.ymm4,
|
||||
X64Register::Ymm5 => self.ymm5,
|
||||
X64Register::Ymm6 => self.ymm6,
|
||||
X64Register::Ymm7 => self.ymm7,
|
||||
X64Register::Ymm8 => self.ymm8,
|
||||
X64Register::Ymm9 => self.ymm9,
|
||||
X64Register::Ymm10 => self.ymm10,
|
||||
X64Register::Ymm11 => self.ymm11,
|
||||
X64Register::Ymm12 => self.ymm12,
|
||||
X64Register::Ymm13 => self.ymm13,
|
||||
X64Register::Ymm14 => self.ymm14,
|
||||
X64Register::Ymm15 => self.ymm15,
|
||||
/*X64Register::Ymm16 => self.ymm16,
|
||||
X64Register::Ymm17 => self.ymm17,
|
||||
X64Register::Ymm18 => self.ymm18,
|
||||
X64Register::Ymm19 => self.ymm19,
|
||||
X64Register::Ymm20 => self.ymm20,
|
||||
X64Register::Ymm21 => self.ymm21,
|
||||
X64Register::Ymm22 => self.ymm22,
|
||||
X64Register::Ymm23 => self.ymm23,
|
||||
X64Register::Ymm24 => self.ymm24,
|
||||
X64Register::Ymm25 => self.ymm25,
|
||||
X64Register::Ymm26 => self.ymm26,
|
||||
X64Register::Ymm27 => self.ymm27,
|
||||
X64Register::Ymm28 => self.ymm28,
|
||||
X64Register::Ymm29 => self.ymm29,
|
||||
X64Register::Ymm30 => self.ymm30,
|
||||
X64Register::Ymm31 => self.ymm31,*/
|
||||
/*X64Register::Zmm0 => self.zmm0,
|
||||
X64Register::Zmm1 => self.zmm1,
|
||||
X64Register::Zmm2 => self.zmm2,
|
||||
X64Register::Zmm3 => self.zmm3,
|
||||
X64Register::Zmm4 => self.zmm4,
|
||||
X64Register::Zmm5 => self.zmm5,
|
||||
X64Register::Zmm6 => self.zmm6,
|
||||
X64Register::Zmm7 => self.zmm7,
|
||||
X64Register::Zmm8 => self.zmm8,
|
||||
X64Register::Zmm9 => self.zmm9,
|
||||
X64Register::Zmm10 => self.zmm10,
|
||||
X64Register::Zmm11 => self.zmm11,
|
||||
X64Register::Zmm12 => self.zmm12,
|
||||
X64Register::Zmm13 => self.zmm13,
|
||||
X64Register::Zmm14 => self.zmm14,
|
||||
X64Register::Zmm15 => self.zmm15,
|
||||
X64Register::Zmm16 => self.zmm16,
|
||||
X64Register::Zmm17 => self.zmm17,
|
||||
X64Register::Zmm18 => self.zmm18,
|
||||
X64Register::Zmm19 => self.zmm19,
|
||||
X64Register::Zmm20 => self.zmm20,
|
||||
X64Register::Zmm21 => self.zmm21,
|
||||
X64Register::Zmm22 => self.zmm22,
|
||||
X64Register::Zmm23 => self.zmm23,
|
||||
X64Register::Zmm24 => self.zmm24,
|
||||
X64Register::Zmm25 => self.zmm25,
|
||||
X64Register::Zmm26 => self.zmm26,
|
||||
X64Register::Zmm27 => self.zmm27,
|
||||
X64Register::Zmm28 => self.zmm28,
|
||||
X64Register::Zmm29 => self.zmm29,
|
||||
X64Register::Zmm30 => self.zmm30,
|
||||
X64Register::Zmm31 => self.zmm31,*/
|
||||
X64Register::R8b => self.r8b,
|
||||
X64Register::R9b => self.r9b,
|
||||
X64Register::R10b => self.r10b,
|
||||
X64Register::R11b => self.r11b,
|
||||
X64Register::R12b => self.r12b,
|
||||
X64Register::R13b => self.r13b,
|
||||
X64Register::R14b => self.r14b,
|
||||
X64Register::R15b => self.r15b,
|
||||
X64Register::R8d => self.r8d,
|
||||
X64Register::R9d => self.r9d,
|
||||
X64Register::R10d => self.r10d,
|
||||
X64Register::R11d => self.r11d,
|
||||
X64Register::R12d => self.r12d,
|
||||
X64Register::R13d => self.r13d,
|
||||
X64Register::R14d => self.r14d,
|
||||
X64Register::R15d => self.r15d,
|
||||
X64Register::R8w => self.r8w,
|
||||
X64Register::R9w => self.r9w,
|
||||
X64Register::R10w => self.r10w,
|
||||
X64Register::R11w => self.r11w,
|
||||
X64Register::R12w => self.r12w,
|
||||
X64Register::R13w => self.r13w,
|
||||
X64Register::R14w => self.r14w,
|
||||
X64Register::R15w => self.r15w,
|
||||
X64Register::Fpcw => self.fpcw,
|
||||
X64Register::Fptag => self.fptag,
|
||||
//X64Register::Msr => self.msr,
|
||||
X64Register::Mxcsr => self.mxcsr,
|
||||
X64Register::FsBase => self.fs_base,
|
||||
X64Register::GsBase => self.gs_base,
|
||||
X64Register::Flags => self.flags,
|
||||
X64Register::Rflags => self.rflags,
|
||||
X64Register::Fip => self.fip,
|
||||
//X64Register::Fcs => self.fcs,
|
||||
X64Register::Fdp => self.fdp,
|
||||
//X64Register::Fds => self.fds,
|
||||
X64Register::Fop => self.fop,
|
||||
_ => panic!("Unsupported register"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,10 @@
|
||||
#include <memory>
|
||||
#include <functional>
|
||||
|
||||
#include "object.hpp"
|
||||
#include <utils/object.hpp>
|
||||
|
||||
template <typename ReturnType, typename... Args>
|
||||
class function_wrapper : public object
|
||||
class function_wrapper : public utils::object
|
||||
{
|
||||
public:
|
||||
using user_data_pointer = void*;
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
struct object
|
||||
{
|
||||
object() = default;
|
||||
virtual ~object() = default;
|
||||
|
||||
object(object&&) = default;
|
||||
object(const object&) = default;
|
||||
object& operator=(object&&) = default;
|
||||
object& operator=(const object&) = default;
|
||||
};
|
||||
@@ -1,6 +1,8 @@
|
||||
#define UNICORN_EMULATOR_IMPL
|
||||
#include "unicorn_x64_emulator.hpp"
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "unicorn_memory_regions.hpp"
|
||||
#include "unicorn_hook.hpp"
|
||||
|
||||
@@ -73,7 +75,7 @@ namespace unicorn
|
||||
}
|
||||
}
|
||||
|
||||
struct hook_object : object
|
||||
struct hook_object : utils::object
|
||||
{
|
||||
emulator_hook* as_opaque_hook()
|
||||
{
|
||||
@@ -85,7 +87,7 @@ namespace unicorn
|
||||
{
|
||||
public:
|
||||
template <typename T>
|
||||
requires(std::is_base_of_v<object, T> && std::is_move_constructible_v<T>)
|
||||
requires(std::is_base_of_v<utils::object, T> && std::is_move_constructible_v<T>)
|
||||
void add(T data, unicorn_hook hook)
|
||||
{
|
||||
hook_entry entry{};
|
||||
@@ -99,7 +101,7 @@ namespace unicorn
|
||||
private:
|
||||
struct hook_entry
|
||||
{
|
||||
std::unique_ptr<object> data{};
|
||||
std::unique_ptr<utils::object> data{};
|
||||
unicorn_hook hook{};
|
||||
};
|
||||
|
||||
@@ -302,6 +304,45 @@ namespace unicorn
|
||||
uce(uc_emu_stop(*this));
|
||||
}
|
||||
|
||||
void load_gdt(const pointer_type address, const uint32_t limit) override
|
||||
{
|
||||
const std::array<uint64_t, 4> gdtr = {0, address, limit, 0};
|
||||
this->write_register(x64_register::gdtr, gdtr.data(), gdtr.size() * sizeof(uint64_t));
|
||||
}
|
||||
|
||||
void set_segment_base(const x64_register base, const pointer_type value) override
|
||||
{
|
||||
constexpr auto IA32_FS_BASE_MSR = 0xC0000100;
|
||||
constexpr auto IA32_GS_BASE_MSR = 0xC0000101;
|
||||
|
||||
struct msr_value
|
||||
{
|
||||
uint32_t id;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
msr_value msr_val{
|
||||
.id = 0,
|
||||
.value = value,
|
||||
};
|
||||
|
||||
switch (base)
|
||||
{
|
||||
case x64_register::fs:
|
||||
case x64_register::fs_base:
|
||||
msr_val.id = IA32_FS_BASE_MSR;
|
||||
break;
|
||||
case x64_register::gs:
|
||||
case x64_register::gs_base:
|
||||
msr_val.id = IA32_GS_BASE_MSR;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
this->write_register(x64_register::msr, &msr_val, sizeof(msr_val));
|
||||
}
|
||||
|
||||
size_t write_raw_register(const int reg, const void* value, const size_t size) override
|
||||
{
|
||||
auto result_size = size;
|
||||
|
||||
@@ -18,6 +18,12 @@ target_link_libraries(windows-emulator PRIVATE
|
||||
unicorn-emulator
|
||||
)
|
||||
|
||||
if (MOMO_ENABLE_RUST_CODE)
|
||||
target_link_libraries(windows-emulator PRIVATE
|
||||
icicle-emulator
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(windows-emulator PUBLIC emulator)
|
||||
|
||||
target_include_directories(windows-emulator INTERFACE "${CMAKE_CURRENT_LIST_DIR}")
|
||||
|
||||
@@ -28,19 +28,6 @@ namespace
|
||||
emu.reg(x64_register::rsp, stack_end);
|
||||
}
|
||||
|
||||
void setup_gs_segment(x64_emulator& emu, const emulator_allocator& allocator)
|
||||
{
|
||||
struct msr_value
|
||||
{
|
||||
uint32_t id;
|
||||
uint64_t value;
|
||||
};
|
||||
|
||||
const msr_value value{IA32_GS_BASE_MSR, allocator.get_base()};
|
||||
|
||||
emu.write_register(x64_register::msr, &value, sizeof(value));
|
||||
}
|
||||
|
||||
bool is_object_signaled(process_context& c, const handle h, const uint32_t current_thread_id)
|
||||
{
|
||||
const auto type = h.value.type;
|
||||
@@ -228,7 +215,7 @@ void emulator_thread::setup_registers(x64_emulator& emu, const process_context&
|
||||
}
|
||||
|
||||
setup_stack(emu, this->stack_base, this->stack_size);
|
||||
setup_gs_segment(emu, *this->gs_segment);
|
||||
emu.set_segment_base(x64_register::gs, this->gs_segment->get_base());
|
||||
|
||||
CONTEXT64 ctx{};
|
||||
ctx.ContextFlags = CONTEXT64_ALL;
|
||||
|
||||
@@ -16,10 +16,8 @@ namespace
|
||||
|
||||
void setup_gdt(x64_emulator& emu, memory_manager& memory)
|
||||
{
|
||||
// NOLINTNEXTLINE(cppcoreguidelines-avoid-c-arrays,hicpp-avoid-c-arrays,modernize-avoid-c-arrays)
|
||||
constexpr uint64_t gdtr[4] = {0, GDT_ADDR, GDT_LIMIT, 0};
|
||||
emu.write_register(x64_register::gdtr, &gdtr, sizeof(gdtr));
|
||||
memory.allocate_memory(GDT_ADDR, GDT_LIMIT, memory_permission::read);
|
||||
emu.load_gdt(GDT_ADDR, GDT_LIMIT);
|
||||
|
||||
emu.write_memory<uint64_t>(GDT_ADDR + 6 * (sizeof(uint64_t)), 0xEFFE000000FFFF);
|
||||
emu.reg<uint16_t>(x64_register::cs, 0x33);
|
||||
|
||||
@@ -19,8 +19,6 @@
|
||||
#define PEB_SEGMENT_SIZE (20 << 20) // 20 MB
|
||||
#define GS_SEGMENT_SIZE (1 << 20) // 1 MB
|
||||
|
||||
#define IA32_GS_BASE_MSR 0xC0000101
|
||||
|
||||
#define STACK_SIZE 0x40000ULL
|
||||
|
||||
#define GDT_ADDR 0x30000
|
||||
|
||||
@@ -5,9 +5,12 @@
|
||||
|
||||
#include <unicorn_x64_emulator.hpp>
|
||||
|
||||
#if MOMO_ENABLE_RUST_CODE
|
||||
#include <icicle_x64_emulator.hpp>
|
||||
#endif
|
||||
|
||||
#include <utils/io.hpp>
|
||||
#include <utils/finally.hpp>
|
||||
#include <utils/compression.hpp>
|
||||
#include <utils/lazy_object.hpp>
|
||||
|
||||
#include "exception_dispatch.hpp"
|
||||
|
||||
Reference in New Issue
Block a user