about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--README.md36
-rw-r--r--example/ida/depgraph.py7
-rw-r--r--example/jitter/unpack_upx.py4
-rw-r--r--example/symbol_exec/dse_crackme.py7
-rw-r--r--miasm/analysis/depgraph.py2
-rw-r--r--miasm/analysis/dse.py2
-rw-r--r--miasm/analysis/sandbox.py20
-rw-r--r--miasm/arch/aarch64/arch.py2
-rw-r--r--miasm/arch/aarch64/sem.py2
-rw-r--r--miasm/arch/x86/arch.py6
-rw-r--r--miasm/arch/x86/sem.py45
-rw-r--r--miasm/core/utils.py16
-rw-r--r--miasm/ir/ir.py10
-rw-r--r--miasm/jitter/jitload.py41
-rw-r--r--miasm/jitter/loader/elf.py2
-rw-r--r--miasm/jitter/loader/pe.py147
-rw-r--r--miasm/jitter/loader/utils.py26
-rw-r--r--miasm/jitter/vm_mngr.c2
-rw-r--r--miasm/jitter/vm_mngr.h5
-rw-r--r--miasm/loader/pe_init.py2
-rw-r--r--miasm/os_dep/common.py35
-rw-r--r--miasm/os_dep/linux/syscall.py32
-rw-r--r--miasm/os_dep/linux_stdlib.py20
-rw-r--r--miasm/os_dep/win_api_x86_32.py299
-rw-r--r--miasm/os_dep/win_api_x86_32_seh.py30
-rw-r--r--test/arch/aarch64/arch.py2
-rw-r--r--test/arch/x86/qemu/testqemu.py6
-rw-r--r--test/arch/x86/qemu/testqemu64.py6
-rwxr-xr-xtest/os_dep/linux/stdlib.py2
-rwxr-xr-xtest/os_dep/win_api_x86_32.py9
-rwxr-xr-xtest/test_all.py2
31 files changed, 486 insertions, 341 deletions
diff --git a/README.md b/README.md
index abbdcf34..8c03635a 100644
--- a/README.md
+++ b/README.md
@@ -7,9 +7,25 @@
 <img src="doc/logo_miasm.png">
 </p>
 
-Reverse engineering framework in Python
 
-**Table of Contents**
+What is Miasm?
+==============
+
+Miasm is a free and open source (GPLv2) reverse engineering framework.
+Miasm aims to analyze / modify / generate binary programs. Here is
+a non exhaustive list of features:
+
+* Opening / modifying / generating PE / ELF 32 / 64 LE / BE
+* Assembling / Disassembling X86 / ARM / MIPS / SH4 / MSP430
+* Representing assembly semantic using intermediate language
+* Emulating using JIT (dynamic code analysis, unpacking, ...)
+* Expression simplification for automatic de-obfuscation
+* ...
+
+See the official [blog](http://miasm.re) for more examples and demos.
+
+Table of Contents
+=================
 
 - [What is Miasm?](#user-content-what-is-miasm)
 - [Basic examples](#user-content-basic-examples)
@@ -28,22 +44,6 @@ Reverse engineering framework in Python
 - [Misc](#user-content-misc)
 
 
-What is Miasm?
-==============
-
-Miasm is a free and open source (GPLv2) reverse engineering framework.
-Miasm aims to analyze / modify / generate binary programs. Here is
-a non exhaustive list of features:
-
-* Opening / modifying / generating PE / ELF 32 / 64 LE / BE
-* Assembling / Disassembling X86 / ARM / MIPS / SH4 / MSP430
-* Representing assembly semantic using intermediate language
-* Emulating using JIT (dynamic code analysis, unpacking, ...)
-* Expression simplification for automatic de-obfuscation
-* ...
-
-See the official [blog](http://miasm.re) for more examples and demos.
-
 Basic examples
 ==============
 
diff --git a/example/ida/depgraph.py b/example/ida/depgraph.py
index 73fc0f87..9e45ffa9 100644
--- a/example/ida/depgraph.py
+++ b/example/ida/depgraph.py
@@ -25,10 +25,11 @@ from utils import guess_machine
 
 class depGraphSettingsForm(ida_kernwin.Form):
 
-    def __init__(self, ira, ircfg):
+    def __init__(self, ira, ircfg, mn):
 
         self.ira = ira
         self.ircfg = ircfg
+        self.mn = mn
         self.stk_args = {'ARG%d' % i:i for i in range(10)}
         self.stk_unalias_force = False
 
@@ -129,7 +130,7 @@ Method to use:
             arg_num = self.stk_args[value]
             stk_high = m2_expr.ExprInt(idc.GetSpd(line.offset), ir_arch.sp.size)
             stk_off = m2_expr.ExprInt(self.ira.sp.size // 8 * arg_num, ir_arch.sp.size)
-            element =  m2_expr.ExprMem(mn.regs.regs_init[ir_arch.sp] + stk_high + stk_off, self.ira.sp.size)
+            element =  m2_expr.ExprMem(self.mn.regs.regs_init[ir_arch.sp] + stk_high + stk_off, self.ira.sp.size)
             element = expr_simp(element)
             # Force stack unaliasing
             self.stk_unalias_force = True
@@ -230,7 +231,7 @@ def launch_depgraph():
     ircfg = ir_arch.new_ircfg_from_asmcfg(asmcfg)
 
     # Get settings
-    settings = depGraphSettingsForm(ir_arch, ircfg)
+    settings = depGraphSettingsForm(ir_arch, ircfg, mn)
     settings.Execute()
 
     loc_key, elements, line_nb = settings.loc_key, settings.elements, settings.line_nb
diff --git a/example/jitter/unpack_upx.py b/example/jitter/unpack_upx.py
index 3b8125f4..baa6f0bb 100644
--- a/example/jitter/unpack_upx.py
+++ b/example/jitter/unpack_upx.py
@@ -5,6 +5,8 @@ from pdb import pm
 from miasm.loader import pe
 from miasm.analysis.sandbox import Sandbox_Win_x86_32
 
+from miasm.os_dep.common import get_win_str_a
+
 # User defined methods
 
 def kernel32_GetProcAddress(jitter):
@@ -17,7 +19,7 @@ def kernel32_GetProcAddress(jitter):
 
     # Handle ordinal imports
     fname = (args.fname if args.fname < 0x10000
-             else jitter.get_str_ansi(args.fname))
+             else get_win_str_a(jitter, args.fname))
     logging.error(fname)
 
     # Get the generated address of the library, and store it in memory to
diff --git a/example/symbol_exec/dse_crackme.py b/example/symbol_exec/dse_crackme.py
index be9f4490..82a7af08 100644
--- a/example/symbol_exec/dse_crackme.py
+++ b/example/symbol_exec/dse_crackme.py
@@ -20,6 +20,7 @@ from miasm.core.utils import int_to_byte
 from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm.analysis.sandbox import Sandbox_Linux_x86_64
 from miasm.expression.expression import *
+from miasm.os_dep.win_api_x86_32 import get_win_str_a
 
 is_win = platform.system() == "Windows"
 
@@ -37,7 +38,7 @@ def xxx_fopen(jitter):
     '''
     global my_FILE_ptr
     ret_addr, args = jitter.func_args_systemv(['path', 'mode'])
-    fname = jitter.get_str_ansi(args.path)
+    fname = get_win_str_a(jitter, args.path)
     FILE_to_info[my_FILE_ptr] = FInfo(fname, open(fname, "rb"))
     my_FILE_ptr += 1
     return jitter.func_ret_stdcall(ret_addr, my_FILE_ptr - 1)
@@ -139,7 +140,7 @@ def xxx_fopen_symb(dse):
     mode = dse.eval_expr(regs.RSI)
     assert fname_addr.is_int()
     assert mode.is_int()
-    fname = dse.jitter.get_str_ansi(int(fname_addr))
+    fname = get_win_str_a(dse.jitter, int(fname_addr))
     ret_addr = ExprInt(dse.jitter.get_stack_arg(0), regs.RIP.size)
 
     assert len(FILE_to_info_symb) == 0
@@ -223,7 +224,7 @@ class FinishOn(Exception):
         super(FinishOn, self).__init__()
 
 def xxx_puts_symb(dse):
-    string = dse.jitter.get_str_ansi(dse.jitter.cpu.RDI)
+    string = get_win_str_a(dse.jitter, dse.jitter.cpu.RDI)
     raise FinishOn(string)
 
 
diff --git a/miasm/analysis/depgraph.py b/miasm/analysis/depgraph.py
index 80e94c7f..7113dd51 100644
--- a/miasm/analysis/depgraph.py
+++ b/miasm/analysis/depgraph.py
@@ -15,7 +15,7 @@ from miasm.expression.expression_helper import possible_values
 
 try:
     import z3
-except ImportError:
+except:
     pass
 
 @total_ordering
diff --git a/miasm/analysis/dse.py b/miasm/analysis/dse.py
index 3f31f344..2c2b41f4 100644
--- a/miasm/analysis/dse.py
+++ b/miasm/analysis/dse.py
@@ -52,7 +52,7 @@ from collections import namedtuple
 
 try:
     import z3
-except ImportError:
+except:
     z3 = None
 
 from future.utils import viewitems
diff --git a/miasm/analysis/sandbox.py b/miasm/analysis/sandbox.py
index b8aaf788..3040a1a8 100644
--- a/miasm/analysis/sandbox.py
+++ b/miasm/analysis/sandbox.py
@@ -6,13 +6,13 @@ import logging
 from argparse import ArgumentParser
 
 from future.utils import viewitems, viewvalues
+from past.builtins import basestring
 
-from miasm.core.utils import force_bytes
 from miasm.analysis.machine import Machine
 from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm.analysis import debugging
 from miasm.jitter.jitload import log_func
-
+from miasm.core.utils import force_bytes
 
 
 class Sandbox(object):
@@ -51,8 +51,7 @@ class Sandbox(object):
         """
 
         # Initialize
-        if not isinstance(fname, bytes):
-            fname = fname.encode('utf8')
+        assert isinstance(fname, basestring)
         self.fname = fname
         self.options = options
         if custom_methods is None:
@@ -183,17 +182,18 @@ class Arch(object):
 
 class OS_Win(OS):
     # DLL to import
-    ALL_IMP_DLL = ["ntdll.dll", "kernel32.dll", "user32.dll",
-                   "ole32.dll", "urlmon.dll",
-                   "ws2_32.dll", 'advapi32.dll', "psapi.dll",
-                   ]
-    modules_path = b"win_dll"
+    ALL_IMP_DLL = [
+        "ntdll.dll", "kernel32.dll", "user32.dll",
+        "ole32.dll", "urlmon.dll",
+        "ws2_32.dll", 'advapi32.dll', "psapi.dll",
+    ]
+    modules_path = "win_dll"
 
     def __init__(self, custom_methods, *args, **kwargs):
         from miasm.jitter.loader.pe import vm_load_pe, vm_load_pe_libs,\
             preload_pe, libimp_pe, vm_load_pe_and_dependencies
         from miasm.os_dep import win_api_x86_32, win_api_x86_32_seh
-        methods = dict((name.encode(),func) for name, func in viewitems(win_api_x86_32.__dict__))
+        methods = dict((name, func) for name, func in viewitems(win_api_x86_32.__dict__))
         methods.update(custom_methods)
 
         super(OS_Win, self).__init__(methods, *args, **kwargs)
diff --git a/miasm/arch/aarch64/arch.py b/miasm/arch/aarch64/arch.py
index d12fbe72..33c1d427 100644
--- a/miasm/arch/aarch64/arch.py
+++ b/miasm/arch/aarch64/arch.py
@@ -2152,7 +2152,7 @@ aarch64op("ldxp", [bs('1'), sf, bs('001000'), bs('0'), bs('1'), bs('1'), bs('111
 
 # load acquire/store release p.141
 aarch64op("ldar", [bs('1'), sf, bs('001000'), bs('1'), bs('1'), bs('0'), bs('11111'), bs('1'), bs('11111'), rn64_deref_nooff, rt], [rt, rn64_deref_nooff])
-aarch64op("ldarb",[bs('0'), bs('0'), bs('001000'), bs('1'), bs('1'), bs('0'), bs('11111'), bs('1'), bs('11111'), rn64_deref_nooff, rt], [rt, rn64_deref_nooff])
+aarch64op("ldarb",[bs('0'), bs('0'), bs('001000'), bs('1'), bs('1'), bs('0'), bs('11111'), bs('1'), bs('11111'), rn64_deref_nooff, rt32], [rt32, rn64_deref_nooff])
 aarch64op("ldarh",[bs('0'), bs('1'), bs('001000'), bs('0'), bs('1'), bs('0'), bs('11111'), bs('1'), bs('11111'), rn64_deref_nooff, rt], [rt, rn64_deref_nooff])
 aarch64op("ldaxp",[bs('1'), sf, bs('001000'), bs('0'), bs('1'), bs('1'), bs('11111'), bs('1'), bs('11111'), rn64_deref_nooff, rt], [rt, rn64_deref_nooff])
 aarch64op("ldaxr",[bs('1'), sf, bs('001000'), bs('0'), bs('1'), bs('0'), bs('11111'), bs('1'), bs('11111'), rn64_deref_nooff, rt], [rt, rn64_deref_nooff])
diff --git a/miasm/arch/aarch64/sem.py b/miasm/arch/aarch64/sem.py
index ce77aa2c..e7db4782 100644
--- a/miasm/arch/aarch64/sem.py
+++ b/miasm/arch/aarch64/sem.py
@@ -1341,6 +1341,8 @@ mnemo_func.update({
     'ldrsh': ldrsh,
     'ldrsw': ldrsw,
 
+    'ldarb': ldrb,
+
     'ldaxrb': ldaxrb,
     'stlxrb': stlxrb,
 
diff --git a/miasm/arch/x86/arch.py b/miasm/arch/x86/arch.py
index 3053301a..3a797d0b 100644
--- a/miasm/arch/x86/arch.py
+++ b/miasm/arch/x86/arch.py
@@ -496,7 +496,7 @@ class instruction_x86(instruction):
             return True
         if self.name.startswith('SYS'):
             return True
-        return self.name in ['CALL', 'HLT', 'IRET', 'IRETD', 'IRETQ', 'ICEBP']
+        return self.name in ['CALL', 'HLT', 'IRET', 'IRETD', 'IRETQ', 'ICEBP', 'UD2']
 
     def splitflow(self):
         if self.name in conditional_branch:
@@ -3807,6 +3807,10 @@ addop("mulsd", [bs8(0x0f), bs8(0x59), pref_f2] + rmmod(xmm_reg, rm_arg_xmm_m64))
 addop("divss", [bs8(0x0f), bs8(0x5e), pref_f3] + rmmod(xmm_reg, rm_arg_xmm_m32))
 addop("divsd", [bs8(0x0f), bs8(0x5e), pref_f2] + rmmod(xmm_reg, rm_arg_xmm_m64))
 
+addop("roundss", [bs8(0x0f), bs8(0x3a), bs8(0x0a), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m32) + [u08])
+addop("roundsd", [bs8(0x0f), bs8(0x3a), bs8(0x0b), pref_66] +
+      rmmod(xmm_reg, rm_arg_xmm_m64) + [u08])
 
 addop("pminsw", [bs8(0x0f), bs8(0xea), no_xmm_pref] + rmmod(mm_reg, rm_arg_mm))
 addop("pminsw", [bs8(0x0f), bs8(0xea), pref_66] + rmmod(xmm_reg, rm_arg_xmm))
diff --git a/miasm/arch/x86/sem.py b/miasm/arch/x86/sem.py
index 962667b4..e59a9b18 100644
--- a/miasm/arch/x86/sem.py
+++ b/miasm/arch/x86/sem.py
@@ -1400,7 +1400,7 @@ def call(ir, instr, dst):
             m2 = base.zeroExtend(meip.size)
         elif dst.op == "far":
             # Far call far [eax]
-            addr = dst.args[0].arg
+            addr = dst.args[0].ptr
             m1 = ir.ExprMem(addr, CS.size)
             m2 = ir.ExprMem(addr + m2_expr.ExprInt(2, addr.size), meip.size)
         else:
@@ -1528,7 +1528,7 @@ def jmp(ir, instr, dst):
             m2 = base.zeroExtend(meip.size)
         elif dst.op == "far":
             # Far jmp far [eax]
-            addr = dst.args[0].arg
+            addr = dst.args[0].ptr
             m1 = ir.ExprMem(addr, CS.size)
             m2 = ir.ExprMem(addr + m2_expr.ExprInt(2, addr.size), meip.size)
         else:
@@ -2625,7 +2625,7 @@ def fnstenv(ir, instr, dst):
     e.append(m2_expr.ExprAssign(ad, float_control))
     ad = ir.ExprMem(
         dst.ptr + m2_expr.ExprInt(
-            size // (8 * 1),
+            (size // 8) * 1,
             dst.ptr.size
         ),
         size=16
@@ -2633,7 +2633,7 @@ def fnstenv(ir, instr, dst):
     e.append(m2_expr.ExprAssign(ad, status_word))
     ad = ir.ExprMem(
         dst.ptr + m2_expr.ExprInt(
-            size // (8 * 3),
+            (size // 8) * 3,
             dst.ptr.size
         ),
         size=size
@@ -2641,7 +2641,7 @@ def fnstenv(ir, instr, dst):
     e.append(m2_expr.ExprAssign(ad, float_eip[:size]))
     ad = ir.ExprMem(
         dst.ptr + m2_expr.ExprInt(
-            size // (8 * 4),
+            (size // 8) * 4,
             dst.ptr.size
         ),
         size=16
@@ -2649,7 +2649,7 @@ def fnstenv(ir, instr, dst):
     e.append(m2_expr.ExprAssign(ad, float_cs))
     ad = ir.ExprMem(
         dst.ptr + m2_expr.ExprInt(
-            size // (8 * 5),
+            (size // 8) * 5,
             dst.ptr.size
         ),
         size=size
@@ -2657,7 +2657,7 @@ def fnstenv(ir, instr, dst):
     e.append(m2_expr.ExprAssign(ad, float_address[:size]))
     ad = ir.ExprMem(
         dst.ptr + m2_expr.ExprInt(
-            size // (8 * 6),
+            (size // 8) * 6,
             dst.ptr.size
         ),
         size=16
@@ -5080,6 +5080,33 @@ def movmskpd(ir, instr, dst, src):
         out.append(src[(64 * i) + 63:(64 * i) + 64])
     return [m2_expr.ExprAssign(dst, m2_expr.ExprCompose(*out).zeroExtend(dst.size))], []
 
+def _roundscalar(ir, inst, dst, src, imm8, double):
+    res = None
+    ctl = int(imm8)
+    dst_expr = dst[:64] if double else dst[:32]
+    src_expr = src[:64] if double else src[:32]
+    if ctl & 0x4 != 0:
+        # Use MXCSR rounding config
+        # TODO: here we assume it's round to nearest, ties to even
+        res = m2_expr.ExprOp('fpround_towardsnearest', src_expr)
+    else:
+        # Use encoded rounding mechanism
+        rounding_mechanism = ctl & 0x3
+        ROUNDING_MODE = {
+            0x0: 'fpround_towardsnearest',
+            0x1: 'fpround_down',
+            0x2: 'fpround_up',
+            0x3: 'fpround_towardszero'
+        }
+        res = m2_expr.ExprOp(ROUNDING_MODE[rounding_mechanism], src_expr)
+    return [m2_expr.ExprAssign(dst_expr, res)], []
+
+def roundss(ir, inst, dst, src, imm8):
+    return _roundscalar(ir, inst, dst, src, imm8, False)
+
+def roundsd(ir, inst, dst, src, imm8):
+    return _roundscalar(ir, inst, dst, src, imm8, True)
+
 def fxsave(_ir, _instr, _src):
     # Implemented as a NOP for now
     return [], []
@@ -5523,6 +5550,10 @@ mnemo_func = {'mov': mov,
               "divps": divps,
               "divpd": divpd,
 
+              # Rounding
+              "roundss": roundss,
+              "roundsd": roundsd,
+
               # Comparisons (floating-point)
               #
               "minps": minps,
diff --git a/miasm/core/utils.py b/miasm/core/utils.py
index 9856d4f2..7667a656 100644
--- a/miasm/core/utils.py
+++ b/miasm/core/utils.py
@@ -1,4 +1,5 @@
 from __future__ import print_function
+import sys
 from builtins import range
 import struct
 import inspect
@@ -86,6 +87,21 @@ def force_bytes(value):
         return value
 
 
+def force_str(value):
+    if isinstance(value, str):
+        return value
+    elif isinstance(value, bytes):
+        out = ""
+        for i in range(len(value)):
+            # For Python2/Python3 compatibility
+            c = ord(value[i:i+1])
+            out += chr(c)
+        value = out
+    else:
+        raise ValueError("Unsupported type")
+    return value
+
+
 def iterbytes(string):
     for i in range(len(string)):
         yield string[i:i+1]
diff --git a/miasm/ir/ir.py b/miasm/ir/ir.py
index 1ddcaab5..613a4bce 100644
--- a/miasm/ir/ir.py
+++ b/miasm/ir/ir.py
@@ -639,16 +639,6 @@ class IRCFG(DiGraph):
             self.blocks[loc_key] = IRBlock(loc_key, assignblks)
         return modified
 
-    def get_rw(self, regs_ids=None):
-        """
-        Calls get_rw(irb) for each block
-        @regs_ids : ids of registers used in IR
-        """
-        if regs_ids is None:
-            regs_ids = []
-        for irblock in viewvalues(self.blocks):
-            irblock.get_rw(regs_ids)
-
     def _extract_dst(self, todo, done):
         """
         Naive extraction of @todo destinations
diff --git a/miasm/jitter/jitload.py b/miasm/jitter/jitload.py
index 9fcb0b0a..e8277e34 100644
--- a/miasm/jitter/jitload.py
+++ b/miasm/jitter/jitload.py
@@ -429,8 +429,8 @@ class Jitter(object):
         return self.cpu.get_exception() | self.vm.get_exception()
 
     # commun functions
-    def get_str_ansi(self, addr, max_char=None):
-        """Get ansi str from vm.
+    def get_c_str(self, addr, max_char=None):
+        """Get C str from vm.
         @addr: address in memory
         @max_char: maximum len"""
         l = 0
@@ -440,31 +440,21 @@ class Jitter(object):
             tmp += 1
             l += 1
         value = self.vm.get_mem(addr, l)
-        return value.decode('utf8')
+        value = force_str(value)
+        return value
 
-    def get_str_unic(self, addr, max_char=None):
-        """Get unicode str from vm.
+    def set_c_str(self, addr, value):
+        """Set C str str from vm.
         @addr: address in memory
-        @max_char: maximum len"""
-        l = 0
-        tmp = addr
-        while ((max_char is None or l < max_char) and
-               self.vm.get_mem(tmp, 2) != b"\x00\x00"):
-            tmp += 2
-            l += 2
-        s = self.vm.get_mem(addr, l)
-        s = s.decode("utf-16le")
-        return s
-
-    def set_str_ansi(self, addr, string):
-        """Set an ansi string in memory"""
-        string = (string + "\x00").encode('utf8')
-        self.vm.set_mem(addr, string)
-
-    def set_str_unic(self, addr, string):
-        """Set an unicode string in memory"""
-        s = (string + "\x00").encode('utf-16le')
-        self.vm.set_mem(addr, s)
+        @value: str"""
+        value = force_bytes(value)
+        self.vm.set_mem(addr, value + b'\x00')
+
+    def get_str_ansi(self, addr, max_char=None):
+        raise NotImplementedError("Deprecated: use os_dep.win_api_x86_32.get_win_str_a")
+
+    def get_str_unic(self, addr, max_char=None):
+        raise NotImplementedError("Deprecated: use os_dep.win_api_x86_32.get_win_str_a")
 
     @staticmethod
     def handle_lib(jitter):
@@ -501,7 +491,6 @@ class Jitter(object):
         self.libs = libs
         out = {}
         for name, func in viewitems(user_globals):
-            name = force_bytes(name)
             out[name] = func
         self.user_globals = out
 
diff --git a/miasm/jitter/loader/elf.py b/miasm/jitter/loader/elf.py
index b70872df..65d96001 100644
--- a/miasm/jitter/loader/elf.py
+++ b/miasm/jitter/loader/elf.py
@@ -9,6 +9,7 @@ import miasm.loader.elf as elf_csts
 
 from miasm.jitter.csts import *
 from miasm.jitter.loader.utils import canon_libname_libfunc, libimp
+from miasm.core.utils import force_str
 from miasm.core.interval import interval
 
 import logging
@@ -26,6 +27,7 @@ def get_import_address_elf(e):
         if not hasattr(sh, 'rel'):
             continue
         for k, v in viewitems(sh.rel):
+            k = force_str(k)
             import2addr[('xxx', k)].add(v.offset)
     return import2addr
 
diff --git a/miasm/jitter/loader/pe.py b/miasm/jitter/loader/pe.py
index c779f508..09319664 100644
--- a/miasm/jitter/loader/pe.py
+++ b/miasm/jitter/loader/pe.py
@@ -12,6 +12,7 @@ from miasm.loader import *
 
 from miasm.jitter.csts import *
 from miasm.jitter.loader.utils import canon_libname_libfunc, libimp
+from miasm.core.utils import force_str
 
 log = logging.getLogger('loader_pe')
 hnd = logging.StreamHandler()
@@ -29,7 +30,27 @@ def get_pe_dependencies(pe_obj):
     out = set()
     for dependency in pe_obj.DirImport.impdesc:
         libname = dependency.dlldescname.name.lower()
+        # transform bytes to chr
+        if isinstance(libname, bytes):
+            libname_str = ''
+            for c in libname:
+                libname_str += chr(c)
+            libname = libname_str
         out.add(libname)
+
+    # If binary has redirected export, add dependencies
+    if pe_obj.DirExport.expdesc != None:
+        addrs = get_export_name_addr_list(pe_obj)
+        for imp_ord_or_name, ad in addrs:
+            # if export is a redirection, search redirected dll
+            # and get function real addr
+            ret = is_redirected_export(pe_obj, ad)
+            if ret is False:
+                continue
+            dllname, func_info = ret
+            dllname = dllname + '.dll'
+            out.add(dllname)
+
     return out
 
 
@@ -40,10 +61,11 @@ def get_import_address_pe(e):
     for s in e.DirImport.impdesc:
         # fthunk = e.rva2virt(s.firstthunk)
         # l = "%2d %-25s %s" % (i, repr(s.dlldescname), repr(s))
-        libname = s.dlldescname.name.lower()
+        libname = force_str(s.dlldescname.name.lower())
+
         for ii, imp in enumerate(s.impbynames):
             if isinstance(imp, pe.ImportByName):
-                funcname = imp.name
+                funcname = force_str(imp.name)
             else:
                 funcname = imp
             # l = "    %2d %-16s" % (ii, repr(funcname))
@@ -59,6 +81,7 @@ def preload_pe(vm, e, runtime_lib, patch_vm_imp=True):
     # log.debug('imported funcs: %s' % fa)
     for (libname, libfunc), ads in viewitems(fa):
         for ad in ads:
+            libname = force_str(libname)
             ad_base_lib = runtime_lib.lib_get_add_base(libname)
             ad_libfunc = runtime_lib.lib_get_add_func(ad_base_lib, libfunc, ad)
 
@@ -88,11 +111,12 @@ def is_redirected_export(pe_obj, addr):
     addr_end = pe_obj.virt.find(b'\x00', addr)
     data = pe_obj.virt.get(addr, addr_end)
 
-    dllname, func_info = data.split(b'.', 1)
+    data = force_str(data)
+    dllname, func_info = data.split('.', 1)
     dllname = dllname.lower()
 
     # Test if function is forwarded using ordinal
-    if func_info.startswith(b'#'):
+    if func_info.startswith('#'):
         func_info = int(func_info[1:])
     return dllname, func_info
 
@@ -102,7 +126,7 @@ def get_export_name_addr_list(e):
     # add func name
     for i, n in enumerate(e.DirExport.f_names):
         addr = e.DirExport.f_address[e.DirExport.f_nameordinals[i].ordinal]
-        f_name = n.name.name
+        f_name = force_str(n.name.name)
         # log.debug('%s %s' % (f_name, hex(e.rva2virt(addr.rva))))
         out.append((f_name, e.rva2virt(addr.rva)))
 
@@ -268,8 +292,7 @@ def vm_load_pe_libs(vm, libs_name, libs, lib_path_base, **kargs):
     """
     out = {}
     for fname in libs_name:
-        if not isinstance(fname, bytes):
-            fname = fname.encode('utf8')
+        assert isinstance(fname, str)
         out[fname] = vm_load_pe_lib(vm, fname, libs, lib_path_base, **kargs)
     return out
 
@@ -371,6 +394,27 @@ class libimp_pe(libimp):
         # dependency -> redirector
         self.created_redirected_imports = {}
 
+
+    def add_function(self, dllname, imp_ord_or_name, addr):
+        assert isinstance(dllname, str)
+        assert isinstance(imp_ord_or_name, (int, str))
+        libad = self.name2off[dllname]
+        c_name = canon_libname_libfunc(
+            dllname, imp_ord_or_name
+        )
+        update_entry = True
+        if addr in self.fad2info:
+            known_libad, known_imp_ord_or_name = self.fad2info[addr]
+            if isinstance(imp_ord_or_name, int):
+                update_entry = False
+        self.cname2addr[c_name] = addr
+        log.debug("Add func %s %s", hex(addr), c_name)
+        if update_entry:
+            log.debug("Real Add func %s %s", hex(addr), c_name)
+            self.fad2cname[addr] = c_name
+            self.fad2info[addr] = libad, imp_ord_or_name
+
+
     def add_export_lib(self, e, name):
         if name in self.created_redirected_imports:
             log.error("%r has previously been created due to redirect\
@@ -397,7 +441,7 @@ class libimp_pe(libimp):
             self.libbase_ad += 0x1000
 
             ads = get_export_name_addr_list(e)
-            todo = ads
+            todo = list(ads)
             # done = []
             while todo:
                 # for imp_ord_or_name, ad in ads:
@@ -408,15 +452,19 @@ class libimp_pe(libimp):
                 ret = is_redirected_export(e, ad)
                 if ret:
                     exp_dname, exp_fname = ret
-                    exp_dname = exp_dname + b'.dll'
+                    exp_dname = exp_dname + '.dll'
                     exp_dname = exp_dname.lower()
                     # if dll auto refes in redirection
                     if exp_dname == name:
                         libad_tmp = self.name2off[exp_dname]
-                        if not exp_fname in self.lib_imp2ad[libad_tmp]:
-                            # schedule func
-                            todo = [(imp_ord_or_name, ad)] + todo
-                            continue
+                        if isinstance(exp_fname, str):
+                            exp_fname = bytes(ord(c) for c in exp_fname)
+                        found = None
+                        for tmp_func, tmp_addr in ads:
+                            if tmp_func == exp_fname:
+                                found = tmp_addr
+                        assert found is not None
+                        ad = found
                     else:
                         # import redirected lib from non loaded dll
                         if not exp_dname in self.name2off:
@@ -428,8 +476,8 @@ class libimp_pe(libimp):
                         # Ensure function entry is created
                         _ = self.lib_get_add_func(new_lib_base, exp_fname)
 
-                    libad_tmp = self.name2off[exp_dname]
-                    ad = self.lib_imp2ad[libad_tmp][exp_fname]
+                        libad_tmp = self.name2off[exp_dname]
+                        ad = self.lib_imp2ad[libad_tmp][exp_fname]
 
                 self.lib_imp2ad[libad][imp_ord_or_name] = ad
                 name_inv = dict(
@@ -543,17 +591,59 @@ def vm_load_pe_and_dependencies(vm, fname, name2module, runtime_lib,
         todo += [(name, os.path.join(lib_path_base, name), weight - 1)
                  for name in new_dependencies]
 
-    ordered_modules = sorted(viewitems(weight2name))
-    for _, modules in ordered_modules:
-        for name in modules:
-            pe_obj = name2module[name]
-            if pe_obj is None:
-                continue
-            # Fix imports
-            if pe_obj.DirExport:
-                runtime_lib.add_export_lib(pe_obj, name)
+    known_export_addresses = {}
+    to_resolve = {}
+    for name, pe_obj in name2module.items():
+        print(name)
+        if pe_obj is None:
+            continue
+        if pe_obj.DirExport.expdesc == None:
+            continue
+        addrs = get_export_name_addr_list(pe_obj)
+        for imp_ord_or_name, ad in addrs:
+            # if export is a redirection, search redirected dll
+            # and get function real addr
+            ret = is_redirected_export(pe_obj, ad)
+            if ret is False:
+                known_export_addresses[(name, imp_ord_or_name)] = ad
+            else:
+                dllname, func_info = ret
+                dllname = dllname + '.dll'
+                to_resolve[(name, imp_ord_or_name)] = (dllname, func_info)
+
+    modified = True
+    while modified:
+        modified = False
+        out = {}
+        for target, dependency in to_resolve.items():
+            dllname, funcname = dependency
+            if dependency in known_export_addresses:
+                known_export_addresses[target] = known_export_addresses[dependency]
+                modified = True
+            else:
+                log.error("Cannot resolve redirection %r %r", dllname, dependency)
+                raise RuntimeError('Cannot resolve redirection')
+        to_resolve = out
 
-    for pe_obj in viewvalues(name2module):
+    for dllname, pe_obj in name2module.items():
+        if pe_obj is None:
+            continue
+        ad = pe_obj.NThdr.ImageBase
+        libad = ad
+        runtime_lib.name2off[dllname] = ad
+        runtime_lib.libbase2lastad[ad] = ad + 0x1
+        runtime_lib.lib_imp2ad[ad] = {}
+        runtime_lib.lib_imp2dstad[ad] = {}
+        runtime_lib.libbase_ad += 0x1000
+
+    for (dllname, imp_ord_or_name), addr in known_export_addresses.items():
+        runtime_lib.add_function(dllname, imp_ord_or_name, addr)
+        libad = runtime_lib.name2off[dllname]
+        runtime_lib.lib_imp2ad[libad][imp_ord_or_name] = addr
+
+    assert not to_resolve
+
+    for dllname, pe_obj in name2module.items():
         if pe_obj is None:
             continue
         preload_pe(vm, pe_obj, runtime_lib, patch_vm_imp=True)
@@ -561,9 +651,10 @@ def vm_load_pe_and_dependencies(vm, fname, name2module, runtime_lib,
     return name2module
 
 # machine -> arch
-PE_machine = {0x14c: "x86_32",
-              0x8664: "x86_64",
-              }
+PE_machine = {
+    0x14c: "x86_32",
+    0x8664: "x86_64",
+}
 
 
 def guess_arch(pe):
diff --git a/miasm/jitter/loader/utils.py b/miasm/jitter/loader/utils.py
index a32729e1..d03adc8a 100644
--- a/miasm/jitter/loader/utils.py
+++ b/miasm/jitter/loader/utils.py
@@ -2,24 +2,23 @@ from builtins import int as int_types
 import logging
 
 from future.utils import viewitems, viewvalues
-
-from miasm.core.utils import force_bytes
+from past.builtins import basestring
 
 log = logging.getLogger('loader_common')
 hnd = logging.StreamHandler()
 hnd.setFormatter(logging.Formatter("[%(levelname)s]: %(message)s"))
 log.addHandler(hnd)
-log.setLevel(logging.INFO)
+log.setLevel(logging.DEBUG)
 
 
 def canon_libname_libfunc(libname, libfunc):
-    libname = force_bytes(libname)
-    dn = libname.split(b'.')[0]
+    assert isinstance(libname, basestring)
+    assert isinstance(libfunc, basestring) or isinstance(libfunc, int)
+    dn = libname.split('.')[0]
     if isinstance(libfunc, int_types):
         return str(dn), libfunc
     else:
-        libfunc = force_bytes(libfunc)
-        return b"%s_%s" % (dn, libfunc)
+        return "%s_%s" % (dn, libfunc)
 
 
 class libimp(object):
@@ -37,11 +36,11 @@ class libimp(object):
         self.fake_libs = set()
 
     def lib_get_add_base(self, name):
-        name = force_bytes(name)
-        name = name.lower().strip(b' ')
-        if not b"." in name:
+        assert isinstance(name, basestring)
+        name = name.lower().strip(' ')
+        if not "." in name:
             log.debug('warning adding .dll to modulename')
-            name += b'.dll'
+            name += '.dll'
             log.debug(name)
 
         if name in self.name2off:
@@ -69,11 +68,12 @@ class libimp(object):
         #/!\ can have multiple dst ad
         if not imp_ord_or_name in self.lib_imp2dstad[libad]:
             self.lib_imp2dstad[libad][imp_ord_or_name] = set()
-        self.lib_imp2dstad[libad][imp_ord_or_name].add(dst_ad)
+        if dst_ad is not None:
+            self.lib_imp2dstad[libad][imp_ord_or_name].add(dst_ad)
 
         if imp_ord_or_name in self.lib_imp2ad[libad]:
             return self.lib_imp2ad[libad][imp_ord_or_name]
-        # log.debug('new imp %s %s' % (imp_ord_or_name, dst_ad))
+        log.debug('new imp %s %s' % (imp_ord_or_name, dst_ad))
         ad = self.libbase2lastad[libad]
         self.libbase2lastad[libad] += 0x10  # arbitrary
         self.lib_imp2ad[libad][imp_ord_or_name] = ad
diff --git a/miasm/jitter/vm_mngr.c b/miasm/jitter/vm_mngr.c
index 43d6db53..53ec9065 100644
--- a/miasm/jitter/vm_mngr.c
+++ b/miasm/jitter/vm_mngr.c
@@ -226,7 +226,6 @@ static uint64_t memory_page_read(vm_mngr_t* vm_mngr, unsigned int my_size, uint6
 		}
 		switch(my_size){
 		case 8:
-			ret = ret;
 			break;
 		case 16:
 			ret = set_endian16(vm_mngr, (uint16_t)ret);
@@ -302,7 +301,6 @@ static void memory_page_write(vm_mngr_t* vm_mngr, unsigned int my_size,
 		switch(my_size){
 
 		case 8:
-			src = src;
 			break;
 		case 16:
 			src = set_endian16(vm_mngr, (uint16_t)src);
diff --git a/miasm/jitter/vm_mngr.h b/miasm/jitter/vm_mngr.h
index bef91771..7ae44d99 100644
--- a/miasm/jitter/vm_mngr.h
+++ b/miasm/jitter/vm_mngr.h
@@ -45,6 +45,10 @@
 #define __BYTE_ORDER __LITTLE_ENDIAN
 #define __BIG_ENDIAN '>'
 #define __LITTLE_ENDIAN '<'
+#elif defined(__ANDROID__)
+#define __BYTE_ORDER __BYTE_ORDER__
+#define __LITTLE_ENDIAN __ORDER_LITTLE_ENDIAN__
+#define __BIG_ENDIAN __ORDER_BIG_ENDIAN__
 #endif
 
 
@@ -80,7 +84,6 @@ LIST_HEAD(memory_breakpoint_info_head, memory_breakpoint_info);
 
 #define MAX_MEMORY_PAGE_POOL_TAB 0x100000
 #define MEMORY_PAGE_POOL_MASK_BIT 12
-#define PAGE_SIZE (1<<MEMORY_PAGE_POOL_MASK_BIT)
 #define VM_BIG_ENDIAN 1
 #define VM_LITTLE_ENDIAN 2
 
diff --git a/miasm/loader/pe_init.py b/miasm/loader/pe_init.py
index 2d7e3fa1..74192849 100644
--- a/miasm/loader/pe_init.py
+++ b/miasm/loader/pe_init.py
@@ -161,7 +161,7 @@ def compute_crc(raw, olds):
     out = 0
     data = raw[:]
     if len(raw) % 2:
-        end = struct.unpack('B', data[-1])[0]
+        end = struct.unpack('B', data[-1:])[0]
         data = data[:-1]
     if (len(raw) & ~0x1) % 4:
         out += struct.unpack('H', data[:2])[0]
diff --git a/miasm/os_dep/common.py b/miasm/os_dep/common.py
index 0b4d7e11..4a92ef2a 100644
--- a/miasm/os_dep/common.py
+++ b/miasm/os_dep/common.py
@@ -2,25 +2,27 @@ import os
 
 from future.utils import viewitems
 
-from miasm.core.utils import force_bytes
+from miasm.core.utils import force_bytes, force_str
 from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
 from miasm.core.utils import get_caller_name
 from miasm.core.utils import pck64, upck64
 
 BASE_SB_PATH = "file_sb"
+WIN_CODEPAGE = "cp1252"
 
-
-def get_str_ansi(jitter, ad_str, max_char=None):
+def get_win_str_a(jitter, ad_str, max_char=None):
     l = 0
     tmp = ad_str
     while ((max_char is None or l < max_char) and
            jitter.vm.get_mem(tmp, 1) != b"\x00"):
         tmp += 1
         l += 1
-    return jitter.vm.get_mem(ad_str, l)
+    data = jitter.vm.get_mem(ad_str, l)
+    ret = data.decode(WIN_CODEPAGE)
+    return ret
 
 
-def get_str_unic(jitter, ad_str, max_char=None):
+def get_win_str_w(jitter, ad_str, max_char=None):
     l = 0
     tmp = ad_str
     while ((max_char is None or l < max_char) and
@@ -31,18 +33,23 @@ def get_str_unic(jitter, ad_str, max_char=None):
     s = s.decode("utf-16le")
     return s
 
+def encode_win_str_a(value):
+    value = value.encode(WIN_CODEPAGE) + b"\x00"
+    return value
+
+def encode_win_str_w(value):
+    value = value.encode("utf-16le") + b'\x00' * 2
+    return value
+
 
-def set_str_ansi(value):
-    value = force_bytes(value)
-    return value + b"\x00"
+def set_win_str_a(jitter, addr, value):
+    value = encode_win_str_a(value)
+    jitter.vm.set_mem(addr, value)
 
 
-def set_str_unic(value):
-    try:
-        value = value.decode()
-    except AttributeError:
-        pass
-    return value.encode("utf-16le") + b'\x00' * 2
+def set_win_str_w(jitter, addr, value):
+    value = encode_win_str_w(value)
+    jitter.vm.set_mem(addr, value)
 
 
 class heap(object):
diff --git a/miasm/os_dep/linux/syscall.py b/miasm/os_dep/linux/syscall.py
index 7fede9f1..01b1687c 100644
--- a/miasm/os_dep/linux/syscall.py
+++ b/miasm/os_dep/linux/syscall.py
@@ -154,7 +154,7 @@ def sys_arml_newuname(jitter, linux_env):
 def sys_generic_access(jitter, linux_env):
     # Parse arguments
     pathname, mode = jitter.syscall_args_systemv(2)
-    rpathname = jitter.get_str_ansi(pathname)
+    rpathname = jitter.get_c_str(pathname)
     rmode = mode
     if mode == 1:
         rmode = "F_OK"
@@ -173,7 +173,7 @@ def sys_generic_access(jitter, linux_env):
 def sys_x86_64_openat(jitter, linux_env):
     # Parse arguments
     dfd, filename, flags, mode = jitter.syscall_args_systemv(4)
-    rpathname = jitter.get_str_ansi(filename)
+    rpathname = jitter.get_c_str(filename)
     log.debug("sys_openat(%x, %r, %x, %x)", dfd, rpathname, flags, mode)
 
     # Stub
@@ -184,7 +184,7 @@ def sys_x86_64_openat(jitter, linux_env):
 def sys_x86_64_newstat(jitter, linux_env):
     # Parse arguments
     filename, statbuf = jitter.syscall_args_systemv(2)
-    rpathname = jitter.get_str_ansi(filename)
+    rpathname = jitter.get_c_str(filename)
     log.debug("sys_newstat(%r, %x)", rpathname, statbuf)
 
     # Stub
@@ -201,7 +201,7 @@ def sys_x86_64_newstat(jitter, linux_env):
 def sys_arml_stat64(jitter, linux_env):
     # Parse arguments
     filename, statbuf = jitter.syscall_args_systemv(2)
-    rpathname = jitter.get_str_ansi(filename)
+    rpathname = jitter.get_c_str(filename)
     log.debug("sys_newstat(%r, %x)", rpathname, statbuf)
 
     # Stub
@@ -229,7 +229,7 @@ def sys_x86_64_writev(jitter, linux_env):
         # };
         iovec = jitter.vm.get_mem(vec + iovec_num * 8 * 2, 8*2)
         iov_base, iov_len = struct.unpack("QQ", iovec)
-        fdesc.write(jitter.get_str_ansi(iov_base)[:iov_len])
+        fdesc.write(jitter.get_c_str(iov_base)[:iov_len])
 
     jitter.syscall_ret_systemv(vlen)
 
@@ -248,7 +248,7 @@ def sys_arml_writev(jitter, linux_env):
         # };
         iovec = jitter.vm.get_mem(vec + iovec_num * 4 * 2, 4*2)
         iov_base, iov_len = struct.unpack("II", iovec)
-        fdesc.write(jitter.get_str_ansi(iov_base)[:iov_len])
+        fdesc.write(jitter.get_c_str(iov_base)[:iov_len])
 
     jitter.syscall_ret_systemv(vlen)
 
@@ -433,7 +433,7 @@ def sys_x86_64_statfs(jitter, linux_env):
     # Parse arguments
     pathname = jitter.cpu.RDI
     buf = jitter.cpu.RSI
-    rpathname = jitter.get_str_ansi(pathname)
+    rpathname = jitter.get_c_str(pathname)
     log.debug("sys_statfs(%r, %x)", rpathname, buf)
 
     # Stub
@@ -486,7 +486,7 @@ def sys_arml_ioctl(jitter, linux_env):
 def sys_generic_open(jitter, linux_env):
     # Parse arguments
     filename, flags, mode = jitter.syscall_args_systemv(3)
-    rpathname = jitter.get_str_ansi(filename)
+    rpathname = jitter.get_c_str(filename)
     log.debug("sys_open(%r, %x, %x)", rpathname, flags, mode)
     # Stub
     # 'mode' is ignored
@@ -569,7 +569,7 @@ def sys_x86_64_newlstat(jitter, linux_env):
     # Parse arguments
     filename = jitter.cpu.RDI
     statbuf = jitter.cpu.RSI
-    rpathname = jitter.get_str_ansi(filename)
+    rpathname = jitter.get_c_str(filename)
     log.debug("sys_newlstat(%s, %x)", rpathname, statbuf)
 
     # Stub
@@ -587,7 +587,7 @@ def sys_arml_lstat64(jitter, linux_env):
     # Parse arguments
     filename = jitter.cpu.R0
     statbuf = jitter.cpu.R1
-    rpathname = jitter.get_str_ansi(filename)
+    rpathname = jitter.get_c_str(filename)
     log.debug("sys_newlstat(%s, %x)", rpathname, statbuf)
 
     # Stub
@@ -607,8 +607,8 @@ def sys_x86_64_lgetxattr(jitter, linux_env):
     name = jitter.cpu.RSI
     value = jitter.cpu.RDX
     size = jitter.cpu.R10
-    rpathname = jitter.get_str_ansi(pathname)
-    rname = jitter.get_str_ansi(name)
+    rpathname = jitter.get_c_str(pathname)
+    rname = jitter.get_c_str(name)
     log.debug("sys_lgetxattr(%r, %r, %x, %x)", rpathname, rname, value, size)
 
     # Stub
@@ -622,8 +622,8 @@ def sys_x86_64_getxattr(jitter, linux_env):
     name = jitter.cpu.RSI
     value = jitter.cpu.RDX
     size = jitter.cpu.R10
-    rpathname = jitter.get_str_ansi(pathname)
-    rname = jitter.get_str_ansi(name)
+    rpathname = jitter.get_c_str(pathname)
+    rname = jitter.get_c_str(name)
     log.debug("sys_getxattr(%r, %r, %x, %x)", rpathname, rname, value, size)
 
     # Stub
@@ -646,7 +646,7 @@ def sys_x86_64_connect(jitter, linux_env):
     fd = jitter.cpu.RDI
     uservaddr = jitter.cpu.RSI
     addrlen = jitter.cpu.RDX
-    raddr = jitter.get_str_ansi(uservaddr + 2)
+    raddr = jitter.get_c_str(uservaddr + 2)
     log.debug("sys_connect(%x, %r, %x)", fd, raddr, addrlen)
 
     # Stub
@@ -698,7 +698,7 @@ def sys_x86_64_readlink(jitter, linux_env):
     path = jitter.cpu.RDI
     buf = jitter.cpu.RSI
     bufsize = jitter.cpu.RDX
-    rpath = jitter.get_str_ansi(path)
+    rpath = jitter.get_c_str(path)
     log.debug("sys_readlink(%r, %x, %x)", rpath, buf, bufsize)
 
     # Stub
diff --git a/miasm/os_dep/linux_stdlib.py b/miasm/os_dep/linux_stdlib.py
index 3fa5b02e..348ef9b4 100644
--- a/miasm/os_dep/linux_stdlib.py
+++ b/miasm/os_dep/linux_stdlib.py
@@ -143,7 +143,7 @@ def xxx_puts(jitter):
 
 
 def get_fmt_args(jitter, fmt, cur_arg):
-    return _get_fmt_args(fmt, cur_arg, jitter.get_str_ansi, jitter.get_arg_n_systemv)
+    return _get_fmt_args(fmt, cur_arg, jitter.get_c_str, jitter.get_arg_n_systemv)
 
 
 def xxx_snprintf(jitter):
@@ -153,7 +153,7 @@ def xxx_snprintf(jitter):
     output = get_fmt_args(jitter, fmt, cur_arg)
     output = output[:size - 1]
     ret = len(output)
-    jitter.vm.set_mem(args.string, (output + '\x00').encode('utf8'))
+    jitter.set_c_str(args.string, output)
     return jitter.func_ret_systemv(ret_addr, ret)
 
 
@@ -162,7 +162,7 @@ def xxx_sprintf(jitter):
     cur_arg, fmt = 2, args.fmt
     output = get_fmt_args(jitter, fmt, cur_arg)
     ret = len(output)
-    jitter.vm.set_mem(args.string, (output + '\x00').encode('utf8'))
+    jitter.set_c_str(args.string, output)
     return jitter.func_ret_systemv(ret_addr, ret)
 
 
@@ -177,14 +177,14 @@ def xxx_printf(jitter):
 
 def xxx_strcpy(jitter):
     ret_ad, args = jitter.func_args_systemv(["dst", "src"])
-    str_src = jitter.get_str_ansi(args.src) + '\x00'
-    jitter.vm.set_mem(args.dst, str_src.encode('utf8'))
+    str_src = jitter.get_c_str(args.src)
+    jitter.set_c_str(args.dst, str_src)
     jitter.func_ret_systemv(ret_ad, args.dst)
 
 
 def xxx_strlen(jitter):
     ret_ad, args = jitter.func_args_systemv(["src"])
-    str_src = jitter.get_str_ansi(args.src)
+    str_src = jitter.get_c_str(args.src)
     jitter.func_ret_systemv(ret_ad, len(str_src))
 
 
@@ -201,13 +201,13 @@ def xxx_free(jitter):
 
 def xxx_strcmp(jitter):
     ret_ad, args = jitter.func_args_systemv(["ptr_str1", "ptr_str2"])
-    s1 = jitter.get_str_ansi(args.ptr_str1)
-    s2 = jitter.get_str_ansi(args.ptr_str2)
+    s1 = jitter.get_c_str(args.ptr_str1)
+    s2 = jitter.get_c_str(args.ptr_str2)
     jitter.func_ret_systemv(ret_ad, cmp_elts(s1, s2))
 
 
 def xxx_strncmp(jitter):
     ret_ad, args = jitter.func_args_systemv(["ptr_str1", "ptr_str2", "size"])
-    s1 = jitter.get_str_ansi(args.ptr_str1, args.size)
-    s2 = jitter.get_str_ansi(args.ptr_str2, args.size)
+    s1 = jitter.get_c_str(args.ptr_str1, args.size)
+    s2 = jitter.get_c_str(args.ptr_str2, args.size)
     jitter.func_ret_systemv(ret_ad, cmp_elts(s1, s2))
diff --git a/miasm/os_dep/win_api_x86_32.py b/miasm/os_dep/win_api_x86_32.py
index be6e7677..051cedb5 100644
--- a/miasm/os_dep/win_api_x86_32.py
+++ b/miasm/os_dep/win_api_x86_32.py
@@ -28,7 +28,7 @@ from io import StringIO
 import time
 import datetime
 
-from future.utils import PY3, viewitems
+from future.utils import PY3, viewitems, viewvalues
 
 try:
     from Crypto.Hash import MD5, SHA
@@ -36,10 +36,12 @@ except ImportError:
     print("cannot find crypto, skipping")
 
 from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, PAGE_EXEC
-from miasm.core.utils import pck16, pck32, hexdump, whoami
+from miasm.core.utils import pck16, pck32, hexdump, whoami, int_to_byte
 from miasm.os_dep.common import heap, windows_to_sbpath
-from miasm.os_dep.common import set_str_unic, set_str_ansi
+from miasm.os_dep.common import set_win_str_w, set_win_str_a
 from miasm.os_dep.common import get_fmt_args as _get_fmt_args
+from miasm.os_dep.common import get_win_str_a, get_win_str_w
+from miasm.os_dep.common import encode_win_str_a, encode_win_str_w
 from miasm.os_dep.win_api_x86_32_seh import tib_address
 
 log = logging.getLogger("win_api_x86_32")
@@ -144,8 +146,8 @@ class c_winobjs(object):
         self.dw_pid_dummy2 = 0x333
         self.dw_pid_cur = 0x444
         self.module_fname_nux = None
-        self.module_name = b"test.exe"
-        self.module_path = b"c:\\mydir\\" + self.module_name
+        self.module_name = "test.exe"
+        self.module_path = "c:\\mydir\\" + self.module_name
         self.hcurmodule = None
         self.module_filesize = None
         self.getversion = 0x0A280105
@@ -169,7 +171,7 @@ class c_winobjs(object):
             0x80000001: b"hkey_current_user",
             0x80000002: b"hkey_local_machine"
         }
-        self.cur_dir = b"c:\\tmp"
+        self.cur_dir = "c:\\tmp"
 
         self.nt_mdl = {}
         self.nt_mdl_ad = None
@@ -203,7 +205,7 @@ process_list = [
         winobjs.dw_pid_explorer,  # DWORD     th32ParentProcessID;
         0xbeef,  # LONG      pcPriClassBase;
         0x0,  # DWORD     dwFlags;
-        b"dummy1.exe"  # TCHAR     szExeFile[MAX_PATH];
+        "dummy1.exe"  # TCHAR     szExeFile[MAX_PATH];
     ],
     [
         0x40,  # DWORD     dwSize;
@@ -215,7 +217,7 @@ process_list = [
         4,  # DWORD     th32ParentProcessID;
         0xbeef,  # LONG      pcPriClassBase;
         0x0,  # DWORD     dwFlags;
-        b"explorer.exe"  # TCHAR     szExeFile[MAX_PATH];
+        "explorer.exe"  # TCHAR     szExeFile[MAX_PATH];
     ],
 
     [
@@ -228,7 +230,7 @@ process_list = [
         winobjs.dw_pid_explorer,  # DWORD     th32ParentProcessID;
         0xbeef,  # LONG      pcPriClassBase;
         0x0,  # DWORD     dwFlags;
-        b"dummy2.exe"  # TCHAR     szExeFile[MAX_PATH];
+        "dummy2.exe"  # TCHAR     szExeFile[MAX_PATH];
     ],
 
     [
@@ -337,7 +339,7 @@ def kernel32_Process32First(jitter):
 
     pentry = struct.pack(
         'IIIIIIIII', *process_list[0][:-1]
-    ) + process_list[0][-1]
+    ) + (process_list[0][-1] + '\x00').encode('utf8')
     jitter.vm.set_mem(args.ad_pentry, pentry)
     winobjs.toolhelpsnapshot_info[args.s_handle] = 0
 
@@ -354,7 +356,7 @@ def kernel32_Process32Next(jitter):
         ret = 1
         n = winobjs.toolhelpsnapshot_info[args.s_handle]
         pentry = struct.pack(
-            'IIIIIIIII', *process_list[n][:-1]) + process_list[n][-1]
+            'IIIIIIIII', *process_list[n][:-1]) + (process_list[n][-1]+ '\x00').encode('utf8')
         jitter.vm.set_mem(args.ad_pentry, pentry)
     jitter.func_ret_stdcall(ret_ad, ret)
 
@@ -370,7 +372,7 @@ def kernel32_GetVersion(jitter):
     jitter.func_ret_stdcall(ret_ad, winobjs.getversion)
 
 
-def kernel32_GetVersionEx(jitter, str_size, set_str):
+def kernel32_GetVersionEx(jitter, str_size, encode_str):
     ret_ad, args = jitter.func_args_stdcall(["ptr_struct"])
 
     size = jitter.vm.get_u32(args.ptr_struct)
@@ -382,7 +384,7 @@ def kernel32_GetVersionEx(jitter, str_size, set_str):
             0x2,              # min vers
             0xa28,            # build nbr
             0x2,              # platform id
-            set_str("Service pack 4"),
+            encode_str("Service pack 4"),
             3,                # wServicePackMajor
             0,                # wServicePackMinor
             0x100,            # wSuiteMask
@@ -398,9 +400,9 @@ def kernel32_GetVersionEx(jitter, str_size, set_str):
 
 
 kernel32_GetVersionExA = lambda jitter: kernel32_GetVersionEx(jitter, 128,
-                                                              set_str_ansi)
+                                                              encode_win_str_a)
 kernel32_GetVersionExW = lambda jitter: kernel32_GetVersionEx(jitter, 256,
-                                                              set_str_unic)
+                                                              encode_win_str_w)
 
 
 def kernel32_GetPriorityClass(jitter):
@@ -426,10 +428,10 @@ def user32_GetForegroundWindow(jitter):
 def user32_FindWindowA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["pclassname", "pwindowname"])
     if args.pclassname:
-        classname = jitter.get_str_ansi(args.pclassname)
+        classname = get_win_str_a(jitter, args.pclassname)
         log.info("FindWindowA classname %s", classname)
     if args.pwindowname:
-        windowname = jitter.get_str_ansi(args.pwindowname)
+        windowname = get_win_str_a(jitter, args.pwindowname)
         log.info("FindWindowA windowname %s", windowname)
     jitter.func_ret_stdcall(ret_ad, 0)
 
@@ -455,11 +457,11 @@ def advapi32_CryptAcquireContext(jitter, funcname, get_str):
 
 
 def advapi32_CryptAcquireContextA(jitter):
-    advapi32_CryptAcquireContext(jitter, whoami(), jitter.get_str_ansi)
+    advapi32_CryptAcquireContext(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def advapi32_CryptAcquireContextW(jitter):
-    advapi32_CryptAcquireContext(jitter, whoami(), jitter.get_str_unic)
+    advapi32_CryptAcquireContext(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def advapi32_CryptCreateHash(jitter):
@@ -666,11 +668,11 @@ def kernel32_CreateFile(jitter, funcname, get_str):
 
 
 def kernel32_CreateFileA(jitter):
-    kernel32_CreateFile(jitter, whoami(), jitter.get_str_ansi)
+    kernel32_CreateFile(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def kernel32_CreateFileW(jitter):
-    kernel32_CreateFile(jitter, whoami(), jitter.get_str_unic)
+    kernel32_CreateFile(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def kernel32_ReadFile(jitter):
@@ -755,9 +757,13 @@ def kernel32_VirtualProtect(jitter):
         old = jitter.vm.get_mem_access(args.lpvoid)
         jitter.vm.set_u32(args.lpfloldprotect, ACCESS_DICT_INV[old])
 
-    for addr in jitter.vm.get_all_memory():
+    print("XXX VIRTUALP")
+    log.warn("set page %x %x", args.lpvoid, args.dwsize)
+    for addr, data in jitter.vm.get_all_memory().items():
+        size = data["size"]
         # Multi-page
-        if args.lpvoid <= addr < args.lpvoid + args.dwsize:
+        if addr <= args.lpvoid < addr + size:
+            log.warn("set page %x %x", addr, ACCESS_DICT[flnewprotect])
             jitter.vm.set_mem_access(addr, ACCESS_DICT[flnewprotect])
 
     jitter.func_ret_stdcall(ret_ad, 1)
@@ -841,11 +847,11 @@ def kernel32_GetModuleFileName(jitter, funcname, set_str):
 
 
 def kernel32_GetModuleFileNameA(jitter):
-    kernel32_GetModuleFileName(jitter, whoami(), jitter.set_str_ansi)
+    kernel32_GetModuleFileName(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_GetModuleFileNameW(jitter):
-    kernel32_GetModuleFileName(jitter, whoami(), jitter.set_str_unic)
+    kernel32_GetModuleFileName(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
 
 
 def kernel32_CreateMutex(jitter, funcname, get_str):
@@ -875,11 +881,11 @@ def kernel32_CreateMutex(jitter, funcname, get_str):
 
 
 def kernel32_CreateMutexA(jitter):
-    kernel32_CreateMutex(jitter, whoami(), jitter.get_str_ansi)
+    kernel32_CreateMutex(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def kernel32_CreateMutexW(jitter):
-    kernel32_CreateMutex(jitter, whoami(), jitter.get_str_unic)
+    kernel32_CreateMutex(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def shell32_SHGetSpecialFolderLocation(jitter):
@@ -900,11 +906,11 @@ def kernel32_SHGetPathFromIDList(jitter, funcname, set_str):
 
 
 def shell32_SHGetPathFromIDListW(jitter):
-    kernel32_SHGetPathFromIDList(jitter, whoami(), jitter.set_str_unic)
+    kernel32_SHGetPathFromIDList(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
 
 
 def shell32_SHGetPathFromIDListA(jitter):
-    kernel32_SHGetPathFromIDList(jitter, whoami(), jitter.set_str_ansi)
+    kernel32_SHGetPathFromIDList(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_GetLastError(jitter):
@@ -935,11 +941,11 @@ def kernel32_LoadLibrary(jitter, get_str):
 
 
 def kernel32_LoadLibraryA(jitter):
-    kernel32_LoadLibrary(jitter, jitter.get_str_ansi)
+    kernel32_LoadLibrary(jitter, lambda addr, max_char=None:get_win_str_a(jitter, addr, max_char))
 
 
 def kernel32_LoadLibraryW(jitter):
-    kernel32_LoadLibrary(jitter, jitter.get_str_unic)
+    kernel32_LoadLibrary(jitter, lambda addr, max_char=None:get_win_str_w(jitter, addr, max_char))
 
 
 def kernel32_LoadLibraryEx(jitter, get_str):
@@ -954,18 +960,18 @@ def kernel32_LoadLibraryEx(jitter, get_str):
 
 
 def kernel32_LoadLibraryExA(jitter):
-    kernel32_LoadLibraryEx(jitter, jitter.get_str_ansi)
+    kernel32_LoadLibraryEx(jitter, lambda addr, max_char=None:get_win_str_a(jitter, addr, max_char))
 
 
 def kernel32_LoadLibraryExW(jitter):
-    kernel32_LoadLibraryEx(jitter, jitter.get_str_unic)
+    kernel32_LoadLibraryEx(jitter, lambda addr, max_char=None:get_win_str_w(jitter, addr, max_char))
 
 
 def kernel32_GetProcAddress(jitter):
     ret_ad, args = jitter.func_args_stdcall(["libbase", "fname"])
     fname = args.fname
     if fname >= 0x10000:
-        fname = jitter.get_str_ansi(fname, 0x100)
+        fname = jitter.get_c_str(fname, 0x100)
         if not fname:
             fname = None
     if fname is not None:
@@ -995,11 +1001,11 @@ def kernel32_GetModuleHandle(jitter, funcname, get_str):
 
 
 def kernel32_GetModuleHandleA(jitter):
-    kernel32_GetModuleHandle(jitter, whoami(), jitter.get_str_ansi)
+    kernel32_GetModuleHandle(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def kernel32_GetModuleHandleW(jitter):
-    kernel32_GetModuleHandle(jitter, whoami(), jitter.get_str_unic)
+    kernel32_GetModuleHandle(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def kernel32_VirtualLock(jitter):
@@ -1049,29 +1055,28 @@ def kernel32_IsWow64Process(jitter):
 def kernel32_GetCommandLine(jitter, set_str):
     ret_ad, _ = jitter.func_args_stdcall(0)
     alloc_addr = winobjs.heap.alloc(jitter, 0x1000)
-    s = set_str('"%s"' % winobjs.module_path)
-    jitter.vm.set_mem(alloc_addr, s)
+    set_str(alloc_addr, '"%s"' % winobjs.module_path)
     jitter.func_ret_stdcall(ret_ad, alloc_addr)
 
 
 def kernel32_GetCommandLineA(jitter):
-    kernel32_GetCommandLine(jitter, set_str_ansi)
+    kernel32_GetCommandLine(jitter, lambda addr, value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_GetCommandLineW(jitter):
-    kernel32_GetCommandLine(jitter, set_str_unic)
+    kernel32_GetCommandLine(jitter, lambda addr, value: set_win_str_w(jitter, addr, value))
 
 
 def shell32_CommandLineToArgvW(jitter):
     ret_ad, args = jitter.func_args_stdcall(["pcmd", "pnumargs"])
-    cmd = jitter.get_str_unic(args.pcmd)
+    cmd = get_win_str_w(jitter, args.pcmd)
     log.info("CommandLineToArgv %r", cmd)
     tks = cmd.split(' ')
     addr = winobjs.heap.alloc(jitter, len(cmd) * 2 + 4 * len(tks))
     addr_ret = winobjs.heap.alloc(jitter, 4 * (len(tks) + 1))
     o = 0
     for i, t in enumerate(tks):
-        jitter.set_str_unic(addr + o, t)
+        jitter.set_win_str_w(addr + o, t)
         jitter.vm.set_u32(addr_ret + 4 * i, addr + o)
         o += len(t)*2 + 2
 
@@ -1118,7 +1123,7 @@ def cryptdll_MD5Final(jitter):
 def ntdll_RtlInitAnsiString(jitter):
     ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_str"])
 
-    s = jitter.get_str_ansi(args.ad_str)
+    s = get_win_str_a(jitter, args.ad_str)
     l = len(s)
     jitter.vm.set_mem(args.ad_ctx,
                       pck16(l) + pck16(l + 1) + pck32(args.ad_str))
@@ -1286,7 +1291,7 @@ def ntoskrnl_RtlGetVersion(jitter):
                     0x2,  # min vers
                     0x666,  # build nbr
                     0x2,   # platform id
-                    ) + jitter.set_str_unic("Service pack 4")
+                    ) + jitter.set_win_str_w("Service pack 4")
 
     jitter.vm.set_mem(args.ptr_version, s)
     jitter.func_ret_stdcall(ret_ad, 0)
@@ -1378,7 +1383,7 @@ def ntoskrnl_RtlQueryRegistryValues(jitter):
                                              "querytable",
                                              "context",
                                              "environ"])
-    # path = get_str_unic(jitter, args.path)
+    # path = get_win_str_w(jitter, args.path)
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
@@ -1403,51 +1408,51 @@ def my_lstrcmp(jitter, funcname, get_str):
 
 def msvcrt_wcscmp(jitter):
     ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"])
-    s1 = jitter.get_str_unic(args.ptr_str1)
-    s2 = jitter.get_str_unic(args.ptr_str2)
+    s1 = get_win_str_w(jitter, args.ptr_str1)
+    s2 = get_win_str_w(jitter, args.ptr_str2)
     log.debug("%s('%s','%s')" % (whoami(), s1, s2))
     jitter.func_ret_cdecl(ret_ad, cmp(s1, s2))
 
 def msvcrt__wcsicmp(jitter):
     ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"])
-    s1 = jitter.get_str_unic(args.ptr_str1)
-    s2 = jitter.get_str_unic(args.ptr_str2)
+    s1 = get_win_str_w(jitter, args.ptr_str1)
+    s2 = get_win_str_w(jitter, args.ptr_str2)
     log.debug("%s('%s','%s')" % (whoami(), s1, s2))
     jitter.func_ret_cdecl(ret_ad, cmp(s1.lower(), s2.lower()))
 
 def msvcrt__wcsnicmp(jitter):
     ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2", "count"])
-    s1 = jitter.get_str_unic(args.ptr_str1)
-    s2 = jitter.get_str_unic(args.ptr_str2)
+    s1 = get_win_str_w(jitter, args.ptr_str1)
+    s2 = get_win_str_w(jitter, args.ptr_str2)
     log.debug("%s('%s','%s',%d)" % (whoami(), s1, s2, args.count))
     jitter.func_ret_cdecl(ret_ad, cmp(s1.lower()[:args.count], s2.lower()[:args.count]))
 
 def msvcrt_wcsncpy(jitter):
     ret_ad, args = jitter.func_args_cdecl(["dst", "src", "n"])
-    src = jitter.get_str_unic(args.src)
+    src = get_win_str_w(jitter, args.src)
     dst = src[:args.n]
     dst += "\x00\x00" * (args.n-len(dst)+1)
     jitter.vm.set_mem(args.dst, dst)
     jitter.func_ret_cdecl(ret_ad, args.dst)
 
 def kernel32_lstrcmpA(jitter):
-    my_lstrcmp(jitter, whoami(), jitter.get_str_ansi)
+    my_lstrcmp(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def kernel32_lstrcmpiA(jitter):
-    my_lstrcmp(jitter, whoami(), lambda x: jitter.get_str_ansi(x).lower())
+    my_lstrcmp(jitter, whoami(), lambda x: get_win_str_a(jitter, x).lower())
 
 
 def kernel32_lstrcmpW(jitter):
-    my_lstrcmp(jitter, whoami(), jitter.get_str_unic)
+    my_lstrcmp(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def kernel32_lstrcmpiW(jitter):
-    my_lstrcmp(jitter, whoami(), lambda x: jitter.get_str_unic(x).lower())
+    my_lstrcmp(jitter, whoami(), lambda x: get_win_str_w(jitter, x).lower())
 
 
 def kernel32_lstrcmpi(jitter):
-    my_lstrcmp(jitter, whoami(), lambda x: jitter.get_str_ansi(x).lower())
+    my_lstrcmp(jitter, whoami(), lambda x: get_win_str_a(jitter, x).lower())
 
 
 def my_strcpy(jitter, funcname, get_str, set_str):
@@ -1459,20 +1464,20 @@ def my_strcpy(jitter, funcname, get_str, set_str):
 
 
 def kernel32_lstrcpyW(jitter):
-    my_strcpy(jitter, whoami(), jitter.get_str_unic, jitter.set_str_unic)
+    my_strcpy(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr), lambda addr,value: set_win_str_w(jitter, addr, value))
 
 
 def kernel32_lstrcpyA(jitter):
-    my_strcpy(jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi)
+    my_strcpy(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), lambda addr,value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_lstrcpy(jitter):
-    my_strcpy(jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi)
+    my_strcpy(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), lambda addr,value: set_win_str_a(jitter, addr, value))
 
 def msvcrt__mbscpy(jitter):
     ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"])
-    s2 = jitter.get_str_unic(args.ptr_str2)
-    jitter.set_str_unic(args.ptr_str1, s2)
+    s2 = get_win_str_w(jitter, args.ptr_str2)
+    jitter.set_win_str_w(args.ptr_str1, s2)
     jitter.func_ret_cdecl(ret_ad, args.ptr_str1)
 
 def msvcrt_wcscpy(jitter):
@@ -1482,11 +1487,11 @@ def msvcrt_wcscpy(jitter):
 def kernel32_lstrcpyn(jitter):
     ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2",
                                              "mlen"])
-    s2 = jitter.get_str_ansi(args.ptr_str2)
+    s2 = get_win_str_a(jitter, args.ptr_str2)
     if len(s2) >= args.mlen:
         s2 = s2[:args.mlen - 1]
     log.info("Copy '%r'", s2)
-    jitter.set_str_ansi(args.ptr_str1, s2)
+    jitter.set_win_str_a(args.ptr_str1, s2)
     jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
 
 
@@ -1499,15 +1504,15 @@ def my_strlen(jitter, funcname, get_str, mylen):
 
 
 def kernel32_lstrlenA(jitter):
-    my_strlen(jitter, whoami(), jitter.get_str_ansi, len)
+    my_strlen(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), len)
 
 
 def kernel32_lstrlenW(jitter):
-    my_strlen(jitter, whoami(), jitter.get_str_unic, len)
+    my_strlen(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr), len)
 
 
 def kernel32_lstrlen(jitter):
-    my_strlen(jitter, whoami(), jitter.get_str_ansi, len)
+    my_strlen(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), len)
 
 
 def my_lstrcat(jitter, funcname, get_str, set_str):
@@ -1519,11 +1524,11 @@ def my_lstrcat(jitter, funcname, get_str, set_str):
 
 
 def kernel32_lstrcatA(jitter):
-    my_lstrcat(jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi)
+    my_lstrcat(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), lambda addr,value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_lstrcatW(jitter):
-    my_lstrcat(jitter, whoami(), jitter.get_str_unic, jitter.set_str_unic)
+    my_lstrcat(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr), lambda addr,value: set_win_str_w(jitter, addr, value))
 
 
 def kernel32_GetUserGeoID(jitter):
@@ -1573,11 +1578,11 @@ def my_GetVolumeInformation(jitter, funcname, get_str, set_str):
 
 def kernel32_GetVolumeInformationA(jitter):
     my_GetVolumeInformation(
-        jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi)
+        jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), lambda addr,value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_GetVolumeInformationW(jitter):
-    my_GetVolumeInformation(jitter, whoami(), jitter.get_str_unic, jitter.set_str_unic)
+    my_GetVolumeInformation(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr), lambda addr,value: set_win_str_w(jitter, addr, value))
 
 
 def kernel32_MultiByteToWideChar(jitter):
@@ -1586,7 +1591,7 @@ def kernel32_MultiByteToWideChar(jitter):
                                              "cbmultibyte",
                                              "lpwidecharstr",
                                              "cchwidechar"])
-    src = jitter.get_str_ansi(args.lpmultibytestr) + '\x00'
+    src = get_win_str_a(jitter, args.lpmultibytestr) + '\x00'
     l = len(src)
 
     src = "\x00".join(list(src))
@@ -1611,15 +1616,15 @@ def my_GetEnvironmentVariable(jitter, funcname, get_str, set_str, mylen):
 
 def kernel32_GetEnvironmentVariableA(jitter):
     my_GetEnvironmentVariable(jitter, whoami(),
-                              jitter.get_str_ansi,
-                              jitter.set_str_ansi,
+                              lambda addr:get_win_str_a(jitter, addr),
+                              lambda addr,value: set_win_str_a(jitter, addr, value),
                               len)
 
 
 def kernel32_GetEnvironmentVariableW(jitter):
     my_GetEnvironmentVariable(jitter, whoami(),
-                              jitter.get_str_unic,
-                              jitter.set_str_ansi,
+                              lambda addr:get_win_str_w(jitter, addr),
+                              lambda addr,value: set_win_str_w(jitter, addr, value),
                               len)
 
 
@@ -1633,11 +1638,11 @@ def my_GetSystemDirectory(jitter, funcname, set_str):
 
 
 def kernel32_GetSystemDirectoryA(jitter):
-    my_GetSystemDirectory(jitter, whoami(), jitter.set_str_ansi)
+    my_GetSystemDirectory(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_GetSystemDirectoryW(jitter):
-    my_GetSystemDirectory(jitter, whoami(), jitter.set_str_unic)
+    my_GetSystemDirectory(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
 
 
 def my_CreateDirectory(jitter, funcname, get_str):
@@ -1647,11 +1652,11 @@ def my_CreateDirectory(jitter, funcname, get_str):
 
 
 def kernel32_CreateDirectoryW(jitter):
-    my_CreateDirectory(jitter, whoami(), jitter.get_str_unic)
+    my_CreateDirectory(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def kernel32_CreateDirectoryA(jitter):
-    my_CreateDirectory(jitter, whoami(), jitter.get_str_ansi)
+    my_CreateDirectory(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 
@@ -1669,11 +1674,11 @@ def my_CreateEvent(jitter, funcname, get_str):
 
 
 def kernel32_CreateEventA(jitter):
-    my_CreateEvent(jitter, whoami(), jitter.get_str_ansi)
+    my_CreateEvent(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def kernel32_CreateEventW(jitter):
-    my_CreateEvent(jitter, whoami(), jitter.get_str_unic)
+    my_CreateEvent(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def kernel32_WaitForSingleObject(jitter):
@@ -1704,7 +1709,7 @@ def kernel32_SetFileAttributesA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["lpfilename",
                                              "dwfileattributes"])
     if args.lpfilename:
-        # fname = get_str_ansi(jitter, args.lpfilename)
+        # fname = get_win_str_a(jitter, args.lpfilename)
         ret = 1
     else:
         ret = 0
@@ -1789,7 +1794,7 @@ def ntdll_ZwFreeVirtualMemory(jitter):
 
 def ntdll_RtlInitString(jitter):
     ret_ad, args = jitter.func_args_stdcall(["pstring", "source"])
-    s = jitter.get_str_ansi(args.source)
+    s = get_win_str_a(jitter, args.source)
     l = len(s) + 1
     o = struct.pack('HHI', l, l, args.source)
     jitter.vm.set_mem(args.pstring, o)
@@ -1800,7 +1805,7 @@ def ntdll_RtlAnsiStringToUnicodeString(jitter):
     ret_ad, args = jitter.func_args_stdcall(["dst", "src", "alloc_str"])
 
     l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8))
-    s = jitter.get_str_ansi(p_src)
+    s = get_win_str_a(jitter, p_src)
     s = ("\x00".join(s + "\x00"))
     l = len(s) + 1
     if args.alloc_str:
@@ -1822,7 +1827,7 @@ def ntdll_LdrLoadDll(jitter):
 
     l1, l2, p_src = struct.unpack('HHI',
                                   jitter.vm.get_mem(args.modname, 0x8))
-    s = jitter.get_str_unic(p_src)
+    s = get_win_str_w(jitter, p_src)
     libname = s.lower()
 
     ad = winobjs.runtime_dll.lib_get_add_base(libname)
@@ -1834,7 +1839,7 @@ def ntdll_LdrLoadDll(jitter):
 def ntdll_RtlFreeUnicodeString(jitter):
     ret_ad, args = jitter.func_args_stdcall(['src'])
     # l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8))
-    # s = get_str_unic(jitter, p_src)
+    # s = get_win_str_w(jitter, p_src)
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
@@ -1843,7 +1848,7 @@ def ntdll_LdrGetProcedureAddress(jitter):
                                              "opt", "p_ad"])
 
     l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.pfname, 0x8))
-    fname = jitter.get_str_ansi(p_src)
+    fname = get_win_str_a(jitter, p_src)
 
     ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
     jitter.add_breakpoint(ad, jitter.handle_lib)
@@ -1866,7 +1871,7 @@ def msvcrt_memset(jitter):
 
 def msvcrt_strrchr(jitter):
     ret_ad, args = jitter.func_args_cdecl(['pstr','c'])
-    s = jitter.get_str_ansi(args.pstr)
+    s = get_win_str_a(jitter, args.pstr)
     c = int_to_byte(args.c)
     ret = args.pstr + s.rfind(c)
     log.info("strrchr(%x '%s','%s') = %x" % (args.pstr,s,c,ret))
@@ -1874,7 +1879,7 @@ def msvcrt_strrchr(jitter):
 
 def msvcrt_wcsrchr(jitter):
     ret_ad, args = jitter.func_args_cdecl(['pstr','c'])
-    s = jitter.get_str_unic(args.pstr)
+    s = get_win_str_w(jitter, args.pstr)
     c = int_to_byte(args.c)
     ret = args.pstr + (s.rfind(c)*2)
     log.info("wcsrchr(%x '%s',%s) = %x" % (args.pstr,s,c,ret))
@@ -1907,7 +1912,7 @@ def msvcrt_memcmp(jitter):
 
 def shlwapi_PathFindExtensionA(jitter):
     ret_ad, args = jitter.func_args_stdcall(['path_ad'])
-    path = jitter.get_str_ansi(args.path_ad)
+    path = get_win_str_a(jitter, args.path_ad)
     i = path.rfind('.')
     if i == -1:
         i = args.path_ad + len(path)
@@ -1918,19 +1923,19 @@ def shlwapi_PathFindExtensionA(jitter):
 
 def shlwapi_PathRemoveFileSpecW(jitter):
     ret_ad, args = jitter.func_args_stdcall(['path_ad'])
-    path = jitter.get_str_unic(args.path_ad)
+    path = get_win_str_w(jitter, args.path_ad)
     i = path.rfind('\\')
     if i == -1:
         i = 0
     jitter.vm.set_mem(args.path_ad + i * 2, "\x00\x00")
-    path = jitter.get_str_unic(args.path_ad)
+    path = get_win_str_w(jitter, args.path_ad)
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def shlwapi_PathIsPrefixW(jitter):
     ret_ad, args = jitter.func_args_stdcall(['ptr_prefix', 'ptr_path'])
-    prefix = jitter.get_str_unic(args.ptr_prefix)
-    path = jitter.get_str_unic(args.ptr_path)
+    prefix = get_win_str_w(jitter, args.ptr_prefix)
+    path = get_win_str_w(jitter, args.ptr_path)
 
     if path.startswith(prefix):
         ret = 1
@@ -1941,7 +1946,7 @@ def shlwapi_PathIsPrefixW(jitter):
 
 def shlwapi_PathIsDirectoryW(jitter):
     ret_ad, args = jitter.func_args_stdcall(['ptr_path'])
-    fname = jitter.get_str_unic(args.ptr_path)
+    fname = get_win_str_w(jitter, args.ptr_path)
 
     sb_fname = windows_to_sbpath(fname)
 
@@ -1977,24 +1982,24 @@ def shlwapi_PathGetDriveNumber(jitter, funcname, get_str):
 
 
 def shlwapi_PathGetDriveNumberA(jitter):
-    shlwapi_PathGetDriveNumber(jitter, whoami(), jitter.get_str_ansi)
+    shlwapi_PathGetDriveNumber(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def shlwapi_PathGetDriveNumberW(jitter):
-    shlwapi_PathGetDriveNumber(jitter, whoami(), jitter.get_str_unic)
+    shlwapi_PathGetDriveNumber(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def shlwapi_PathIsFileSpecA(jitter):
-    shlwapi_PathIsFileSpec(jitter, whoami(), jitter.get_str_ansi)
+    shlwapi_PathIsFileSpec(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def shlwapi_PathIsFileSpecW(jitter):
-    shlwapi_PathIsFileSpec(jitter, whoami(), jitter.get_str_unic)
+    shlwapi_PathIsFileSpec(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def shlwapi_StrToIntA(jitter):
     ret_ad, args = jitter.func_args_stdcall(['i_str_ad'])
-    i_str = jitter.get_str_ansi(args.i_str_ad)
+    i_str = get_win_str_a(jitter, args.i_str_ad)
     try:
         i = int(i_str)
     except:
@@ -2020,11 +2025,11 @@ def shlwapi_StrToInt64Ex(jitter, funcname, get_str):
 
 
 def shlwapi_StrToInt64ExA(jitter):
-    shlwapi_StrToInt64Ex(jitter, whoami(), jitter.get_str_ansi)
+    shlwapi_StrToInt64Ex(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def shlwapi_StrToInt64ExW(jitter):
-    shlwapi_StrToInt64Ex(jitter, whoami(), jitter.get_str_unic)
+    shlwapi_StrToInt64Ex(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def user32_IsCharAlpha(jitter, funcname, get_str):
@@ -2042,11 +2047,11 @@ def user32_IsCharAlpha(jitter, funcname, get_str):
 
 
 def user32_IsCharAlphaA(jitter):
-    user32_IsCharAlpha(jitter, whoami(), jitter.get_str_ansi)
+    user32_IsCharAlpha(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def user32_IsCharAlphaW(jitter):
-    user32_IsCharAlpha(jitter, whoami(), jitter.get_str_unic)
+    user32_IsCharAlpha(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def user32_IsCharAlphaNumericA(jitter):
@@ -2067,7 +2072,7 @@ def msvcrt_sprintf_str(jitter, get_str):
     return ret_ad, args, get_fmt_args(jitter, fmt, cur_arg, get_str)
 
 def msvcrt_sprintf(jitter):
-    ret_ad, args, output = msvcrt_sprintf_str(jitter, jitter.get_str_ansi)
+    ret_ad, args, output = msvcrt_sprintf_str(jitter, lambda addr:get_win_str_a(jitter, addr))
     ret = len(output)
     log.info("sprintf() = '%s'" % (output))
     jitter.vm.set_mem(args.string, (output + '\x00').encode('utf8'))
@@ -2076,18 +2081,18 @@ def msvcrt_sprintf(jitter):
 def msvcrt_swprintf(jitter):
     ret_ad, args = jitter.func_args_cdecl(['string', 'fmt'])
     cur_arg, fmt = 2, args.fmt
-    output = get_fmt_args(jitter, fmt, cur_arg, jitter.get_str_unic)
+    output = get_fmt_args(jitter, fmt, cur_arg, lambda addr:get_win_str_w(jitter, addr))
     ret = len(output)
-    log.info("swprintf('%s') = '%s'" % (jitter.get_str_unic(args.fmt), output))
+    log.info("swprintf('%s') = '%s'" % (get_win_str_w(jitter, args.fmt), output))
     jitter.vm.set_mem(args.string, output.encode("utf-16le") + b'\x00\x00')
     return jitter.func_ret_cdecl(ret_ad, ret)
 
 def msvcrt_fprintf(jitter):
     ret_addr, args = jitter.func_args_cdecl(['file', 'fmt'])
     cur_arg, fmt = 2, args.fmt
-    output = get_fmt_args(jitter, fmt, cur_arg, jitter.get_str_ansi)
+    output = get_fmt_args(jitter, fmt, cur_arg, lambda addr:get_win_str_a(jitter, addr))
     ret = len(output)
-    log.info("fprintf(%x, '%s') = '%s'" % (args.file, jitter.get_str_ansi(args.fmt), output))
+    log.info("fprintf(%x, '%s') = '%s'" % (args.file, lambda addr:get_win_str_a(jitter, addr)(args.fmt), output))
 
     fd = jitter.vm.get_u32(args.file + 0x10)
     if not fd in winobjs.handle_pool:
@@ -2099,8 +2104,8 @@ def msvcrt_fprintf(jitter):
 def shlwapi_StrCmpNIA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2",
                                              "nchar"])
-    s1 = jitter.get_str_ansi(args.ptr_str1).lower()
-    s2 = jitter.get_str_ansi(args.ptr_str2).lower()
+    s1 = get_win_str_a(jitter, args.ptr_str1).lower()
+    s2 = get_win_str_a(jitter, args.ptr_str2).lower()
     s1 = s1[:args.nchar]
     s2 = s2[:args.nchar]
     jitter.func_ret_stdcall(ret_ad, cmp(s1, s2))
@@ -2109,7 +2114,7 @@ def shlwapi_StrCmpNIA(jitter):
 def advapi32_RegCreateKeyW(jitter):
     ret_ad, args = jitter.func_args_stdcall(["hkey", "subkey",
                                              "phandle"])
-    s_subkey = jitter.get_str_unic(args.subkey).lower() if args.subkey else ""
+    s_subkey = get_win_str_w(jitter, args.subkey).lower() if args.subkey else ""
 
     ret_hkey = 0
     ret = 2
@@ -2130,7 +2135,7 @@ def kernel32_GetCurrentDirectoryA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["size","buf"])
     dir_ = winobjs.cur_dir
     log.debug("GetCurrentDirectory() = '%s'" % dir_)
-    jitter.vm.set_mem(args.buf, dir_[:args.size-1] + b"\x00")
+    set_win_str_a(jitter, args.buf, dir_[:args.size-1])
     ret = len(dir_)
     if args.size <= len(dir_):
         ret += 1
@@ -2159,11 +2164,11 @@ def advapi32_RegOpenKeyEx(jitter, funcname, get_str):
 
 
 def advapi32_RegOpenKeyExA(jitter):
-    advapi32_RegOpenKeyEx(jitter, whoami(), jitter.get_str_ansi)
+    advapi32_RegOpenKeyEx(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def advapi32_RegOpenKeyExW(jitter):
-    advapi32_RegOpenKeyEx(jitter, whoami(), jitter.get_str_unic)
+    advapi32_RegOpenKeyEx(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def advapi32_RegSetValue(jitter, funcname, get_str):
@@ -2193,19 +2198,19 @@ def advapi32_RegCloseKey(jitter):
     jitter.func_ret_stdcall(ret_ad, 0)
 
 def advapi32_RegSetValueExA(jitter):
-    advapi32_RegSetValueEx(jitter, whoami(), jitter.get_str_ansi)
+    advapi32_RegSetValueEx(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def advapi32_RegSetValueExW(jitter):
-    advapi32_RegOpenKeyEx(jitter, whoami(), jitter.get_str_unic)
+    advapi32_RegOpenKeyEx(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def advapi32_RegSetValueA(jitter):
-    advapi32_RegSetValue(jitter, whoami(), jitter.get_str_ansi)
+    advapi32_RegSetValue(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def advapi32_RegSetValueW(jitter):
-    advapi32_RegSetValue(jitter, whoami(), jitter.get_str_unic)
+    advapi32_RegSetValue(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def kernel32_GetThreadLocale(jitter):
@@ -2220,15 +2225,15 @@ def kernel32_SetCurrentDirectory(jitter, get_str):
     jitter.func_ret_stdcall(ret_ad, 1)
 
 def kernel32_SetCurrentDirectoryW(jitter):
-    return kernel32_SetCurrentDirectory(jitter, jitter.get_str_unic)
+    return kernel32_SetCurrentDirectory(jitter, lambda addr:get_win_str_w(jitter, addr))
 
 def kernel32_SetCurrentDirectoryA(jitter):
-    return kernel32_SetCurrentDirectory(jitter, jitter.get_str_ansi)
+    return kernel32_SetCurrentDirectory(jitter, lambda addr:get_win_str_a(jitter, addr))
 
 def msvcrt_wcscat(jitter):
     ret_ad, args = jitter.func_args_cdecl(['ptr_str1', 'ptr_str2'])
-    s1 = jitter.get_str_unic(args.ptr_str1)
-    s2 = jitter.get_str_unic(args.ptr_str2)
+    s1 = get_win_str_w(jitter, args.ptr_str1)
+    s2 = get_win_str_w(jitter, args.ptr_str2)
     log.info("strcat('%s','%s')" % (s1,s2))
     jitter.vm.set_mem(args.ptr_str1, (s1 + s2).encode("utf-16le") + "\x00\x00")
     jitter.func_ret_cdecl(ret_ad, args.ptr_str1)
@@ -2253,11 +2258,11 @@ def kernel32_GetLocaleInfo(jitter, funcname, set_str):
 
 
 def kernel32_GetLocaleInfoA(jitter):
-    kernel32_GetLocaleInfo(jitter, whoami(), jitter.set_str_ansi)
+    kernel32_GetLocaleInfo(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_GetLocaleInfoW(jitter):
-    kernel32_GetLocaleInfo(jitter, whoami(), jitter.set_str_unic)
+    kernel32_GetLocaleInfo(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
 
 
 def kernel32_TlsAlloc(jitter):
@@ -2306,11 +2311,11 @@ def kernel32_GetStartupInfo(jitter, funcname, set_str):
 
 
 def kernel32_GetStartupInfoA(jitter):
-    kernel32_GetStartupInfo(jitter, whoami(), jitter.set_str_ansi)
+    kernel32_GetStartupInfo(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_GetStartupInfoW(jitter):
-    kernel32_GetStartupInfo(jitter, whoami(), jitter.set_str_unic)
+    kernel32_GetStartupInfo(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
 
 
 def kernel32_GetCurrentThreadId(jitter):
@@ -2336,7 +2341,7 @@ def user32_GetSystemMetrics(jitter):
 
 def wsock32_WSAStartup(jitter):
     ret_ad, args = jitter.func_args_stdcall(["version", "pwsadata"])
-    jitter.vm.set_mem(args.pwsadata, "\x01\x01\x02\x02WinSock 2.0\x00")
+    jitter.vm.set_mem(args.pwsadata, b"\x01\x01\x02\x02WinSock 2.0\x00")
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
@@ -2430,11 +2435,11 @@ def kernel32_CreateFileMapping(jitter, funcname, get_str):
 
 
 def kernel32_CreateFileMappingA(jitter):
-    kernel32_CreateFileMapping(jitter, whoami(), jitter.get_str_ansi)
+    kernel32_CreateFileMapping(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def kernel32_CreateFileMappingW(jitter):
-    kernel32_CreateFileMapping(jitter, whoami(), jitter.get_str_unic)
+    kernel32_CreateFileMapping(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def kernel32_MapViewOfFile(jitter):
@@ -2501,11 +2506,11 @@ def kernel32_GetDriveType(jitter, funcname, get_str):
 
 
 def kernel32_GetDriveTypeA(jitter):
-    kernel32_GetDriveType(jitter, whoami(), jitter.get_str_ansi)
+    kernel32_GetDriveType(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def kernel32_GetDriveTypeW(jitter):
-    kernel32_GetDriveType(jitter, whoami(), jitter.get_str_unic)
+    kernel32_GetDriveType(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def kernel32_GetDiskFreeSpace(jitter, funcname, get_str):
@@ -2522,11 +2527,11 @@ def kernel32_GetDiskFreeSpace(jitter, funcname, get_str):
 
 
 def kernel32_GetDiskFreeSpaceA(jitter):
-    kernel32_GetDiskFreeSpace(jitter, whoami(), jitter.get_str_ansi)
+    kernel32_GetDiskFreeSpace(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
 
 
 def kernel32_GetDiskFreeSpaceW(jitter):
-    kernel32_GetDiskFreeSpace(jitter, whoami(), jitter.get_str_unic)
+    kernel32_GetDiskFreeSpace(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
 
 
 def kernel32_VirtualQuery(jitter):
@@ -2574,7 +2579,7 @@ def msvcrt_srand(jitter):
 
 def msvcrt_wcslen(jitter):
     ret_ad, args = jitter.func_args_cdecl(["pwstr"])
-    s = jitter.get_str_unic(args.pwstr)
+    s = get_win_str_w(jitter, args.pwstr)
     jitter.func_ret_cdecl(ret_ad, len(s))
 
 def kernel32_SetFilePointer(jitter):
@@ -2777,8 +2782,8 @@ def user32_MessageBoxA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["hwnd", "lptext",
                                              "lpcaption", "utype"])
 
-    text = jitter.get_str_ansi(args.lptext)
-    caption = jitter.get_str_ansi(args.lpcaption)
+    text = get_win_str_a(jitter, args.lptext)
+    caption = get_win_str_a(jitter, args.lpcaption)
 
     log.info('Caption: %r Text: %r', caption, text)
 
@@ -2794,11 +2799,11 @@ def kernel32_myGetTempPath(jitter, set_str):
 
 
 def kernel32_GetTempPathA(jitter):
-    kernel32_myGetTempPath(jitter, jitter.set_str_ansi)
+    kernel32_myGetTempPath(jitter, lambda addr,value: set_win_str_a(jitter, addr, value))
 
 
 def kernel32_GetTempPathW(jitter):
-    kernel32_myGetTempPath(jitter, jitter.set_str_unic)
+    kernel32_myGetTempPath(jitter, lambda addr,value: set_win_str_w(jitter, addr, value))
 
 
 temp_num = 0
@@ -2809,8 +2814,8 @@ def kernel32_GetTempFileNameA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["path", "ext", "unique", "buf"])
 
     temp_num += 1
-    ext = jitter.get_str_ansi(args.ext) if args.ext else 'tmp'
-    path = jitter.get_str_ansi(args.path) if args.path else "xxx"
+    ext = get_win_str_a(jitter, args.ext) if args.ext else 'tmp'
+    path = get_win_str_a(jitter, args.path) if args.path else "xxx"
     fname = path + "\\" + "temp%.4d" % temp_num + "." + ext
     jitter.vm.set_mem(args.buf, fname)
 
@@ -2887,7 +2892,7 @@ class find_data_mngr(object):
 def kernel32_FindFirstFileA(jitter):
     ret_ad, args = jitter.func_args_stdcall(["pfilepattern", "pfindfiledata"])
 
-    filepattern = jitter.get_str_ansi(args.pfilepattern)
+    filepattern = get_win_str_a(jitter, args.pfilepattern)
     h = winobjs.find_data.findfirst(filepattern)
 
     fname = winobjs.find_data.findnext(h)
@@ -2951,7 +2956,7 @@ def msvcrt__ultow(jitter):
     if not args.radix in [10, 16, 20]:
         raise ValueError("Not tested")
     s = int2base(value, args.radix)
-    jitter.vm.set_mem(args.p, jitter.set_str_unic(s + "\x00"))
+    jitter.vm.set_mem(args.p, lambda addr,value: set_win_str_w(jitter, addr, value)(s + "\x00"))
     jitter.func_ret_cdecl(ret_ad, args.p)
 
 
@@ -2978,15 +2983,15 @@ def msvcrt_myfopen(jitter, get_str):
 
 
 def msvcrt__wfopen(jitter):
-    msvcrt_myfopen(jitter, jitter.get_str_unic)
+    msvcrt_myfopen(jitter, lambda addr:get_win_str_w(jitter, addr))
 
 
 def msvcrt_fopen(jitter):
-    msvcrt_myfopen(jitter, jitter.get_str_ansi)
+    msvcrt_myfopen(jitter, lambda addr:get_win_str_a(jitter, addr))
 
 
 def msvcrt_strlen(jitter):
     ret_ad, args = jitter.func_args_cdecl(["src"])
 
-    s = jitter.get_str_ansi(args.src)
+    s = get_win_str_a(jitter, args.src)
     jitter.func_ret_cdecl(ret_ad, len(s))
diff --git a/miasm/os_dep/win_api_x86_32_seh.py b/miasm/os_dep/win_api_x86_32_seh.py
index dadd0889..374a975e 100644
--- a/miasm/os_dep/win_api_x86_32_seh.py
+++ b/miasm/os_dep/win_api_x86_32_seh.py
@@ -81,7 +81,7 @@ return_from_exception = 0x6eadbeef
 
 name2module = []
 main_pe = None
-main_pe_name = b"c:\\xxx\\toto.exe"
+main_pe_name = "c:\\xxx\\toto.exe"
 
 MAX_SEH = 5
 
@@ -254,9 +254,9 @@ def create_modules_chain(jitter, name2module):
                         fname)
             continue
         addr = base_addr + i * 0x1000
-        bpath = fname.replace(b'/', b'\\')
+        bpath = fname.replace('/', '\\')
         bname_str = os.path.split(fname)[1].lower()
-        bname_unicode = bname_str.decode('utf8').encode("utf-16le")
+        bname_unicode = bname_str.encode("utf-16le")
         log.info("Add module %x %r", pe_obj.NThdr.ImageBase, bname_str)
 
         modules_info.add(bname_str, pe_obj, addr)
@@ -553,7 +553,7 @@ def fake_seh_handler(jitter, except_code, previous_seh=None):
     @previous_seh: (optional) last SEH address when multiple SEH are used
     """
     global seh_count
-    log.warning('Exception at %x %r', jitter.cpu.EIP, seh_count)
+    log.info('Exception at %x %r', jitter.cpu.EIP, seh_count)
     seh_count += 1
 
     # Get space on stack for exception handling
@@ -576,7 +576,7 @@ def fake_seh_handler(jitter, except_code, previous_seh=None):
             seh = seh.Next.deref
         seh = seh.Next.deref
 
-    log.info(
+    log.debug(
         'seh_ptr %x { old_seh %r eh %r} ctx_addr %x',
         seh.get_addr(),
         seh.Next,
@@ -597,7 +597,7 @@ def fake_seh_handler(jitter, except_code, previous_seh=None):
     jitter.push_uint32_t(return_from_exception)         # Ret address
 
     # Set fake new current seh for exception
-    log.info("Fake seh ad %x", fake_seh_address)
+    log.debug("Fake seh ad %x", fake_seh_address)
     fake_seh = EXCEPTION_REGISTRATION_RECORD(jitter.vm, fake_seh_address)
     fake_seh.Next.val = tib.ExceptionList.val
     fake_seh.Handler = 0xaaaaaaaa
@@ -611,7 +611,7 @@ def fake_seh_handler(jitter, except_code, previous_seh=None):
     # XXX set ebx to nul?
     jitter.cpu.EBX = 0
 
-    log.info('Jumping at %r', seh.Handler)
+    log.debug('Jumping at %r', seh.Handler)
     return seh.Handler.val
 
 
@@ -620,16 +620,16 @@ def dump_seh(jitter):
     Walk and dump the SEH entries
     @jitter: jitter instance
     """
-    log.info('Dump_seh. Tib_address: %x', tib_address)
+    log.debug('Dump_seh. Tib_address: %x', tib_address)
     cur_seh_ptr = NT_TIB(jitter.vm, tib_address).ExceptionList
     loop = 0
     while cur_seh_ptr and jitter.vm.is_mapped(cur_seh_ptr.val,
                                               len(cur_seh_ptr)):
         if loop > MAX_SEH:
-            log.warn("Too many seh, quit")
+            log.debug("Too many seh, quit")
             return
         err = cur_seh_ptr.deref
-        log.info('\t' * (loop + 1) + 'seh_ptr: %x { prev_seh: %r eh %r }',
+        log.debug('\t' * (loop + 1) + 'seh_ptr: %x { prev_seh: %r eh %r }',
                  err.get_addr(), err.Next, err.Handler)
         cur_seh_ptr = err.Next
         loop += 1
@@ -656,27 +656,27 @@ def return_from_seh(jitter):
     context_address = jitter.vm.get_u32(jitter.cpu.ESP + 0x8)
 
     # Get registers changes
-    log.info('Context address: %x', context_address)
+    log.debug('Context address: %x', context_address)
     status = jitter.cpu.EAX
     ctxt2regs(jitter, context_address)
 
     # Rebuild SEH (remove fake SEH)
     tib = NT_TIB(jitter.vm, tib_address)
     seh = tib.ExceptionList.deref
-    log.info('Old seh: %x New seh: %x', seh.get_addr(), seh.Next.val)
+    log.debug('Old seh: %x New seh: %x', seh.get_addr(), seh.Next.val)
     tib.ExceptionList.val = seh.Next.val
     dump_seh(jitter)
 
     # Handle returned values
     if status == 0x0:
         # ExceptionContinueExecution
-        log.info('SEH continue')
+        log.debug('SEH continue')
         jitter.pc = jitter.cpu.EIP
-        log.info('Context::Eip: %x', jitter.pc)
+        log.debug('Context::Eip: %x', jitter.pc)
 
     elif status == 1:
         # ExceptionContinueSearch
-        log.info("Delegate to the next SEH handler")
+        log.debug("Delegate to the next SEH handler")
         # exception_base_address: context_address - 0xfc
         # -> exception_record_address: exception_base_address + 0xe8
         exception_record = EXCEPTION_RECORD(jitter.vm,
diff --git a/test/arch/aarch64/arch.py b/test/arch/aarch64/arch.py
index 70a44053..9fc6ee8e 100644
--- a/test/arch/aarch64/arch.py
+++ b/test/arch/aarch64/arch.py
@@ -1763,6 +1763,8 @@ reg_tests_aarch64 = [
      "8DFE5F88"),
     ("0046FA7C    LDAXR      X17, [X16]",
      "11FE5FC8"),
+    ("XXXXXXXX    LDARB      W0, [X20]",
+     "80FEDF08"),
     ("00464090    STLXR      W14, W2, [X20]",
      "82FE0E88"),
 
diff --git a/test/arch/x86/qemu/testqemu.py b/test/arch/x86/qemu/testqemu.py
index 594a826b..64312928 100644
--- a/test/arch/x86/qemu/testqemu.py
+++ b/test/arch/x86/qemu/testqemu.py
@@ -48,7 +48,7 @@ def xxx___printf_chk(jitter):
     ret_ad, args = jitter.func_args_systemv(["out", "format"])
     if args.out != 1:
         raise RuntimeError("Not implemented")
-    fmt = jitter.get_str_ansi(args.format)
+    fmt = jitter.get_c_str(args.format)
     # Manage llx
     fmt = fmt.replace("llx", "lx")
     fmt = fmt.replace("%016lx", "%016z")
@@ -60,7 +60,7 @@ def xxx___printf_chk(jitter):
     for x in fmt_a:
         a = jitter.vm.get_u32(esp + 8 + 4*i)
         if x == "s":
-            a = jitter.get_str_ansi(a)
+            a = jitter.get_c_str(a)
         elif x in ("x", 'X', "d"):
             pass
         elif x.lower() in ("f", "l"):
@@ -102,7 +102,7 @@ def xxx_puts(jitter):
     writes the string s and a trailing newline to stdout.
     '''
     ret_addr, args = jitter.func_args_systemv(['target'])
-    output = jitter.get_str_ansi(args.target)
+    output = jitter.get_c_str(args.target)
     # Check with expected result
     line = next(expected)
     if output != line.rstrip():
diff --git a/test/arch/x86/qemu/testqemu64.py b/test/arch/x86/qemu/testqemu64.py
index 636cb6a9..8d25ca68 100644
--- a/test/arch/x86/qemu/testqemu64.py
+++ b/test/arch/x86/qemu/testqemu64.py
@@ -48,7 +48,7 @@ def xxx___printf_chk(jitter):
     ret_ad, args = jitter.func_args_systemv(["out", "format"])
     if args.out != 1:
         raise RuntimeError("Not implemented")
-    fmt = jitter.get_str_ansi(args.format)
+    fmt = jitter.get_c_str(args.format)
     # Manage llx
     fmt = fmt.replace("llx", "lx")
     fmt = fmt.replace("%016lx", "%016z")
@@ -60,7 +60,7 @@ def xxx___printf_chk(jitter):
     for x in fmt_a:
         a = jitter.get_arg_n_systemv(2 + i)
         if x == "s":
-            a = jitter.get_str_ansi(a)
+            a = jitter.get_c_str(a)
         elif x in ("x", 'X', 'd', 'z', 'Z'):
             pass
         elif x.lower() in ("f","l"):
@@ -98,7 +98,7 @@ def xxx_puts(jitter):
     writes the string s and a trailing newline to stdout.
     '''
     ret_addr, args = jitter.func_args_systemv(['target'])
-    output = jitter.get_str_ansi(args.target)
+    output = jitter.get_c_str(args.target)
     # Check with expected result
     line = next(expected)
     if output != line.rstrip():
diff --git a/test/os_dep/linux/stdlib.py b/test/os_dep/linux/stdlib.py
index ef890625..a0432e65 100755
--- a/test/os_dep/linux/stdlib.py
+++ b/test/os_dep/linux/stdlib.py
@@ -33,7 +33,7 @@ class TestLinuxStdlib(unittest.TestCase):
         jit.push_uint32_t(buf)
         jit.push_uint32_t(0) # ret_ad
         stdlib.xxx_sprintf(jit)
-        ret = jit.get_str_ansi(buf)
+        ret = jit.get_c_str(buf)
         self.assertEqual(ret, "'coucou' 1111")
 
 
diff --git a/test/os_dep/win_api_x86_32.py b/test/os_dep/win_api_x86_32.py
index f759c6af..66a4e628 100755
--- a/test/os_dep/win_api_x86_32.py
+++ b/test/os_dep/win_api_x86_32.py
@@ -6,6 +6,7 @@ import unittest
 import logging
 from miasm.analysis.machine import Machine
 import miasm.os_dep.win_api_x86_32 as winapi
+from miasm.os_dep.win_api_x86_32 import get_win_str_a, get_win_str_w
 from miasm.core.utils import pck32
 from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
 
@@ -42,7 +43,7 @@ class TestWinAPI(unittest.TestCase):
         jit.push_uint32_t(buf)
         jit.push_uint32_t(0) # ret_ad
         winapi.msvcrt_sprintf(jit)
-        ret = jit.get_str_ansi(buf)
+        ret = get_win_str_a(jit, buf)
         self.assertEqual(ret, "'coucou' 1111")
 
 
@@ -63,7 +64,7 @@ class TestWinAPI(unittest.TestCase):
         jit.push_uint32_t(buf)
         jit.push_uint32_t(0) # ret_ad
         winapi.msvcrt_swprintf(jit)
-        ret = jit.get_str_unic(buf)
+        ret = get_win_str_w(jit, buf)
         self.assertEqual(ret, u"'coucou' 1111")
 
 
@@ -94,7 +95,7 @@ class TestWinAPI(unittest.TestCase):
         jit.push_uint32_t(size)   # size
         jit.push_uint32_t(0)      # @return
         winapi.kernel32_GetCurrentDirectoryA(jit)
-        dir_ = jit.get_str_ansi(addr)
+        dir_ = get_win_str_a(jit, addr)
         size_ret = jit.cpu.EAX
         self.assertEqual(len(dir_), size_ret)
 
@@ -106,7 +107,7 @@ class TestWinAPI(unittest.TestCase):
         winapi.kernel32_GetCurrentDirectoryA(jit)
         size_ret = jit.cpu.EAX
         self.assertEqual(len(dir_)+1, size_ret)
-        dir_short = jit.get_str_ansi(addr)
+        dir_short = get_win_str_a(jit, addr)
         self.assertEqual(dir_short, dir_[:4])
 
     def test_MemoryManagementFunctions(self):
diff --git a/test/test_all.py b/test/test_all.py
index 02bddb51..7fb43525 100755
--- a/test/test_all.py
+++ b/test/test_all.py
@@ -923,7 +923,7 @@ By default, all tag are considered." % ", ".join(list(TAGS)), default="")
     # Handle Z3 dependency
     try:
         import z3
-    except ImportError:
+    except:
         print("%(red)s[Z3]%(end)s " % cosmetics.colors + \
             "Z3 and its python binding are necessary for TranslatorZ3.")
         if TAGS["z3"] not in exclude_tags: