merge msvc with master
This commit is contained in:
@ -120,7 +120,10 @@ module Arm =
|
||||
let UC_ARM_REG_S29 = 108
|
||||
let UC_ARM_REG_S30 = 109
|
||||
let UC_ARM_REG_S31 = 110
|
||||
let UC_ARM_REG_ENDING = 111
|
||||
let UC_ARM_REG_C1_C0_2 = 111
|
||||
let UC_ARM_REG_C13_C0_2 = 112
|
||||
let UC_ARM_REG_C13_C0_3 = 113
|
||||
let UC_ARM_REG_ENDING = 114
|
||||
|
||||
// alias registers
|
||||
let UC_ARM_REG_R13 = 12
|
||||
|
@ -115,7 +115,10 @@ const (
|
||||
ARM_REG_S29 = 108
|
||||
ARM_REG_S30 = 109
|
||||
ARM_REG_S31 = 110
|
||||
ARM_REG_ENDING = 111
|
||||
ARM_REG_C1_C0_2 = 111
|
||||
ARM_REG_C13_C0_2 = 112
|
||||
ARM_REG_C13_C0_3 = 113
|
||||
ARM_REG_ENDING = 114
|
||||
|
||||
// alias registers
|
||||
ARM_REG_R13 = 12
|
||||
|
@ -117,7 +117,10 @@ public interface ArmConst {
|
||||
public static final int UC_ARM_REG_S29 = 108;
|
||||
public static final int UC_ARM_REG_S30 = 109;
|
||||
public static final int UC_ARM_REG_S31 = 110;
|
||||
public static final int UC_ARM_REG_ENDING = 111;
|
||||
public static final int UC_ARM_REG_C1_C0_2 = 111;
|
||||
public static final int UC_ARM_REG_C13_C0_2 = 112;
|
||||
public static final int UC_ARM_REG_C13_C0_3 = 113;
|
||||
public static final int UC_ARM_REG_ENDING = 114;
|
||||
|
||||
// alias registers
|
||||
public static final int UC_ARM_REG_R13 = 12;
|
||||
|
@ -24,9 +24,6 @@ IS_64BITS = platform.architecture()[0] == '64bit'
|
||||
ALL_WINDOWS_DLLS = (
|
||||
"libwinpthread-1.dll",
|
||||
"libgcc_s_seh-1.dll" if IS_64BITS else "libgcc_s_dw2-1.dll",
|
||||
"libiconv-2.dll",
|
||||
"libpcre-1.dll",
|
||||
"libintl-8.dll",
|
||||
)
|
||||
|
||||
# are we building from the repository or from a source distribution?
|
||||
|
@ -113,7 +113,10 @@ UC_ARM_REG_S28 = 107
|
||||
UC_ARM_REG_S29 = 108
|
||||
UC_ARM_REG_S30 = 109
|
||||
UC_ARM_REG_S31 = 110
|
||||
UC_ARM_REG_ENDING = 111
|
||||
UC_ARM_REG_C1_C0_2 = 111
|
||||
UC_ARM_REG_C13_C0_2 = 112
|
||||
UC_ARM_REG_C13_C0_3 = 113
|
||||
UC_ARM_REG_ENDING = 114
|
||||
|
||||
# alias registers
|
||||
UC_ARM_REG_R13 = 12
|
||||
|
@ -30,9 +30,6 @@ _all_windows_dlls = (
|
||||
"libwinpthread-1.dll",
|
||||
"libgcc_s_seh-1.dll",
|
||||
"libgcc_s_dw2-1.dll",
|
||||
"libiconv-2.dll",
|
||||
"libpcre-1.dll",
|
||||
"libintl-8.dll",
|
||||
)
|
||||
|
||||
_loaded_windows_dlls = set()
|
||||
@ -108,6 +105,14 @@ uc_engine = ctypes.c_void_p
|
||||
uc_context = ctypes.c_void_p
|
||||
uc_hook_h = ctypes.c_size_t
|
||||
|
||||
class _uc_mem_region(ctypes.Structure):
|
||||
_fields_ = [
|
||||
("begin", ctypes.c_uint64),
|
||||
("end", ctypes.c_uint64),
|
||||
("perms", ctypes.c_uint32),
|
||||
]
|
||||
|
||||
|
||||
_setup_prototype(_uc, "uc_version", ctypes.c_uint, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
|
||||
_setup_prototype(_uc, "uc_arch_supported", ctypes.c_bool, ctypes.c_int)
|
||||
_setup_prototype(_uc, "uc_open", ucerr, ctypes.c_uint, ctypes.c_uint, ctypes.POINTER(uc_engine))
|
||||
@ -130,6 +135,7 @@ _setup_prototype(_uc, "uc_context_alloc", ucerr, uc_engine, ctypes.POINTER(uc_co
|
||||
_setup_prototype(_uc, "uc_free", ucerr, ctypes.c_void_p)
|
||||
_setup_prototype(_uc, "uc_context_save", ucerr, uc_engine, uc_context)
|
||||
_setup_prototype(_uc, "uc_context_restore", ucerr, uc_engine, uc_context)
|
||||
_setup_prototype(_uc, "uc_mem_regions", ucerr, uc_engine, ctypes.POINTER(ctypes.POINTER(_uc_mem_region)), ctypes.POINTER(ctypes.c_uint32))
|
||||
|
||||
# uc_hook_add is special due to variable number of arguments
|
||||
_uc.uc_hook_add = _uc.uc_hook_add
|
||||
@ -511,6 +517,21 @@ class Uc(object):
|
||||
if status != uc.UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
|
||||
# this returns a generator of regions in the form (begin, end, perms)
|
||||
def mem_regions(self):
|
||||
regions = ctypes.POINTER(_uc_mem_region)()
|
||||
count = ctypes.c_uint32()
|
||||
status = _uc.uc_mem_regions(self._uch, ctypes.byref(regions), ctypes.byref(count))
|
||||
if status != uc.UC_ERR_OK:
|
||||
raise UcError(status)
|
||||
|
||||
try:
|
||||
for i in range(count.value):
|
||||
yield (regions[i].begin, regions[i].end, regions[i].perms)
|
||||
finally:
|
||||
_uc.uc_free(regions)
|
||||
|
||||
|
||||
class SavedContext(object):
|
||||
def __init__(self, pointer):
|
||||
self.pointer = pointer
|
||||
|
@ -5,7 +5,7 @@
|
||||
# Use bundle install && rake to install gem and test
|
||||
install: gen_const
|
||||
cd unicorn_gem && rake build
|
||||
cd unicorn_gem && gem install --local pkg/unicorn-0.9.0.gem
|
||||
cd unicorn_gem && gem install --local pkg/unicorn-1.0.0.gem
|
||||
|
||||
gen_const:
|
||||
cd .. && python const_generator.py ruby
|
||||
|
@ -258,7 +258,7 @@ def test_i386_invalid_mem_write()
|
||||
|
||||
r_ecx = mu.reg_read(UC_X86_REG_ECX)
|
||||
r_edx = mu.reg_read(UC_X86_REG_EDX)
|
||||
puts ">>> ECX = 0x%x" % r_ecx
|
||||
puts ">>> ECX = 0x%x" % r_ecx
|
||||
puts ">>> EDX = 0x%x" % r_edx
|
||||
|
||||
begin
|
||||
@ -282,6 +282,47 @@ def test_i386_invalid_mem_write()
|
||||
end
|
||||
end
|
||||
|
||||
def test_i386_context_save()
|
||||
|
||||
puts("Save/restore CPU context in opaque blob")
|
||||
address = 0
|
||||
code = '\x40' # inc eax
|
||||
begin
|
||||
# Initialize emulator
|
||||
mu = Uc.new UC_ARCH_X86, UC_MODE_32
|
||||
|
||||
# map 8KB memory for this emulation
|
||||
mu.mem_map(address, 8 * 1024, UC_PROT_ALL)
|
||||
|
||||
# write machine code to be emulated to memory
|
||||
mu.mem_write(address, code)
|
||||
|
||||
# set eax to 1
|
||||
mu.reg_write(UC_X86_REG_EAX, 1)
|
||||
|
||||
puts(">>> Running emulation for the first time")
|
||||
mu.emu_start(address, address+1)
|
||||
|
||||
puts(">>> Emulation done. Below is the CPU context")
|
||||
puts(">>> EAX = 0x%x" %(mu.reg_read(UC_X86_REG_EAX)))
|
||||
puts(">>> Saving CPU context")
|
||||
saved_context = mu.context_save()
|
||||
|
||||
puts(">>> Running emulation for the second time")
|
||||
mu.emu_start(address, address+1)
|
||||
puts(">>> Emulation done. Below is the CPU context")
|
||||
puts(">>> EAX = 0x%x" %(mu.reg_read(UC_X86_REG_EAX)))
|
||||
|
||||
puts(">>> CPU context restored. Below is the CPU context")
|
||||
mu.context_restore(saved_context)
|
||||
puts(">>> EAX = 0x%x" %(mu.reg_read(UC_X86_REG_EAX)))
|
||||
|
||||
rescue UcError => e
|
||||
puts("ERROR: %s" % e)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
# Test X86 32 bit with IN/OUT instruction
|
||||
def test_i386_inout()
|
||||
puts("Emulate i386 code with IN/OUT instructions")
|
||||
@ -500,6 +541,8 @@ test_i386_invalid_mem_read()
|
||||
puts("=" * 20)
|
||||
test_i386_invalid_mem_write()
|
||||
puts("=" * 20)
|
||||
test_i386_context_save()
|
||||
puts("=" * 20)
|
||||
test_i386_inout()
|
||||
puts("=" * 20)
|
||||
test_x86_64()
|
||||
|
@ -26,12 +26,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
VALUE UnicornModule = Qnil;
|
||||
VALUE UcClass = Qnil;
|
||||
VALUE UcError = Qnil;
|
||||
VALUE SavedContext = Qnil;
|
||||
|
||||
|
||||
void Init_unicorn() {
|
||||
rb_require("unicorn/unicorn_const");
|
||||
UnicornModule = rb_define_module("Unicorn");
|
||||
UcError = rb_define_class_under(UnicornModule, "UcError", rb_eStandardError);
|
||||
SavedContext = rb_define_class_under(UnicornModule, "SavedContext", rb_cObject);
|
||||
|
||||
UcClass = rb_define_class_under(UnicornModule, "Uc", rb_cObject);
|
||||
rb_define_method(UcClass, "initialize", m_uc_initialize, 2);
|
||||
@ -47,6 +49,9 @@ void Init_unicorn() {
|
||||
rb_define_method(UcClass, "hook_add", m_uc_hook_add, -1);
|
||||
rb_define_method(UcClass, "hook_del", m_uc_hook_del, 1);
|
||||
rb_define_method(UcClass, "query", m_uc_hook_del, 1);
|
||||
rb_define_method(UcClass, "context_save", m_uc_context_save, 0);
|
||||
rb_define_method(UcClass, "context_update", m_uc_context_update, 1);
|
||||
rb_define_method(UcClass, "contest_restore", m_uc_context_restore, 1);
|
||||
}
|
||||
|
||||
VALUE m_uc_initialize(VALUE self, VALUE arch, VALUE mode) {
|
||||
@ -422,3 +427,53 @@ VALUE m_uc_query(VALUE self, VALUE query_mode){
|
||||
}
|
||||
return INT2NUM(result);
|
||||
}
|
||||
|
||||
VALUE m_uc_context_save(VALUE self){
|
||||
uc_err err;
|
||||
uc_engine *_uc;
|
||||
Data_Get_Struct(rb_iv_get(self,"@uch"), uc_engine, _uc);
|
||||
|
||||
uc_context *_context;
|
||||
err = uc_context_alloc(_uc, &_context);
|
||||
if (err != UC_ERR_OK) {
|
||||
rb_raise(UcError, "%s", uc_strerror(err));
|
||||
}
|
||||
|
||||
err = uc_context_save(_uc, _context);
|
||||
if (err != UC_ERR_OK) {
|
||||
rb_raise(UcError, "%s", uc_strerror(err));
|
||||
}
|
||||
|
||||
VALUE sc = Data_Wrap_Struct(SavedContext, 0, uc_free, _context);
|
||||
return sc;
|
||||
}
|
||||
|
||||
VALUE m_uc_context_update(VALUE self, VALUE context){
|
||||
uc_err err;
|
||||
uc_engine *_uc;
|
||||
Data_Get_Struct(rb_iv_get(self,"@uch"), uc_engine, _uc);
|
||||
|
||||
uc_context *_context;
|
||||
Data_Get_Struct(context, uc_context, _context);
|
||||
|
||||
err = uc_context_save(_uc, _context);
|
||||
if (err != UC_ERR_OK) {
|
||||
rb_raise(UcError, "%s", uc_strerror(err));
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
||||
VALUE m_uc_context_restore(VALUE self, VALUE context){
|
||||
uc_err err;
|
||||
uc_engine *_uc;
|
||||
Data_Get_Struct(rb_iv_get(self,"@uch"), uc_engine, _uc);
|
||||
|
||||
uc_context *_context;
|
||||
Data_Get_Struct(context, uc_context, _context);
|
||||
|
||||
err = uc_context_restore(_uc, _context);
|
||||
if (err != UC_ERR_OK) {
|
||||
rb_raise(UcError, "%s", uc_strerror(err));
|
||||
}
|
||||
return Qnil;
|
||||
}
|
||||
|
@ -30,4 +30,7 @@ VALUE m_uc_mem_unmap(VALUE self, VALUE address, VALUE size);
|
||||
VALUE m_uc_mem_protect(VALUE self, VALUE address, VALUE size, VALUE perms);
|
||||
VALUE m_uc_hook_add(int argc, VALUE* argv, VALUE self);
|
||||
VALUE m_uc_hook_del(VALUE self, VALUE hook);
|
||||
VALUE m_uc_query(VALUE self, VALUE query_mode);
|
||||
VALUE m_uc_query(VALUE self, VALUE query_mode);
|
||||
VALUE m_uc_context_save(VALUE self);
|
||||
VALUE m_uc_context_update(VALUE self, VALUE context);
|
||||
VALUE m_uc_context_restore(VALUE self, VALUE context);
|
||||
|
@ -115,7 +115,10 @@ module Unicorn
|
||||
UC_ARM_REG_S29 = 108
|
||||
UC_ARM_REG_S30 = 109
|
||||
UC_ARM_REG_S31 = 110
|
||||
UC_ARM_REG_ENDING = 111
|
||||
UC_ARM_REG_C1_C0_2 = 111
|
||||
UC_ARM_REG_C13_C0_2 = 112
|
||||
UC_ARM_REG_C13_C0_3 = 113
|
||||
UC_ARM_REG_ENDING = 114
|
||||
|
||||
# alias registers
|
||||
UC_ARM_REG_R13 = 12
|
||||
|
Reference in New Issue
Block a user