diff options
| author | Axel Souchet <0vercl0k@tuxfamily.org> | 2018-09-09 06:11:00 -0700 |
|---|---|---|
| committer | serpilliere <serpilliere@users.noreply.github.com> | 2018-09-09 15:11:00 +0200 |
| commit | 8e6b39d80e9f8db8389bd2a8106d0f64b91c19e9 (patch) | |
| tree | dbf342089690704e89c10532b83d1d81709a49f4 | |
| parent | e61116884ac7879db08313542c6c28a8b00297c5 (diff) | |
| download | focaccia-miasm-8e6b39d80e9f8db8389bd2a8106d0f64b91c19e9.tar.gz focaccia-miasm-8e6b39d80e9f8db8389bd2a8106d0f64b91c19e9.zip | |
Adds Windows support and AppVeyor CI (#835)
* Get miasm to work on Windows, also add AppVeyor CI * Fix gcc jitter on Linux * Make the dse_crackme tests work on Windows * calling build and then install is less confusing than install twice * fix os.rename race condition on Windows * clean it up * Clean up after the unused cl.exe's artifacts * Use is_win instead of an additional check * Fix issue on Windows where 'w' and 'wb' modes are different * Address review feedback * setuptools is actually not required, so reverting
28 files changed, 532 insertions, 324 deletions
diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 00000000..1a2c6ef9 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,59 @@ +version: 1.{build} + +configuration: + - Release + +clone_folder: c:\projects\miasm + +environment: + matrix: + - platform: Win32 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PLATFORM_TOOLSET: v141 + PYTHON: c:\Python27 + Z3_PKG_NAME: z3-4.6.0-x86-win + + - platform: x64 + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 + PLATFORM_TOOLSET: v141 + PYTHON: c:\Python27-x64 + Z3_INCLUDE_DIRS: c:\projects\triton\build\z3-4.6.0-x64-win\include + Z3_LIBRARIES: c:\projects\triton\build\z3-4.6.0-x64-win\bin\libz3.lib + Z3_PKG_NAME: z3-4.6.0-x64-win + + # on_finish: + # - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) + +install: + - cmd: cd c:\projects\miasm + - cmd: mkdir build + - cmd: cd build + - cmd: echo Downloading z3... + - cmd: appveyor DownloadFile https://github.com/Z3Prover/z3/releases/download/z3-4.6.0/%Z3_PKG_NAME%.zip + - cmd: 7z x %Z3_PKG_NAME%.zip + - "%PYTHON%\\Scripts\\pip.exe install pyparsing llvmlite" + - cmd: git clone https://github.com/serpilliere/elfesteem + - cmd: cd elfesteem + - "%PYTHON%\\python.exe setup.py install" + +build_script: + - cmd: if "%platform%"=="Win32" call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x86 + - cmd: if "%platform%"=="x64" call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" x64 + - cmd: cd c:\projects\miasm + - "%PYTHON%\\python.exe setup.py build" + - "%PYTHON%\\python.exe setup.py install" + +test_script: + - cmd: set PYTHONPATH=c:\projects\miasm\build\%Z3_PKG_NAME%\bin\python + - cmd: set PATH=c:\projects\miasm\build\%Z3_PKG_NAME%\bin;%PATH% + - cmd: cd c:\projects\miasm\test + - "%PYTHON%\\python.exe test_all.py" + +after_test: + - cmd: chdir + - cmd: set plat + - cmd: if "%platform%"=="Win32" 7z a -t7z ..\miasm.x86.release.7z c:\projects\miasm\build\*lib* + - cmd: if "%platform%"=="X64" 7z a -t7z ..\miasm.x64.release.7z c:\projects\miasm\build\*lib* + +artifacts: + - path: miasm.*.7z diff --git a/example/symbol_exec/depgraph.py b/example/symbol_exec/depgraph.py index f306e6e3..260d62ab 100644 --- a/example/symbol_exec/depgraph.py +++ b/example/symbol_exec/depgraph.py @@ -103,7 +103,7 @@ for sol_nb, sol in enumerate(dg.get(current_block.loc_key, elements, assignblk_i if sat: for element in sol.constraints: try: - result = hex(sol.constraints[element].as_long()) + result = '0x%x' % sol.constraints[element].as_long() except AttributeError: result = str(sol.constraints[element]) constraints[element] = result diff --git a/example/symbol_exec/dse_crackme.py b/example/symbol_exec/dse_crackme.py index f6050486..22b6d9b1 100644 --- a/example/symbol_exec/dse_crackme.py +++ b/example/symbol_exec/dse_crackme.py @@ -8,6 +8,7 @@ This example should run on the compiled ELF x86 64bits version of #### This part is only related to the run of the sample, without DSE #### import os import subprocess +import platform from collections import namedtuple from pdb import pm from tempfile import NamedTemporaryFile @@ -16,11 +17,13 @@ from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE from miasm2.analysis.sandbox import Sandbox_Linux_x86_64 from miasm2.expression.expression import * +is_win = platform.system() == "Windows" + # File "management" my_FILE_ptr = 0x11223344 FInfo = namedtuple("FInfo", ["path", "fdesc"]) FILE_to_info = {} -TEMP_FILE = NamedTemporaryFile() +TEMP_FILE = NamedTemporaryFile(delete = False) def xxx_fopen(jitter): ''' @@ -260,7 +263,7 @@ while todo: # Prepare a solution to try, based on the clean state file_content = todo.pop() print "CUR: %r" % file_content - open(TEMP_FILE.name, "w").write(file_content) + open(TEMP_FILE.name, "wb").write(file_content) dse.restore_snapshot(snapshot, keep_known_solutions=True) FILE_to_info.clear() FILE_to_info_symb.clear() @@ -296,13 +299,20 @@ while todo: assert found == True print "FOUND !" +TEMP_FILE.close() + # Replay for real -print "Trying to launch the binary without Miasm" -crackme = subprocess.Popen([options.filename, TEMP_FILE.name], - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) -stdout, stderr = crackme.communicate() -assert not stderr -stdout = stdout.strip() -print stdout -assert stdout == "OK" +if not is_win: + print "Trying to launch the binary without Miasm" + crackme = subprocess.Popen([options.filename, TEMP_FILE.name], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + stdout, stderr = crackme.communicate() + assert not stderr + os.unlink(TEMP_FILE.name) + stdout = stdout.strip() + print stdout + assert stdout == "OK" +else: + os.unlink(TEMP_FILE.name) + diff --git a/miasm2/jitter/JitCore.c b/miasm2/jitter/JitCore.c index 1b9790d8..a2873d03 100644 --- a/miasm2/jitter/JitCore.c +++ b/miasm2/jitter/JitCore.c @@ -55,27 +55,26 @@ PyObject * JitCpu_set_jitter(JitCpu *self, PyObject *value, void *closure) return 0; } -uint8_t __attribute__((weak)) MEM_LOOKUP_08(JitCpu* jitcpu, uint64_t addr) +uint8_t MEM_LOOKUP_08(JitCpu* jitcpu, uint64_t addr) { - return vm_MEM_LOOKUP_08(&(jitcpu->pyvm->vm_mngr), addr); + return vm_MEM_LOOKUP_08(&(jitcpu->pyvm->vm_mngr), addr); } -uint16_t __attribute__((weak)) MEM_LOOKUP_16(JitCpu* jitcpu, uint64_t addr) +uint16_t MEM_LOOKUP_16(JitCpu* jitcpu, uint64_t addr) { return vm_MEM_LOOKUP_16(&(jitcpu->pyvm->vm_mngr), addr); } -uint32_t __attribute__((weak)) MEM_LOOKUP_32(JitCpu* jitcpu, uint64_t addr) +uint32_t MEM_LOOKUP_32(JitCpu* jitcpu, uint64_t addr) { - return vm_MEM_LOOKUP_32(&(jitcpu->pyvm->vm_mngr), addr); + return vm_MEM_LOOKUP_32(&(jitcpu->pyvm->vm_mngr), addr); } -uint64_t __attribute__((weak)) MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr) +uint64_t MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr) { return vm_MEM_LOOKUP_64(&(jitcpu->pyvm->vm_mngr), addr); } - bn_t MEM_LOOKUP_BN_BN(JitCpu* jitcpu, int size, bn_t addr) { uint64_t ptr; @@ -156,26 +155,6 @@ void MEM_LOOKUP_INT_BN_TO_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* ptr memcpy(ptr, (char*)&ret, size / 8); } -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); -} - -void __attribute__((weak)) MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src) -{ - vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); -} - -void __attribute__((weak)) MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src) -{ - vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); -} - -void __attribute__((weak)) MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src) -{ - vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, addr, src); -} - void MEM_WRITE_BN_BN(JitCpu* jitcpu, int size, bn_t addr, bn_t src) { @@ -200,13 +179,13 @@ void MEM_WRITE_BN_INT(JitCpu* jitcpu, int size, bn_t addr, uint64_t src) switch (size) { case 8: - vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, src); + vm_MEM_WRITE_08(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, (unsigned char)src); break; case 16: - vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, src); + vm_MEM_WRITE_16(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, (unsigned short)src); break; case 32: - vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, src); + vm_MEM_WRITE_32(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, (unsigned int)src); break; case 64: vm_MEM_WRITE_64(&((VmMngr*)jitcpu->pyvm)->vm_mngr, ptr, src); @@ -248,7 +227,7 @@ void MEM_WRITE_INT_BN_FROM_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* pt -PyObject* __attribute__((weak)) vm_get_mem(JitCpu *self, PyObject* args) +PyObject* vm_get_mem(JitCpu *self, PyObject* args) { PyObject *py_addr; PyObject *py_len; diff --git a/miasm2/jitter/JitCore.h b/miasm2/jitter/JitCore.h index dfa67b6b..312a70d6 100644 --- a/miasm2/jitter/JitCore.h +++ b/miasm2/jitter/JitCore.h @@ -1,7 +1,11 @@ #ifndef JITCORE_H #define JITCORE_H - +#if _WIN32 +#define _MIASM_EXPORT __declspec(dllexport) +#else +#define _MIASM_EXPORT +#endif #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;} @@ -46,7 +50,7 @@ while (!bignum_is_zero(bn)) { \ tmp = bignum_to_uint64(bignum_mask(bn, 32)) & 0xffffffff; \ bn = bignum_rshift(bn, 32); \ - py_tmp = PyLong_FromLong(tmp); \ + py_tmp = PyLong_FromUnsignedLong(tmp); \ py_long = PyObject_CallMethod(py_long, "__lshift__", "O", cst_32); \ py_long = PyObject_CallMethod(py_long, "__add__", "O", py_tmp); \ } \ @@ -203,30 +207,25 @@ void Resolve_dst(block_id* BlockDst, uint64_t addr, uint64_t is_local); -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); - -bn_t MEM_LOOKUP_BN_BN(JitCpu* jitcpu, int size, bn_t addr); -bn_t MEM_LOOKUP_INT_BN(JitCpu* jitcpu, int size, uint64_t addr); +_MIASM_EXPORT uint8_t MEM_LOOKUP_08(JitCpu* jitcpu, uint64_t addr); +_MIASM_EXPORT uint16_t MEM_LOOKUP_16(JitCpu* jitcpu, uint64_t addr); +_MIASM_EXPORT uint32_t MEM_LOOKUP_32(JitCpu* jitcpu, uint64_t addr); +_MIASM_EXPORT uint64_t MEM_LOOKUP_64(JitCpu* jitcpu, uint64_t addr); -uint64_t MEM_LOOKUP_BN_INT(JitCpu* jitcpu, int size, bn_t addr); +_MIASM_EXPORT bn_t MEM_LOOKUP_BN_BN(JitCpu* jitcpu, int size, bn_t addr); +_MIASM_EXPORT bn_t MEM_LOOKUP_INT_BN(JitCpu* jitcpu, int size, 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); +_MIASM_EXPORT uint64_t MEM_LOOKUP_BN_INT(JitCpu* jitcpu, int size, bn_t addr); -void MEM_WRITE_BN_BN(JitCpu* jitcpu, int size, bn_t addr, bn_t src); -void MEM_WRITE_BN_INT(JitCpu* jitcpu, int size, bn_t addr, uint64_t src); -void MEM_WRITE_INT_BN(JitCpu* jitcpu, int size, uint64_t addr, bn_t src); +_MIASM_EXPORT void MEM_WRITE_BN_BN(JitCpu* jitcpu, int size, bn_t addr, bn_t src); +_MIASM_EXPORT void MEM_WRITE_BN_INT(JitCpu* jitcpu, int size, bn_t addr, uint64_t src); +_MIASM_EXPORT void MEM_WRITE_INT_BN(JitCpu* jitcpu, int size, uint64_t addr, bn_t src); PyObject* vm_get_mem(JitCpu *self, PyObject* args); -void MEM_LOOKUP_INT_BN_TO_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* ptr); -void MEM_WRITE_INT_BN_FROM_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* ptr); +_MIASM_EXPORT void MEM_LOOKUP_INT_BN_TO_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* ptr); +_MIASM_EXPORT void MEM_WRITE_INT_BN_FROM_PTR(JitCpu* jitcpu, int size, uint64_t addr, char* ptr); diff --git a/miasm2/jitter/arch/JitCore_aarch64.h b/miasm2/jitter/arch/JitCore_aarch64.h index fa50513f..fa958244 100644 --- a/miasm2/jitter/arch/JitCore_aarch64.h +++ b/miasm2/jitter/arch/JitCore_aarch64.h @@ -47,6 +47,11 @@ typedef struct { uint32_t cf; }vm_cpu_t; -void dump_gpregs(vm_cpu_t* vmcpu); +_MIASM_EXPORT void dump_gpregs(vm_cpu_t* vmcpu); + +_MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); +_MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); +_MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); +_MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); #define RETURN_PC return BlockDst; diff --git a/miasm2/jitter/arch/JitCore_arm.h b/miasm2/jitter/arch/JitCore_arm.h index abd821db..67a1096a 100644 --- a/miasm2/jitter/arch/JitCore_arm.h +++ b/miasm2/jitter/arch/JitCore_arm.h @@ -37,6 +37,11 @@ typedef struct { }vm_cpu_t; -void dump_gpregs(vm_cpu_t* vmcpu); +_MIASM_EXPORT void dump_gpregs(vm_cpu_t* vmcpu); + +_MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); +_MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); +_MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); +_MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); #define RETURN_PC return BlockDst; diff --git a/miasm2/jitter/arch/JitCore_mep.h b/miasm2/jitter/arch/JitCore_mep.h index 47075ba5..0148cd13 100644 --- a/miasm2/jitter/arch/JitCore_mep.h +++ b/miasm2/jitter/arch/JitCore_mep.h @@ -72,6 +72,11 @@ typedef struct { } vm_cpu_t; -void dump_gpregs(vm_cpu_t* vmcpu); +_MIASM_EXPORT void dump_gpregs(vm_cpu_t* vmcpu); + +_MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); +_MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); +_MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); +_MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); #define RETURN_PC return BlockDst; diff --git a/miasm2/jitter/arch/JitCore_mips32.h b/miasm2/jitter/arch/JitCore_mips32.h index ff2045d7..e20d5133 100644 --- a/miasm2/jitter/arch/JitCore_mips32.h +++ b/miasm2/jitter/arch/JitCore_mips32.h @@ -333,6 +333,11 @@ typedef struct { uint32_t CPR0_255; }vm_cpu_t; -void dump_gpregs(vm_cpu_t* vmcpu); +_MIASM_EXPORT void dump_gpregs(vm_cpu_t* vmcpu); + +_MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); +_MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); +_MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); +_MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); #define RETURN_PC return BlockDst; diff --git a/miasm2/jitter/arch/JitCore_msp430.h b/miasm2/jitter/arch/JitCore_msp430.h index 3934d37a..1c802e9e 100644 --- a/miasm2/jitter/arch/JitCore_msp430.h +++ b/miasm2/jitter/arch/JitCore_msp430.h @@ -36,4 +36,9 @@ typedef struct { #define RETURN_PC return BlockDst; -void dump_gpregs(vm_cpu_t* vmcpu); +_MIASM_EXPORT void dump_gpregs(vm_cpu_t* vmcpu); + +_MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); +_MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); +_MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); +_MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); diff --git a/miasm2/jitter/arch/JitCore_ppc32.h b/miasm2/jitter/arch/JitCore_ppc32.h index 5a048190..f2a5200e 100644 --- a/miasm2/jitter/arch/JitCore_ppc32.h +++ b/miasm2/jitter/arch/JitCore_ppc32.h @@ -14,6 +14,11 @@ struct vm_cpu { uint32_t reserve_address; }; -void dump_gpregs(struct vm_cpu *); +_MIASM_EXPORT void dump_gpregs(struct vm_cpu *); typedef struct vm_cpu vm_cpu_t; + +_MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); +_MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); +_MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); +_MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); diff --git a/miasm2/jitter/arch/JitCore_x86.c b/miasm2/jitter/arch/JitCore_x86.c index cc3f8573..c64d1606 100644 --- a/miasm2/jitter/arch/JitCore_x86.c +++ b/miasm2/jitter/arch/JitCore_x86.c @@ -216,7 +216,7 @@ PyObject* cpu_set_gpreg(JitCpu* self, PyObject *args) /* Ensure py_long is a PyLong */ if (PyInt_Check(py_long)){ tmp = (uint64_t)PyInt_AsLong(py_long); - py_long = PyLong_FromLong(tmp); + py_long = PyLong_FromLong((long)tmp); } else if (PyLong_Check(py_long)){ /* Already PyLong */ } diff --git a/miasm2/jitter/arch/JitCore_x86.h b/miasm2/jitter/arch/JitCore_x86.h index cde113ab..6d86d6b8 100644 --- a/miasm2/jitter/arch/JitCore_x86.h +++ b/miasm2/jitter/arch/JitCore_x86.h @@ -1,5 +1,10 @@ #include "../bn.h" +#if _WIN32 +#define _MIASM_EXPORT __declspec(dllexport) +#else +#define _MIASM_EXPORT +#endif typedef struct { uint32_t exception_flags; @@ -120,8 +125,13 @@ typedef struct { }vm_cpu_t; -void dump_gpregs_32(vm_cpu_t* vmcpu); -void dump_gpregs_64(vm_cpu_t* vmcpu); -uint64_t segm2addr(JitCpu* jitcpu, uint64_t segm, uint64_t addr); +_MIASM_EXPORT void dump_gpregs_32(vm_cpu_t* vmcpu); +_MIASM_EXPORT void dump_gpregs_64(vm_cpu_t* vmcpu); +_MIASM_EXPORT uint64_t segm2addr(JitCpu* jitcpu, uint64_t segm, uint64_t addr); + +_MIASM_EXPORT void MEM_WRITE_08(JitCpu* jitcpu, uint64_t addr, uint8_t src); +_MIASM_EXPORT void MEM_WRITE_16(JitCpu* jitcpu, uint64_t addr, uint16_t src); +_MIASM_EXPORT void MEM_WRITE_32(JitCpu* jitcpu, uint64_t addr, uint32_t src); +_MIASM_EXPORT void MEM_WRITE_64(JitCpu* jitcpu, uint64_t addr, uint64_t src); #define RETURN_PC return BlockDst; diff --git a/miasm2/jitter/bn.h b/miasm2/jitter/bn.h index 6f726eb3..67d20a77 100644 --- a/miasm2/jitter/bn.h +++ b/miasm2/jitter/bn.h @@ -1,5 +1,12 @@ #ifndef __BIGNUM_H__ #define __BIGNUM_H__ + +#if _WIN32 +#define _MIASM_EXPORT __declspec(dllexport) +#else +#define _MIASM_EXPORT +#endif + /* Big number library - arithmetic on multiple-precision unsigned integers. @@ -94,51 +101,51 @@ typedef struct bn enum { SMALLER = -1, EQUAL = 0, LARGER = 1 }; /* Initialization functions: */ -bn_t bignum_init(void); -bn_t bignum_from_int(DTYPE_TMP i); -bn_t bignum_from_uint64(uint64_t i); -int bignum_to_int(bn_t n); -uint64_t bignum_to_uint64(bn_t n); -bn_t bignum_from_string(char* str, int nbytes); -void bignum_to_string(bn_t n, char* str, int maxsize); +_MIASM_EXPORT bn_t bignum_init(void); +_MIASM_EXPORT bn_t bignum_from_int(DTYPE_TMP i); +_MIASM_EXPORT bn_t bignum_from_uint64(uint64_t i); +_MIASM_EXPORT int bignum_to_int(bn_t n); +_MIASM_EXPORT uint64_t bignum_to_uint64(bn_t n); +_MIASM_EXPORT bn_t bignum_from_string(char* str, int nbytes); +_MIASM_EXPORT void bignum_to_string(bn_t n, char* str, int maxsize); /* Basic arithmetic operations: */ -bn_t bignum_add(bn_t a, bn_t b); /* c = a + b */ -bn_t bignum_sub(bn_t a, bn_t b); /* c = a - b */ -bn_t bignum_mul(bn_t a, bn_t b); /* c = a * b */ -bn_t bignum_udiv(bn_t a, bn_t b); /* c = a / b */ -bn_t bignum_umod(bn_t a, bn_t b); /* c = a % b */ -bn_t bignum_idiv(bn_t a, bn_t b, int size); -bn_t bignum_imod(bn_t a, bn_t b, int size); +_MIASM_EXPORT bn_t bignum_add(bn_t a, bn_t b); /* c = a + b */ +_MIASM_EXPORT bn_t bignum_sub(bn_t a, bn_t b); /* c = a - b */ +_MIASM_EXPORT bn_t bignum_mul(bn_t a, bn_t b); /* c = a * b */ +_MIASM_EXPORT bn_t bignum_udiv(bn_t a, bn_t b); /* c = a / b */ +_MIASM_EXPORT bn_t bignum_umod(bn_t a, bn_t b); /* c = a % b */ +_MIASM_EXPORT bn_t bignum_idiv(bn_t a, bn_t b, int size); +_MIASM_EXPORT bn_t bignum_imod(bn_t a, bn_t b, int size); //void bignum_udivmod(struct bn* a, struct bn* b, struct bn* c, struct bn* d); /* c = a/b, d = a%b */ /* Bitwise operations: */ -bn_t bignum_and(bn_t a, bn_t b); /* c = a & b */ -bn_t bignum_or(bn_t a, bn_t b); /* c = a | b */ -bn_t bignum_xor(bn_t a, bn_t b); /* c = a ^ b */ -bn_t bignum_lshift(bn_t a, int nbits); /* b = a << nbits */ -bn_t bignum_rshift(bn_t a, int nbits); /* b = a >> nbits */ -bn_t bignum_a_rshift(bn_t a, int size, int nbits); /* b = a a>> nbits */ -bn_t bignum_not(bn_t a); /* c = ~a */ +_MIASM_EXPORT bn_t bignum_and(bn_t a, bn_t b); /* c = a & b */ +_MIASM_EXPORT bn_t bignum_or(bn_t a, bn_t b); /* c = a | b */ +_MIASM_EXPORT bn_t bignum_xor(bn_t a, bn_t b); /* c = a ^ b */ +_MIASM_EXPORT bn_t bignum_lshift(bn_t a, int nbits); /* b = a << nbits */ +_MIASM_EXPORT bn_t bignum_rshift(bn_t a, int nbits); /* b = a >> nbits */ +_MIASM_EXPORT bn_t bignum_a_rshift(bn_t a, int size, int nbits); /* b = a a>> nbits */ +_MIASM_EXPORT bn_t bignum_not(bn_t a); /* c = ~a */ /* Special operators and comparison */ -int bignum_cmp(bn_t a, bn_t b); /* Compare: returns LARGER, EQUAL or SMALLER */ -int bignum_is_zero(bn_t n); /* For comparison with zero */ -bn_t bignum_inc(bn_t n); /* Increment: add one to n */ -bn_t bignum_dec(bn_t n); /* Decrement: subtract one from n */ +_MIASM_EXPORT int bignum_cmp(bn_t a, bn_t b); /* Compare: returns LARGER, EQUAL or SMALLER */ +_MIASM_EXPORT int bignum_is_zero(bn_t n); /* For comparison with zero */ +_MIASM_EXPORT bn_t bignum_inc(bn_t n); /* Increment: add one to n */ +_MIASM_EXPORT bn_t bignum_dec(bn_t n); /* Decrement: subtract one from n */ //bn_t bignum_pow(bn_t a, bn_t b, bn_t c); /* Calculate a^b -- e.g. 2^10 => 1024 */ //bn_t bignum_isqrt(bn_t a, bn_t b); /* Integer square root -- e.g. isqrt(5) => 2*/ -int bignum_cntleadzeros(bn_t n, int size); -int bignum_cnttrailzeros(bn_t n, int size); -bn_t bignum_assign(bn_t src); /* Copy src into dst -- dst := src */ -bn_t bignum_mask(bn_t src, int bits); /* c = src & ((1<<bits) -1) */ - -bn_t bignum_rol(bn_t a, int size, int nbits); -bn_t bignum_ror(bn_t a, int size, int nbits); -int bignum_getbit(bn_t a, int pos); +_MIASM_EXPORT int bignum_cntleadzeros(bn_t n, int size); +_MIASM_EXPORT int bignum_cnttrailzeros(bn_t n, int size); +_MIASM_EXPORT bn_t bignum_assign(bn_t src); /* Copy src into dst -- dst := src */ +_MIASM_EXPORT bn_t bignum_mask(bn_t src, int bits); /* c = src & ((1<<bits) -1) */ + +_MIASM_EXPORT bn_t bignum_rol(bn_t a, int size, int nbits); +_MIASM_EXPORT bn_t bignum_ror(bn_t a, int size, int nbits); +_MIASM_EXPORT int bignum_getbit(bn_t a, int pos); #endif /* #ifndef __BIGNUM_H__ */ diff --git a/miasm2/jitter/jitcore_cc_base.py b/miasm2/jitter/jitcore_cc_base.py index 81a5d009..7853816a 100644 --- a/miasm2/jitter/jitcore_cc_base.py +++ b/miasm2/jitter/jitcore_cc_base.py @@ -2,11 +2,13 @@ import os import tempfile +import platform from distutils.sysconfig import get_python_inc from miasm2.jitter.jitcore import JitCore from miasm2.core.utils import keydefaultdict +is_win = platform.system() == "Windows" def gen_core(arch, attrib): lib_dir = os.path.dirname(os.path.realpath(__file__)) @@ -70,9 +72,9 @@ class JitCore_Cc_Base(JitCore): def load(self): lib_dir = os.path.dirname(os.path.realpath(__file__)) - libs = [os.path.join(lib_dir, 'VmMngr.so'), - os.path.join(lib_dir, - 'arch/JitCore_%s.so' % (self.ir_arch.arch.name))] + ext = ".so" if not is_win else ".lib" + libs = [os.path.join(lib_dir, "VmMngr" + ext), + os.path.join(lib_dir, "arch", "JitCore_%s%s" % (self.ir_arch.arch.name, ext))] include_files = [os.path.dirname(__file__), get_python_inc()] @@ -91,7 +93,7 @@ class JitCore_Cc_Base(JitCore): Return the C code corresponding to the @irblocks @irblocks: list of irblocks """ - f_declaration = 'int %s(block_id * BlockDst, JitCpu* jitcpu)' % self.FUNCNAME + f_declaration = '_MIASM_EXPORT int %s(block_id * BlockDst, JitCpu* jitcpu)' % self.FUNCNAME out = self.codegen.gen_c(block, log_mn=self.log_mn, log_regs=self.log_regs) out = [f_declaration + '{'] + out + ['}\n'] c_code = out diff --git a/miasm2/jitter/jitcore_gcc.py b/miasm2/jitter/jitcore_gcc.py index dbaa2a08..238f2239 100644 --- a/miasm2/jitter/jitcore_gcc.py +++ b/miasm2/jitter/jitcore_gcc.py @@ -4,11 +4,14 @@ import os import tempfile import ctypes import _ctypes +import platform from subprocess import check_call +from distutils.sysconfig import get_python_inc from miasm2.jitter import Jitgcc from miasm2.jitter.jitcore_cc_base import JitCore_Cc_Base, gen_core +is_win = platform.system() == "Windows" class JitCore_Gcc(JitCore_Cc_Base): "JiT management, using a C compiler as backend" @@ -21,7 +24,12 @@ class JitCore_Gcc(JitCore_Cc_Base): """Free the state associated to @offset and delete it @offset: gcc state offset """ - _ctypes.dlclose(self.states[offset]._handle) + flib = None + if is_win: + flib = _ctypes.FreeLibrary + else: + flib = _ctypes.dlclose + flib(self.states[offset]._handle) del self.states[offset] def load_code(self, label, fname_so): @@ -37,7 +45,8 @@ class JitCore_Gcc(JitCore_Cc_Base): @block: block to jit """ block_hash = self.hash_block(block) - fname_out = os.path.join(self.tempdir, "%s.so" % block_hash) + ext = ".so" if not is_win else ".pyd" + fname_out = os.path.join(self.tempdir, "%s%s" % (block_hash, ext)) if not os.access(fname_out, os.R_OK | os.X_OK): func_code = self.gen_c_code(block) @@ -48,16 +57,49 @@ class JitCore_Gcc(JitCore_Cc_Base): os.close(fdesc) # Create unique SO file - fdesc, fname_tmp = tempfile.mkstemp(suffix=".so") + fdesc, fname_tmp = tempfile.mkstemp(suffix=ext) os.close(fdesc) inc_dir = ["-I%s" % inc for inc in self.include_files] libs = ["%s" % lib for lib in self.libs] - args = ["cc"] + ["-O3"] + [ - "-shared", "-fPIC", fname_in, '-o', fname_tmp] + inc_dir + libs - check_call(args) + if is_win: + libs.append(os.path.join(get_python_inc(), "..", "libs", "python27.lib")) + cl = [ + "cl", "/nologo", "/W3", "/MP", + "/Od", "/DNDEBUG", "/D_WINDOWS", "/Gm-", "/EHsc", + "/RTC1", "/MD", "/GS", + fname_in + ] + inc_dir + libs + cl += ["/link", "/DLL", "/OUT:" + fname_tmp] + out_dir, _ = os.path.split(fname_tmp) + check_call(cl, cwd = out_dir) + basename_out, _ = os.path.splitext(fname_tmp) + basename_in, _ = os.path.splitext(os.path.basename(fname_in)) + for ext in ('.obj', '.exp', '.lib'): + artifact_out_path = os.path.join(out_dir, basename_out + ext) + if os.path.isfile(artifact_out_path): + os.remove(artifact_out_path) + artifact_in_path = os.path.join(out_dir, basename_in + ext) + if os.path.isfile(artifact_in_path): + os.remove(artifact_in_path) + else: + args = ["cc", "-O3", "-shared", "-fPIC", fname_in, "-o", fname_tmp] + inc_dir + libs + check_call(args) + # Move temporary file to final file - os.rename(fname_tmp, fname_out) + try: + os.rename(fname_tmp, fname_out) + except WindowsError, e: + # On Windows, os.rename works slightly differently than on Linux; quoting the documentation: + # "On Unix, if dst exists and is a file, it will be replaced silently if the user has permission. + # The operation may fail on some Unix flavors if src and dst are on different filesystems. + # If successful, the renaming will be an atomic operation (this is a POSIX requirement). + # On Windows, if dst already exists, OSError will be raised even if it is a file; there may be no way + # to implement an atomic rename when dst names an existing file." + # [Error 183] Cannot create a file when that file already exists + if e.winerror != 183: + raise + os.remove(fname_tmp) os.remove(fname_in) self.load_code(block.loc_key, fname_out) @@ -68,6 +110,5 @@ class JitCore_Gcc(JitCore_Cc_Base): c_source += "\n".join(func_code) c_source = gen_core(ir_arch.arch, ir_arch.attrib) + c_source - c_source = "#include <Python.h>\n" + c_source - + c_source = "#define PARITY_IMPORT\n#include <Python.h>\n" + c_source return c_source diff --git a/miasm2/jitter/jitcore_llvm.py b/miasm2/jitter/jitcore_llvm.py index ea4f20ec..6c7d47ac 100644 --- a/miasm2/jitter/jitcore_llvm.py +++ b/miasm2/jitter/jitcore_llvm.py @@ -5,18 +5,18 @@ import tempfile from miasm2.jitter.llvmconvert import * import miasm2.jitter.jitcore as jitcore import Jitllvm - +import platform class JitCore_LLVM(jitcore.JitCore): "JiT management, using LLVM as backend" # Architecture dependant libraries - arch_dependent_libs = {"x86": "JitCore_x86.so", - "arm": "JitCore_arm.so", - "msp430": "JitCore_msp430.so", - "mips32": "JitCore_mips32.so", - "aarch64": "JitCore_aarch64.so", - "ppc32": "JitCore_ppc32.so", + arch_dependent_libs = {"x86": "JitCore_x86", + "arm": "JitCore_arm", + "msp430": "JitCore_msp430", + "mips32": "JitCore_mips32", + "aarch64": "JitCore_aarch64", + "ppc32": "JitCore_ppc32", } def __init__(self, ir_arch, bin_stream): @@ -49,9 +49,10 @@ class JitCore_LLVM(jitcore.JitCore): # Get architecture dependant Jitcore library (if any) lib_dir = os.path.dirname(os.path.realpath(__file__)) lib_dir = os.path.join(lib_dir, 'arch') + ext = '.so' if platform.system() != 'Windows' else '.pyd' try: jit_lib = os.path.join( - lib_dir, self.arch_dependent_libs[self.ir_arch.arch.name]) + lib_dir, self.arch_dependent_libs[self.ir_arch.arch.name] + ext) libs_to_load.append(jit_lib) except KeyError: pass diff --git a/miasm2/jitter/op_semantics.c b/miasm2/jitter/op_semantics.c index a0c2316e..33a07054 100644 --- a/miasm2/jitter/op_semantics.c +++ b/miasm2/jitter/op_semantics.c @@ -140,21 +140,21 @@ int imul_hi_op_08(char a, char b) { int64_t res = 0; res = a*b; - return res>>8; + return (int)(res>>8); } int imul_hi_op_16(short a, short b) { int64_t res = 0; res = a*b; - return res>>16; + return (int)(res>>16); } int imul_hi_op_32(int a, int b) { int64_t res = 0; res = (int64_t)a*(int64_t)b; - return res>>32ULL; + return (int)(res>>32ULL); } unsigned int umul16_lo(unsigned short a, unsigned short b) @@ -259,9 +259,9 @@ unsigned int cntleadzeros(uint64_t size, uint64_t src) for (i=(int64_t)size-1; i>=0; i--){ if (src & (1ull << i)) - return size - (i + 1); + return (unsigned int)(size - (i + 1)); } - return size; + return (unsigned int)size; } /* @@ -277,9 +277,9 @@ unsigned int cnttrailzeros(uint64_t size, uint64_t src) uint64_t i; for (i=0; i<size; i++){ if (src & (1ull << i)) - return i; + return (unsigned int)i; } - return size; + return (unsigned int)size; } diff --git a/miasm2/jitter/op_semantics.h b/miasm2/jitter/op_semantics.h index c56c41cf..f797e52b 100644 --- a/miasm2/jitter/op_semantics.h +++ b/miasm2/jitter/op_semantics.h @@ -1,30 +1,44 @@ #ifndef OP_SEMANTICS_H #define OP_SEMANTICS_H +#include <stdint.h> + +#if _WIN32 +#define _MIASM_EXPORT __declspec(dllexport) +#define _MIASM_IMPORT __declspec(dllimport) +#else +#define _MIASM_EXPORT +#define _MIASM_IMPORT +#endif + #define CC_P 1 -extern const uint8_t parity_table[256]; +#ifdef PARITY_IMPORT +_MIASM_IMPORT extern const uint8_t parity_table[256]; +#else +_MIASM_EXPORT extern const uint8_t parity_table[256]; +#endif #define parity(a) parity_table[(a) & 0xFF] -unsigned int my_imul08(unsigned int a, unsigned int b); -unsigned int mul_lo_op(unsigned int size, unsigned int a, unsigned int b); -unsigned int mul_hi_op(unsigned int size, unsigned int a, unsigned int b); -unsigned int imul_lo_op_08(char a, char b); -unsigned int imul_lo_op_16(short a, short b); -unsigned int imul_lo_op_32(int a, int b); -int imul_hi_op_08(char a, char b); -int imul_hi_op_16(short a, short b); -int imul_hi_op_32(int a, int b); +_MIASM_EXPORT unsigned int my_imul08(unsigned int a, unsigned int b); +_MIASM_EXPORT unsigned int mul_lo_op(unsigned int size, unsigned int a, unsigned int b); +_MIASM_EXPORT unsigned int mul_hi_op(unsigned int size, unsigned int a, unsigned int b); +_MIASM_EXPORT unsigned int imul_lo_op_08(char a, char b); +_MIASM_EXPORT unsigned int imul_lo_op_16(short a, short b); +_MIASM_EXPORT unsigned int imul_lo_op_32(int a, int b); +_MIASM_EXPORT int imul_hi_op_08(char a, char b); +_MIASM_EXPORT int imul_hi_op_16(short a, short b); +_MIASM_EXPORT int imul_hi_op_32(int a, int b); -unsigned int umul16_lo(unsigned short a, unsigned short b); -unsigned int umul16_hi(unsigned short a, unsigned short b); +_MIASM_EXPORT unsigned int umul16_lo(unsigned short a, unsigned short b); +_MIASM_EXPORT unsigned int umul16_hi(unsigned short a, unsigned short b); -uint64_t rot_left(uint64_t size, uint64_t a, uint64_t b); -uint64_t rot_right(uint64_t size, uint64_t a, uint64_t b); +_MIASM_EXPORT uint64_t rot_left(uint64_t size, uint64_t a, uint64_t b); +_MIASM_EXPORT uint64_t rot_right(uint64_t size, uint64_t a, uint64_t b); -unsigned int cntleadzeros(uint64_t size, uint64_t src); -unsigned int cnttrailzeros(uint64_t size, uint64_t src); +_MIASM_EXPORT unsigned int cntleadzeros(uint64_t size, uint64_t src); +_MIASM_EXPORT unsigned int cnttrailzeros(uint64_t size, uint64_t src); #define UDIV(sizeA) \ uint ## sizeA ## _t udiv ## sizeA (uint ## sizeA ## _t a, uint ## sizeA ## _t b) \ @@ -77,63 +91,63 @@ unsigned int cnttrailzeros(uint64_t size, uint64_t src); return r; \ } -uint64_t udiv64(uint64_t a, uint64_t b); -uint64_t umod64(uint64_t a, uint64_t b); -int64_t idiv64(int64_t a, int64_t b); -int64_t imod64(int64_t a, int64_t b); - -uint32_t udiv32(uint32_t a, uint32_t b); -uint32_t umod32(uint32_t a, uint32_t b); -int32_t idiv32(int32_t a, int32_t b); -int32_t imod32(int32_t a, int32_t b); - -uint16_t udiv16(uint16_t a, uint16_t b); -uint16_t umod16(uint16_t a, uint16_t b); -int16_t idiv16(int16_t a, int16_t b); -int16_t imod16(int16_t a, int16_t b); - -uint8_t udiv8(uint8_t a, uint8_t b); -uint8_t umod8(uint8_t a, uint8_t b); -int8_t idiv8(int8_t a, int8_t b); -int8_t imod8(int8_t a, int8_t b); - -unsigned int x86_cpuid(unsigned int a, unsigned int reg_num); - -uint32_t fpu_fadd32(uint32_t a, uint32_t b); -uint64_t fpu_fadd64(uint64_t a, uint64_t b); -uint32_t fpu_fsub32(uint32_t a, uint32_t b); -uint64_t fpu_fsub64(uint64_t a, uint64_t b); -uint32_t fpu_fmul32(uint32_t a, uint32_t b); -uint64_t fpu_fmul64(uint64_t a, uint64_t b); -uint32_t fpu_fdiv32(uint32_t a, uint32_t b); -uint64_t fpu_fdiv64(uint64_t a, uint64_t b); -double fpu_ftan(double a); -double fpu_frndint(double a); -double fpu_fsin(double a); -double fpu_fcos(double a); -double fpu_fscale(double a, double b); -double fpu_f2xm1(double a); -uint32_t fpu_fsqrt32(uint32_t a); -uint64_t fpu_fsqrt64(uint64_t a); -uint64_t fpu_fabs64(uint64_t a); -uint64_t fpu_fprem64(uint64_t a, uint64_t b); -double fpu_fchs(double a); -double fpu_fyl2x(double a, double b); -double fpu_fpatan(double a, double b); -unsigned int fpu_fcom_c0(double a, double b); -unsigned int fpu_fcom_c1(double a, double b); -unsigned int fpu_fcom_c2(double a, double b); -unsigned int fpu_fcom_c3(double a, double b); - -uint64_t sint_to_fp_64(int64_t a); -uint32_t sint_to_fp_32(int32_t a); -int32_t fp32_to_sint32(uint32_t a); -int64_t fp64_to_sint64(uint64_t a); -int32_t fp64_to_sint32(uint64_t a); -uint32_t fp64_to_fp32(uint64_t a); -uint64_t fp32_to_fp64(uint32_t a); -uint32_t fpround_towardszero_fp32(uint32_t a); -uint64_t fpround_towardszero_fp64(uint64_t a); +_MIASM_EXPORT uint64_t udiv64(uint64_t a, uint64_t b); +_MIASM_EXPORT uint64_t umod64(uint64_t a, uint64_t b); +_MIASM_EXPORT int64_t idiv64(int64_t a, int64_t b); +_MIASM_EXPORT int64_t imod64(int64_t a, int64_t b); + +_MIASM_EXPORT uint32_t udiv32(uint32_t a, uint32_t b); +_MIASM_EXPORT uint32_t umod32(uint32_t a, uint32_t b); +_MIASM_EXPORT int32_t idiv32(int32_t a, int32_t b); +_MIASM_EXPORT int32_t imod32(int32_t a, int32_t b); + +_MIASM_EXPORT uint16_t udiv16(uint16_t a, uint16_t b); +_MIASM_EXPORT uint16_t umod16(uint16_t a, uint16_t b); +_MIASM_EXPORT int16_t idiv16(int16_t a, int16_t b); +_MIASM_EXPORT int16_t imod16(int16_t a, int16_t b); + +_MIASM_EXPORT uint8_t udiv8(uint8_t a, uint8_t b); +_MIASM_EXPORT uint8_t umod8(uint8_t a, uint8_t b); +_MIASM_EXPORT int8_t idiv8(int8_t a, int8_t b); +_MIASM_EXPORT int8_t imod8(int8_t a, int8_t b); + +_MIASM_EXPORT unsigned int x86_cpuid(unsigned int a, unsigned int reg_num); + +_MIASM_EXPORT uint32_t fpu_fadd32(uint32_t a, uint32_t b); +_MIASM_EXPORT uint64_t fpu_fadd64(uint64_t a, uint64_t b); +_MIASM_EXPORT uint32_t fpu_fsub32(uint32_t a, uint32_t b); +_MIASM_EXPORT uint64_t fpu_fsub64(uint64_t a, uint64_t b); +_MIASM_EXPORT uint32_t fpu_fmul32(uint32_t a, uint32_t b); +_MIASM_EXPORT uint64_t fpu_fmul64(uint64_t a, uint64_t b); +_MIASM_EXPORT uint32_t fpu_fdiv32(uint32_t a, uint32_t b); +_MIASM_EXPORT uint64_t fpu_fdiv64(uint64_t a, uint64_t b); +_MIASM_EXPORT double fpu_ftan(double a); +_MIASM_EXPORT double fpu_frndint(double a); +_MIASM_EXPORT double fpu_fsin(double a); +_MIASM_EXPORT double fpu_fcos(double a); +_MIASM_EXPORT double fpu_fscale(double a, double b); +_MIASM_EXPORT double fpu_f2xm1(double a); +_MIASM_EXPORT uint32_t fpu_fsqrt32(uint32_t a); +_MIASM_EXPORT uint64_t fpu_fsqrt64(uint64_t a); +_MIASM_EXPORT uint64_t fpu_fabs64(uint64_t a); +_MIASM_EXPORT uint64_t fpu_fprem64(uint64_t a, uint64_t b); +_MIASM_EXPORT double fpu_fchs(double a); +_MIASM_EXPORT double fpu_fyl2x(double a, double b); +_MIASM_EXPORT double fpu_fpatan(double a, double b); +_MIASM_EXPORT unsigned int fpu_fcom_c0(double a, double b); +_MIASM_EXPORT unsigned int fpu_fcom_c1(double a, double b); +_MIASM_EXPORT unsigned int fpu_fcom_c2(double a, double b); +_MIASM_EXPORT unsigned int fpu_fcom_c3(double a, double b); + +_MIASM_EXPORT uint64_t sint_to_fp_64(int64_t a); +_MIASM_EXPORT uint32_t sint_to_fp_32(int32_t a); +_MIASM_EXPORT int32_t fp32_to_sint32(uint32_t a); +_MIASM_EXPORT int64_t fp64_to_sint64(uint64_t a); +_MIASM_EXPORT int32_t fp64_to_sint32(uint64_t a); +_MIASM_EXPORT uint32_t fp64_to_fp32(uint64_t a); +_MIASM_EXPORT uint64_t fp32_to_fp64(uint32_t a); +_MIASM_EXPORT uint32_t fpround_towardszero_fp32(uint32_t a); +_MIASM_EXPORT uint64_t fpround_towardszero_fp64(uint64_t a); #define SHIFT_RIGHT_ARITH(size, value, shift) \ ((uint ## size ## _t)((((uint64_t) (shift)) > ((size) - 1))? \ diff --git a/miasm2/jitter/vm_mngr.c b/miasm2/jitter/vm_mngr.c index 9b7a4c98..bd1de2f4 100644 --- a/miasm2/jitter/vm_mngr.c +++ b/miasm2/jitter/vm_mngr.c @@ -15,18 +15,14 @@ ** with this program; if not, write to the Free Software Foundation, Inc., ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#include <Python.h> - -#include <stdio.h> -#include <stdlib.h> +#include "vm_mngr.h" -#include <stdint.h> #include <inttypes.h> +#include <stdio.h> +#include <stdlib.h> #include "queue.h" -#include "vm_mngr.h" - @@ -192,11 +188,11 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6 break; case 16: ret = *((unsigned short*)addr)&0xFFFF; - ret = set_endian16(vm_mngr, ret); + ret = set_endian16(vm_mngr, (uint16_t)ret); break; case 32: ret = *((unsigned int*)addr)&0xFFFFFFFF; - ret = set_endian32(vm_mngr, ret); + ret = set_endian32(vm_mngr, (uint32_t)ret); break; case 64: ret = *((uint64_t*)addr)&0xFFFFFFFFFFFFFFFFULL; @@ -227,10 +223,10 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6 ret = ret; break; case 16: - ret = set_endian16(vm_mngr, ret); + ret = set_endian16(vm_mngr, (uint16_t)ret); break; case 32: - ret = set_endian32(vm_mngr, ret); + ret = set_endian32(vm_mngr, (uint32_t)ret); break; case 64: ret = set_endian64(vm_mngr, ret); @@ -278,11 +274,11 @@ static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size, *((unsigned char*)addr) = src&0xFF; break; case 16: - src = set_endian16(vm_mngr, src); + src = set_endian16(vm_mngr, (uint16_t)src); *((unsigned short*)addr) = src&0xFFFF; break; case 32: - src = set_endian32(vm_mngr, src); + src = set_endian32(vm_mngr, (uint32_t)src); *((unsigned int*)addr) = src&0xFFFFFFFF; break; case 64: @@ -303,10 +299,10 @@ static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size, src = src; break; case 16: - src = set_endian16(vm_mngr, src); + src = set_endian16(vm_mngr, (uint16_t)src); break; case 32: - src = set_endian32(vm_mngr, src); + src = set_endian32(vm_mngr, (uint32_t)src); break; case 64: src = set_endian64(vm_mngr, src); @@ -484,21 +480,21 @@ unsigned char vm_MEM_LOOKUP_08(vm_mngr_t* vm_mngr, uint64_t addr) { unsigned char ret; add_mem_read(vm_mngr, addr, 1); - ret = memory_page_read(vm_mngr, 8, addr); + ret = (unsigned char)memory_page_read(vm_mngr, 8, addr); return ret; } unsigned short vm_MEM_LOOKUP_16(vm_mngr_t* vm_mngr, uint64_t addr) { unsigned short ret; add_mem_read(vm_mngr, addr, 2); - ret = memory_page_read(vm_mngr, 16, addr); + ret = (unsigned short)memory_page_read(vm_mngr, 16, addr); return ret; } unsigned int vm_MEM_LOOKUP_32(vm_mngr_t* vm_mngr, uint64_t addr) { unsigned int ret; add_mem_read(vm_mngr, addr, 4); - ret = memory_page_read(vm_mngr, 32, addr); + ret = (unsigned int)memory_page_read(vm_mngr, 32, addr); return ret; } uint64_t vm_MEM_LOOKUP_64(vm_mngr_t* vm_mngr, uint64_t addr) @@ -533,7 +529,7 @@ int vm_read_mem(vm_mngr_t* vm_mngr, uint64_t addr, char** buffer_ptr, uint64_t s } len = MIN(size, mpn->size - (addr - mpn->ad)); - memcpy(buffer, (char*)(mpn->ad_hp + (addr - mpn->ad)), len); + memcpy(buffer, (char*)mpn->ad_hp + (addr - mpn->ad), len); buffer += len; addr += len; size -= len; @@ -556,7 +552,7 @@ int vm_write_mem(vm_mngr_t* vm_mngr, uint64_t addr, char *buffer, uint64_t size) } len = MIN(size, mpn->size - (addr - mpn->ad)); - memcpy(mpn->ad_hp + (addr-mpn->ad), buffer, len); + memcpy((char*)mpn->ad_hp + (addr-mpn->ad), buffer, len); buffer += len; addr += len; size -= len; @@ -800,7 +796,7 @@ char* dump(vm_mngr_t* vm_mngr) struct memory_page_node * mpn; /* 0x1234567812345678 0x1234567812345678 */ char* intro = "Addr Size Access Comment\n"; - int total_len = strlen(intro) + 1; + size_t total_len = strlen(intro) + 1; buf_final = malloc(total_len); if (buf_final == NULL) { @@ -883,7 +879,7 @@ void remove_memory_breakpoint(vm_mngr_t* vm_mngr, uint64_t ad, unsigned int acce void hexdump(char* m, unsigned int l) { - int i, j, last; + unsigned int i, j, last; last = 0; for (i=0;i<l;i++){ if (!(i%0x10) && i){ @@ -922,7 +918,7 @@ void hexdump(char* m, unsigned int l) // Return vm_mngr's exception flag value -uint64_t get_exception_flag(vm_mngr_t* vm_mngr) +_MIASM_EXPORT uint64_t get_exception_flag(vm_mngr_t* vm_mngr) { return vm_mngr->exception_flags; } diff --git a/miasm2/jitter/vm_mngr.h b/miasm2/jitter/vm_mngr.h index d65a45e8..e55847ea 100644 --- a/miasm2/jitter/vm_mngr.h +++ b/miasm2/jitter/vm_mngr.h @@ -18,12 +18,31 @@ #ifndef CODENAT_H #define CODENAT_H +#if defined(_WIN32) || defined(_WIN64) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#if _WIN32 +#define _MIASM_EXPORT __declspec(dllexport) +#else +#define _MIASM_EXPORT +#endif + +#include <Python.h> +#include <stdint.h> + +#include "queue.h" + #ifdef __APPLE__ #define __BYTE_ORDER __BYTE_ORDER__ #elif defined(__NetBSD__) || defined(__OpenBSD__) #define __BYTE_ORDER _BYTE_ORDER #define __BIG_ENDIAN _BIG_ENDIAN #define __LITTLE_ENDIAN _LITTLE_ENDIAN +#elif defined(_WIN32) || defined(_WIN64) +#define __BIG_ENDIAN '>' +#define __LITTLE_ENDIAN '<' +#define __BYTE_ORDER __LITTLE_ENDIAN #endif @@ -219,9 +238,9 @@ void add_memory_page(vm_mngr_t* vm_mngr, struct memory_page_node* mpn); void add_mem_read(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size); void add_mem_write(vm_mngr_t* vm_mngr, uint64_t addr, uint64_t size); -void check_invalid_code_blocs(vm_mngr_t* vm_mngr); -void check_memory_breakpoint(vm_mngr_t* vm_mngr); -void reset_memory_access(vm_mngr_t* vm_mngr); +_MIASM_EXPORT void check_invalid_code_blocs(vm_mngr_t* vm_mngr); +_MIASM_EXPORT void check_memory_breakpoint(vm_mngr_t* vm_mngr); +_MIASM_EXPORT void reset_memory_access(vm_mngr_t* vm_mngr); PyObject* get_memory_read(vm_mngr_t* vm_mngr); PyObject* get_memory_write(vm_mngr_t* vm_mngr); diff --git a/miasm2/jitter/vm_mngr_py.c b/miasm2/jitter/vm_mngr_py.c index 24f9dd9a..d1610fb8 100644 --- a/miasm2/jitter/vm_mngr_py.c +++ b/miasm2/jitter/vm_mngr_py.c @@ -117,7 +117,7 @@ PyObject* vm_add_memory_page(VmMngr* self, PyObject* args) RAISE(PyExc_TypeError,"name must be str"); name_ptr = PyString_AsString(name); } - mpn = create_memory_page_node(page_addr, buf_size, page_access, name_ptr); + mpn = create_memory_page_node(page_addr, (unsigned int)buf_size, (unsigned int)page_access, name_ptr); if (mpn == NULL) RAISE(PyExc_TypeError,"cannot create page"); if (is_mpn_in_tab(&self->vm_mngr, mpn)) { @@ -261,7 +261,7 @@ PyObject* vm_add_memory_breakpoint(VmMngr* self, PyObject* args) PyGetInt(size, b_size); PyGetInt(access, b_access); - add_memory_breakpoint(&self->vm_mngr, b_ad, b_size, b_access); + add_memory_breakpoint(&self->vm_mngr, b_ad, b_size, (unsigned int)b_access); /* Raise exception in the following pattern: - set_mem(XXX) @@ -287,7 +287,7 @@ PyObject* vm_remove_memory_breakpoint(VmMngr* self, PyObject* args) PyGetInt(ad, b_ad); PyGetInt(access, b_access); - remove_memory_breakpoint(&self->vm_mngr, b_ad, b_access); + remove_memory_breakpoint(&self->vm_mngr, b_ad, (unsigned int)b_access); Py_INCREF(Py_None); return Py_None; @@ -452,7 +452,7 @@ PyObject* vm_get_all_memory(VmMngr* self, PyObject* args) PyDict_SetItemString(dict2, "access", o); Py_DECREF(o); - o = PyInt_FromLong((long)mpn->ad); + o = PyLong_FromUnsignedLongLong(mpn->ad); PyDict_SetItem(dict, o, dict2); Py_DECREF(o); Py_DECREF(dict2); diff --git a/miasm2/jitter/vm_mngr_py.h b/miasm2/jitter/vm_mngr_py.h index 3c7c487b..e2e43c65 100644 --- a/miasm2/jitter/vm_mngr_py.h +++ b/miasm2/jitter/vm_mngr_py.h @@ -1,7 +1,9 @@ #ifndef VM_MNGR_PY_H #define VM_MNGR_PY_H - +#ifdef _WIN32 +#define SIGALRM 0 +#endif typedef struct { PyObject_HEAD diff --git a/setup.py b/setup.py index 7cff1b34..f85dd350 100755 --- a/setup.py +++ b/setup.py @@ -2,30 +2,33 @@ from distutils.core import setup, Extension from distutils.util import get_platform -import shutil +from shutil import copy2 +import platform import os, sys +is_win = platform.system() == "Windows" + def buil_all(): - packages=['miasm2', - 'miasm2/arch', - 'miasm2/arch/x86', - 'miasm2/arch/arm', - 'miasm2/arch/aarch64', - 'miasm2/arch/msp430', - 'miasm2/arch/mep', - 'miasm2/arch/sh4', - 'miasm2/arch/mips32', - 'miasm2/arch/ppc', - 'miasm2/core', - 'miasm2/expression', - 'miasm2/ir', - 'miasm2/ir/translators', - 'miasm2/analysis', - 'miasm2/os_dep', - 'miasm2/os_dep/linux', - 'miasm2/jitter', - 'miasm2/jitter/arch', - 'miasm2/jitter/loader', + packages=["miasm2", + "miasm2/arch", + "miasm2/arch/x86", + "miasm2/arch/arm", + "miasm2/arch/aarch64", + "miasm2/arch/msp430", + "miasm2/arch/mep", + "miasm2/arch/sh4", + "miasm2/arch/mips32", + "miasm2/arch/ppc", + "miasm2/core", + "miasm2/expression", + "miasm2/ir", + "miasm2/ir/translators", + "miasm2/analysis", + "miasm2/os_dep", + "miasm2/os_dep/linux", + "miasm2/jitter", + "miasm2/jitter/arch", + "miasm2/jitter/loader", ] ext_modules_all = [ Extension("miasm2.jitter.VmMngr", @@ -88,26 +91,31 @@ def buil_all(): ]), ] - print 'building' + if is_win: + # Force setuptools to use whatever msvc version installed + os.environ['MSSdk'] = '1' + os.environ['DISTUTILS_USE_SDK'] = '1' + + print "building" build_ok = False - for name, ext_modules in [('all', ext_modules_all), + for name, ext_modules in [("all", ext_modules_all), ]: - print 'build with', repr(name) + print "build with", repr(name) try: s = setup( - name = 'Miasm', - version = '2.0', + name = "Miasm", + version = "2.0", packages = packages, - package_data = {'miasm2':['jitter/*.h', - 'jitter/arch/*.h',]}, + package_data = {"miasm2":["jitter/*.h", + "jitter/arch/*.h",]}, ext_modules = ext_modules, # Metadata - author = 'Fabrice Desclaux', - author_email = 'serpilliere@droid-corp.org', - description = 'Machine code manipulation library', - license = 'GPLv2', - # keywords = '', - # url = '', + author = "Fabrice Desclaux", + author_email = "serpilliere@droid-corp.org", + description = "Machine code manipulation library", + license = "GPLv2", + # keywords = "", + # url = "", ) except SystemExit, e: print repr(e) @@ -115,17 +123,41 @@ def buil_all(): build_ok = True break if not build_ok: - raise ValueError('Unable to build Miasm!') - print 'build', name + raise ValueError("Unable to build Miasm!") + print "build", name # we copy libraries from build dir to current miasm directory - build_base = None - if 'build' in s.command_options: - if 'build_base' in s.command_options['build']: - build_base = s.command_options['build']['build_base'] - if build_base is None: - build_base = "build" - plat_specifier = ".%s-%s" % (get_platform(), sys.version[0:3]) - build_base = os.path.join('build','lib' + plat_specifier) - print build_base + build_base = "build" + if "build" in s.command_options: + if "build_base" in s.command_options["build"]: + build_base = s.command_options["build"]["build_base"] + + print build_base + if is_win: + libs = [] + for root, _, files in os.walk(build_base): + for filename in files: + if not filename.endswith(".lib"): + continue + f_path = os.path.join(root, filename) + libs.append(f_path) + + lib_dirname = None + for dirname in os.listdir(build_base): + if not dirname.startswith("lib"): + continue + lib_dirname = dirname + break + + jitters = [] + for lib in libs: + filename = os.path.basename(lib) + dst = os.path.join(build_base, lib_dirname, "miasm2", "jitter") + if filename not in ["VmMngr.lib", "Jitgcc.lib", "Jitllvm.lib"]: + dst = os.path.join(dst, "arch") + dst = os.path.join(dst, filename) + if not os.path.isfile(dst): + print "Copying", lib, "to", dst + copy2(lib, dst) buil_all() + diff --git a/test/jitter/test_post_instr.py b/test/jitter/test_post_instr.py index 39e87616..97ba167f 100644 --- a/test/jitter/test_post_instr.py +++ b/test/jitter/test_post_instr.py @@ -35,7 +35,7 @@ jitter.add_exception_handler(EXCEPT_BREAKPOINT_MEMORY, jitter.vm.add_memory_breakpoint(0x11000-4, 4, PAGE_READ | PAGE_WRITE) # The memory write pending will raise automod execption -# The RET should not re evalueate PC @ [ESP+4] +# The RET should not re evaluate PC @ [ESP+4] jitter.init_run(0x1000) try: jitter.continue_run() diff --git a/test/test_all.py b/test/test_all.py index a69ec229..d1ccb19f 100755 --- a/test/test_all.py +++ b/test/test_all.py @@ -6,12 +6,15 @@ import os import platform import time import tempfile +import platform from utils.test import Test from utils.testset import TestSet from utils import cosmetics, multithread from multiprocessing import Queue +is_win = platform.system() == "Windows" + testset = TestSet("../") TAGS = {"regression": "REGRESSION", # Regression tests "example": "EXAMPLE", # Examples @@ -99,6 +102,8 @@ for script in ["x86/sem.py", if jitter in blacklist.get(script, []): continue tags = [TAGS[jitter]] if jitter in TAGS else [] + if is_win and script.endswith("mn_div.py"): + continue testset += ArchUnitTest(script, jitter, base_dir="arch", tags=tags) testset += ArchUnitTest("x86/unit/access_xmm.py", "python", base_dir="arch") @@ -653,7 +658,7 @@ for strategy in ["code-cov", "branch-cov", "path-cov"]: testset += ExampleSymbolExec(["dse_strategies.py", Example.get_sample("simple_test.bin"), strategy], - tags=[TAGS["z3"]]) + tags=[TAGS["z3"]]) ## Jitter class ExampleJitter(Example): diff --git a/test/utils/cosmetics.py b/test/utils/cosmetics.py index d870507b..e80e1f09 100644 --- a/test/utils/cosmetics.py +++ b/test/utils/cosmetics.py @@ -1,5 +1,7 @@ import os +import platform +is_win = platform.system() == "Windows" def getTerminalSize(): "Return the size of the terminal : COLUMNS, LINES" @@ -37,6 +39,12 @@ colors = {"red": "\033[91;1m", "lightcyan": "\033[96m", "blue": "\033[94;1m"} +if is_win: + colors = {"red": "", + "end": "", + "green": "", + "lightcyan": "", + "blue": ""} def write_colored(text, color, already_printed=0): text_colored = colors[color] + text + colors["end"] diff --git a/test/utils/testset.py b/test/utils/testset.py index 29a4e5d0..5688b7e5 100644 --- a/test/utils/testset.py +++ b/test/utils/testset.py @@ -35,11 +35,45 @@ class MessageClose(Message): "Close the channel" pass +def worker(todo_queue, message_queue, init_args): + """Worker launched in parrallel + @todo_queue: task to do + @message_queue: communication with Host + @init_args: additionnal arguments for command line + """ + + # Main loop + while True: + # Acquire a task + test = todo_queue.get() + if test is None: + break + test.start_time = time.time() + message_queue.put(MessageTaskNew(test)) + + # Launch test + executable = test.executable if test.executable else sys.executable + testpy = subprocess.Popen(([executable] + + init_args + test.command_line), + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + cwd=test.base_dir) + outputs = testpy.communicate() + + # Check result + error = None + if testpy.returncode != 0: + error = outputs[1] + + # Report task finish + message_queue.put(MessageTaskDone(test, error)) class TestSet(object): "Manage a set of test" + worker = staticmethod(worker) + def __init__(self, base_dir): """Initalise a test set @base_dir: base directory for tests @@ -132,46 +166,6 @@ class TestSet(object): raise ValueError("Unknown message type %s" % type(message)) @staticmethod - def worker(todo_queue, message_queue, init_args): - """Worker launched in parrallel - @todo_queue: task to do - @message_queue: communication with Host - @init_args: additionnal arguments for command line - """ - - # Main loop - while True: - # Acquire a task - test = todo_queue.get() - if test is None: - break - test.start_time = time.time() - message_queue.put(MessageTaskNew(test)) - - # Go to the expected directory - current_directory = os.getcwd() - os.chdir(test.base_dir) - - # Launch test - executable = test.executable if test.executable else sys.executable - testpy = subprocess.Popen(([executable] + - init_args + test.command_line), - stdout=subprocess.PIPE, - stderr=subprocess.PIPE) - outputs = testpy.communicate() - - # Check result - error = None - if testpy.returncode != 0: - error = outputs[1] - - # Restore directory - os.chdir(current_directory) - - # Report task finish - message_queue.put(MessageTaskDone(test, error)) - - @staticmethod def fast_unify(seq, idfun=None): """Order preserving unifying list function @seq: list to unify |