diff options
Diffstat (limited to 'miasm/os_dep/win_api_x86_32.py')
| -rw-r--r-- | miasm/os_dep/win_api_x86_32.py | 3595 |
1 files changed, 0 insertions, 3595 deletions
diff --git a/miasm/os_dep/win_api_x86_32.py b/miasm/os_dep/win_api_x86_32.py deleted file mode 100644 index 6e568abb..00000000 --- a/miasm/os_dep/win_api_x86_32.py +++ /dev/null @@ -1,3595 +0,0 @@ -from __future__ import print_function -# -# Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License along -# with this program; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -# -from past.builtins import cmp -import struct -import os -import stat -import time -import string -import logging -from zlib import crc32 -from io import StringIO -import time -import datetime - -from future.utils import PY3, viewitems, viewvalues - -try: - from Crypto.Hash import MD5, SHA -except ImportError: - print("cannot find crypto, skipping") - -from miasm.jitter.csts import PAGE_READ, PAGE_WRITE, PAGE_EXEC -from miasm.core.utils import pck16, pck32, hexdump, whoami, int_to_byte -from miasm.os_dep.common import heap, windows_to_sbpath -from miasm.os_dep.common import set_win_str_w, set_win_str_a -from miasm.os_dep.common import get_fmt_args as _get_fmt_args -from miasm.os_dep.common import get_win_str_a, get_win_str_w -from miasm.os_dep.common import encode_win_str_a, encode_win_str_w -from miasm.os_dep.win_api_x86_32_seh import tib_address - -log = logging.getLogger("win_api_x86_32") -console_handler = logging.StreamHandler() -console_handler.setFormatter(logging.Formatter("[%(levelname)-8s]: %(message)s")) -log.addHandler(console_handler) -log.setLevel(logging.WARN) - -DATE_1601_TO_1970 = 116444736000000000 - -MAX_PATH = 260 - - -""" -typedef struct tagPROCESSENTRY32 { - DWORD dwSize; - DWORD cntUsage; - DWORD th32ProcessID; - ULONG_PTR th32DefaultHeapID; - DWORD th32ModuleID; - DWORD cntThreads; - DWORD th32ParentProcessID; - LONG pcPriClassBase; - DWORD dwFlags; - TCHAR szExeFile[MAX_PATH]; -} PROCESSENTRY32, *PPROCESSENTRY32; -""" - - -ACCESS_DICT = {0x0: 0, - 0x1: 0, - 0x2: PAGE_READ, - 0x4: PAGE_READ | PAGE_WRITE, - 0x10: PAGE_EXEC, - 0x20: PAGE_EXEC | PAGE_READ, - 0x40: PAGE_EXEC | PAGE_READ | PAGE_WRITE, - 0x80: PAGE_EXEC | PAGE_READ | PAGE_WRITE, - # 0x80: PAGE_EXECUTE_WRITECOPY - 0x100: 0 - } - -ACCESS_DICT_INV = dict((x[1], x[0]) for x in viewitems(ACCESS_DICT)) - - -class whandle(object): - - def __init__(self, name, info): - self.name = name - self.info = info - - def __repr__(self): - return '<%r %r %r>' % (self.__class__.__name__, self.name, self.info) - - -class handle_generator(object): - - def __init__(self): - self.offset = 600 - self.all_handles = {} - - def add(self, name, info=None): - self.offset += 1 - h = whandle(name, info) - self.all_handles[self.offset] = h - - log.debug(repr(self)) - return self.offset - - def __repr__(self): - out = '<%r\n' % self.__class__.__name__ - ks = list(self.all_handles) - ks.sort() - - for k in ks: - out += " %r %r\n" % (k, self.all_handles[k]) - out += '>' - return out - - def __contains__(self, e): - return e in self.all_handles - - def __getitem__(self, item): - return self.all_handles.__getitem__(item) - - def __delitem__(self, item): - self.all_handles.__delitem__(item) - - -class c_winobjs(object): - - def __init__(self): - self.alloc_ad = 0x20000000 - self.alloc_align = 0x1000 - self.heap = heap() - self.handle_toolhelpsnapshot = 0xaaaa00 - self.toolhelpsnapshot_info = {} - self.handle_curprocess = 0xaaaa01 - self.dbg_present = 0 - self.tickcount = 0 - self.dw_pid_dummy1 = 0x111 - self.dw_pid_explorer = 0x222 - self.dw_pid_dummy2 = 0x333 - self.dw_pid_cur = 0x444 - self.module_fname_nux = None - self.module_name = "test.exe" - self.module_path = "c:\\mydir\\" + self.module_name - self.hcurmodule = None - self.module_filesize = None - self.getversion = 0x0A280105 - self.getforegroundwindow = 0x333333 - self.cryptcontext_hwnd = 0x44400 - self.cryptcontext_bnum = 0x44000 - self.cryptcontext_num = 0 - self.cryptcontext = {} - self.phhash_crypt_md5 = 0x55555 - # key used by EncodePointer and DecodePointer - # (kernel32) - self.ptr_encode_key = 0xabababab - self.files_hwnd = {} - self.windowlong_dw = 0x77700 - self.module_cur_hwnd = 0x88800 - self.module_file_nul = 0x999000 - self.runtime_dll = None - self.current_pe = None - self.tls_index = 0xf - self.tls_values = {} - self.handle_pool = handle_generator() - self.handle_mapped = {} - self.hkey_handles = { - 0x80000001: b"hkey_current_user", - 0x80000002: b"hkey_local_machine" - } - self.cur_dir = "c:\\tmp" - - self.nt_mdl = {} - self.nt_mdl_ad = None - self.nt_mdl_cur = 0 - self.win_event_num = 0x13370 - self.cryptdll_md5_h = {} - - self.lastwin32error = 0 - self.mutex = {} - self.env_variables = {} - self.events_pool = {} - self.find_data = None - - self.allocated_pages = {} - self.current_datetime = datetime.datetime( - year=2017, month=8, day=21, - hour=13, minute=37, - second=11, microsecond=123456 - ) - -winobjs = c_winobjs() - - -process_list = [ - [ - 0x40, # DWORD dwSize; - 0, # DWORD cntUsage; - winobjs.dw_pid_dummy1, # DWORD th32ProcessID; - 0x11111111, # ULONG_PTR th32DefaultHeapID; - 0x11111112, # DWORD th32ModuleID; - 1, # DWORD cntThreads; - winobjs.dw_pid_explorer, # DWORD th32ParentProcessID; - 0xbeef, # LONG pcPriClassBase; - 0x0, # DWORD dwFlags; - "dummy1.exe" # TCHAR szExeFile[MAX_PATH]; - ], - [ - 0x40, # DWORD dwSize; - 0, # DWORD cntUsage; - winobjs.dw_pid_explorer, # DWORD th32ProcessID; - 0x11111111, # ULONG_PTR th32DefaultHeapID; - 0x11111112, # DWORD th32ModuleID; - 1, # DWORD cntThreads; - 4, # DWORD th32ParentProcessID; - 0xbeef, # LONG pcPriClassBase; - 0x0, # DWORD dwFlags; - "explorer.exe" # TCHAR szExeFile[MAX_PATH]; - ], - - [ - 0x40, # DWORD dwSize; - 0, # DWORD cntUsage; - winobjs.dw_pid_dummy2, # DWORD th32ProcessID; - 0x11111111, # ULONG_PTR th32DefaultHeapID; - 0x11111112, # DWORD th32ModuleID; - 1, # DWORD cntThreads; - winobjs.dw_pid_explorer, # DWORD th32ParentProcessID; - 0xbeef, # LONG pcPriClassBase; - 0x0, # DWORD dwFlags; - "dummy2.exe" # TCHAR szExeFile[MAX_PATH]; - ], - - [ - 0x40, # DWORD dwSize; - 0, # DWORD cntUsage; - winobjs.dw_pid_cur, # DWORD th32ProcessID; - 0x11111111, # ULONG_PTR th32DefaultHeapID; - 0x11111112, # DWORD th32ModuleID; - 1, # DWORD cntThreads; - winobjs.dw_pid_explorer, # DWORD th32ParentProcessID; - 0xbeef, # LONG pcPriClassBase; - 0x0, # DWORD dwFlags; - winobjs.module_name # TCHAR szExeFile[MAX_PATH]; - ], - - -] - - -class hobj(object): - pass - - -class mdl(object): - - def __init__(self, ad, l): - self.ad = ad - self.l = l - - def __bytes__(self): - return struct.pack('LL', self.ad, self.l) - - def __str__(self): - if PY3: - return repr(self) - return self.__bytes__() - - -def kernel32_HeapAlloc(jitter): - ret_ad, args = jitter.func_args_stdcall(["heap", "flags", "size"]) - alloc_addr = winobjs.heap.alloc(jitter, args.size, cmt=hex(ret_ad)) - jitter.func_ret_stdcall(ret_ad, alloc_addr) - - -def kernel32_HeapFree(jitter): - ret_ad, _ = jitter.func_args_stdcall(["heap", "flags", "pmem"]) - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_GlobalAlloc(jitter): - ret_ad, args = jitter.func_args_stdcall(["uflags", "msize"]) - alloc_addr = winobjs.heap.alloc(jitter, args.msize) - jitter.func_ret_stdcall(ret_ad, alloc_addr) - - -def kernel32_LocalFree(jitter): - ret_ad, _ = jitter.func_args_stdcall(["lpvoid"]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_LocalAlloc(jitter): - ret_ad, args = jitter.func_args_stdcall(["uflags", "msize"]) - alloc_addr = winobjs.heap.alloc(jitter, args.msize) - jitter.func_ret_stdcall(ret_ad, alloc_addr) - -def msvcrt_new(jitter): - ret_ad, args = jitter.func_args_cdecl(["size"]) - alloc_addr = winobjs.heap.alloc(jitter, args.size) - jitter.func_ret_cdecl(ret_ad, alloc_addr) - -globals()['msvcrt_??2@YAPAXI@Z'] = msvcrt_new - -def msvcrt_delete(jitter): - ret_ad, args = jitter.func_args_cdecl(["ptr"]) - jitter.func_ret_cdecl(ret_ad, 0) - -globals()['msvcrt_??3@YAXPAX@Z'] = msvcrt_delete - -def kernel32_GlobalFree(jitter): - ret_ad, _ = jitter.func_args_stdcall(["addr"]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_IsDebuggerPresent(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, winobjs.dbg_present) - - -def kernel32_CreateToolhelp32Snapshot(jitter): - ret_ad, _ = jitter.func_args_stdcall(["dwflags", "th32processid"]) - jitter.func_ret_stdcall(ret_ad, winobjs.handle_toolhelpsnapshot) - - -def kernel32_GetCurrentProcess(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, winobjs.handle_curprocess) - - -def kernel32_GetCurrentProcessId(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, winobjs.dw_pid_cur) - - -def kernel32_Process32First(jitter): - ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"]) - - pentry = struct.pack( - 'IIIIIIIII', *process_list[0][:-1] - ) + (process_list[0][-1] + '\x00').encode('utf8') - jitter.vm.set_mem(args.ad_pentry, pentry) - winobjs.toolhelpsnapshot_info[args.s_handle] = 0 - - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_Process32Next(jitter): - ret_ad, args = jitter.func_args_stdcall(["s_handle", "ad_pentry"]) - - winobjs.toolhelpsnapshot_info[args.s_handle] += 1 - if winobjs.toolhelpsnapshot_info[args.s_handle] >= len(process_list): - ret = 0 - else: - ret = 1 - n = winobjs.toolhelpsnapshot_info[args.s_handle] - pentry = struct.pack( - 'IIIIIIIII', *process_list[n][:-1]) + (process_list[n][-1]+ '\x00').encode('utf8') - jitter.vm.set_mem(args.ad_pentry, pentry) - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_GetTickCount(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - winobjs.tickcount += 1 - jitter.func_ret_stdcall(ret_ad, winobjs.tickcount) - - -def kernel32_GetVersion(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, winobjs.getversion) - - -def kernel32_GetVersionEx(jitter, str_size, encode_str): - ret_ad, args = jitter.func_args_stdcall(["ptr_struct"]) - - size = jitter.vm.get_u32(args.ptr_struct) - if size in [0x14+str_size, 0x1c+str_size]: - tmp = struct.pack( - "IIIII%dsHHHBB" % str_size, - 0x114, # struct size - 0x5, # maj vers - 0x2, # min vers - 0xa28, # build nbr - 0x2, # platform id - encode_str("Service pack 4"), - 3, # wServicePackMajor - 0, # wServicePackMinor - 0x100, # wSuiteMask - 1, # wProductType - 0 # wReserved - ) - tmp = tmp[:size] - jitter.vm.set_mem(args.ptr_struct, tmp) - ret = 1 - else: - ret = 0 - jitter.func_ret_stdcall(ret_ad, ret) - - -kernel32_GetVersionExA = lambda jitter: kernel32_GetVersionEx(jitter, 128, - encode_win_str_a) -kernel32_GetVersionExW = lambda jitter: kernel32_GetVersionEx(jitter, 256, - encode_win_str_w) - - -def kernel32_GetPriorityClass(jitter): - ret_ad, _ = jitter.func_args_stdcall(["hwnd"]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_SetPriorityClass(jitter): - ret_ad, _ = jitter.func_args_stdcall(["hwnd", "dwpclass"]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_CloseHandle(jitter): - ret_ad, _ = jitter.func_args_stdcall(["hwnd"]) - jitter.func_ret_stdcall(ret_ad, 1) - -def kernel32_EncodePointer(jitter): - """ - PVOID EncodePointer( - _In_ PVOID Ptr - ); - - Encoding globally available pointers helps protect them from being - exploited. The EncodePointer function obfuscates the pointer value - with a secret so that it cannot be predicted by an external agent. - The secret used by EncodePointer is different for each process. - - A pointer must be decoded before it can be used. - - """ - ret, args = jitter.func_args_stdcall(1) - jitter.func_ret_stdcall(ret, args[0] ^ winobjs.ptr_encode_key) - return True - -def kernel32_DecodePointer(jitter): - """ - PVOID DecodePointer( - PVOID Ptr - ); - - The function returns the decoded pointer. - - """ - ret, args = jitter.func_args_stdcall(1) - jitter.func_ret_stdcall(ret, args[0] ^ winobjs.ptr_encode_key) - return True - -def user32_GetForegroundWindow(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, winobjs.getforegroundwindow) - - -def user32_FindWindowA(jitter): - ret_ad, args = jitter.func_args_stdcall(["pclassname", "pwindowname"]) - if args.pclassname: - classname = get_win_str_a(jitter, args.pclassname) - log.info("FindWindowA classname %s", classname) - if args.pwindowname: - windowname = get_win_str_a(jitter, args.pwindowname) - log.info("FindWindowA windowname %s", windowname) - jitter.func_ret_stdcall(ret_ad, 0) - - -def user32_GetTopWindow(jitter): - ret_ad, _ = jitter.func_args_stdcall(["hwnd"]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def user32_BlockInput(jitter): - ret_ad, _ = jitter.func_args_stdcall(["blockit"]) - jitter.func_ret_stdcall(ret_ad, 1) - - -def advapi32_CryptAcquireContext(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["phprov", "pszcontainer", - "pszprovider", "dwprovtype", - "dwflags"]) - prov = get_str(args.pszprovider) if args.pszprovider else "NONE" - log.debug('prov: %r', prov) - jitter.vm.set_u32(args.phprov, winobjs.cryptcontext_hwnd) - jitter.func_ret_stdcall(ret_ad, 1) - - -def advapi32_CryptAcquireContextA(jitter): - advapi32_CryptAcquireContext(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def advapi32_CryptAcquireContextW(jitter): - advapi32_CryptAcquireContext(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def advapi32_CryptCreateHash(jitter): - ret_ad, args = jitter.func_args_stdcall(["hprov", "algid", "hkey", - "dwflags", "phhash"]) - - winobjs.cryptcontext_num += 1 - - if args.algid == 0x00008003: - log.debug('algo is MD5') - jitter.vm.set_u32( - args.phhash, - winobjs.cryptcontext_bnum + winobjs.cryptcontext_num - ) - winobjs.cryptcontext[ - winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj() - winobjs.cryptcontext[ - winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = MD5.new() - elif args.algid == 0x00008004: - log.debug('algo is SHA1') - jitter.vm.set_u32( - args.phhash, - winobjs.cryptcontext_bnum + winobjs.cryptcontext_num - ) - winobjs.cryptcontext[ - winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj() - winobjs.cryptcontext[ - winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = SHA.new() - else: - raise ValueError('un impl algo1') - jitter.func_ret_stdcall(ret_ad, 1) - - -def advapi32_CryptHashData(jitter): - ret_ad, args = jitter.func_args_stdcall(["hhash", "pbdata", "dwdatalen", - "dwflags"]) - - if not args.hhash in winobjs.cryptcontext: - raise ValueError("unknown crypt context") - - data = jitter.vm.get_mem(args.pbdata, args.dwdatalen) - log.debug('will hash %X', args.dwdatalen) - log.debug(repr(data[:0x10]) + "...") - winobjs.cryptcontext[args.hhash].h.update(data) - jitter.func_ret_stdcall(ret_ad, 1) - - -def advapi32_CryptGetHashParam(jitter): - ret_ad, args = jitter.func_args_stdcall(["hhash", "param", "pbdata", - "dwdatalen", "dwflags"]) - - if not args.hhash in winobjs.cryptcontext: - raise ValueError("unknown crypt context") - - if args.param == 2: - # HP_HASHVAL - # XXX todo: save h state? - h = winobjs.cryptcontext[args.hhash].h.digest() - jitter.vm.set_mem(args.pbdata, h) - jitter.vm.set_u32(args.dwdatalen, len(h)) - elif args.param == 4: - # HP_HASHSIZE - ret = winobjs.cryptcontext[args.hhash].h.digest_size - jitter.vm.set_u32(args.pbdata, ret) - jitter.vm.set_u32(args.dwdatalen, 4) - else: - raise ValueError('not impl', args.param) - - jitter.func_ret_stdcall(ret_ad, 1) - - -def advapi32_CryptReleaseContext(jitter): - ret_ad, _ = jitter.func_args_stdcall(["hhash", "flags"]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def advapi32_CryptDeriveKey(jitter): - ret_ad, args = jitter.func_args_stdcall(["hprov", "algid", "hbasedata", - "dwflags", "phkey"]) - - if args.algid == 0x6801: - log.debug('using DES') - else: - raise ValueError('un impl algo2') - h = winobjs.cryptcontext[args.hbasedata].h.digest() - log.debug('hash %r', h) - winobjs.cryptcontext[args.hbasedata].h_result = h - jitter.vm.set_u32(args.phkey, args.hbasedata) - jitter.func_ret_stdcall(ret_ad, 1) - - -def advapi32_CryptDestroyHash(jitter): - ret_ad, _ = jitter.func_args_stdcall(["hhash"]) - jitter.func_ret_stdcall(ret_ad, 1) - - -def advapi32_CryptDecrypt(jitter): - # ret_ad, _ = jitter.func_args_stdcall(["hkey", "hhash", "final", - # "dwflags", "pbdata", - # "pdwdatalen"]) - raise ValueError("Not implemented") - # jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_CreateFile(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["lpfilename", "access", - "dwsharedmode", - "lpsecurityattr", - "dwcreationdisposition", - "dwflagsandattr", - "htemplatefile"]) - if args.lpfilename == 0: - jitter.func_ret_stdcall(ret_ad, 0xffffffff) - return - - fname = get_str(args.lpfilename) - log.info('CreateFile fname %s', fname) - ret = 0xffffffff - - log.debug("%r %r", fname.lower(), winobjs.module_path.lower()) - is_original_file = fname.lower() == winobjs.module_path.lower() - - if fname.upper() in [r"\\.\SICE", r"\\.\NTICE", r"\\.\SIWVID", r'\\.\SIWDEBUG']: - pass - elif fname.upper() in ['NUL']: - ret = winobjs.module_cur_hwnd - else: - # sandbox path - sb_fname = windows_to_sbpath(fname) - if args.access & 0x80000000 or args.access == 1: - # read and maybe write - if args.dwcreationdisposition == 2: - # create_always - if os.access(sb_fname, os.R_OK): - # but file exist - pass - else: - raise NotImplementedError("Untested case") # to test - # h = open(sb_fname, 'rb+') - elif args.dwcreationdisposition == 3: - # open_existing - if os.access(sb_fname, os.R_OK): - s = os.stat(sb_fname) - if stat.S_ISDIR(s.st_mode): - ret = winobjs.handle_pool.add(sb_fname, 0x1337) - else: - open_mode = 'rb' - if (args.access & 0x40000000) or args.access == 2: - open_mode = 'r+b' - h = open(sb_fname, open_mode) - ret = winobjs.handle_pool.add(sb_fname, h) - else: - log.warning("FILE %r (%s) DOES NOT EXIST!", fname, sb_fname) - elif args.dwcreationdisposition == 1: - # create new - if os.access(sb_fname, os.R_OK): - # file exist - # ret = 80 - winobjs.lastwin32error = 80 - else: - # first create an empty file - open(sb_fname, 'wb').close() - # then open - h = open(sb_fname, 'r+b') - ret = winobjs.handle_pool.add(sb_fname, h) - elif args.dwcreationdisposition == 4: - # open_always - if os.access(sb_fname, os.R_OK): - s = os.stat(sb_fname) - if stat.S_ISDIR(s.st_mode): - ret = winobjs.handle_pool.add(sb_fname, 0x1337) - else: - h = open(sb_fname, 'r+b') - ret = winobjs.handle_pool.add(sb_fname, h) - else: - raise NotImplementedError("Untested case") - else: - raise NotImplementedError("Untested case") - elif (args.access & 0x40000000) or args.access == 2: - # write but not read - if args.dwcreationdisposition == 3: - # open existing - if is_original_file: - # cannot open self in write mode! - pass - elif os.access(sb_fname, os.R_OK): - s = os.stat(sb_fname) - if stat.S_ISDIR(s.st_mode): - # open dir - ret = winobjs.handle_pool.add(sb_fname, 0x1337) - else: - h = open(sb_fname, 'wb') - ret = winobjs.handle_pool.add(sb_fname, h) - else: - raise NotImplementedError("Untested case") # to test - elif args.dwcreationdisposition == 5: - # truncate_existing - if is_original_file: - pass - else: - raise NotImplementedError("Untested case") # to test - else: - # raise NotImplementedError("Untested case") # to test - h = open(sb_fname, 'wb') - ret = winobjs.handle_pool.add(sb_fname, h) - else: - raise NotImplementedError("Untested case") - - # h = open(sb_fname, 'rb+') - # ret = winobjs.handle_pool.add(sb_fname, h) - log.debug('CreateFile ret %x', ret) - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_CreateFileA(jitter): - kernel32_CreateFile(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def kernel32_CreateFileW(jitter): - kernel32_CreateFile(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def kernel32_ReadFile(jitter): - ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpbuffer", - "nnumberofbytestoread", - "lpnumberofbytesread", - "lpoverlapped"]) - if args.hwnd == winobjs.module_cur_hwnd: - pass - elif args.hwnd in winobjs.handle_pool: - pass - else: - raise ValueError('unknown hwnd!') - - data = None - if args.hwnd in winobjs.files_hwnd: - data = winobjs.files_hwnd[ - winobjs.module_cur_hwnd].read(args.nnumberofbytestoread) - elif args.hwnd in winobjs.handle_pool: - wh = winobjs.handle_pool[args.hwnd] - data = wh.info.read(args.nnumberofbytestoread) - else: - raise ValueError('unknown filename') - - if data is not None: - if (args.lpnumberofbytesread): - jitter.vm.set_u32(args.lpnumberofbytesread, len(data)) - jitter.vm.set_mem(args.lpbuffer, data) - - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_GetFileSize(jitter): - ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"]) - - if args.hwnd == winobjs.module_cur_hwnd: - ret = len(open(winobjs.module_fname_nux, "rb").read()) - elif args.hwnd in winobjs.handle_pool: - wh = winobjs.handle_pool[args.hwnd] - ret = len(open(wh.name, "rb").read()) - else: - raise ValueError('unknown hwnd!') - - if args.lpfilesizehight != 0: - jitter.vm.set_u32(args.lpfilesizehight, ret) - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_GetFileSizeEx(jitter): - ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"]) - - if args.hwnd == winobjs.module_cur_hwnd: - l = len(open(winobjs.module_fname_nux, "rb").read()) - elif args.hwnd in winobjs.handle_pool: - wh = winobjs.handle_pool[args.hwnd] - l = len(open(wh.name, "rb").read()) - else: - raise ValueError('unknown hwnd!') - - if args.lpfilesizehight == 0: - raise NotImplementedError("Untested case") - jitter.vm.set_mem(args.lpfilesizehight, pck32( - l & 0xffffffff) + pck32((l >> 32) & 0xffffffff)) - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_FlushInstructionCache(jitter): - ret_ad, _ = jitter.func_args_stdcall(["hprocess", "lpbasead", "dwsize"]) - jitter.func_ret_stdcall(ret_ad, 0x1337) - - -def kernel32_VirtualProtect(jitter): - ret_ad, args = jitter.func_args_stdcall(['lpvoid', 'dwsize', - 'flnewprotect', - 'lpfloldprotect']) - # XXX mask hpart - flnewprotect = args.flnewprotect & 0xFFF - if not flnewprotect in ACCESS_DICT: - raise ValueError('unknown access dw!') - - if args.lpfloldprotect: - old = jitter.vm.get_mem_access(args.lpvoid) - jitter.vm.set_u32(args.lpfloldprotect, ACCESS_DICT_INV[old]) - - paddr = args.lpvoid - (args.lpvoid % winobjs.alloc_align) - paddr_max = (args.lpvoid + args.dwsize + winobjs.alloc_align - 1) - paddr_max_round = paddr_max - (paddr_max % winobjs.alloc_align) - psize = paddr_max_round - paddr - for addr, items in list(winobjs.allocated_pages.items()): - alloc_addr, alloc_size = items - if (paddr + psize <= alloc_addr or - paddr > alloc_addr + alloc_size): - continue - size = jitter.vm.get_all_memory()[addr]["size"] - # Page is included in Protect area - if (paddr <= addr < addr + size <= paddr + psize): - log.warn("set page %x %x", addr, ACCESS_DICT[flnewprotect]) - jitter.vm.set_mem_access(addr, ACCESS_DICT[flnewprotect]) - continue - - # Page is partly in Protect area: splitting is needed - if (addr <= paddr < addr + size or - addr <= paddr + psize < addr + size): - - old_access = jitter.vm.get_mem_access(addr) - - # splits = [ - # addr -> max(paddr, addr) - # max(paddr, addr) -> min(addr + size, paddr + psize) - # min(addr + size, paddr + psize) -> addr + size - # ] - splits = [ - (addr, old_access, - jitter.vm.get_mem(addr, max(paddr, addr) - addr)), - (max(paddr, addr), ACCESS_DICT[flnewprotect], - jitter.vm.get_mem( - max(paddr, addr), - min(addr + size, paddr + psize) - max(paddr, addr))), - (min(addr + size, paddr + psize), old_access, - jitter.vm.get_mem( - min(addr + size, paddr + psize), - addr + size - min(addr + size, paddr + psize))) - ] - - jitter.vm.remove_memory_page(addr) - for split_addr, split_access, split_data in splits: - if not split_data: - continue - log.warn("create page %x %x", split_addr, - ACCESS_DICT[flnewprotect]) - jitter.vm.add_memory_page( - split_addr, split_access, split_data, - "VirtualProtect split ret 0x%X" % ret_ad) - winobjs.allocated_pages[split_addr] = (alloc_addr, alloc_size) - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_VirtualAlloc(jitter): - ret_ad, args = jitter.func_args_stdcall(['lpvoid', 'dwsize', - 'alloc_type', 'flprotect']) - - - if not args.flprotect in ACCESS_DICT: - raise ValueError('unknown access dw!') - - if args.lpvoid == 0: - alloc_addr = winobjs.heap.next_addr(args.dwsize) - winobjs.allocated_pages[alloc_addr] = (alloc_addr, args.dwsize) - jitter.vm.add_memory_page( - alloc_addr, ACCESS_DICT[args.flprotect], b"\x00" * args.dwsize, - "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) - else: - all_mem = jitter.vm.get_all_memory() - if args.lpvoid in all_mem: - alloc_addr = args.lpvoid - jitter.vm.set_mem_access(args.lpvoid, ACCESS_DICT[args.flprotect]) - else: - alloc_addr = winobjs.heap.next_addr(args.dwsize) - winobjs.allocated_pages[alloc_addr] = (alloc_addr, args.dwsize) - # alloc_addr = args.lpvoid - jitter.vm.add_memory_page( - alloc_addr, ACCESS_DICT[args.flprotect], b"\x00" * args.dwsize, - "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) - - log.info('VirtualAlloc addr: 0x%x', alloc_addr) - jitter.func_ret_stdcall(ret_ad, alloc_addr) - - -def kernel32_VirtualFree(jitter): - ret_ad, _ = jitter.func_args_stdcall(["lpvoid", "dwsize", "alloc_type"]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def user32_GetWindowLongA(jitter): - ret_ad, _ = jitter.func_args_stdcall(["hwnd", "nindex"]) - jitter.func_ret_stdcall(ret_ad, winobjs.windowlong_dw) - - -def user32_SetWindowLongA(jitter): - ret_ad, _ = jitter.func_args_stdcall(["hwnd", "nindex", "newlong"]) - jitter.func_ret_stdcall(ret_ad, winobjs.windowlong_dw) - - -def kernel32_GetModuleFileName(jitter, funcname, set_str): - ret_ad, args = jitter.func_args_stdcall(["hmodule", "lpfilename", "nsize"]) - - if args.hmodule in [0, winobjs.hcurmodule]: - p = winobjs.module_path[:] - elif (winobjs.runtime_dll and - args.hmodule in viewvalues(winobjs.runtime_dll.name2off)): - name_inv = dict( - [ - (x[1], x[0]) - for x in viewitems(winobjs.runtime_dll.name2off) - ] - ) - p = name_inv[args.hmodule] - else: - log.warning(('Unknown module 0x%x.' + - 'Set winobjs.hcurmodule and retry'), args.hmodule) - p = None - - if p is None: - l = 0 - elif args.nsize < len(p): - p = p[:args.nsize] - l = len(p) - else: - l = len(p) - - if p: - set_str(args.lpfilename, p) - - jitter.func_ret_stdcall(ret_ad, l) - - -def kernel32_GetModuleFileNameA(jitter): - kernel32_GetModuleFileName(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value)) - - -def kernel32_GetModuleFileNameW(jitter): - kernel32_GetModuleFileName(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value)) - - -def kernel32_CreateMutex(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["mutexattr", "initowner", - "lpname"]) - - if args.lpname: - name = get_str(args.lpname) - log.info("CreateMutex %r", name) - else: - name = None - if args.initowner: - if name in winobjs.mutex: - raise NotImplementedError("Untested case") - # ret = 0 - else: - winobjs.mutex[name] = id(name) & 0xFFFFFFFF - ret = winobjs.mutex[name] - else: - if name in winobjs.mutex: - raise NotImplementedError("Untested case") - # ret = 0 - else: - winobjs.mutex[name] = id(name) & 0xFFFFFFFF - ret = winobjs.mutex[name] - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_CreateMutexA(jitter): - kernel32_CreateMutex(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def kernel32_CreateMutexW(jitter): - kernel32_CreateMutex(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def shell32_SHGetSpecialFolderLocation(jitter): - ret_ad, args = jitter.func_args_stdcall(["hwndowner", "nfolder", "ppidl"]) - jitter.vm.set_u32(args.ppidl, args.nfolder) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_SHGetPathFromIDList(jitter, funcname, set_str): - ret_ad, args = jitter.func_args_stdcall(["pidl", "ppath"]) - - if args.pidl == 7: # CSIDL_STARTUP: - s = "c:\\doc\\user\\startmenu\\programs\\startup" - set_str(args.ppath, s) - else: - raise ValueError('pidl not implemented', args.pidl) - jitter.func_ret_stdcall(ret_ad, 1) - - -def shell32_SHGetPathFromIDListW(jitter): - kernel32_SHGetPathFromIDList(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value)) - - -def shell32_SHGetPathFromIDListA(jitter): - kernel32_SHGetPathFromIDList(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value)) - - -def kernel32_GetLastError(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, winobjs.lastwin32error) - - -def kernel32_SetLastError(jitter): - ret_ad, args = jitter.func_args_stdcall(["errcode"]) - # lasterr addr - # ad = tib_address + 0x34 - # jitter.vm.set_mem(ad, pck32(args.errcode)) - winobjs.lastwin32error = args.errcode - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_RestoreLastError(jitter): - kernel32_SetLastError(jitter) - - -def kernel32_LoadLibrary(jitter, get_str): - ret_ad, args = jitter.func_args_stdcall(["dllname"]) - - libname = get_str(args.dllname, 0x100) - ret = winobjs.runtime_dll.lib_get_add_base(libname) - log.info("Loading %r ret 0x%x", libname, ret) - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_LoadLibraryA(jitter): - kernel32_LoadLibrary(jitter, lambda addr, max_char=None:get_win_str_a(jitter, addr, max_char)) - - -def kernel32_LoadLibraryW(jitter): - kernel32_LoadLibrary(jitter, lambda addr, max_char=None:get_win_str_w(jitter, addr, max_char)) - - -def kernel32_LoadLibraryEx(jitter, get_str): - ret_ad, args = jitter.func_args_stdcall(["dllname", "hfile", "flags"]) - - if args.hfile != 0: - raise NotImplementedError("Untested case") - libname = get_str(args.dllname, 0x100) - ret = winobjs.runtime_dll.lib_get_add_base(libname) - log.info("Loading %r ret 0x%x", libname, ret) - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_LoadLibraryExA(jitter): - kernel32_LoadLibraryEx(jitter, lambda addr, max_char=None:get_win_str_a(jitter, addr, max_char)) - - -def kernel32_LoadLibraryExW(jitter): - kernel32_LoadLibraryEx(jitter, lambda addr, max_char=None:get_win_str_w(jitter, addr, max_char)) - - -def kernel32_GetProcAddress(jitter): - ret_ad, args = jitter.func_args_stdcall(["libbase", "fname"]) - fname = args.fname - if fname >= 0x10000: - fname = jitter.get_c_str(fname, 0x100) - if not fname: - fname = None - if fname is not None: - ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname) - else: - ad = 0 - log.info("GetProcAddress %r %r ret 0x%x", args.libbase, fname, ad) - jitter.add_breakpoint(ad, jitter.handle_lib) - jitter.func_ret_stdcall(ret_ad, ad) - - -def kernel32_GetModuleHandle(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["dllname"]) - - if args.dllname: - libname = get_str(args.dllname) - if libname: - ret = winobjs.runtime_dll.lib_get_add_base(libname) - else: - log.warning('unknown module!') - ret = 0 - log.info("GetModuleHandle %r ret 0x%x", libname, ret) - else: - ret = winobjs.current_pe.NThdr.ImageBase - log.info("GetModuleHandle default ret 0x%x", ret) - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_GetModuleHandleA(jitter): - kernel32_GetModuleHandle(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def kernel32_GetModuleHandleW(jitter): - kernel32_GetModuleHandle(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def kernel32_VirtualLock(jitter): - ret_ad, _ = jitter.func_args_stdcall(["lpaddress", "dwsize"]) - jitter.func_ret_stdcall(ret_ad, 1) - - -class systeminfo(object): - oemId = 0 - dwPageSize = 0x1000 - lpMinimumApplicationAddress = 0x10000 - lpMaximumApplicationAddress = 0x7ffeffff - dwActiveProcessorMask = 0x1 - numberOfProcessors = 0x1 - ProcessorsType = 586 - dwAllocationgranularity = 0x10000 - wProcessorLevel = 0x6 - ProcessorRevision = 0xf0b - - def pack(self): - return struct.pack('IIIIIIIIHH', - self.oemId, - self.dwPageSize, - self.lpMinimumApplicationAddress, - self.lpMaximumApplicationAddress, - self.dwActiveProcessorMask, - self.numberOfProcessors, - self.ProcessorsType, - self.dwAllocationgranularity, - self.wProcessorLevel, - self.ProcessorRevision) - - -def kernel32_GetSystemInfo(jitter): - ret_ad, args = jitter.func_args_stdcall(["sys_ptr"]) - sysinfo = systeminfo() - jitter.vm.set_mem(args.sys_ptr, sysinfo.pack()) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_IsWow64Process(jitter): - ret_ad, args = jitter.func_args_stdcall(["process", "bool_ptr"]) - jitter.vm.set_u32(args.bool_ptr, 0) - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_GetCommandLine(jitter, set_str): - ret_ad, _ = jitter.func_args_stdcall(0) - alloc_addr = winobjs.heap.alloc(jitter, 0x1000) - set_str(alloc_addr, '"%s"' % winobjs.module_path) - jitter.func_ret_stdcall(ret_ad, alloc_addr) - - -def kernel32_GetCommandLineA(jitter): - kernel32_GetCommandLine(jitter, lambda addr, value: set_win_str_a(jitter, addr, value)) - - -def kernel32_GetCommandLineW(jitter): - kernel32_GetCommandLine(jitter, lambda addr, value: set_win_str_w(jitter, addr, value)) - - -def shell32_CommandLineToArgvW(jitter): - ret_ad, args = jitter.func_args_stdcall(["pcmd", "pnumargs"]) - cmd = get_win_str_w(jitter, args.pcmd) - if cmd.startswith('"') and cmd.endswith('"'): - cmd = cmd[1:-1] - log.info("CommandLineToArgv %r", cmd) - tks = cmd.split(' ') - addr = winobjs.heap.alloc(jitter, len(cmd) * 2 + 4 * len(tks)) - addr_ret = winobjs.heap.alloc(jitter, 4 * (len(tks) + 1)) - o = 0 - for i, t in enumerate(tks): - set_win_str_w(jitter, addr + o, t) - jitter.vm.set_u32(addr_ret + 4 * i, addr + o) - o += len(t)*2 + 2 - - jitter.vm.set_u32(addr_ret + 4 * (i+1), 0) - jitter.vm.set_u32(args.pnumargs, len(tks)) - jitter.func_ret_stdcall(ret_ad, addr_ret) - -def cryptdll_MD5Init(jitter): - ret_ad, args = jitter.func_args_stdcall(["ad_ctx"]) - index = len(winobjs.cryptdll_md5_h) - h = MD5.new() - winobjs.cryptdll_md5_h[index] = h - - jitter.vm.set_u32(args.ad_ctx, index) - jitter.func_ret_stdcall(ret_ad, 0) - - -def cryptdll_MD5Update(jitter): - ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_input", "inlen"]) - - index = jitter.vm.get_u32(args.ad_ctx) - if not index in winobjs.cryptdll_md5_h: - raise ValueError('unknown h context', index) - - data = jitter.vm.get_mem(args.ad_input, args.inlen) - winobjs.cryptdll_md5_h[index].update(data) - log.debug(hexdump(data)) - - jitter.func_ret_stdcall(ret_ad, 0) - - -def cryptdll_MD5Final(jitter): - ret_ad, args = jitter.func_args_stdcall(["ad_ctx"]) - - index = jitter.vm.get_u32(args.ad_ctx) - if not index in winobjs.cryptdll_md5_h: - raise ValueError('unknown h context', index) - h = winobjs.cryptdll_md5_h[index].digest() - jitter.vm.set_mem(args.ad_ctx + 88, h) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_RtlInitAnsiString(jitter): - ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_str"]) - - s = get_win_str_a(jitter, args.ad_str) - l = len(s) - jitter.vm.set_mem(args.ad_ctx, - pck16(l) + pck16(l + 1) + pck32(args.ad_str)) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_RtlHashUnicodeString(jitter): - ret_ad, args = jitter.func_args_stdcall(["ad_ctxu", "case_i", "h_id", - "phout"]) - - if args.h_id != 1: - raise ValueError('unk hash unicode', args.h_id) - - l1, l2, ptra = struct.unpack('HHL', jitter.vm.get_mem(args.ad_ctxu, 8)) - s = jitter.vm.get_mem(ptra, l1) - s = s[:-1] - hv = 0 - - if args.case_i: - s = s.lower() - for c in s: - hv = ((65599 * hv) + ord(c)) & 0xffffffff - jitter.vm.set_u32(args.phout, hv) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_RtlMoveMemory(jitter): - ret_ad, args = jitter.func_args_stdcall(["ad_dst", "ad_src", "m_len"]) - data = jitter.vm.get_mem(args.ad_src, args.m_len) - jitter.vm.set_mem(args.ad_dst, data) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_RtlAnsiCharToUnicodeChar(jitter): - ret_ad, args = jitter.func_args_stdcall(['ad_ad_ch']) - ad_ch = jitter.vm.get_u32(args.ad_ad_ch) - ch = ord(jitter.vm.get_mem(ad_ch, 1)) - jitter.vm.set_u32(args.ad_ad_ch, ad_ch + 1) - jitter.func_ret_stdcall(ret_ad, ch) - - -def ntdll_RtlFindCharInUnicodeString(jitter): - ret_ad, args = jitter.func_args_stdcall(["flags", "main_str_ad", - "search_chars_ad", "pos_ad"]) - - if args.flags != 0: - raise ValueError('unk flags') - - ml1, ml2, mptra = struct.unpack('HHL', - jitter.vm.get_mem(args.main_str_ad, 8)) - sl1, sl2, sptra = struct.unpack( - 'HHL', jitter.vm.get_mem(args.search_chars_ad, 8)) - main_data = jitter.vm.get_mem(mptra, ml1)[:-1] - search_data = jitter.vm.get_mem(sptra, sl1)[:-1] - - pos = None - for i, c in enumerate(main_data): - for s in search_data: - if s == c: - pos = i - break - if pos: - break - if pos is None: - ret = 0xC0000225 - jitter.vm.set_u32(args.pos_ad, 0) - else: - ret = 0 - jitter.vm.set_u32(args.pos_ad, pos) - - jitter.func_ret_stdcall(ret_ad, ret) - - -def ntdll_RtlComputeCrc32(jitter): - ret_ad, args = jitter.func_args_stdcall(["dwinit", "pdata", "ilen"]) - data = jitter.vm.get_mem(args.pdata, args.ilen) - crc_r = crc32(data, args.dwinit) - jitter.func_ret_stdcall(ret_ad, crc_r) - - -def ntdll_RtlExtendedIntegerMultiply(jitter): - ret_ad, args = jitter.func_args_stdcall(['multiplicand_low', - 'multiplicand_high', - 'multiplier']) - a = (args.multiplicand_high << 32) + args.multiplicand_low - a = a * args.multiplier - jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff) - - -def ntdll_RtlLargeIntegerAdd(jitter): - ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high', - 'b_low', 'b_high']) - a = (args.a_high << 32) + args.a_low + (args.b_high << 32) + args.b_low - jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff) - - -def ntdll_RtlLargeIntegerShiftRight(jitter): - ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high', 's_count']) - a = ((args.a_high << 32) + args.a_low) >> args.s_count - jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff) - - -def ntdll_RtlEnlargedUnsignedMultiply(jitter): - ret_ad, args = jitter.func_args_stdcall(['a', 'b']) - a = args.a * args.b - jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff) - - -def ntdll_RtlLargeIntegerSubtract(jitter): - ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high', - 'b_low', 'b_high']) - a = (args.a_high << 32) + args.a_low - (args.b_high << 32) + args.b_low - jitter.func_ret_stdcall(ret_ad, a & 0xffffffff, (a >> 32) & 0xffffffff) - - -def ntdll_RtlCompareMemory(jitter): - ret_ad, args = jitter.func_args_stdcall(['ad1', 'ad2', 'm_len']) - data1 = jitter.vm.get_mem(args.ad1, args.m_len) - data2 = jitter.vm.get_mem(args.ad2, args.m_len) - - i = 0 - while data1[i] == data2[i]: - i += 1 - if i >= args.m_len: - break - - jitter.func_ret_stdcall(ret_ad, i) - - -def user32_GetMessagePos(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, 0x00110022) - - -def kernel32_Sleep(jitter): - ret_ad, _ = jitter.func_args_stdcall(['t']) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_ZwUnmapViewOfSection(jitter): - ret_ad, _ = jitter.func_args_stdcall(['h', 'ad']) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_IsBadReadPtr(jitter): - ret_ad, _ = jitter.func_args_stdcall(['lp', 'ucb']) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntoskrnl_KeInitializeEvent(jitter): - ret_ad, args = jitter.func_args_stdcall(['my_event', 'my_type', - 'my_state']) - jitter.vm.set_u32(args.my_event, winobjs.win_event_num) - winobjs.win_event_num += 1 - - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntoskrnl_RtlGetVersion(jitter): - ret_ad, args = jitter.func_args_stdcall(['ptr_version']) - - s = struct.pack("IIIII", - 0x114, # struct size - 0x5, # maj vers - 0x2, # min vers - 0x666, # build nbr - 0x2, # platform id - ) + encode_win_str_w("Service pack 4") - - jitter.vm.set_mem(args.ptr_version, s) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntoskrnl_RtlVerifyVersionInfo(jitter): - ret_ad, args = jitter.func_args_stdcall(['ptr_version']) - - s = jitter.vm.get_mem(args.ptr_version, 0x5 * 4) - s_size, s_majv, s_minv, s_buildn, s_platform = struct.unpack('IIIII', s) - raise NotImplementedError("Untested case") - # jitter.vm.set_mem(args.ptr_version, s) - # jitter.func_ret_stdcall(ret_ad, 0) - - -def hal_ExAcquireFastMutex(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, 0) - - -def mdl2ad(n): - return winobjs.nt_mdl_ad + 0x10 * n - - -def ad2mdl(ad): - return ((ad - winobjs.nt_mdl_ad) & 0xFFFFFFFF) // 0x10 - - -def ntoskrnl_IoAllocateMdl(jitter): - ret_ad, args = jitter.func_args_stdcall(["v_addr", "l", "second_buf", - "chargequota", "pirp"]) - m = mdl(args.v_addr, args.l) - winobjs.nt_mdl[winobjs.nt_mdl_cur] = m - jitter.vm.set_mem(mdl2ad(winobjs.nt_mdl_cur), bytes(m)) - jitter.func_ret_stdcall(ret_ad, mdl2ad(winobjs.nt_mdl_cur)) - winobjs.nt_mdl_cur += 1 - - -def ntoskrnl_MmProbeAndLockPages(jitter): - ret_ad, args = jitter.func_args_stdcall(["p_mdl", "access_mode", "op"]) - - if not ad2mdl(args.p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(args.p_mdl)) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntoskrnl_MmMapLockedPagesSpecifyCache(jitter): - ret_ad, args = jitter.func_args_stdcall(["p_mdl", "access_mode", - "cache_type", "base_ad", - "bugcheckonfailure", - "priority"]) - if not ad2mdl(args.p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(args.p_mdl)) - - jitter.func_ret_stdcall(ret_ad, winobjs.nt_mdl[ad2mdl(args.p_mdl)].ad) - - -def ntoskrnl_MmProtectMdlSystemAddress(jitter): - ret_ad, args = jitter.func_args_stdcall(["p_mdl", "prot"]) - if not ad2mdl(args.p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(args.p_mdl)) - - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntoskrnl_MmUnlockPages(jitter): - ret_ad, args = jitter.func_args_stdcall(['p_mdl']) - if not ad2mdl(args.p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(args.p_mdl)) - - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntoskrnl_IoFreeMdl(jitter): - ret_ad, args = jitter.func_args_stdcall(['p_mdl']) - if not ad2mdl(args.p_mdl) in winobjs.nt_mdl: - raise ValueError('unk mdl', hex(args.p_mdl)) - del(winobjs.nt_mdl[ad2mdl(args.p_mdl)]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def hal_ExReleaseFastMutex(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntoskrnl_RtlQueryRegistryValues(jitter): - ret_ad, args = jitter.func_args_stdcall(["relativeto", "path", - "querytable", - "context", - "environ"]) - # path = get_win_str_w(jitter, args.path) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntoskrnl_ExAllocatePoolWithTagPriority(jitter): - ret_ad, args = jitter.func_args_stdcall(["pool_type", - "nbr_of_bytes", - "tag", "priority"]) - alloc_addr = winobjs.heap.next_addr(args.nbr_of_bytes) - jitter.vm.add_memory_page( - alloc_addr, PAGE_READ | PAGE_WRITE, b"\x00" * args.nbr_of_bytes, - "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) - - jitter.func_ret_stdcall(ret_ad, alloc_addr) - - -def my_lstrcmp(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2"]) - s1 = get_str(args.ptr_str1) - s2 = get_str(args.ptr_str2) - log.info("Compare %r with %r", s1, s2) - jitter.func_ret_stdcall(ret_ad, cmp(s1, s2)) - -def msvcrt_wcscmp(jitter): - ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"]) - s1 = get_win_str_w(jitter, args.ptr_str1) - s2 = get_win_str_w(jitter, args.ptr_str2) - log.debug("%s('%s','%s')" % (whoami(), s1, s2)) - jitter.func_ret_cdecl(ret_ad, cmp(s1, s2)) - -def msvcrt__wcsicmp(jitter): - ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"]) - s1 = get_win_str_w(jitter, args.ptr_str1) - s2 = get_win_str_w(jitter, args.ptr_str2) - log.debug("%s('%s','%s')" % (whoami(), s1, s2)) - jitter.func_ret_cdecl(ret_ad, cmp(s1.lower(), s2.lower())) - -def msvcrt__wcsnicmp(jitter): - ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2", "count"]) - s1 = get_win_str_w(jitter, args.ptr_str1) - s2 = get_win_str_w(jitter, args.ptr_str2) - log.debug("%s('%s','%s',%d)" % (whoami(), s1, s2, args.count)) - jitter.func_ret_cdecl(ret_ad, cmp(s1.lower()[:args.count], s2.lower()[:args.count])) - -def msvcrt_wcsncpy(jitter): - ret_ad, args = jitter.func_args_cdecl(["dst", "src", "n"]) - src = get_win_str_w(jitter, args.src) - dst = src[:args.n] - jitter.vm.set_mem(args.dst, b"\x00\x00" * args.n) - jitter.vm.set_mem(args.dst, dst.encode("utf-16le")) - jitter.func_ret_cdecl(ret_ad, args.dst) - -def kernel32_lstrcmpA(jitter): - my_lstrcmp(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def kernel32_lstrcmpiA(jitter): - my_lstrcmp(jitter, whoami(), lambda x: get_win_str_a(jitter, x).lower()) - - -def kernel32_lstrcmpW(jitter): - my_lstrcmp(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def kernel32_lstrcmpiW(jitter): - my_lstrcmp(jitter, whoami(), lambda x: get_win_str_w(jitter, x).lower()) - - -def kernel32_lstrcmpi(jitter): - my_lstrcmp(jitter, whoami(), lambda x: get_win_str_a(jitter, x).lower()) - - -def my_strcpy(jitter, funcname, get_str, set_str): - ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2"]) - s2 = get_str(args.ptr_str2) - set_str(args.ptr_str1, s2) - log.info("Copy '%r'", s2) - jitter.func_ret_stdcall(ret_ad, args.ptr_str1) - - -def kernel32_lstrcpyW(jitter): - my_strcpy(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr), lambda addr,value: set_win_str_w(jitter, addr, value)) - - -def kernel32_lstrcpyA(jitter): - my_strcpy(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), lambda addr,value: set_win_str_a(jitter, addr, value)) - - -def kernel32_lstrcpy(jitter): - my_strcpy(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), lambda addr,value: set_win_str_a(jitter, addr, value)) - -def msvcrt__mbscpy(jitter): - ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"]) - s2 = get_win_str_w(jitter, args.ptr_str2) - set_win_str_w(jitter, args.ptr_str1, s2) - jitter.func_ret_cdecl(ret_ad, args.ptr_str1) - -def msvcrt_wcscpy(jitter): - return msvcrt__mbscpy(jitter) - - -def kernel32_lstrcpyn(jitter): - ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2", - "mlen"]) - s2 = get_win_str_a(jitter, args.ptr_str2) - if len(s2) >= args.mlen: - s2 = s2[:args.mlen - 1] - log.info("Copy '%r'", s2) - set_win_str_a(jitter, args.ptr_str1, s2) - jitter.func_ret_stdcall(ret_ad, args.ptr_str1) - - -def my_strlen(jitter, funcname, get_str, mylen): - ret_ad, args = jitter.func_args_stdcall(["src"]) - src = get_str(args.src) - length = mylen(src) - log.info("Len of '%r' -> 0x%x", src, length) - jitter.func_ret_stdcall(ret_ad, length) - - -def kernel32_lstrlenA(jitter): - my_strlen(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), len) - - -def kernel32_lstrlenW(jitter): - my_strlen(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr), len) - - -def kernel32_lstrlen(jitter): - my_strlen(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), len) - - -def my_lstrcat(jitter, funcname, get_str, set_str): - ret_ad, args = jitter.func_args_stdcall(['ptr_str1', 'ptr_str2']) - s1 = get_str(args.ptr_str1) - s2 = get_str(args.ptr_str2) - set_str(args.ptr_str1, s1 + s2) - jitter.func_ret_stdcall(ret_ad, args.ptr_str1) - - -def kernel32_lstrcatA(jitter): - my_lstrcat(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), lambda addr,value: set_win_str_a(jitter, addr, value)) - - -def kernel32_lstrcatW(jitter): - my_lstrcat(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr), lambda addr,value: set_win_str_w(jitter, addr, value)) - - -def kernel32_GetUserGeoID(jitter): - ret_ad, args = jitter.func_args_stdcall(["geoclass"]) - if args.geoclass == 14: - ret = 12345678 - elif args.geoclass == 16: - ret = 55667788 - else: - raise ValueError('unknown geolcass') - jitter.func_ret_stdcall(ret_ad, ret) - - -def my_GetVolumeInformation(jitter, funcname, get_str, set_str): - ret_ad, args = jitter.func_args_stdcall(["lprootpathname", - "lpvolumenamebuffer", - "nvolumenamesize", - "lpvolumeserialnumber", - "lpmaximumcomponentlength", - "lpfilesystemflags", - "lpfilesystemnamebuffer", - "nfilesystemnamesize"]) - if args.lprootpathname: - s = get_str(args.lprootpathname) - log.info('GetVolumeInformation %r', s) - - - if args.lpvolumenamebuffer: - s = "volumename" - s = s[:args.nvolumenamesize] - set_str(args.lpvolumenamebuffer, s) - - if args.lpvolumeserialnumber: - jitter.vm.set_u32(args.lpvolumeserialnumber, 11111111) - if args.lpmaximumcomponentlength: - jitter.vm.set_u32(args.lpmaximumcomponentlength, 0xff) - if args.lpfilesystemflags: - jitter.vm.set_u32(args.lpfilesystemflags, 22222222) - - if args.lpfilesystemnamebuffer: - s = "filesystemname" - s = s[:args.nfilesystemnamesize] - set_str(args.lpfilesystemnamebuffer, s) - - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_GetVolumeInformationA(jitter): - my_GetVolumeInformation( - jitter, whoami(), lambda addr:get_win_str_a(jitter, addr), lambda addr,value: set_win_str_a(jitter, addr, value)) - - -def kernel32_GetVolumeInformationW(jitter): - my_GetVolumeInformation(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr), lambda addr,value: set_win_str_w(jitter, addr, value)) - - -def kernel32_MultiByteToWideChar(jitter): - MB_ERR_INVALID_CHARS = 0x8 - CP_ACP = 0x000 - CP_1252 = 0x4e4 - - ret_ad, args = jitter.func_args_stdcall(["codepage", "dwflags", - "lpmultibytestr", - "cbmultibyte", - "lpwidecharstr", - "cchwidechar"]) - if args.codepage != CP_ACP and args.codepage != CP_1252: - raise NotImplementedError - # according to MSDN: - # "Note that, if cbMultiByte is 0, the function fails." - if args.cbmultibyte == 0: - raise ValueError - # according to MSDN: - # "Alternatively, this parameter can be set to -1 if the string is - # null-terminated." - if args.cbmultibyte == 0xffffffff: - src_len = 0 - while jitter.vm.get_mem(args.lpmultibytestr + src_len, 1) != b'\0': - src_len += 1 - src = jitter.vm.get_mem(args.lpmultibytestr, src_len) - else: - src = jitter.vm.get_mem(args.lpmultibytestr, args.cbmultibyte) - if args.dwflags & MB_ERR_INVALID_CHARS: - # will raise an exception if decoding fails - s = src.decode("cp1252", errors="replace").encode("utf-16le") - else: - # silently replace undecodable chars with U+FFFD - s = src.decode("cp1252", errors="replace").encode("utf-16le") - if args.cchwidechar > 0: - # return value is number of bytes written - retval = min(args.cchwidechar, len(s)) - jitter.vm.set_mem(args.lpwidecharstr, s[:retval]) - else: - # return value is number of bytes to write - # i.e., size of dest. buffer to allocate - retval = len(s) - jitter.func_ret_stdcall(ret_ad, retval) - - -def kernel32_WideCharToMultiByte(jitter): - """ - int WideCharToMultiByte( - UINT CodePage, - DWORD dwFlags, - _In_NLS_string_(cchWideChar)LPCWCH lpWideCharStr, - int cchWideChar, - LPSTR lpMultiByteStr, - int cbMultiByte, - LPCCH lpDefaultChar, - LPBOOL lpUsedDefaultChar - ); - - """ - CP_ACP = 0x000 - CP_1252 = 0x4e4 - - ret, args = jitter.func_args_stdcall([ - 'CodePage', 'dwFlags', 'lpWideCharStr', 'cchWideChar', - 'lpMultiByteStr', 'cbMultiByte', 'lpDefaultChar', 'lpUsedDefaultChar', - ]) - if args.CodePage != CP_ACP and args.CodePage != CP_1252: - raise NotImplementedError - cchWideChar = args.cchWideChar - if cchWideChar == 0xffffffff: - cchWideChar = len(get_win_str_w(jitter, args.lpWideCharStr)) + 1 - src = jitter.vm.get_mem(args.lpWideCharStr, cchWideChar * 2) - dst = src.decode("utf-16le").encode("cp1252", errors="replace") - if args.cbMultiByte > 0: - # return value is the number of bytes written - retval = min(args.cbMultiByte, len(dst)) - jitter.vm.set_mem(args.lpMultiByteStr, dst[:retval]) - else: - # return value is the size of the buffer to allocate - # to get the multibyte string - retval = len(dst) - jitter.func_ret_stdcall(ret, retval) - - -def my_GetEnvironmentVariable(jitter, funcname, get_str, set_str, mylen): - ret_ad, args = jitter.func_args_stdcall(["lpname", "lpbuffer", - "nsize"]) - - s = get_str(args.lpname) - log.info('GetEnvironmentVariable %r', s) - if s in winobjs.env_variables: - v = winobjs.env_variables[s] - else: - log.warning('WARNING unknown env variable %r', s) - v = "" - set_str(args.lpbuffer, v) - jitter.func_ret_stdcall(ret_ad, mylen(v)) - - -def kernel32_GetEnvironmentVariableA(jitter): - my_GetEnvironmentVariable(jitter, whoami(), - lambda addr:get_win_str_a(jitter, addr), - lambda addr,value: set_win_str_a(jitter, addr, value), - len) - - -def kernel32_GetEnvironmentVariableW(jitter): - my_GetEnvironmentVariable(jitter, whoami(), - lambda addr:get_win_str_w(jitter, addr), - lambda addr,value: set_win_str_w(jitter, addr, value), - len) - - -def my_GetSystemDirectory(jitter, funcname, set_str): - ret_ad, args = jitter.func_args_stdcall(["lpbuffer", "usize"]) - s = "c:\\windows\\system32" - l = len(s) - set_str(args.lpbuffer, s) - jitter.func_ret_stdcall(ret_ad, l) - - - -def kernel32_GetSystemDirectoryA(jitter): - my_GetSystemDirectory(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value)) - - -def kernel32_GetSystemDirectoryW(jitter): - my_GetSystemDirectory(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value)) - - -def my_CreateDirectory(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(['lppath', 'secattrib']) - # path = get_str(jitter, args.lppath) - jitter.func_ret_stdcall(ret_ad, 0x1337) - - -def kernel32_CreateDirectoryW(jitter): - my_CreateDirectory(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def kernel32_CreateDirectoryA(jitter): - my_CreateDirectory(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - - -def my_CreateEvent(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["lpeventattributes", - "bmanualreset", - "binitialstate", - "lpname"]) - s = get_str(args.lpname) if args.lpname else None - if not s in winobjs.events_pool: - winobjs.events_pool[s] = (args.bmanualreset, args.binitialstate) - else: - log.warning('WARNING: known event') - jitter.func_ret_stdcall(ret_ad, id(s) & 0xFFFFFFFF) - - -def kernel32_CreateEventA(jitter): - my_CreateEvent(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def kernel32_CreateEventW(jitter): - my_CreateEvent(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def kernel32_WaitForSingleObject(jitter): - ret_ad, args = jitter.func_args_stdcall(['handle', 'dwms']) - - t_start = time.time() * 1000 - found = False - while True: - if args.dwms and args.dwms + t_start > time.time() * 1000: - ret = 0x102 - break - for key, value in viewitems(winobjs.events_pool): - if key != args.handle: - continue - found = True - if value[1] == 1: - ret = 0 - break - if not found: - log.warning('unknown handle') - ret = 0xffffffff - break - time.sleep(0.1) - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_SetFileAttributesA(jitter): - ret_ad, args = jitter.func_args_stdcall(["lpfilename", - "dwfileattributes"]) - if args.lpfilename: - # fname = get_win_str_a(jitter, args.lpfilename) - ret = 1 - else: - ret = 0 - jitter.vm.set_u32(tib_address + 0x34, 3) - - jitter.func_ret_stdcall(ret_ad, ret) - - -def ntdll_RtlMoveMemory(jitter): - ret_ad, args = jitter.func_args_stdcall(["dst", "src", "l"]) - s = jitter.vm.get_mem(args.src, args.l) - jitter.vm.set_mem(args.dst, s) - jitter.func_ret_stdcall(ret_ad, 1) - - -def ntdll_ZwQuerySystemInformation(jitter): - ret_ad, args = jitter.func_args_stdcall(["systeminformationclass", - "systeminformation", - "systeminformationl", - "returnl"]) - if args.systeminformationclass == 2: - # SYSTEM_PERFORMANCE_INFORMATION - o = struct.pack('II', 0x22222222, 0x33333333) - o += b"\x00" * args.systeminformationl - o = o[:args.systeminformationl] - jitter.vm.set_mem(args.systeminformation, o) - else: - raise ValueError('unknown sysinfo class', - args.systeminformationclass) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_ZwProtectVirtualMemory(jitter): - ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid", - "pdwsize", - "flnewprotect", - "lpfloldprotect"]) - - ad = jitter.vm.get_u32(args.lppvoid) - # dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4)) - # XXX mask hpart - flnewprotect = args.flnewprotect & 0xFFF - - if not flnewprotect in ACCESS_DICT: - raise ValueError('unknown access dw!') - jitter.vm.set_mem_access(ad, ACCESS_DICT[flnewprotect]) - - # XXX todo real old protect - jitter.vm.set_u32(args.lpfloldprotect, 0x40) - - jitter.func_ret_stdcall(ret_ad, 1) - - -def ntdll_ZwAllocateVirtualMemory(jitter): - ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid", - "zerobits", "pdwsize", - "alloc_type", - "flprotect"]) - - # ad = upck32(jitter.vm.get_mem(args.lppvoid, 4)) - dwsize = jitter.vm.get_u32(args.pdwsize) - - if not args.flprotect in ACCESS_DICT: - raise ValueError('unknown access dw!') - - alloc_addr = winobjs.heap.next_addr(dwsize) - jitter.vm.add_memory_page( - alloc_addr, ACCESS_DICT[args.flprotect], b"\x00" * dwsize, - "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) - jitter.vm.set_u32(args.lppvoid, alloc_addr) - - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_ZwFreeVirtualMemory(jitter): - ret_ad, args = jitter.func_args_stdcall(["handle", "lppvoid", - "pdwsize", "alloc_type"]) - # ad = upck32(jitter.vm.get_mem(args.lppvoid, 4)) - # dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4)) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_RtlInitString(jitter): - ret_ad, args = jitter.func_args_stdcall(["pstring", "source"]) - s = get_win_str_a(jitter, args.source) - l = len(s) + 1 - o = struct.pack('HHI', l, l, args.source) - jitter.vm.set_mem(args.pstring, o) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_RtlAnsiStringToUnicodeString(jitter): - ret_ad, args = jitter.func_args_stdcall(["dst", "src", "alloc_str"]) - - l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8)) - s = get_win_str_a(jitter, p_src) - l = (len(s) + 1) * 2 - if args.alloc_str: - alloc_addr = winobjs.heap.next_addr(l) - jitter.vm.add_memory_page( - alloc_addr, PAGE_READ | PAGE_WRITE, b"\x00" * l, - "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) - else: - alloc_addr = p_src - set_win_str_w(jitter, alloc_addr, s) - o = struct.pack('HHI', l, l, alloc_addr) - jitter.vm.set_mem(args.dst, o) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_LdrLoadDll(jitter): - ret_ad, args = jitter.func_args_stdcall(["path", "flags", - "modname", "modhandle"]) - - l1, l2, p_src = struct.unpack('HHI', - jitter.vm.get_mem(args.modname, 0x8)) - s = get_win_str_w(jitter, p_src) - libname = s.lower() - - ad = winobjs.runtime_dll.lib_get_add_base(libname) - log.info("Loading %r ret 0x%x", s, ad) - jitter.vm.set_u32(args.modhandle, ad) - - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_RtlFreeUnicodeString(jitter): - ret_ad, args = jitter.func_args_stdcall(['src']) - # l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8)) - # s = get_win_str_w(jitter, p_src) - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_LdrGetProcedureAddress(jitter): - ret_ad, args = jitter.func_args_stdcall(["libbase", "pfname", - "opt", "p_ad"]) - - l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.pfname, 0x8)) - fname = get_win_str_a(jitter, p_src) - - ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname) - jitter.add_breakpoint(ad, jitter.handle_lib) - - jitter.vm.set_u32(args.p_ad, ad) - - jitter.func_ret_stdcall(ret_ad, 0) - - -def ntdll_memset(jitter): - ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size']) - jitter.vm.set_mem(args.addr, int_to_byte(args.c) * args.size) - jitter.func_ret_cdecl(ret_ad, args.addr) - - -def msvcrt_memset(jitter): - ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size']) - jitter.vm.set_mem(args.addr, int_to_byte(args.c) * args.size) - jitter.func_ret_cdecl(ret_ad, args.addr) - -def msvcrt_strrchr(jitter): - ret_ad, args = jitter.func_args_cdecl(['pstr','c']) - s = get_win_str_a(jitter, args.pstr) - c = int_to_byte(args.c).decode() - ret = args.pstr + s.rfind(c) - log.info("strrchr(%x '%s','%s') = %x" % (args.pstr,s,c,ret)) - jitter.func_ret_cdecl(ret_ad, ret) - -def msvcrt_wcsrchr(jitter): - ret_ad, args = jitter.func_args_cdecl(['pstr','c']) - s = get_win_str_w(jitter, args.pstr) - c = int_to_byte(args.c).decode() - ret = args.pstr + (s.rfind(c)*2) - log.info("wcsrchr(%x '%s',%s) = %x" % (args.pstr,s,c,ret)) - jitter.func_ret_cdecl(ret_ad, ret) - -def msvcrt_memcpy(jitter): - ret_ad, args = jitter.func_args_cdecl(['dst', 'src', 'size']) - s = jitter.vm.get_mem(args.src, args.size) - jitter.vm.set_mem(args.dst, s) - jitter.func_ret_cdecl(ret_ad, args.dst) - -def msvcrt_realloc(jitter): - ret_ad,args = jitter.func_args_cdecl(['ptr','new_size']) - if args.ptr == 0: - addr = winobjs.heap.alloc(jitter, args.new_size) - else: - addr = winobjs.heap.alloc(jitter, args.new_size) - size = winobjs.heap.get_size(jitter.vm, args.ptr) - data = jitter.vm.get_mem(args.ptr, size) - jitter.vm.set_mem(addr, data) - jitter.func_ret_cdecl(ret_ad, addr) - -def msvcrt_memcmp(jitter): - ret_ad, args = jitter.func_args_cdecl(['ps1', 'ps2', 'size']) - s1 = jitter.vm.get_mem(args.ps1, args.size) - s2 = jitter.vm.get_mem(args.ps2, args.size) - ret = cmp(s1, s2) - jitter.func_ret_cdecl(ret_ad, ret) - - -def shlwapi_PathFindExtensionA(jitter): - ret_ad, args = jitter.func_args_stdcall(['path_ad']) - path = get_win_str_a(jitter, args.path_ad) - i = path.rfind('.') - if i == -1: - i = args.path_ad + len(path) - else: - i = args.path_ad + i - jitter.func_ret_stdcall(ret_ad, i) - - -def shlwapi_PathRemoveFileSpecW(jitter): - ret_ad, args = jitter.func_args_stdcall(['path_ad']) - path = get_win_str_w(jitter, args.path_ad) - i = path.rfind('\\') - if i == -1: - i = 0 - jitter.vm.set_mem(args.path_ad + i * 2, b"\x00\x00") - path = get_win_str_w(jitter, args.path_ad) - jitter.func_ret_stdcall(ret_ad, 1) - - -def shlwapi_PathIsPrefixW(jitter): - ret_ad, args = jitter.func_args_stdcall(['ptr_prefix', 'ptr_path']) - prefix = get_win_str_w(jitter, args.ptr_prefix) - path = get_win_str_w(jitter, args.ptr_path) - - if path.startswith(prefix): - ret = 1 - else: - ret = 0 - jitter.func_ret_stdcall(ret_ad, ret) - - -def shlwapi_PathIsDirectoryW(jitter): - ret_ad, args = jitter.func_args_stdcall(['ptr_path']) - fname = get_win_str_w(jitter, args.ptr_path) - - sb_fname = windows_to_sbpath(fname) - - s = os.stat(sb_fname) - ret = 0 - if stat.S_ISDIR(s.st_mode): - ret = 1 - - jitter.func_ret_cdecl(ret_ad, ret) - - -def shlwapi_PathIsFileSpec(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(['path_ad']) - path = get_str(args.path_ad) - if path.find(':') != -1 and path.find('\\') != -1: - ret = 0 - else: - ret = 1 - - jitter.func_ret_stdcall(ret_ad, ret) - - -def shlwapi_PathGetDriveNumber(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(['path_ad']) - path = get_str(args.path_ad) - l = ord(path[0].upper()) - ord('A') - if 0 <= l <= 25: - ret = l - else: - ret = -1 - - jitter.func_ret_stdcall(ret_ad, ret) - - -def shlwapi_PathGetDriveNumberA(jitter): - shlwapi_PathGetDriveNumber(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def shlwapi_PathGetDriveNumberW(jitter): - shlwapi_PathGetDriveNumber(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def shlwapi_PathIsFileSpecA(jitter): - shlwapi_PathIsFileSpec(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def shlwapi_PathIsFileSpecW(jitter): - shlwapi_PathIsFileSpec(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def shlwapi_StrToIntA(jitter): - ret_ad, args = jitter.func_args_stdcall(['i_str_ad']) - i_str = get_win_str_a(jitter, args.i_str_ad) - try: - i = int(i_str) - except: - log.warning('WARNING cannot convert int') - i = 0 - - jitter.func_ret_stdcall(ret_ad, i) - - -def shlwapi_StrToInt64Ex(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(['pstr', 'flags', 'pret']) - i_str = get_str(args.pstr) - - if args.flags == 0: - r = int(i_str) - elif args.flags == 1: - r = int(i_str, 16) - else: - raise ValueError('cannot decode int') - - jitter.vm.set_mem(args.pret, struct.pack('q', r)) - jitter.func_ret_stdcall(ret_ad, 1) - - -def shlwapi_StrToInt64ExA(jitter): - shlwapi_StrToInt64Ex(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def shlwapi_StrToInt64ExW(jitter): - shlwapi_StrToInt64Ex(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def user32_IsCharAlpha(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["c"]) - try: - c = int_to_byte(args.c) - except: - log.error('bad char %r', args.c) - c = "\x00" - if c.isalpha(jitter): - ret = 1 - else: - ret = 0 - jitter.func_ret_stdcall(ret_ad, ret) - - -def user32_IsCharAlphaA(jitter): - user32_IsCharAlpha(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def user32_IsCharAlphaW(jitter): - user32_IsCharAlpha(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def user32_IsCharAlphaNumericA(jitter): - ret_ad, args = jitter.func_args_stdcall(["c"]) - c = int_to_byte(args.c) - if c.isalnum(jitter): - ret = 1 - else: - ret = 0 - jitter.func_ret_stdcall(ret_ad, ret) - -def get_fmt_args(jitter, fmt, cur_arg, get_str): - return _get_fmt_args(fmt, cur_arg, get_str, jitter.get_arg_n_cdecl) - -def msvcrt_sprintf_str(jitter, get_str): - ret_ad, args = jitter.func_args_cdecl(['string', 'fmt']) - cur_arg, fmt = 2, args.fmt - return ret_ad, args, get_fmt_args(jitter, fmt, cur_arg, get_str) - -def msvcrt_sprintf(jitter): - ret_ad, args, output = msvcrt_sprintf_str(jitter, lambda addr:get_win_str_a(jitter, addr)) - ret = len(output) - log.info("sprintf() = '%s'" % (output)) - jitter.vm.set_mem(args.string, (output + '\x00').encode('utf8')) - return jitter.func_ret_cdecl(ret_ad, ret) - -def msvcrt_swprintf(jitter): - ret_ad, args = jitter.func_args_cdecl(['string', 'fmt']) - cur_arg, fmt = 2, args.fmt - output = get_fmt_args(jitter, fmt, cur_arg, lambda addr:get_win_str_w(jitter, addr)) - ret = len(output) - log.info("swprintf('%s') = '%s'" % (get_win_str_w(jitter, args.fmt), output)) - jitter.vm.set_mem(args.string, output.encode("utf-16le") + b'\x00\x00') - return jitter.func_ret_cdecl(ret_ad, ret) - -def msvcrt_fprintf(jitter): - ret_addr, args = jitter.func_args_cdecl(['file', 'fmt']) - cur_arg, fmt = 2, args.fmt - output = get_fmt_args(jitter, fmt, cur_arg, lambda addr:get_win_str_a(jitter, addr)) - ret = len(output) - log.info("fprintf(%x, '%s') = '%s'" % (args.file, lambda addr:get_win_str_a(jitter, addr)(args.fmt), output)) - - fd = jitter.vm.get_u32(args.file + 0x10) - if not fd in winobjs.handle_pool: - raise NotImplementedError("Untested case") - winobjs.handle_pool[fd].info.write(output) - - return jitter.func_ret_cdecl(ret_addr, ret) - -def shlwapi_StrCmpNIA(jitter): - ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2", - "nchar"]) - s1 = get_win_str_a(jitter, args.ptr_str1).lower() - s2 = get_win_str_a(jitter, args.ptr_str2).lower() - s1 = s1[:args.nchar] - s2 = s2[:args.nchar] - jitter.func_ret_stdcall(ret_ad, cmp(s1, s2)) - - -def advapi32_RegCreateKeyW(jitter): - ret_ad, args = jitter.func_args_stdcall(["hkey", "subkey", - "phandle"]) - s_subkey = get_win_str_w(jitter, args.subkey).lower() if args.subkey else "" - - ret_hkey = 0 - ret = 2 - if args.hkey in winobjs.hkey_handles: - ret = 0 - if s_subkey: - ret_hkey = hash(s_subkey) & 0xffffffff - winobjs.hkey_handles[ret_hkey] = s_subkey - else: - ret_hkey = args.hkey - - log.info("RegCreateKeyW(%x, '%s') = (%x,%d)" % (args.hkey, s_subkey, ret_hkey, ret)) - jitter.vm.set_u32(args.phandle, ret_hkey) - - jitter.func_ret_stdcall(ret_ad, ret) - -def kernel32_GetCurrentDirectoryA(jitter): - ret_ad, args = jitter.func_args_stdcall(["size","buf"]) - dir_ = winobjs.cur_dir - log.debug("GetCurrentDirectory() = '%s'" % dir_) - set_win_str_a(jitter, args.buf, dir_[:args.size-1]) - ret = len(dir_) - if args.size <= len(dir_): - ret += 1 - jitter.func_ret_stdcall(ret_ad, ret) - -def advapi32_RegOpenKeyEx(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["hkey", "subkey", - "reserved", "access", - "phandle"]) - s_subkey = get_str(args.subkey).lower() if args.subkey else "" - - ret_hkey = 0 - ret = 2 - if args.hkey in winobjs.hkey_handles: - if s_subkey: - h = hash(s_subkey) & 0xffffffff - if h in winobjs.hkey_handles: - ret_hkey = h - ret = 0 - else: - log.error('unknown skey') - - jitter.vm.set_u32(args.phandle, ret_hkey) - - jitter.func_ret_stdcall(ret_ad, ret) - - -def advapi32_RegOpenKeyExA(jitter): - advapi32_RegOpenKeyEx(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def advapi32_RegOpenKeyExW(jitter): - advapi32_RegOpenKeyEx(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def advapi32_RegSetValue(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["hkey", "psubkey", - "valuetype", "pvalue", - "vlen"]) - if args.psubkey: - log.info("Subkey %s", get_str(args.psubkey)) - if args.pvalue: - log.info("Value %s", get_str(args.pvalue)) - jitter.func_ret_stdcall(ret_ad, 0) - -def advapi32_RegSetValueEx(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["hkey", "lpvaluename", - "reserved", "dwtype", - "lpdata", "cbData"]) - hkey = winobjs.hkey_handles.get(args.hkey, "unknown HKEY") - value_name = get_str(args.lpvaluename) if args.lpvaluename else "" - data = get_str(args.lpdata) if args.lpdata else "" - log.info("%s('%s','%s'='%s',%x)" % (funcname, hkey, value_name, data, args.dwtype)) - jitter.func_ret_stdcall(ret_ad, 0) - -def advapi32_RegCloseKey(jitter): - ret_ad, args = jitter.func_args_stdcall(["hkey"]) - del winobjs.hkey_handles[args.hkey] - log.info("RegCloseKey(%x)" % args.hkey) - jitter.func_ret_stdcall(ret_ad, 0) - -def advapi32_RegSetValueExA(jitter): - advapi32_RegSetValueEx(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def advapi32_RegSetValueExW(jitter): - advapi32_RegOpenKeyEx(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def advapi32_RegSetValueA(jitter): - advapi32_RegSetValue(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def advapi32_RegSetValueW(jitter): - advapi32_RegSetValue(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def kernel32_GetThreadLocale(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, 0x40c) - -def kernel32_SetCurrentDirectory(jitter, get_str): - ret_ad, args = jitter.func_args_stdcall(['dir']) - dir_ = get_str(args.dir) - log.debug("SetCurrentDirectory('%s') = 1" % dir_) - winobjs.cur_dir = dir_ - jitter.func_ret_stdcall(ret_ad, 1) - -def kernel32_SetCurrentDirectoryW(jitter): - return kernel32_SetCurrentDirectory(jitter, lambda addr:get_win_str_w(jitter, addr)) - -def kernel32_SetCurrentDirectoryA(jitter): - return kernel32_SetCurrentDirectory(jitter, lambda addr:get_win_str_a(jitter, addr)) - -def msvcrt_wcscat(jitter): - ret_ad, args = jitter.func_args_cdecl(['ptr_str1', 'ptr_str2']) - s1 = get_win_str_w(jitter, args.ptr_str1) - s2 = get_win_str_w(jitter, args.ptr_str2) - log.info("strcat('%s','%s')" % (s1,s2)) - set_win_str_w(jitter, args.ptr_str1, s1 + s2) - jitter.func_ret_cdecl(ret_ad, args.ptr_str1) - - -def kernel32_GetLocaleInfo(jitter, funcname, set_str): - ret_ad, args = jitter.func_args_stdcall(["localeid", "lctype", - "lplcdata", "cchdata"]) - - buf = None - ret = 0 - if args.localeid == 0x40c: - if args.lctype == 0x3: - buf = "ENGLISH" - buf = buf[:args.cchdata - 1] - set_str(args.lplcdata, buf) - ret = len(buf) - else: - raise ValueError('unimpl localeid') - - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_GetLocaleInfoA(jitter): - kernel32_GetLocaleInfo(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value)) - - -def kernel32_GetLocaleInfoW(jitter): - kernel32_GetLocaleInfo(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value)) - - -def kernel32_TlsAlloc(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - winobjs.tls_index += 1 - jitter.func_ret_stdcall(ret_ad, winobjs.tls_index) - - -def kernel32_TlsFree(jitter): - ret_ad, _ = jitter.func_args_stdcall(["tlsindex"]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_TlsSetValue(jitter): - ret_ad, args = jitter.func_args_stdcall(["tlsindex", "tlsvalue"]) - winobjs.tls_values[args.tlsindex] = args.tlsvalue - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_TlsGetValue(jitter): - ret_ad, args = jitter.func_args_stdcall(["tlsindex"]) - if not args.tlsindex in winobjs.tls_values: - raise ValueError("unknown tls val", repr(args.tlsindex)) - jitter.func_ret_stdcall(ret_ad, winobjs.tls_values[args.tlsindex]) - - -def user32_GetKeyboardType(jitter): - ret_ad, args = jitter.func_args_stdcall(["typeflag"]) - - ret = 0 - if args.typeflag == 0: - ret = 4 - else: - raise ValueError('unimpl keyboard type') - - jitter.func_ret_stdcall(ret_ad, ret) - - -class startupinfo(object): - """ - typedef struct _STARTUPINFOA { - /* 00000000 */ DWORD cb; - /* 00000004 */ LPSTR lpReserved; - /* 00000008 */ LPSTR lpDesktop; - /* 0000000C */ LPSTR lpTitle; - /* 00000010 */ DWORD dwX; - /* 00000014 */ DWORD dwY; - /* 00000018 */ DWORD dwXSize; - /* 0000001C */ DWORD dwYSize; - /* 00000020 */ DWORD dwXCountChars; - /* 00000024 */ DWORD dwYCountChars; - /* 00000028 */ DWORD dwFillAttribute; - /* 0000002C */ DWORD dwFlags; - /* 00000030 */ WORD wShowWindow; - /* 00000032 */ WORD cbReserved2; - /* 00000034 */ LPBYTE lpReserved2; - /* 00000038 */ HANDLE hStdInput; - /* 0000003C */ HANDLE hStdOutput; - /* 00000040 */ HANDLE hStdError; - } STARTUPINFOA, *LPSTARTUPINFOA; - - """ - # TODO: fill with relevant values - # for now, struct is just a placeholder - cb = 0x0 - lpReserved = 0x0 - lpDesktop = 0x0 - lpTitle = 0x0 - dwX = 0x0 - dwY = 0x0 - dwXSize = 0x0 - dwYSize = 0x0 - dwXCountChars = 0x0 - dwYCountChars = 0x0 - dwFillAttribute = 0x0 - dwFlags = 0x0 - wShowWindow = 0x0 - cbReserved2 = 0x0 - lpReserved2 = 0x0 - hStdInput = 0x0 - hStdOutput = 0x0 - hStdError = 0x0 - - def pack(self): - return struct.pack('IIIIIIIIIIIIHHIIII', - self.cb, - self.lpReserved, - self.lpDesktop, - self.lpTitle, - self.dwX, - self.dwY, - self.dwXSize, - self.dwYSize, - self.dwXCountChars, - self.dwYCountChars, - self.dwFillAttribute, - self.dwFlags, - self.wShowWindow, - self.cbReserved2, - self.lpReserved2, - self.hStdInput, - self.hStdOutput, - self.hStdError) - - -def kernel32_GetStartupInfo(jitter, funcname, set_str): - """ - void GetStartupInfo( - LPSTARTUPINFOW lpStartupInfo - ); - - Retrieves the contents of the STARTUPINFO structure that was specified - when the calling process was created. - - https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getstartupinfow - - """ - ret_ad, args = jitter.func_args_stdcall(["ptr"]) - jitter.vm.set_mem(args.ptr, startupinfo().pack()) - jitter.func_ret_stdcall(ret_ad, args.ptr) - - -def kernel32_GetStartupInfoA(jitter): - kernel32_GetStartupInfo(jitter, whoami(), lambda addr,value: set_win_str_a(jitter, addr, value)) - - -def kernel32_GetStartupInfoW(jitter): - kernel32_GetStartupInfo(jitter, whoami(), lambda addr,value: set_win_str_w(jitter, addr, value)) - - -def kernel32_GetCurrentThreadId(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, 0x113377) - - -def kernel32_InitializeCriticalSection(jitter): - ret_ad, _ = jitter.func_args_stdcall(["lpcritic"]) - jitter.func_ret_stdcall(ret_ad, 0) - - -def user32_GetSystemMetrics(jitter): - ret_ad, args = jitter.func_args_stdcall(["nindex"]) - - ret = 0 - if args.nindex in [0x2a, 0x4a]: - ret = 0 - else: - raise ValueError('unimpl index') - jitter.func_ret_stdcall(ret_ad, ret) - - -def wsock32_WSAStartup(jitter): - ret_ad, args = jitter.func_args_stdcall(["version", "pwsadata"]) - jitter.vm.set_mem(args.pwsadata, b"\x01\x01\x02\x02WinSock 2.0\x00") - jitter.func_ret_stdcall(ret_ad, 0) - - -def get_current_filetime(): - """ - Get current filetime - https://msdn.microsoft.com/en-us/library/ms724228 - """ - curtime = winobjs.current_datetime - unixtime = int(time.mktime(curtime.timetuple())) - filetime = (int(unixtime * 1000000 + curtime.microsecond) * 10 + - DATE_1601_TO_1970) - return filetime - - -def unixtime_to_filetime(unixtime): - """ - Convert unixtime to filetime - https://msdn.microsoft.com/en-us/library/ms724228 - """ - return (unixtime * 10000000) + DATE_1601_TO_1970 - - -def filetime_to_unixtime(filetime): - """ - Convert filetime to unixtime - # https://msdn.microsoft.com/en-us/library/ms724228 - """ - return int((filetime - DATE_1601_TO_1970) // 10000000) - - -def datetime_to_systemtime(curtime): - - s = struct.pack('HHHHHHHH', - curtime.year, # year - curtime.month, # month - curtime.weekday(), # dayofweek - curtime.day, # day - curtime.hour, # hour - curtime.minute , # minutes - curtime.second, # seconds - int(curtime.microsecond // 1000), # millisec - ) - return s - - -def kernel32_GetSystemTimeAsFileTime(jitter): - ret_ad, args = jitter.func_args_stdcall(["lpSystemTimeAsFileTime"]) - - current_filetime = get_current_filetime() - filetime = struct.pack('II', - current_filetime & 0xffffffff, - (current_filetime>>32) & 0xffffffff) - - jitter.vm.set_mem(args.lpSystemTimeAsFileTime, filetime) - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_GetLocalTime(jitter): - ret_ad, args = jitter.func_args_stdcall(["lpsystemtime"]) - systemtime = datetime_to_systemtime(winobjs.current_datetime) - jitter.vm.set_mem(args.lpsystemtime, systemtime) - jitter.func_ret_stdcall(ret_ad, args.lpsystemtime) - - -def kernel32_GetSystemTime(jitter): - ret_ad, args = jitter.func_args_stdcall(["lpsystemtime"]) - systemtime = datetime_to_systemtime(winobjs.current_datetime) - jitter.vm.set_mem(args.lpsystemtime, systemtime) - jitter.func_ret_stdcall(ret_ad, args.lpsystemtime) - - -def kernel32_CreateFileMapping(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["hfile", "lpattr", "flprotect", - "dwmaximumsizehigh", - "dwmaximumsizelow", "lpname"]) - - if args.hfile == 0xffffffff: - # Create null mapping - if args.dwmaximumsizehigh: - raise NotImplementedError("Untested case") - hmap = StringIO("\x00" * args.dwmaximumsizelow) - hmap_handle = winobjs.handle_pool.add('filemem', hmap) - - ret = winobjs.handle_pool.add('filemapping', hmap_handle) - else: - if not args.hfile in winobjs.handle_pool: - raise ValueError('unknown handle') - ret = winobjs.handle_pool.add('filemapping', args.hfile) - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_CreateFileMappingA(jitter): - kernel32_CreateFileMapping(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def kernel32_CreateFileMappingW(jitter): - kernel32_CreateFileMapping(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def kernel32_MapViewOfFile(jitter): - ret_ad, args = jitter.func_args_stdcall(["hfile", "flprotect", - "dwfileoffsethigh", - "dwfileoffsetlow", - "length"]) - - if not args.hfile in winobjs.handle_pool: - raise ValueError('unknown handle') - hmap = winobjs.handle_pool[args.hfile] - if not hmap.info in winobjs.handle_pool: - raise ValueError('unknown file handle') - - hfile_o = winobjs.handle_pool[hmap.info] - fd = hfile_o.info - fd.seek((args.dwfileoffsethigh << 32) | args.dwfileoffsetlow) - data = fd.read(args.length) if args.length else fd.read() - length = len(data) - - log.debug('MapViewOfFile len: %x', len(data)) - - if not args.flprotect in ACCESS_DICT: - raise ValueError('unknown access dw!') - - alloc_addr = winobjs.heap.alloc(jitter, len(data)) - jitter.vm.set_mem(alloc_addr, data) - - winobjs.handle_mapped[alloc_addr] = (hfile_o, args.dwfileoffsethigh, - args.dwfileoffsetlow, length) - - jitter.func_ret_stdcall(ret_ad, alloc_addr) - - -def kernel32_UnmapViewOfFile(jitter): - ret_ad, args = jitter.func_args_stdcall(['ad']) - - if not args.ad in winobjs.handle_mapped: - raise NotImplementedError("Untested case") - """ - hfile_o, dwfileoffsethigh, dwfileoffsetlow, length = winobjs.handle_mapped[ad] - off = (dwfileoffsethigh<<32) | dwfileoffsetlow - s = jitter.vm.get_mem(ad, length) - hfile_o.info.seek(off) - hfile_o.info.write(s) - hfile_o.info.close() - """ - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_GetDriveType(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(['pathname']) - - p = get_str(args.pathname) - p = p.upper() - - log.debug('Drive: %r', p) - - ret = 0 - if p[0] == "C": - ret = 3 - - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_GetDriveTypeA(jitter): - kernel32_GetDriveType(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def kernel32_GetDriveTypeW(jitter): - kernel32_GetDriveType(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def kernel32_GetDiskFreeSpace(jitter, funcname, get_str): - ret_ad, args = jitter.func_args_stdcall(["lprootpathname", - "lpsectorpercluster", - "lpbytespersector", - "lpnumberoffreeclusters", - "lptotalnumberofclusters"]) - jitter.vm.set_u32(args.lpsectorpercluster, 8) - jitter.vm.set_u32(args.lpbytespersector, 0x200) - jitter.vm.set_u32(args.lpnumberoffreeclusters, 0x222222) - jitter.vm.set_u32(args.lptotalnumberofclusters, 0x333333) - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_GetDiskFreeSpaceA(jitter): - kernel32_GetDiskFreeSpace(jitter, whoami(), lambda addr:get_win_str_a(jitter, addr)) - - -def kernel32_GetDiskFreeSpaceW(jitter): - kernel32_GetDiskFreeSpace(jitter, whoami(), lambda addr:get_win_str_w(jitter, addr)) - - -def kernel32_VirtualQuery(jitter): - ret_ad, args = jitter.func_args_stdcall(["ad", "lpbuffer", "dwl"]) - - all_mem = jitter.vm.get_all_memory() - found = None - for basead, m in viewitems(all_mem): - if basead <= args.ad < basead + m['size']: - found = args.ad, m - break - if not found: - raise ValueError('cannot find mem', hex(args.ad)) - - if args.dwl != 0x1c: - raise ValueError('strange mem len', hex(args.dwl)) - s = struct.pack('IIIIIII', - args.ad, - basead, - ACCESS_DICT_INV[m['access']], - m['size'], - 0x1000, - ACCESS_DICT_INV[m['access']], - 0x01000000) - jitter.vm.set_mem(args.lpbuffer, s) - jitter.func_ret_stdcall(ret_ad, args.dwl) - - -def kernel32_GetProcessAffinityMask(jitter): - ret_ad, args = jitter.func_args_stdcall(["hprocess", - "procaffmask", - "systemaffmask"]) - jitter.vm.set_u32(args.procaffmask, 1) - jitter.vm.set_u32(args.systemaffmask, 1) - jitter.func_ret_stdcall(ret_ad, 1) - - -def msvcrt_rand(jitter): - ret_ad, _ = jitter.func_args_cdecl(0) - jitter.func_ret_stdcall(ret_ad, 0x666) - -def msvcrt_srand(jitter): - ret_ad, _ = jitter.func_args_cdecl(['seed']) - jitter.func_ret_stdcall(ret_ad, 0) - -def msvcrt_wcslen(jitter): - ret_ad, args = jitter.func_args_cdecl(["pwstr"]) - s = get_win_str_w(jitter, args.pwstr) - jitter.func_ret_cdecl(ret_ad, len(s)) - -def kernel32_SetFilePointer(jitter): - ret_ad, args = jitter.func_args_stdcall(["hwnd", "dinstance", - "p_dinstance_high", - "movemethod"]) - - if args.hwnd == winobjs.module_cur_hwnd: - pass - elif args.hwnd in winobjs.handle_pool: - pass - else: - raise ValueError('unknown hwnd!') - - # data = None - if args.hwnd in winobjs.files_hwnd: - winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(args.dinstance, args.movemethod) - elif args.hwnd in winobjs.handle_pool: - wh = winobjs.handle_pool[args.hwnd] - wh.info.seek(args.dinstance, args.movemethod) - else: - raise ValueError('unknown filename') - jitter.func_ret_stdcall(ret_ad, args.dinstance) - - -def kernel32_SetFilePointerEx(jitter): - ret_ad, args = jitter.func_args_stdcall(["hwnd", "dinstance_l", - "dinstance_h", - "pnewfileptr", - "movemethod"]) - dinstance = args.dinstance_l | (args.dinstance_h << 32) - if dinstance: - raise ValueError('Not implemented') - if args.pnewfileptr: - raise ValueError('Not implemented') - if args.hwnd == winobjs.module_cur_hwnd: - pass - elif args.hwnd in winobjs.handle_pool: - pass - else: - raise ValueError('unknown hwnd!') - - # data = None - if args.hwnd in winobjs.files_hwnd: - winobjs.files_hwnd[winobjs.module_cur_hwnd].seek(dinstance, args.movemethod) - elif args.hwnd in winobjs.handle_pool: - wh = winobjs.handle_pool[args.hwnd] - wh.info.seek(dinstance, args.movemethod) - else: - raise ValueError('unknown filename') - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_SetEndOfFile(jitter): - ret_ad, args = jitter.func_args_stdcall(['hwnd']) - if args.hwnd in winobjs.handle_pool: - wh = winobjs.handle_pool[args.hwnd] - wh.info.seek(0, 2) - else: - raise ValueError('unknown filename') - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_FlushFileBuffers(jitter): - ret_ad, args = jitter.func_args_stdcall(['hwnd']) - if args.hwnd in winobjs.handle_pool: - pass - else: - raise ValueError('unknown filename') - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_WriteFile(jitter): - ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpbuffer", - "nnumberofbytestowrite", - "lpnumberofbyteswrite", - "lpoverlapped"]) - data = jitter.vm.get_mem(args.lpbuffer, args.nnumberofbytestowrite) - - if args.hwnd == winobjs.module_cur_hwnd: - pass - elif args.hwnd in winobjs.handle_pool: - pass - else: - raise ValueError('unknown hwnd!') - - if args.hwnd in winobjs.files_hwnd: - winobjs.files_hwnd[winobjs.module_cur_hwnd].write(data) - elif args.hwnd in winobjs.handle_pool: - wh = winobjs.handle_pool[args.hwnd] - wh.info.write(data) - else: - raise ValueError('unknown filename') - - if (args.lpnumberofbyteswrite): - jitter.vm.set_u32(args.lpnumberofbyteswrite, len(data)) - - jitter.func_ret_stdcall(ret_ad, 1) - - -def user32_IsCharUpperA(jitter): - ret_ad, args = jitter.func_args_stdcall(["c"]) - ret = 0 if args.c & 0x20 else 1 - jitter.func_ret_stdcall(ret_ad, ret) - - -def user32_IsCharLowerA(jitter): - ret_ad, args = jitter.func_args_stdcall(["c"]) - ret = 1 if args.c & 0x20 else 0 - jitter.func_ret_stdcall(ret_ad, ret) - - -def kernel32_GetSystemDefaultLangID(jitter): - ret_ad, _ = jitter.func_args_stdcall(0) - jitter.func_ret_stdcall(ret_ad, 0x409) # encglish - - -def msvcrt_malloc(jitter): - ret_ad, args = jitter.func_args_cdecl(["msize"]) - addr = winobjs.heap.alloc(jitter, args.msize) - jitter.func_ret_cdecl(ret_ad, addr) - - -def msvcrt_free(jitter): - ret_ad, _ = jitter.func_args_cdecl(["ptr"]) - jitter.func_ret_cdecl(ret_ad, 0) - - -def msvcrt_fseek(jitter): - ret_ad, args = jitter.func_args_cdecl(['stream', 'offset', 'orig']) - fd = jitter.vm.get_u32(args.stream + 0x10) - - if not fd in winobjs.handle_pool: - raise NotImplementedError("Untested case") - o = winobjs.handle_pool[fd] - o.info.seek(args.offset, args.orig) - jitter.func_ret_cdecl(ret_ad, 0) - - -def msvcrt_ftell(jitter): - ret_ad, args = jitter.func_args_cdecl(["stream"]) - fd = jitter.vm.get_u32(args.stream + 0x10) - - if not fd in winobjs.handle_pool: - raise NotImplementedError("Untested case") - o = winobjs.handle_pool[fd] - off = o.info.tell() - jitter.func_ret_cdecl(ret_ad, off) - - -def msvcrt_rewind(jitter): - ret_ad, args = jitter.func_args_cdecl(["stream"]) - fd = jitter.vm.get_u32(args.stream + 0x10) - if not fd in winobjs.handle_pool: - raise NotImplementedError("Untested case") - o = winobjs.handle_pool[fd] - # off = o.info.seek(0, 0) - jitter.func_ret_cdecl(ret_ad, 0) - - -def msvcrt_fread(jitter): - ret_ad, args = jitter.func_args_cdecl(["buf", "size", "nmemb", "stream"]) - fd = jitter.vm.get_u32(args.stream + 0x10) - if not fd in winobjs.handle_pool: - raise NotImplementedError("Untested case") - - data = winobjs.handle_pool[fd].info.read(args.size * args.nmemb) - jitter.vm.set_mem(args.buf, data) - jitter.func_ret_cdecl(ret_ad, args.nmemb) - - -def msvcrt_fwrite(jitter): - ret_ad, args = jitter.func_args_cdecl(["buf", "size", "nmemb", "stream"]) - fd = jitter.vm.get_u32(args.stream + 0x10) - if not fd in winobjs.handle_pool: - raise NotImplementedError("Unknown file handle!") - - data = jitter.vm.get_mem(args.buf, args.size*args.nmemb) - winobjs.handle_pool[fd].info.write(data) - jitter.func_ret_cdecl(ret_ad, args.nmemb) - - -def msvcrt_fclose(jitter): - ret_ad, args = jitter.func_args_cdecl(['stream']) - fd = jitter.vm.get_u32(args.stream + 0x10) - - if not fd in winobjs.handle_pool: - raise NotImplementedError("Untested case") - o = winobjs.handle_pool[fd] - # off = o.info.close() - jitter.func_ret_cdecl(ret_ad, 0) - - -def msvcrt_atexit(jitter): - ret_ad, _ = jitter.func_args_cdecl(["func"]) - jitter.func_ret_cdecl(ret_ad, 0) - - -def user32_MessageBoxA(jitter): - ret_ad, args = jitter.func_args_stdcall(["hwnd", "lptext", - "lpcaption", "utype"]) - - text = get_win_str_a(jitter, args.lptext) - caption = get_win_str_a(jitter, args.lpcaption) - - log.info('Caption: %r Text: %r', caption, text) - - jitter.func_ret_stdcall(ret_ad, 0) - - -def kernel32_myGetTempPath(jitter, set_str): - ret_ad, args = jitter.func_args_stdcall(["l", "buf"]) - l = 'c:\\temp\\' - if len(l) < args.l: - set_str(args.buf, l) - jitter.func_ret_stdcall(ret_ad, len(l)) - - -def kernel32_GetTempPathA(jitter): - kernel32_myGetTempPath(jitter, lambda addr,value: set_win_str_a(jitter, addr, value)) - - -def kernel32_GetTempPathW(jitter): - kernel32_myGetTempPath(jitter, lambda addr,value: set_win_str_w(jitter, addr, value)) - - -temp_num = 0 - - -def kernel32_GetTempFileNameA(jitter): - global temp_num - ret_ad, args = jitter.func_args_stdcall(["path", "ext", "unique", "buf"]) - - temp_num += 1 - ext = get_win_str_a(jitter, args.ext) if args.ext else 'tmp' - path = get_win_str_a(jitter, args.path) if args.path else "xxx" - fname = path + "\\" + "temp%.4d" % temp_num + "." + ext - jitter.vm.set_mem(args.buf, fname.encode('utf-8')) - - jitter.func_ret_stdcall(ret_ad, 0) - - -class win32_find_data(object): - fileattrib = 0 - creationtime = 0 - lastaccesstime = 0 - lastwritetime = 0 - filesizehigh = 0 - filesizelow = 0 - dwreserved0 = 0 - dwreserved1 = 0x1337beef - cfilename = "" - alternamefilename = "" - - def __init__(self, **kargs): - for k, v in viewitems(kargs): - setattr(self, k, v) - - def toStruct(self, encode_str=encode_win_str_w): - s = struct.pack('=IQQQIIII', - self.fileattrib, - self.creationtime, - self.lastaccesstime, - self.lastwritetime, - self.filesizehigh, - self.filesizelow, - self.dwreserved0, - self.dwreserved1) - fname = encode_str(self.cfilename) + b'\x00' * MAX_PATH - fname = fname[:MAX_PATH] - s += fname - fname = encode_str(self.alternamefilename) + b'\x00' * 14 - fname = fname[:14] - s += fname - return s - - -class find_data_mngr(object): - - def __init__(self): - self.patterns = {} - self.flist = [] - # handle number -> (flist index, current index in list) - self.handles = {} - - def add_list(self, pattern, flist): - index = len(self.flist) - self.flist.append(flist) - - self.patterns[pattern] = index - - def findfirst(self, pattern): - assert(pattern in self.patterns) - findex = self.patterns[pattern] - h = len(self.handles) + 1 - self.handles[h] = [findex, 0] - return h - - def findnext(self, h): - assert(h in self.handles) - findex, index = self.handles[h] - if index >= len(self.flist[findex]): - return None - fname = self.flist[findex][index] - self.handles[h][1] += 1 - - return fname - -def my_FindFirstFile(jitter, pfilepattern, pfindfiledata, get_win_str, encode_str): - filepattern = get_win_str(jitter, pfilepattern) - h = winobjs.find_data.findfirst(filepattern) - - fname = winobjs.find_data.findnext(h) - fdata = win32_find_data(cfilename=fname) - - jitter.vm.set_mem(pfindfiledata, fdata.toStruct(encode_str=encode_str)) - return h - -def kernel32_FindFirstFileA(jitter): - ret_ad, args = jitter.func_args_stdcall(["pfilepattern", "pfindfiledata"]) - h = my_FindFirstFile(jitter, args.pfilepattern, args.pfindfiledata, - get_win_str_a, encode_win_str_a) - jitter.func_ret_stdcall(ret_ad, h) - -def kernel32_FindFirstFileW(jitter): - ret_ad, args = jitter.func_args_stdcall(["pfilepattern", "pfindfiledata"]) - h = my_FindFirstFile(jitter, args.pfilepattern, args.pfindfiledata, - get_win_str_w, encode_win_str_w) - jitter.func_ret_stdcall(ret_ad, h) - -def kernel32_FindFirstFileExA(jitter): - ret_ad, args = jitter.func_args_stdcall([ - "lpFileName", - "fInfoLevelId", - "lpFindFileData", - "fSearchOp", - "lpSearchFilter", - "dwAdditionalFlags"]) - h = my_FindFirstFile(jitter, args.lpFileName, args.lpFindFileData, - get_win_str_a, encode_win_str_a) - jitter.func_ret_stdcall(ret_ad, h) - -def kernel32_FindFirstFileExW(jitter): - ret_ad, args = jitter.func_args_stdcall([ - "lpFileName", - "fInfoLevelId", - "lpFindFileData", - "fSearchOp", - "lpSearchFilter", - "dwAdditionalFlags"]) - h = my_FindFirstFile(jitter, args.lpFileName, args.lpFindFileData, - get_win_str_w, encode_win_str_w) - jitter.func_ret_stdcall(ret_ad, h) - -def my_FindNextFile(jitter, encode_str): - ret_ad, args = jitter.func_args_stdcall(["handle", "pfindfiledata"]) - fname = winobjs.find_data.findnext(args.handle) - if fname is None: - winobjs.lastwin32error = 0x12 # ERROR_NO_MORE_FILES - ret = 0 - else: - ret = 1 - fdata = win32_find_data(cfilename=fname) - jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct(encode_str=encode_str)) - jitter.func_ret_stdcall(ret_ad, ret) - -kernel32_FindNextFileA = lambda jitter: my_FindNextFile(jitter, encode_win_str_a) -kernel32_FindNextFileW = lambda jitter: my_FindNextFile(jitter, encode_win_str_w) - -def kernel32_GetNativeSystemInfo(jitter): - ret_ad, args = jitter.func_args_stdcall(["sys_ptr"]) - sysinfo = systeminfo() - jitter.vm.set_mem(args.sys_ptr, sysinfo.pack()) - jitter.func_ret_stdcall(ret_ad, 0) - - -def raw2guid(r): - o = struct.unpack('IHHHBBBBBB', r) - return '{%.8X-%.4X-%.4X-%.4X-%.2X%.2X%.2X%.2X%.2X%.2X}' % o - - -digs = string.digits + string.ascii_lowercase - - -def int2base(x, base): - if x < 0: - sign = -1 - elif x == 0: - return '0' - else: - sign = 1 - x *= sign - digits = [] - while x: - digits.append(digs[x % base]) - x /= base - if sign < 0: - digits.append('-') - digits.reverse() - return ''.join(digits) - - -def msvcrt__ultow(jitter): - ret_ad, args = jitter.func_args_cdecl(["value", "p", "radix"]) - - value = args.value & 0xFFFFFFFF - if not args.radix in [10, 16, 20]: - raise ValueError("Not tested") - s = int2base(value, args.radix) - set_win_str_w(jitter, args.p, s) - jitter.func_ret_cdecl(ret_ad, args.p) - - -def msvcrt_myfopen(jitter, get_str): - ret_ad, args = jitter.func_args_cdecl(["pfname", "pmode"]) - - fname = get_str(args.pfname) - rw = get_str(args.pmode) - log.info("fopen %r, %r", fname, rw) - - if rw in ['r', 'rb', 'wb+','wb','wt']: - sb_fname = windows_to_sbpath(fname) - h = open(sb_fname, rw) - eax = winobjs.handle_pool.add(sb_fname, h) - dwsize = 0x20 - alloc_addr = winobjs.heap.alloc(jitter, dwsize) - pp = pck32(0x11112222) + pck32(0) + pck32(0) + pck32(0) + pck32(eax) - jitter.vm.set_mem(alloc_addr, pp) - - else: - raise ValueError('unknown access mode %s' % rw) - - jitter.func_ret_cdecl(ret_ad, alloc_addr) - - -def msvcrt__wfopen(jitter): - msvcrt_myfopen(jitter, lambda addr:get_win_str_w(jitter, addr)) - - -def msvcrt_fopen(jitter): - msvcrt_myfopen(jitter, lambda addr:get_win_str_a(jitter, addr)) - - -def msvcrt_strlen(jitter): - ret_ad, args = jitter.func_args_cdecl(["src"]) - - s = get_win_str_a(jitter, args.src) - jitter.func_ret_cdecl(ret_ad, len(s)) - - -def kernel32_QueryPerformanceCounter(jitter): - ret_ad, args = jitter.func_args_stdcall(["lpPerformanceCount"]) - jitter.vm.set_mem(args.lpPerformanceCount, struct.pack('<Q', 0x1)) - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_InitializeCriticalSectionEx(jitter): - ''' - LPCRITICAL_SECTION lpCriticalSection, - DWORD dwSpinCount, - DWORD Flags - ''' - ret_ad, args = jitter.func_args_stdcall(["lpCriticalSection", "dwSpinCount", "Flags"]) - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_EnterCriticalSection(jitter): - ''' - void EnterCriticalSection( - LPCRITICAL_SECTION lpCriticalSection - ); - ''' - ret_ad, args = jitter.func_args_stdcall(["lpCriticalSection"]) - jitter.func_ret_stdcall(ret_ad, 0x0) - - -def kernel32_LeaveCriticalSection(jitter): - ''' - void LeaveCriticalSection( - LPCRITICAL_SECTION lpCriticalSection - ); - ''' - ret_ad, args = jitter.func_args_stdcall(["lpCriticalSection"]) - jitter.func_ret_stdcall(ret_ad, 0x0) - - -class FLS(object): - def __init__(self): - self.slots = [] - - def kernel32_FlsAlloc(self, jitter): - ''' - DWORD FlsAlloc( - PFLS_CALLBACK_FUNCTION lpCallback - ); - ''' - ret_ad, args = jitter.func_args_stdcall(["lpCallback"]) - index = len(self.slots) - self.slots.append(0x0) - jitter.func_ret_stdcall(ret_ad, index) - - def kernel32_FlsSetValue(self, jitter): - ''' - BOOL FlsSetValue( - DWORD dwFlsIndex, - PVOID lpFlsData - ); - ''' - ret_ad, args = jitter.func_args_stdcall(["dwFlsIndex", "lpFlsData"]) - self.slots[args.dwFlsIndex] = args.lpFlsData - jitter.func_ret_stdcall(ret_ad, 1) - - def kernel32_FlsGetValue(self, jitter): - ''' - PVOID FlsGetValue( - DWORD dwFlsIndex - ); - ''' - ret_ad, args = jitter.func_args_stdcall(["dwFlsIndex"]) - jitter.func_ret_stdcall(ret_ad, self.slots[args.dwFlsIndex]) - -fls = FLS() - - -def kernel32_GetProcessHeap(jitter): - ''' - HANDLE GetProcessHeap(); - ''' - ret_ad, args = jitter.func_args_stdcall([]) - hHeap = 0x67676767 - jitter.func_ret_stdcall(ret_ad, hHeap) - - -STD_INPUT_HANDLE = 0xfffffff6 -STD_OUTPUT_HANDLE = 0xfffffff5 -STD_ERROR_HANDLE = 0xfffffff4 - - -def kernel32_GetStdHandle(jitter): - ''' - HANDLE WINAPI GetStdHandle( - _In_ DWORD nStdHandle - ); - - STD_INPUT_HANDLE (DWORD)-10 - The standard input device. Initially, this is the console input buffer, CONIN$. - - STD_OUTPUT_HANDLE (DWORD)-11 - The standard output device. Initially, this is the active console screen buffer, CONOUT$. - - STD_ERROR_HANDLE (DWORD)-12 - The standard error device. Initially, this is the active console screen buffer, CONOUT$. - ''' - ret_ad, args = jitter.func_args_stdcall(["nStdHandle"]) - jitter.func_ret_stdcall(ret_ad, { - STD_OUTPUT_HANDLE: 1, - STD_ERROR_HANDLE: 2, - STD_INPUT_HANDLE: 3, - }[args.nStdHandle]) - - -FILE_TYPE_UNKNOWN = 0x0000 -FILE_TYPE_CHAR = 0x0002 - - -def kernel32_GetFileType(jitter): - ''' - DWORD GetFileType( - HANDLE hFile - ); - ''' - ret_ad, args = jitter.func_args_stdcall(["hFile"]) - jitter.func_ret_stdcall(ret_ad, { - # STD_OUTPUT_HANDLE - 1: FILE_TYPE_CHAR, - # STD_ERROR_HANDLE - 2: FILE_TYPE_CHAR, - # STD_INPUT_HANDLE - 3: FILE_TYPE_CHAR, - }.get(args.hFile, FILE_TYPE_UNKNOWN)) - - -def kernel32_IsProcessorFeaturePresent(jitter): - ''' - BOOL IsProcessorFeaturePresent( - DWORD ProcessorFeature - ); - ''' - ret_ad, args = jitter.func_args_stdcall(["ProcessorFeature"]) - jitter.func_ret_stdcall(ret_ad, { - # PF_ARM_64BIT_LOADSTORE_ATOMIC - 25: False, - # PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE - 24: False, - # PF_ARM_EXTERNAL_CACHE_AVAILABLE - 26: False, - # PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE - 27: False, - # PF_ARM_VFP_32_REGISTERS_AVAILABLE - 18: False, - # PF_3DNOW_INSTRUCTIONS_AVAILABLE - 7: False, - # PF_CHANNELS_ENABLED - 16: True, - # PF_COMPARE_EXCHANGE_DOUBLE - 2: False, - # PF_COMPARE_EXCHANGE128 - 14: False, - # PF_COMPARE64_EXCHANGE128 - 15: False, - # PF_FASTFAIL_AVAILABLE - 23: False, - # PF_FLOATING_POINT_EMULATED - 1: False, - # PF_FLOATING_POINT_PRECISION_ERRATA - 0: True, - # PF_MMX_INSTRUCTIONS_AVAILABLE - 3: True, - # PF_NX_ENABLED - 12: True, - # PF_PAE_ENABLED - 9: True, - # PF_RDTSC_INSTRUCTION_AVAILABLE - 8: True, - # PF_RDWRFSGSBASE_AVAILABLE - 22: True, - # PF_SECOND_LEVEL_ADDRESS_TRANSLATION - 20: True, - # PF_SSE3_INSTRUCTIONS_AVAILABLE - 13: True, - # PF_VIRT_FIRMWARE_ENABLED - 21: False, - # PF_XMMI_INSTRUCTIONS_AVAILABLE - 6: True, - # PF_XMMI64_INSTRUCTIONS_AVAILABLE - 10: True, - # PF_XSAVE_ENABLED - 17: False, - }[args.ProcessorFeature]) - - -def kernel32_GetACP(jitter): - ''' - UINT GetACP(); - ''' - ret_ad, args = jitter.func_args_stdcall([]) - # Windows-1252: Latin 1 / Western European Superset of ISO-8859-1 (without C1 controls). - jitter.func_ret_stdcall(ret_ad, 1252) - - -# ref: https://docs.microsoft.com/en-us/windows/win32/intl/code-page-identifiers -VALID_CODE_PAGES = { - 37,437,500,708,709,710,720,737,775,850,852,855,857,858,860,861,862,863,864,865,866,869,870,874,875, - 932,936,949,950,1026,1047,1140,1141,1142,1143,1144,1145,1146,1147,1148,1149,1200,1201,1250,1251,1252, - 1253,1254,1255,1256,1257,1258,1361,10000,10001,10002,10003,10004,10005,10006,10007,10008,10010,10017, - 10021,10029,10079,10081,10082,12000,12001,20000,20001,20002,20003,20004,20005,20105,20106,20107,20108, - 20127,20261,20269,20273,20277,20278,20280,20284,20285,20290,20297,20420,20423,20424,20833,20838,20866, - 20871,20880,20905,20924,20932,20936,20949,21025,21027,21866,28591,28592,28593,28594,28595,28596,28597, - 28598,28599,28603,28605,29001,38598,50220,50221,50222,50225,50227,50229,50930,50931,50933,50935,50936, - 50937,50939,51932,51936,51949,51950,52936,54936,57002,57003,57004,57005,57006,57007,57008,57009,57010, - 57011,65000,65001 -} - - -def kernel32_IsValidCodePage(jitter): - ''' - BOOL IsValidCodePage( - UINT CodePage - ); - ''' - ret_ad, args = jitter.func_args_stdcall(["CodePage"]) - jitter.func_ret_stdcall(ret_ad, args.CodePage in VALID_CODE_PAGES) - - -def kernel32_GetCPInfo(jitter): - ''' - BOOL GetCPInfo( - UINT CodePage, - LPCPINFO lpCPInfo - ); - ''' - ret_ad, args = jitter.func_args_stdcall(["CodePage", "lpCPInfo"]) - assert args.CodePage == 1252 - # ref: http://www.rensselaer.org/dept/cis/software/g77-mingw32/include/winnls.h - #define MAX_LEADBYTES 12 - #define MAX_DEFAULTCHAR 2 - jitter.vm.set_mem(args.lpCPInfo, struct.pack('<I', 0x1) + b'??' + b'\x00' * 12) - jitter.func_ret_stdcall(ret_ad, 1) - - -def kernel32_GetStringTypeW(jitter): - """ - BOOL GetStringTypeW( - DWORD dwInfoType, - _In_NLS_string_(cchSrc)LPCWCH lpSrcStr, - int cchSrc, - LPWORD lpCharType - ); - - Retrieves character type information for the characters in the specified - Unicode source string. For each character in the string, the function - sets one or more bits in the corresponding 16-bit element of the output - array. Each bit identifies a given character type, for example, letter, - digit, or neither. - - """ - # These types support ANSI C and POSIX (LC_CTYPE) character typing - # functions.A bitwise-OR of these values is retrieved in the array in the - # output buffer when dwInfoType is set to CT_CTYPE1. For DBCS locales, the - # type attributes apply to both narrow characters and wide characters. The - # Japanese hiragana and katakana characters, and the kanji ideograph - # characters all have the C1_ALPHA attribute. - CT_TYPE1 = 0x01 - # TODO handle other types of information - # (CT_TYPE2, CT_TYPE3) - # for now, they raise NotImplemented - CT_TYPE2 = 0x02 - CT_TYPE3 = 0x03 - - C1_UPPER = 0x0001 # Uppercase - C1_LOWER = 0x0002 # Lowercase - C1_DIGIT = 0x0004 # Decimal digits - C1_SPACE = 0x0008 # Space characters - C1_PUNCT = 0x0010 # Punctuation - C1_CNTRL = 0x0020 # Control characters - C1_BLANK = 0x0040 # Blank characters - C1_XDIGIT = 0x0080 # Hexadecimal digits - C1_ALPHA = 0x0100 # Any linguistic character: alphabetical, syllabary, or ideographic - C1_DEFINED = 0x0200 # A defined character, but not one of the other C1_* types - - # the following sets have been generated from the Linux python library curses - # e.g., C1_PUNCT_SET = [chr(i) for i in range(256) if curses.ascii.ispunct(chr(i))] - C1_PUNCT_SET = ['!', '"', '#', '$', '%', '&', "'", '(', ')', '*', '+', ',', - '-', '.', '/', ':', ';', '<', '=', '>', '?', '@', '[', '\\', ']', - '^', '_', '`', '{', '|', '}', '~'] - C1_CNTRL_SET = ['\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', - '\x07', '\x08', '\t', '\n', '\x0b', '\x0c', '\r', '\x0e', '\x0f', - '\x10', '\x11', '\x12', '\x13', '\x14', '\x15', '\x16', '\x17', - '\x18', '\x19', '\x1a', '\x1b', '\x1c', '\x1d', '\x1e', '\x1f', - '\x7f'] - C1_BLANK_SET = ['\t', ' '] - C1_XDIGIT_SET = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', - 'B', 'C', 'D', 'E', 'F', 'a', 'b', 'c', 'd', 'e', 'f'] - - ret, args = jitter.func_args_stdcall(['dwInfoType', 'lpSrcStr', 'cchSrc', - 'lpCharType']) - s = jitter.vm.get_mem(args.lpSrcStr, args.cchSrc).decode("utf-16") - if args.dwInfoType == CT_TYPE1: - # iterate over characters from the decoded W string - for i, c in enumerate(s): - # TODO handle non-ascii characters - if not c.isascii(): - continue - val = 0 - if c.isupper(): - val |= C1_UPPER - if c.islower(): - val |= C1_LOWER - if c.isdigit(): - val |= C1_DIGIT - if c.isspace(): - val |= C1_SPACE - if c in C1_PUNCT_SET: - val |= C1_PUNCT - if c in C1_CNTRL_SET: - val |= C1_CNTRL - if c in C1_BLANK_SET: - val |= C1_BLANK - if c in C1_XDIGIT_SET: - val |= C1_XDIGIT - if c.isalpha(): - val |= C1_ALPHA - if val == 0: - val = C1_DEFINED - jitter.vm.set_u16(args.lpCharType + i * 2, val) - elif args.dwInfoType == CT_TYPE2: - raise NotImplemented - elif args.dwInfoType == CT_TYPE3: - raise NotImplemented - else: - raise ValueError("CT_TYPE unknown: %i" % args.dwInfoType) - jitter.func_ret_stdcall(ret, 1) - return True |