about summary refs log tree commit diff stats
path: root/miasm/os_dep
diff options
context:
space:
mode:
Diffstat (limited to 'miasm/os_dep')
-rw-r--r--miasm/os_dep/__init__.py1
-rw-r--r--miasm/os_dep/common.py169
-rw-r--r--miasm/os_dep/linux/__init__.py1
-rw-r--r--miasm/os_dep/linux/environment.py993
-rw-r--r--miasm/os_dep/linux/syscall.py1129
-rw-r--r--miasm/os_dep/linux_stdlib.py213
-rw-r--r--miasm/os_dep/win_32_structs.py231
-rw-r--r--miasm/os_dep/win_api_x86_32.py3595
-rw-r--r--miasm/os_dep/win_api_x86_32_seh.py705
9 files changed, 0 insertions, 7037 deletions
diff --git a/miasm/os_dep/__init__.py b/miasm/os_dep/__init__.py
deleted file mode 100644
index 6aa660d8..00000000
--- a/miasm/os_dep/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"Operating System specific methods"
diff --git a/miasm/os_dep/common.py b/miasm/os_dep/common.py
deleted file mode 100644
index 74100817..00000000
--- a/miasm/os_dep/common.py
+++ /dev/null
@@ -1,169 +0,0 @@
-import os
-
-from future.utils import viewitems
-
-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_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
-    data = jitter.vm.get_mem(ad_str, l)
-    ret = data.decode(WIN_CODEPAGE)
-    return ret
-
-
-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
-           jitter.vm.get_mem(tmp, 2) != b"\x00\x00"):
-        tmp += 2
-        l += 2
-    s = jitter.vm.get_mem(ad_str, l)
-    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_win_str_a(jitter, addr, value):
-    value = encode_win_str_a(value)
-    jitter.vm.set_mem(addr, value)
-
-
-def set_win_str_w(jitter, addr, value):
-    value = encode_win_str_w(value)
-    jitter.vm.set_mem(addr, value)
-
-
-class heap(object):
-
-    "Light heap simulation"
-
-    addr = 0x20000000
-    align = 0x1000
-    size = 32
-    mask = (1 << size) - 1
-
-    def next_addr(self, size):
-        """
-        @size: the size to allocate
-        return the future checnk address
-        """
-        ret = self.addr
-        self.addr = (self.addr + size + self.align - 1)
-        self.addr &= self.mask ^ (self.align - 1)
-        return ret
-
-    def alloc(self, jitter, size, perm=PAGE_READ | PAGE_WRITE, cmt=""):
-        """
-        @jitter: a jitter instance
-        @size: the size to allocate
-        @perm: permission flags (see vm_alloc doc)
-        """
-        return self.vm_alloc(jitter.vm, size, perm=perm, cmt=cmt)
-
-    def vm_alloc(self, vm, size, perm=PAGE_READ | PAGE_WRITE, cmt=""):
-        """
-        @vm: a VmMngr instance
-        @size: the size to allocate
-        @perm: permission flags (PAGE_READ, PAGE_WRITE, PAGE_EXEC or any `|`
-            combination of them); default is PAGE_READ|PAGE_WRITE
-        """
-        addr = self.next_addr(size)
-        vm.add_memory_page(
-            addr,
-            perm,
-            b"\x00" * (size),
-            "Heap alloc by %s %s" % (get_caller_name(2), cmt)
-        )
-        return addr
-
-    def get_size(self, vm, ptr):
-        """
-        @vm: a VmMngr instance
-        @size: ptr to get the size of the associated allocation.
-
-        `ptr` can be the base address of a previous allocation, or an address
-        within the allocated range. The size of the whole allocation is always
-        returned, regardless ptr is the base address or not.
-        """
-        assert vm.is_mapped(ptr, 1)
-        data = vm.get_all_memory()
-        ptr_page = data.get(ptr, None)
-        if ptr_page is None:
-            for address, page_info in viewitems(data):
-                if address <= ptr < address + page_info["size"]:
-                    ptr_page = page_info
-                    break
-            else:
-                raise RuntimeError("Must never happen (unmapped but mark as mapped by API)")
-        return ptr_page["size"]
-
-
-def windows_to_sbpath(path):
-    """Convert a Windows path to a valid filename within the sandbox
-    base directory.
-
-    """
-    path = [elt for elt in path.lower().replace('/', '_').split('\\') if elt]
-    return os.path.join(BASE_SB_PATH, *path)
-
-
-def unix_to_sbpath(path):
-    """Convert a POSIX path to a valid filename within the sandbox
-    base directory.
-
-    """
-    path = [elt for elt in path.split('/') if elt]
-    return os.path.join(BASE_SB_PATH, *path)
-
-def get_fmt_args(fmt, cur_arg, get_str, get_arg_n):
-    idx = 0
-    fmt = get_str(fmt)
-    chars_format = '%cdfsuxX'
-    char_percent = '%'
-    char_string = 's'
-    output = ""
-
-    while True:
-        if idx == len(fmt):
-            break
-        char = fmt[idx:idx+1]
-        idx += 1
-        if char == char_percent:
-            token = char_percent
-            while True:
-                char = fmt[idx:idx+1]
-                idx += 1
-                token += char
-                if char in chars_format:
-                    break
-            if char == char_percent:
-                output += char
-                continue
-            if token.endswith(char_string):
-                addr = get_arg_n(cur_arg)
-                arg = get_str(addr)
-            else:
-                arg = get_arg_n(cur_arg)
-            char = token % arg
-            cur_arg += 1
-        output += char
-    return output
diff --git a/miasm/os_dep/linux/__init__.py b/miasm/os_dep/linux/__init__.py
deleted file mode 100644
index 4434ce50..00000000
--- a/miasm/os_dep/linux/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# Linux emulation
diff --git a/miasm/os_dep/linux/environment.py b/miasm/os_dep/linux/environment.py
deleted file mode 100644
index 3ba4382f..00000000
--- a/miasm/os_dep/linux/environment.py
+++ /dev/null
@@ -1,993 +0,0 @@
-from __future__ import print_function
-from collections import namedtuple
-import functools
-import logging
-import os
-import re
-import struct
-import termios
-
-from future.utils import viewitems
-
-from miasm.core.interval import interval
-from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
-
-
-REGEXP_T = type(re.compile(r''))
-
-StatInfo = namedtuple("StatInfo", [
-    "st_dev", "st_ino", "st_nlink", "st_mode", "st_uid", "st_gid", "st_rdev",
-    "st_size", "st_blksize", "st_blocks", "st_atime", "st_atimensec",
-    "st_mtime", "st_mtimensec", "st_ctime", "st_ctimensec"
-])
-StatFSInfo = namedtuple("StatFSInfo", [
-    "f_type", "f_bsize", "f_blocks", "f_bfree", "f_bavail", "f_files",
-    "f_ffree", "f_fsid", "f_namelen", "f_frsize", "f_flags", "f_spare",
-])
-
-log = logging.getLogger("environment")
-console_handler = logging.StreamHandler()
-console_handler.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s"))
-log.addHandler(console_handler)
-log.setLevel(logging.WARNING)
-
-class FileDescriptor(object):
-    """Stand for a file descriptor on a system
-
-    According to inode(7), following types are possibles:
-     - socket
-     - symbolic link
-     - regular file
-     - block device
-     - directory
-     - character device
-     - FIFO
-    """
-
-    # st_mode's file type
-    file_type = None
-    # st_mode's file mode (9 least bits are file permission bits)
-    file_mode = 0o0777
-    # st_dev / st_rdev
-    cont_device_id = None
-    device_id = 0
-    # inode number (st_ino)
-    inode = None
-    # Number of hardlink (st_nlink)
-    nlink = 0
-    # Owner / group
-    uid = None
-    gid = None
-    # Size (st_size / st_blksize / st_blocks)
-    size = 0
-    blksize = 0
-    blocks = 0
-    # Times
-    atime = 0
-    atimensec = 0
-    mtime = 0
-    mtimensec = 0
-    ctime = 0
-    ctimensec = 0
-
-    def __init__(self, number):
-        self.number = number
-        self.is_closed = False
-
-    def stat(self):
-        mode = self.file_type | self.file_mode
-        return StatInfo(
-            st_dev=self.cont_device_id, st_ino=self.inode,
-            st_nlink=self.nlink, st_mode=mode,
-            st_uid=self.uid, st_gid=self.gid,
-            st_rdev=self.device_id, st_size=self.size,
-            st_blksize=self.blksize, st_blocks=self.blocks,
-            st_atime=self.atime, st_atimensec=self.atimensec,
-            st_mtime=self.mtime, st_mtimensec=self.mtimensec,
-            st_ctime=self.ctime, st_ctimensec=self.ctimensec
-        )
-
-    def close(self):
-        self.is_closed = True
-
-
-class FileDescriptorCharDevice(FileDescriptor):
-    file_type = 0o0020000 # S_IFCHR
-    file_mode = 0o0620
-    cont_device_id = 1
-    device_id = 1
-
-
-class FileDescriptorSTDIN(FileDescriptorCharDevice):
-    """Special file descriptor standinf for STDIN"""
-    inode = 0
-
-    def read(self, count):
-        raise RuntimeError("Not implemented")
-
-
-class FileDescriptorSTDOUT(FileDescriptorCharDevice):
-    """Special file descriptor standinf for STDOUT"""
-    inode = 1
-
-    def write(self, data):
-        print("[STDOUT] %s" % data.rstrip())
-
-
-class FileDescriptorSTDERR(FileDescriptorCharDevice):
-    """Special file descriptor standinf for STDERR"""
-    inode = 2
-
-    def write(self, data):
-        print("[STDERR] %s" % data.rstrip())
-
-
-class FileDescriptorDirectory(FileDescriptor):
-    """FileDescription designing a directory"""
-
-    file_type = 0o0040000 # S_IFDIR
-
-    def __init__(self, number, flags, filesystem, real_path):
-        super(FileDescriptorDirectory, self).__init__(number)
-        self.filesystem = filesystem
-        self.real_path = real_path
-        self.cur_listdir = None
-        self.flags = flags
-
-    def listdir(self):
-        if self.cur_listdir is None:
-            self.cur_listdir = os.listdir(self.real_path)
-        while self.cur_listdir:
-            yield self.cur_listdir.pop()
-
-
-class FileDescriptorRegularFile(FileDescriptor):
-    """FileDescriptor designing a regular file"""
-
-    file_type = 0o0100000 # S_IFREG
-
-    def __init__(self, number, flags, filesystem, real_fd):
-        super(FileDescriptorRegularFile, self).__init__(number)
-        self.flags = flags
-        self.filesystem = filesystem
-        self.real_fd = real_fd
-
-    def write(self, data):
-        raise RuntimeError("Not implemented")
-
-    def read(self, count):
-        return os.read(self.real_fd, count)
-
-    def close(self):
-        super(FileDescriptorRegularFile, self).close()
-        return os.close(self.real_fd)
-
-    def lseek(self, offset, whence):
-        return os.lseek(self.real_fd, offset, whence) # SEEK_SET
-
-    def tell(self):
-        return self.lseek(0, 1) # SEEK_CUR
-
-    def seek(self, offset):
-        return self.lseek(offset, 0) # SEEK_SET
-
-
-class FileDescriptorSocket(FileDescriptor):
-    """FileDescription standing for a socket"""
-
-    file_type = 0o0140000 # S_IFSOCK
-
-    def __init__(self, number, family, type_, protocol):
-        super(FileDescriptorSocket, self).__init__(number)
-        self.family = family
-        self.type_ = type_
-        self.protocol = protocol
-
-
-class FileSystem(object):
-    """File system abstraction
-    Provides standard operations on the filesystem, (a bit like FUSE)
-
-    API using FileSystem only used sandbox-side path. FileSystem should be the
-    only object able to interact with real path, outside the sandbox.
-
-    Thus, if `resolve_path` is correctly implemented and used, it should not be
-    possible to modify files outside the sandboxed path
-    """
-
-    device_id = 0x1234 # ID of device containing file (stat.st_dev)
-    blocksize = 0x1000 # Size of block on this filesystem
-    f_type = 0xef53 # (Type of filesystem) EXT4_SUPER_MAGIC
-    nb_total_block = 0x1000
-    nb_free_block = 0x100
-    nb_avail_block = nb_free_block # Available to unprivileged user
-    nb_total_fnode = 100 # Total file nodes in filesystem
-    nb_free_fnode = 50
-    max_filename_len = 256
-    fragment_size = 0
-    mount_flags = 0
-
-    def __init__(self, base_path, linux_env):
-        self.base_path = base_path
-        self.linux_env = linux_env
-        self.passthrough = []
-        self.path_to_inode = {} # Real path (post-resolution) -> inode number
-
-    def resolve_path(self, path, follow_link=True):
-        """Resolve @path to the corresponding sandboxed path"""
-
-        # path_bytes is used for Python 2 / Python 3 compatibility
-        path_bytes = not isinstance(path, str)
-        path_sep = os.path.sep.encode() if path_bytes else os.path.sep
-
-        if path_bytes:
-            def _convert(subpath):
-                if not isinstance(subpath, str):
-                    return subpath
-                return subpath.encode()
-            def _convert_re(expr):
-                if isinstance(expr.pattern, str):
-                    try:
-                        return re.compile(
-                            expr.pattern.encode(),
-                            flags=expr.flags & ~re.UNICODE
-                        )
-                    except UnicodeEncodeError:
-                        # Will never match
-                        log.warning(
-                            'Cannot convert regexp to bytes %r %r',
-                            expr.pattern,
-                            expr.flags,
-                            exc_info=True,
-                        )
-                        return re.compile(b'$X')
-                return expr
-        else:
-            def _convert(subpath):
-                if not isinstance(subpath, str):
-                    return subpath.decode()
-                return subpath
-            def _convert_re(expr):
-                if not isinstance(expr.pattern, str):
-                    try:
-                        return re.compile(
-                            expr.pattern.decode(),
-                            flags=expr.flags & re.UNICODE
-                        )
-                    except UnicodeDecodeError:
-                        # Will never match
-                        log.warning(
-                            'Cannot convert regexp to str %r %r',
-                            expr.pattern,
-                            expr.flags,
-                            exc_info=True,
-                        )
-                        return re.compile(r'$X')
-                return expr
-
-        # Remove '../', etc.
-        path = os.path.normpath(path)
-
-        # Passthrough
-        for passthrough in self.passthrough:
-            if isinstance(passthrough, REGEXP_T):
-                if _convert_re(passthrough).match(path):
-                    return path
-            elif _convert(passthrough) == path:
-                return path
-
-        # Remove leading '/' if any
-        path = path.lstrip(path_sep)
-
-        base_path = os.path.abspath(_convert(self.base_path))
-        out_path = os.path.join(base_path, path)
-        assert out_path.startswith(base_path + path_sep)
-        if os.path.islink(out_path):
-            link_target = os.readlink(out_path)
-            # Link can be absolute or relative -> absolute
-            link = os.path.normpath(os.path.join(os.path.dirname(path), link_target))
-            if follow_link:
-                out_path = self.resolve_path(link)
-            else:
-                out_path = link
-        return out_path
-
-    def get_path_inode(self, real_path):
-        inode = self.path_to_inode.setdefault(real_path, len(self.path_to_inode))
-        return inode
-
-    def exists(self, path):
-        sb_path = self.resolve_path(path)
-        return os.path.exists(sb_path)
-
-    def readlink(self, path):
-        sb_path = self.resolve_path(path, follow_link=False)
-        if not os.path.islink(sb_path):
-            return None
-        return os.readlink(sb_path)
-
-    def statfs(self):
-        return StatFSInfo(
-            f_type=self.f_type, f_bsize=self.blocksize,
-            f_blocks=self.nb_total_block, f_bfree=self.nb_free_block,
-            f_bavail=self.nb_avail_block, f_files=self.nb_total_fnode,
-            f_ffree=self.nb_free_fnode, f_fsid=self.device_id,
-            f_namelen=self.max_filename_len,
-            f_frsize=self.fragment_size, f_flags=self.mount_flags, f_spare=0)
-
-    def getattr_(self, path, follow_link=True):
-        sb_path = self.resolve_path(path, follow_link=follow_link)
-        flags = self.linux_env.O_RDONLY
-        if os.path.isdir(sb_path):
-            flags |= self.linux_env.O_DIRECTORY
-
-        fd = self.open_(path, flags, follow_link=follow_link)
-        info = self.linux_env.fstat(fd)
-        self.linux_env.close(fd)
-        return info
-
-    def open_(self, path, flags, follow_link=True):
-        path = self.resolve_path(path, follow_link=follow_link)
-        if not os.path.exists(path):
-            # ENOENT (No such file or directory)
-            return -1
-        fd = self.linux_env.next_fd()
-        acc_mode = flags & self.linux_env.O_ACCMODE
-
-        if os.path.isdir(path):
-            assert flags & self.linux_env.O_DIRECTORY == self.linux_env.O_DIRECTORY
-            if acc_mode == self.linux_env.O_RDONLY:
-                fdesc = FileDescriptorDirectory(fd, flags, self, path)
-            else:
-                raise RuntimeError("Not implemented")
-        elif os.path.isfile(path):
-            if acc_mode == os.O_RDONLY:
-                # Read only
-                real_fd = os.open(path, os.O_RDONLY)
-            else:
-                raise RuntimeError("Not implemented")
-            fdesc = FileDescriptorRegularFile(fd, flags, self, real_fd)
-
-        elif os.path.islink(path):
-            raise RuntimeError("Not implemented")
-        else:
-            raise RuntimeError("Unknown file type for %r" % path)
-
-        self.linux_env.file_descriptors[fd] = fdesc
-        # Set stat info
-        fdesc.cont_device_id = self.device_id
-        fdesc.inode = self.get_path_inode(path)
-        fdesc.uid = self.linux_env.user_uid
-        fdesc.gid = self.linux_env.user_gid
-        size = os.path.getsize(path)
-        fdesc.size = size
-        fdesc.blksize = self.blocksize
-        fdesc.blocks = (size + ((512 - (size % 512)) % 512)) // 512
-        return fd
-
-
-class Networking(object):
-    """Network abstraction"""
-
-    def __init__(self, linux_env):
-        self.linux_env = linux_env
-
-    def socket(self, family, type_, protocol):
-        fd = self.linux_env.next_fd()
-        fdesc = FileDescriptorSocket(fd, family, type_, protocol)
-        self.linux_env.file_descriptors[fd] = fdesc
-        return fd
-
-
-class LinuxEnvironment(object):
-    """A LinuxEnvironment regroups information to simulate a Linux-like
-    environment"""
-
-    # To be overridden
-    platform_arch = None
-
-    # User information
-    user_uid = 1000
-    user_euid = 1000
-    user_gid = 1000
-    user_egid = 1000
-    user_name = b"user"
-
-    # Memory mapping information
-    brk_current = 0x74000000
-    mmap_current = 0x75000000
-
-    # System information
-    sys_sysname = b"Linux"
-    sys_nodename = b"user-pc"
-    sys_release = b"4.13.0-19-generic"
-    sys_version = b"#22-Ubuntu"
-    sys_machine = None
-
-    # Filesystem
-    filesystem_base = "file_sb"
-    file_descriptors = None
-
-    # Current process
-    process_tid = 1000
-    process_pid = 1000
-
-    # Syscall restrictions
-    ioctl_allowed = None # list of (fd, cmd), None value for wildcard
-    ioctl_disallowed = None # list of (fd, cmd), None value for wildcard
-
-    # Time
-    base_time = 1531900000
-
-    # Arch specific constant
-    O_ACCMODE = None
-    O_CLOEXEC = None
-    O_DIRECTORY = None
-    O_LARGEFILE = None
-    O_NONBLOCK = None
-    O_RDONLY = None
-
-    def __init__(self):
-        stdin = FileDescriptorSTDIN(0)
-        stdout = FileDescriptorSTDOUT(1)
-        stderr = FileDescriptorSTDERR(2)
-        for std in [stdin, stdout, stderr]:
-            std.uid = self.user_uid
-            std.gid = self.user_gid
-        self.file_descriptors = {
-            0: stdin,
-            1: stdout,
-            2: stderr,
-        }
-        self.ioctl_allowed = [
-            (0, termios.TCGETS),
-            (0, termios.TIOCGWINSZ),
-            (0, termios.TIOCSWINSZ),
-            (1, termios.TCGETS),
-            (1, termios.TIOCGWINSZ),
-            (1, termios.TIOCSWINSZ),
-        ]
-        self.ioctl_disallowed = [
-            (2, termios.TCGETS),
-            (0, termios.TCSETSW),
-        ]
-        self.filesystem = FileSystem(self.filesystem_base, self)
-        self.network = Networking(self)
-
-    def next_fd(self):
-        return len(self.file_descriptors)
-
-    def clock_gettime(self):
-        out = self.base_time
-        self.base_time += 1
-        return out
-
-    def open_(self, path, flags, follow_link=True):
-        """Stub for 'open' syscall"""
-        return self.filesystem.open_(path, flags, follow_link=follow_link)
-
-    def socket(self, family, type_, protocol):
-        """Stub for 'socket' syscall"""
-        return self.network.socket(family, type_, protocol)
-
-    def fstat(self, fd):
-        """Get file status through fd"""
-        fdesc = self.file_descriptors.get(fd)
-        if fdesc is None:
-            return None
-        return fdesc.stat()
-
-    def stat(self, path):
-        """Get file status through path"""
-        return self.filesystem.getattr_(path)
-
-    def lstat(self, path):
-        """Get file status through path (not following links)"""
-        return self.filesystem.getattr_(path, follow_link=False)
-
-    def close(self, fd):
-        """Stub for 'close' syscall"""
-        fdesc = self.file_descriptors.get(fd)
-        if fdesc is None:
-            return None
-        return fdesc.close()
-
-    def write(self, fd, data):
-        """Stub for 'write' syscall"""
-        fdesc = self.file_descriptors.get(fd)
-        if fdesc is None:
-            return None
-        fdesc.write(data)
-        return len(data)
-
-    def read(self, fd, count):
-        """Stub for 'read' syscall"""
-        fdesc = self.file_descriptors.get(fd)
-        if fdesc is None:
-            return None
-        return fdesc.read(count)
-
-    def getdents(self, fd, count, packing_callback):
-        """Stub for 'getdents' syscall
-
-        'getdents64' must be handled by caller (only the structure layout is
-        modified)
-
-        @fd: getdents' fd argument
-        @count: getdents' count argument
-        @packing_callback(cur_len, d_ino, d_type, name) -> entry
-        """
-        fdesc = self.file_descriptors[fd]
-        if not isinstance(fdesc, FileDescriptorDirectory):
-            raise RuntimeError("Not implemented")
-
-        out = b""
-        # fdesc.listdir continues from where it stopped
-        for name in fdesc.listdir():
-            d_ino = 1 # Not the real one
-            d_type = 0 # DT_UNKNOWN (getdents(2) "All applications must properly
-                       # handle a return of DT_UNKNOWN.")
-            entry = packing_callback(len(out), d_ino, d_type, name)
-
-            if len(out) + len(entry) > count:
-                # Report to a further call
-                fdesc.cur_listdir.append(name)
-                break
-            out = out + entry
-        return out
-
-    def ioctl(self, fd, cmd, arg):
-        """Stub for 'ioctl' syscall
-        Return the list of element to pack back depending on target ioctl
-        If the ioctl is disallowed, return False
-        """
-        allowed = False
-        disallowed = False
-        for test in [(fd, cmd), (None, cmd), (fd, None)]:
-            if test in self.ioctl_allowed:
-                allowed = True
-            if test in self.ioctl_disallowed:
-                disallowed = True
-
-        if allowed and disallowed:
-            raise ValueError("fd: %x, cmd: %x is allowed and disallowed" % (fd, cmd))
-
-        if allowed:
-            if cmd == termios.TCGETS:
-                return 0, 0, 0, 0
-            elif cmd == termios.TIOCGWINSZ:
-                # struct winsize
-                # {
-                #   unsigned short ws_row;	/* rows, in characters */
-                #   unsigned short ws_col;	/* columns, in characters */
-                #   unsigned short ws_xpixel;	/* horizontal size, pixels */
-                #   unsigned short ws_ypixel;	/* vertical size, pixels */
-                # };
-                return 1000, 360, 1000, 1000
-            elif cmd == termios.TIOCSWINSZ:
-                # Ignore it
-                return
-            else:
-                raise RuntimeError("Not implemented")
-
-        elif disallowed:
-            return False
-
-        else:
-            raise KeyError("Unknown ioctl fd:%x cmd:%x" % (fd, cmd))
-
-    def mmap(self, addr, len_, prot, flags, fd, off, vmmngr):
-        """Stub for 'mmap' syscall
-
-        'mmap2' must be implemented by calling this function with off * 4096
-        """
-        if addr == 0:
-            addr = self.mmap_current
-            self.mmap_current += (len_ + 0x1000) & ~0xfff
-
-        all_mem = vmmngr.get_all_memory()
-        mapped = interval(
-            [
-                (start, start + info["size"] - 1)
-                for start, info in viewitems(all_mem)
-            ]
-        )
-
-        MAP_FIXED = 0x10
-        if flags & MAP_FIXED:
-            # Alloc missing and override
-            missing = interval([(addr, addr + len_ - 1)]) - mapped
-            for start, stop in missing:
-                vmmngr.add_memory_page(
-                    start,
-                    PAGE_READ|PAGE_WRITE,
-                    b"\x00" * (stop - start + 1),
-                    "mmap allocated"
-                )
-        else:
-            # Find first candidate segment nearby addr
-            for start, stop in mapped:
-                if stop < addr:
-                    continue
-                rounded = (stop + 1 + 0x1000) & ~0xfff
-                if (interval([(rounded, rounded + len_)]) & mapped).empty:
-                    addr = rounded
-                    break
-            else:
-                assert (interval([(addr, addr + len_)]) & mapped).empty
-
-            vmmngr.add_memory_page(
-                addr,
-                PAGE_READ|PAGE_WRITE,
-                b"\x00" * len_,
-                "mmap allocated"
-            )
-
-        if fd == 0xffffffff:
-            MAP_ANONYMOUS = 0x20    # mman.h
-            # fd and offset are ignored if MAP_ANONYMOUS flag is present
-            if not(flags & MAP_ANONYMOUS) and off != 0:
-                raise RuntimeError("Not implemented")
-            data = b"\x00" * len_
-        else:
-            fdesc = self.file_descriptors[fd]
-            cur_pos = fdesc.tell()
-            fdesc.seek(off)
-            data = fdesc.read(len_)
-            fdesc.seek(cur_pos)
-
-        vmmngr.set_mem(addr, data)
-        return addr
-
-    def brk(self, addr, vmmngr):
-        """Stub for 'brk' syscall"""
-        if addr == 0:
-            addr = self.brk_current
-        else:
-            all_mem = vmmngr.get_all_memory()
-            mapped = interval(
-                [
-                    (start, start + info["size"] - 1)
-                    for start, info in viewitems(all_mem)
-                ]
-            )
-
-            # Alloc missing and override
-            missing = interval([(self.brk_current, addr)]) - mapped
-            for start, stop in missing:
-                vmmngr.add_memory_page(
-                    start,
-                    PAGE_READ|PAGE_WRITE,
-                    b"\x00" * (stop - start + 1),
-                    "BRK"
-                )
-
-            self.brk_current = addr
-        return addr
-
-
-class LinuxEnvironment_x86_32(LinuxEnvironment):
-    platform_arch = b"x86_32"
-    sys_machine = b"x86_32"
-
-    # TODO FIXME
-    ## O_ACCMODE = 0x3
-    ## O_CLOEXEC = 0x80000
-    ## O_DIRECTORY = 0x10000
-    ## O_LARGEFILE = 0x8000
-    ## O_NONBLOCK = 0x800
-    ## O_RDONLY = 0
-
-
-class LinuxEnvironment_x86_64(LinuxEnvironment):
-    platform_arch = b"x86_64"
-    sys_machine = b"x86_64"
-
-    O_ACCMODE = 0x3
-    O_CLOEXEC = 0x80000
-    O_DIRECTORY = 0x10000
-    O_LARGEFILE = 0x8000
-    O_NONBLOCK = 0x800
-    O_RDONLY = 0
-
-
-class LinuxEnvironment_arml(LinuxEnvironment):
-    platform_arch = b"arml"
-    sys_machine = b"arml"
-
-    O_ACCMODE = 0x3
-    O_CLOEXEC = 0x80000
-    O_DIRECTORY = 0x4000
-    O_LARGEFILE = 0x20000
-    O_NONBLOCK = 0x800
-    O_RDONLY = 0
-
-    # ARM specific
-    tls = 0
-    # get_tls: __kuser_helper_version >= 1
-    # cmpxchg: __kuser_helper_version >= 2
-    # memory_barrier: __kuser_helper_version >= 3
-    kuser_helper_version = 3
-
-
-class LinuxEnvironment_mips32b(LinuxEnvironment):
-    platform_arch = b"mips32b"
-    sys_machine = b"mips32b"
-
-
-class AuxVec(object):
-    """Auxiliary vector abstraction, filled with default values
-    (mainly based on https://lwn.net/Articles/519085)
-
-    # Standard usage
-    >>> auxv = AuxVec(elf_base_addr, cont_target.entry_point, linux_env)
-
-    # Enable AT_SECURE
-    >>> auxv = AuxVec(..., AuxVec.AT_SECURE=1)
-    # Modify AT_RANDOM
-    >>> auxv = AuxVec(..., AuxVec.AT_RANDOM="\x00"*0x10)
-
-    # Using AuxVec instance for stack preparation
-    # First, fill memory with vectors data
-    >>> for AT_number, data in auxv.data_to_map():
-            dest_ptr = ...
-            copy_to_dest(data, dest_ptr)
-            auxv.ptrs[AT_number] = dest_ptr
-    # Then, get the key: value (with value being sometime a pointer)
-    >>> for auxid, auxval in auxv.iteritems():
-            ...
-    """
-
-    AT_PHDR = 3
-    AT_PHNUM = 5
-    AT_PAGESZ = 6
-    AT_ENTRY = 9
-    AT_UID = 11
-    AT_EUID = 12
-    AT_GID = 13
-    AT_EGID = 14
-    AT_PLATFORM = 15
-    AT_HWCAP = 16
-    AT_SECURE = 23
-    AT_RANDOM = 25
-    AT_SYSINFO_EHDR = 33
-
-    def __init__(self, elf_phdr_vaddr, entry_point, linux_env, **kwargs):
-        """Instantiate an AuxVec, with required elements:
-        - elf_phdr_vaddr: virtual address of the ELF's PHDR in memory
-        - entry_point: virtual address of the ELF entry point
-        - linux_env: LinuxEnvironment instance, used to provides some of the
-          option values
-
-        Others options can be overridden by named arguments
-
-        """
-        self.info = {
-            self.AT_PHDR: elf_phdr_vaddr,
-            self.AT_PHNUM: 9,
-            self.AT_PAGESZ: 0x1000,
-            self.AT_ENTRY: entry_point,
-            self.AT_UID: linux_env.user_uid,
-            self.AT_EUID: linux_env.user_euid,
-            self.AT_GID: linux_env.user_gid,
-            self.AT_EGID: linux_env.user_egid,
-            self.AT_PLATFORM: linux_env.platform_arch,
-            self.AT_HWCAP: 0,
-            self.AT_SECURE: 0,
-            self.AT_RANDOM: b"\x00" * 0x10,
-            # vDSO is not mandatory
-            self.AT_SYSINFO_EHDR: None,
-        }
-        self.info.update(kwargs)
-        self.ptrs = {} # info key -> corresponding virtual address
-
-    def data_to_map(self):
-        """Iterator on (AT_number, data)
-        Once the data has been mapped, the corresponding ptr must be set in
-        'self.ptrs[AT_number]'
-        """
-        for AT_number in [self.AT_PLATFORM, self.AT_RANDOM]:
-            yield (AT_number, self.info[AT_number])
-
-    def iteritems(self):
-        """Iterator on auxiliary vector id and values"""
-        for AT_number, value in viewitems(self.info):
-            if AT_number in self.ptrs:
-                value = self.ptrs[AT_number]
-            if value is None:
-                # AT to ignore
-                continue
-            yield (AT_number, value)
-
-    items = iteritems
-
-def prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env,
-                          hlt_address=0x13371acc):
-    """Fill the environment with enough information to run a linux loader
-
-    @jitter: Jitter instance
-    @argv: list of strings
-    @envp: dict of environment variables names to their values
-    @auxv: AuxVec instance
-    @hlt_address (default to 0x13371acc): stopping address
-
-    Example of use:
-    >>> jitter = machine.jitter()
-    >>> jitter.init_stack()
-    >>> linux_env = LinuxEnvironment_x86_64()
-    >>> argv = ["/bin/ls", "-lah"]
-    >>> envp = {"PATH": "/usr/local/bin", "USER": linux_env.user_name}
-    >>> auxv = AuxVec(elf_base_addr, entry_point, linux_env)
-    >>> prepare_loader_x86_64(jitter, argv, envp, auxv, linux_env)
-    # One may want to enable syscall handling here
-    # The program can now run from the loader
-    >>> jitter.init_run(ld_entry_point)
-    >>> jitter.continue_run()
-    """
-    # Stack layout looks like
-    # [data]
-    #  - auxv values
-    #  - envp name=value
-    #  - argv arguments
-    # [auxiliary vector]
-    # [environment pointer]
-    # [argument vector]
-
-    for AT_number, data in auxv.data_to_map():
-        data += b"\x00"
-        jitter.cpu.RSP -= len(data)
-        ptr = jitter.cpu.RSP
-        jitter.vm.set_mem(ptr, data)
-        auxv.ptrs[AT_number] = ptr
-
-    env_ptrs = []
-    for name, value in viewitems(envp):
-        env = b"%s=%s\x00" % (name, value)
-        jitter.cpu.RSP -= len(env)
-        ptr = jitter.cpu.RSP
-        jitter.vm.set_mem(ptr, env)
-        env_ptrs.append(ptr)
-
-    argv_ptrs = []
-    for arg in argv:
-        arg += b"\x00"
-        jitter.cpu.RSP -= len(arg)
-        ptr = jitter.cpu.RSP
-        jitter.vm.set_mem(ptr, arg)
-        argv_ptrs.append(ptr)
-
-    jitter.push_uint64_t(hlt_address)
-    jitter.push_uint64_t(0)
-    jitter.push_uint64_t(0)
-    for auxid, auxval in viewitems(auxv):
-        jitter.push_uint64_t(auxval)
-        jitter.push_uint64_t(auxid)
-    jitter.push_uint64_t(0)
-    for ptr in reversed(env_ptrs):
-        jitter.push_uint64_t(ptr)
-    jitter.push_uint64_t(0)
-    for ptr in reversed(argv_ptrs):
-        jitter.push_uint64_t(ptr)
-    jitter.push_uint64_t(len(argv))
-
-
-
-def _arml__kuser_get_tls(linux_env, jitter):
-    # __kuser_get_tls
-    jitter.pc = jitter.cpu.LR
-    jitter.cpu.R0 = linux_env.tls
-    return True
-
-def _arml__kuser_cmpxchg(jitter):
-    oldval = jitter.cpu.R0
-    newval = jitter.cpu.R1
-    ptr = jitter.cpu.R2
-
-    value = struct.unpack("<I", jitter.vm.get_mem(ptr, 4))[0]
-    if value == oldval:
-        jitter.vm.set_mem(ptr, struct.pack("<I", newval))
-        jitter.cpu.R0 = 0
-        jitter.cpu.cf = 1
-    else:
-        jitter.cpu.R0 = -1
-        jitter.cpu.cf = 0
-
-    jitter.pc = jitter.cpu.LR
-    return True
-
-def _arml__kuser_memory_barrier(jitter):
-    # __kuser_memory_barrier
-    jitter.pc = jitter.cpu.LR
-    return True
-
-def _arml__kuser_helper_version(linux_env, jitter):
-    jitter.pc = jitter.cpu.LR
-    jitter.cpu.R0 = linux_env.kuser_helper_version
-    return True
-
-
-def prepare_loader_arml(jitter, argv, envp, auxv, linux_env,
-                        hlt_address=0x13371acc):
-    """Fill the environment with enough information to run a linux loader
-
-    @jitter: Jitter instance
-    @argv: list of strings
-    @envp: dict of environment variables names to their values
-    @auxv: AuxVec instance
-    @hlt_address (default to 0x13371acc): stopping address
-
-    Example of use:
-    >>> jitter = machine.jitter()
-    >>> jitter.init_stack()
-    >>> linux_env = LinuxEnvironment_arml()
-    >>> argv = ["/bin/ls", "-lah"]
-    >>> envp = {"PATH": "/usr/local/bin", "USER": linux_env.user_name}
-    >>> auxv = AuxVec(elf_base_addr, entry_point, linux_env)
-    >>> prepare_loader_arml(jitter, argv, envp, auxv, linux_env)
-    # One may want to enable syscall handling here
-    # The program can now run from the loader
-    >>> jitter.init_run(ld_entry_point)
-    >>> jitter.continue_run()
-    """
-    # Stack layout looks like
-    # [data]
-    #  - auxv values
-    #  - envp name=value
-    #  - argv arguments
-    # [auxiliary vector]
-    # [environment pointer]
-    # [argument vector]
-
-    for AT_number, data in auxv.data_to_map():
-        data += b"\x00"
-        jitter.cpu.SP -= len(data)
-        ptr = jitter.cpu.SP
-        jitter.vm.set_mem(ptr, data)
-        auxv.ptrs[AT_number] = ptr
-
-    env_ptrs = []
-    for name, value in viewitems(envp):
-        env = b"%s=%s\x00" % (name, value)
-        jitter.cpu.SP -= len(env)
-        ptr = jitter.cpu.SP
-        jitter.vm.set_mem(ptr, env)
-        env_ptrs.append(ptr)
-
-    argv_ptrs = []
-    for arg in argv:
-        arg += b"\x00"
-        jitter.cpu.SP -= len(arg)
-        ptr = jitter.cpu.SP
-        jitter.vm.set_mem(ptr, arg)
-        argv_ptrs.append(ptr)
-
-    jitter.push_uint32_t(hlt_address)
-    jitter.push_uint32_t(0)
-    jitter.push_uint32_t(0)
-    for auxid, auxval in viewitems(auxv):
-        jitter.push_uint32_t(auxval)
-        jitter.push_uint32_t(auxid)
-    jitter.push_uint32_t(0)
-    for ptr in reversed(env_ptrs):
-        jitter.push_uint32_t(ptr)
-    jitter.push_uint32_t(0)
-    for ptr in reversed(argv_ptrs):
-        jitter.push_uint32_t(ptr)
-    jitter.push_uint32_t(len(argv))
-
-    # Add kernel user helpers
-    # from Documentation/arm/kernel_user_helpers.txt
-
-    if linux_env.kuser_helper_version >= 1:
-        jitter.add_breakpoint(
-            0xFFFF0FE0,
-            functools.partial(_arml__kuser_get_tls, linux_env)
-        )
-
-    if linux_env.kuser_helper_version >= 2:
-        jitter.add_breakpoint(0XFFFF0FC0, _arml__kuser_cmpxchg)
-
-    if linux_env.kuser_helper_version >= 3:
-        jitter.add_breakpoint(0xFFFF0FA0, _arml__kuser_memory_barrier)
-
-    jitter.add_breakpoint(0xffff0ffc, _arml__kuser_helper_version)
diff --git a/miasm/os_dep/linux/syscall.py b/miasm/os_dep/linux/syscall.py
deleted file mode 100644
index bbaae1bc..00000000
--- a/miasm/os_dep/linux/syscall.py
+++ /dev/null
@@ -1,1129 +0,0 @@
-from builtins import range
-import fcntl
-import functools
-import logging
-import struct
-import termios
-
-from miasm.jitter.csts import EXCEPT_INT_XX, EXCEPT_SYSCALL
-from miasm.core.utils import pck64
-
-log = logging.getLogger('syscalls')
-hnd = logging.StreamHandler()
-hnd.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s"))
-log.addHandler(hnd)
-log.setLevel(logging.WARNING)
-
-
-def _dump_struct_stat_x86_64(info):
-    data = struct.pack(
-        "QQQIIIIQQQQQQQQQQQQQ",
-        info.st_dev,
-        info.st_ino,
-        info.st_nlink,
-        info.st_mode,
-        info.st_uid,
-        info.st_gid,
-        0, # 32 bit padding
-        info.st_rdev,
-        info.st_size,
-        info.st_blksize,
-        info.st_blocks,
-        info.st_atime,
-        info.st_atimensec,
-        info.st_mtime,
-        info.st_mtimensec,
-        info.st_ctime,
-        info.st_ctimensec,
-        0, # unused
-        0, # unused
-        0, # unused
-    )
-    return data
-
-
-def _dump_struct_stat_arml(info):
-    data = struct.pack(
-        "QIIIIIIIIIIIIIIIIII",
-        info.st_dev,
-        0, # pad
-        info.st_ino,
-        info.st_mode,
-        info.st_nlink,
-        info.st_uid,
-        info.st_gid,
-        info.st_rdev,
-        info.st_size,
-        info.st_blksize,
-        info.st_blocks,
-        info.st_atime,
-        info.st_atimensec,
-        info.st_mtime,
-        info.st_mtimensec,
-        info.st_ctime,
-        info.st_ctimensec,
-        0, # unused
-        0, # unused
-    )
-    return data
-
-
-def sys_x86_64_rt_sigaction(jitter, linux_env):
-    # Parse arguments
-    sig, act, oact, sigsetsize = jitter.syscall_args_systemv(4)
-    log.debug("sys_rt_sigaction(%x, %x, %x, %x)", sig, act, oact, sigsetsize)
-
-    # Stub
-    if oact != 0:
-        # Return an empty old action
-        jitter.vm.set_mem(oact, b"\x00" * sigsetsize)
-    jitter.syscall_ret_systemv(0)
-
-
-def sys_generic_brk(jitter, linux_env):
-    # Parse arguments
-    addr, = jitter.syscall_args_systemv(1)
-    log.debug("sys_brk(%d)", addr)
-
-    # Stub
-    jitter.syscall_ret_systemv(linux_env.brk(addr, jitter.vm))
-
-
-def sys_x86_32_newuname(jitter, linux_env):
-    # struct utsname {
-    #     char sysname[];    /* Operating system name (e.g., "Linux") */
-    #     char nodename[];   /* Name within "some implementation-defined
-    #                            network" */
-    #     char release[];    /* Operating system release (e.g., "2.6.28") */
-    #     char version[];    /* Operating system version */
-    #     char machine[];    /* Hardware identifier */
-    # }
-
-    # Parse arguments
-    nameptr, = jitter.syscall_args_systemv(1)
-    log.debug("sys_newuname(%x)", nameptr)
-
-    # Stub
-    info = [
-        linux_env.sys_sysname,
-        linux_env.sys_nodename,
-        linux_env.sys_release,
-        linux_env.sys_version,
-        linux_env.sys_machine
-    ]
-    # TODO: Elements start at 0x41 multiples on my tests...
-    output = b""
-    for elem in info:
-        output += elem
-        output += b"\x00" * (0x41 - len(elem))
-    jitter.vm.set_mem(nameptr, output)
-    jitter.syscall_ret_systemv(0)
-
-
-def sys_x86_64_newuname(jitter, linux_env):
-    # struct utsname {
-    #     char sysname[];    /* Operating system name (e.g., "Linux") */
-    #     char nodename[];   /* Name within "some implementation-defined
-    #                            network" */
-    #     char release[];    /* Operating system release (e.g., "2.6.28") */
-    #     char version[];    /* Operating system version */
-    #     char machine[];    /* Hardware identifier */
-    # }
-
-    # Parse arguments
-    nameptr, = jitter.syscall_args_systemv(1)
-    log.debug("sys_newuname(%x)", nameptr)
-
-    # Stub
-    info = [
-        linux_env.sys_sysname,
-        linux_env.sys_nodename,
-        linux_env.sys_release,
-        linux_env.sys_version,
-        linux_env.sys_machine
-    ]
-    # TODO: Elements start at 0x41 multiples on my tests...
-    output = b""
-    for elem in info:
-        output += elem
-        output += b"\x00" * (0x41 - len(elem))
-    jitter.vm.set_mem(nameptr, output)
-    jitter.syscall_ret_systemv(0)
-
-
-def sys_arml_newuname(jitter, linux_env):
-    # struct utsname {
-    #     char sysname[];    /* Operating system name (e.g., "Linux") */
-    #     char nodename[];   /* Name within "some implementation-defined
-    #                            network" */
-    #     char release[];    /* Operating system release (e.g., "2.6.28") */
-    #     char version[];    /* Operating system version */
-    #     char machine[];    /* Hardware identifier */
-    # }
-
-    # Parse arguments
-    nameptr, = jitter.syscall_args_systemv(1)
-    log.debug("sys_newuname(%x)", nameptr)
-
-    # Stub
-    info = [
-        linux_env.sys_sysname,
-        linux_env.sys_nodename,
-        linux_env.sys_release,
-        linux_env.sys_version,
-        linux_env.sys_machine
-    ]
-    # TODO: Elements start at 0x41 multiples on my tests...
-    output = b""
-    for elem in info:
-        output += elem
-        output += b"\x00" * (0x41 - len(elem))
-    jitter.vm.set_mem(nameptr, output)
-    jitter.syscall_ret_systemv(0)
-
-
-def sys_generic_access(jitter, linux_env):
-    # Parse arguments
-    pathname, mode = jitter.syscall_args_systemv(2)
-    rpathname = jitter.get_c_str(pathname)
-    rmode = mode
-    if mode == 1:
-        rmode = "F_OK"
-    elif mode == 2:
-        rmode = "R_OK"
-    log.debug("sys_access(%s, %s)", rpathname, rmode)
-
-    # Stub
-    # Do not check the mode
-    if linux_env.filesystem.exists(rpathname):
-        jitter.syscall_ret_systemv(0)
-    else:
-        jitter.syscall_ret_systemv(-1)
-
-
-def sys_x86_64_openat(jitter, linux_env):
-    # Parse arguments
-    dfd, filename, flags, mode = jitter.syscall_args_systemv(4)
-    rpathname = jitter.get_c_str(filename)
-    log.debug("sys_openat(%x, %r, %x, %x)", dfd, rpathname, flags, mode)
-
-    # Stub
-    # flags, openat particularity over 'open' are ignored
-    jitter.syscall_ret_systemv(linux_env.open_(rpathname, flags))
-
-
-def sys_x86_64_newstat(jitter, linux_env):
-    # Parse arguments
-    filename, statbuf = jitter.syscall_args_systemv(2)
-    rpathname = jitter.get_c_str(filename)
-    log.debug("sys_newstat(%r, %x)", rpathname, statbuf)
-
-    # Stub
-    if linux_env.filesystem.exists(rpathname):
-        info = linux_env.stat(rpathname)
-        data = _dump_struct_stat_x86_64(info)
-        jitter.vm.set_mem(statbuf, data)
-        jitter.syscall_ret_systemv(0)
-    else:
-        # ENOENT (No such file or directory)
-        jitter.syscall_ret_systemv(-1)
-
-
-def sys_arml_stat64(jitter, linux_env):
-    # Parse arguments
-    filename, statbuf = jitter.syscall_args_systemv(2)
-    rpathname = jitter.get_c_str(filename)
-    log.debug("sys_newstat(%r, %x)", rpathname, statbuf)
-
-    # Stub
-    if linux_env.filesystem.exists(rpathname):
-        info = linux_env.stat(rpathname)
-        data = _dump_struct_stat_arml(info)
-        jitter.vm.set_mem(statbuf, data)
-        jitter.syscall_ret_systemv(0)
-    else:
-        # ENOENT (No such file or directory)
-        jitter.syscall_ret_systemv(-1)
-
-
-def sys_x86_64_writev(jitter, linux_env):
-    # Parse arguments
-    fd, vec, vlen = jitter.syscall_args_systemv(3)
-    log.debug("sys_writev(%d, %d, %x)", fd, vec, vlen)
-
-    # Stub
-    fdesc = linux_env.file_descriptors[fd]
-    for iovec_num in range(vlen):
-        # struct iovec {
-        #    void  *iov_base;    /* Starting address */
-        #    size_t iov_len;     /* Number of bytes to transfer */
-        # };
-        iovec = jitter.vm.get_mem(vec + iovec_num * 8 * 2, 8*2)
-        iov_base, iov_len = struct.unpack("QQ", iovec)
-        fdesc.write(jitter.get_c_str(iov_base)[:iov_len])
-
-    jitter.syscall_ret_systemv(vlen)
-
-
-def sys_arml_writev(jitter, linux_env):
-    # Parse arguments
-    fd, vec, vlen = jitter.syscall_args_systemv(3)
-    log.debug("sys_writev(%d, %d, %x)", fd, vec, vlen)
-
-    # Stub
-    fdesc = linux_env.file_descriptors[fd]
-    for iovec_num in range(vlen):
-        # struct iovec {
-        #    void  *iov_base;    /* Starting address */
-        #    size_t iov_len;     /* Number of bytes to transfer */
-        # };
-        iovec = jitter.vm.get_mem(vec + iovec_num * 4 * 2, 4*2)
-        iov_base, iov_len = struct.unpack("II", iovec)
-        fdesc.write(jitter.get_c_str(iov_base)[:iov_len])
-
-    jitter.syscall_ret_systemv(vlen)
-
-
-def sys_generic_exit_group(jitter, linux_env):
-    # Parse arguments
-    status, = jitter.syscall_args_systemv(1)
-    log.debug("sys_exit_group(%d)", status)
-
-    # Stub
-    log.debug("Exit with status code %d", status)
-    jitter.running = False
-
-
-def sys_generic_read(jitter, linux_env):
-    # Parse arguments
-    fd, buf, count = jitter.syscall_args_systemv(3)
-    log.debug("sys_read(%d, %x, %x)", fd, buf, count)
-
-    # Stub
-    data = linux_env.read(fd, count)
-    jitter.vm.set_mem(buf, data)
-    jitter.syscall_ret_systemv(len(data))
-
-
-def sys_x86_64_fstat(jitter, linux_env):
-    # Parse arguments
-    fd, statbuf = jitter.syscall_args_systemv(2)
-    log.debug("sys_fstat(%d, %x)", fd, statbuf)
-
-    # Stub
-    info = linux_env.fstat(fd)
-    data = _dump_struct_stat_x86_64(info)
-    jitter.vm.set_mem(statbuf, data)
-    jitter.syscall_ret_systemv(0)
-
-
-def sys_arml_fstat64(jitter, linux_env):
-    # Parse arguments
-    fd, statbuf = jitter.syscall_args_systemv(2)
-    log.debug("sys_fstat(%d, %x)", fd, statbuf)
-
-    # Stub
-    info = linux_env.fstat(fd)
-    data = _dump_struct_stat_arml(info)
-    jitter.vm.set_mem(statbuf, data)
-    jitter.syscall_ret_systemv(0)
-
-
-def sys_generic_mmap(jitter, linux_env):
-    # Parse arguments
-    addr, len_, prot, flags, fd, off = jitter.syscall_args_systemv(6)
-    log.debug("sys_mmap(%x, %x, %x, %x, %x, %x)", addr, len_, prot, flags, fd, off)
-
-    # Stub
-    addr = linux_env.mmap(addr, len_, prot & 0xFFFFFFFF, flags & 0xFFFFFFFF,
-                          fd & 0xFFFFFFFF, off, jitter.vm)
-    jitter.syscall_ret_systemv(addr)
-
-
-def sys_generic_mmap2(jitter, linux_env):
-    # Parse arguments
-    addr, len_, prot, flags, fd, off = jitter.syscall_args_systemv(6)
-    log.debug("sys_mmap2(%x, %x, %x, %x, %x, %x)", addr, len_, prot, flags, fd, off)
-    off = off * 4096
-
-    # Stub
-    addr = linux_env.mmap(addr, len_, prot & 0xFFFFFFFF, flags & 0xFFFFFFFF,
-                          fd & 0xFFFFFFFF, off, jitter.vm)
-    jitter.syscall_ret_systemv(addr)
-
-
-def sys_generic_mprotect(jitter, linux_env):
-    # Parse arguments
-    start, len_, prot = jitter.syscall_args_systemv(3)
-    assert jitter.vm.is_mapped(start, len_)
-    log.debug("sys_mprotect(%x, %x, %x)", start, len_, prot)
-
-    # Do nothing
-    jitter.syscall_ret_systemv(0)
-
-
-def sys_generic_close(jitter, linux_env):
-    # Parse arguments
-    fd, = jitter.syscall_args_systemv(1)
-    log.debug("sys_close(%x)", fd)
-
-    # Stub
-    linux_env.close(fd)
-    jitter.syscall_ret_systemv(0)
-
-
-def sys_x86_64_arch_prctl(jitter, linux_env):
-    # Parse arguments
-    code_name = {
-        0x1001: "ARCH_SET_GS",
-        0x1002: "ARCH_SET_FS",
-        0x1003: "ARCH_GET_FS",
-        0x1004: "ARCH_GET_GS",
-        0x1011: "ARCH_GET_CPUID",
-        0x1012: "ARCH_SET_CPUID",
-        0x2001: "ARCH_MAP_VDSO_X32",
-        0x2002: "ARCH_MAP_VDSO_32",
-        0x2003: "ARCH_MAP_VDSO_64",
-        0x3001: "ARCH_CET_STATUS",
-        0x3002: "ARCH_CET_DISABLE",
-        0x3003: "ARCH_CET_LOCK",
-        0x3004: "ARCH_CET_EXEC",
-        0x3005: "ARCH_CET_ALLOC_SHSTK",
-        0x3006: "ARCH_CET_PUSH_SHSTK",
-        0x3007: "ARCH_CET_LEGACY_BITMAP",
-    }
-    code = jitter.cpu.RDI
-    rcode = code_name[code]
-    addr = jitter.cpu.RSI
-    log.debug("sys_arch_prctl(%s, %x)", rcode, addr)
-
-    if code == 0x1002:
-        jitter.cpu.set_segm_base(jitter.cpu.FS, addr)
-    elif code == 0x3001:
-        # CET status (disabled)
-        jitter.vm.set_mem(addr, pck64(0))
-    else:
-        raise RuntimeError("Not implemented")
-    jitter.cpu.RAX = 0
-
-
-def sys_x86_64_set_tid_address(jitter, linux_env):
-    # Parse arguments
-    tidptr = jitter.cpu.RDI
-    # clear_child_tid = tidptr
-    log.debug("sys_set_tid_address(%x)", tidptr)
-
-    jitter.cpu.RAX = linux_env.process_tid
-
-
-def sys_x86_64_set_robust_list(jitter, linux_env):
-    # Parse arguments
-    head = jitter.cpu.RDI
-    len_ = jitter.cpu.RSI
-    # robust_list = head
-    log.debug("sys_set_robust_list(%x, %x)", head, len_)
-    jitter.cpu.RAX = 0
-
-def sys_x86_64_rt_sigprocmask(jitter, linux_env):
-    # Parse arguments
-    how = jitter.cpu.RDI
-    nset = jitter.cpu.RSI
-    oset = jitter.cpu.RDX
-    sigsetsize = jitter.cpu.R10
-    log.debug("sys_rt_sigprocmask(%x, %x, %x, %x)", how, nset, oset, sigsetsize)
-    if oset != 0:
-        raise RuntimeError("Not implemented")
-    jitter.cpu.RAX = 0
-
-
-def sys_x86_64_prlimit64(jitter, linux_env):
-    # Parse arguments
-    pid = jitter.cpu.RDI
-    resource = jitter.cpu.RSI
-    new_rlim = jitter.cpu.RDX
-    if new_rlim != 0:
-        raise RuntimeError("Not implemented")
-    old_rlim = jitter.cpu.R10
-    log.debug("sys_prlimit64(%x, %x, %x, %x)", pid, resource, new_rlim,
-              old_rlim)
-
-    # Stub
-    if resource == 3:
-        # RLIMIT_STACK
-        jitter.vm.set_mem(old_rlim,
-                          struct.pack("QQ",
-                                      0x100000,
-                                      0x7fffffffffffffff, # RLIM64_INFINITY
-                          ))
-    else:
-        raise RuntimeError("Not implemented")
-    jitter.cpu.RAX = 0
-
-
-def sys_x86_64_statfs(jitter, linux_env):
-    # Parse arguments
-    pathname = jitter.cpu.RDI
-    buf = jitter.cpu.RSI
-    rpathname = jitter.get_c_str(pathname)
-    log.debug("sys_statfs(%r, %x)", rpathname, buf)
-
-    # Stub
-    if not linux_env.filesystem.exists(rpathname):
-        jitter.cpu.RAX = -1
-    else:
-        info = linux_env.filesystem.statfs()
-        raise RuntimeError("Not implemented")
-
-
-def sys_x86_64_ioctl(jitter, linux_env):
-    # Parse arguments
-    fd, cmd, arg = jitter.syscall_args_systemv(3)
-    log.debug("sys_ioctl(%x, %x, %x)", fd, cmd, arg)
-
-    info = linux_env.ioctl(fd, cmd, arg)
-    if info is False:
-        jitter.syscall_ret_systemv(-1)
-    else:
-        if cmd == termios.TCGETS:
-            data = struct.pack("BBBB", *info)
-            jitter.vm.set_mem(arg, data)
-        elif cmd == termios.TIOCGWINSZ:
-            data = struct.pack("HHHH", *info)
-            jitter.vm.set_mem(arg, data)
-        else:
-            assert data is None
-        jitter.syscall_ret_systemv(0)
-
-
-def sys_arml_ioctl(jitter, linux_env):
-    # Parse arguments
-    fd, cmd, arg = jitter.syscall_args_systemv(3)
-    log.debug("sys_ioctl(%x, %x, %x)", fd, cmd, arg)
-
-    info = linux_env.ioctl(fd, cmd, arg)
-    if info is False:
-        jitter.syscall_ret_systemv(-1)
-    else:
-        if cmd == termios.TCGETS:
-            data = struct.pack("BBBB", *info)
-            jitter.vm.set_mem(arg, data)
-        elif cmd == termios.TIOCGWINSZ:
-            data = struct.pack("HHHH", *info)
-            jitter.vm.set_mem(arg, data)
-        else:
-            assert data is None
-        jitter.syscall_ret_systemv(0)
-
-def sys_generic_open(jitter, linux_env):
-    # Parse arguments
-    filename, flags, mode = jitter.syscall_args_systemv(3)
-    rpathname = jitter.get_c_str(filename)
-    log.debug("sys_open(%r, %x, %x)", rpathname, flags, mode)
-    # Stub
-    # 'mode' is ignored
-    jitter.syscall_ret_systemv(linux_env.open_(rpathname, flags))
-
-
-def sys_generic_write(jitter, linux_env):
-    # Parse arguments
-    fd, buf, count = jitter.syscall_args_systemv(3)
-    log.debug("sys_write(%d, %x, %x)", fd, buf, count)
-
-    # Stub
-    data = jitter.vm.get_mem(buf, count)
-    jitter.syscall_ret_systemv(linux_env.write(fd, data))
-
-
-def sys_x86_64_getdents(jitter, linux_env):
-    # Parse arguments
-    fd = jitter.cpu.RDI
-    dirent = jitter.cpu.RSI
-    count = jitter.cpu.RDX
-    log.debug("sys_getdents(%x, %x, %x)", fd, dirent, count)
-
-    # Stub
-    def packing_callback(cur_len, d_ino, d_type, name):
-        # struct linux_dirent {
-        #        unsigned long  d_ino;     /* Inode number */
-        #        unsigned long  d_off;     /* Offset to next linux_dirent */
-        #        unsigned short d_reclen;  /* Length of this linux_dirent */
-        #        char           d_name[];  /* Filename (null-terminated) */
-        #                          /* length is actually (d_reclen - 2 -
-        #                             offsetof(struct linux_dirent, d_name)) */
-        #        /*
-        #        char           pad;       // Zero padding byte
-        #        char           d_type;    // File type (only since Linux
-        #                                  // 2.6.4); offset is (d_reclen - 1)
-        #        */
-        #    }
-        d_reclen = 8 * 2 + 2 + 1 + len(name) + 1
-        d_off = cur_len + d_reclen
-        entry = struct.pack("QqH", d_ino, d_off, d_reclen) + \
-                name.encode("utf8") + b"\x00" + struct.pack("B", d_type)
-        assert len(entry) == d_reclen
-        return entry
-
-    out = linux_env.getdents(fd, count, packing_callback)
-    jitter.vm.set_mem(dirent, out)
-    jitter.cpu.RAX = len(out)
-
-
-def sys_arml_getdents64(jitter, linux_env):
-    # Parse arguments
-    fd = jitter.cpu.R0
-    dirent = jitter.cpu.R1
-    count = jitter.cpu.R2
-    log.debug("sys_getdents64(%x, %x, %x)", fd, dirent, count)
-
-    # Stub
-    def packing_callback(cur_len, d_ino, d_type, name):
-        # struct linux_dirent64 {
-        #        ino64_t        d_ino;    /* 64-bit inode number */
-        #        off64_t        d_off;    /* 64-bit offset to next structure */
-        #        unsigned short d_reclen; /* Size of this dirent */
-        #        unsigned char  d_type;   /* File type */
-        #        char           d_name[]; /* Filename (null-terminated) */
-        #    };
-        d_reclen = 8 * 2 + 2 + 1 + len(name) + 1
-        d_off = cur_len + d_reclen
-        entry = struct.pack("QqHB", d_ino, d_off, d_reclen, d_type) + \
-                name + b"\x00"
-        assert len(entry) == d_reclen
-        return entry
-
-    out = linux_env.getdents(fd, count, packing_callback)
-    jitter.vm.set_mem(dirent, out)
-    jitter.cpu.R0 = len(out)
-
-
-def sys_x86_64_newlstat(jitter, linux_env):
-    # Parse arguments
-    filename = jitter.cpu.RDI
-    statbuf = jitter.cpu.RSI
-    rpathname = jitter.get_c_str(filename)
-    log.debug("sys_newlstat(%s, %x)", rpathname, statbuf)
-
-    # Stub
-    if not linux_env.filesystem.exists(rpathname):
-        # ENOENT (No such file or directory)
-        jitter.cpu.RAX = -1
-    else:
-        info = linux_env.lstat(rpathname)
-        data = _dump_struct_stat_x86_64(info)
-        jitter.vm.set_mem(statbuf, data)
-        jitter.cpu.RAX = 0
-
-
-def sys_arml_lstat64(jitter, linux_env):
-    # Parse arguments
-    filename = jitter.cpu.R0
-    statbuf = jitter.cpu.R1
-    rpathname = jitter.get_c_str(filename)
-    log.debug("sys_newlstat(%s, %x)", rpathname, statbuf)
-
-    # Stub
-    if not linux_env.filesystem.exists(rpathname):
-        # ENOENT (No such file or directory)
-        jitter.cpu.R0 = -1
-    else:
-        info = linux_env.lstat(rpathname)
-        data = _dump_struct_stat_arml(info)
-        jitter.vm.set_mem(statbuf, data)
-        jitter.cpu.R0 = 0
-
-
-def sys_x86_64_lgetxattr(jitter, linux_env):
-    # Parse arguments
-    pathname = jitter.cpu.RDI
-    name = jitter.cpu.RSI
-    value = jitter.cpu.RDX
-    size = jitter.cpu.R10
-    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
-    jitter.vm.set_mem(value, b"\x00" * size)
-    jitter.cpu.RAX = 0
-
-
-def sys_x86_64_getxattr(jitter, linux_env):
-    # Parse arguments
-    pathname = jitter.cpu.RDI
-    name = jitter.cpu.RSI
-    value = jitter.cpu.RDX
-    size = jitter.cpu.R10
-    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
-    jitter.vm.set_mem(value, b"\x00" * size)
-    jitter.cpu.RAX = 0
-
-
-def sys_x86_64_socket(jitter, linux_env):
-    # Parse arguments
-    family = jitter.cpu.RDI
-    type_ = jitter.cpu.RSI
-    protocol = jitter.cpu.RDX
-    log.debug("sys_socket(%x, %x, %x)", family, type_, protocol)
-
-    jitter.cpu.RAX = linux_env.socket(family, type_, protocol)
-
-
-def sys_x86_64_connect(jitter, linux_env):
-    # Parse arguments
-    fd = jitter.cpu.RDI
-    uservaddr = jitter.cpu.RSI
-    addrlen = jitter.cpu.RDX
-    raddr = jitter.get_c_str(uservaddr + 2)
-    log.debug("sys_connect(%x, %r, %x)", fd, raddr, addrlen)
-
-    # Stub
-    # Always refuse the connection
-    jitter.cpu.RAX = -1
-
-
-def sys_x86_64_clock_gettime(jitter, linux_env):
-    # Parse arguments
-    which_clock = jitter.cpu.RDI
-    tp = jitter.cpu.RSI
-    log.debug("sys_clock_gettime(%x, %x)", which_clock, tp)
-
-    # Stub
-    value = linux_env.clock_gettime()
-    jitter.vm.set_mem(tp, struct.pack("Q", value))
-    jitter.cpu.RAX = 0
-
-
-def sys_x86_64_lseek(jitter, linux_env):
-    # Parse arguments
-    fd = jitter.cpu.RDI
-    offset = jitter.cpu.RSI
-    whence = jitter.cpu.RDX
-    log.debug("sys_lseek(%d, %x, %x)", fd, offset, whence)
-
-    # Stub
-    fdesc = linux_env.file_descriptors[fd]
-    mask = (1 << 64) - 1
-    if offset > (1 << 63):
-        offset = - ((offset ^ mask) + 1)
-
-    new_offset = fdesc.lseek(offset, whence)
-    jitter.cpu.RAX = new_offset
-
-
-def sys_x86_64_munmap(jitter, linux_env):
-    # Parse arguments
-    addr = jitter.cpu.RDI
-    len_ = jitter.cpu.RSI
-    log.debug("sys_munmap(%x, %x)", addr, len_)
-
-    # Do nothing
-    jitter.cpu.RAX = 0
-
-
-def sys_x86_64_readlink(jitter, linux_env):
-    # Parse arguments
-    path = jitter.cpu.RDI
-    buf = jitter.cpu.RSI
-    bufsize = jitter.cpu.RDX
-    rpath = jitter.get_c_str(path)
-    log.debug("sys_readlink(%r, %x, %x)", rpath, buf, bufsize)
-
-    # Stub
-    link = linux_env.filesystem.readlink(rpath)
-    if link is None:
-        # Not a link
-        jitter.cpu.RAX = -1
-    else:
-        data = link[:bufsize - 1] + b"\x00"
-        jitter.vm.set_mem(buf, data)
-        jitter.cpu.RAX = len(data) - 1
-
-def sys_x86_64_getpid(jitter, linux_env):
-    # Parse arguments
-    log.debug("sys_getpid()")
-
-    # Stub
-    jitter.cpu.RAX = linux_env.process_pid
-
-
-def sys_x86_64_sysinfo(jitter, linux_env):
-    # Parse arguments
-    info = jitter.cpu.RDI
-    log.debug("sys_sysinfo(%x)", info)
-
-    # Stub
-    data = struct.pack("QQQQQQQQQQHQQI",
-                       0x1234, # uptime
-                       0x2000, # loads (1 min)
-                       0x2000, # loads (5 min)
-                       0x2000, # loads (15 min)
-                       0x10000000, # total ram
-                       0x10000000, # free ram
-                       0x10000000, # shared memory
-                       0x0, # memory used by buffers
-                       0x0, # total swap
-                       0x0, # free swap
-                       0x1, # nb current processes
-                       0x0, # total high mem
-                       0x0, # available high mem
-                       0x1, # memory unit size
-    )
-    jitter.vm.set_mem(info, data)
-    jitter.cpu.RAX = 0
-
-
-def sys_generic_geteuid(jitter, linux_env):
-    # Parse arguments
-    log.debug("sys_geteuid()")
-
-    # Stub
-    jitter.syscall_ret_systemv(linux_env.user_euid)
-
-
-def sys_generic_getegid(jitter, linux_env):
-    # Parse arguments
-    log.debug("sys_getegid()")
-
-    # Stub
-    jitter.syscall_ret_systemv(linux_env.user_egid)
-
-
-def sys_generic_getuid(jitter, linux_env):
-    # Parse arguments
-    log.debug("sys_getuid()")
-
-    # Stub
-    jitter.syscall_ret_systemv(linux_env.user_uid)
-
-
-def sys_generic_getgid(jitter, linux_env):
-    # Parse arguments
-    log.debug("sys_getgid()")
-
-    # Stub
-    jitter.syscall_ret_systemv(linux_env.user_gid)
-
-
-def sys_generic_setgid(jitter, linux_env):
-    # Parse arguments
-    gid, = jitter.syscall_args_systemv(1)
-    log.debug("sys_setgid(%x)", gid)
-
-    # Stub
-    # Denied if different
-    if gid != linux_env.user_gid:
-        jitter.syscall_ret_systemv(-1)
-    else:
-        jitter.syscall_ret_systemv(0)
-
-
-def sys_generic_setuid(jitter, linux_env):
-    # Parse arguments
-    uid, = jitter.syscall_args_systemv(1)
-    log.debug("sys_setuid(%x)", uid)
-
-    # Stub
-    # Denied if different
-    if uid != linux_env.user_uid:
-        jitter.syscall_ret_systemv(-1)
-    else:
-        jitter.syscall_ret_systemv(0)
-
-
-def sys_arml_set_tls(jitter, linux_env):
-    # Parse arguments
-    ptr = jitter.cpu.R0
-    log.debug("sys_set_tls(%x)", ptr)
-
-    # Stub
-    linux_env.tls = ptr
-    jitter.cpu.R0 = 0
-
-
-def sys_generic_fcntl64(jitter, linux_env):
-    # Parse arguments
-    fd, cmd, arg = jitter.syscall_args_systemv(3)
-    log.debug("sys_fcntl(%x, %x, %x)", fd, cmd, arg)
-
-    # Stub
-    fdesc = linux_env.file_descriptors[fd]
-    if cmd == fcntl.F_GETFL:
-        jitter.syscall_ret_systemv(fdesc.flags)
-    elif cmd == fcntl.F_SETFL:
-        # Ignore flag change
-        jitter.syscall_ret_systemv(0)
-    elif cmd == fcntl.F_GETFD:
-        jitter.syscall_ret_systemv(fdesc.flags)
-    elif cmd == fcntl.F_SETFD:
-        # Ignore flag change
-        jitter.syscall_ret_systemv(0)
-    else:
-        raise RuntimeError("Not implemented")
-
-
-def sys_x86_64_pread64(jitter, linux_env):
-    # Parse arguments
-    fd = jitter.cpu.RDI
-    buf = jitter.cpu.RSI
-    count = jitter.cpu.RDX
-    pos = jitter.cpu.R10
-    log.debug("sys_pread64(%x, %x, %x, %x)", fd, buf, count, pos)
-
-    # Stub
-    fdesc = linux_env.file_descriptors[fd]
-    cur_pos = fdesc.tell()
-    fdesc.seek(pos)
-    data = fdesc.read(count)
-    jitter.vm.set_mem(buf, data)
-    fdesc.seek(cur_pos)
-    jitter.cpu.RAX = len(data)
-
-
-def sys_arml_gettimeofday(jitter, linux_env):
-    # Parse arguments
-    tv = jitter.cpu.R0
-    tz = jitter.cpu.R1
-    log.debug("sys_gettimeofday(%x, %x)", tv, tz)
-
-    # Stub
-    value = linux_env.clock_gettime()
-    if tv:
-        jitter.vm.set_mem(tv, struct.pack("II", value, 0))
-    if tz:
-        jitter.vm.set_mem(tz, struct.pack("II", 0, 0))
-    jitter.cpu.R0 = 0
-
-
-def sys_mips32b_socket(jitter, linux_env):
-    # Parse arguments
-    family, type_, protocol = jitter.syscall_args_systemv(3)
-    log.debug("sys_socket(%x, %x, %x)", family, type_, protocol)
-
-    ret1 = linux_env.socket(family, type_, protocol)
-    jitter.syscall_ret_systemv(ret1, 0, 0)
-
-
-syscall_callbacks_x86_32 = {
-    0x7A: sys_x86_32_newuname,
-}
-
-
-syscall_callbacks_x86_64 = {
-    0x0: sys_generic_read,
-    0x1: sys_generic_write,
-    0x2: sys_generic_open,
-    0x3: sys_generic_close,
-    0x4: sys_x86_64_newstat,
-    0x5: sys_x86_64_fstat,
-    0x6: sys_x86_64_newlstat,
-    0x8: sys_x86_64_lseek,
-    0x9: sys_generic_mmap,
-    0x10: sys_x86_64_ioctl,
-    0xA: sys_generic_mprotect,
-    0xB: sys_x86_64_munmap,
-    0xC: sys_generic_brk,
-    0xD: sys_x86_64_rt_sigaction,
-    0xE: sys_x86_64_rt_sigprocmask,
-    0x11: sys_x86_64_pread64,
-    0x14: sys_x86_64_writev,
-    0x15: sys_generic_access,
-    0x27: sys_x86_64_getpid,
-    0x29: sys_x86_64_socket,
-    0x2A: sys_x86_64_connect,
-    0x3F: sys_x86_64_newuname,
-    0x48: sys_generic_fcntl64,
-    0x4E: sys_x86_64_getdents,
-    0x59: sys_x86_64_readlink,
-    0x63: sys_x86_64_sysinfo,
-    0x66: sys_generic_getuid,
-    0x68: sys_generic_getgid,
-    0x6B: sys_generic_geteuid,
-    0x6C: sys_generic_getegid,
-    0xE4: sys_x86_64_clock_gettime,
-    0x89: sys_x86_64_statfs,
-    0x9E: sys_x86_64_arch_prctl,
-    0xBF: sys_x86_64_getxattr,
-    0xC0: sys_x86_64_lgetxattr,
-    0xDA: sys_x86_64_set_tid_address,
-    0xE7: sys_generic_exit_group,
-    0x101: sys_x86_64_openat,
-    0x111: sys_x86_64_set_robust_list,
-    0x12E: sys_x86_64_prlimit64,
-}
-
-
-syscall_callbacks_arml = {
-
-    0x3: sys_generic_read,
-    0x4: sys_generic_write,
-    0x5: sys_generic_open,
-    0x6: sys_generic_close,
-    0x2d: sys_generic_brk,
-    0x21: sys_generic_access,
-    0x36: sys_arml_ioctl,
-    0x7a: sys_arml_newuname,
-    0x7d: sys_generic_mprotect,
-    0x92: sys_arml_writev,
-    0xc0: sys_generic_mmap2,
-    0xc3: sys_arml_stat64,
-    0xc4: sys_arml_lstat64,
-    0xc5: sys_arml_fstat64,
-    0xc7: sys_generic_getuid,
-    0xc8: sys_generic_getgid,
-    0xc9: sys_generic_geteuid,
-    0xcA: sys_generic_getegid,
-    0x4e: sys_arml_gettimeofday,
-    0xd5: sys_generic_setuid,
-    0xd6: sys_generic_setgid,
-    0xd9: sys_arml_getdents64,
-    0xdd: sys_generic_fcntl64,
-    0xf8: sys_generic_exit_group,
-
-    # ARM-specific ARM_NR_BASE == 0x0f0000
-    0xf0005: sys_arml_set_tls,
-}
-
-
-syscall_callbacks_mips32b = {
-    0x1057: sys_mips32b_socket,
-}
-
-def syscall_x86_64_exception_handler(linux_env, syscall_callbacks, jitter):
-    """Call to actually handle an EXCEPT_SYSCALL exception
-    In the case of an error raised by a SYSCALL, call the corresponding
-    syscall_callbacks
-    @linux_env: LinuxEnvironment_x86_64 instance
-    @syscall_callbacks: syscall number -> func(jitter, linux_env)
-    """
-
-    # Dispatch to SYSCALL stub
-    syscall_number = jitter.cpu.RAX
-    callback = syscall_callbacks.get(syscall_number)
-    if callback is None:
-        raise KeyError(
-            "No callback found for syscall number 0x%x" % syscall_number
-        )
-    callback(jitter, linux_env)
-    log.debug("-> %x", jitter.cpu.RAX)
-
-    # Clean exception and move pc to the next instruction, to let the jitter
-    # continue
-    jitter.cpu.set_exception(jitter.cpu.get_exception() ^ EXCEPT_SYSCALL)
-    return True
-
-
-
-def syscall_x86_32_exception_handler(linux_env, syscall_callbacks, jitter):
-    """Call to actually handle an EXCEPT_INT_XX exception
-    In the case of an error raised by a SYSCALL, call the corresponding
-    syscall_callbacks
-    @linux_env: LinuxEnvironment_x86_32 instance
-    @syscall_callbacks: syscall number -> func(jitter, linux_env)
-    """
-    # Ensure the jitter has break on a SYSCALL
-    if jitter.cpu.interrupt_num != 0x80:
-        return True
-
-    # Dispatch to SYSCALL stub
-    syscall_number = jitter.cpu.EAX
-    callback = syscall_callbacks.get(syscall_number)
-    if callback is None:
-        raise KeyError(
-            "No callback found for syscall number 0x%x" % syscall_number
-        )
-    callback(jitter, linux_env)
-    log.debug("-> %x", jitter.cpu.EAX)
-
-    # Clean exception and move pc to the next instruction, to let the jitter
-    # continue
-    jitter.cpu.set_exception(jitter.cpu.get_exception() ^ EXCEPT_INT_XX)
-    return True
-
-
-
-def syscall_arml_exception_handler(linux_env, syscall_callbacks, jitter):
-    """Call to actually handle an EXCEPT_PRIV_INSN exception
-    In the case of an error raised by a SYSCALL, call the corresponding
-    syscall_callbacks
-    @linux_env: LinuxEnvironment_arml instance
-    @syscall_callbacks: syscall number -> func(jitter, linux_env)
-    """
-    # Ensure the jitter has break on a SYSCALL
-    if jitter.cpu.interrupt_num != 0x0:
-        return True
-
-    # Dispatch to SYSCALL stub
-    syscall_number = jitter.cpu.R7
-    callback = syscall_callbacks.get(syscall_number)
-    if callback is None:
-        raise KeyError(
-            "No callback found for syscall number 0x%x" % syscall_number
-        )
-    callback(jitter, linux_env)
-    log.debug("-> %x", jitter.cpu.R0)
-
-    # Clean exception and move pc to the next instruction, to let the jitter
-    # continue
-    jitter.cpu.set_exception(jitter.cpu.get_exception() ^ EXCEPT_INT_XX)
-    return True
-
-
-
-def syscall_mips32b_exception_handler(linux_env, syscall_callbacks, jitter):
-    """Call to actually handle an EXCEPT_SYSCALL exception
-    In the case of an error raised by a SYSCALL, call the corresponding
-    syscall_callbacks
-    @linux_env: LinuxEnvironment_mips32b instance
-    @syscall_callbacks: syscall number -> func(jitter, linux_env)
-    """
-
-    # Dispatch to SYSCALL stub
-    syscall_number = jitter.cpu.V0
-    callback = syscall_callbacks.get(syscall_number)
-    if callback is None:
-        raise KeyError(
-            "No callback found for syscall number 0x%x" % syscall_number
-        )
-    callback(jitter, linux_env)
-    log.debug("-> %x", jitter.cpu.V0)
-
-    # Clean exception and move pc to the next instruction, to let the jitter
-    # continue
-    jitter.cpu.set_exception(jitter.cpu.get_exception() ^ EXCEPT_SYSCALL)
-    return True
-
-
-
-def enable_syscall_handling(jitter, linux_env, syscall_callbacks):
-    """Activate handling of syscall for the current jitter instance.
-    Syscall handlers are provided by @syscall_callbacks
-    @linux_env: LinuxEnvironment instance
-    @syscall_callbacks: syscall number -> func(jitter, linux_env)
-
-    Example of use:
-    >>> linux_env = LinuxEnvironment_x86_64()
-    >>> enable_syscall_handling(jitter, linux_env, syscall_callbacks_x86_64)
-    """
-    arch_name = jitter.jit.arch_name
-    if arch_name == "x8664":
-        handler = syscall_x86_64_exception_handler
-        handler = functools.partial(handler, linux_env, syscall_callbacks)
-        jitter.add_exception_handler(EXCEPT_SYSCALL, handler)
-    elif arch_name == "x8632":
-        handler = syscall_x86_32_exception_handler
-        handler = functools.partial(handler, linux_env, syscall_callbacks)
-        jitter.add_exception_handler(EXCEPT_INT_XX, handler)
-    elif arch_name == "arml":
-        handler = syscall_arml_exception_handler
-        handler = functools.partial(handler, linux_env, syscall_callbacks)
-        jitter.add_exception_handler(EXCEPT_INT_XX, handler)
-    elif arch_name == "mips32b":
-        handler = syscall_mips32b_exception_handler
-        handler = functools.partial(handler, linux_env, syscall_callbacks)
-        jitter.add_exception_handler(EXCEPT_SYSCALL, handler)
-    else:
-        raise ValueError("No syscall handler implemented for %s" % arch_name)
diff --git a/miasm/os_dep/linux_stdlib.py b/miasm/os_dep/linux_stdlib.py
deleted file mode 100644
index f0c708ba..00000000
--- a/miasm/os_dep/linux_stdlib.py
+++ /dev/null
@@ -1,213 +0,0 @@
-#-*- coding:utf-8 -*-
-
-from __future__ import print_function
-import struct
-from sys import stdout
-
-try:
-    # Python3 binary stdout
-    stdout = stdout.buffer
-except AttributeError:
-    pass
-
-from miasm.core.utils import int_to_byte, cmp_elts
-from miasm.os_dep.common import heap
-from miasm.os_dep.common import get_fmt_args as _get_fmt_args
-
-
-class c_linobjs(object):
-
-    base_addr = 0x20000000
-    align_addr = 0x1000
-    def __init__(self):
-        self.alloc_ad = self.base_addr
-        self.alloc_align = self.align_addr
-        self.heap = heap()
-
-linobjs = c_linobjs()
-
-ABORT_ADDR = 0x1337beef
-
-def xxx___libc_start_main(jitter):
-    """Basic implementation of __libc_start_main
-
-    int __libc_start_main(int *(main) (int, char * *, char * *), int argc,
-                          char * * ubp_av, void (*init) (void),
-                          void (*fini) (void), void (*rtld_fini) (void),
-                          void (* stack_end));
-
-    Note:
-     - init, fini, rtld_fini are ignored
-     - return address is forced to ABORT_ADDR, to avoid calling abort/hlt/...
-     - in powerpc, signature is:
-
-    int __libc_start_main (int argc, char **argv, char **ev, ElfW (auxv_t) *
-                       auxvec, void (*rtld_fini) (void), struct startup_info
-                       *stinfo, char **stack_on_entry)
-
-    """
-    global ABORT_ADDR
-    if jitter.arch.name == "ppc32":
-        ret_ad, args = jitter.func_args_systemv(
-            ["argc", "argv", "ev", "aux_vec", "rtld_fini", "st_info",
-             "stack_on_entry"]
-        )
-
-        # Mimic glibc implementation
-        if args.stack_on_entry != 0:
-            argc = struct.unpack(">I",
-                                 jitter.vm.get_mem(args.stack_on_entry, 4))[0]
-            argv = args.stack_on_entry + 4
-            envp = argv + ((argc + 1) * 4)
-        else:
-            argc = args.argc
-            argv = args.argv
-            envp = args.ev
-        # sda_base, main, init, fini
-        _, main, _, _ = struct.unpack(">IIII",
-                                      jitter.vm.get_mem(args.st_info, 4 * 4))
-
-    else:
-        ret_ad, args = jitter.func_args_systemv(
-            ["main", "argc", "ubp_av", "init", "fini", "rtld_fini", "stack_end"]
-        )
-
-        main = args.main
-        # done by __libc_init_first
-        size = jitter.lifter.pc.size // 8
-        argc = args.argc
-        argv = args.ubp_av
-        envp = argv + (args.argc + 1) * size
-
-
-    # Call int main(int argc, char** argv, char** envp)
-    jitter.func_ret_systemv(main)
-    ret_ad = ABORT_ADDR
-    jitter.func_prepare_systemv(ret_ad, argc, argv, envp)
-    return True
-
-
-def xxx_isprint(jitter):
-    '''
-    #include <ctype.h>
-    int isprint(int c);
-
-    checks for any printable character including space.
-    '''
-    ret_addr, args = jitter.func_args_systemv(['c'])
-    ret = 1 if 0x20 <= args.c & 0xFF < 0x7f else 0
-    return jitter.func_ret_systemv(ret_addr, ret)
-
-
-def xxx_memcpy(jitter):
-    '''
-    #include <string.h>
-    void *memcpy(void *dest, const void *src, size_t n);
-
-    copies n bytes from memory area src to memory area dest.
-    '''
-    ret_addr, args = jitter.func_args_systemv(['dest', 'src', 'n'])
-    jitter.vm.set_mem(args.dest, jitter.vm.get_mem(args.src, args.n))
-    return jitter.func_ret_systemv(ret_addr, args.dest)
-
-
-def xxx_memset(jitter):
-    '''
-    #include <string.h>
-    void *memset(void *s, int c, size_t n);
-
-    fills the first n bytes of the memory area pointed to by s with the constant
-    byte c.'''
-
-    ret_addr, args = jitter.func_args_systemv(['dest', 'c', 'n'])
-    jitter.vm.set_mem(args.dest, int_to_byte(args.c & 0xFF) * args.n)
-    return jitter.func_ret_systemv(ret_addr, args.dest)
-
-
-def xxx_puts(jitter):
-    '''
-    #include <stdio.h>
-    int puts(const char *s);
-
-    writes the string s and a trailing newline to stdout.
-    '''
-    ret_addr, args = jitter.func_args_systemv(['s'])
-    index = args.s
-    char = jitter.vm.get_mem(index, 1)
-    while char != b'\x00':
-        stdout.write(char)
-        index += 1
-        char = jitter.vm.get_mem(index, 1)
-    stdout.write(b'\n')
-    return jitter.func_ret_systemv(ret_addr, 1)
-
-
-def get_fmt_args(jitter, fmt, cur_arg):
-    return _get_fmt_args(fmt, cur_arg, jitter.get_c_str, jitter.get_arg_n_systemv)
-
-
-def xxx_snprintf(jitter):
-    ret_addr, args = jitter.func_args_systemv(['string', 'size', 'fmt'])
-    cur_arg, fmt = 3, args.fmt
-    size = args.size if args.size else 1
-    output = get_fmt_args(jitter, fmt, cur_arg)
-    output = output[:size - 1]
-    ret = len(output)
-    jitter.set_c_str(args.string, output)
-    return jitter.func_ret_systemv(ret_addr, ret)
-
-
-def xxx_sprintf(jitter):
-    ret_addr, args = jitter.func_args_systemv(['string', 'fmt'])
-    cur_arg, fmt = 2, args.fmt
-    output = get_fmt_args(jitter, fmt, cur_arg)
-    ret = len(output)
-    jitter.set_c_str(args.string, output)
-    return jitter.func_ret_systemv(ret_addr, ret)
-
-
-def xxx_printf(jitter):
-    ret_addr, args = jitter.func_args_systemv(['fmt'])
-    cur_arg, fmt = 1, args.fmt
-    output = get_fmt_args(jitter, fmt, cur_arg)
-    ret = len(output)
-    stdout.write(output.encode('utf8'))
-    return jitter.func_ret_systemv(ret_addr, ret)
-
-
-def xxx_strcpy(jitter):
-    ret_ad, args = jitter.func_args_systemv(["dst", "src"])
-    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_c_str(args.src)
-    jitter.func_ret_systemv(ret_ad, len(str_src))
-
-
-def xxx_malloc(jitter):
-    ret_ad, args = jitter.func_args_systemv(["msize"])
-    addr = linobjs.heap.alloc(jitter, args.msize)
-    jitter.func_ret_systemv(ret_ad, addr)
-
-
-def xxx_free(jitter):
-    ret_ad, args = jitter.func_args_systemv(["ptr"])
-    jitter.func_ret_systemv(ret_ad, 0)
-
-
-def xxx_strcmp(jitter):
-    ret_ad, args = jitter.func_args_systemv(["ptr_str1", "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_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_32_structs.py b/miasm/os_dep/win_32_structs.py
deleted file mode 100644
index fc9c62ea..00000000
--- a/miasm/os_dep/win_32_structs.py
+++ /dev/null
@@ -1,231 +0,0 @@
-from miasm.core.types import MemStruct, Num, Ptr, Str, \
-    Array, RawStruct, Union, \
-    BitField, Self, Void, Bits, \
-    set_allocator, MemUnion, Struct
-
-
-class UnicodeString(MemStruct):
-    fields = [
-        ("length", Num("H")),
-        ("maxlength", Num("H")),
-        ("data", Ptr("<I", Str("utf16"))),
-    ]
-
-
-class ListEntry(MemStruct):
-    fields = [
-        ("flink", Ptr("<I", Void())),
-        ("blink", Ptr("<I", Void())),
-    ]
-
-
-class LdrDataEntry(MemStruct):
-
-    """
-    +0x000 InLoadOrderLinks : _LIST_ENTRY
-    +0x008 InMemoryOrderLinks : _LIST_ENTRY
-    +0x010 InInitializationOrderLinks : _LIST_ENTRY
-    +0x018 DllBase : Ptr32 Void
-    +0x01c EntryPoint : Ptr32 Void
-    +0x020 SizeOfImage : Uint4B
-    +0x024 FullDllName : _UNICODE_STRING
-    +0x02c BaseDllName : _UNICODE_STRING
-    +0x034 Flags : Uint4B
-    +0x038 LoadCount : Uint2B
-    +0x03a TlsIndex : Uint2B
-    +0x03c HashLinks : _LIST_ENTRY
-    +0x03c SectionPointer : Ptr32 Void
-    +0x040 CheckSum : Uint4B
-    +0x044 TimeDateStamp : Uint4B
-    +0x044 LoadedImports : Ptr32 Void
-    +0x048 EntryPointActivationContext : Ptr32 Void
-    +0x04c PatchInformation : Ptr32 Void
-    """
-
-    fields = [
-        ("InLoadOrderLinks", ListEntry),
-        ("InMemoryOrderLinks", ListEntry),
-        ("InInitializationOrderLinks", ListEntry),
-        ("DllBase", Ptr("<I", Void())),
-        ("EntryPoint", Ptr("<I", Void())),
-        ("SizeOfImage", Num("<I")),
-        ("FullDllName", UnicodeString),
-        ("BaseDllName", UnicodeString),
-        ("Flags", Array(Num("B"), 4)),
-        ("LoadCount", Num("H")),
-        ("TlsIndex", Num("H")),
-        ("union1", Union([
-            ("HashLinks", Ptr("<I", Void())),
-            ("SectionPointer", Ptr("<I", Void())),
-        ])),
-        ("CheckSum", Num("<I")),
-        ("union2", Union([
-            ("TimeDateStamp", Num("<I")),
-            ("LoadedImports", Ptr("<I", Void())),
-        ])),
-        ("EntryPointActivationContext", Ptr("<I", Void())),
-        ("PatchInformation", Ptr("<I", Void())),
-
-    ]
-
-
-class PEB_LDR_DATA(MemStruct):
-
-    """
-    +0x000 Length                          : Uint4B
-    +0x004 Initialized                     : UChar
-    +0x008 SsHandle                        : Ptr32 Void
-    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
-    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
-    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
-    """
-
-    fields = [
-        ("Length", Num("<I")),
-        ("Initialized", Num("<I")),
-        ("SsHandle", Ptr("<I", Void())),
-        ("InLoadOrderModuleList", ListEntry),
-        ("InMemoryOrderModuleList", ListEntry),
-        ("InInitializationOrderModuleList", ListEntry)
-    ]
-
-
-class PEB(MemStruct):
-
-    """
-    +0x000 InheritedAddressSpace    : UChar
-    +0x001 ReadImageFileExecOptions : UChar
-    +0x002 BeingDebugged            : UChar
-    +0x003 SpareBool                : UChar
-    +0x004 Mutant                   : Ptr32 Void
-    +0x008 ImageBaseAddress         : Ptr32 Void
-    +0x00c Ldr                      : Ptr32 _PEB_LDR_DATA
-    +0x010 processparameter
-    """
-
-    fields = [
-        ("InheritedAddressSpace", Num("B")),
-        ("ReadImageFileExecOptions", Num("B")),
-        ("BeingDebugged", Num("B")),
-        ("SpareBool", Num("B")),
-        ("Mutant", Ptr("<I", Void())),
-        ("ImageBaseAddress", Num("<I")),
-        ("Ldr", Ptr("<I", PEB_LDR_DATA)),
-    ]
-
-
-class EXCEPTION_REGISTRATION_RECORD(MemStruct):
-    """
-    +0x00 Next    : struct _EXCEPTION_REGISTRATION_RECORD *
-    +0x04 Handler : Ptr32 Void
-    """
-
-    fields = [
-        ("Next", Ptr("<I", Self())),
-        ("Handler", Ptr("<I", Void())),
-    ]
-
-
-class EXCEPTION_RECORD(MemStruct):
-    """
-    DWORD                    ExceptionCode;
-    DWORD                    ExceptionFlags;
-    struct _EXCEPTION_RECORD *ExceptionRecord;
-    PVOID                    ExceptionAddress;
-    DWORD                    NumberParameters;
-    ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
-    """
-    EXCEPTION_MAXIMUM_PARAMETERS = 15
-
-    fields = [
-        ("ExceptionCode", Num("<I")),
-        ("ExceptionFlags", Num("<I")),
-        ("ExceptionRecord", Ptr("<I", Self())),
-        ("ExceptionAddress", Ptr("<I", Void())),
-        ("NumberParameters", Num("<I")),
-        ("ExceptionInformation", Ptr("<I", Void())),
-    ]
-
-
-class NT_TIB(MemStruct):
-
-    """
-    +00 struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList
-    +04 void *StackBase
-    +08 void *StackLimit
-    +0c void *SubSystemTib
-    +10 void *FiberData
-    +10 uint32 Version
-    +14 void *ArbitraryUserPointer
-    +18 struct _NT_TIB *Self
-    """
-
-    fields = [
-        ("ExceptionList", Ptr("<I", EXCEPTION_REGISTRATION_RECORD)),
-        ("StackBase", Ptr("<I", Void())),
-        ("StackLimit", Ptr("<I", Void())),
-        ("SubSystemTib", Ptr("<I", Void())),
-        (None, Union([
-            ("FiberData", Ptr("<I", Void())),
-            ("Version", Num("<I"))
-        ])),
-        ("ArbitraryUserPointer", Ptr("<I", Void())),
-        ("Self", Ptr("<I", Self())),
-    ]
-
-
-class TEB(MemStruct):
-
-    """
-    +0x000 NtTib                     : _NT_TIB
-    +0x01c EnvironmentPointer        : Ptr32 Void
-    +0x020 ClientId                  : _CLIENT_ID
-    +0x028 ActiveRpcHandle           : Ptr32 Void
-    +0x02c ThreadLocalStoragePointer : Ptr32 Void
-    +0x030 ProcessEnvironmentBlock   : Ptr32 _PEB
-    +0x034 LastErrorValue            : Uint4B
-    ...
-    """
-
-    fields = [
-        ("NtTib", NT_TIB),
-        ("EnvironmentPointer", Ptr("<I", Void())),
-        ("ClientId", Array(Num("B"), 0x8)),
-        ("ActiveRpcHandle", Ptr("<I", Void())),
-        ("ThreadLocalStoragePointer", Ptr("<I", Void())),
-        ("ProcessEnvironmentBlock", Ptr("<I", PEB)),
-        ("LastErrorValue", Num("<I")),
-    ]
-
-
-class ContextException(MemStruct):
-    fields = [
-        ("ContextFlags", Num("<I")),
-        ("dr0", Num("<I")),
-        ("dr1", Num("<I")),
-        ("dr2", Num("<I")),
-        ("dr3", Num("<I")),
-        ("dr4", Num("<I")),
-        ("dr5", Num("<I")),
-
-        ("Float", Array(Num("B"), 112)),
-
-        ("gs", Num("<I")),
-        ("fs", Num("<I")),
-        ("es", Num("<I")),
-        ("ds", Num("<I")),
-
-        ("edi", Num("<I")),
-        ("esi", Num("<I")),
-        ("ebx", Num("<I")),
-        ("edx", Num("<I")),
-        ("ecx", Num("<I")),
-        ("eax", Num("<I")),
-        ("ebp", Num("<I")),
-        ("eip", Num("<I")),
-
-        ("cs", Num("<I")),
-        ("eflags", Num("<I")),
-        ("esp", Num("<I")),
-        ("ss", Num("<I")),
-    ]
diff --git a/miasm/os_dep/win_api_x86_32.py b/miasm/os_dep/win_api_x86_32.py
deleted file mode 100644
index 6e568abb..00000000
--- a/miasm/os_dep/win_api_x86_32.py
+++ /dev/null
@@ -1,3595 +0,0 @@
-from __future__ import print_function
-#
-# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-from past.builtins import cmp
-import struct
-import os
-import stat
-import time
-import string
-import logging
-from zlib import crc32
-from io import StringIO
-import time
-import datetime
-
-from future.utils import PY3, viewitems, viewvalues
-
-try:
-    from Crypto.Hash import MD5, SHA
-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, int_to_byte
-from miasm.os_dep.common import heap, windows_to_sbpath
-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")
-console_handler = logging.StreamHandler()
-console_handler.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s"))
-log.addHandler(console_handler)
-log.setLevel(logging.WARN)
-
-DATE_1601_TO_1970 = 116444736000000000
-
-MAX_PATH = 260
-
-
-"""
-typedef struct tagPROCESSENTRY32 {
-  DWORD     dwSize;
-  DWORD     cntUsage;
-  DWORD     th32ProcessID;
-  ULONG_PTR th32DefaultHeapID;
-  DWORD     th32ModuleID;
-  DWORD     cntThreads;
-  DWORD     th32ParentProcessID;
-  LONG      pcPriClassBase;
-  DWORD     dwFlags;
-  TCHAR     szExeFile[MAX_PATH];
-} PROCESSENTRY32, *PPROCESSENTRY32;
-"""
-
-
-ACCESS_DICT = {0x0: 0,
-               0x1: 0,
-               0x2: PAGE_READ,
-               0x4: PAGE_READ | PAGE_WRITE,
-               0x10: PAGE_EXEC,
-               0x20: PAGE_EXEC | PAGE_READ,
-               0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
-               0x80: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
-               # 0x80: PAGE_EXECUTE_WRITECOPY
-               0x100: 0
-               }
-
-ACCESS_DICT_INV = dict((x[1], x[0]) for x in viewitems(ACCESS_DICT))
-
-
-class whandle(object):
-
-    def __init__(self, name, info):
-        self.name = name
-        self.info = info
-
-    def __repr__(self):
-        return '<%r %r %r>' % (self.__class__.__name__, self.name, self.info)
-
-
-class handle_generator(object):
-
-    def __init__(self):
-        self.offset = 600
-        self.all_handles = {}
-
-    def add(self, name, info=None):
-        self.offset += 1
-        h = whandle(name, info)
-        self.all_handles[self.offset] = h
-
-        log.debug(repr(self))
-        return self.offset
-
-    def __repr__(self):
-        out = '<%r\n' % self.__class__.__name__
-        ks = list(self.all_handles)
-        ks.sort()
-
-        for k in ks:
-            out += "    %r %r\n" % (k, self.all_handles[k])
-        out += '>'
-        return out
-
-    def __contains__(self, e):
-        return e in self.all_handles
-
-    def __getitem__(self, item):
-        return self.all_handles.__getitem__(item)
-
-    def __delitem__(self, item):
-        self.all_handles.__delitem__(item)
-
-
-class c_winobjs(object):
-
-    def __init__(self):
-        self.alloc_ad = 0x20000000
-        self.alloc_align = 0x1000
-        self.heap = heap()
-        self.handle_toolhelpsnapshot = 0xaaaa00
-        self.toolhelpsnapshot_info = {}
-        self.handle_curprocess = 0xaaaa01
-        self.dbg_present = 0
-        self.tickcount = 0
-        self.dw_pid_dummy1 = 0x111
-        self.dw_pid_explorer = 0x222
-        self.dw_pid_dummy2 = 0x333
-        self.dw_pid_cur = 0x444
-        self.module_fname_nux = None
-        self.module_name = "test.exe"
-        self.module_path = "c:\\mydir\\" + self.module_name
-        self.hcurmodule = None
-        self.module_filesize = None
-        self.getversion = 0x0A280105
-        self.getforegroundwindow = 0x333333
-        self.cryptcontext_hwnd = 0x44400
-        self.cryptcontext_bnum = 0x44000
-        self.cryptcontext_num = 0
-        self.cryptcontext = {}
-        self.phhash_crypt_md5 = 0x55555
-        # key used by EncodePointer and DecodePointer
-        # (kernel32)
-        self.ptr_encode_key = 0xabababab
-        self.files_hwnd = {}
-        self.windowlong_dw = 0x77700
-        self.module_cur_hwnd = 0x88800
-        self.module_file_nul = 0x999000
-        self.runtime_dll = None
-        self.current_pe = None
-        self.tls_index = 0xf
-        self.tls_values = {}
-        self.handle_pool = handle_generator()
-        self.handle_mapped = {}
-        self.hkey_handles = {
-            0x80000001: b"hkey_current_user",
-            0x80000002: b"hkey_local_machine"
-        }
-        self.cur_dir = "c:\\tmp"
-
-        self.nt_mdl = {}
-        self.nt_mdl_ad = None
-        self.nt_mdl_cur = 0
-        self.win_event_num = 0x13370
-        self.cryptdll_md5_h = {}
-
-        self.lastwin32error = 0
-        self.mutex = {}
-        self.env_variables = {}
-        self.events_pool = {}
-        self.find_data = None
-
-        self.allocated_pages = {}
-        self.current_datetime = datetime.datetime(
-            year=2017, month=8, day=21,
-            hour=13, minute=37,
-            second=11, microsecond=123456
-        )
-
-winobjs = c_winobjs()
-
-
-process_list = [
-    [
-        0x40,  # DWORD     dwSize;
-        0,  # DWORD     cntUsage;
-        winobjs.dw_pid_dummy1,  # DWORD     th32ProcessID;
-        0x11111111,  # ULONG_PTR th32DefaultHeapID;
-        0x11111112,  # DWORD     th32ModuleID;
-        1,  # DWORD     cntThreads;
-        winobjs.dw_pid_explorer,  # DWORD     th32ParentProcessID;
-        0xbeef,  # LONG      pcPriClassBase;
-        0x0,  # DWORD     dwFlags;
-        "dummy1.exe"  # TCHAR     szExeFile[MAX_PATH];
-    ],
-    [
-        0x40,  # DWORD     dwSize;
-        0,  # DWORD     cntUsage;
-        winobjs.dw_pid_explorer,  # DWORD     th32ProcessID;
-        0x11111111,  # ULONG_PTR th32DefaultHeapID;
-        0x11111112,  # DWORD     th32ModuleID;
-        1,  # DWORD     cntThreads;
-        4,  # DWORD     th32ParentProcessID;
-        0xbeef,  # LONG      pcPriClassBase;
-        0x0,  # DWORD     dwFlags;
-        "explorer.exe"  # TCHAR     szExeFile[MAX_PATH];
-    ],
-
-    [
-        0x40,  # DWORD     dwSize;
-        0,  # DWORD     cntUsage;
-        winobjs.dw_pid_dummy2,  # DWORD     th32ProcessID;
-        0x11111111,  # ULONG_PTR th32DefaultHeapID;
-        0x11111112,  # DWORD     th32ModuleID;
-        1,  # DWORD     cntThreads;
-        winobjs.dw_pid_explorer,  # DWORD     th32ParentProcessID;
-        0xbeef,  # LONG      pcPriClassBase;
-        0x0,  # DWORD     dwFlags;
-        "dummy2.exe"  # TCHAR     szExeFile[MAX_PATH];
-    ],
-
-    [
-        0x40,  # DWORD     dwSize;
-        0,  # DWORD     cntUsage;
-        winobjs.dw_pid_cur,  # DWORD     th32ProcessID;
-        0x11111111,  # ULONG_PTR th32DefaultHeapID;
-        0x11111112,  # DWORD     th32ModuleID;
-        1,  # DWORD     cntThreads;
-        winobjs.dw_pid_explorer,  # DWORD     th32ParentProcessID;
-        0xbeef,  # LONG      pcPriClassBase;
-        0x0,  # DWORD     dwFlags;
-        winobjs.module_name  # TCHAR     szExeFile[MAX_PATH];
-    ],
-
-
-]
-
-
-class hobj(object):
-    pass
-
-
-class mdl(object):
-
-    def __init__(self, ad, l):
-        self.ad = ad
-        self.l = l
-
-    def __bytes__(self):
-        return struct.pack('LL', self.ad, self.l)
-
-    def __str__(self):
-        if PY3:
-            return repr(self)
-        return self.__bytes__()
-
-
-def kernel32_HeapAlloc(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["heap", "flags", "size"])
-    alloc_addr = winobjs.heap.alloc(jitter, args.size, cmt=hex(ret_ad))
-    jitter.func_ret_stdcall(ret_ad, alloc_addr)
-
-
-def kernel32_HeapFree(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["heap", "flags", "pmem"])
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_GlobalAlloc(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["uflags", "msize"])
-    alloc_addr = winobjs.heap.alloc(jitter, args.msize)
-    jitter.func_ret_stdcall(ret_ad, alloc_addr)
-
-
-def kernel32_LocalFree(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["lpvoid"])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_LocalAlloc(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["uflags", "msize"])
-    alloc_addr = winobjs.heap.alloc(jitter, args.msize)
-    jitter.func_ret_stdcall(ret_ad, alloc_addr)
-
-def msvcrt_new(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["size"])
-    alloc_addr = winobjs.heap.alloc(jitter, args.size)
-    jitter.func_ret_cdecl(ret_ad, alloc_addr)
-
-globals()['msvcrt_??2@YAPAXI@Z'] = msvcrt_new
-
-def msvcrt_delete(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["ptr"])
-    jitter.func_ret_cdecl(ret_ad, 0)
-
-globals()['msvcrt_??3@YAXPAX@Z'] = msvcrt_delete
-
-def kernel32_GlobalFree(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["addr"])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_IsDebuggerPresent(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, winobjs.dbg_present)
-
-
-def kernel32_CreateToolhelp32Snapshot(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["dwflags", "th32processid"])
-    jitter.func_ret_stdcall(ret_ad, winobjs.handle_toolhelpsnapshot)
-
-
-def kernel32_GetCurrentProcess(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, winobjs.handle_curprocess)
-
-
-def kernel32_GetCurrentProcessId(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, winobjs.dw_pid_cur)
-
-
-def kernel32_Process32First(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"])
-
-    pentry = struct.pack(
-        'IIIIIIIII', *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
-
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_Process32Next(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"])
-
-    winobjs.toolhelpsnapshot_info[args.s_handle] += 1
-    if winobjs.toolhelpsnapshot_info[args.s_handle] >= len(process_list):
-        ret = 0
-    else:
-        ret = 1
-        n = winobjs.toolhelpsnapshot_info[args.s_handle]
-        pentry = struct.pack(
-            '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)
-
-
-def kernel32_GetTickCount(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    winobjs.tickcount += 1
-    jitter.func_ret_stdcall(ret_ad, winobjs.tickcount)
-
-
-def kernel32_GetVersion(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, winobjs.getversion)
-
-
-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)
-    if size in [0x14+str_size, 0x1c+str_size]:
-        tmp = struct.pack(
-            "IIIII%dsHHHBB" % str_size,
-            0x114,            # struct size
-            0x5,              # maj vers
-            0x2,              # min vers
-            0xa28,            # build nbr
-            0x2,              # platform id
-            encode_str("Service pack 4"),
-            3,                # wServicePackMajor
-            0,                # wServicePackMinor
-            0x100,            # wSuiteMask
-            1,                # wProductType
-            0                 # wReserved
-        )
-        tmp = tmp[:size]
-        jitter.vm.set_mem(args.ptr_struct, tmp)
-        ret = 1
-    else:
-        ret = 0
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-kernel32_GetVersionExA = lambda jitter: kernel32_GetVersionEx(jitter, 128,
-                                                              encode_win_str_a)
-kernel32_GetVersionExW = lambda jitter: kernel32_GetVersionEx(jitter, 256,
-                                                              encode_win_str_w)
-
-
-def kernel32_GetPriorityClass(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["hwnd"])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_SetPriorityClass(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["hwnd", "dwpclass"])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_CloseHandle(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["hwnd"])
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-def kernel32_EncodePointer(jitter):
-    """
-        PVOID EncodePointer(
-            _In_ PVOID Ptr
-        );
-
-        Encoding globally available pointers helps protect them from being
-        exploited. The EncodePointer function obfuscates the pointer value
-        with a secret so that it cannot be predicted by an external agent.
-        The secret used by EncodePointer is different for each process.
-
-        A pointer must be decoded before it can be used.
-
-    """
-    ret, args = jitter.func_args_stdcall(1)
-    jitter.func_ret_stdcall(ret, args[0] ^ winobjs.ptr_encode_key)
-    return True
-
-def kernel32_DecodePointer(jitter):
-    """
-        PVOID DecodePointer(
-           PVOID Ptr
-        );
-
-        The function returns the decoded pointer.
-
-    """
-    ret, args = jitter.func_args_stdcall(1)
-    jitter.func_ret_stdcall(ret, args[0] ^ winobjs.ptr_encode_key)
-    return True
-
-def user32_GetForegroundWindow(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, winobjs.getforegroundwindow)
-
-
-def user32_FindWindowA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["pclassname", "pwindowname"])
-    if args.pclassname:
-        classname = get_win_str_a(jitter, args.pclassname)
-        log.info("FindWindowA classname %s", classname)
-    if args.pwindowname:
-        windowname = get_win_str_a(jitter, args.pwindowname)
-        log.info("FindWindowA windowname %s", windowname)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def user32_GetTopWindow(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["hwnd"])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def user32_BlockInput(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["blockit"])
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def advapi32_CryptAcquireContext(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["phprov", "pszcontainer",
-                                             "pszprovider", "dwprovtype",
-                                             "dwflags"])
-    prov = get_str(args.pszprovider) if args.pszprovider else "NONE"
-    log.debug('prov: %r', prov)
-    jitter.vm.set_u32(args.phprov, winobjs.cryptcontext_hwnd)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def advapi32_CryptAcquireContextA(jitter):
-    advapi32_CryptAcquireContext(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def advapi32_CryptAcquireContextW(jitter):
-    advapi32_CryptAcquireContext(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def advapi32_CryptCreateHash(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hprov", "algid", "hkey",
-                                             "dwflags", "phhash"])
-
-    winobjs.cryptcontext_num += 1
-
-    if args.algid == 0x00008003:
-        log.debug('algo is MD5')
-        jitter.vm.set_u32(
-            args.phhash,
-            winobjs.cryptcontext_bnum + winobjs.cryptcontext_num
-        )
-        winobjs.cryptcontext[
-            winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj()
-        winobjs.cryptcontext[
-            winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = MD5.new()
-    elif args.algid == 0x00008004:
-        log.debug('algo is SHA1')
-        jitter.vm.set_u32(
-            args.phhash,
-            winobjs.cryptcontext_bnum + winobjs.cryptcontext_num
-        )
-        winobjs.cryptcontext[
-            winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj()
-        winobjs.cryptcontext[
-            winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = SHA.new()
-    else:
-        raise ValueError('un impl algo1')
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def advapi32_CryptHashData(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hhash", "pbdata", "dwdatalen",
-                                             "dwflags"])
-
-    if not args.hhash in winobjs.cryptcontext:
-        raise ValueError("unknown crypt context")
-
-    data = jitter.vm.get_mem(args.pbdata, args.dwdatalen)
-    log.debug('will hash %X', args.dwdatalen)
-    log.debug(repr(data[:0x10]) + "...")
-    winobjs.cryptcontext[args.hhash].h.update(data)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def advapi32_CryptGetHashParam(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hhash", "param", "pbdata",
-                                             "dwdatalen", "dwflags"])
-
-    if not args.hhash in winobjs.cryptcontext:
-        raise ValueError("unknown crypt context")
-
-    if args.param == 2:
-        # HP_HASHVAL
-        # XXX todo: save h state?
-        h = winobjs.cryptcontext[args.hhash].h.digest()
-        jitter.vm.set_mem(args.pbdata, h)
-        jitter.vm.set_u32(args.dwdatalen, len(h))
-    elif args.param == 4:
-        # HP_HASHSIZE
-        ret = winobjs.cryptcontext[args.hhash].h.digest_size
-        jitter.vm.set_u32(args.pbdata, ret)
-        jitter.vm.set_u32(args.dwdatalen, 4)
-    else:
-        raise ValueError('not impl', args.param)
-
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def advapi32_CryptReleaseContext(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["hhash", "flags"])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def advapi32_CryptDeriveKey(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hprov", "algid", "hbasedata",
-                                             "dwflags", "phkey"])
-
-    if args.algid == 0x6801:
-        log.debug('using DES')
-    else:
-        raise ValueError('un impl algo2')
-    h = winobjs.cryptcontext[args.hbasedata].h.digest()
-    log.debug('hash %r', h)
-    winobjs.cryptcontext[args.hbasedata].h_result = h
-    jitter.vm.set_u32(args.phkey, args.hbasedata)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def advapi32_CryptDestroyHash(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["hhash"])
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def advapi32_CryptDecrypt(jitter):
-    # ret_ad, _ = jitter.func_args_stdcall(["hkey", "hhash", "final",
-    #                                       "dwflags", "pbdata",
-    #                                       "pdwdatalen"])
-    raise ValueError("Not implemented")
-    # jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_CreateFile(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["lpfilename", "access",
-                                             "dwsharedmode",
-                                             "lpsecurityattr",
-                                             "dwcreationdisposition",
-                                             "dwflagsandattr",
-                                             "htemplatefile"])
-    if args.lpfilename == 0:
-        jitter.func_ret_stdcall(ret_ad, 0xffffffff)
-        return
-
-    fname = get_str(args.lpfilename)
-    log.info('CreateFile fname %s', fname)
-    ret = 0xffffffff
-
-    log.debug("%r %r", fname.lower(), winobjs.module_path.lower())
-    is_original_file = fname.lower() == winobjs.module_path.lower()
-
-    if fname.upper() in [r"\\.\SICE", r"\\.\NTICE", r"\\.\SIWVID", r'\\.\SIWDEBUG']:
-        pass
-    elif fname.upper() in ['NUL']:
-        ret = winobjs.module_cur_hwnd
-    else:
-        # sandbox path
-        sb_fname = windows_to_sbpath(fname)
-        if args.access & 0x80000000 or args.access == 1:
-            # read and maybe write
-            if args.dwcreationdisposition == 2:
-                # create_always
-                if os.access(sb_fname, os.R_OK):
-                    # but file exist
-                    pass
-                else:
-                    raise NotImplementedError("Untested case")  # to test
-                    # h = open(sb_fname, 'rb+')
-            elif args.dwcreationdisposition == 3:
-                # open_existing
-                if os.access(sb_fname, os.R_OK):
-                    s = os.stat(sb_fname)
-                    if stat.S_ISDIR(s.st_mode):
-                        ret = winobjs.handle_pool.add(sb_fname, 0x1337)
-                    else:
-                        open_mode = 'rb'
-                        if (args.access & 0x40000000) or args.access == 2:
-                            open_mode = 'r+b'
-                        h = open(sb_fname, open_mode)
-                        ret = winobjs.handle_pool.add(sb_fname, h)
-                else:
-                    log.warning("FILE %r (%s) DOES NOT EXIST!", fname, sb_fname)
-            elif args.dwcreationdisposition == 1:
-                # create new
-                if os.access(sb_fname, os.R_OK):
-                    # file exist
-                    # ret = 80
-                    winobjs.lastwin32error = 80
-                else:
-                    # first create an empty file
-                    open(sb_fname, 'wb').close()
-                    # then open
-                    h = open(sb_fname, 'r+b')
-                    ret = winobjs.handle_pool.add(sb_fname, h)
-            elif args.dwcreationdisposition == 4:
-                # open_always
-                if os.access(sb_fname, os.R_OK):
-                    s = os.stat(sb_fname)
-                    if stat.S_ISDIR(s.st_mode):
-                        ret = winobjs.handle_pool.add(sb_fname, 0x1337)
-                    else:
-                        h = open(sb_fname, 'r+b')
-                        ret = winobjs.handle_pool.add(sb_fname, h)
-                else:
-                    raise NotImplementedError("Untested case")
-            else:
-                raise NotImplementedError("Untested case")
-        elif (args.access & 0x40000000) or args.access == 2:
-            # write but not read
-            if args.dwcreationdisposition == 3:
-                # open existing
-                if is_original_file:
-                    # cannot open self in write mode!
-                    pass
-                elif os.access(sb_fname, os.R_OK):
-                    s = os.stat(sb_fname)
-                    if stat.S_ISDIR(s.st_mode):
-                        # open dir
-                        ret = winobjs.handle_pool.add(sb_fname, 0x1337)
-                    else:
-                        h = open(sb_fname, 'wb')
-                        ret = winobjs.handle_pool.add(sb_fname, h)
-                else:
-                    raise NotImplementedError("Untested case")  # to test
-            elif args.dwcreationdisposition == 5:
-                # truncate_existing
-                if is_original_file:
-                    pass
-                else:
-                    raise NotImplementedError("Untested case")  # to test
-            else:
-                # raise NotImplementedError("Untested case") # to test
-                h = open(sb_fname, 'wb')
-                ret = winobjs.handle_pool.add(sb_fname, h)
-        else:
-            raise NotImplementedError("Untested case")
-
-        # h = open(sb_fname, 'rb+')
-        # ret = winobjs.handle_pool.add(sb_fname, h)
-    log.debug('CreateFile ret %x', ret)
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_CreateFileA(jitter):
-    kernel32_CreateFile(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def kernel32_CreateFileW(jitter):
-    kernel32_CreateFile(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def kernel32_ReadFile(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpbuffer",
-                                             "nnumberofbytestoread",
-                                             "lpnumberofbytesread",
-                                             "lpoverlapped"])
-    if args.hwnd == winobjs.module_cur_hwnd:
-        pass
-    elif args.hwnd in winobjs.handle_pool:
-        pass
-    else:
-        raise ValueError('unknown hwnd!')
-
-    data = None
-    if args.hwnd in winobjs.files_hwnd:
-        data = winobjs.files_hwnd[
-            winobjs.module_cur_hwnd].read(args.nnumberofbytestoread)
-    elif args.hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[args.hwnd]
-        data = wh.info.read(args.nnumberofbytestoread)
-    else:
-        raise ValueError('unknown filename')
-
-    if data is not None:
-        if (args.lpnumberofbytesread):
-            jitter.vm.set_u32(args.lpnumberofbytesread, len(data))
-        jitter.vm.set_mem(args.lpbuffer, data)
-
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_GetFileSize(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"])
-
-    if args.hwnd == winobjs.module_cur_hwnd:
-        ret = len(open(winobjs.module_fname_nux, "rb").read())
-    elif args.hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[args.hwnd]
-        ret = len(open(wh.name, "rb").read())
-    else:
-        raise ValueError('unknown hwnd!')
-
-    if args.lpfilesizehight != 0:
-        jitter.vm.set_u32(args.lpfilesizehight, ret)
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_GetFileSizeEx(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"])
-
-    if args.hwnd == winobjs.module_cur_hwnd:
-        l = len(open(winobjs.module_fname_nux, "rb").read())
-    elif args.hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[args.hwnd]
-        l = len(open(wh.name, "rb").read())
-    else:
-        raise ValueError('unknown hwnd!')
-
-    if args.lpfilesizehight == 0:
-        raise NotImplementedError("Untested case")
-    jitter.vm.set_mem(args.lpfilesizehight, pck32(
-        l & 0xffffffff) + pck32((l >> 32) & 0xffffffff))
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_FlushInstructionCache(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["hprocess", "lpbasead", "dwsize"])
-    jitter.func_ret_stdcall(ret_ad, 0x1337)
-
-
-def kernel32_VirtualProtect(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['lpvoid', 'dwsize',
-                                             'flnewprotect',
-                                             'lpfloldprotect'])
-    # XXX mask hpart
-    flnewprotect = args.flnewprotect & 0xFFF
-    if not flnewprotect in ACCESS_DICT:
-        raise ValueError('unknown access dw!')
-
-    if args.lpfloldprotect:
-        old = jitter.vm.get_mem_access(args.lpvoid)
-        jitter.vm.set_u32(args.lpfloldprotect, ACCESS_DICT_INV[old])
-
-    paddr = args.lpvoid - (args.lpvoid % winobjs.alloc_align)
-    paddr_max = (args.lpvoid + args.dwsize + winobjs.alloc_align - 1)
-    paddr_max_round = paddr_max - (paddr_max % winobjs.alloc_align)
-    psize = paddr_max_round - paddr
-    for addr, items in list(winobjs.allocated_pages.items()):
-        alloc_addr, alloc_size = items
-        if (paddr + psize <= alloc_addr or
-            paddr > alloc_addr + alloc_size):
-            continue
-        size = jitter.vm.get_all_memory()[addr]["size"]
-        # Page is included in Protect area
-        if (paddr <= addr < addr + size <= paddr + psize):
-            log.warn("set page %x %x", addr, ACCESS_DICT[flnewprotect])
-            jitter.vm.set_mem_access(addr, ACCESS_DICT[flnewprotect])
-            continue
-
-        # Page is partly in Protect area: splitting is needed
-        if (addr <= paddr < addr + size or
-            addr <= paddr + psize < addr + size):
-
-            old_access = jitter.vm.get_mem_access(addr)
-
-            # splits = [
-            #     addr -> max(paddr, addr)
-            #     max(paddr, addr) -> min(addr + size, paddr + psize)
-            #     min(addr + size, paddr + psize) -> addr + size
-            # ]
-            splits = [
-                (addr, old_access,
-                 jitter.vm.get_mem(addr, max(paddr, addr) - addr)),
-                (max(paddr, addr), ACCESS_DICT[flnewprotect],
-                 jitter.vm.get_mem(
-                     max(paddr, addr),
-                     min(addr + size, paddr + psize) - max(paddr, addr))),
-                (min(addr + size, paddr + psize), old_access,
-                 jitter.vm.get_mem(
-                     min(addr + size, paddr + psize),
-                     addr + size - min(addr + size, paddr + psize)))
-            ]
-
-            jitter.vm.remove_memory_page(addr)
-            for split_addr, split_access, split_data in splits:
-                if not split_data:
-                    continue
-                log.warn("create page %x %x", split_addr,
-                         ACCESS_DICT[flnewprotect])
-                jitter.vm.add_memory_page(
-                    split_addr, split_access, split_data,
-                    "VirtualProtect split ret 0x%X" % ret_ad)
-                winobjs.allocated_pages[split_addr] = (alloc_addr, alloc_size)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_VirtualAlloc(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['lpvoid', 'dwsize',
-                                             'alloc_type', 'flprotect'])
-
-
-    if not args.flprotect in ACCESS_DICT:
-        raise ValueError('unknown access dw!')
-
-    if args.lpvoid == 0:
-        alloc_addr = winobjs.heap.next_addr(args.dwsize)
-        winobjs.allocated_pages[alloc_addr] = (alloc_addr, args.dwsize)
-        jitter.vm.add_memory_page(
-            alloc_addr, ACCESS_DICT[args.flprotect], b"\x00" * args.dwsize,
-            "Alloc in %s ret 0x%X" % (whoami(), ret_ad))
-    else:
-        all_mem = jitter.vm.get_all_memory()
-        if args.lpvoid in all_mem:
-            alloc_addr = args.lpvoid
-            jitter.vm.set_mem_access(args.lpvoid, ACCESS_DICT[args.flprotect])
-        else:
-            alloc_addr = winobjs.heap.next_addr(args.dwsize)
-            winobjs.allocated_pages[alloc_addr] = (alloc_addr, args.dwsize)
-            # alloc_addr = args.lpvoid
-            jitter.vm.add_memory_page(
-                alloc_addr, ACCESS_DICT[args.flprotect], b"\x00" * args.dwsize,
-                "Alloc in %s ret 0x%X" % (whoami(), ret_ad))
-
-    log.info('VirtualAlloc addr: 0x%x', alloc_addr)
-    jitter.func_ret_stdcall(ret_ad, alloc_addr)
-
-
-def kernel32_VirtualFree(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["lpvoid", "dwsize", "alloc_type"])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def user32_GetWindowLongA(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["hwnd", "nindex"])
-    jitter.func_ret_stdcall(ret_ad, winobjs.windowlong_dw)
-
-
-def user32_SetWindowLongA(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["hwnd", "nindex", "newlong"])
-    jitter.func_ret_stdcall(ret_ad, winobjs.windowlong_dw)
-
-
-def kernel32_GetModuleFileName(jitter, funcname, set_str):
-    ret_ad, args = jitter.func_args_stdcall(["hmodule", "lpfilename", "nsize"])
-
-    if args.hmodule in [0, winobjs.hcurmodule]:
-        p = winobjs.module_path[:]
-    elif (winobjs.runtime_dll and
-          args.hmodule in viewvalues(winobjs.runtime_dll.name2off)):
-        name_inv = dict(
-            [
-                (x[1], x[0])
-                for x in viewitems(winobjs.runtime_dll.name2off)
-            ]
-        )
-        p = name_inv[args.hmodule]
-    else:
-        log.warning(('Unknown module 0x%x.' +
-                     'Set winobjs.hcurmodule and retry'), args.hmodule)
-        p = None
-
-    if p is None:
-        l = 0
-    elif args.nsize < len(p):
-        p = p[:args.nsize]
-        l = len(p)
-    else:
-        l = len(p)
-
-    if p:
-        set_str(args.lpfilename, p)
-
-    jitter.func_ret_stdcall(ret_ad, l)
-
-
-def kernel32_GetModuleFileNameA(jitter):
-    kernel32_GetModuleFileName(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
-
-
-def kernel32_GetModuleFileNameW(jitter):
-    kernel32_GetModuleFileName(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
-
-
-def kernel32_CreateMutex(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["mutexattr", "initowner",
-                                             "lpname"])
-
-    if args.lpname:
-        name = get_str(args.lpname)
-        log.info("CreateMutex %r", name)
-    else:
-        name = None
-    if args.initowner:
-        if name in winobjs.mutex:
-            raise NotImplementedError("Untested case")
-            # ret = 0
-        else:
-            winobjs.mutex[name] = id(name) & 0xFFFFFFFF
-            ret = winobjs.mutex[name]
-    else:
-        if name in winobjs.mutex:
-            raise NotImplementedError("Untested case")
-            # ret = 0
-        else:
-            winobjs.mutex[name] = id(name) & 0xFFFFFFFF
-            ret = winobjs.mutex[name]
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_CreateMutexA(jitter):
-    kernel32_CreateMutex(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def kernel32_CreateMutexW(jitter):
-    kernel32_CreateMutex(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def shell32_SHGetSpecialFolderLocation(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hwndowner", "nfolder", "ppidl"])
-    jitter.vm.set_u32(args.ppidl, args.nfolder)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_SHGetPathFromIDList(jitter, funcname, set_str):
-    ret_ad, args = jitter.func_args_stdcall(["pidl", "ppath"])
-
-    if args.pidl == 7:  # CSIDL_STARTUP:
-        s = "c:\\doc\\user\\startmenu\\programs\\startup"
-        set_str(args.ppath, s)
-    else:
-        raise ValueError('pidl not implemented', args.pidl)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def shell32_SHGetPathFromIDListW(jitter):
-    kernel32_SHGetPathFromIDList(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
-
-
-def shell32_SHGetPathFromIDListA(jitter):
-    kernel32_SHGetPathFromIDList(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
-
-
-def kernel32_GetLastError(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, winobjs.lastwin32error)
-
-
-def kernel32_SetLastError(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["errcode"])
-    # lasterr addr
-    # ad = tib_address + 0x34
-    # jitter.vm.set_mem(ad, pck32(args.errcode))
-    winobjs.lastwin32error = args.errcode
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_RestoreLastError(jitter):
-    kernel32_SetLastError(jitter)
-
-
-def kernel32_LoadLibrary(jitter, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["dllname"])
-
-    libname = get_str(args.dllname, 0x100)
-    ret = winobjs.runtime_dll.lib_get_add_base(libname)
-    log.info("Loading %r ret 0x%x", libname, ret)
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_LoadLibraryA(jitter):
-    kernel32_LoadLibrary(jitter, lambda addr, max_char=None:get_win_str_a(jitter, addr, max_char))
-
-
-def kernel32_LoadLibraryW(jitter):
-    kernel32_LoadLibrary(jitter, lambda addr, max_char=None:get_win_str_w(jitter, addr, max_char))
-
-
-def kernel32_LoadLibraryEx(jitter, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["dllname", "hfile", "flags"])
-
-    if args.hfile != 0:
-        raise NotImplementedError("Untested case")
-    libname = get_str(args.dllname, 0x100)
-    ret = winobjs.runtime_dll.lib_get_add_base(libname)
-    log.info("Loading %r ret 0x%x", libname, ret)
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_LoadLibraryExA(jitter):
-    kernel32_LoadLibraryEx(jitter, lambda addr, max_char=None:get_win_str_a(jitter, addr, max_char))
-
-
-def kernel32_LoadLibraryExW(jitter):
-    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_c_str(fname, 0x100)
-        if not fname:
-            fname = None
-    if fname is not None:
-        ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
-    else:
-        ad = 0
-    log.info("GetProcAddress %r %r ret 0x%x", args.libbase, fname, ad)
-    jitter.add_breakpoint(ad, jitter.handle_lib)
-    jitter.func_ret_stdcall(ret_ad, ad)
-
-
-def kernel32_GetModuleHandle(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["dllname"])
-
-    if args.dllname:
-        libname = get_str(args.dllname)
-        if libname:
-            ret = winobjs.runtime_dll.lib_get_add_base(libname)
-        else:
-            log.warning('unknown module!')
-            ret = 0
-        log.info("GetModuleHandle %r ret 0x%x", libname, ret)
-    else:
-        ret = winobjs.current_pe.NThdr.ImageBase
-        log.info("GetModuleHandle default ret 0x%x", ret)
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_GetModuleHandleA(jitter):
-    kernel32_GetModuleHandle(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def kernel32_GetModuleHandleW(jitter):
-    kernel32_GetModuleHandle(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def kernel32_VirtualLock(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["lpaddress", "dwsize"])
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-class systeminfo(object):
-    oemId = 0
-    dwPageSize = 0x1000
-    lpMinimumApplicationAddress = 0x10000
-    lpMaximumApplicationAddress = 0x7ffeffff
-    dwActiveProcessorMask = 0x1
-    numberOfProcessors = 0x1
-    ProcessorsType = 586
-    dwAllocationgranularity = 0x10000
-    wProcessorLevel = 0x6
-    ProcessorRevision = 0xf0b
-
-    def pack(self):
-        return struct.pack('IIIIIIIIHH',
-                           self.oemId,
-                           self.dwPageSize,
-                           self.lpMinimumApplicationAddress,
-                           self.lpMaximumApplicationAddress,
-                           self.dwActiveProcessorMask,
-                           self.numberOfProcessors,
-                           self.ProcessorsType,
-                           self.dwAllocationgranularity,
-                           self.wProcessorLevel,
-                           self.ProcessorRevision)
-
-
-def kernel32_GetSystemInfo(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["sys_ptr"])
-    sysinfo = systeminfo()
-    jitter.vm.set_mem(args.sys_ptr, sysinfo.pack())
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_IsWow64Process(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["process", "bool_ptr"])
-    jitter.vm.set_u32(args.bool_ptr, 0)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_GetCommandLine(jitter, set_str):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    alloc_addr = winobjs.heap.alloc(jitter, 0x1000)
-    set_str(alloc_addr, '"%s"' % winobjs.module_path)
-    jitter.func_ret_stdcall(ret_ad, alloc_addr)
-
-
-def kernel32_GetCommandLineA(jitter):
-    kernel32_GetCommandLine(jitter, lambda addr, value: set_win_str_a(jitter, addr, value))
-
-
-def kernel32_GetCommandLineW(jitter):
-    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 = get_win_str_w(jitter, args.pcmd)
-    if cmd.startswith('"') and cmd.endswith('"'):
-        cmd = cmd[1:-1]
-    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):
-        set_win_str_w(jitter, addr + o, t)
-        jitter.vm.set_u32(addr_ret + 4 * i, addr + o)
-        o += len(t)*2 + 2
-
-    jitter.vm.set_u32(addr_ret + 4 * (i+1), 0)
-    jitter.vm.set_u32(args.pnumargs, len(tks))
-    jitter.func_ret_stdcall(ret_ad, addr_ret)
-
-def cryptdll_MD5Init(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["ad_ctx"])
-    index = len(winobjs.cryptdll_md5_h)
-    h = MD5.new()
-    winobjs.cryptdll_md5_h[index] = h
-
-    jitter.vm.set_u32(args.ad_ctx, index)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def cryptdll_MD5Update(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_input", "inlen"])
-
-    index = jitter.vm.get_u32(args.ad_ctx)
-    if not index in winobjs.cryptdll_md5_h:
-        raise ValueError('unknown h context', index)
-
-    data = jitter.vm.get_mem(args.ad_input, args.inlen)
-    winobjs.cryptdll_md5_h[index].update(data)
-    log.debug(hexdump(data))
-
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def cryptdll_MD5Final(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["ad_ctx"])
-
-    index = jitter.vm.get_u32(args.ad_ctx)
-    if not index in winobjs.cryptdll_md5_h:
-        raise ValueError('unknown h context', index)
-    h = winobjs.cryptdll_md5_h[index].digest()
-    jitter.vm.set_mem(args.ad_ctx + 88, h)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_RtlInitAnsiString(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "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))
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_RtlHashUnicodeString(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["ad_ctxu", "case_i", "h_id",
-                                             "phout"])
-
-    if args.h_id != 1:
-        raise ValueError('unk hash unicode', args.h_id)
-
-    l1, l2, ptra = struct.unpack('HHL', jitter.vm.get_mem(args.ad_ctxu, 8))
-    s = jitter.vm.get_mem(ptra, l1)
-    s = s[:-1]
-    hv = 0
-
-    if args.case_i:
-        s = s.lower()
-    for c in s:
-        hv = ((65599 * hv) + ord(c)) & 0xffffffff
-    jitter.vm.set_u32(args.phout, hv)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_RtlMoveMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["ad_dst", "ad_src", "m_len"])
-    data = jitter.vm.get_mem(args.ad_src, args.m_len)
-    jitter.vm.set_mem(args.ad_dst, data)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_RtlAnsiCharToUnicodeChar(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['ad_ad_ch'])
-    ad_ch = jitter.vm.get_u32(args.ad_ad_ch)
-    ch = ord(jitter.vm.get_mem(ad_ch, 1))
-    jitter.vm.set_u32(args.ad_ad_ch, ad_ch + 1)
-    jitter.func_ret_stdcall(ret_ad, ch)
-
-
-def ntdll_RtlFindCharInUnicodeString(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["flags", "main_str_ad",
-                                             "search_chars_ad", "pos_ad"])
-
-    if args.flags != 0:
-        raise ValueError('unk flags')
-
-    ml1, ml2, mptra = struct.unpack('HHL',
-                                    jitter.vm.get_mem(args.main_str_ad, 8))
-    sl1, sl2, sptra = struct.unpack(
-        'HHL', jitter.vm.get_mem(args.search_chars_ad, 8))
-    main_data = jitter.vm.get_mem(mptra, ml1)[:-1]
-    search_data = jitter.vm.get_mem(sptra, sl1)[:-1]
-
-    pos = None
-    for i, c in enumerate(main_data):
-        for s in search_data:
-            if s == c:
-                pos = i
-                break
-        if pos:
-            break
-    if pos is None:
-        ret = 0xC0000225
-        jitter.vm.set_u32(args.pos_ad, 0)
-    else:
-        ret = 0
-        jitter.vm.set_u32(args.pos_ad, pos)
-
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def ntdll_RtlComputeCrc32(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["dwinit", "pdata", "ilen"])
-    data = jitter.vm.get_mem(args.pdata, args.ilen)
-    crc_r = crc32(data, args.dwinit)
-    jitter.func_ret_stdcall(ret_ad, crc_r)
-
-
-def ntdll_RtlExtendedIntegerMultiply(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['multiplicand_low',
-                                             'multiplicand_high',
-                                             'multiplier'])
-    a = (args.multiplicand_high << 32) + args.multiplicand_low
-    a = a * args.multiplier
-    jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
-
-
-def ntdll_RtlLargeIntegerAdd(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high',
-                                             'b_low', 'b_high'])
-    a = (args.a_high << 32) + args.a_low + (args.b_high << 32) + args.b_low
-    jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
-
-
-def ntdll_RtlLargeIntegerShiftRight(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high', 's_count'])
-    a = ((args.a_high << 32) + args.a_low) >> args.s_count
-    jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
-
-
-def ntdll_RtlEnlargedUnsignedMultiply(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['a', 'b'])
-    a = args.a * args.b
-    jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
-
-
-def ntdll_RtlLargeIntegerSubtract(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high',
-                                             'b_low', 'b_high'])
-    a = (args.a_high << 32) + args.a_low - (args.b_high << 32) + args.b_low
-    jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff)
-
-
-def ntdll_RtlCompareMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['ad1', 'ad2', 'm_len'])
-    data1 = jitter.vm.get_mem(args.ad1, args.m_len)
-    data2 = jitter.vm.get_mem(args.ad2, args.m_len)
-
-    i = 0
-    while data1[i] == data2[i]:
-        i += 1
-        if i >= args.m_len:
-            break
-
-    jitter.func_ret_stdcall(ret_ad, i)
-
-
-def user32_GetMessagePos(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, 0x00110022)
-
-
-def kernel32_Sleep(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(['t'])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_ZwUnmapViewOfSection(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(['h', 'ad'])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_IsBadReadPtr(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(['lp', 'ucb'])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntoskrnl_KeInitializeEvent(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['my_event', 'my_type',
-                                             'my_state'])
-    jitter.vm.set_u32(args.my_event, winobjs.win_event_num)
-    winobjs.win_event_num += 1
-
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntoskrnl_RtlGetVersion(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['ptr_version'])
-
-    s = struct.pack("IIIII",
-                    0x114,  # struct size
-                    0x5,   # maj vers
-                    0x2,  # min vers
-                    0x666,  # build nbr
-                    0x2,   # platform id
-                    ) + encode_win_str_w("Service pack 4")
-
-    jitter.vm.set_mem(args.ptr_version, s)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntoskrnl_RtlVerifyVersionInfo(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['ptr_version'])
-
-    s = jitter.vm.get_mem(args.ptr_version, 0x5 * 4)
-    s_size, s_majv, s_minv, s_buildn, s_platform = struct.unpack('IIIII', s)
-    raise NotImplementedError("Untested case")
-    # jitter.vm.set_mem(args.ptr_version, s)
-    # jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def hal_ExAcquireFastMutex(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def mdl2ad(n):
-    return winobjs.nt_mdl_ad + 0x10 * n
-
-
-def ad2mdl(ad):
-    return ((ad - winobjs.nt_mdl_ad) & 0xFFFFFFFF) // 0x10
-
-
-def ntoskrnl_IoAllocateMdl(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["v_addr", "l", "second_buf",
-                                             "chargequota", "pirp"])
-    m = mdl(args.v_addr, args.l)
-    winobjs.nt_mdl[winobjs.nt_mdl_cur] = m
-    jitter.vm.set_mem(mdl2ad(winobjs.nt_mdl_cur), bytes(m))
-    jitter.func_ret_stdcall(ret_ad, mdl2ad(winobjs.nt_mdl_cur))
-    winobjs.nt_mdl_cur += 1
-
-
-def ntoskrnl_MmProbeAndLockPages(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["p_mdl", "access_mode", "op"])
-
-    if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(args.p_mdl))
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntoskrnl_MmMapLockedPagesSpecifyCache(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["p_mdl", "access_mode",
-                                             "cache_type", "base_ad",
-                                             "bugcheckonfailure",
-                                             "priority"])
-    if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(args.p_mdl))
-
-    jitter.func_ret_stdcall(ret_ad, winobjs.nt_mdl[ad2mdl(args.p_mdl)].ad)
-
-
-def ntoskrnl_MmProtectMdlSystemAddress(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["p_mdl", "prot"])
-    if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(args.p_mdl))
-
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntoskrnl_MmUnlockPages(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['p_mdl'])
-    if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(args.p_mdl))
-
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntoskrnl_IoFreeMdl(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['p_mdl'])
-    if not ad2mdl(args.p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(args.p_mdl))
-    del(winobjs.nt_mdl[ad2mdl(args.p_mdl)])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def hal_ExReleaseFastMutex(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntoskrnl_RtlQueryRegistryValues(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["relativeto", "path",
-                                             "querytable",
-                                             "context",
-                                             "environ"])
-    # path = get_win_str_w(jitter, args.path)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntoskrnl_ExAllocatePoolWithTagPriority(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["pool_type",
-                                             "nbr_of_bytes",
-                                             "tag", "priority"])
-    alloc_addr = winobjs.heap.next_addr(args.nbr_of_bytes)
-    jitter.vm.add_memory_page(
-        alloc_addr, PAGE_READ | PAGE_WRITE, b"\x00" * args.nbr_of_bytes,
-        "Alloc in %s ret 0x%X" % (whoami(), ret_ad))
-
-    jitter.func_ret_stdcall(ret_ad, alloc_addr)
-
-
-def my_lstrcmp(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2"])
-    s1 = get_str(args.ptr_str1)
-    s2 = get_str(args.ptr_str2)
-    log.info("Compare %r with %r", s1, s2)
-    jitter.func_ret_stdcall(ret_ad, cmp(s1, s2))
-
-def msvcrt_wcscmp(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "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 = 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 = 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 = get_win_str_w(jitter, args.src)
-    dst = src[:args.n]
-    jitter.vm.set_mem(args.dst, b"\x00\x00" * args.n)
-    jitter.vm.set_mem(args.dst, dst.encode("utf-16le"))
-    jitter.func_ret_cdecl(ret_ad, args.dst)
-
-def kernel32_lstrcmpA(jitter):
-    my_lstrcmp(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def kernel32_lstrcmpiA(jitter):
-    my_lstrcmp(jitter, whoami(), lambda x: get_win_str_a(jitter, x).lower())
-
-
-def kernel32_lstrcmpW(jitter):
-    my_lstrcmp(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def kernel32_lstrcmpiW(jitter):
-    my_lstrcmp(jitter, whoami(), lambda x: get_win_str_w(jitter, x).lower())
-
-
-def kernel32_lstrcmpi(jitter):
-    my_lstrcmp(jitter, whoami(), lambda x: get_win_str_a(jitter, x).lower())
-
-
-def my_strcpy(jitter, funcname, get_str, set_str):
-    ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2"])
-    s2 = get_str(args.ptr_str2)
-    set_str(args.ptr_str1, s2)
-    log.info("Copy '%r'", s2)
-    jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
-
-
-def kernel32_lstrcpyW(jitter):
-    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(), 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(), 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 = get_win_str_w(jitter, args.ptr_str2)
-    set_win_str_w(jitter, args.ptr_str1, s2)
-    jitter.func_ret_cdecl(ret_ad, args.ptr_str1)
-
-def msvcrt_wcscpy(jitter):
-    return msvcrt__mbscpy(jitter)
-
-
-def kernel32_lstrcpyn(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2",
-                                             "mlen"])
-    s2 = get_win_str_a(jitter, args.ptr_str2)
-    if len(s2) >= args.mlen:
-        s2 = s2[:args.mlen - 1]
-    log.info("Copy '%r'", s2)
-    set_win_str_a(jitter, args.ptr_str1, s2)
-    jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
-
-
-def my_strlen(jitter, funcname, get_str, mylen):
-    ret_ad, args = jitter.func_args_stdcall(["src"])
-    src = get_str(args.src)
-    length = mylen(src)
-    log.info("Len of '%r' -> 0x%x", src, length)
-    jitter.func_ret_stdcall(ret_ad, length)
-
-
-def kernel32_lstrlenA(jitter):
-    my_strlen(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), len)
-
-
-def kernel32_lstrlenW(jitter):
-    my_strlen(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr), len)
-
-
-def kernel32_lstrlen(jitter):
-    my_strlen(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), len)
-
-
-def my_lstrcat(jitter, funcname, get_str, set_str):
-    ret_ad, args = jitter.func_args_stdcall(['ptr_str1', 'ptr_str2'])
-    s1 = get_str(args.ptr_str1)
-    s2 = get_str(args.ptr_str2)
-    set_str(args.ptr_str1, s1 + s2)
-    jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
-
-
-def kernel32_lstrcatA(jitter):
-    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(), lambda addr:get_win_str_w(jitter, addr), lambda addr,value: set_win_str_w(jitter, addr, value))
-
-
-def kernel32_GetUserGeoID(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["geoclass"])
-    if args.geoclass == 14:
-        ret = 12345678
-    elif args.geoclass == 16:
-        ret = 55667788
-    else:
-        raise ValueError('unknown geolcass')
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def my_GetVolumeInformation(jitter, funcname, get_str, set_str):
-    ret_ad, args = jitter.func_args_stdcall(["lprootpathname",
-                                             "lpvolumenamebuffer",
-                                             "nvolumenamesize",
-                                             "lpvolumeserialnumber",
-                                             "lpmaximumcomponentlength",
-                                             "lpfilesystemflags",
-                                             "lpfilesystemnamebuffer",
-                                             "nfilesystemnamesize"])
-    if args.lprootpathname:
-        s = get_str(args.lprootpathname)
-        log.info('GetVolumeInformation %r', s)
-
-
-    if args.lpvolumenamebuffer:
-        s = "volumename"
-        s = s[:args.nvolumenamesize]
-        set_str(args.lpvolumenamebuffer, s)
-
-    if args.lpvolumeserialnumber:
-        jitter.vm.set_u32(args.lpvolumeserialnumber, 11111111)
-    if args.lpmaximumcomponentlength:
-        jitter.vm.set_u32(args.lpmaximumcomponentlength, 0xff)
-    if args.lpfilesystemflags:
-        jitter.vm.set_u32(args.lpfilesystemflags, 22222222)
-
-    if args.lpfilesystemnamebuffer:
-        s = "filesystemname"
-        s = s[:args.nfilesystemnamesize]
-        set_str(args.lpfilesystemnamebuffer, s)
-
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_GetVolumeInformationA(jitter):
-    my_GetVolumeInformation(
-        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(), lambda addr:get_win_str_w(jitter, addr), lambda addr,value: set_win_str_w(jitter, addr, value))
-
-
-def kernel32_MultiByteToWideChar(jitter):
-    MB_ERR_INVALID_CHARS = 0x8
-    CP_ACP  = 0x000
-    CP_1252 = 0x4e4
-
-    ret_ad, args = jitter.func_args_stdcall(["codepage", "dwflags",
-                                             "lpmultibytestr",
-                                             "cbmultibyte",
-                                             "lpwidecharstr",
-                                             "cchwidechar"])
-    if args.codepage != CP_ACP and args.codepage != CP_1252:
-        raise NotImplementedError
-    # according to MSDN:
-    # "Note that, if cbMultiByte is 0, the function fails."
-    if args.cbmultibyte == 0:
-        raise ValueError
-    # according to MSDN:
-    # "Alternatively, this parameter can be set to -1 if the string is
-    #  null-terminated."
-    if args.cbmultibyte == 0xffffffff:
-        src_len = 0
-        while jitter.vm.get_mem(args.lpmultibytestr + src_len, 1) != b'\0':
-            src_len += 1
-        src = jitter.vm.get_mem(args.lpmultibytestr, src_len)
-    else:
-        src = jitter.vm.get_mem(args.lpmultibytestr, args.cbmultibyte)
-    if args.dwflags & MB_ERR_INVALID_CHARS:
-        # will raise an exception if decoding fails
-        s = src.decode("cp1252", errors="replace").encode("utf-16le")
-    else:
-        # silently replace undecodable chars with U+FFFD
-        s = src.decode("cp1252", errors="replace").encode("utf-16le")
-    if args.cchwidechar > 0:
-        # return value is number of bytes written
-        retval = min(args.cchwidechar, len(s))
-        jitter.vm.set_mem(args.lpwidecharstr, s[:retval])
-    else:
-        # return value is number of bytes to write
-        # i.e., size of dest. buffer to allocate
-        retval = len(s)
-    jitter.func_ret_stdcall(ret_ad, retval)
-
-
-def kernel32_WideCharToMultiByte(jitter):
-    """
-        int WideCharToMultiByte(
-          UINT                               CodePage,
-          DWORD                              dwFlags,
-          _In_NLS_string_(cchWideChar)LPCWCH lpWideCharStr,
-          int                                cchWideChar,
-          LPSTR                              lpMultiByteStr,
-          int                                cbMultiByte,
-          LPCCH                              lpDefaultChar,
-          LPBOOL                             lpUsedDefaultChar
-        );
-
-    """
-    CP_ACP  = 0x000
-    CP_1252 = 0x4e4
-
-    ret, args = jitter.func_args_stdcall([
-        'CodePage', 'dwFlags', 'lpWideCharStr', 'cchWideChar',
-        'lpMultiByteStr', 'cbMultiByte', 'lpDefaultChar', 'lpUsedDefaultChar',
-      ])
-    if args.CodePage != CP_ACP and args.CodePage != CP_1252:
-        raise NotImplementedError
-    cchWideChar = args.cchWideChar
-    if cchWideChar == 0xffffffff:
-        cchWideChar = len(get_win_str_w(jitter, args.lpWideCharStr)) + 1
-    src = jitter.vm.get_mem(args.lpWideCharStr, cchWideChar * 2)
-    dst = src.decode("utf-16le").encode("cp1252", errors="replace")
-    if args.cbMultiByte > 0:
-        # return value is the number of bytes written
-        retval = min(args.cbMultiByte, len(dst))
-        jitter.vm.set_mem(args.lpMultiByteStr, dst[:retval])
-    else:
-        # return value is the size of the buffer to allocate
-        # to get the multibyte string
-        retval = len(dst)
-    jitter.func_ret_stdcall(ret, retval)
-
-
-def my_GetEnvironmentVariable(jitter, funcname, get_str, set_str, mylen):
-    ret_ad, args = jitter.func_args_stdcall(["lpname", "lpbuffer",
-                                             "nsize"])
-
-    s = get_str(args.lpname)
-    log.info('GetEnvironmentVariable %r', s)
-    if s in winobjs.env_variables:
-        v = winobjs.env_variables[s]
-    else:
-        log.warning('WARNING unknown env variable %r', s)
-        v = ""
-    set_str(args.lpbuffer, v)
-    jitter.func_ret_stdcall(ret_ad, mylen(v))
-
-
-def kernel32_GetEnvironmentVariableA(jitter):
-    my_GetEnvironmentVariable(jitter, whoami(),
-                              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(),
-                              lambda addr:get_win_str_w(jitter, addr),
-                              lambda addr,value: set_win_str_w(jitter, addr, value),
-                              len)
-
-
-def my_GetSystemDirectory(jitter, funcname, set_str):
-    ret_ad, args = jitter.func_args_stdcall(["lpbuffer", "usize"])
-    s = "c:\\windows\\system32"
-    l = len(s)
-    set_str(args.lpbuffer, s)
-    jitter.func_ret_stdcall(ret_ad, l)
-
-
-
-def kernel32_GetSystemDirectoryA(jitter):
-    my_GetSystemDirectory(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
-
-
-def kernel32_GetSystemDirectoryW(jitter):
-    my_GetSystemDirectory(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
-
-
-def my_CreateDirectory(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(['lppath', 'secattrib'])
-    # path = get_str(jitter, args.lppath)
-    jitter.func_ret_stdcall(ret_ad, 0x1337)
-
-
-def kernel32_CreateDirectoryW(jitter):
-    my_CreateDirectory(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def kernel32_CreateDirectoryA(jitter):
-    my_CreateDirectory(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-
-def my_CreateEvent(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["lpeventattributes",
-                                             "bmanualreset",
-                                             "binitialstate",
-                                             "lpname"])
-    s = get_str(args.lpname) if args.lpname else None
-    if not s in winobjs.events_pool:
-        winobjs.events_pool[s] = (args.bmanualreset, args.binitialstate)
-    else:
-        log.warning('WARNING: known event')
-    jitter.func_ret_stdcall(ret_ad, id(s) & 0xFFFFFFFF)
-
-
-def kernel32_CreateEventA(jitter):
-    my_CreateEvent(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def kernel32_CreateEventW(jitter):
-    my_CreateEvent(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def kernel32_WaitForSingleObject(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['handle', 'dwms'])
-
-    t_start = time.time() * 1000
-    found = False
-    while True:
-        if args.dwms and args.dwms + t_start > time.time() * 1000:
-            ret = 0x102
-            break
-        for key, value in viewitems(winobjs.events_pool):
-            if key != args.handle:
-                continue
-            found = True
-            if value[1] == 1:
-                ret = 0
-                break
-        if not found:
-            log.warning('unknown handle')
-            ret = 0xffffffff
-            break
-        time.sleep(0.1)
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_SetFileAttributesA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["lpfilename",
-                                             "dwfileattributes"])
-    if args.lpfilename:
-        # fname = get_win_str_a(jitter, args.lpfilename)
-        ret = 1
-    else:
-        ret = 0
-        jitter.vm.set_u32(tib_address + 0x34, 3)
-
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def ntdll_RtlMoveMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["dst", "src", "l"])
-    s = jitter.vm.get_mem(args.src, args.l)
-    jitter.vm.set_mem(args.dst, s)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def ntdll_ZwQuerySystemInformation(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["systeminformationclass",
-                                             "systeminformation",
-                                             "systeminformationl",
-                                             "returnl"])
-    if args.systeminformationclass == 2:
-        # SYSTEM_PERFORMANCE_INFORMATION
-        o = struct.pack('II', 0x22222222, 0x33333333)
-        o += b"\x00" * args.systeminformationl
-        o = o[:args.systeminformationl]
-        jitter.vm.set_mem(args.systeminformation, o)
-    else:
-        raise ValueError('unknown sysinfo class',
-                         args.systeminformationclass)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_ZwProtectVirtualMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid",
-                                             "pdwsize",
-                                             "flnewprotect",
-                                             "lpfloldprotect"])
-
-    ad = jitter.vm.get_u32(args.lppvoid)
-    # dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4))
-    # XXX mask hpart
-    flnewprotect = args.flnewprotect & 0xFFF
-
-    if not flnewprotect in ACCESS_DICT:
-        raise ValueError('unknown access dw!')
-    jitter.vm.set_mem_access(ad, ACCESS_DICT[flnewprotect])
-
-    # XXX todo real old protect
-    jitter.vm.set_u32(args.lpfloldprotect, 0x40)
-
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def ntdll_ZwAllocateVirtualMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid",
-                                             "zerobits", "pdwsize",
-                                             "alloc_type",
-                                             "flprotect"])
-
-    # ad = upck32(jitter.vm.get_mem(args.lppvoid, 4))
-    dwsize = jitter.vm.get_u32(args.pdwsize)
-
-    if not args.flprotect in ACCESS_DICT:
-        raise ValueError('unknown access dw!')
-
-    alloc_addr = winobjs.heap.next_addr(dwsize)
-    jitter.vm.add_memory_page(
-        alloc_addr, ACCESS_DICT[args.flprotect], b"\x00" * dwsize,
-        "Alloc in %s ret 0x%X" % (whoami(), ret_ad))
-    jitter.vm.set_u32(args.lppvoid, alloc_addr)
-
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_ZwFreeVirtualMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid",
-                                             "pdwsize", "alloc_type"])
-    # ad = upck32(jitter.vm.get_mem(args.lppvoid, 4))
-    # dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4))
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_RtlInitString(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["pstring", "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)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-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 = get_win_str_a(jitter, p_src)
-    l = (len(s) + 1) * 2
-    if args.alloc_str:
-        alloc_addr = winobjs.heap.next_addr(l)
-        jitter.vm.add_memory_page(
-            alloc_addr, PAGE_READ | PAGE_WRITE, b"\x00" * l,
-            "Alloc in %s ret 0x%X" % (whoami(), ret_ad))
-    else:
-        alloc_addr = p_src
-    set_win_str_w(jitter, alloc_addr, s)
-    o = struct.pack('HHI', l, l, alloc_addr)
-    jitter.vm.set_mem(args.dst, o)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_LdrLoadDll(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["path", "flags",
-                                             "modname", "modhandle"])
-
-    l1, l2, p_src = struct.unpack('HHI',
-                                  jitter.vm.get_mem(args.modname, 0x8))
-    s = get_win_str_w(jitter, p_src)
-    libname = s.lower()
-
-    ad = winobjs.runtime_dll.lib_get_add_base(libname)
-    log.info("Loading %r ret 0x%x", s, ad)
-    jitter.vm.set_u32(args.modhandle, ad)
-
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-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_win_str_w(jitter, p_src)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_LdrGetProcedureAddress(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["libbase", "pfname",
-                                             "opt", "p_ad"])
-
-    l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.pfname, 0x8))
-    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)
-
-    jitter.vm.set_u32(args.p_ad, ad)
-
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def ntdll_memset(jitter):
-    ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size'])
-    jitter.vm.set_mem(args.addr, int_to_byte(args.c) * args.size)
-    jitter.func_ret_cdecl(ret_ad, args.addr)
-
-
-def msvcrt_memset(jitter):
-    ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size'])
-    jitter.vm.set_mem(args.addr, int_to_byte(args.c) * args.size)
-    jitter.func_ret_cdecl(ret_ad, args.addr)
-
-def msvcrt_strrchr(jitter):
-    ret_ad, args = jitter.func_args_cdecl(['pstr','c'])
-    s = get_win_str_a(jitter, args.pstr)
-    c = int_to_byte(args.c).decode()
-    ret = args.pstr + s.rfind(c)
-    log.info("strrchr(%x '%s','%s') = %x" % (args.pstr,s,c,ret))
-    jitter.func_ret_cdecl(ret_ad, ret)
-
-def msvcrt_wcsrchr(jitter):
-    ret_ad, args = jitter.func_args_cdecl(['pstr','c'])
-    s = get_win_str_w(jitter, args.pstr)
-    c = int_to_byte(args.c).decode()
-    ret = args.pstr + (s.rfind(c)*2)
-    log.info("wcsrchr(%x '%s',%s) = %x" % (args.pstr,s,c,ret))
-    jitter.func_ret_cdecl(ret_ad, ret)
-
-def msvcrt_memcpy(jitter):
-    ret_ad, args = jitter.func_args_cdecl(['dst', 'src', 'size'])
-    s = jitter.vm.get_mem(args.src, args.size)
-    jitter.vm.set_mem(args.dst, s)
-    jitter.func_ret_cdecl(ret_ad, args.dst)
-
-def msvcrt_realloc(jitter):
-    ret_ad,args = jitter.func_args_cdecl(['ptr','new_size'])
-    if args.ptr == 0:
-        addr = winobjs.heap.alloc(jitter, args.new_size)
-    else:
-        addr = winobjs.heap.alloc(jitter, args.new_size)
-        size = winobjs.heap.get_size(jitter.vm, args.ptr)
-        data = jitter.vm.get_mem(args.ptr, size)
-        jitter.vm.set_mem(addr, data)
-    jitter.func_ret_cdecl(ret_ad, addr)
-
-def msvcrt_memcmp(jitter):
-    ret_ad, args = jitter.func_args_cdecl(['ps1', 'ps2', 'size'])
-    s1 = jitter.vm.get_mem(args.ps1, args.size)
-    s2 = jitter.vm.get_mem(args.ps2, args.size)
-    ret = cmp(s1, s2)
-    jitter.func_ret_cdecl(ret_ad, ret)
-
-
-def shlwapi_PathFindExtensionA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['path_ad'])
-    path = get_win_str_a(jitter, args.path_ad)
-    i = path.rfind('.')
-    if i == -1:
-        i = args.path_ad + len(path)
-    else:
-        i = args.path_ad + i
-    jitter.func_ret_stdcall(ret_ad, i)
-
-
-def shlwapi_PathRemoveFileSpecW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['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, b"\x00\x00")
-    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 = get_win_str_w(jitter, args.ptr_prefix)
-    path = get_win_str_w(jitter, args.ptr_path)
-
-    if path.startswith(prefix):
-        ret = 1
-    else:
-        ret = 0
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def shlwapi_PathIsDirectoryW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['ptr_path'])
-    fname = get_win_str_w(jitter, args.ptr_path)
-
-    sb_fname = windows_to_sbpath(fname)
-
-    s = os.stat(sb_fname)
-    ret = 0
-    if stat.S_ISDIR(s.st_mode):
-        ret = 1
-
-    jitter.func_ret_cdecl(ret_ad, ret)
-
-
-def shlwapi_PathIsFileSpec(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(['path_ad'])
-    path = get_str(args.path_ad)
-    if path.find(':') != -1 and path.find('\\') != -1:
-        ret = 0
-    else:
-        ret = 1
-
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def shlwapi_PathGetDriveNumber(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(['path_ad'])
-    path = get_str(args.path_ad)
-    l = ord(path[0].upper()) - ord('A')
-    if 0 <= l <= 25:
-        ret = l
-    else:
-        ret = -1
-
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def shlwapi_PathGetDriveNumberA(jitter):
-    shlwapi_PathGetDriveNumber(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def shlwapi_PathGetDriveNumberW(jitter):
-    shlwapi_PathGetDriveNumber(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def shlwapi_PathIsFileSpecA(jitter):
-    shlwapi_PathIsFileSpec(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def shlwapi_PathIsFileSpecW(jitter):
-    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 = get_win_str_a(jitter, args.i_str_ad)
-    try:
-        i = int(i_str)
-    except:
-        log.warning('WARNING cannot convert int')
-        i = 0
-
-    jitter.func_ret_stdcall(ret_ad, i)
-
-
-def shlwapi_StrToInt64Ex(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(['pstr', 'flags', 'pret'])
-    i_str = get_str(args.pstr)
-
-    if args.flags == 0:
-        r = int(i_str)
-    elif args.flags == 1:
-        r = int(i_str, 16)
-    else:
-        raise ValueError('cannot decode int')
-
-    jitter.vm.set_mem(args.pret, struct.pack('q', r))
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def shlwapi_StrToInt64ExA(jitter):
-    shlwapi_StrToInt64Ex(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def shlwapi_StrToInt64ExW(jitter):
-    shlwapi_StrToInt64Ex(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def user32_IsCharAlpha(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["c"])
-    try:
-        c = int_to_byte(args.c)
-    except:
-        log.error('bad char %r', args.c)
-        c = "\x00"
-    if c.isalpha(jitter):
-        ret = 1
-    else:
-        ret = 0
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def user32_IsCharAlphaA(jitter):
-    user32_IsCharAlpha(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def user32_IsCharAlphaW(jitter):
-    user32_IsCharAlpha(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def user32_IsCharAlphaNumericA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["c"])
-    c = int_to_byte(args.c)
-    if c.isalnum(jitter):
-        ret = 1
-    else:
-        ret = 0
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-def get_fmt_args(jitter, fmt, cur_arg, get_str):
-    return _get_fmt_args(fmt, cur_arg, get_str, jitter.get_arg_n_cdecl)
-
-def msvcrt_sprintf_str(jitter, get_str):
-    ret_ad, args = jitter.func_args_cdecl(['string', 'fmt'])
-    cur_arg, fmt = 2, args.fmt
-    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, 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'))
-    return jitter.func_ret_cdecl(ret_ad, ret)
-
-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, lambda addr:get_win_str_w(jitter, addr))
-    ret = len(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, lambda addr:get_win_str_a(jitter, addr))
-    ret = len(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:
-        raise NotImplementedError("Untested case")
-    winobjs.handle_pool[fd].info.write(output)
-
-    return jitter.func_ret_cdecl(ret_addr, ret)
-
-def shlwapi_StrCmpNIA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2",
-                                             "nchar"])
-    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))
-
-
-def advapi32_RegCreateKeyW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hkey", "subkey",
-                                             "phandle"])
-    s_subkey = get_win_str_w(jitter, args.subkey).lower() if args.subkey else ""
-
-    ret_hkey = 0
-    ret = 2
-    if args.hkey in winobjs.hkey_handles:
-        ret = 0
-        if s_subkey:
-            ret_hkey = hash(s_subkey) & 0xffffffff
-            winobjs.hkey_handles[ret_hkey] = s_subkey
-        else:
-            ret_hkey = args.hkey
-
-    log.info("RegCreateKeyW(%x, '%s') = (%x,%d)" % (args.hkey, s_subkey, ret_hkey, ret))
-    jitter.vm.set_u32(args.phandle, ret_hkey)
-
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-def kernel32_GetCurrentDirectoryA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["size","buf"])
-    dir_ = winobjs.cur_dir
-    log.debug("GetCurrentDirectory() = '%s'" % dir_)
-    set_win_str_a(jitter, args.buf, dir_[:args.size-1])
-    ret = len(dir_)
-    if args.size <= len(dir_):
-        ret += 1
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-def advapi32_RegOpenKeyEx(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["hkey", "subkey",
-                                             "reserved", "access",
-                                             "phandle"])
-    s_subkey = get_str(args.subkey).lower() if args.subkey else ""
-
-    ret_hkey = 0
-    ret = 2
-    if args.hkey in winobjs.hkey_handles:
-        if s_subkey:
-            h = hash(s_subkey) & 0xffffffff
-            if h in winobjs.hkey_handles:
-                ret_hkey = h
-                ret = 0
-        else:
-            log.error('unknown skey')
-
-    jitter.vm.set_u32(args.phandle, ret_hkey)
-
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def advapi32_RegOpenKeyExA(jitter):
-    advapi32_RegOpenKeyEx(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def advapi32_RegOpenKeyExW(jitter):
-    advapi32_RegOpenKeyEx(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def advapi32_RegSetValue(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["hkey", "psubkey",
-                                             "valuetype", "pvalue",
-                                             "vlen"])
-    if args.psubkey:
-        log.info("Subkey %s", get_str(args.psubkey))
-    if args.pvalue:
-        log.info("Value %s", get_str(args.pvalue))
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-def advapi32_RegSetValueEx(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["hkey", "lpvaluename",
-                                             "reserved", "dwtype",
-                                             "lpdata", "cbData"])
-    hkey = winobjs.hkey_handles.get(args.hkey, "unknown HKEY")
-    value_name = get_str(args.lpvaluename) if args.lpvaluename else ""
-    data = get_str(args.lpdata) if args.lpdata else ""
-    log.info("%s('%s','%s'='%s',%x)" % (funcname, hkey, value_name, data, args.dwtype))
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-def advapi32_RegCloseKey(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hkey"])
-    del winobjs.hkey_handles[args.hkey]
-    log.info("RegCloseKey(%x)" % args.hkey)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-def advapi32_RegSetValueExA(jitter):
-    advapi32_RegSetValueEx(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def advapi32_RegSetValueExW(jitter):
-    advapi32_RegOpenKeyEx(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def advapi32_RegSetValueA(jitter):
-    advapi32_RegSetValue(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def advapi32_RegSetValueW(jitter):
-    advapi32_RegSetValue(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def kernel32_GetThreadLocale(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, 0x40c)
-
-def kernel32_SetCurrentDirectory(jitter, get_str):
-    ret_ad, args = jitter.func_args_stdcall(['dir'])
-    dir_ = get_str(args.dir)
-    log.debug("SetCurrentDirectory('%s') = 1" % dir_)
-    winobjs.cur_dir = dir_
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-def kernel32_SetCurrentDirectoryW(jitter):
-    return kernel32_SetCurrentDirectory(jitter, lambda addr:get_win_str_w(jitter, addr))
-
-def kernel32_SetCurrentDirectoryA(jitter):
-    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 = get_win_str_w(jitter, args.ptr_str1)
-    s2 = get_win_str_w(jitter, args.ptr_str2)
-    log.info("strcat('%s','%s')" % (s1,s2))
-    set_win_str_w(jitter, args.ptr_str1, s1 + s2)
-    jitter.func_ret_cdecl(ret_ad, args.ptr_str1)
-
-
-def kernel32_GetLocaleInfo(jitter, funcname, set_str):
-    ret_ad, args = jitter.func_args_stdcall(["localeid", "lctype",
-                                             "lplcdata", "cchdata"])
-
-    buf = None
-    ret = 0
-    if args.localeid == 0x40c:
-        if args.lctype == 0x3:
-            buf = "ENGLISH"
-            buf = buf[:args.cchdata - 1]
-            set_str(args.lplcdata, buf)
-            ret = len(buf)
-    else:
-        raise ValueError('unimpl localeid')
-
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_GetLocaleInfoA(jitter):
-    kernel32_GetLocaleInfo(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
-
-
-def kernel32_GetLocaleInfoW(jitter):
-    kernel32_GetLocaleInfo(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
-
-
-def kernel32_TlsAlloc(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    winobjs.tls_index += 1
-    jitter.func_ret_stdcall(ret_ad, winobjs.tls_index)
-
-
-def kernel32_TlsFree(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["tlsindex"])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_TlsSetValue(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["tlsindex", "tlsvalue"])
-    winobjs.tls_values[args.tlsindex] = args.tlsvalue
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_TlsGetValue(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["tlsindex"])
-    if not args.tlsindex in winobjs.tls_values:
-        raise ValueError("unknown tls val", repr(args.tlsindex))
-    jitter.func_ret_stdcall(ret_ad, winobjs.tls_values[args.tlsindex])
-
-
-def user32_GetKeyboardType(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["typeflag"])
-
-    ret = 0
-    if args.typeflag == 0:
-        ret = 4
-    else:
-        raise ValueError('unimpl keyboard type')
-
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-class startupinfo(object):
-    """
-        typedef struct _STARTUPINFOA {
-          /* 00000000 */ DWORD  cb;
-          /* 00000004 */ LPSTR  lpReserved;
-          /* 00000008 */ LPSTR  lpDesktop;
-          /* 0000000C */ LPSTR  lpTitle;
-          /* 00000010 */ DWORD  dwX;
-          /* 00000014 */ DWORD  dwY;
-          /* 00000018 */ DWORD  dwXSize;
-          /* 0000001C */ DWORD  dwYSize;
-          /* 00000020 */ DWORD  dwXCountChars;
-          /* 00000024 */ DWORD  dwYCountChars;
-          /* 00000028 */ DWORD  dwFillAttribute;
-          /* 0000002C */ DWORD  dwFlags;
-          /* 00000030 */ WORD   wShowWindow;
-          /* 00000032 */ WORD   cbReserved2;
-          /* 00000034 */ LPBYTE lpReserved2;
-          /* 00000038 */ HANDLE hStdInput;
-          /* 0000003C */ HANDLE hStdOutput;
-          /* 00000040 */ HANDLE hStdError;
-        } STARTUPINFOA, *LPSTARTUPINFOA;
-
-    """
-    # TODO: fill with relevant values
-    # for now, struct is just a placeholder
-    cb = 0x0
-    lpReserved = 0x0
-    lpDesktop = 0x0
-    lpTitle = 0x0
-    dwX = 0x0
-    dwY = 0x0
-    dwXSize = 0x0
-    dwYSize = 0x0
-    dwXCountChars = 0x0
-    dwYCountChars = 0x0
-    dwFillAttribute = 0x0
-    dwFlags = 0x0
-    wShowWindow = 0x0
-    cbReserved2 = 0x0
-    lpReserved2 = 0x0
-    hStdInput = 0x0
-    hStdOutput = 0x0
-    hStdError = 0x0
-
-    def pack(self):
-        return struct.pack('IIIIIIIIIIIIHHIIII',
-                self.cb,
-                self.lpReserved,
-                self.lpDesktop,
-                self.lpTitle,
-                self.dwX,
-                self.dwY,
-                self.dwXSize,
-                self.dwYSize,
-                self.dwXCountChars,
-                self.dwYCountChars,
-                self.dwFillAttribute,
-                self.dwFlags,
-                self.wShowWindow,
-                self.cbReserved2,
-                self.lpReserved2,
-                self.hStdInput,
-                self.hStdOutput,
-                self.hStdError)
-
-
-def kernel32_GetStartupInfo(jitter, funcname, set_str):
-    """
-        void GetStartupInfo(
-          LPSTARTUPINFOW lpStartupInfo
-        );
-
-        Retrieves the contents of the STARTUPINFO structure that was specified
-        when the calling process was created.
-
-        https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getstartupinfow
-
-    """
-    ret_ad, args = jitter.func_args_stdcall(["ptr"])
-    jitter.vm.set_mem(args.ptr, startupinfo().pack())
-    jitter.func_ret_stdcall(ret_ad, args.ptr)
-
-
-def kernel32_GetStartupInfoA(jitter):
-    kernel32_GetStartupInfo(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value))
-
-
-def kernel32_GetStartupInfoW(jitter):
-    kernel32_GetStartupInfo(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value))
-
-
-def kernel32_GetCurrentThreadId(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, 0x113377)
-
-
-def kernel32_InitializeCriticalSection(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(["lpcritic"])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def user32_GetSystemMetrics(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["nindex"])
-
-    ret = 0
-    if args.nindex in [0x2a, 0x4a]:
-        ret = 0
-    else:
-        raise ValueError('unimpl index')
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def wsock32_WSAStartup(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["version", "pwsadata"])
-    jitter.vm.set_mem(args.pwsadata, b"\x01\x01\x02\x02WinSock 2.0\x00")
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def get_current_filetime():
-    """
-    Get current filetime
-    https://msdn.microsoft.com/en-us/library/ms724228
-    """
-    curtime = winobjs.current_datetime
-    unixtime = int(time.mktime(curtime.timetuple()))
-    filetime = (int(unixtime * 1000000 + curtime.microsecond) * 10 +
-                DATE_1601_TO_1970)
-    return filetime
-
-
-def unixtime_to_filetime(unixtime):
-    """
-    Convert unixtime to filetime
-    https://msdn.microsoft.com/en-us/library/ms724228
-    """
-    return (unixtime * 10000000) + DATE_1601_TO_1970
-
-
-def filetime_to_unixtime(filetime):
-    """
-    Convert filetime to unixtime
-    # https://msdn.microsoft.com/en-us/library/ms724228
-    """
-    return int((filetime - DATE_1601_TO_1970) // 10000000)
-
-
-def datetime_to_systemtime(curtime):
-
-    s = struct.pack('HHHHHHHH',
-                    curtime.year,      # year
-                    curtime.month,     # month
-                    curtime.weekday(), # dayofweek
-                    curtime.day,       # day
-                    curtime.hour,      # hour
-                    curtime.minute ,   # minutes
-                    curtime.second,    # seconds
-                    int(curtime.microsecond // 1000),  # millisec
-                    )
-    return s
-
-
-def kernel32_GetSystemTimeAsFileTime(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["lpSystemTimeAsFileTime"])
-
-    current_filetime = get_current_filetime()
-    filetime = struct.pack('II',
-                           current_filetime & 0xffffffff,
-                           (current_filetime>>32) & 0xffffffff)
-
-    jitter.vm.set_mem(args.lpSystemTimeAsFileTime, filetime)
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_GetLocalTime(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["lpsystemtime"])
-    systemtime = datetime_to_systemtime(winobjs.current_datetime)
-    jitter.vm.set_mem(args.lpsystemtime, systemtime)
-    jitter.func_ret_stdcall(ret_ad, args.lpsystemtime)
-
-
-def kernel32_GetSystemTime(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["lpsystemtime"])
-    systemtime = datetime_to_systemtime(winobjs.current_datetime)
-    jitter.vm.set_mem(args.lpsystemtime, systemtime)
-    jitter.func_ret_stdcall(ret_ad, args.lpsystemtime)
-
-
-def kernel32_CreateFileMapping(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["hfile", "lpattr", "flprotect",
-                                             "dwmaximumsizehigh",
-                                             "dwmaximumsizelow", "lpname"])
-
-    if args.hfile == 0xffffffff:
-        # Create null mapping
-        if args.dwmaximumsizehigh:
-            raise NotImplementedError("Untested case")
-        hmap = StringIO("\x00" * args.dwmaximumsizelow)
-        hmap_handle = winobjs.handle_pool.add('filemem', hmap)
-
-        ret = winobjs.handle_pool.add('filemapping', hmap_handle)
-    else:
-        if not args.hfile in winobjs.handle_pool:
-            raise ValueError('unknown handle')
-        ret = winobjs.handle_pool.add('filemapping', args.hfile)
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_CreateFileMappingA(jitter):
-    kernel32_CreateFileMapping(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def kernel32_CreateFileMappingW(jitter):
-    kernel32_CreateFileMapping(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def kernel32_MapViewOfFile(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hfile", "flprotect",
-                                             "dwfileoffsethigh",
-                                             "dwfileoffsetlow",
-                                             "length"])
-
-    if not args.hfile in winobjs.handle_pool:
-        raise ValueError('unknown handle')
-    hmap = winobjs.handle_pool[args.hfile]
-    if not hmap.info in winobjs.handle_pool:
-        raise ValueError('unknown file handle')
-
-    hfile_o = winobjs.handle_pool[hmap.info]
-    fd = hfile_o.info
-    fd.seek((args.dwfileoffsethigh << 32) | args.dwfileoffsetlow)
-    data = fd.read(args.length) if args.length else fd.read()
-    length = len(data)
-
-    log.debug('MapViewOfFile len: %x', len(data))
-
-    if not args.flprotect in ACCESS_DICT:
-        raise ValueError('unknown access dw!')
-
-    alloc_addr = winobjs.heap.alloc(jitter, len(data))
-    jitter.vm.set_mem(alloc_addr, data)
-
-    winobjs.handle_mapped[alloc_addr] = (hfile_o, args.dwfileoffsethigh,
-                                         args.dwfileoffsetlow, length)
-
-    jitter.func_ret_stdcall(ret_ad, alloc_addr)
-
-
-def kernel32_UnmapViewOfFile(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['ad'])
-
-    if not args.ad in winobjs.handle_mapped:
-        raise NotImplementedError("Untested case")
-    """
-    hfile_o, dwfileoffsethigh, dwfileoffsetlow, length = winobjs.handle_mapped[ad]
-    off = (dwfileoffsethigh<<32) | dwfileoffsetlow
-    s = jitter.vm.get_mem(ad, length)
-    hfile_o.info.seek(off)
-    hfile_o.info.write(s)
-    hfile_o.info.close()
-    """
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_GetDriveType(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(['pathname'])
-
-    p = get_str(args.pathname)
-    p = p.upper()
-
-    log.debug('Drive: %r', p)
-
-    ret = 0
-    if p[0] == "C":
-        ret = 3
-
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_GetDriveTypeA(jitter):
-    kernel32_GetDriveType(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def kernel32_GetDriveTypeW(jitter):
-    kernel32_GetDriveType(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def kernel32_GetDiskFreeSpace(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(["lprootpathname",
-                                             "lpsectorpercluster",
-                                             "lpbytespersector",
-                                             "lpnumberoffreeclusters",
-                                             "lptotalnumberofclusters"])
-    jitter.vm.set_u32(args.lpsectorpercluster, 8)
-    jitter.vm.set_u32(args.lpbytespersector, 0x200)
-    jitter.vm.set_u32(args.lpnumberoffreeclusters, 0x222222)
-    jitter.vm.set_u32(args.lptotalnumberofclusters, 0x333333)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_GetDiskFreeSpaceA(jitter):
-    kernel32_GetDiskFreeSpace(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr))
-
-
-def kernel32_GetDiskFreeSpaceW(jitter):
-    kernel32_GetDiskFreeSpace(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr))
-
-
-def kernel32_VirtualQuery(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["ad", "lpbuffer", "dwl"])
-
-    all_mem = jitter.vm.get_all_memory()
-    found = None
-    for basead, m in viewitems(all_mem):
-        if basead <= args.ad < basead + m['size']:
-            found = args.ad, m
-            break
-    if not found:
-        raise ValueError('cannot find mem', hex(args.ad))
-
-    if args.dwl != 0x1c:
-        raise ValueError('strange mem len', hex(args.dwl))
-    s = struct.pack('IIIIIII',
-                    args.ad,
-                    basead,
-                    ACCESS_DICT_INV[m['access']],
-                    m['size'],
-                    0x1000,
-                    ACCESS_DICT_INV[m['access']],
-                    0x01000000)
-    jitter.vm.set_mem(args.lpbuffer, s)
-    jitter.func_ret_stdcall(ret_ad, args.dwl)
-
-
-def kernel32_GetProcessAffinityMask(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hprocess",
-                                             "procaffmask",
-                                             "systemaffmask"])
-    jitter.vm.set_u32(args.procaffmask, 1)
-    jitter.vm.set_u32(args.systemaffmask, 1)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def msvcrt_rand(jitter):
-    ret_ad, _ = jitter.func_args_cdecl(0)
-    jitter.func_ret_stdcall(ret_ad, 0x666)
-
-def msvcrt_srand(jitter):
-    ret_ad, _ = jitter.func_args_cdecl(['seed'])
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-def msvcrt_wcslen(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["pwstr"])
-    s = get_win_str_w(jitter, args.pwstr)
-    jitter.func_ret_cdecl(ret_ad, len(s))
-
-def kernel32_SetFilePointer(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hwnd", "dinstance",
-                                             "p_dinstance_high",
-                                             "movemethod"])
-
-    if args.hwnd == winobjs.module_cur_hwnd:
-        pass
-    elif args.hwnd in winobjs.handle_pool:
-        pass
-    else:
-        raise ValueError('unknown hwnd!')
-
-    # data = None
-    if args.hwnd in winobjs.files_hwnd:
-        winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(args.dinstance, args.movemethod)
-    elif args.hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[args.hwnd]
-        wh.info.seek(args.dinstance, args.movemethod)
-    else:
-        raise ValueError('unknown filename')
-    jitter.func_ret_stdcall(ret_ad, args.dinstance)
-
-
-def kernel32_SetFilePointerEx(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hwnd", "dinstance_l",
-                                             "dinstance_h",
-                                             "pnewfileptr",
-                                             "movemethod"])
-    dinstance = args.dinstance_l | (args.dinstance_h << 32)
-    if dinstance:
-        raise ValueError('Not implemented')
-    if args.pnewfileptr:
-        raise ValueError('Not implemented')
-    if args.hwnd == winobjs.module_cur_hwnd:
-        pass
-    elif args.hwnd in winobjs.handle_pool:
-        pass
-    else:
-        raise ValueError('unknown hwnd!')
-
-    # data = None
-    if args.hwnd in winobjs.files_hwnd:
-        winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(dinstance, args.movemethod)
-    elif args.hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[args.hwnd]
-        wh.info.seek(dinstance, args.movemethod)
-    else:
-        raise ValueError('unknown filename')
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_SetEndOfFile(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['hwnd'])
-    if args.hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[args.hwnd]
-        wh.info.seek(0, 2)
-    else:
-        raise ValueError('unknown filename')
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_FlushFileBuffers(jitter):
-    ret_ad, args = jitter.func_args_stdcall(['hwnd'])
-    if args.hwnd in winobjs.handle_pool:
-        pass
-    else:
-        raise ValueError('unknown filename')
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_WriteFile(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpbuffer",
-                                             "nnumberofbytestowrite",
-                                             "lpnumberofbyteswrite",
-                                             "lpoverlapped"])
-    data = jitter.vm.get_mem(args.lpbuffer, args.nnumberofbytestowrite)
-
-    if args.hwnd == winobjs.module_cur_hwnd:
-        pass
-    elif args.hwnd in winobjs.handle_pool:
-        pass
-    else:
-        raise ValueError('unknown hwnd!')
-
-    if args.hwnd in winobjs.files_hwnd:
-        winobjs.files_hwnd[winobjs.module_cur_hwnd].write(data)
-    elif args.hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[args.hwnd]
-        wh.info.write(data)
-    else:
-        raise ValueError('unknown filename')
-
-    if (args.lpnumberofbyteswrite):
-        jitter.vm.set_u32(args.lpnumberofbyteswrite, len(data))
-
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def user32_IsCharUpperA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["c"])
-    ret = 0 if args.c & 0x20 else 1
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def user32_IsCharLowerA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["c"])
-    ret = 1 if args.c & 0x20 else 0
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-
-def kernel32_GetSystemDefaultLangID(jitter):
-    ret_ad, _ = jitter.func_args_stdcall(0)
-    jitter.func_ret_stdcall(ret_ad, 0x409)  # encglish
-
-
-def msvcrt_malloc(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["msize"])
-    addr = winobjs.heap.alloc(jitter, args.msize)
-    jitter.func_ret_cdecl(ret_ad, addr)
-
-
-def msvcrt_free(jitter):
-    ret_ad, _ = jitter.func_args_cdecl(["ptr"])
-    jitter.func_ret_cdecl(ret_ad, 0)
-
-
-def msvcrt_fseek(jitter):
-    ret_ad, args = jitter.func_args_cdecl(['stream', 'offset', 'orig'])
-    fd = jitter.vm.get_u32(args.stream + 0x10)
-
-    if not fd in winobjs.handle_pool:
-        raise NotImplementedError("Untested case")
-    o = winobjs.handle_pool[fd]
-    o.info.seek(args.offset, args.orig)
-    jitter.func_ret_cdecl(ret_ad, 0)
-
-
-def msvcrt_ftell(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["stream"])
-    fd = jitter.vm.get_u32(args.stream + 0x10)
-
-    if not fd in winobjs.handle_pool:
-        raise NotImplementedError("Untested case")
-    o = winobjs.handle_pool[fd]
-    off = o.info.tell()
-    jitter.func_ret_cdecl(ret_ad, off)
-
-
-def msvcrt_rewind(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["stream"])
-    fd = jitter.vm.get_u32(args.stream + 0x10)
-    if not fd in winobjs.handle_pool:
-        raise NotImplementedError("Untested case")
-    o = winobjs.handle_pool[fd]
-    # off = o.info.seek(0, 0)
-    jitter.func_ret_cdecl(ret_ad, 0)
-
-
-def msvcrt_fread(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["buf", "size", "nmemb", "stream"])
-    fd = jitter.vm.get_u32(args.stream + 0x10)
-    if not fd in winobjs.handle_pool:
-        raise NotImplementedError("Untested case")
-
-    data = winobjs.handle_pool[fd].info.read(args.size * args.nmemb)
-    jitter.vm.set_mem(args.buf, data)
-    jitter.func_ret_cdecl(ret_ad, args.nmemb)
-
-
-def msvcrt_fwrite(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["buf", "size", "nmemb", "stream"])
-    fd = jitter.vm.get_u32(args.stream + 0x10)
-    if not fd in winobjs.handle_pool:
-        raise NotImplementedError("Unknown file handle!")
-
-    data = jitter.vm.get_mem(args.buf, args.size*args.nmemb)
-    winobjs.handle_pool[fd].info.write(data)
-    jitter.func_ret_cdecl(ret_ad, args.nmemb)
-
-
-def msvcrt_fclose(jitter):
-    ret_ad, args = jitter.func_args_cdecl(['stream'])
-    fd = jitter.vm.get_u32(args.stream + 0x10)
-
-    if not fd in winobjs.handle_pool:
-        raise NotImplementedError("Untested case")
-    o = winobjs.handle_pool[fd]
-    # off = o.info.close()
-    jitter.func_ret_cdecl(ret_ad, 0)
-
-
-def msvcrt_atexit(jitter):
-    ret_ad, _ = jitter.func_args_cdecl(["func"])
-    jitter.func_ret_cdecl(ret_ad, 0)
-
-
-def user32_MessageBoxA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lptext",
-                                             "lpcaption", "utype"])
-
-    text = get_win_str_a(jitter, args.lptext)
-    caption = get_win_str_a(jitter, args.lpcaption)
-
-    log.info('Caption: %r Text: %r', caption, text)
-
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def kernel32_myGetTempPath(jitter, set_str):
-    ret_ad, args = jitter.func_args_stdcall(["l", "buf"])
-    l = 'c:\\temp\\'
-    if len(l) < args.l:
-        set_str(args.buf, l)
-    jitter.func_ret_stdcall(ret_ad, len(l))
-
-
-def kernel32_GetTempPathA(jitter):
-    kernel32_myGetTempPath(jitter, lambda addr,value: set_win_str_a(jitter, addr, value))
-
-
-def kernel32_GetTempPathW(jitter):
-    kernel32_myGetTempPath(jitter, lambda addr,value: set_win_str_w(jitter, addr, value))
-
-
-temp_num = 0
-
-
-def kernel32_GetTempFileNameA(jitter):
-    global temp_num
-    ret_ad, args = jitter.func_args_stdcall(["path", "ext", "unique", "buf"])
-
-    temp_num += 1
-    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.encode('utf-8'))
-
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-class win32_find_data(object):
-    fileattrib = 0
-    creationtime = 0
-    lastaccesstime = 0
-    lastwritetime = 0
-    filesizehigh = 0
-    filesizelow = 0
-    dwreserved0 = 0
-    dwreserved1 = 0x1337beef
-    cfilename = ""
-    alternamefilename = ""
-
-    def __init__(self, **kargs):
-        for k, v in viewitems(kargs):
-            setattr(self, k, v)
-
-    def toStruct(self, encode_str=encode_win_str_w):
-        s = struct.pack('=IQQQIIII',
-                        self.fileattrib,
-                        self.creationtime,
-                        self.lastaccesstime,
-                        self.lastwritetime,
-                        self.filesizehigh,
-                        self.filesizelow,
-                        self.dwreserved0,
-                        self.dwreserved1)
-        fname = encode_str(self.cfilename) + b'\x00' * MAX_PATH
-        fname = fname[:MAX_PATH]
-        s += fname
-        fname = encode_str(self.alternamefilename) + b'\x00' * 14
-        fname = fname[:14]
-        s += fname
-        return s
-
-
-class find_data_mngr(object):
-
-    def __init__(self):
-        self.patterns = {}
-        self.flist = []
-        # handle number -> (flist index, current index in list)
-        self.handles = {}
-
-    def add_list(self, pattern, flist):
-        index = len(self.flist)
-        self.flist.append(flist)
-
-        self.patterns[pattern] = index
-
-    def findfirst(self, pattern):
-        assert(pattern in self.patterns)
-        findex = self.patterns[pattern]
-        h = len(self.handles) + 1
-        self.handles[h] = [findex, 0]
-        return h
-
-    def findnext(self, h):
-        assert(h in self.handles)
-        findex, index = self.handles[h]
-        if index >= len(self.flist[findex]):
-            return None
-        fname = self.flist[findex][index]
-        self.handles[h][1] += 1
-
-        return fname
-
-def my_FindFirstFile(jitter, pfilepattern, pfindfiledata, get_win_str, encode_str):
-    filepattern = get_win_str(jitter, pfilepattern)
-    h = winobjs.find_data.findfirst(filepattern)
-
-    fname = winobjs.find_data.findnext(h)
-    fdata = win32_find_data(cfilename=fname)
-
-    jitter.vm.set_mem(pfindfiledata, fdata.toStruct(encode_str=encode_str))
-    return h
-
-def kernel32_FindFirstFileA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["pfilepattern", "pfindfiledata"])
-    h = my_FindFirstFile(jitter, args.pfilepattern, args.pfindfiledata,
-                           get_win_str_a, encode_win_str_a)
-    jitter.func_ret_stdcall(ret_ad, h)
-
-def kernel32_FindFirstFileW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["pfilepattern", "pfindfiledata"])
-    h = my_FindFirstFile(jitter, args.pfilepattern, args.pfindfiledata,
-                           get_win_str_w, encode_win_str_w)
-    jitter.func_ret_stdcall(ret_ad, h)
-
-def kernel32_FindFirstFileExA(jitter):
-    ret_ad, args = jitter.func_args_stdcall([
-        "lpFileName",
-        "fInfoLevelId",
-        "lpFindFileData",
-        "fSearchOp",
-        "lpSearchFilter",
-        "dwAdditionalFlags"])
-    h = my_FindFirstFile(jitter, args.lpFileName, args.lpFindFileData,
-                         get_win_str_a, encode_win_str_a)
-    jitter.func_ret_stdcall(ret_ad, h)
-
-def kernel32_FindFirstFileExW(jitter):
-    ret_ad, args = jitter.func_args_stdcall([
-        "lpFileName",
-        "fInfoLevelId",
-        "lpFindFileData",
-        "fSearchOp",
-        "lpSearchFilter",
-        "dwAdditionalFlags"])
-    h = my_FindFirstFile(jitter, args.lpFileName, args.lpFindFileData,
-                         get_win_str_w, encode_win_str_w)
-    jitter.func_ret_stdcall(ret_ad, h)
-
-def my_FindNextFile(jitter, encode_str):
-    ret_ad, args = jitter.func_args_stdcall(["handle", "pfindfiledata"])
-    fname = winobjs.find_data.findnext(args.handle)
-    if fname is None:
-        winobjs.lastwin32error = 0x12 # ERROR_NO_MORE_FILES
-        ret = 0
-    else:
-        ret = 1
-        fdata = win32_find_data(cfilename=fname)
-        jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct(encode_str=encode_str))
-    jitter.func_ret_stdcall(ret_ad, ret)
-
-kernel32_FindNextFileA = lambda jitter: my_FindNextFile(jitter, encode_win_str_a)
-kernel32_FindNextFileW = lambda jitter: my_FindNextFile(jitter, encode_win_str_w)
-
-def kernel32_GetNativeSystemInfo(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["sys_ptr"])
-    sysinfo = systeminfo()
-    jitter.vm.set_mem(args.sys_ptr, sysinfo.pack())
-    jitter.func_ret_stdcall(ret_ad, 0)
-
-
-def raw2guid(r):
-    o = struct.unpack('IHHHBBBBBB', r)
-    return '{%.8X-%.4X-%.4X-%.4X-%.2X%.2X%.2X%.2X%.2X%.2X}' % o
-
-
-digs = string.digits + string.ascii_lowercase
-
-
-def int2base(x, base):
-    if x < 0:
-        sign = -1
-    elif x == 0:
-        return '0'
-    else:
-        sign = 1
-    x *= sign
-    digits = []
-    while x:
-        digits.append(digs[x % base])
-        x /= base
-    if sign < 0:
-        digits.append('-')
-    digits.reverse()
-    return ''.join(digits)
-
-
-def msvcrt__ultow(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["value", "p", "radix"])
-
-    value = args.value & 0xFFFFFFFF
-    if not args.radix in [10, 16, 20]:
-        raise ValueError("Not tested")
-    s = int2base(value, args.radix)
-    set_win_str_w(jitter, args.p, s)
-    jitter.func_ret_cdecl(ret_ad, args.p)
-
-
-def msvcrt_myfopen(jitter, get_str):
-    ret_ad, args = jitter.func_args_cdecl(["pfname", "pmode"])
-
-    fname = get_str(args.pfname)
-    rw = get_str(args.pmode)
-    log.info("fopen %r, %r", fname, rw)
-
-    if rw in ['r', 'rb', 'wb+','wb','wt']:
-        sb_fname = windows_to_sbpath(fname)
-        h = open(sb_fname, rw)
-        eax = winobjs.handle_pool.add(sb_fname, h)
-        dwsize = 0x20
-        alloc_addr = winobjs.heap.alloc(jitter, dwsize)
-        pp = pck32(0x11112222) + pck32(0) + pck32(0) + pck32(0) + pck32(eax)
-        jitter.vm.set_mem(alloc_addr, pp)
-
-    else:
-        raise ValueError('unknown access mode %s' % rw)
-
-    jitter.func_ret_cdecl(ret_ad, alloc_addr)
-
-
-def msvcrt__wfopen(jitter):
-    msvcrt_myfopen(jitter, lambda addr:get_win_str_w(jitter, addr))
-
-
-def msvcrt_fopen(jitter):
-    msvcrt_myfopen(jitter, lambda addr:get_win_str_a(jitter, addr))
-
-
-def msvcrt_strlen(jitter):
-    ret_ad, args = jitter.func_args_cdecl(["src"])
-
-    s = get_win_str_a(jitter, args.src)
-    jitter.func_ret_cdecl(ret_ad, len(s))
-
-
-def kernel32_QueryPerformanceCounter(jitter):
-    ret_ad, args = jitter.func_args_stdcall(["lpPerformanceCount"])
-    jitter.vm.set_mem(args.lpPerformanceCount, struct.pack('<Q', 0x1))
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_InitializeCriticalSectionEx(jitter):
-    '''
-      LPCRITICAL_SECTION lpCriticalSection,
-      DWORD              dwSpinCount,
-      DWORD              Flags
-    '''
-    ret_ad, args = jitter.func_args_stdcall(["lpCriticalSection", "dwSpinCount", "Flags"])
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_EnterCriticalSection(jitter):
-    '''
-    void EnterCriticalSection(
-      LPCRITICAL_SECTION lpCriticalSection
-    );
-    '''
-    ret_ad, args = jitter.func_args_stdcall(["lpCriticalSection"])
-    jitter.func_ret_stdcall(ret_ad, 0x0)
-
-
-def kernel32_LeaveCriticalSection(jitter):
-    '''
-    void LeaveCriticalSection(
-      LPCRITICAL_SECTION lpCriticalSection
-    );
-    '''
-    ret_ad, args = jitter.func_args_stdcall(["lpCriticalSection"])
-    jitter.func_ret_stdcall(ret_ad, 0x0)
-
-
-class FLS(object):
-    def __init__(self):
-        self.slots = []
-
-    def kernel32_FlsAlloc(self, jitter):
-        '''
-        DWORD FlsAlloc(
-          PFLS_CALLBACK_FUNCTION lpCallback
-        );
-        '''
-        ret_ad, args = jitter.func_args_stdcall(["lpCallback"])
-        index = len(self.slots)
-        self.slots.append(0x0)
-        jitter.func_ret_stdcall(ret_ad, index)
-
-    def kernel32_FlsSetValue(self, jitter):
-        '''
-        BOOL FlsSetValue(
-          DWORD dwFlsIndex,
-          PVOID lpFlsData
-        );
-        '''
-        ret_ad, args = jitter.func_args_stdcall(["dwFlsIndex", "lpFlsData"])
-        self.slots[args.dwFlsIndex] = args.lpFlsData
-        jitter.func_ret_stdcall(ret_ad, 1)
-
-    def kernel32_FlsGetValue(self, jitter):
-        '''
-        PVOID FlsGetValue(
-          DWORD dwFlsIndex
-        );
-        '''
-        ret_ad, args = jitter.func_args_stdcall(["dwFlsIndex"])
-        jitter.func_ret_stdcall(ret_ad, self.slots[args.dwFlsIndex])
-
-fls = FLS()
-
-
-def kernel32_GetProcessHeap(jitter):
-    '''
-    HANDLE GetProcessHeap();
-    '''
-    ret_ad, args = jitter.func_args_stdcall([])
-    hHeap = 0x67676767
-    jitter.func_ret_stdcall(ret_ad, hHeap)
-
-
-STD_INPUT_HANDLE = 0xfffffff6
-STD_OUTPUT_HANDLE = 0xfffffff5
-STD_ERROR_HANDLE = 0xfffffff4
-
-
-def kernel32_GetStdHandle(jitter):
-    '''
-    HANDLE WINAPI GetStdHandle(
-      _In_ DWORD nStdHandle
-    );
-
-    STD_INPUT_HANDLE (DWORD)-10
-    The standard input device. Initially, this is the console input buffer, CONIN$.
-
-    STD_OUTPUT_HANDLE (DWORD)-11
-    The standard output device. Initially, this is the active console screen buffer, CONOUT$.
-
-    STD_ERROR_HANDLE (DWORD)-12
-    The standard error device. Initially, this is the active console screen buffer, CONOUT$.
-    '''
-    ret_ad, args = jitter.func_args_stdcall(["nStdHandle"])
-    jitter.func_ret_stdcall(ret_ad, {
-        STD_OUTPUT_HANDLE: 1,
-        STD_ERROR_HANDLE: 2,
-        STD_INPUT_HANDLE: 3,
-    }[args.nStdHandle])
-
-
-FILE_TYPE_UNKNOWN = 0x0000
-FILE_TYPE_CHAR = 0x0002
-
-
-def kernel32_GetFileType(jitter):
-    '''
-    DWORD GetFileType(
-      HANDLE hFile
-    );
-    '''
-    ret_ad, args = jitter.func_args_stdcall(["hFile"])
-    jitter.func_ret_stdcall(ret_ad, {
-        # STD_OUTPUT_HANDLE
-        1: FILE_TYPE_CHAR,
-        # STD_ERROR_HANDLE
-        2: FILE_TYPE_CHAR,
-        # STD_INPUT_HANDLE
-        3: FILE_TYPE_CHAR,
-    }.get(args.hFile, FILE_TYPE_UNKNOWN))
-
-
-def kernel32_IsProcessorFeaturePresent(jitter):
-    '''
-    BOOL IsProcessorFeaturePresent(
-      DWORD ProcessorFeature
-    );
-    '''
-    ret_ad, args = jitter.func_args_stdcall(["ProcessorFeature"])
-    jitter.func_ret_stdcall(ret_ad, {
-        # PF_ARM_64BIT_LOADSTORE_ATOMIC
-        25: False,
-        # PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE
-        24: False,
-        # PF_ARM_EXTERNAL_CACHE_AVAILABLE
-        26: False,
-        # PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE
-        27: False,
-        # PF_ARM_VFP_32_REGISTERS_AVAILABLE
-        18: False,
-        # PF_3DNOW_INSTRUCTIONS_AVAILABLE
-        7: False,
-        # PF_CHANNELS_ENABLED
-        16: True,
-        # PF_COMPARE_EXCHANGE_DOUBLE
-        2: False,
-        # PF_COMPARE_EXCHANGE128
-        14: False,
-        # PF_COMPARE64_EXCHANGE128
-        15: False,
-        # PF_FASTFAIL_AVAILABLE
-        23: False,
-        # PF_FLOATING_POINT_EMULATED
-        1: False,
-        # PF_FLOATING_POINT_PRECISION_ERRATA
-        0: True,
-        # PF_MMX_INSTRUCTIONS_AVAILABLE
-        3: True,
-        # PF_NX_ENABLED
-        12: True,
-        # PF_PAE_ENABLED
-        9: True,
-        # PF_RDTSC_INSTRUCTION_AVAILABLE
-        8: True,
-        # PF_RDWRFSGSBASE_AVAILABLE
-        22: True,
-        # PF_SECOND_LEVEL_ADDRESS_TRANSLATION
-        20: True,
-        # PF_SSE3_INSTRUCTIONS_AVAILABLE
-        13: True,
-        # PF_VIRT_FIRMWARE_ENABLED
-        21: False,
-        # PF_XMMI_INSTRUCTIONS_AVAILABLE
-        6: True,
-        # PF_XMMI64_INSTRUCTIONS_AVAILABLE
-        10: True,
-        # PF_XSAVE_ENABLED
-        17: False,
-    }[args.ProcessorFeature])
-
-
-def kernel32_GetACP(jitter):
-    '''
-    UINT GetACP();
-    '''
-    ret_ad, args = jitter.func_args_stdcall([])
-    # Windows-1252: Latin 1 / Western European  Superset of ISO-8859-1 (without C1 controls).
-    jitter.func_ret_stdcall(ret_ad, 1252)
-
-
-# ref: https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers
-VALID_CODE_PAGES = {
-    37,437,500,708,709,710,720,737,775,850,852,855,857,858,860,861,862,863,864,865,866,869,870,874,875,
-    932,936,949,950,1026,1047,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1200,1201,1250,1251,1252,
-    1253,1254,1255,1256,1257,1258,1361,10000,10001,10002,10003,10004,10005,10006,10007,10008,10010,10017,
-    10021,10029,10079,10081,10082,12000,12001,20000,20001,20002,20003,20004,20005,20105,20106,20107,20108,
-    20127,20261,20269,20273,20277,20278,20280,20284,20285,20290,20297,20420,20423,20424,20833,20838,20866,
-    20871,20880,20905,20924,20932,20936,20949,21025,21027,21866,28591,28592,28593,28594,28595,28596,28597,
-    28598,28599,28603,28605,29001,38598,50220,50221,50222,50225,50227,50229,50930,50931,50933,50935,50936,
-    50937,50939,51932,51936,51949,51950,52936,54936,57002,57003,57004,57005,57006,57007,57008,57009,57010,
-    57011,65000,65001
-}
-
-
-def kernel32_IsValidCodePage(jitter):
-    '''
-    BOOL IsValidCodePage(
-      UINT CodePage
-    );
-    '''
-    ret_ad, args = jitter.func_args_stdcall(["CodePage"])
-    jitter.func_ret_stdcall(ret_ad, args.CodePage in VALID_CODE_PAGES)
-
-
-def kernel32_GetCPInfo(jitter):
-    '''
-    BOOL GetCPInfo(
-      UINT     CodePage,
-      LPCPINFO lpCPInfo
-    );
-    '''
-    ret_ad, args = jitter.func_args_stdcall(["CodePage", "lpCPInfo"])
-    assert args.CodePage == 1252
-    # ref: http://www.rensselaer.org/dept/cis/software/g77-mingw32/include/winnls.h
-    #define MAX_LEADBYTES       12
-    #define MAX_DEFAULTCHAR	2
-    jitter.vm.set_mem(args.lpCPInfo, struct.pack('<I', 0x1) + b'??' + b'\x00' * 12)
-    jitter.func_ret_stdcall(ret_ad, 1)
-
-
-def kernel32_GetStringTypeW(jitter):
-    """
-        BOOL GetStringTypeW(
-          DWORD                         dwInfoType,
-          _In_NLS_string_(cchSrc)LPCWCH lpSrcStr,
-          int                           cchSrc,
-          LPWORD                        lpCharType
-        );
-
-        Retrieves character type information for the characters in the specified
-        Unicode source string. For each character in the string, the function
-        sets one or more bits in the corresponding 16-bit element of the output
-        array. Each bit identifies a given character type, for example, letter,
-        digit, or neither.
-
-    """
-    # These types support ANSI C and POSIX (LC_CTYPE) character typing
-    # functions.A bitwise-OR of these values is retrieved in the array in the
-    # output buffer when dwInfoType is set to CT_CTYPE1. For DBCS locales, the
-    # type attributes apply to both narrow characters and wide characters. The
-    # Japanese hiragana and katakana characters, and the kanji ideograph
-    # characters all have the C1_ALPHA attribute.
-    CT_TYPE1 = 0x01
-    # TODO handle other types of information
-    # (CT_TYPE2, CT_TYPE3)
-    # for now, they raise NotImplemented
-    CT_TYPE2 = 0x02
-    CT_TYPE3 = 0x03
-
-    C1_UPPER   = 0x0001  # Uppercase
-    C1_LOWER   = 0x0002  # Lowercase
-    C1_DIGIT   = 0x0004  # Decimal digits
-    C1_SPACE   = 0x0008  # Space characters
-    C1_PUNCT   = 0x0010  # Punctuation
-    C1_CNTRL   = 0x0020  # Control characters
-    C1_BLANK   = 0x0040  # Blank characters
-    C1_XDIGIT  = 0x0080  # Hexadecimal digits
-    C1_ALPHA   = 0x0100  # Any linguistic character: alphabetical, syllabary, or ideographic
-    C1_DEFINED = 0x0200  # A defined character, but not one of the other C1_* types
-
-    # the following sets have been generated from the Linux python library curses
-    # e.g., C1_PUNCT_SET = [chr(i) for i in range(256) if curses.ascii.ispunct(chr(i))]
-    C1_PUNCT_SET = ['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',',
-            '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']',
-            '^', '_', '`', '{', '|', '}', '~']
-    C1_CNTRL_SET = ['\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06',
-            '\x07', '\x08', '\t', '\n', '\x0b', '\x0c', '\r', '\x0e', '\x0f',
-            '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17',
-            '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f',
-            '\x7f']
-    C1_BLANK_SET = ['\t', ' ']
-    C1_XDIGIT_SET = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A',
-            'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f']
-
-    ret, args = jitter.func_args_stdcall(['dwInfoType', 'lpSrcStr', 'cchSrc',
-        'lpCharType'])
-    s = jitter.vm.get_mem(args.lpSrcStr, args.cchSrc).decode("utf-16")
-    if args.dwInfoType == CT_TYPE1:
-        # iterate over characters from the decoded W string
-        for i, c in enumerate(s):
-            # TODO handle non-ascii characters
-            if not c.isascii():
-                continue
-            val = 0
-            if c.isupper():
-                val |= C1_UPPER
-            if c.islower():
-                val |= C1_LOWER
-            if c.isdigit():
-                val |= C1_DIGIT
-            if c.isspace():
-                val |= C1_SPACE
-            if c in C1_PUNCT_SET:
-                val |= C1_PUNCT
-            if c in C1_CNTRL_SET:
-                val |= C1_CNTRL
-            if c in C1_BLANK_SET:
-                val |= C1_BLANK
-            if c in C1_XDIGIT_SET:
-                val |= C1_XDIGIT
-            if c.isalpha():
-                val |= C1_ALPHA
-            if val == 0:
-                val = C1_DEFINED
-            jitter.vm.set_u16(args.lpCharType + i * 2, val)
-    elif args.dwInfoType == CT_TYPE2:
-        raise NotImplemented
-    elif args.dwInfoType == CT_TYPE3:
-        raise NotImplemented
-    else:
-        raise ValueError("CT_TYPE unknown: %i" % args.dwInfoType)
-    jitter.func_ret_stdcall(ret, 1)
-    return True
diff --git a/miasm/os_dep/win_api_x86_32_seh.py b/miasm/os_dep/win_api_x86_32_seh.py
deleted file mode 100644
index 57416477..00000000
--- a/miasm/os_dep/win_api_x86_32_seh.py
+++ /dev/null
@@ -1,705 +0,0 @@
-#-*- coding:utf-8 -*-
-
-#
-# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net>
-#
-# This program is free software; you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-#
-import logging
-import os
-import struct
-
-from future.utils import viewitems
-
-from miasm.loader import pe_init
-
-from miasm.jitter.csts import PAGE_READ, PAGE_WRITE
-from miasm.core.utils import pck32
-import miasm.arch.x86.regs as x86_regs
-
-from miasm.os_dep.win_32_structs import LdrDataEntry, ListEntry, \
-    TEB, NT_TIB, PEB, PEB_LDR_DATA, ContextException, \
-    EXCEPTION_REGISTRATION_RECORD, EXCEPTION_RECORD
-
-# Constants Windows
-EXCEPTION_BREAKPOINT = 0x80000003
-EXCEPTION_SINGLE_STEP = 0x80000004
-EXCEPTION_ACCESS_VIOLATION = 0xc0000005
-EXCEPTION_INT_DIVIDE_BY_ZERO = 0xc0000094
-EXCEPTION_PRIV_INSTRUCTION = 0xc0000096
-EXCEPTION_ILLEGAL_INSTRUCTION = 0xc000001d
-
-
-log = logging.getLogger("seh_helper")
-console_handler = logging.StreamHandler()
-console_handler.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s"))
-log.addHandler(console_handler)
-log.setLevel(logging.INFO)
-
-# fs:[0] Page (TIB)
-tib_address = 0x7ff70000
-PEB_AD = 0x7ffdf000
-LDR_AD = 0x340000
-DEFAULT_SEH = 0x7ffff000
-
-MAX_MODULES = 0x40
-
-peb_address = PEB_AD
-peb_ldr_data_offset = 0x1ea0
-peb_ldr_data_address = LDR_AD + peb_ldr_data_offset
-
-
-modules_list_offset = 0x1f00
-
-InInitializationOrderModuleList_offset = 0x1ee0
-InInitializationOrderModuleList_address = LDR_AD + \
-    InInitializationOrderModuleList_offset
-
-InLoadOrderModuleList_offset = 0x1ee0 + \
-    MAX_MODULES * 0x1000
-InLoadOrderModuleList_address = LDR_AD + \
-    InLoadOrderModuleList_offset
-
-
-process_environment_address = 0x10000
-process_parameters_address = 0x200000
-
-return_from_exception = 0x6eadbeef
-
-
-name2module = []
-main_pe = None
-main_pe_name = "c:\\xxx\\toto.exe"
-
-MAX_SEH = 5
-
-
-def build_teb(jitter, teb_address):
-    """
-    Build TEB information using following structure:
-
-    @jitter: jitter instance
-    @teb_address: the TEB address
-    """
-
-    # Only allocate space for ExceptionList/ProcessEnvironmentBlock/Self
-    jitter.vm.add_memory_page(
-        teb_address,
-        PAGE_READ | PAGE_WRITE,
-        b"\x00" * NT_TIB.get_offset("StackBase"),
-        "TEB.NtTib.ExceptionList"
-    )
-    jitter.vm.add_memory_page(
-        teb_address + NT_TIB.get_offset("Self"),
-        PAGE_READ | PAGE_WRITE,
-        b"\x00" * (NT_TIB.sizeof() - NT_TIB.get_offset("Self")),
-        "TEB.NtTib.Self"
-    )
-    jitter.vm.add_memory_page(
-        teb_address + TEB.get_offset("ProcessEnvironmentBlock"),
-        PAGE_READ | PAGE_WRITE,
-        b"\x00" * (
-            TEB.get_offset("LastErrorValue") -
-            TEB.get_offset("ProcessEnvironmentBlock")
-        ),
-        "TEB.ProcessEnvironmentBlock"
-    )
-    Teb = TEB(jitter.vm, teb_address)
-    Teb.NtTib.ExceptionList = DEFAULT_SEH
-    Teb.NtTib.Self = teb_address
-    Teb.ProcessEnvironmentBlock = peb_address
-
-def build_peb(jitter, peb_address):
-    """
-    Build PEB information using following structure:
-
-    @jitter: jitter instance
-    @peb_address: the PEB address
-    """
-
-    if main_pe:
-        offset, length = 8, 4
-    else:
-        offset, length = 0xC, 0
-    length += 4
-
-    jitter.vm.add_memory_page(
-        peb_address + offset,
-        PAGE_READ | PAGE_WRITE,
-        b"\x00" * length,
-        "PEB + 0x%x" % offset
-    )
-
-    Peb = PEB(jitter.vm, peb_address)
-    if main_pe:
-        Peb.ImageBaseAddress = main_pe.NThdr.ImageBase
-    Peb.Ldr = peb_ldr_data_address
-
-
-def build_ldr_data(jitter, modules_info):
-    """
-    Build Loader information using following structure:
-
-    +0x000 Length                          : Uint4B
-    +0x004 Initialized                     : UChar
-    +0x008 SsHandle                        : Ptr32 Void
-    +0x00c InLoadOrderModuleList           : _LIST_ENTRY
-    +0x014 InMemoryOrderModuleList         : _LIST_ENTRY
-    +0x01C InInitializationOrderModuleList         : _LIST_ENTRY
-    # dummy dll base
-    +0x024 DllBase : Ptr32 Void
-
-    @jitter: jitter instance
-    @modules_info: LoadedModules instance
-
-    """
-    # ldr offset pad
-    offset = 0xC
-    addr = LDR_AD + peb_ldr_data_offset
-    ldrdata = PEB_LDR_DATA(jitter.vm, addr)
-
-    main_pe = modules_info.name2module.get(main_pe_name, None)
-    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
-
-
-    size = 0
-    if main_pe:
-        size += ListEntry.sizeof() * 2
-        main_addr_entry = modules_info.module2entry[main_pe]
-    if ntdll_pe:
-        size += ListEntry.sizeof()
-        ntdll_addr_entry = modules_info.module2entry[ntdll_pe]
-
-    jitter.vm.add_memory_page(
-        addr + offset,
-        PAGE_READ | PAGE_WRITE,
-        b"\x00" * size,
-        "Loader struct"
-    )  # (ldrdata.get_size() - offset))
-
-    last_module = modules_info.module2entry[
-        modules_info.modules[-1]]
-
-    if main_pe:
-        ldrdata.InLoadOrderModuleList.flink = main_addr_entry
-        ldrdata.InLoadOrderModuleList.blink = last_module
-
-
-        ldrdata.InMemoryOrderModuleList.flink = main_addr_entry + \
-            LdrDataEntry.get_type().get_offset("InMemoryOrderLinks")
-        ldrdata.InMemoryOrderModuleList.blink = last_module + \
-            LdrDataEntry.get_type().get_offset("InMemoryOrderLinks")
-    if ntdll_pe:
-        ldrdata.InInitializationOrderModuleList.flink = ntdll_addr_entry + \
-            LdrDataEntry.get_type().get_offset("InInitializationOrderLinks")
-        ldrdata.InInitializationOrderModuleList.blink = last_module + \
-                LdrDataEntry.get_type().get_offset("InInitializationOrderLinks")
-
-    # Add dummy dll base
-    jitter.vm.add_memory_page(peb_ldr_data_address + 0x24,
-                              PAGE_READ | PAGE_WRITE, pck32(0),
-                              "Loader struct dummy dllbase")
-
-
-class LoadedModules(object):
-
-    """Class representing modules in memory"""
-
-    def __init__(self):
-        self.modules = []
-        self.name2module = {}
-        self.module2entry = {}
-        self.module2name = {}
-
-    def add(self, name, module, module_entry):
-        """Track a new module
-        @name: module name (with extension)
-        @module: module object
-        @module_entry: address of the module entry
-        """
-
-        self.modules.append(module)
-        self.name2module[name] = module
-        self.module2entry[module] = module_entry
-        self.module2name[module] = name
-
-    def __repr__(self):
-        return "\n".join(str(x) for x in viewitems(self.name2module))
-
-
-def create_modules_chain(jitter, name2module):
-    """
-    Create the modules entries. Those modules are not linked in this function.
-
-    @jitter: jitter instance
-    @name2module: dict containing association between name and its pe instance
-    """
-
-    modules_info = LoadedModules()
-    base_addr = LDR_AD + modules_list_offset  # XXXX
-    offset_name = 0x500
-    offset_path = 0x600
-
-    out = ""
-    for i, (fname, pe_obj) in enumerate(viewitems(name2module), 1):
-        if pe_obj is None:
-            log.warning("Unknown module: omitted from link list (%r)",
-                        fname)
-            continue
-        addr = base_addr + i * 0x1000
-        bpath = fname.replace('/', '\\')
-        bname_str = os.path.split(fname)[1].lower()
-        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)
-
-        # Allocate a partial LdrDataEntry (0-Flags)
-        jitter.vm.add_memory_page(
-            addr,
-            PAGE_READ | PAGE_WRITE,
-            b"\x00" * LdrDataEntry.get_offset("Flags"),
-            "Module info %r" % bname_str
-        )
-
-        LdrEntry = LdrDataEntry(jitter.vm, addr)
-
-        LdrEntry.DllBase = pe_obj.NThdr.ImageBase
-        LdrEntry.EntryPoint = pe_obj.Opthdr.AddressOfEntryPoint
-        LdrEntry.SizeOfImage = pe_obj.NThdr.sizeofimage
-        LdrEntry.FullDllName.length = len(bname_unicode)
-        LdrEntry.FullDllName.maxlength = len(bname_unicode) + 2
-        LdrEntry.FullDllName.data = addr + offset_path
-        LdrEntry.BaseDllName.length = len(bname_unicode)
-        LdrEntry.BaseDllName.maxlength = len(bname_unicode) + 2
-        LdrEntry.BaseDllName.data = addr + offset_name
-
-        jitter.vm.add_memory_page(
-            addr + offset_name,
-            PAGE_READ | PAGE_WRITE,
-            bname_unicode + b"\x00" * 2,
-            "Module name %r" % bname_str
-        )
-
-        if isinstance(bpath, bytes):
-            bpath = bpath.decode('utf8')
-        bpath_unicode = bpath.encode('utf-16le')
-        jitter.vm.add_memory_page(
-            addr + offset_path,
-            PAGE_READ | PAGE_WRITE,
-            bpath_unicode + b"\x00" * 2,
-            "Module path %r" % bname_str
-        )
-
-    return modules_info
-
-
-def set_link_list_entry(jitter, loaded_modules, modules_info, offset):
-    for i, module in enumerate(loaded_modules):
-        cur_module_entry = modules_info.module2entry[module]
-        prev_module = loaded_modules[(i - 1) % len(loaded_modules)]
-        next_module = loaded_modules[(i + 1) % len(loaded_modules)]
-        prev_module_entry = modules_info.module2entry[prev_module]
-        next_module_entry = modules_info.module2entry[next_module]
-        if i == 0:
-            prev_module_entry = peb_ldr_data_address + 0xC
-        if i == len(loaded_modules) - 1:
-            next_module_entry = peb_ldr_data_address + 0xC
-
-        list_entry = ListEntry(jitter.vm, cur_module_entry + offset)
-        list_entry.flink = next_module_entry + offset
-        list_entry.blink = prev_module_entry + offset
-
-
-
-def fix_InLoadOrderModuleList(jitter, modules_info):
-    """Fix InLoadOrderModuleList double link list. First module is the main pe,
-    then ntdll, kernel32.
-
-    @jitter: the jitter instance
-    @modules_info: the LoadedModules instance
-    """
-
-    log.debug("Fix InLoadOrderModuleList")
-    main_pe = modules_info.name2module.get(main_pe_name, None)
-    kernel32_pe = modules_info.name2module.get("kernel32.dll", None)
-    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
-    special_modules = [main_pe, kernel32_pe, ntdll_pe]
-    if not all(special_modules):
-        log.warn(
-            'No main pe, ldr data will be unconsistant %r', special_modules)
-        loaded_modules = modules_info.modules
-    else:
-        loaded_modules = [module for module in modules_info.modules
-                          if module not in special_modules]
-        loaded_modules[0:0] = [main_pe]
-        loaded_modules[1:1] = [ntdll_pe]
-        loaded_modules[2:2] = [kernel32_pe]
-
-    set_link_list_entry(jitter, loaded_modules, modules_info, 0x0)
-
-
-def fix_InMemoryOrderModuleList(jitter, modules_info):
-    """Fix InMemoryOrderLinks double link list. First module is the main pe,
-    then ntdll, kernel32.
-
-    @jitter: the jitter instance
-    @modules_info: the LoadedModules instance
-    """
-
-    log.debug("Fix InMemoryOrderModuleList")
-    main_pe = modules_info.name2module.get(main_pe_name, None)
-    kernel32_pe = modules_info.name2module.get("kernel32.dll", None)
-    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
-    special_modules = [main_pe, kernel32_pe, ntdll_pe]
-    if not all(special_modules):
-        log.warn('No main pe, ldr data will be unconsistant')
-        loaded_modules = modules_info.modules
-    else:
-        loaded_modules = [module for module in modules_info.modules
-                          if module not in special_modules]
-        loaded_modules[0:0] = [main_pe]
-        loaded_modules[1:1] = [ntdll_pe]
-        loaded_modules[2:2] = [kernel32_pe]
-
-    set_link_list_entry(jitter, loaded_modules, modules_info, 0x8)
-
-
-def fix_InInitializationOrderModuleList(jitter, modules_info):
-    """Fix InInitializationOrderModuleList double link list. First module is the
-    ntdll, then kernel32.
-
-    @jitter: the jitter instance
-    @modules_info: the LoadedModules instance
-
-    """
-
-    log.debug("Fix InInitializationOrderModuleList")
-    main_pe = modules_info.name2module.get(main_pe_name, None)
-    kernel32_pe = modules_info.name2module.get("kernel32.dll", None)
-    ntdll_pe = modules_info.name2module.get("ntdll.dll", None)
-    special_modules = [main_pe, kernel32_pe, ntdll_pe]
-    if not all(special_modules):
-        log.warn('No main pe, ldr data will be unconsistant')
-        loaded_modules = modules_info.modules
-    else:
-        loaded_modules = [module for module in modules_info.modules
-                          if module not in special_modules]
-        loaded_modules[0:0] = [ntdll_pe]
-        loaded_modules[1:1] = [kernel32_pe]
-
-    set_link_list_entry(jitter, loaded_modules, modules_info, 0x10)
-
-
-def add_process_env(jitter):
-    """
-    Build a process environment structure
-    @jitter: jitter instance
-    """
-
-    env_unicode = 'ALLUSEESPROFILE=C:\\Documents and Settings\\All Users\x00'.encode('utf-16le')
-    env_unicode += b"\x00" * 0x10
-    jitter.vm.add_memory_page(
-        process_environment_address,
-        PAGE_READ | PAGE_WRITE,
-        env_unicode,
-        "Process environment"
-    )
-    jitter.vm.set_mem(process_environment_address, env_unicode)
-
-
-def add_process_parameters(jitter):
-    """
-    Build a process parameters structure
-    @jitter: jitter instance
-    """
-
-    o = b""
-    o += pck32(0x1000)  # size
-    o += b"E" * (0x48 - len(o))
-    o += pck32(process_environment_address)
-    jitter.vm.add_memory_page(
-        process_parameters_address,
-        PAGE_READ | PAGE_WRITE,
-        o, "Process parameters"
-    )
-
-
-# http://blog.fireeye.com/research/2010/08/download_exec_notes.html
-seh_count = 0
-
-
-def init_seh(jitter):
-    """
-    Build the modules entries and create double links
-    @jitter: jitter instance
-    """
-
-    global seh_count
-    seh_count = 0
-    tib_ad = jitter.cpu.get_segm_base(jitter.cpu.FS)
-    build_teb(jitter, tib_ad)
-    build_peb(jitter, peb_address)
-
-    modules_info = create_modules_chain(jitter, name2module)
-    fix_InLoadOrderModuleList(jitter, modules_info)
-    fix_InMemoryOrderModuleList(jitter, modules_info)
-    fix_InInitializationOrderModuleList(jitter, modules_info)
-
-    build_ldr_data(jitter, modules_info)
-    add_process_env(jitter)
-    add_process_parameters(jitter)
-
-
-
-def regs2ctxt(jitter, context_address):
-    """
-    Build x86_32 cpu context for exception handling
-    @jitter: jitload instance
-    """
-
-    ctxt = ContextException(jitter.vm, context_address)
-    ctxt.memset(b"\x00")
-    # ContextFlags
-    # XXX
-
-    # DRX
-    ctxt.dr0 = 0
-    ctxt.dr1 = 0
-    ctxt.dr2 = 0
-    ctxt.dr3 = 0
-    ctxt.dr4 = 0
-    ctxt.dr5 = 0
-
-    # Float context
-    # XXX
-
-    # Segment selectors
-    ctxt.gs = jitter.cpu.GS
-    ctxt.fs = jitter.cpu.FS
-    ctxt.es = jitter.cpu.ES
-    ctxt.ds = jitter.cpu.DS
-
-    # Gpregs
-    ctxt.edi = jitter.cpu.EDI
-    ctxt.esi = jitter.cpu.ESI
-    ctxt.ebx = jitter.cpu.EBX
-    ctxt.edx = jitter.cpu.EDX
-    ctxt.ecx = jitter.cpu.ECX
-    ctxt.eax = jitter.cpu.EAX
-    ctxt.ebp = jitter.cpu.EBP
-    ctxt.eip = jitter.cpu.EIP
-
-    # CS
-    ctxt.cs = jitter.cpu.CS
-
-    # Eflags
-    # XXX TODO real eflag
-
-    # ESP
-    ctxt.esp = jitter.cpu.ESP
-
-    # SS
-    ctxt.ss = jitter.cpu.SS
-
-
-def ctxt2regs(jitter, ctxt_ptr):
-    """
-    Restore x86_32 registers from an exception context
-    @ctxt: the serialized context
-    @jitter: jitload instance
-    """
-
-    ctxt = ContextException(jitter.vm, ctxt_ptr)
-
-    # Selectors
-    jitter.cpu.GS = ctxt.gs
-    jitter.cpu.FS = ctxt.fs
-    jitter.cpu.ES = ctxt.es
-    jitter.cpu.DS = ctxt.ds
-
-    # Gpregs
-    jitter.cpu.EDI = ctxt.edi
-    jitter.cpu.ESI = ctxt.esi
-    jitter.cpu.EBX = ctxt.ebx
-    jitter.cpu.EDX = ctxt.edx
-    jitter.cpu.ECX = ctxt.ecx
-    jitter.cpu.EAX = ctxt.eax
-    jitter.cpu.EBP = ctxt.ebp
-    jitter.cpu.EIP = ctxt.eip
-
-    # CS
-    jitter.cpu.CS = ctxt.cs
-
-    # Eflag
-    # XXX TODO
-
-    # ESP
-    jitter.cpu.ESP = ctxt.esp
-    # SS
-    jitter.cpu.SS = ctxt.ss
-
-
-def fake_seh_handler(jitter, except_code, previous_seh=None):
-    """
-    Create an exception context
-    @jitter: jitter instance
-    @except_code: x86 exception code
-    @previous_seh: (optional) last SEH address when multiple SEH are used
-    """
-    global seh_count
-    log.info('Exception at %x %r', jitter.cpu.EIP, seh_count)
-    seh_count += 1
-
-    # Get space on stack for exception handling
-    new_ESP = jitter.cpu.ESP - 0x3c8
-    exception_base_address = new_ESP
-    exception_record_address = exception_base_address + 0xe8
-    context_address = exception_base_address + 0xfc
-    fake_seh_address = exception_base_address + 0x14
-
-    # Save a CONTEXT
-    regs2ctxt(jitter, context_address)
-    jitter.cpu.ESP = new_ESP
-
-    # Get current seh (fs:[0])
-    tib = NT_TIB(jitter.vm, tib_address)
-    seh = tib.ExceptionList.deref
-    if previous_seh:
-        # Recursive SEH
-        while seh.get_addr() != previous_seh:
-            seh = seh.Next.deref
-        seh = seh.Next.deref
-
-    log.debug(
-        'seh_ptr %x { old_seh %r eh %r} ctx_addr %x',
-        seh.get_addr(),
-        seh.Next,
-        seh.Handler,
-        context_address
-    )
-
-    # Write exception_record
-    except_record = EXCEPTION_RECORD(jitter.vm, exception_record_address)
-    except_record.memset(b"\x00")
-    except_record.ExceptionCode = except_code
-    except_record.ExceptionAddress = jitter.cpu.EIP
-
-    # Prepare the stack
-    jitter.push_uint32_t(context_address)               # Context
-    jitter.push_uint32_t(seh.get_addr())                # SEH
-    jitter.push_uint32_t(except_record.get_addr())      # ExceptRecords
-    jitter.push_uint32_t(return_from_exception)         # Ret address
-
-    # Set fake new current seh for exception
-    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
-    tib.ExceptionList.val = fake_seh.get_addr()
-    dump_seh(jitter)
-
-    # Remove exceptions
-    jitter.vm.set_exception(0)
-    jitter.cpu.set_exception(0)
-
-    # XXX set ebx to nul?
-    jitter.cpu.EBX = 0
-
-    log.debug('Jumping at %r', seh.Handler)
-    return seh.Handler.val
-
-
-def dump_seh(jitter):
-    """
-    Walk and dump the SEH entries
-    @jitter: jitter instance
-    """
-    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.debug("Too many seh, quit")
-            return
-        err = cur_seh_ptr.deref
-        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
-
-
-def set_win_fs_0(jitter, fs=4):
-    """
-    Set FS segment selector and create its corresponding segment
-    @jitter: jitter instance
-    @fs: segment selector value
-    """
-    jitter.cpu.FS = fs
-    jitter.cpu.set_segm_base(fs, tib_address)
-    segm_to_do = set([x86_regs.FS])
-    return segm_to_do
-
-
-def return_from_seh(jitter):
-    """Handle the return from an exception handler
-    @jitter: jitter instance"""
-
-    # Get object addresses
-    seh_address = jitter.vm.get_u32(jitter.cpu.ESP + 0x4)
-    context_address = jitter.vm.get_u32(jitter.cpu.ESP + 0x8)
-
-    # Get registers changes
-    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.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.debug('SEH continue')
-        jitter.pc = jitter.cpu.EIP
-        log.debug('Context::Eip: %x', jitter.pc)
-
-    elif status == 1:
-        # ExceptionContinueSearch
-        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,
-                                            context_address - 0xfc + 0xe8)
-
-        pc = fake_seh_handler(jitter, exception_record.ExceptionCode,
-                              seh_address)
-        jitter.pc = pc
-
-    else:
-        # https://msdn.microsoft.com/en-us/library/aa260344%28v=vs.60%29.aspx
-        # But the type _EXCEPTION_DISPOSITION may take 2 others values:
-        #  - ExceptionNestedException = 2
-        #  - ExceptionCollidedUnwind = 3
-        raise ValueError("Valid values are ExceptionContinueExecution and "
-                         "ExceptionContinueSearch")
-
-    # Jitter's breakpoint compliant
-    return True