about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAxel Souchet <0vercl0k@tuxfamily.org>2018-09-09 06:11:00 -0700
committerserpilliere <serpilliere@users.noreply.github.com>2018-09-09 15:11:00 +0200
commit8e6b39d80e9f8db8389bd2a8106d0f64b91c19e9 (patch)
treedbf342089690704e89c10532b83d1d81709a49f4
parente61116884ac7879db08313542c6c28a8b00297c5 (diff)
downloadfocaccia-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
-rw-r--r--.appveyor.yml59
-rw-r--r--example/symbol_exec/depgraph.py2
-rw-r--r--example/symbol_exec/dse_crackme.py32
-rw-r--r--miasm2/jitter/JitCore.c41
-rw-r--r--miasm2/jitter/JitCore.h37
-rw-r--r--miasm2/jitter/arch/JitCore_aarch64.h7
-rw-r--r--miasm2/jitter/arch/JitCore_arm.h7
-rw-r--r--miasm2/jitter/arch/JitCore_mep.h7
-rw-r--r--miasm2/jitter/arch/JitCore_mips32.h7
-rw-r--r--miasm2/jitter/arch/JitCore_msp430.h7
-rw-r--r--miasm2/jitter/arch/JitCore_ppc32.h7
-rw-r--r--miasm2/jitter/arch/JitCore_x86.c2
-rw-r--r--miasm2/jitter/arch/JitCore_x86.h16
-rw-r--r--miasm2/jitter/bn.h73
-rw-r--r--miasm2/jitter/jitcore_cc_base.py10
-rw-r--r--miasm2/jitter/jitcore_gcc.py59
-rw-r--r--miasm2/jitter/jitcore_llvm.py17
-rw-r--r--miasm2/jitter/op_semantics.c14
-rw-r--r--miasm2/jitter/op_semantics.h160
-rw-r--r--miasm2/jitter/vm_mngr.c42
-rw-r--r--miasm2/jitter/vm_mngr.h25
-rw-r--r--miasm2/jitter/vm_mngr_py.c8
-rw-r--r--miasm2/jitter/vm_mngr_py.h4
-rwxr-xr-xsetup.py122
-rw-r--r--test/jitter/test_post_instr.py2
-rwxr-xr-xtest/test_all.py7
-rw-r--r--test/utils/cosmetics.py8
-rw-r--r--test/utils/testset.py74
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