diff options
| author | Ajax <commial@gmail.com> | 2018-05-17 10:51:28 +0200 |
|---|---|---|
| committer | Ajax <commial@gmail.com> | 2018-05-17 10:51:28 +0200 |
| commit | 18ac4b21a484265ff50f400ad400a6f028038455 (patch) | |
| tree | 0a5f5ae8b99907e8123225193a17614b0066fc96 | |
| parent | f01c7ffbc51c2b9a08b0d2a2efce26a23ef3268a (diff) | |
| download | miasm-18ac4b21a484265ff50f400ad400a6f028038455.tar.gz miasm-18ac4b21a484265ff50f400ad400a6f028038455.zip | |
Add support for 128 bits operations in VmMngr and GCC outputs
Diffstat (limited to '')
| -rw-r--r-- | miasm2/ir/translators/C.py | 91 | ||||
| -rw-r--r-- | miasm2/jitter/JitCore.c | 11 | ||||
| -rw-r--r-- | miasm2/jitter/JitCore.h | 20 | ||||
| -rw-r--r-- | miasm2/jitter/codegen.py | 11 | ||||
| -rw-r--r-- | miasm2/jitter/llvmconvert.py | 2 | ||||
| -rw-r--r-- | miasm2/jitter/vm_mngr.c | 40 | ||||
| -rw-r--r-- | miasm2/jitter/vm_mngr.h | 27 |
7 files changed, 158 insertions, 44 deletions
diff --git a/miasm2/ir/translators/C.py b/miasm2/ir/translators/C.py index 26443b09..226f26f1 100644 --- a/miasm2/ir/translators/C.py +++ b/miasm2/ir/translators/C.py @@ -18,6 +18,17 @@ class TranslatorC(Translator): '>>>': 'rot_right', } + def _size2mask(self, size): + """Return a C string corresponding to the size2mask operation, with support for + @size <= 128""" + mask = size2mask(size) + if size > 64: + # Avoid "integer constant is too large for its type" error + return "(0x%x | ((uint128_t) 0x%x << 64))" % ( + mask & 0xFFFFFFFFFFFFFFFF, + (mask >> 64) & 0xFFFFFFFFFFFFFFFF, + ) + return "0x%x" % mask def from_ExprId(self, expr): if isinstance(expr.name, asmblock.AsmLabel): @@ -25,6 +36,12 @@ class TranslatorC(Translator): return str(expr) def from_ExprInt(self, expr): + if expr.size == 128: + # Avoid "integer constant is too large for its type" error + return "(0x%x | ((uint128_t) 0x%x << 64))" % ( + int(expr) & 0xFFFFFFFFFFFFFFFF, + (int(expr) >> 64) & 0xFFFFFFFFFFFFFFFF, + ) return "0x%x" % expr.arg.arg def from_ExprAff(self, expr): @@ -41,15 +58,19 @@ class TranslatorC(Translator): def from_ExprOp(self, expr): if len(expr.args) == 1: if expr.op == 'parity': - return "parity(%s&0x%x)" % (self.from_expr(expr.args[0]), - size2mask(expr.args[0].size)) + return "parity(%s&%s)" % ( + self.from_expr(expr.args[0]), + self._size2mask(expr.args[0].size), + ) elif expr.op in ['cntleadzeros', 'cnttrailzeros']: return "%s(0x%x, %s)" % (expr.op, expr.args[0].size, self.from_expr(expr.args[0])) elif expr.op == '!': - return "(~ %s)&0x%x" % (self.from_expr(expr.args[0]), - size2mask(expr.args[0].size)) + return "(~ %s)&%s" % ( + self.from_expr(expr.args[0]), + self._size2mask(expr.args[0].size), + ) elif (expr.op.startswith("double_to_") or expr.op.endswith("_to_double") or expr.op.startswith("access_") or @@ -63,31 +84,40 @@ class TranslatorC(Translator): elif len(expr.args) == 2: if expr.op == "==": - return '(((%s&0x%x) == (%s&0x%x))?1:0)' % ( - self.from_expr(expr.args[0]), size2mask(expr.args[0].size), - self.from_expr(expr.args[1]), size2mask(expr.args[1].size)) + return '(((%s&%s) == (%s&%s))?1:0)' % ( + self.from_expr(expr.args[0]), + self._size2mask(expr.args[0].size), + self.from_expr(expr.args[1]), + self._size2mask(expr.args[1].size), + ) elif expr.op in self.dct_shift: return 'SHIFT_%s(%d, %s, %s)' % (self.dct_shift[expr.op].upper(), expr.args[0].size, self.from_expr(expr.args[0]), self.from_expr(expr.args[1])) elif expr.is_associative() or expr.op in ["%", "/"]: - oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size)) + oper = ['(%s&%s)' % ( + self.from_expr(arg), + self._size2mask(arg.size) + ) for arg in expr.args] oper = str(expr.op).join(oper) - return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) + return "((%s)&%s)" % (oper, self._size2mask(expr.args[0].size)) elif expr.op in ['-']: - return '(((%s&0x%x) %s (%s&0x%x))&0x%x)' % ( - self.from_expr(expr.args[0]), size2mask(expr.args[0].size), + return '(((%s&%s) %s (%s&%s))&%s)' % ( + self.from_expr(expr.args[0]), self._size2mask(expr.args[0].size), str(expr.op), - self.from_expr(expr.args[1]), size2mask(expr.args[1].size), - size2mask(expr.args[0].size)) + self.from_expr(expr.args[1]), self._size2mask(expr.args[1].size), + self._size2mask(expr.args[0].size) + ) elif expr.op in self.dct_rot: - return '(%s(%s, %s, %s) &0x%x)' % (self.dct_rot[expr.op], - expr.args[0].size, - self.from_expr(expr.args[0]), - self.from_expr(expr.args[1]), - size2mask(expr.args[0].size)) + return '(%s(%s, %s, %s) &%s)' % ( + self.dct_rot[expr.op], + expr.args[0].size, + self.from_expr(expr.args[0]), + self.from_expr(expr.args[1]), + self._size2mask(expr.args[0].size), + ) elif expr.op == 'x86_cpuid': return "%s(%s, %s)" % (expr.op, self.from_expr(expr.args[0]), @@ -114,19 +144,24 @@ class TranslatorC(Translator): raise NotImplementedError('Unknown op: %r' % expr.op) elif len(expr.args) >= 3 and expr.is_associative(): # ????? - oper = ['(%s&0x%x)' % (self.from_expr(arg), size2mask(arg.size)) + oper = ['(%s&%s)' % ( + self.from_expr(arg), + self._size2mask(arg.size), + ) for arg in expr.args] oper = str(expr.op).join(oper) - return "((%s)&0x%x)" % (oper, size2mask(expr.args[0].size)) - + return "((%s)&%s)" % ( + oper, + self._size2mask(expr.args[0].size) + ) else: raise NotImplementedError('Unknown op: %s' % expr.op) def from_ExprSlice(self, expr): # XXX check mask for 64 bit & 32 bit compat - return "((%s>>%d) & 0x%X)" % (self.from_expr(expr.arg), - expr.start, - (1 << (expr.stop - expr.start)) - 1) + return "((%s>>%d) &%s)" % (self.from_expr(expr.arg), + expr.start, + self._size2mask(expr.stop - expr.start)) def from_ExprCompose(self, expr): out = [] @@ -143,10 +178,10 @@ class TranslatorC(Translator): dst_cast = "uint%d_t" % size for index, arg in expr.iter_args(): - out.append("(((%s)(%s & 0x%X)) << %d)" % (dst_cast, - self.from_expr(arg), - (1 << arg.size) - 1, - index)) + out.append("(((%s)(%s & %s)) << %d)" % (dst_cast, + self.from_expr(arg), + self._size2mask(arg.size), + index)) out = ' | '.join(out) return '(' + out + ')' diff --git a/miasm2/jitter/JitCore.c b/miasm2/jitter/JitCore.c index 84f835f1..496ec8e1 100644 --- a/miasm2/jitter/JitCore.c +++ b/miasm2/jitter/JitCore.c @@ -74,6 +74,11 @@ uint64_t __attribute__((weak)) MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr) return vm_MEM_LOOKUP_64(&(jitcpu->pyvm->vm_mngr), addr); } +uint128_t __attribute__((weak)) MEM_LOOKUP_128(JitCpu* jitcpu, uint64_t addr) +{ + return vm_MEM_LOOKUP_128(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr); +} + void __attribute__((weak)) MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src) { vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); @@ -94,8 +99,10 @@ void __attribute__((weak)) MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); } - - +void __attribute__((weak)) MEM_WRITE_128(JitCpu* jitcpu, uint64_t addr, uint128_t src) +{ + vm_MEM_WRITE_128(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); +} PyObject* __attribute__((weak)) vm_get_mem(JitCpu *self, PyObject* args) { diff --git a/miasm2/jitter/JitCore.h b/miasm2/jitter/JitCore.h index f599d6ea..c703178d 100644 --- a/miasm2/jitter/JitCore.h +++ b/miasm2/jitter/JitCore.h @@ -4,6 +4,7 @@ #define RAISE(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return p;} #define RAISE_ret0(errtype, msg) {PyObject* p; p = PyErr_Format( errtype, msg ); return 0;} +#define uint128_t __uint128_t #define PyGetInt(item, value) \ if (PyInt_Check(item)){ \ @@ -30,6 +31,23 @@ } \ +#define getset_reg_u128(regname) \ + static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ + { \ + return _PyLong_FromByteArray((const unsigned char*) &(((vm_cpu_t*)(self->cpu))-> regname ), sizeof(uint128_t), /*little_endian*/ 1, /*is_signed*/ 0); \ + } \ + static int JitCpu_set_ ## regname (JitCpu *self, PyObject *value, void *closure) \ + { \ + uint128_t val = 0; \ + int i; \ + unsigned char bytes[sizeof(uint128_t)]; \ + _PyLong_AsByteArray((PyLongObject*)value, bytes, sizeof(uint128_t), /*little_endian*/ 1, /*is_signed*/ 0); \ + for (i = 0; i < sizeof(uint128_t); i++) { \ + val |= (uint128_t) bytes[i] << (8 * i); \ + } \ + ((vm_cpu_t*)(self->cpu))-> regname = val; \ + return 0; \ + } #define getset_reg_u64(regname) \ static PyObject *JitCpu_get_ ## regname (JitCpu *self, void *closure) \ @@ -122,10 +140,12 @@ uint8_t MEM_LOOKUP_08(JitCpu* jitcpu, uint64_t addr); uint16_t MEM_LOOKUP_16(JitCpu* jitcpu, uint64_t addr); uint32_t MEM_LOOKUP_32(JitCpu* jitcpu, uint64_t addr); uint64_t MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr); +uint128_t MEM_LOOKUP_128(JitCpu* jitcpu, uint64_t addr); void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); +void MEM_WRITE_128(JitCpu* jitcpu, uint64_t addr, uint128_t src); PyObject* vm_get_mem(JitCpu *self, PyObject* args); diff --git a/miasm2/jitter/codegen.py b/miasm2/jitter/codegen.py index 2c546be8..b10a9257 100644 --- a/miasm2/jitter/codegen.py +++ b/miasm2/jitter/codegen.py @@ -10,9 +10,8 @@ from miasm2.core.asmblock import expr_is_label, AsmBlockBad, AsmLabel # Miasm to C translator TRANSLATOR = Translator.to_language("C") -SIZE_TO_MASK = {x: 2**x - 1 for x in (1, 2, 3, 7, 8, 16, 32, 64)} - -MASK_INT = 0xffffffffffffffff +SIZE_TO_MASK = {size: TRANSLATOR.from_expr(m2_expr.ExprInt(0, size).mask) + for size in (1, 2, 3, 7, 8, 16, 32, 64, 128)} class Attributes(object): @@ -246,9 +245,9 @@ class CGen(object): '%s = (%s);' % (self.id_to_c(new_dst), self.id_to_c(src))) else: c_main.append( - '%s = (%s)&0x%X;' % (self.id_to_c(new_dst), - self.id_to_c(src), - SIZE_TO_MASK[src.size])) + '%s = (%s)&%s;' % (self.id_to_c(new_dst), + self.id_to_c(src), + SIZE_TO_MASK[src.size])) elif isinstance(dst, m2_expr.ExprMem): ptr = dst.arg.replace_expr(prefetchers) new_dst = m2_expr.ExprMem(ptr, dst.size) diff --git a/miasm2/jitter/llvmconvert.py b/miasm2/jitter/llvmconvert.py index 97cd9f17..2b0f2702 100644 --- a/miasm2/jitter/llvmconvert.py +++ b/miasm2/jitter/llvmconvert.py @@ -193,7 +193,7 @@ class LLVMContext_JIT(LLVMContext): fc = {} p8 = llvm_ir.PointerType(LLVMType.IntType(8)) - for i in [8, 16, 32, 64]: + for i in [8, 16, 32, 64, 128]: fc["MEM_LOOKUP_%02d" % i] = {"ret": LLVMType.IntType(i), "args": [p8, LLVMType.IntType(64)]} diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c index 6da7bfed..8601ec20 100644 --- a/miasm2/jitter/vm_mngr.c +++ b/miasm2/jitter/vm_mngr.c @@ -101,6 +101,13 @@ uint64_t set_endian64(vm_mngr_t* vm_mngr, uint64_t val) return Endian64_Swap(val); } +uint128_t set_endian128(vm_mngr_t* vm_mngr, uint128_t val) +{ + if (vm_mngr->sex == __BYTE_ORDER) + return val; + else + return Endian128_Swap(val); +} void print_val(uint64_t base, uint64_t addr) { @@ -159,11 +166,11 @@ struct memory_page_node * get_memory_page_from_address(vm_mngr_t* vm_mngr, uint6 -static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t ad) +static uint128_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint64_t ad) { struct memory_page_node * mpn; unsigned char * addr; - uint64_t ret = 0; + uint128_t ret = 0; struct memory_breakpoint_info * b; @@ -206,6 +213,10 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6 ret = *((uint64_t*)addr)&0xFFFFFFFFFFFFFFFFULL; ret = set_endian64(vm_mngr, ret); break; + case 128: + ret = *((uint128_t*)addr)&MASK_128; + ret = set_endian128(vm_mngr, ret); + break; default: exit(EXIT_FAILURE); break; @@ -238,6 +249,9 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6 case 64: ret = set_endian64(vm_mngr, ret); break; + case 128: + ret = set_endian128(vm_mngr, ret); + break; default: exit(EXIT_FAILURE); break; @@ -247,7 +261,7 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6 } static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size, - uint64_t ad, uint64_t src) + uint64_t ad, uint128_t src) { struct memory_page_node * mpn; unsigned char * addr; @@ -291,6 +305,10 @@ static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size, src = set_endian64(vm_mngr, src); *((uint64_t*)addr) = src&0xFFFFFFFFFFFFFFFFULL; break; + case 128: + src = set_endian128(vm_mngr, src); + *((uint128_t*)addr) = src&MASK_128; + break; default: exit(EXIT_FAILURE); break; @@ -312,6 +330,9 @@ static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size, case 64: src = set_endian64(vm_mngr, src); break; + case 128: + src = set_endian128(vm_mngr, src); + break; default: exit(EXIT_FAILURE); break; @@ -480,6 +501,12 @@ void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src) memory_page_write(vm_mngr, 64, addr, src); } +void vm_MEM_WRITE_128(vm_mngr_t* vm_mngr, uint64_t addr, uint128_t src) +{ + add_mem_write(vm_mngr, addr, 16); + memory_page_write(vm_mngr, 128, addr, src); +} + unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr) { unsigned char ret; @@ -508,6 +535,13 @@ uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr) ret = memory_page_read(vm_mngr, 64, addr); return ret; } +uint128_t vm_MEM_LOOKUP_128(vm_mngr_t* vm_mngr, uint128_t addr) +{ + uint128_t ret; + add_mem_read(vm_mngr, addr, 16); + ret = memory_page_read(vm_mngr, 128, addr); + return ret; +} int vm_read_mem(vm_mngr_t* vm_mngr, uint64_t addr, char** buffer_ptr, uint64_t size) diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h index eff5e0da..a50b52d0 100644 --- a/miasm2/jitter/vm_mngr.h +++ b/miasm2/jitter/vm_mngr.h @@ -26,6 +26,8 @@ #define __LITTLE_ENDIAN _LITTLE_ENDIAN #endif +#define uint128_t __uint128_t + #define Endian16_Swap(value) \ ((((uint16_t)((value) & 0x00FF)) << 8) | \ (((uint16_t)((value) & 0xFF00)) >> 8)) @@ -46,8 +48,25 @@ ((((uint64_t)value)>>40) & 0x000000000000FF00ULL) | \ ((((uint64_t)value)>>56) & 0x00000000000000FFULL)) - - +#define Endian128_Swap(value) \ + (((((uint128_t)value)>>120) & 0xFF) | \ + ((((uint128_t)value)>>112) & 0xFF) << 8 | \ + ((((uint128_t)value)>>104) & 0xFF) << 16 | \ + ((((uint128_t)value)>>96) & 0xFF) << 24 | \ + ((((uint128_t)value)>>88) & 0xFF) << 32 | \ + ((((uint128_t)value)>>80) & 0xFF) << 40 | \ + ((((uint128_t)value)>>72) & 0xFF) << 48 | \ + ((((uint128_t)value)>>64) & 0xFF) << 56 | \ + ((((uint128_t)value)>>56) & 0xFF) << 64 | \ + ((((uint128_t)value)>>48) & 0xFF) << 72 | \ + ((((uint128_t)value)>>40) & 0xFF) << 80 | \ + ((((uint128_t)value)>>32) & 0xFF) << 88 | \ + ((((uint128_t)value)>>24) & 0xFF) << 96 | \ + ((((uint128_t)value)>>16) & 0xFF) << 104 | \ + ((((uint128_t)value)>>8) & 0xFF) << 112 | \ + ((((uint128_t)value)) & 0xFF) << 120) + +#define MASK_128 ((uint128_t) 0xFFFFFFFFFFFFFFFFULL | (uint128_t) 0xFFFFFFFFFFFFFFFFULL << 64) LIST_HEAD(code_bloc_list_head, code_bloc_node); LIST_HEAD(memory_breakpoint_info_head, memory_breakpoint_info); @@ -174,13 +193,13 @@ void vm_MEM_WRITE_08(vm_mngr_t* vm_mngr, uint64_t addr, unsigned char src); void vm_MEM_WRITE_16(vm_mngr_t* vm_mngr, uint64_t addr, unsigned short src); void vm_MEM_WRITE_32(vm_mngr_t* vm_mngr, uint64_t addr, unsigned int src); void vm_MEM_WRITE_64(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t src); - +void vm_MEM_WRITE_128(vm_mngr_t* vm_mngr, uint64_t addr, uint128_t src); unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr); unsigned short vm_MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr); unsigned int vm_MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr); uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr); - +uint128_t vm_MEM_LOOKUP_128(vm_mngr_t* vm_mngr, uint128_t addr); void MEM_WRITE_08_PASSTHROUGH(uint64_t addr, unsigned char src); void MEM_WRITE_16_PASSTHROUGH(uint64_t addr, unsigned short src); |