about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorPierre LALET <pierre.lalet@cea.fr>2015-02-16 19:16:56 +0100
committerPierre LALET <pierre.lalet@cea.fr>2015-02-17 18:45:53 +0100
commit9a40e4bbf93e820bb9bd51e9a6523d6131c4bba4 (patch)
tree5ecb8b017c5dd037ae1ad3b7096bd11fb3492b0a
parentc8c67dbe4f9d28ab106fa04445e5d97359386862 (diff)
downloadmiasm-9a40e4bbf93e820bb9bd51e9a6523d6131c4bba4.tar.gz
miasm-9a40e4bbf93e820bb9bd51e9a6523d6131c4bba4.zip
os_dep.win_api_x86_32: use argument lists in .func_args_*(), (bug)fixes
-rw-r--r--miasm2/os_dep/win_api_x86_32.py1572
1 files changed, 693 insertions, 879 deletions
diff --git a/miasm2/os_dep/win_api_x86_32.py b/miasm2/os_dep/win_api_x86_32.py
index 59cbe990..5a673265 100644
--- a/miasm2/os_dep/win_api_x86_32.py
+++ b/miasm2/os_dep/win_api_x86_32.py
@@ -22,7 +22,6 @@ import stat
 import time
 import string
 import logging
-from collections import namedtuple
 from zlib import crc32
 
 try:
@@ -33,6 +32,7 @@ except ImportError:
 from miasm2.jitter.csts import *
 from miasm2.core.utils import *
 from miasm2.os_dep.common import *
+from miasm2.os_dep.win_api_x86_32_seh import FS_0_AD
 
 log = logging.getLogger("win_api_x86_32")
 console_handler = logging.StreamHandler()
@@ -249,110 +249,97 @@ class mdl:
 
 
 def kernel32_HeapAlloc(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    heap, flags, size = args
-
-    alloc_addr = winobjs.heap.alloc(jitter, size)
-
+    ret_ad, args = jitter.func_args_stdcall(["heap", "flags", "size"])
+    alloc_addr = winobjs.heap.alloc(jitter, args.size)
     jitter.func_ret_stdcall(ret_ad, alloc_addr)
 
 
 def kernel32_HeapFree(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    heap, flags, pmem = args
-
+    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(2)
-    uflags, msize = args
-    alloc_addr = winobjs.heap.alloc(jitter, msize)
+    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, args = jitter.func_args_stdcall(1)
-    lpvoid, = args
+    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(2)
-    uflags, msize = args
-    alloc_addr = winobjs.heap.alloc(jitter, msize)
+    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_GlobalFree(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    ad, = args
+    ret_ad, _ = jitter.func_args_stdcall(["addr"])
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def kernel32_IsDebuggerPresent(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     jitter.func_ret_stdcall(ret_ad, winobjs.dbg_present)
 
 
 def kernel32_CreateToolhelp32Snapshot(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    dwflags, th32processid = args
+    ret_ad, _ = jitter.func_args_stdcall(["dwflags", "th32processid"])
     jitter.func_ret_stdcall(ret_ad, winobjs.handle_toolhelpsnapshot)
 
 
 def kernel32_GetCurrentProcess(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     jitter.func_ret_stdcall(ret_ad, winobjs.handle_curprocess)
 
 
 def kernel32_GetCurrentProcessId(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    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(2)
-    s_handle, ad_pentry = args
+    ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"])
 
     pentry = struct.pack(
         'IIIIIIIII', *process_list[0][:-1]) + process_list[0][-1]
-    jitter.vm.set_mem(ad_pentry, pentry)
-    winobjs.toolhelpsnapshot_info[s_handle] = 0
+    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(2)
-    s_handle, ad_pentry = args
+    ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"])
 
-    winobjs.toolhelpsnapshot_info[s_handle] += 1
-    if winobjs.toolhelpsnapshot_info[s_handle] >= len(process_list):
+    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[s_handle]
+        n = winobjs.toolhelpsnapshot_info[args.s_handle]
         pentry = struct.pack(
             'IIIIIIIII', *process_list[n][:-1]) + process_list[n][-1]
-        jitter.vm.set_mem(ad_pentry, pentry)
+        jitter.vm.set_mem(args.ad_pentry, pentry)
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
 def kernel32_GetTickCount(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     winobjs.tickcount += 1
     jitter.func_ret_stdcall(ret_ad, winobjs.tickcount)
 
 
 def kernel32_GetVersion(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     jitter.func_ret_stdcall(ret_ad, winobjs.getversion)
 
 
-def kernel32_GetVersionEx(jitter, set_str = set_str_unic):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    ptr_struct, = args
+def kernel32_GetVersionEx(jitter, set_str=set_str_unic):
+    ret_ad, args = jitter.func_args_stdcall(["ptr_struct"])
 
     s = struct.pack("IIIII",
                     0x114,  # struct size
@@ -365,66 +352,58 @@ def kernel32_GetVersionEx(jitter, set_str = set_str_unic):
     t = s + (t + '\x00' * 128 * 2)[:128 * 2]
     t += struct.pack('HHHBB', 3, 0, 0x100, 1, 0)
     s = t
-    jitter.vm.set_mem(ptr_struct, s)
+    jitter.vm.set_mem(args.ptr_struct, s)
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
-kernel32_GetVersionExA = lambda jitter: kernel32_GetVersionEx(jitter, set_str_ansi)
-kernel32_GetVersionExW = lambda jitter: kernel32_GetVersionEx(jitter, set_str_unic)
+kernel32_GetVersionExA = lambda jitter: kernel32_GetVersionEx(jitter,
+                                                              set_str_ansi)
+kernel32_GetVersionExW = lambda jitter: kernel32_GetVersionEx(jitter,
+                                                              set_str_unic)
 
 
 def kernel32_GetPriorityClass(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    hwnd, = args
+    ret_ad, _ = jitter.func_args_stdcall(["hwnd"])
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def kernel32_SetPriorityClass(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    hwnd, dwpclass = args
+    ret_ad, _ = jitter.func_args_stdcall(["hwnd", "dwpclass"])
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def kernel32_CloseHandle(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    hwnd, = args
+    ret_ad, _ = jitter.func_args_stdcall(["hwnd"])
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def user32_GetForegroundWindow(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    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(2)
-    pclassname, pwindowname = args
+    ret_ad, _ = jitter.func_args_stdcall(["pclassname", "pwindowname"])
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def user32_GetTopWindow(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    hwnd, = args
+    ret_ad, _ = jitter.func_args_stdcall(["hwnd"])
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def user32_BlockInput(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    b, = args
+    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(5)
-    phprov, pszcontainer, pszprovider, dwprovtype, dwflags = args
-
-    if pszprovider:
-        prov = get_str(jitter, pszprovider)
-    else:
-        prov = "NONE"
-    log.debug('prov: %r'%prov)
-    jitter.vm.set_mem(phprov, pck32(winobjs.cryptcontext_hwnd))
-
+    ret_ad, args = jitter.func_args_stdcall(["phprov", "pszcontainer",
+                                             "pszprovider", "dwprovtype",
+                                             "dwflags"])
+    prov = get_str(jitter, args.pszprovider) if args.pszprovider else "NONE"
+    log.debug('prov: %r' % prov)
+    jitter.vm.set_mem(args.phprov, pck32(winobjs.cryptcontext_hwnd))
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
@@ -437,23 +416,27 @@ def advapi32_CryptAcquireContextW(jitter):
 
 
 def advapi32_CryptCreateHash(jitter):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    hprov, algid, hkey, dwflags, phhash = args
+    ret_ad, args = jitter.func_args_stdcall(["hprov", "algid", "hkey",
+                                             "dwflags", "phhash"])
 
     winobjs.cryptcontext_num += 1
 
-    if algid == 0x00008003:
+    if args.algid == 0x00008003:
         log.debug('algo is MD5')
         jitter.vm.set_mem(
-            phhash, pck32(winobjs.cryptcontext_bnum + winobjs.cryptcontext_num))
+            args.phhash,
+            pck32(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 algid == 0x00008004:
+    elif args.algid == 0x00008004:
         log.debug('algo is SHA1')
         jitter.vm.set_mem(
-            phhash, pck32(winobjs.cryptcontext_bnum + winobjs.cryptcontext_num))
+            args.phhash,
+            pck32(winobjs.cryptcontext_bnum + winobjs.cryptcontext_num)
+        )
         winobjs.cryptcontext[
             winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj()
         winobjs.cryptcontext[
@@ -464,78 +447,79 @@ def advapi32_CryptCreateHash(jitter):
 
 
 def advapi32_CryptHashData(jitter):
-    ret_ad, args = jitter.func_args_stdcall(4)
-    hhash, pbdata, dwdatalen, dwflags = args
+    ret_ad, args = jitter.func_args_stdcall(["hhash", "pbdata", "dwdatalen",
+                                             "dwflags"])
 
-    if not hhash in winobjs.cryptcontext:
+    if not args.hhash in winobjs.cryptcontext:
         raise ValueError("unknown crypt context")
 
-    data = jitter.vm.get_mem(pbdata, dwdatalen)
-    log.debug('will hash %X' % dwdatalen)
+    data = jitter.vm.get_mem(args.pbdata, args.dwdatalen)
+    log.debug('will hash %X' % args.dwdatalen)
     log.debug(repr(data[:10]) + "...")
-    winobjs.cryptcontext[hhash].h.update(data)
+    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(5)
-    hhash, param, pbdata, dwdatalen, dwflags = args
+    ret_ad, args = jitter.func_args_stdcall(["hhash", "param", "pbdata",
+                                             "dwdatalen", "dwflags"])
 
-    if not hhash in winobjs.cryptcontext:
+    if not args.hhash in winobjs.cryptcontext:
         raise ValueError("unknown crypt context")
 
-    if param == 2:
+    if args.param == 2:
         # XXX todo: save h state?
-        h = winobjs.cryptcontext[hhash].h.digest()
+        h = winobjs.cryptcontext[args.hhash].h.digest()
     else:
-        raise ValueError('not impl', param)
-    jitter.vm.set_mem(pbdata, h)
-    jitter.vm.set_mem(dwdatalen, pck32(len(h)))
+        raise ValueError('not impl', args.param)
+    jitter.vm.set_mem(args.pbdata, h)
+    jitter.vm.set_mem(args.dwdatalen, pck32(len(h)))
 
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def advapi32_CryptReleaseContext(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    hhash, flags = args
+    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(5)
-    hprov, algid, hbasedata, dwflags, phkey = args
+    ret_ad, args = jitter.func_args_stdcall(["hprov", "algid", "hbasedata",
+                                             "dwflags", "phkey"])
 
-    if algid == 0x6801:
+    if args.algid == 0x6801:
         log.debug('using DES')
     else:
         raise ValueError('un impl algo2')
-    h = winobjs.cryptcontext[hbasedata].h.digest()
+    h = winobjs.cryptcontext[args.hbasedata].h.digest()
     log.debug('hash %r'% h)
-    winobjs.cryptcontext[hbasedata].h_result = h
-    jitter.vm.set_mem(phkey, pck32(hbasedata))
+    winobjs.cryptcontext[args.hbasedata].h_result = h
+    jitter.vm.set_mem(args.phkey, pck32(args.hbasedata))
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def advapi32_CryptDestroyHash(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    hhash, = args
+    ret_ad, _ = jitter.func_args_stdcall(["hhash"])
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def advapi32_CryptDecrypt(jitter):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    hkey, hhash, final, dwflags, pbdata, pdwdatalen = args
-    raise NotImplementedError()
-    jitter.func_ret_stdcall(ret_ad, 1)
+    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(7)
-    (lpfilename, access, dwsharedmode, lpsecurityattr,
-     dwcreationdisposition, dwflagsandattr, htemplatefile) = args
-
-    fname = get_str(jitter, lpfilename)
-    log.debug('fname %s' % fname )
+    ret_ad, args = jitter.func_args_stdcall(["lpfilename", "access",
+                                             "dwsharedmode",
+                                             "lpsecurityattr",
+                                             "dwcreationdisposition",
+                                             "dwflagsandattr",
+                                             "htemplatefile"])
+    fname = get_str(jitter, args.lpfilename)
+    log.debug('fname %s' % fname)
     fname_o = fname[:]
     ret = 0xffffffff
 
@@ -559,17 +543,17 @@ def kernel32_CreateFile(jitter, funcname, get_str):
         fname = fname.replace('\\', "/").lower()
         # go in sandbox files
         f = os.path.join('file_sb', fname)
-        if access & 0x80000000 or access == 1:
+        if args.access & 0x80000000 or args.access == 1:
             # read
-            if dwcreationdisposition == 2:
+            if args.dwcreationdisposition == 2:
                 # create_always
                 if os.access(f, os.R_OK):
                     # but file exist
                     pass
                 else:
                     raise NotImplementedError("Untested case")  # to test
-                    h = open(f, 'rb+')
-            elif dwcreationdisposition == 3:
+                    # h = open(f, 'rb+')
+            elif args.dwcreationdisposition == 3:
                 # open_existing
                 if os.access(f, os.R_OK):
                     s = os.stat(f)
@@ -580,19 +564,17 @@ def kernel32_CreateFile(jitter, funcname, get_str):
                         ret = winobjs.handle_pool.add(f, h)
                 else:
                     log.warning("FILE %r DOES NOT EXIST!" % fname)
-                    pass
-            elif dwcreationdisposition == 1:
+            elif args.dwcreationdisposition == 1:
                 # create new
                 if os.access(f, os.R_OK):
                     # file exist
                     # ret = 80
                     winobjs.lastwin32error = 80
-                    pass
                 else:
                     open(f, 'w')
                     h = open(f, 'rb+')
                     ret = winobjs.handle_pool.add(f, h)
-            elif dwcreationdisposition == 4:
+            elif args.dwcreationdisposition == 4:
                 # open_always
                 if os.access(f, os.R_OK):
                     s = os.stat(f)
@@ -605,9 +587,9 @@ def kernel32_CreateFile(jitter, funcname, get_str):
                     raise NotImplementedError("Untested case")
             else:
                 raise NotImplementedError("Untested case")
-        elif access & 0x40000000:
+        elif args.access & 0x40000000:
             # write
-            if dwcreationdisposition == 3:
+            if args.dwcreationdisposition == 3:
                 # open existing
                 if is_original_file:
                     # cannot open self in write mode!
@@ -622,7 +604,7 @@ def kernel32_CreateFile(jitter, funcname, get_str):
                         ret = winobjs.handle_pool.add(f, h)
                 else:
                     raise NotImplementedError("Untested case")  # to test
-            elif dwcreationdisposition == 5:
+            elif args.dwcreationdisposition == 5:
                 # truncate_existing
                 if is_original_file:
                     pass
@@ -650,99 +632,94 @@ def kernel32_CreateFileW(jitter):
 
 
 def kernel32_ReadFile(jitter):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    (hwnd, lpbuffer, nnumberofbytestoread,
-     lpnumberofbytesread, lpoverlapped) = args
-
-    if hwnd == winobjs.module_cur_hwnd:
+    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpbuffer",
+                                             "nnumberofbytestoread",
+                                             "lpnumberofbytesread",
+                                             "lpoverlapped"])
+    if args.hwnd == winobjs.module_cur_hwnd:
         pass
-    elif hwnd in winobjs.handle_pool:
+    elif args.hwnd in winobjs.handle_pool:
         pass
     else:
         raise ValueError('unknown hwnd!')
 
-    eax = 0xffffffff
     data = None
-    if hwnd in winobjs.files_hwnd:
+    if args.hwnd in winobjs.files_hwnd:
         data = winobjs.files_hwnd[
-            winobjs.module_cur_hwnd].read(nnumberofbytestoread)
-    elif hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[hwnd]
-        data = wh.info.read(nnumberofbytestoread)
+            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 (lpnumberofbytesread):
-            jitter.vm.set_mem(lpnumberofbytesread, pck32(len(data)))
-        jitter.vm.set_mem(lpbuffer, data)
+        if (args.lpnumberofbytesread):
+            jitter.vm.set_mem(args.lpnumberofbytesread, pck32(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(2)
-    hwnd, lpfilesizehight = args
+    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"])
 
-    if hwnd == winobjs.module_cur_hwnd:
+    if args.hwnd == winobjs.module_cur_hwnd:
         ret = len(open(winobjs.module_fname_nux).read())
-    elif hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[hwnd]
+    elif args.hwnd in winobjs.handle_pool:
+        wh = winobjs.handle_pool[args.hwnd]
         ret = len(open(wh.name).read())
     else:
         raise ValueError('unknown hwnd!')
 
-    if lpfilesizehight != 0:
-        jitter.vm.set_mem(lpfilesizehight, pck32(ret))
+    if args.lpfilesizehight != 0:
+        jitter.vm.set_mem(args.lpfilesizehight, pck32(ret))
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
 def kernel32_GetFileSizeEx(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    hwnd, lpfilesizehight = args
+    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"])
 
-    if hwnd == winobjs.module_cur_hwnd:
+    if args.hwnd == winobjs.module_cur_hwnd:
         l = len(open(winobjs.module_fname_nux).read())
-    elif hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[hwnd]
+    elif args.hwnd in winobjs.handle_pool:
+        wh = winobjs.handle_pool[args.hwnd]
         l = len(open(wh.name).read())
     else:
         raise ValueError('unknown hwnd!')
 
-    if lpfilesizehight == 0:
+    if args.lpfilesizehight == 0:
         raise NotImplementedError("Untested case")
-    jitter.vm.set_mem(lpfilesizehight, pck32(
+    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, args = jitter.func_args_stdcall(3)
-    hprocess, lpbasead, dwsize = args
+    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(4)
-    lpvoid, dwsize, flnewprotect, lpfloldprotect = args
-
+    ret_ad, args = jitter.func_args_stdcall(['lpvoid', 'dwsize',
+                                             'flnewprotect',
+                                             'lpfloldprotect'])
     # XXX mask hpart
-    flnewprotect &= 0xFFF
-
+    flnewprotect = args.flnewprotect & 0xFFF
     if not flnewprotect in access_dict:
         raise ValueError('unknown access dw!')
-    jitter.vm.set_mem_access(lpvoid, access_dict[flnewprotect])
+    jitter.vm.set_mem_access(args.lpvoid, access_dict[flnewprotect])
 
     # XXX todo real old protect
-    if lpfloldprotect:
-        jitter.vm.set_mem(lpfloldprotect, pck32(0x40))
+    if args.lpfloldprotect:
+        jitter.vm.set_mem(args.lpfloldprotect, pck32(0x40))
 
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def kernel32_VirtualAlloc(jitter):
-    ret_ad, args = jitter.func_args_stdcall(4)
-    lpvoid, dwsize, alloc_type, flprotect = args
+    ret_ad, args = jitter.func_args_stdcall(['lpvoid', 'dwsize',
+                                             'alloc_type', 'flprotect'])
 
     access_dict = {0x0: 0,
                    0x1: 0,
@@ -754,74 +731,70 @@ def kernel32_VirtualAlloc(jitter):
                    0x100: 0
                        }
 
-    access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
+    # access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
 
-    if not flprotect in access_dict:
+    if not args.flprotect in access_dict:
         raise ValueError('unknown access dw!')
 
-    if lpvoid == 0:
-        alloc_addr = winobjs.heap.next_addr(dwsize)
+    if args.lpvoid == 0:
+        alloc_addr = winobjs.heap.next_addr(args.dwsize)
         jitter.vm.add_memory_page(
-            alloc_addr, access_dict[flprotect], "\x00" * dwsize)
+            alloc_addr, access_dict[args.flprotect], "\x00" * args.dwsize)
     else:
         all_mem = jitter.vm.get_all_memory()
-        if lpvoid in all_mem:
-            alloc_addr = lpvoid
-            jitter.vm.set_mem_access(lpvoid, access_dict[flprotect])
+        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(dwsize)
-            # alloc_addr = lpvoid
+            alloc_addr = winobjs.heap.next_addr(args.dwsize)
+            # alloc_addr = args.lpvoid
             jitter.vm.add_memory_page(
-                alloc_addr, access_dict[flprotect], "\x00" * dwsize)
+                alloc_addr, access_dict[args.flprotect], "\x00" * args.dwsize)
 
     log.debug('Memory addr: %x' %alloc_addr)
     jitter.func_ret_stdcall(ret_ad, alloc_addr)
 
 
 def kernel32_VirtualFree(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    lpvoid, dwsize, alloc_type = args
+    ret_ad, _ = jitter.func_args_stdcall(["lpvoid", "dwsize", "alloc_type"])
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def user32_GetWindowLongA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    hwnd, nindex = args
+    ret_ad, _ = jitter.func_args_stdcall(["hwnd", "nindex"])
     jitter.func_ret_stdcall(ret_ad, winobjs.windowlong_dw)
 
 
 def user32_SetWindowLongA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    hwnd, nindex, newlong = args
+    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(3)
-    hmodule, lpfilename, nsize = args
+    ret_ad, args = jitter.func_args_stdcall(["hmodule", "lpfilename", "nsize"])
 
-    if hmodule in [0, winobjs.hcurmodule]:
+    if args.hmodule in [0, winobjs.hcurmodule]:
         p = winobjs.module_path[:]
     elif (winobjs.runtime_dll and
-        hmodule in winobjs.runtime_dll.name2off.values()):
+        args.hmodule in winobjs.runtime_dll.name2off.values()):
         name_inv = dict([(x[1], x[0])
                         for x in winobjs.runtime_dll.name2off.items()])
-        p = name_inv[hmodule]
+        p = name_inv[args.hmodule]
     else:
         log.warning('Unknown module 0x%x.' + \
-                        'Set winobjs.hcurmodule and retry' % hmodule)
+                        'Set winobjs.hcurmodule and retry' % args.hmodule)
         p = None
 
     if p is None:
         l = 0
-    elif nsize < len(p):
-        p = p[:nsize]
+    elif args.nsize < len(p):
+        p = p[:args.nsize]
         l = len(p)
     else:
         l = len(p)
 
     if p:
-        jitter.vm.set_mem(lpfilename, set_str(p))
+        jitter.vm.set_mem(args.lpfilename, set_str(p))
 
     jitter.func_ret_stdcall(ret_ad, l)
 
@@ -835,25 +808,25 @@ def kernel32_GetModuleFileNameW(jitter):
 
 
 def kernel32_CreateMutex(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    mutexattr, initowner, lpname = args
+    ret_ad, args = jitter.func_args_stdcall(["mutexattr", "initowner",
+                                             "lpname"])
 
-    if lpname:
-        name = get_str(jitter, lpname)
+    if args.lpname:
+        name = get_str(jitter, args.lpname)
         log.debug(name)
     else:
         name = None
-    if initowner:
+    if args.initowner:
         if name in winobjs.mutex:
             raise NotImplementedError("Untested case")
-            ret = 0
+            # ret = 0
         else:
             winobjs.mutex[name] = id(name)
             ret = winobjs.mutex[name]
     else:
         if name in winobjs.mutex:
             raise NotImplementedError("Untested case")
-            ret = 0
+            # ret = 0
         else:
             winobjs.mutex[name] = id(name)
             ret = winobjs.mutex[name]
@@ -869,22 +842,20 @@ def kernel32_CreateMutexW(jitter):
 
 
 def shell32_SHGetSpecialFolderLocation(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    hwndowner, nfolder, ppidl = args
-    jitter.vm.set_mem(ppidl, pck32(nfolder))
+    ret_ad, args = jitter.func_args_stdcall(["hwndowner", "nfolder", "ppidl"])
+    jitter.vm.set_mem(args.ppidl, pck32(args.nfolder))
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def kernel32_SHGetPathFromIDList(jitter, funcname, set_str):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    pidl, ppath = args
+    ret_ad, args = jitter.func_args_stdcall(["pidl", "ppath"])
 
-    if pidl == 7:  # CSIDL_STARTUP:
+    if args.pidl == 7:  # CSIDL_STARTUP:
         s = "c:\\doc\\user\\startmenu\\programs\\startup"
         s = set_str(s)
     else:
-        raise ValueError('pidl not implemented', pidl)
-    jitter.vm.set_mem(ppath, s)
+        raise ValueError('pidl not implemented', args.pidl)
+    jitter.vm.set_mem(args.ppath, s)
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
@@ -897,17 +868,16 @@ def shell32_SHGetPathFromIDListA(jitter):
 
 
 def kernel32_GetLastError(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    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(1)
-    e, = args
+    ret_ad, args = jitter.func_args_stdcall(["errcode"])
     # lasterr addr
-    # ad = seh_helper.FS_0_AD + 0x34
-    # jitter.vm.set_mem(ad, pck32(e))
-    winobjs.lastwin32error = e
+    # ad = FS_0_AD + 0x34
+    # jitter.vm.set_mem(ad, pck32(args.errcode))
+    winobjs.lastwin32error = args.errcode
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
@@ -916,10 +886,9 @@ def kernel32_RestoreLastError(jitter):
 
 
 def kernel32_LoadLibraryA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    dllname, = args
+    ret_ad, args = jitter.func_args_stdcall(["dllname"])
 
-    libname = get_str_ansi(jitter, dllname, 0x100)
+    libname = get_str_ansi(jitter, args.dllname, 0x100)
     log.info(libname)
 
     ret = winobjs.runtime_dll.lib_get_add_base(libname)
@@ -928,12 +897,11 @@ def kernel32_LoadLibraryA(jitter):
 
 
 def kernel32_LoadLibraryExA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    dllname, hfile, flags = args
+    ret_ad, args = jitter.func_args_stdcall(["dllname", "hfile", "flags"])
 
-    if hfile != 0:
+    if args.hfile != 0:
         raise NotImplementedError("Untested case")
-    libname = get_str_ansi(jitter, dllname, 0x100)
+    libname = get_str_ansi(jitter, args.dllname, 0x100)
     log.info(libname)
 
     ret = winobjs.runtime_dll.lib_get_add_base(libname)
@@ -942,9 +910,9 @@ def kernel32_LoadLibraryExA(jitter):
 
 
 def kernel32_GetProcAddress(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    libbase, fname = args
-    fname = fname & 0xFFFFFFFF
+    ret_ad, args = jitter.func_args_stdcall(["libbase", "fname"])
+    # Ensure high-order WORD is 0
+    fname = args.fname & 0xFFFFFFFF
     if fname < 0x10000:
         fname = fname
     else:
@@ -953,19 +921,18 @@ def kernel32_GetProcAddress(jitter):
             fname = None
     log.info(fname)
     if fname is not None:
-        ad = winobjs.runtime_dll.lib_get_add_func(libbase, fname)
+        ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
     else:
         ad = 0
-    ad = winobjs.runtime_dll.lib_get_add_func(libbase, fname)
+    ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
     jitter.add_breakpoint(ad, jitter.handle_lib)
     jitter.func_ret_stdcall(ret_ad, ad)
 
 
 def kernel32_LoadLibraryW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    dllname, = args
+    ret_ad, args = jitter.func_args_stdcall(["dllname"])
 
-    libname = get_str_unic(jitter, dllname, 0x100)
+    libname = get_str_unic(jitter, args.dllname, 0x100)
     log.info(libname)
 
     ret = winobjs.runtime_dll.lib_get_add_base(libname)
@@ -974,11 +941,10 @@ def kernel32_LoadLibraryW(jitter):
 
 
 def kernel32_GetModuleHandle(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    dllname, = args
+    ret_ad, args = jitter.func_args_stdcall(["dllname"])
 
-    if dllname:
-        libname = get_str(jitter, dllname)
+    if args.dllname:
+        libname = get_str(jitter, args.dllname)
         log.info(libname)
         if libname:
             ret = winobjs.runtime_dll.lib_get_add_base(libname)
@@ -1000,8 +966,7 @@ def kernel32_GetModuleHandleW(jitter):
 
 
 def kernel32_VirtualLock(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    lpaddress, dwsize = args
+    ret_ad, _ = jitter.func_args_stdcall(["lpaddress", "dwsize"])
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
@@ -1032,23 +997,20 @@ class systeminfo:
 
 
 def kernel32_GetSystemInfo(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    sys_ptr, = args
+    ret_ad, args = jitter.func_args_stdcall(["sys_ptr"])
     sysinfo = systeminfo()
-    jitter.vm.set_mem(sys_ptr, sysinfo.pack())
+    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(2)
-    h, bool_ptr = args
-
-    jitter.vm.set_mem(bool_ptr, pck32(0))
+    ret_ad, args = jitter.func_args_stdcall(["process", "bool_ptr"])
+    jitter.vm.set_mem(args.bool_ptr, pck32(0))
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def kernel32_GetCommandLineA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     s = winobjs.module_path + '\x00'
     s = '"%s"' % s
     alloc_addr = winobjs.heap.alloc(jitter, 0x1000)
@@ -1057,7 +1019,7 @@ def kernel32_GetCommandLineA(jitter):
 
 
 def kernel32_GetCommandLineW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     s = winobjs.module_path + '\x00'
     s = set_str_unic('"%s"' % s)
     alloc_addr = winobjs.heap.alloc(jitter, 0x1000)
@@ -1066,9 +1028,8 @@ def kernel32_GetCommandLineW(jitter):
 
 
 def shell32_CommandLineToArgvW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    pcmd, pnumargs = args
-    cmd = get_str_unic(jitter, pcmd)
+    ret_ad, args = jitter.func_args_stdcall(["pcmd", "pnumargs"])
+    cmd = get_str_unic(jitter, args.pcmd)
     log.debug(cmd)
     tks = cmd.split(' ')
     addr = winobjs.heap.alloc(jitter, len(cmd) * 2 + 4 * len(tks))
@@ -1081,31 +1042,29 @@ def shell32_CommandLineToArgvW(jitter):
         o += len(x) + 2
 
     jitter.vm.set_mem(addr_ret + 4 * i, pck32(0))
-    jitter.vm.set_mem(pnumargs, pck32(len(tks)))
+    jitter.vm.set_mem(args.pnumargs, pck32(len(tks)))
     jitter.func_ret_stdcall(ret_ad, addr_ret)
 
 
 def cryptdll_MD5Init(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    ad_ctx, = args
+    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_mem(ad_ctx, pck32(index))
+    jitter.vm.set_mem(args.ad_ctx, pck32(index))
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def cryptdll_MD5Update(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    ad_ctx, ad_input, inlen = args
+    ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_input", "inlen"])
 
-    index = jitter.vm.get_mem(ad_ctx, 4)
+    index = jitter.vm.get_mem(args.ad_ctx, 4)
     index = upck32(index)
     if not index in winobjs.cryptdll_md5_h:
         raise ValueError('unknown h context', index)
 
-    data = jitter.vm.get_mem(ad_input, inlen)
+    data = jitter.vm.get_mem(args.ad_input, args.inlen)
     winobjs.cryptdll_md5_h[index].update(data)
     log.debug(hexdump(data))
 
@@ -1113,77 +1072,73 @@ def cryptdll_MD5Update(jitter):
 
 
 def cryptdll_MD5Final(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    ad_ctx, = args
+    ret_ad, args = jitter.func_args_stdcall(["ad_ctx"])
 
-    index = jitter.vm.get_mem(ad_ctx, 4)
+    index = jitter.vm.get_mem(args.ad_ctx, 4)
     index = upck32(index)
     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(ad_ctx + 88, h)
+    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(2)
-    ad_ctx, ad_str = args
+    ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_str"])
 
-    s = get_str_ansi(jitter, ad_str)
+    s = get_str_ansi(jitter, args.ad_str)
     l = len(s)
-    jitter.vm.set_mem(ad_ctx, pck16(l) + pck16(l + 1) + pck32(ad_str))
+    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(4)
-    ad_ctxu, case_i, h_id, phout = args
+    ret_ad, args = jitter.func_args_stdcall(["ad_ctxu", "case_i", "h_id",
+                                             "phout"])
 
-    if h_id != 1:
-        raise ValueError('unk hash unicode', h_id)
+    if args.h_id != 1:
+        raise ValueError('unk hash unicode', args.h_id)
 
-    l1, l2, ptra = struct.unpack('HHL', jitter.vm.get_mem(ad_ctxu, 8))
+    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 case_i:
+    if args.case_i:
         s = s.lower()
     for c in s:
         hv = ((65599 * hv) + ord(c)) & 0xffffffff
-    jitter.vm.set_mem(phout, pck32(hv))
+    jitter.vm.set_mem(args.phout, pck32(hv))
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def kernel32_RtlMoveMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    ad_dst, ad_src, m_len = args
-    data = jitter.vm.get_mem(ad_src, m_len)
-    jitter.vm.set_mem(ad_dst, data)
-
+    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(1)
-    ad_ad_ch, = args
-    ad_ch = upck32(jitter.vm.get_mem(ad_ad_ch, 4))
+    ret_ad, args = jitter.func_args_stdcall(['ad_ad_ch'])
+    ad_ch = upck32(jitter.vm.get_mem(args.ad_ad_ch, 4))
     ch = ord(jitter.vm.get_mem(ad_ch, 1))
-    jitter.vm.set_mem(ad_ad_ch, pck32(ad_ch + 1))
-
+    jitter.vm.set_mem(args.ad_ad_ch, pck32(ad_ch + 1))
     jitter.func_ret_stdcall(ret_ad, ch)
 
 
 def ntdll_RtlFindCharInUnicodeString(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    flags, main_str_ad, search_chars_ad, pos_ad = args
+    ret_ad, args = jitter.func_args_stdcall(["flags", "main_str_ad",
+                                             "search_chars_ad", "pos_ad"])
 
-    if flags != 0:
+    if args.flags != 0:
         raise ValueError('unk flags')
 
-    ml1, ml2, mptra = struct.unpack('HHL', jitter.vm.get_mem(main_str_ad, 8))
+    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(search_chars_ad, 8))
+        '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]
 
@@ -1197,109 +1152,101 @@ def ntdll_RtlFindCharInUnicodeString(jitter):
             break
     if pos is None:
         ret = 0xC0000225
-        jitter.vm.set_mem(pos_ad, pck32(0))
+        jitter.vm.set_mem(args.pos_ad, pck32(0))
     else:
         ret = 0
-        jitter.vm.set_mem(pos_ad, pck32(pos))
+        jitter.vm.set_mem(args.pos_ad, pck32(pos))
 
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
 def ntdll_RtlComputeCrc32(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    dwinit, pdata, ilen = args
-
-    data = jitter.vm.get_mem(pdata, ilen)
-    crc_r = crc32(data, dwinit)
+    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(3)
-    b2, b1, bm = args
-    a = (b1 << 32) + b2
-    a = a * bm
+    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(4)
-    a2, a1, b2, b1 = args
-    a = (a1 << 32) + a2 + (b1 << 32) + b2
+    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(3)
-    a2, a1, m = args
-    a = ((a1 << 32) + a2) >> m
+    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(2)
-    a, b = args
-    a = a * b
+    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(4)
-    a2, a1, b2, b1 = args
-    a = (a1 << 32) + a2 - (b1 << 32) + b2
+    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(3)
-    ad1, ad2, m_len = args
-    data1 = jitter.vm.get_mem(ad1, m_len)
-    data2 = jitter.vm.get_mem(ad2, m_len)
+    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 >= m_len:
+        if i >= args.m_len:
             break
 
     jitter.func_ret_stdcall(ret_ad, i)
 
 
 def user32_GetMessagePos(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     jitter.func_ret_stdcall(ret_ad, 0x00110022)
 
 
 def kernel32_Sleep(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    t, = args
+    ret_ad, _ = jitter.func_args_stdcall(['t'])
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def ntdll_ZwUnmapViewOfSection(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    h, ad = args
+    ret_ad, _ = jitter.func_args_stdcall(['h', 'ad'])
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def kernel32_IsBadReadPtr(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    lp, ucb = args
+    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(3)
-    my_event, my_type, my_state = args
-    jitter.vm.set_mem(my_event, pck32(winobjs.win_event_num))
+    ret_ad, args = jitter.func_args_stdcall(['my_event', 'my_type',
+                                             'my_state'])
+    jitter.vm.set_mem(args.my_event, pck32(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(1)
-    ptr_version, = args
+    ret_ad, args = jitter.func_args_stdcall(['ptr_version'])
 
     s = struct.pack("IIIII",
                     0x114,  # struct size
@@ -1309,23 +1256,22 @@ def ntoskrnl_RtlGetVersion(jitter):
                     0x2,   # platform id
                     ) + set_str_unic("Service pack 4")
 
-    jitter.vm.set_mem(ptr_version, s)
+    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(1)
-    ptr_version, = args
+    ret_ad, args = jitter.func_args_stdcall(['ptr_version'])
 
-    s = jitter.vm.get_mem(ptr_version, 0x5 * 4)
+    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(ptr_version, s)
-    jitter.func_ret_stdcall(ret_ad, 0)
+    # jitter.vm.set_mem(args.ptr_version, s)
+    # jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def hal_ExAcquireFastMutex(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
@@ -1338,9 +1284,9 @@ def ad2mdl(ad):
 
 
 def ntoskrnl_IoAllocateMdl(jitter):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    v_addr, l, second_buf, chargequota, pirp = args
-    m = mdl(v_addr, l)
+    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), str(m))
     jitter.func_ret_stdcall(ret_ad, mdl2ad(winobjs.nt_mdl_cur))
@@ -1348,78 +1294,77 @@ def ntoskrnl_IoAllocateMdl(jitter):
 
 
 def ntoskrnl_MmProbeAndLockPages(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    p_mdl, access_mode, op = args
+    ret_ad, args = jitter.func_args_stdcall(["p_mdl", "access_mode", "op"])
 
-    if not ad2mdl(p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(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_MmMapLockedPagesSpecifyCache(jitter):
-    ret_ad, args = jitter.func_args_stdcall(6)
-    p_mdl, access_mode, cache_type, base_ad, bugcheckonfailure, priority = args
-    if not ad2mdl(p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(p_mdl))
+    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(p_mdl)].ad)
+    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(2)
-    p_mdl, prot = args
-    if not ad2mdl(p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(p_mdl))
+    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(1)
-    p_mdl, = args
-    if not ad2mdl(p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(p_mdl))
+    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(1)
-    p_mdl, = args
-    if not ad2mdl(p_mdl) in winobjs.nt_mdl:
-        raise ValueError('unk mdl', hex(p_mdl))
-    del(winobjs.nt_mdl[ad2mdl(p_mdl)])
+    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, args = jitter.func_args_stdcall(0)
+    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(5)
-    relativeto, path, querytable, context, environ = args
-    p = get_str_unic(jitter, path)
+    ret_ad, args = jitter.func_args_stdcall(["relativeto", "path",
+                                             "querytable",
+                                             "context",
+                                             "environ"])
+    # path = get_str_unic(jitter, args.path)
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def ntoskrnl_ExAllocatePoolWithTagPriority(jitter):
-    ret_ad, args = jitter.func_args_stdcall(4)
-    pool_type, nbr_of_bytes, tag, priority = args
-
-    alloc_addr = winobjs.heap.next_addr(nbr_of_bytes)
+    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, "\x00" * nbr_of_bytes)
+        alloc_addr, PAGE_READ | PAGE_WRITE, "\x00" * args.nbr_of_bytes)
 
     jitter.func_ret_stdcall(ret_ad, alloc_addr)
 
 
 def my_lstrcmp(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    ptr_str1, ptr_str2 = args
-    s1 = get_str(ptr_str1)
-    s2 = get_str(ptr_str2)
+    ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2"])
+    s1 = get_str(args.ptr_str1)
+    s2 = get_str(args.ptr_str2)
     jitter.func_ret_stdcall(ret_ad, cmp(s1, s2))
 
 
@@ -1444,11 +1389,10 @@ def kernel32_lstrcmpi(jitter):
 
 
 def my_strcpy(jitter, funcname, get_str, set_str):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    ptr_str1, ptr_str2 = args
-    s2 = get_str(jitter, ptr_str2)
-    jitter.vm.set_mem(ptr_str1, set_str(s2))
-    jitter.func_ret_stdcall(ret_ad, ptr_str1)
+    ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2"])
+    s2 = get_str(jitter, args.ptr_str2)
+    jitter.vm.set_mem(args.ptr_str1, set_str(s2))
+    jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
 
 
 def kernel32_lstrcpyW(jitter):
@@ -1465,43 +1409,38 @@ def kernel32_lstrcpy(jitter):
 
 
 def kernel32_lstrcpyn(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    ptr_str1, ptr_str2, mlen = args
-    s2 = get_str_ansi(jitter, ptr_str2)
-    s2 = s2[:mlen]
-    jitter.vm.set_mem(ptr_str1, s2)
-
-    jitter.func_ret_stdcall(ret_ad, ptr_str1)
+    ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2",
+                                             "mlen"])
+    s2 = get_str_ansi(jitter, args.ptr_str2)
+    s2 = s2[:args.mlen]
+    jitter.vm.set_mem(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(1)
-    arg_src, = args
-    src = get_str(jitter, arg_src)
+    ret_ad, args = jitter.func_args_stdcall(["src"])
+    src = get_str(jitter, args.src)
     jitter.func_ret_stdcall(ret_ad, mylen(src))
 
 
 def kernel32_lstrlenA(jitter):
-    my_strlen(jitter, whoami(), get_str_ansi, lambda x: len(x))
+    my_strlen(jitter, whoami(), get_str_ansi, len)
 
 
 def kernel32_lstrlenW(jitter):
-    my_strlen(jitter, whoami(), get_str_unic, lambda x: len(x))
+    my_strlen(jitter, whoami(), get_str_unic, len)
 
 
 def kernel32_lstrlen(jitter):
-    my_strlen(jitter, whoami(), get_str_ansi, lambda x: len(x))
+    my_strlen(jitter, whoami(), get_str_ansi, len)
 
 
 def my_lstrcat(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    ptr_str1, ptr_str2 = args
-    s1 = get_str(jitter, ptr_str1)
-    s2 = get_str(jitter, ptr_str2)
-
-    s = s1 + s2
-    jitter.vm.set_mem(ptr_str1, s1 + s2)
-    jitter.func_ret_stdcall(ret_ad, ptr_str1)
+    ret_ad, args = jitter.func_args_stdcall(['ptr_str1', 'ptr_str2'])
+    s1 = get_str(jitter, args.ptr_str1)
+    s2 = get_str(jitter, args.ptr_str2)
+    jitter.vm.set_mem(args.ptr_str1, s1 + s2)
+    jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
 
 
 def kernel32_lstrcatA(jitter):
@@ -1513,44 +1452,44 @@ def kernel32_lstrcatW(jitter):
 
 
 def kernel32_GetUserGeoID(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    geoclass, = args
-    if geoclass == 14:
+    ret_ad, args = jitter.func_args_stdcall(["geoclass"])
+    if args.geoclass == 14:
         ret = 12345678
-    elif geoclass == 16:
+    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(8)
-    (lprootpathname, lpvolumenamebuffer, nvolumenamesize,
-     lpvolumeserialnumber, lpmaximumcomponentlength, lpfilesystemflags,
-     lpfilesystemnamebuffer, nfilesystemnamesize) = args
-
-
-    if lprootpathname:
-        s = get_str(jitter, lprootpathname)
-
-    if lpvolumenamebuffer:
+    ret_ad, args = jitter.func_args_stdcall(["lprootpathname",
+                                             "lpvolumenamebuffer",
+                                             "nvolumenamesize",
+                                             "lpvolumeserialnumber",
+                                             "lpmaximumcomponentlength",
+                                             "lpfilesystemflags",
+                                             "lpfilesystemnamebuffer",
+                                             "nfilesystemnamesize"])
+    if args.lprootpathname:
+        s = get_str(jitter, args.lprootpathname)
+
+    if args.lpvolumenamebuffer:
         s = "volumename"
-        s = s[:nvolumenamesize]
-        jitter.vm.set_mem(lpvolumenamebuffer, set_str(s))
+        s = s[:args.nvolumenamesize]
+        jitter.vm.set_mem(args.lpvolumenamebuffer, set_str(s))
 
-    if lpvolumeserialnumber:
-        jitter.vm.set_mem(lpvolumeserialnumber, pck32(11111111))
-    if lpmaximumcomponentlength:
-        jitter.vm.set_mem(lpmaximumcomponentlength, pck32(0xff))
-    if lpfilesystemflags:
-        jitter.vm.set_mem(lpfilesystemflags, pck32(22222222))
+    if args.lpvolumeserialnumber:
+        jitter.vm.set_mem(args.lpvolumeserialnumber, pck32(11111111))
+    if args.lpmaximumcomponentlength:
+        jitter.vm.set_mem(args.lpmaximumcomponentlength, pck32(0xff))
+    if args.lpfilesystemflags:
+        jitter.vm.set_mem(args.lpfilesystemflags, pck32(22222222))
 
-    if lpfilesystemnamebuffer:
+    if args.lpfilesystemnamebuffer:
         s = "filesystemname"
-        s = s[:nfilesystemnamesize]
-        jitter.vm.set_mem(lpfilesystemnamebuffer, set_str(s))
+        s = s[:args.nfilesystemnamesize]
+        jitter.vm.set_mem(args.lpfilesystemnamebuffer, set_str(s))
 
     jitter.func_ret_stdcall(ret_ad, 1)
 
@@ -1565,23 +1504,24 @@ def kernel32_GetVolumeInformationW(jitter):
 
 
 def kernel32_MultiByteToWideChar(jitter):
-    ret_ad, args = jitter.func_args_stdcall(6)
-    (codepage, dwflags, lpmultibytestr,
-     cbmultibyte, lpwidecharstr, cchwidechar) = args
-
-    src = get_str_ansi(jitter, lpmultibytestr) + '\x00'
+    ret_ad, args = jitter.func_args_stdcall(["codepage", "dwflags",
+                                             "lpmultibytestr",
+                                             "cbmultibyte",
+                                             "lpwidecharstr",
+                                             "cchwidechar"])
+    src = get_str_ansi(jitter, args.lpmultibytestr) + '\x00'
     l = len(src)
 
     src = "\x00".join(list(src))
-    jitter.vm.set_mem(lpwidecharstr, src)
+    jitter.vm.set_mem(args.lpwidecharstr, src)
     jitter.func_ret_stdcall(ret_ad, l)
 
 
 def my_GetEnvironmentVariable(jitter, funcname, get_str, set_str, mylen):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    lpname, lpbuffer, nsize = args
+    ret_ad, args = jitter.func_args_stdcall(["lpname", "lpbuffer",
+                                             "nsize"])
 
-    s = get_str(jitter, lpname)
+    s = get_str(jitter, args.lpname)
     if get_str == get_str_unic:
         s = s
     log.debug('variable %r' % s)
@@ -1590,19 +1530,16 @@ def my_GetEnvironmentVariable(jitter, funcname, get_str, set_str, mylen):
     else:
         log.warning('WARNING unknown env variable %r' % s)
         v = ""
-    jitter.vm.set_mem(lpbuffer, v)
+    jitter.vm.set_mem(args.lpbuffer, v)
     jitter.func_ret_stdcall(ret_ad, mylen(v))
 
 
 def my_GetSystemDirectory(jitter, funcname, set_str):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    lpbuffer, usize = args
-
+    ret_ad, args = jitter.func_args_stdcall(["lpbuffer", "usize"])
     s = "c:\\windows\\system32"
     l = len(s)
     s = set_str(s)
-    jitter.vm.set_mem(lpbuffer, s)
-
+    jitter.vm.set_mem(args.lpbuffer, s)
     jitter.func_ret_stdcall(ret_ad, l)
 
 
@@ -1615,9 +1552,8 @@ def kernel32_GetSystemDirectoryW(jitter):
 
 
 def my_CreateDirectory(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    lppath, secattrib = args
-    p = get_str(jitter, lppath)
+    ret_ad, args = jitter.func_args_stdcall(['lppath', 'secattrib'])
+    # path = get_str(jitter, args.lppath)
     jitter.func_ret_stdcall(ret_ad, 0x1337)
 
 
@@ -1633,28 +1569,26 @@ def kernel32_GetEnvironmentVariableA(jitter):
     my_GetEnvironmentVariable(jitter, whoami(),
                               get_str_ansi,
                               lambda x: x + "\x00",
-                              lambda x: len(x))
+                              len)
 
 
 def kernel32_GetEnvironmentVariableW(jitter):
     my_GetEnvironmentVariable(jitter, whoami(),
                               get_str_unic,
                               lambda x: "\x00".join(list(x + "\x00")),
-                              lambda x: len(x))
+                              len)
 
 
 def my_CreateEvent(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(4)
-    lpeventattributes, bmanualreset, binitialstate, lpname = args
-    if lpname:
-        s = get_str(jitter, lpname)
-    else:
-        s = None
+    ret_ad, args = jitter.func_args_stdcall(["lpeventattributes",
+                                             "bmanualreset",
+                                             "binitialstate",
+                                             "lpname"])
+    s = get_str(jitter, args.lpname) if args.lpname else None
     if not s in winobjs.events_pool:
-        winobjs.events_pool[s] = (bmanualreset, binitialstate)
+        winobjs.events_pool[s] = (args.bmanualreset, args.binitialstate)
     else:
         log.warning('WARNING: known event')
-
     jitter.func_ret_stdcall(ret_ad, id(s))
 
 
@@ -1667,20 +1601,19 @@ def kernel32_CreateEventW(jitter):
 
 
 def kernel32_WaitForSingleObject(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    handle, dwms = args
+    ret_ad, args = jitter.func_args_stdcall(['handle', 'dwms'])
 
     t_start = time.time() * 1000
     found = False
     while True:
-        if dwms and dwms + t_start > time.time() * 1000:
+        if args.dwms and args.dwms + t_start > time.time() * 1000:
             ret = 0x102
             break
-        for k, v in winobjs.events_pool.items():
-            if k != handle:
+        for key, value in winobjs.events_pool.iteritems():
+            if key != args.handle:
                 continue
             found = True
-            if winobjs.events_pool[k][1] == 1:
+            if value[1] == 1:
                 ret = 0
                 break
         if not found:
@@ -1692,70 +1625,72 @@ def kernel32_WaitForSingleObject(jitter):
 
 
 def kernel32_SetFileAttributesA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    lpfilename, dwfileattributes = args
-
-    if lpfilename:
-        fname = get_str_ansi(jitter, lpfilename)
+    ret_ad, args = jitter.func_args_stdcall(["lpfilename",
+                                             "dwfileattributes"])
+    if args.lpfilename:
+        # fname = get_str_ansi(jitter, args.lpfilename)
         ret = 1
     else:
         ret = 0
-        jitter.vm.set_mem(seh_helper.FS_0_AD + 0x34, pck32(3))
+        jitter.vm.set_mem(FS_0_AD + 0x34, pck32(3))
 
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
 def ntdll_RtlMoveMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    dst, src, l = args
-    s = jitter.vm.get_mem(src, l)
-    jitter.vm.set_mem(dst, s)
-
+    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(4)
-    (systeminformationclass, systeminformation,
-     systeminformationl, returnl) = args
-    if systeminformationclass == 2:
+    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 += "\x00" * systeminformationl
-        o = o[:systeminformationl]
-        jitter.vm.set_mem(systeminformation, o)
+        o += "\x00" * args.systeminformationl
+        o = o[:args.systeminformationl]
+        jitter.vm.set_mem(args.systeminformation, o)
     else:
-        raise ValueError('unknown sysinfo class', systeminformationclass)
-
+        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(5)
-    handle, lppvoid, pdwsize, flnewprotect, lpfloldprotect = args
+    ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid",
+                                             "pdwsize",
+                                             "flnewprotect",
+                                             "lpfloldprotect"])
 
-    ad = upck32(jitter.vm.get_mem(lppvoid, 4))
-    dwsize = upck32(jitter.vm.get_mem(pdwsize, 4))
+    ad = upck32(jitter.vm.get_mem(args.lppvoid, 4))
+    # dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4))
     # XXX mask hpart
-    flnewprotect &= 0xFFF
+    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_mem(lpfloldprotect, pck32(0x40))
+    jitter.vm.set_mem(args.lpfloldprotect, pck32(0x40))
 
-    dump_memory_page_pool_py()
+    # dump_memory_page_pool_py()
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def ntdll_ZwAllocateVirtualMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(6)
-    handle, lppvoid, zerobits, pdwsize, alloc_type, flprotect = args
+    ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid",
+                                             "zerobits", "pdwsize",
+                                             "alloc_type",
+                                             "flprotect"])
 
-    ad = upck32(jitter.vm.get_mem(lppvoid, 4))
-    dwsize = upck32(jitter.vm.get_mem(pdwsize, 4))
+    # ad = upck32(jitter.vm.get_mem(args.lppvoid, 4))
+    dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4))
 
     access_dict = {0x0: 0,
                    0x1: 0,
@@ -1767,51 +1702,45 @@ def ntdll_ZwAllocateVirtualMemory(jitter):
                    0x100: 0
                        }
 
-    access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
+    # access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
 
-    if not flprotect in access_dict:
+    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[flprotect], "\x00" * dwsize)
-    jitter.vm.set_mem(lppvoid, pck32(alloc_addr))
+        alloc_addr, access_dict[args.flprotect], "\x00" * dwsize)
+    jitter.vm.set_mem(args.lppvoid, pck32(alloc_addr))
 
-    dump_memory_page_pool_py()
+    # dump_memory_page_pool_py()
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def ntdll_ZwFreeVirtualMemory(jitter):
-    ret_ad, args = jitter.func_args_stdcall(4)
-    handle, lppvoid, pdwsize, alloc_type = args
-    ad = upck32(jitter.vm.get_mem(lppvoid, 4))
-    dwsize = upck32(jitter.vm.get_mem(pdwsize, 4))
-
+    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(2)
-    pstring, source = args
-    s = get_str_ansi(jitter, source)
-
+    ret_ad, args = jitter.func_args_stdcall(["pstring", "source"])
+    s = get_str_ansi(jitter, args.source)
     l = len(s) + 1
-
-    o = struct.pack('HHI', l, l, source)
-    jitter.vm.set_mem(pstring, o)
-
+    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(3)
-    dst, src, alloc_str = args
+    ret_ad, args = jitter.func_args_stdcall(["dst", "src", "alloc_str"])
 
-    l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(src, 0x8))
+    l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8))
     s = get_str_ansi(jitter, p_src)
     s = ("\x00".join(s + "\x00"))
     l = len(s) + 1
-    if alloc_str:
+    if args.alloc_str:
         alloc_addr = winobjs.heap.next_addr(l)
         jitter.vm.add_memory_page(
             alloc_addr, PAGE_READ | PAGE_WRITE, "\x00" * l)
@@ -1819,114 +1748,99 @@ def ntdll_RtlAnsiStringToUnicodeString(jitter):
         alloc_addr = p_src
     jitter.vm.set_mem(alloc_addr, s)
     o = struct.pack('HHI', l, l, alloc_addr)
-    jitter.vm.set_mem(dst, o)
+    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(4)
-    path, flags, modname, modhandle = args
+    ret_ad, args = jitter.func_args_stdcall(["path", "flags",
+                                             "modname", "modhandle"])
 
-    l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(modname, 0x8))
+    l1, l2, p_src = struct.unpack('HHI',
+                                  jitter.vm.get_mem(args.modname, 0x8))
     s = get_str_unic(jitter, p_src)
     libname = s.lower()
 
     ad = winobjs.runtime_dll.lib_get_add_base(libname)
-    jitter.vm.set_mem(modhandle, pck32(ad))
+    jitter.vm.set_mem(args.modhandle, pck32(ad))
 
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def ntdll_RtlFreeUnicodeString(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    src, = args
-
-    l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(src, 0x8))
-    s = get_str_unic(jitter, p_src)
-
+    ret_ad, args = jitter.func_args_stdcall(['src'])
+    # l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8))
+    # s = get_str_unic(jitter, p_src)
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def ntdll_LdrGetProcedureAddress(jitter):
-    ret_ad, args = jitter.func_args_stdcall(4)
-    libbase, pfname, opt, p_ad = args
+    ret_ad, args = jitter.func_args_stdcall(["libbase", "pfname",
+                                             "opt", "p_ad"])
 
-    l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(pfname, 0x8))
+    l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.pfname, 0x8))
     fname = get_str_ansi(jitter, p_src)
 
-    ad = winobjs.runtime_dll.lib_get_add_func(libbase, fname)
+    ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname)
 
-    jitter.vm.set_mem(p_ad, pck32(ad))
+    jitter.vm.set_mem(args.p_ad, pck32(ad))
 
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def ntdll_memset(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    arg_addr, arg_c, arg_size = args
-
-    jitter.vm.set_mem(arg_addr, chr(arg_c) * arg_size)
-    jitter.func_ret_stdcall(ret_ad, arg_addr)
+    ret_ad, args = jitter.func_args_stdcall(['addr', 'c', 'size'])
+    jitter.vm.set_mem(args.addr, chr(args.c) * args.size)
+    jitter.func_ret_stdcall(ret_ad, args.addr)
 
 
 def msvcrt_memset(jitter):
-    ret_ad, args = jitter.func_args_cdecl(3)
-    arg_addr, arg_c, arg_size = args
-
-    jitter.vm.set_mem(arg_addr, chr(arg_c) * arg_size)
-    jitter.func_ret_cdecl(ret_ad, arg_addr)
+    ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size'])
+    jitter.vm.set_mem(args.addr, chr(args.c) * args.size)
+    jitter.func_ret_cdecl(ret_ad, args.addr)
 
 
 def msvcrt_memcpy(jitter):
-    ret_ad, args = jitter.func_args_cdecl(3)
-    dst, src, size = args
-
-    s = jitter.vm.get_mem(src, size)
-    jitter.vm.set_mem(dst, s)
-    jitter.func_ret_cdecl(ret_ad, dst)
+    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_memcmp(jitter):
-    ret_ad, args = jitter.func_args_cdecl(3)
-    ps1, ps2, size = args
-
-    s1 = jitter.vm.get_mem(ps1, size)
-    s2 = jitter.vm.get_mem(ps2, size)
+    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(1)
-    path_ad, = args
-
-    path = get_str_ansi(jitter, path_ad)
+    ret_ad, args = jitter.func_args_stdcall(['path_ad'])
+    path = get_str_ansi(jitter, args.path_ad)
     i = path.rfind('.')
     if i == -1:
-        i = path_ad + len(path)
+        i = args.path_ad + len(path)
     else:
-        i = path_ad + i
+        i = args.path_ad + i
     jitter.func_ret_stdcall(ret_ad, i)
 
 
 def shlwapi_PathRemoveFileSpecW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    path_ad, = args
-
-    path = get_str_unic(jitter, path_ad)
+    ret_ad, args = jitter.func_args_stdcall(['path_ad'])
+    path = get_str_unic(jitter, args.path_ad)
     i = path.rfind('\\')
     if i == -1:
         i = 0
-    jitter.vm.set_mem(path_ad + i * 2, "\x00\x00")
-    path = get_str_unic(jitter, path_ad)
+    jitter.vm.set_mem(args.path_ad + i * 2, "\x00\x00")
+    path = get_str_unic(jitter, args.path_ad)
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def shlwapi_PathIsPrefixW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    ptr_prefix, ptr_path = args
-    prefix = get_str_unic(jitter, ptr_prefix)
-    path = get_str_unic(jitter, ptr_path)
+    ret_ad, args = jitter.func_args_stdcall(['ptr_prefix', 'ptr_path'])
+    prefix = get_str_unic(jitter, args.ptr_prefix)
+    path = get_str_unic(jitter, args.ptr_path)
 
     if path.startswith(prefix):
         ret = 1
@@ -1936,9 +1850,8 @@ def shlwapi_PathIsPrefixW(jitter):
 
 
 def shlwapi_PathIsDirectoryW(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    ppath, = args
-    fname = get_str_unic(jitter, ppath)
+    ret_ad, args = jitter.func_args_stdcall(['ptr_path'])
+    fname = get_str_unic(jitter, args.ptr_path)
 
     fname = fname.replace('\\', "/").lower()
     f = os.path.join('file_sb', fname)
@@ -1951,10 +1864,9 @@ def shlwapi_PathIsDirectoryW(jitter):
     jitter.func_ret_cdecl(ret_ad, ret)
 
 
-def shlwapi_PathIsFileSpec(funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    path_ad, = args
-    path = get_str(jitter, path_ad)
+def shlwapi_PathIsFileSpec(jitter, funcname, get_str):
+    ret_ad, args = jitter.func_args_stdcall(['path_ad'])
+    path = get_str(jitter, args.path_ad)
     if path.find(':') != -1 and path.find('\\') != -1:
         ret = 0
     else:
@@ -1964,9 +1876,8 @@ def shlwapi_PathIsFileSpec(funcname, get_str):
 
 
 def shlwapi_PathGetDriveNumber(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    path_ad, = args
-    path = get_str(jitter, path_ad)
+    ret_ad, args = jitter.func_args_stdcall(['path_ad'])
+    path = get_str(jitter, args.path_ad)
     l = ord(path[0].upper()) - ord('A')
     if 0 <= l <= 25:
         ret = l
@@ -1985,17 +1896,16 @@ def shlwapi_PathGetDriveNumberW(jitter):
 
 
 def shlwapi_PathIsFileSpecA(jitter):
-    shlwapi_PathIsFileSpec(whoami(), get_str_ansi)
+    shlwapi_PathIsFileSpec(jitter, whoami(), get_str_ansi)
 
 
 def shlwapi_PathIsFileSpecW(jitter):
-    shlwapi_PathIsFileSpec(whoami(), get_str_unic)
+    shlwapi_PathIsFileSpec(jitter, whoami(), get_str_unic)
 
 
 def shlwapi_StrToIntA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    i_str_ad, = args
-    i_str = get_str_ansi(jitter, i_str_ad)
+    ret_ad, args = jitter.func_args_stdcall(['i_str_ad'])
+    i_str = get_str_ansi(jitter, args.i_str_ad)
     try:
         i = int(i_str)
     except:
@@ -2006,22 +1916,20 @@ def shlwapi_StrToIntA(jitter):
 
 
 def shlwapi_StrToInt64Ex(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    pstr, flags, pret = args
-    i_str = get_str(jitter, pstr)
+    ret_ad, args = jitter.func_args_stdcall(['pstr', 'flags', 'pret'])
+    i_str = get_str(jitter, args.pstr)
     if get_str is get_str_unic:
         i_str = i_str
 
-    if flags == 0:
+    if args.flags == 0:
         r = int(i_str)
-    elif flags == 1:
+    elif args.flags == 1:
         r = int(i_str, 16)
     else:
         raise ValueError('cannot decode int')
 
-    jitter.vm.set_mem(pret, struct.pack('q', r))
-
-    jitter.func_ret_stdcall(ret_ad, i)
+    jitter.vm.set_mem(args.pret, struct.pack('q', r))
+    jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def shlwapi_StrToInt64ExA(jitter):
@@ -2033,12 +1941,11 @@ def shlwapi_StrToInt64ExW(jitter):
 
 
 def user32_IsCharAlpha(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    c, = args
+    ret_ad, args = jitter.func_args_stdcall(["c"])
     try:
-        c = chr(c)
+        c = chr(args.c)
     except:
-        log.error('bad char %r' % c)
+        log.error('bad char %r' % args.c)
         c = "\x00"
     if c.isalpha(jitter):
         ret = 1
@@ -2056,9 +1963,8 @@ def user32_IsCharAlphaW(jitter):
 
 
 def user32_IsCharAlphaNumericA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    c, = args
-    c = chr(c)
+    ret_ad, args = jitter.func_args_stdcall(["c"])
+    c = chr(args.c)
     if c.isalnum(jitter):
         ret = 1
     else:
@@ -2067,27 +1973,24 @@ def user32_IsCharAlphaNumericA(jitter):
 
 
 def shlwapi_StrCmpNIA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    ptr_str1, ptr_str2, nchar = args
-    s1 = get_str_ansi(jitter, ptr_str1).lower()
-    s2 = get_str_ansi(jitter, ptr_str2).lower()
-    s1 = s1[:nchar]
-    s2 = s2[:nchar]
-
+    ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2",
+                                             "nchar"])
+    s1 = get_str_ansi(jitter, args.ptr_str1).lower()
+    s2 = get_str_ansi(jitter, args.ptr_str2).lower()
+    s1 = s1[:args.nchar]
+    s2 = s2[:args.nchar]
     jitter.func_ret_stdcall(ret_ad, cmp(s1, s2))
 
 
 def advapi32_RegOpenKeyEx(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    hkey, subkey, reserved, access, phandle = args
-    if subkey:
-        s_subkey = get_str(jitter, subkey).lower()
-    else:
-        s_subkey = ""
+    ret_ad, args = jitter.func_args_stdcall(["hkey", "subkey",
+                                             "reserved", "access",
+                                             "phandle"])
+    s_subkey = get_str(jitter, args.subkey).lower() if args.subkey else ""
 
     ret_hkey = 0
     ret = 2
-    if hkey in winobjs.hkey_handles:
+    if args.hkey in winobjs.hkey_handles:
         if s_subkey:
             h = hash(s_subkey) & 0xffffffff
             if h in winobjs.hkey_handles:
@@ -2096,7 +1999,7 @@ def advapi32_RegOpenKeyEx(jitter, funcname, get_str):
         else:
             log.error('unknown skey')
 
-    jitter.vm.set_mem(phandle, pck32(ret_hkey))
+    jitter.vm.set_mem(args.phandle, pck32(ret_hkey))
 
     jitter.func_ret_stdcall(ret_ad, ret)
 
@@ -2110,17 +2013,11 @@ def advapi32_RegOpenKeyExW(jitter):
 
 
 def advapi32_RegSetValue(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    hkey, psubkey, valuetype, pvalue, length = args
-    if psubkey:
-        subkey = get_str(jitter, psubkey).lower()
-    else:
-        subkey = ""
-
-    if pvalue:
-        value = jitter.vm.get_mem(pvalue, length)
-    else:
-        value = None
+    ret_ad, args = jitter.func_args_stdcall(["hkey", "psubkey",
+                                             "valuetype", "pvalue",
+                                             "vlen"])
+    # subkey = get_str(jitter, args.psubkey).lower() if args.psubkey else ""
+    # value = jitter.vm.get_mem(args.pvalue, args.vlen) if args.pvalue else None
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
@@ -2133,21 +2030,21 @@ def advapi32_RegSetValueW(jitter):
 
 
 def kernel32_GetThreadLocale(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     jitter.func_ret_stdcall(ret_ad, 0x40c)
 
 
 def kernel32_GetLocaleInfo(jitter, funcname, set_str):
-    ret_ad, args = jitter.func_args_stdcall(4)
-    localeid, lctype, lplcdata, cchdata = args
+    ret_ad, args = jitter.func_args_stdcall(["localeid", "lctype",
+                                             "lplcdata", "cchdata"])
 
     buf = None
     ret = 0
-    if localeid == 0x40c:
-        if lctype == 0x3:
+    if args.localeid == 0x40c:
+        if args.lctype == 0x3:
             buf = "ENGLISH"
-            buf = buf[:cchdata - 1]
-            jitter.vm.set_mem(lplcdata, set_str(buf))
+            buf = buf[:args.cchdata - 1]
+            jitter.vm.set_mem(args.lplcdata, set_str(buf))
             ret = len(buf)
     else:
         raise ValueError('unimpl localeid')
@@ -2164,38 +2061,34 @@ def kernel32_GetLocaleInfoW(jitter):
 
 
 def kernel32_TlsAlloc(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    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, args = jitter.func_args_stdcall(1)
+    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(2)
-    tlsindex, tlsvalue = args
-    winobjs.tls_values[tlsindex] = tlsvalue
+    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(1)
-    tlsindex, = args
-
-    if not tlsindex in winobjs.tls_values:
-        raise ValueError("unknown tls val", repr(tlsindex))
-    jitter.func_ret_stdcall(ret_ad, winobjs.tls_values[tlsindex])
+    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(1)
-    typeflag, = args
+    ret_ad, args = jitter.func_args_stdcall(["typeflag"])
 
     ret = 0
-    if typeflag == 0:
+    if args.typeflag == 0:
         ret = 4
     else:
         raise ValueError('unimpl keyboard type')
@@ -2204,13 +2097,12 @@ def user32_GetKeyboardType(jitter):
 
 
 def kernel32_GetStartupInfo(jitter, funcname, set_str):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    ptr, = args
+    ret_ad, args = jitter.func_args_stdcall(["ptr"])
 
     s = "\x00" * 0x2c + "\x81\x00\x00\x00" + "\x0a"
 
-    jitter.vm.set_mem(ptr, s)
-    jitter.func_ret_stdcall(ret_ad, ptr)
+    jitter.vm.set_mem(args.ptr, s)
+    jitter.func_ret_stdcall(ret_ad, args.ptr)
 
 
 def kernel32_GetStartupInfoA(jitter):
@@ -2222,22 +2114,20 @@ def kernel32_GetStartupInfoW(jitter):
 
 
 def kernel32_GetCurrentThreadId(jitter):
-    ret_ad, args = jitter.func_args_stdcall(0)
+    ret_ad, _ = jitter.func_args_stdcall(0)
     jitter.func_ret_stdcall(ret_ad, 0x113377)
 
 
 def kernel32_InitializeCriticalSection(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    lpcritic, = args
+    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(1)
-    nindex, = args
+    ret_ad, args = jitter.func_args_stdcall(["nindex"])
 
     ret = 0
-    if nindex in [0x2a, 0x4a]:
+    if args.nindex in [0x2a, 0x4a]:
         ret = 0
     else:
         raise ValueError('unimpl index')
@@ -2245,16 +2135,13 @@ def user32_GetSystemMetrics(jitter):
 
 
 def wsock32_WSAStartup(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    version, pwsadata = args
-    jitter.vm.set_mem(pwsadata, "\x01\x01\x02\x02WinSock 2.0\x00")
-
+    ret_ad, args = jitter.func_args_stdcall(["version, pwsadata"])
+    jitter.vm.set_mem(args.pwsadata, "\x01\x01\x02\x02WinSock 2.0\x00")
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def kernel32_GetLocalTime(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    lpsystemtime, = args
+    ret_ad, args = jitter.func_args_stdcall(["lpsystemtime"])
 
     s = struct.pack('HHHHHHHH',
                     2011,  # year
@@ -2266,13 +2153,12 @@ def kernel32_GetLocalTime(jitter):
                     00,   # seconds
                     999,  # millisec
                     )
-    jitter.vm.set_mem(lpsystemtime, s)
-    jitter.func_ret_stdcall(ret_ad, lpsystemtime)
+    jitter.vm.set_mem(args.lpsystemtime, s)
+    jitter.func_ret_stdcall(ret_ad, args.lpsystemtime)
 
 
 def kernel32_GetSystemTime(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    lpsystemtime, = args
+    ret_ad, args = jitter.func_args_stdcall(["lpsystemtime"])
 
     s = struct.pack('HHHHHHHH',
                     2011,  # year
@@ -2284,24 +2170,20 @@ def kernel32_GetSystemTime(jitter):
                     00,   # seconds
                     999,  # millisec
                     )
-    jitter.vm.set_mem(lpsystemtime, s)
-    jitter.func_ret_stdcall(ret_ad, lpsystemtime)
+    jitter.vm.set_mem(args.lpsystemtime, s)
+    jitter.func_ret_stdcall(ret_ad, args.lpsystemtime)
 
 
 def kernel32_CreateFileMapping(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(6)
-    hfile, lpattr, flprotect, dwmaximumsizehigh, dwmaximumsizelow, lpname = args
+    ret_ad, args = jitter.func_args_stdcall(["hfile", "lpattr", "flprotect",
+                                             "dwmaximumsizehigh",
+                                             "dwmaximumsizelow", "lpname"])
+    # f = get_str(jitter, args.lpname) if args.lpname else None
 
-    if lpname:
-        f = get_str(jitter, lpname)
-    else:
-        f = None
-
-    if not hfile in winobjs.handle_pool:
+    if not args.hfile in winobjs.handle_pool:
         raise ValueError('unknown handle')
 
-    ret = winobjs.handle_pool.add('filemapping', hfile)
-
+    ret = winobjs.handle_pool.add('filemapping', args.hfile)
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
@@ -2314,25 +2196,24 @@ def kernel32_CreateFileMappingW(jitter):
 
 
 def kernel32_MapViewOfFile(jitter):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    hfile, flprotect, dwfileoffsethigh, dwfileoffsetlow, length = args
+    ret_ad, args = jitter.func_args_stdcall(["hfile", "flprotect",
+                                             "dwfileoffsethigh",
+                                             "dwfileoffsetlow",
+                                             "length"])
 
-    if not hfile in winobjs.handle_pool:
+    if not args.hfile in winobjs.handle_pool:
         raise ValueError('unknown handle')
-    hmap = winobjs.handle_pool[hfile]
+    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((dwfileoffsethigh << 32) | dwfileoffsetlow)
-    if length:
-        data = fd.read(length)
-    else:
-        data = fd.read()
+    fd.seek((args.dwfileoffsethigh << 32) | args.dwfileoffsetlow)
+    data = fd.read(args.length) if args.length else args.read()
     length = len(data)
 
-    log.debug( 'mapp total: %x' %len(data))
+    log.debug('mapp total: %x' %len(data))
     access_dict = {0x0: 0,
                    0x1: 0,
                    0x2: PAGE_READ,
@@ -2342,25 +2223,24 @@ def kernel32_MapViewOfFile(jitter):
                    0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
                    0x100: 0
                        }
-    access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
+    # access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
 
-    if not flprotect in access_dict:
+    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, dwfileoffsethigh, dwfileoffsetlow, length
+    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(1)
-    ad, = args
+    ret_ad, args = jitter.func_args_stdcall(['ad'])
 
-    if not ad in winobjs.handle_mapped:
+    if not args.ad in winobjs.handle_mapped:
         raise NotImplementedError("Untested case")
     """
     hfile_o, dwfileoffsethigh, dwfileoffsetlow, length = winobjs.handle_mapped[ad]
@@ -2374,11 +2254,9 @@ def kernel32_UnmapViewOfFile(jitter):
 
 
 def kernel32_GetDriveType(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    pathname, = args
-
+    ret_ad, args = jitter.func_args_stdcall(['pathname'])
 
-    p = get_str(jitter, pathname)
+    p = get_str(jitter, args.pathname)
     p = p.upper()
 
     ret = 0
@@ -2397,19 +2275,17 @@ def kernel32_GetDriveTypeW(jitter):
 
 
 def kernel32_GetDiskFreeSpace(jitter, funcname, get_str):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    (lprootpathname, lpsectorpercluster, lpbytespersector,
-     lpnumberoffreeclusters, lptotalnumberofclusters) = args
-
-    if lprootpathname:
-        rootpath = get_str(jitter, lprootpathname)
-    else:
-        rootpath = ""
-
-    jitter.vm.set_mem(lpsectorpercluster, pck32(8))
-    jitter.vm.set_mem(lpbytespersector, pck32(0x200))
-    jitter.vm.set_mem(lpnumberoffreeclusters, pck32(0x222222))
-    jitter.vm.set_mem(lptotalnumberofclusters, pck32(0x333333))
+    ret_ad, args = jitter.func_args_stdcall(["lprootpathname",
+                                             "lpsectorpercluster",
+                                             "lpbytespersector",
+                                             "lpnumberoffreeclusters",
+                                             "lptotalnumberofclusters"])
+    # rootpath = (get_str(jitter, args.lprootpathname)
+    #             if args.lprootpathname else "")
+    jitter.vm.set_mem(args.lpsectorpercluster, pck32(8))
+    jitter.vm.set_mem(args.lpbytespersector, pck32(0x200))
+    jitter.vm.set_mem(args.lpnumberoffreeclusters, pck32(0x222222))
+    jitter.vm.set_mem(args.lptotalnumberofclusters, pck32(0x333333))
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
@@ -2422,8 +2298,7 @@ def kernel32_GetDiskFreeSpaceW(jitter):
 
 
 def kernel32_VirtualQuery(jitter):
-    ret_ad, args = jitter.func_args_stdcall(3)
-    ad, lpbuffer, dwl = args
+    ret_ad, args = jitter.func_args_stdcall(["ad", "lpbuffer", "dwl"])
 
     access_dict = {0x0: 0,
                    0x1: 0,
@@ -2433,104 +2308,101 @@ def kernel32_VirtualQuery(jitter):
                    0x20: PAGE_EXEC | PAGE_READ,
                    0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE,
                    0x100: 0
-                       }
-    access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()])
+               }
+    access_dict_inv = dict([(x[1], x[0]) for x in access_dict.iteritems()])
 
     all_mem = jitter.vm.get_all_memory()
     found = None
-    for basead, m in all_mem.items():
-        if basead <= ad < basead + m['size']:
-            found = ad, m
+    for basead, m in all_mem.iteritems():
+        if basead <= args.ad < basead + m['size']:
+            found = args.ad, m
             break
     if not found:
-        raise ValueError('cannot find mem', hex(ad))
+        raise ValueError('cannot find mem', hex(args.ad))
 
-    if dwl != 0x1c:
-        raise ValueError('strange mem len', hex(dwl))
+    if args.dwl != 0x1c:
+        raise ValueError('strange mem len', hex(args.dwl))
     s = struct.pack('IIIIIII',
-                    ad,
+                    args.ad,
                     basead,
                     access_dict_inv[m['access']],
                     m['size'],
                     0x1000,
                     access_dict_inv[m['access']],
                     0x01000000)
-    jitter.vm.set_mem(lpbuffer, s)
-
-    jitter.func_ret_stdcall(ret_ad, dwl)
+    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(3)
-    hprocess, procaffmask, systemaffmask = args
-    jitter.vm.set_mem(procaffmask, pck32(1))
-    jitter.vm.set_mem(systemaffmask, pck32(1))
-
+    ret_ad, args = jitter.func_args_stdcall(["hprocess",
+                                             "procaffmask",
+                                             "systemaffmask"])
+    jitter.vm.set_mem(args.procaffmask, pck32(1))
+    jitter.vm.set_mem(args.systemaffmask, pck32(1))
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def msvcrt_rand(jitter):
-    ret_ad, args = jitter.func_args_cdecl(0)
+    ret_ad, _ = jitter.func_args_cdecl(0)
     jitter.func_ret_stdcall(ret_ad, 0x666)
 
 
 def kernel32_SetFilePointer(jitter):
-    ret_ad, args = jitter.func_args_stdcall(4)
-    hwnd, distance, p_distance_high, movemethod = args
+    ret_ad, args = jitter.func_args_stdcall(["hwnd", "distance",
+                                             "p_distance_high",
+                                             "movemethod"])
 
-    if hwnd == winobjs.module_cur_hwnd:
+    if args.hwnd == winobjs.module_cur_hwnd:
         pass
-    elif hwnd in winobjs.handle_pool:
+    elif args.hwnd in winobjs.handle_pool:
         pass
     else:
         raise ValueError('unknown hwnd!')
 
-    eax = 0xffffffff
-    data = None
-    if hwnd in winobjs.files_hwnd:
-        winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(distance)
-    elif hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[hwnd]
-        data = wh.info.seek(distance)
+    # data = None
+    if args.hwnd in winobjs.files_hwnd:
+        winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(args.distance)
+    elif args.hwnd in winobjs.handle_pool:
+        wh = winobjs.handle_pool[args.hwnd]
+        # data = wh.info.seek(args.distance)
     else:
         raise ValueError('unknown filename')
-    jitter.func_ret_stdcall(ret_ad, distance)
+    jitter.func_ret_stdcall(ret_ad, args.distance)
 
 
 def kernel32_SetFilePointerEx(jitter):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    hwnd, distance_l, distance_h, pnewfileptr, movemethod = args
-
-    distance = distance_l | (distance_h << 32)
+    ret_ad, args = jitter.func_args_stdcall(["hwnd", "distance_l",
+                                             "distance_h",
+                                             "pnewfileptr",
+                                             "movemethod"])
+    distance = args.distance_l | (args.distance_h << 32)
     if distance:
-        TODO_XXX
-
-    if pnewfileptr:
-        TODO_XXX
-    if hwnd == winobjs.module_cur_hwnd:
+        raise ValueError('Not implemented')
+    if args.pnewfileptr:
+        raise ValueError('Not implemented')
+    if args.hwnd == winobjs.module_cur_hwnd:
         pass
-    elif hwnd in winobjs.handle_pool:
+    elif args.hwnd in winobjs.handle_pool:
         pass
     else:
         raise ValueError('unknown hwnd!')
 
-    eax = 0xffffffff
-    data = None
-    if hwnd in winobjs.files_hwnd:
+    # data = None
+    if args.hwnd in winobjs.files_hwnd:
         winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(distance)
-    elif hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[hwnd]
-        data = wh.info.seek(distance)
+    elif args.hwnd in winobjs.handle_pool:
+        wh = winobjs.handle_pool[args.hwnd]
+        # data = wh.info.seek(distance)
     else:
         raise ValueError('unknown filename')
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def kernel32_SetEndOfFile(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    hwnd, = args
-    if hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[hwnd]
+    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')
@@ -2538,9 +2410,8 @@ def kernel32_SetEndOfFile(jitter):
 
 
 def kernel32_FlushFileBuffers(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    hwnd, = args
-    if hwnd in winobjs.handle_pool:
+    ret_ad, args = jitter.func_args_stdcall(['hwnd'])
+    if args.hwnd in winobjs.handle_pool:
         pass
     else:
         raise ValueError('unknown filename')
@@ -2548,112 +2419,75 @@ def kernel32_FlushFileBuffers(jitter):
 
 
 def kernel32_WriteFile(jitter):
-    ret_ad, args = jitter.func_args_stdcall(5)
-    (hwnd, lpbuffer, nnumberofbytestowrite,
-     lpnumberofbyteswrite, lpoverlapped) = args
-
-    data = jitter.vm.get_mem(lpbuffer, nnumberofbytestowrite)
+    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpbuffer",
+                                             "nnumberofbytestowrite",
+                                             "lpnumberofbyteswrite",
+                                             "lpoverlapped"])
+    data = jitter.vm.get_mem(args.lpbuffer, args.nnumberofbytestowrite)
 
-    if hwnd == winobjs.module_cur_hwnd:
+    if args.hwnd == winobjs.module_cur_hwnd:
         pass
-    elif hwnd in winobjs.handle_pool:
+    elif args.hwnd in winobjs.handle_pool:
         pass
     else:
         raise ValueError('unknown hwnd!')
 
-    eax = 0xffffffff
-    if hwnd in winobjs.files_hwnd:
+    if args.hwnd in winobjs.files_hwnd:
         winobjs.files_hwnd[winobjs.module_cur_hwnd].write(data)
-    elif hwnd in winobjs.handle_pool:
-        wh = winobjs.handle_pool[hwnd]
+    elif args.hwnd in winobjs.handle_pool:
+        wh = winobjs.handle_pool[args.hwnd]
         wh.info.write(data)
     else:
         raise ValueError('unknown filename')
 
-    if (lpnumberofbyteswrite):
-        jitter.vm.set_mem(lpnumberofbyteswrite, pck32(len(data)))
+    if (args.lpnumberofbyteswrite):
+        jitter.vm.set_mem(args.lpnumberofbyteswrite, pck32(len(data)))
 
     jitter.func_ret_stdcall(ret_ad, 1)
 
 
 def user32_IsCharUpperA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    c, = args
-
-    if c & 0x20:
-        ret = 0
-    else:
-        ret = 1
+    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(1)
-    c, = args
-
-    if c & 0x20:
-        ret = 1
-    else:
-        ret = 0
-
+    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, args = jitter.func_args_stdcall(0)
+    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(1)
-    msize, = args
-    addr = winobjs.heap.alloc(jitter, msize)
+    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, args = jitter.func_args_cdecl(1)
-    ptr, = args
+    ret_ad, _ = jitter.func_args_cdecl(["ptr"])
     jitter.func_ret_cdecl(ret_ad, 0)
 
 
-def msvcrt_fopen(jitter):
-    ret_ad, args = jitter.func_args_cdecl(2)
-    fname, rw = args
-
-    fname = get_str_ansi(jitter, fname)
-    rw = get_str_ansi(jitter, rw)
-    log.debug((fname, rw))
-    if rw in ['rb', 'wb+']:
-        fname = fname.replace('\\', "/").lower()
-        f = os.path.join('file_sb', fname)
-        h = open(f, rw)
-        eax = winobjs.handle_pool.add(f, h)
-        alloc_addr = winobjs.heap.alloc(jitter, 0x20)
-        jitter.vm.set_mem(alloc_addr, pck32(0x11112222) + pck32(
-            0) + pck32(0) + pck32(0) + pck32(eax))  # pck32(0x11112222)
-    else:
-        raise NotImplementedError("Untested case")
-
-    jitter.func_ret_cdecl(ret_ad, alloc_addr)
-
-
 def msvcrt_fseek(jitter):
-    ret_ad, args = jitter.func_args_cdecl(3)
-    stream, offset, orig = args
-    fd = upck32(jitter.vm.get_mem(stream + 0x10, 4))
+    ret_ad, args = jitter.func_args_cdecl(['stream', 'offset', 'orig'])
+    fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
 
     if not fd in winobjs.handle_pool:
         raise NotImplementedError("Untested case")
     o = winobjs.handle_pool[fd]
-    o.info.seek(offset, orig)
+    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(1)
-    stream, = args
-    fd = upck32(jitter.vm.get_mem(stream + 0x10, 4))
+    ret_ad, args = jitter.func_args_cdecl(["stream"])
+    fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
 
     if not fd in winobjs.handle_pool:
         raise NotImplementedError("Untested case")
@@ -2663,65 +2497,58 @@ def msvcrt_ftell(jitter):
 
 
 def msvcrt_rewind(jitter):
-    ret_ad, args = jitter.func_args_cdecl(1)
-    stream, = args
-    fd = upck32(jitter.vm.get_mem(stream + 0x10, 4))
-
+    ret_ad, args = jitter.func_args_cdecl(["stream"])
+    fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
     if not fd in winobjs.handle_pool:
         raise NotImplementedError("Untested case")
     o = winobjs.handle_pool[fd]
-    off = o.info.seek(0, 0)
+    # off = o.info.seek(0, 0)
     jitter.func_ret_cdecl(ret_ad, 0)
 
 
 def msvcrt_fread(jitter):
-    ret_ad, args = jitter.func_args_cdecl(4)
-    buf, size, nmemb, stream = args
-    fd = upck32(jitter.vm.get_mem(stream + 0x10, 4))
+    ret_ad, args = jitter.func_args_cdecl(["buf", "size", "nmemb", "stream"])
+    fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
     if not fd in winobjs.handle_pool:
         raise NotImplementedError("Untested case")
 
-    data = winobjs.handle_pool[fd].info.read(size * nmemb)
-    jitter.vm.set_mem(buf, data)
-    jitter.func_ret_cdecl(ret_ad, nmemb)
+    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_fclose(jitter):
-    ret_ad, args = jitter.func_args_cdecl(1)
-    stream, = args
-    fd = upck32(jitter.vm.get_mem(stream + 0x10, 4))
+    ret_ad, args = jitter.func_args_cdecl(['stream'])
+    fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4))
 
     if not fd in winobjs.handle_pool:
         raise NotImplementedError("Untested case")
     o = winobjs.handle_pool[fd]
-    off = o.info.close()
+    # off = o.info.close()
     jitter.func_ret_cdecl(ret_ad, 0)
 
 
 def msvcrt_atexit(jitter):
-    ret_ad, args = jitter.func_args_cdecl(1)
-    func, = args
+    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(4)
-    hwnd, lptext, lpcaption, utype = args
+    ret_ad, args = jitter.func_args_stdcall(["hwnd", "lptext",
+                                             "lpcaption", "utype"])
 
-    text = get_str_ansi(jitter, lptext)
-    caption = get_str_ansi(jitter, lpcaption)
+    text = get_str_ansi(jitter, args.lptext)
+    caption = get_str_ansi(jitter, args.lpcaption)
 
-    log.info('Caption: %r Text: %r' %(caption, text))
+    log.info('Caption: %r Text: %r' % (caption, text))
 
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
 def kernel32_myGetTempPath(jitter, func):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    l, buf = args
-
+    ret_ad, args = jitter.func_args_stdcall(["l", "buf"])
     l = 'c:\\temp\\'
-    jitter.vm.set_mem(buf, func(l + '\x00'))
+    jitter.vm.set_mem(args.buf, func(l + '\x00'))
     jitter.func_ret_stdcall(ret_ad, len(l))
 
 
@@ -2738,20 +2565,13 @@ temp_num = 0
 
 def kernel32_GetTempFileNameA(jitter):
     global temp_num
-    ret_ad, args = jitter.func_args_stdcall(4)
-    path, ext, unique, buf = args
+    ret_ad, args = jitter.func_args_stdcall(["path", "ext", "unique", "buf"])
 
     temp_num += 1
-    if ext:
-        ext = get_str_ansi(jitter, ext)
-    else:
-        ext = 'tmp'
-    if path:
-        path = get_str_ansi(jitter, path)
-    else:
-        path = "xxx"
+    ext = get_str_ansi(jitter, args.ext) if args.ext else 'tmp'
+    path = get_str_ansi(jitter, args.path) if args.path else "xxx"
     fname = path + "\\" + "temp%.4d" % temp_num + "." + ext
-    jitter.vm.set_mem(buf, fname)
+    jitter.vm.set_mem(args.buf, fname)
 
     jitter.func_ret_stdcall(ret_ad, 0)
 
@@ -2782,8 +2602,8 @@ class win32_find_data:
                         self.filesizelow,
                         self.dwreserved0,
                         self.dwreserved1)
-        fname = self.cfilename + '\x00' * win_api_x86_32.MAX_PATH
-        fname = fname[:win_api_x86_32.MAX_PATH]
+        fname = self.cfilename + '\x00' * MAX_PATH
+        fname = fname[:MAX_PATH]
         s += fname
         fname = self.alternamefilename + '\x00' * 14
         fname = fname[:14]
@@ -2824,39 +2644,36 @@ class find_data_mngr:
 
 
 def kernel32_FindFirstFileA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    pfilepattern, pfindfiledata = args
+    ret_ad, args = jitter.func_args_stdcall(["pfilepattern", "pfindfiledata"])
 
-    filepattern = get_str_ansi(jitter, pfilepattern)
+    filepattern = get_str_ansi(jitter, args.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())
+    jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct())
     jitter.func_ret_stdcall(ret_ad, h)
 
 
 def kernel32_FindNextFileA(jitter):
-    ret_ad, args = jitter.func_args_stdcall(2)
-    handle, pfindfiledata = args
+    ret_ad, args = jitter.func_args_stdcall(["handle", "pfindfiledata"])
 
-    fname = winobjs.find_data.findnext(handle)
+    fname = winobjs.find_data.findnext(args.handle)
     if fname is None:
         ret = 0
     else:
         ret = 1
         fdata = win32_find_data(cfilename=fname)
-        jitter.vm.set_mem(pfindfiledata, fdata.toStruct())
+        jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct())
 
     jitter.func_ret_stdcall(ret_ad, ret)
 
 
 def kernel32_GetNativeSystemInfo(jitter):
-    ret_ad, args = jitter.func_args_stdcall(1)
-    sys_ptr, = args
+    ret_ad, args = jitter.func_args_stdcall(["sys_ptr"])
     sysinfo = systeminfo()
-    jitter.vm.set_mem(sys_ptr, sysinfo.pack())
+    jitter.vm.set_mem(args.sys_ptr, sysinfo.pack())
     jitter.func_ret_stdcall(ret_ad, 0)
 
 
@@ -2887,24 +2704,21 @@ def int2base(x, base):
 
 
 def msvcrt__ultow(jitter):
-    ret_ad, args = jitter.func_args_cdecl(3)
-    value, p, radix = args
+    ret_ad, args = jitter.func_args_cdecl(["value", "p", "radix"])
 
-    value &= 0xFFFFFFFF
-    if not radix in [10, 16, 20]:
-        TODO_TEST
-    s = int2base(value, radix)
-    jitter.vm.set_mem(p, set_str_unic(s + "\x00"))
-    jitter.func_ret_cdecl(ret_ad, p)
+    value = args.value & 0xFFFFFFFF
+    if not args.radix in [10, 16, 20]:
+        raise ValueError("Not tested")
+    s = int2base(value, args.radix)
+    jitter.vm.set_mem(args.p, set_str_unic(s + "\x00"))
+    jitter.func_ret_cdecl(ret_ad, args.p)
 
 
 def msvcrt_myfopen(jitter, func):
-    ret_ad, args = jitter.func_args_cdecl(2)
-    pfname, pmode = args
-
+    ret_ad, args = jitter.func_args_cdecl(["pfname", "pmode"])
 
-    fname = func(jitter, pfname)
-    rw = func(jitter, pmode)
+    fname = func(jitter, args.pfname)
+    rw = func(jitter, args.pmode)
     log.debug(fname)
     log.debug(rw)
 
@@ -2915,7 +2729,8 @@ def msvcrt_myfopen(jitter, func):
         eax = winobjs.handle_pool.add(f, h)
         dwsize = 0x20
         alloc_addr = winobjs.heap.alloc(jitter, dwsize)
-        pp = pck32(0x11112222)+pck32(0)+pck32(0)+pck32(0)+pck32(eax)#pdw(0x11112222)
+        pp = pck32(0x11112222) + pck32(0) + pck32(0) + pck32(0) + pck32(eax)
+        #pdw(0x11112222)
         jitter.vm.set_mem(alloc_addr, pp)
 
 
@@ -2932,8 +2747,7 @@ def msvcrt_fopen(jitter):
 
 
 def msvcrt_strlen(jitter):
-    ret_ad, args = jitter.func_args_cdecl(1)
-    src, = args
+    ret_ad, args = jitter.func_args_cdecl(["src"])
 
-    s = get_str_ansi(jitter, src)
+    s = get_str_ansi(jitter, args.src)
     jitter.func_ret_cdecl(ret_ad, len(s))