Arion 1.0.2-alpha
A high-performance C++ framework for emulating executable binaries.
 
Loading...
Searching...
No Matches
arch_manager.hpp
Go to the documentation of this file.
1#ifndef ARION_ARCH_MANAGER_HPP
2#define ARION_ARCH_MANAGER_HPP
3
4#include <arion/capstone/capstone.h>
7#include <arion/keystone/keystone.h>
8#include <arion/unicorn/unicorn.h>
9#include <arion/unicorn/x86.h>
10#include <cstdint>
11#include <map>
12#include <memory>
13#include <string>
14#include <vector>
15
17#define ARION_VVAR_PRESENT (1 << 0)
19#define ARION_VDSO_PRESENT (1 << 1)
21#define ARION_VSYSCALL_PRESENT (1 << 2)
23#define ARION_ARM_TRAPS_PRESENT (1 << 3)
24
26#define ARION_VSYSCALL_ENTRY_SZ 1024
27
28namespace arion
29{
31using KERNEL_SEG_FLAGS = uint8_t;
32
33class Arion;
34
37{
47 ABI_REGISTERS(REG pc, REG sp) : pc(pc), sp(sp) {};
48};
49
52{
56 std::vector<REG> param_regs;
57 /*
58 * Builder for ABI_CALLING_CONVENTION instances.
59 * @param[in] ret_reg Unicorn register handling the call return value.
60 * @param[in] param_regs Unicorn registers handling the call parameters.
61 */
62 ABI_CALLING_CONVENTION(REG ret_reg, std::vector<REG> param_regs)
63 : ret_reg(ret_reg), param_regs(std::move(param_regs)) {};
64};
65
68{
74 std::vector<REG> sys_param_regs;
81 ABI_SYSCALLING_CONVENTION(REG sysno_reg, REG ret_reg, std::vector<REG> sys_param_regs)
82 : sysno_reg(sysno_reg), ret_reg(ret_reg), sys_param_regs(std::move(sys_param_regs)) {};
83};
84
87{
91 uint16_t arch_sz;
93 size_t ptr_sz;
95 uint32_t hwcap;
97 uint32_t hwcap2;
107 std::map<uint64_t, std::string> name_by_syscall_no;
121 ARCH_ATTRIBUTES(CPU_ARCH arch, uint16_t arch_sz, size_t ptr_sz, uint32_t hwcap, uint32_t hwcap2,
122 KERNEL_SEG_FLAGS seg_flags, ABI_REGISTERS regs, ABI_CALLING_CONVENTION calling_conv,
123 ABI_SYSCALLING_CONVENTION syscalling_conv, std::map<uint64_t, std::string> &name_by_syscall_no)
124 : arch(arch), arch_sz(arch_sz), ptr_sz(ptr_sz), seg_flags(seg_flags), hwcap(hwcap), hwcap2(hwcap2), regs(regs),
125 calling_conv(calling_conv), syscalling_conv(syscalling_conv), name_by_syscall_no(name_by_syscall_no) {};
126};
127
176
180{
181 private:
183 static std::map<CPU_INTR, int> signo_by_intr;
184
185 protected:
187 std::weak_ptr<Arion> arion;
189 uc_engine *uc;
191 std::vector<ks_engine *> ks;
193 std::vector<csh *> cs;
195 std::shared_ptr<ARCH_ATTRIBUTES> attrs;
197 std::map<std::string, REG> arch_regs;
199 std::map<REG, uint8_t> arch_regs_sz;
201 std::vector<REG> ctxt_regs;
203 std::map<uint64_t, CPU_INTR> cpu_idt;
215 ArchManager(std::shared_ptr<ARCH_ATTRIBUTES> attrs, std::map<std::string, REG> arch_regs,
216 std::map<REG, uint8_t> arch_regs_sz, std::vector<REG> ctxt_regs, std::map<uint64_t, CPU_INTR> cpu_idt,
217 bool hooks_intr)
218 : attrs(attrs), arch_regs(arch_regs), arch_regs_sz(arch_regs_sz), ctxt_regs(ctxt_regs), cpu_idt(cpu_idt),
219 hooks_intr(hooks_intr) {};
220
221 public:
222 /*
223 * Destructor for ArchManager instances.
224 */
225 virtual ~ArchManager() = default;
233 static std::unique_ptr<ArchManager> initialize(std::weak_ptr<Arion> arion, CPU_ARCH arch,
234 PLATFORM platform = PLATFORM::UNKNOWN_PLATFORM);
245 std::shared_ptr<ARCH_ATTRIBUTES> ARION_EXPORT get_attrs();
256 std::string ARION_EXPORT get_name_by_syscall_no(uint64_t syscall_no);
262 bool ARION_EXPORT has_syscall_with_name(std::string name);
268 uint64_t ARION_EXPORT get_syscall_no_by_name(std::string name);
273 std::vector<REG> ARION_EXPORT get_context_regs();
278 std::unique_ptr<std::map<REG, RVAL>> ARION_EXPORT dump_regs();
283 void ARION_EXPORT load_regs(std::unique_ptr<std::map<REG, RVAL>> regs);
289 bool ARION_EXPORT has_idt_entry(uint64_t intno);
303 std::unique_ptr<std::map<REG, RVAL>> init_thread_regs(ADDR pc, ADDR sp);
308 virtual ks_engine ARION_EXPORT *curr_ks() = 0;
313 virtual csh ARION_EXPORT *curr_cs() = 0;
317 virtual void setup() = 0;
327 virtual void ARION_EXPORT load_tls(ADDR new_tls) = 0;
332 virtual void prerun_hook(ADDR &start) {};
339 template <typename T> T ARION_EXPORT read_reg(REG reg)
340 {
341 auto reg_sz_it = this->arch_regs_sz.find(reg);
342 if (reg_sz_it == this->arch_regs_sz.end())
344 if (sizeof(T) < reg_sz_it->second)
345 throw arion_exception::HeavierRegException(reg_sz_it->second, sizeof(T));
346 T val;
347 uc_err uc_reg_err = uc_reg_read(this->uc, reg, &val);
348 if (uc_reg_err != UC_ERR_OK)
350 return val;
351 }
358 template <typename T> T ARION_EXPORT read_reg(std::string reg_name)
359 {
360 reg_name = str_to_uppercase(reg_name);
361 auto reg_it = this->arch_regs.find(reg_name);
362 if (reg_it == this->arch_regs.end())
364 return this->read_reg<T>(reg_it->second);
365 }
372 uint64_t read_arch_reg(REG reg);
379 template <typename T> void ARION_EXPORT write_reg(REG reg, T val)
380 {
381 auto reg_sz_it = this->arch_regs_sz.find(reg);
382 if (reg_sz_it == this->arch_regs_sz.end())
384 if (sizeof(T) < reg_sz_it->second)
385 throw arion_exception::HeavierRegException(reg_sz_it->second, sizeof(T));
386 uc_err uc_reg_err = uc_reg_write(this->uc, reg, &val);
387 if (uc_reg_err != UC_ERR_OK)
389 }
396 template <typename T> void ARION_EXPORT write_reg(std::string reg_name, T val)
397 {
398 reg_name = str_to_uppercase(reg_name);
399 auto reg_it = this->arch_regs.find(reg_name);
400 if (reg_it == this->arch_regs.end())
402 this->write_reg(reg_it->second, val);
403 }
410 void write_arch_reg(REG reg, uint64_t val);
411};
412
413}; // namespace arion
414
415#endif // ARION_ARCH_MANAGER_HPP
Definition arch_manager.hpp:180
std::map< REG, uint8_t > arch_regs_sz
Unicorn registers sizes.
Definition arch_manager.hpp:199
uint64_t read_arch_reg(REG reg)
std::map< uint64_t, CPU_INTR > cpu_idt
Interrupt Descriptor Table for the CPU.
Definition arch_manager.hpp:203
std::vector< REG > get_context_regs()
virtual ADDR dump_tls()=0
std::vector< csh * > cs
The Capstone engine associated with this instance.
Definition arch_manager.hpp:193
static int get_signal_from_intr(CPU_INTR intr)
virtual ks_engine * curr_ks()=0
static std::map< CPU_INTR, int > signo_by_intr
A map identifying a signal number given a cpu interruption.
Definition arch_manager.hpp:183
std::unique_ptr< std::map< REG, RVAL > > dump_regs()
virtual ~ArchManager()=default
virtual void prerun_hook(ADDR &start)
Definition arch_manager.hpp:332
uint64_t get_syscall_no_by_name(std::string name)
CPU_INTR get_idt_entry(uint64_t intno)
std::shared_ptr< ARCH_ATTRIBUTES > get_attrs()
std::string get_name_by_syscall_no(uint64_t syscall_no)
virtual void setup()=0
std::map< std::string, REG > arch_regs
Unicorn registers by their name.
Definition arch_manager.hpp:197
std::vector< ks_engine * > ks
The Keystone engine associated with this instance.
Definition arch_manager.hpp:191
virtual csh * curr_cs()=0
T read_reg(std::string reg_name)
Definition arch_manager.hpp:358
static std::unique_ptr< ArchManager > initialize(std::weak_ptr< Arion > arion, CPU_ARCH arch, PLATFORM platform=PLATFORM::UNKNOWN_PLATFORM)
void write_reg(REG reg, T val)
Definition arch_manager.hpp:379
void write_reg(std::string reg_name, T val)
Definition arch_manager.hpp:396
bool has_idt_entry(uint64_t intno)
virtual void load_tls(ADDR new_tls)=0
std::unique_ptr< std::map< REG, RVAL > > init_thread_regs(ADDR pc, ADDR sp)
T read_reg(REG reg)
Definition arch_manager.hpp:339
std::weak_ptr< Arion > arion
The Arion instanced associated to this instance.
Definition arch_manager.hpp:187
void write_arch_reg(REG reg, uint64_t val)
uc_engine * uc
The Unicorn engine associated with this instance.
Definition arch_manager.hpp:189
void load_regs(std::unique_ptr< std::map< REG, RVAL > > regs)
bool has_syscall_with_name(std::string name)
std::shared_ptr< ARCH_ATTRIBUTES > attrs
Multiple architecture specific attributes, grouped in a structure for genericity purpose.
Definition arch_manager.hpp:195
ArchManager(std::shared_ptr< ARCH_ATTRIBUTES > attrs, std::map< std::string, REG > arch_regs, std::map< REG, uint8_t > arch_regs_sz, std::vector< REG > ctxt_regs, std::map< uint64_t, CPU_INTR > cpu_idt, bool hooks_intr)
Definition arch_manager.hpp:215
bool hooks_intr
True if the ArchManager subclass uses hook_intr to intercept syscalls.
Definition arch_manager.hpp:205
std::vector< REG > ctxt_regs
Unicorn registers making up the context to save and restore.
Definition arch_manager.hpp:201
An emulation unit associated with a process.
Definition arion.hpp:127
Thrown when attempting to read/write a register with a size that doesn't match the register's size.
Definition global_excepts.hpp:523
Thrown when trying to access a register that does not exist in the current architecture.
Definition global_excepts.hpp:551
Thrown when trying to access a register that does not exist in the current architecture.
Definition global_excepts.hpp:538
Thrown when an error occurs while reading a register with Unicorn engine.
Definition global_excepts.hpp:726
Thrown when an error occurs while writing a register with Unicorn engine.
Definition global_excepts.hpp:739
#define ARION_EXPORT
Defines which symbols should be exported from the library.
Definition global_defs.hpp:13
Definition arch_x86-64.hpp:11
uint64_t REG
Identifies a Unicorn register.
Definition global_defs.hpp:42
uint64_t ADDR
Identifies a memory address.
Definition global_defs.hpp:36
CPU_ARCH
Identifies a CPU architecture.
Definition global_defs.hpp:128
uint8_t KERNEL_SEG_FLAGS
Flags telling the loader which architecture specific segments should stand in memory.
Definition arch_manager.hpp:31
std::string str_to_uppercase(const std::string &input)
Definition convert_utils.hpp:22
PLATFORM
Identifies an Operating System (OS).
Definition global_defs.hpp:143
CPU_INTR
Fields for Interrupt Descriptor Tables.
Definition arch_manager.hpp:130
@ X87_FLOATING_POINT_EXCEPTION
x87 Floating-point exception.
Definition arch_manager.hpp:148
@ SMC
Secure monitor call.
Definition arch_manager.hpp:165
@ NOCP
No coprocessor present.
Definition arch_manager.hpp:169
@ LAZYFP
Lazy floating-point state preservation.
Definition arch_manager.hpp:172
@ OVERFLOW
Overflow exception.
Definition arch_manager.hpp:136
@ PREFETCH_ABORT
Prefetch abort.
Definition arch_manager.hpp:156
@ VIRQ
Virtual IRQ.
Definition arch_manager.hpp:166
@ DOUBLE_FAULT
Double fault.
Definition arch_manager.hpp:140
@ STKOF
Stack overflow.
Definition arch_manager.hpp:171
@ INVALID_OPCODE
Invalid opcode exception.
Definition arch_manager.hpp:138
@ MACHINE_CHECK
Machine check.
Definition arch_manager.hpp:150
@ DEVICE_NOT_AVAILABLE
Device not available.
Definition arch_manager.hpp:139
@ SEMIHOST
Semihosting trap.
Definition arch_manager.hpp:168
@ RESERVED
Reserved interrupt vector.
Definition arch_manager.hpp:147
@ EXCEPTION_EXIT
Exception exit handler.
Definition arch_manager.hpp:161
@ BOUND_RANGE_EXCEEDED
Bound range exceeded.
Definition arch_manager.hpp:137
@ IRQ
Normal interrupt request.
Definition arch_manager.hpp:158
@ UNALIGNED
Unaligned access.
Definition arch_manager.hpp:174
@ PAGE_FAULT
Page fault.
Definition arch_manager.hpp:146
@ SIMD_FLOATING_POINT_ERROR
SIMD Floating-point exception.
Definition arch_manager.hpp:151
@ DIVIDE_ERROR
Divide-by-zero error.
Definition arch_manager.hpp:132
@ ALIGNMENT_CHECK
Alignment check.
Definition arch_manager.hpp:149
@ VFIQ
Virtual FIQ.
Definition arch_manager.hpp:167
@ GENERAL_PROTECTION_FAULT
General protection fault.
Definition arch_manager.hpp:145
@ COPROCESSOR_SEGMENT_OVERRUN
Coprocessor segment overrun.
Definition arch_manager.hpp:141
@ DATA_ABORT
Data abort.
Definition arch_manager.hpp:157
@ FIQ
Fast interrupt request.
Definition arch_manager.hpp:159
@ STACK_SEGMENT_FAULT
Stack segment fault.
Definition arch_manager.hpp:144
@ DEBUG_EXCEPTION
Debug exception.
Definition arch_manager.hpp:133
@ BREAKPOINT
Breakpoint exception.
Definition arch_manager.hpp:135
@ HVC
Hypervisor call.
Definition arch_manager.hpp:163
@ INVALID_TSS
Invalid Task State Segment.
Definition arch_manager.hpp:142
@ NON_MASKABLE_INTR
Non-maskable interrupt.
Definition arch_manager.hpp:134
@ BKPT
Breakpoint.
Definition arch_manager.hpp:160
@ HYP_TRAP
Hypervisor trap.
Definition arch_manager.hpp:164
@ SEGMENT_NOT_PRESENT
Segment not present.
Definition arch_manager.hpp:143
@ LSERR
Lock-step error.
Definition arch_manager.hpp:173
@ KERNEL_TRAP
Kernel trap.
Definition arch_manager.hpp:162
@ UDEF
Undefined instruction.
Definition arch_manager.hpp:154
@ INVSTATE
Invalid processor state.
Definition arch_manager.hpp:170
Unicorn registers involved in calling convention.
Definition arch_manager.hpp:52
ABI_CALLING_CONVENTION(REG ret_reg, std::vector< REG > param_regs)
Definition arch_manager.hpp:62
std::vector< REG > param_regs
Unicorn registers handling the call parameters.
Definition arch_manager.hpp:56
REG ret_reg
Unicorn register handling the call return value.
Definition arch_manager.hpp:54
Unicorn PC and SP registers for genericity.
Definition arch_manager.hpp:37
REG sp
Unicorn SP register.
Definition arch_manager.hpp:41
REG pc
Unicorn PC register.
Definition arch_manager.hpp:39
ABI_REGISTERS(REG pc, REG sp)
Definition arch_manager.hpp:47
Unicorn registers involved in syscalling convention.
Definition arch_manager.hpp:68
REG ret_reg
Unicorn register handling the syscall return value.
Definition arch_manager.hpp:72
REG sysno_reg
Unicorn register handling the syscall number.
Definition arch_manager.hpp:70
std::vector< REG > sys_param_regs
Unicorn registers handling the syscall parameters.
Definition arch_manager.hpp:74
ABI_SYSCALLING_CONVENTION(REG sysno_reg, REG ret_reg, std::vector< REG > sys_param_regs)
Definition arch_manager.hpp:81
Multiple architecture specific attributes, grouped in a structure for genericity purpose.
Definition arch_manager.hpp:87
uint32_t hwcap
HWCAP to be inserted in Auxiliary Vector (AUXV).
Definition arch_manager.hpp:95
ARCH_ATTRIBUTES(CPU_ARCH arch, uint16_t arch_sz, size_t ptr_sz, uint32_t hwcap, uint32_t hwcap2, KERNEL_SEG_FLAGS seg_flags, ABI_REGISTERS regs, ABI_CALLING_CONVENTION calling_conv, ABI_SYSCALLING_CONVENTION syscalling_conv, std::map< uint64_t, std::string > &name_by_syscall_no)
Definition arch_manager.hpp:121
ABI_CALLING_CONVENTION calling_conv
Unicorn registers involved in calling convention.
Definition arch_manager.hpp:103
KERNEL_SEG_FLAGS seg_flags
Flags telling the loader which kernel segments should be mapped in memory.
Definition arch_manager.hpp:99
size_t ptr_sz
Size in bytes of a pointer.
Definition arch_manager.hpp:93
uint16_t arch_sz
Size in bits of the general-purpose registers.
Definition arch_manager.hpp:91
ABI_SYSCALLING_CONVENTION syscalling_conv
Unicorn registers involved in syscalling convention.
Definition arch_manager.hpp:105
std::map< uint64_t, std::string > name_by_syscall_no
A map identifying a syscall name given its number.
Definition arch_manager.hpp:107
CPU_ARCH arch
Arion CPU architecture.
Definition arch_manager.hpp:89
uint32_t hwcap2
HWCAP2 to be inserted in Auxiliary Vector (AUXV).
Definition arch_manager.hpp:97
ABI_REGISTERS regs
Unicorn IP and SP registers for genericity.
Definition arch_manager.hpp:101