miasm2.os_dep.win_api_x86_32 module
# # Copyright (C) 2011 EADS France, Fabrice Desclaux <fabrice.desclaux@eads.net> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. # import struct import os import stat import time import string import logging from zlib import crc32 from StringIO import StringIO import time import datetime try: from Crypto.Hash import MD5, SHA except ImportError: print "cannot find crypto, skipping" from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, PAGE_EXEC from miasm2.core.utils import pck16, pck32, upck16, upck32, hexdump, whoami from miasm2.os_dep.common import heap, windows_to_sbpath from miasm2.os_dep.common import set_str_unic, set_str_ansi from miasm2.os_dep.common import get_fmt_args as _get_fmt_args from miasm2.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)-5s: %(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 ACCESS_DICT.iteritems()) class whandle(): 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(): 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 = self.all_handles.keys() 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: 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 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: "hkey_current_user", 0x80000002: "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.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: pass class mdl: def __init__(self, ad, l): self.ad = ad self.l = l def __str__(self): return struct.pack('LL', self.ad, self.l) def kernel32_HeapAlloc(jitter): ret_ad, args = jitter.func_args_stdcall(["heap", "flags", "size"]) alloc_addr = winobjs.heap.alloc(jitter, args.size) jitter.func_ret_stdcall(ret_ad, alloc_addr) def kernel32_HeapFree(jitter): ret_ad, _ = 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] 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] 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, set_str): ret_ad, args = jitter.func_args_stdcall(["ptr_struct"]) size = upck32(jitter.vm.get_mem(args.ptr_struct, 4)) 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 set_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, set_str_ansi) kernel32_GetVersionExW = lambda jitter: kernel32_GetVersionEx(jitter, 256, set_str_unic) 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 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 = jitter.get_str_ansi(args.pclassname) log.info("FindWindowA classname %s", classname) if args.pwindowname: windowname = jitter.get_str_ansi(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_mem(args.phprov, pck32(winobjs.cryptcontext_hwnd)) jitter.func_ret_stdcall(ret_ad, 1) def advapi32_CryptAcquireContextA(jitter): advapi32_CryptAcquireContext(jitter, whoami(), jitter.get_str_ansi) def advapi32_CryptAcquireContextW(jitter): advapi32_CryptAcquireContext(jitter, whoami(), jitter.get_str_unic) 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_mem( args.phhash, pck32(winobjs.cryptcontext_bnum + winobjs.cryptcontext_num) ) winobjs.cryptcontext[ winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj() winobjs.cryptcontext[ winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = MD5.new() elif args.algid == 0x00008004: log.debug('algo is SHA1') jitter.vm.set_mem( args.phhash, pck32(winobjs.cryptcontext_bnum + winobjs.cryptcontext_num) ) winobjs.cryptcontext[ winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj() winobjs.cryptcontext[ winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = 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[:10]) + "...") 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: # XXX todo: save h state? h = winobjs.cryptcontext[args.hhash].h.digest() else: raise ValueError('not impl', args.param) jitter.vm.set_mem(args.pbdata, h) jitter.vm.set_mem(args.dwdatalen, pck32(len(h))) jitter.func_ret_stdcall(ret_ad, 1) def advapi32_CryptReleaseContext(jitter): ret_ad, _ = 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_mem(args.phkey, pck32(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: # sandox path sb_fname = windows_to_sbpath(fname) if args.access & 0x80000000 or args.access == 1: # read 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: h = open(sb_fname, 'r+b') ret = winobjs.handle_pool.add(sb_fname, h) else: log.warning("FILE %r DOES NOT EXIST!", 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, 'w').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: # write 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, 'r+b') 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, 'w') 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(), jitter.get_str_ansi) def kernel32_CreateFileW(jitter): kernel32_CreateFile(jitter, whoami(), jitter.get_str_unic) 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_mem(args.lpnumberofbytesread, pck32(len(data))) jitter.vm.set_mem(args.lpbuffer, data) jitter.func_ret_stdcall(ret_ad, 1) def kernel32_GetFileSize(jitter): ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"]) if args.hwnd == winobjs.module_cur_hwnd: ret = len(open(winobjs.module_fname_nux).read()) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] ret = len(open(wh.name).read()) else: raise ValueError('unknown hwnd!') if args.lpfilesizehight != 0: jitter.vm.set_mem(args.lpfilesizehight, pck32(ret)) jitter.func_ret_stdcall(ret_ad, ret) def kernel32_GetFileSizeEx(jitter): ret_ad, args = jitter.func_args_stdcall(["hwnd", "lpfilesizehight"]) if args.hwnd == winobjs.module_cur_hwnd: l = len(open(winobjs.module_fname_nux).read()) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] l = len(open(wh.name).read()) else: raise ValueError('unknown hwnd!') if 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_mem(args.lpfloldprotect, pck32(ACCESS_DICT_INV[old])) for addr in jitter.vm.get_all_memory(): # Multi-page if args.lpvoid <= addr < args.lpvoid + args.dwsize: jitter.vm.set_mem_access(addr, ACCESS_DICT[flnewprotect]) 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) jitter.vm.add_memory_page( alloc_addr, ACCESS_DICT[args.flprotect], "\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) # alloc_addr = args.lpvoid jitter.vm.add_memory_page( alloc_addr, ACCESS_DICT[args.flprotect], "\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 winobjs.runtime_dll.name2off.values()): name_inv = dict([(x[1], x[0]) for x in winobjs.runtime_dll.name2off.items()]) 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(), jitter.set_str_ansi) def kernel32_GetModuleFileNameW(jitter): kernel32_GetModuleFileName(jitter, whoami(), jitter.set_str_unic) 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) ret = winobjs.mutex[name] else: if name in winobjs.mutex: raise NotImplementedError("Untested case") # ret = 0 else: winobjs.mutex[name] = id(name) ret = winobjs.mutex[name] jitter.func_ret_stdcall(ret_ad, ret) def kernel32_CreateMutexA(jitter): kernel32_CreateMutex(jitter, whoami(), jitter.get_str_ansi) def kernel32_CreateMutexW(jitter): kernel32_CreateMutex(jitter, whoami(), jitter.get_str_unic) def shell32_SHGetSpecialFolderLocation(jitter): ret_ad, args = jitter.func_args_stdcall(["hwndowner", "nfolder", "ppidl"]) jitter.vm.set_mem(args.ppidl, pck32(args.nfolder)) jitter.func_ret_stdcall(ret_ad, 0) def kernel32_SHGetPathFromIDList(jitter, funcname, set_str): ret_ad, args = jitter.func_args_stdcall(["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(), jitter.set_str_unic) def shell32_SHGetPathFromIDListA(jitter): kernel32_SHGetPathFromIDList(jitter, whoami(), jitter.set_str_ansi) 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, jitter.get_str_ansi) def kernel32_LoadLibraryW(jitter): kernel32_LoadLibrary(jitter, jitter.get_str_unic) 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, jitter.get_str_ansi) def kernel32_LoadLibraryExW(jitter): kernel32_LoadLibraryEx(jitter, jitter.get_str_unic) def kernel32_GetProcAddress(jitter): ret_ad, args = jitter.func_args_stdcall(["libbase", "fname"]) fname = args.fname if fname < 0x10000: fname = fname else: fname = jitter.get_str_ansi(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(), jitter.get_str_ansi) def kernel32_GetModuleHandleW(jitter): kernel32_GetModuleHandle(jitter, whoami(), jitter.get_str_unic) def kernel32_VirtualLock(jitter): ret_ad, _ = jitter.func_args_stdcall(["lpaddress", "dwsize"]) jitter.func_ret_stdcall(ret_ad, 1) class systeminfo: 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_mem(args.bool_ptr, pck32(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) s = set_str('"%s"' % winobjs.module_path) jitter.vm.set_mem(alloc_addr, s) jitter.func_ret_stdcall(ret_ad, alloc_addr) def kernel32_GetCommandLineA(jitter): kernel32_GetCommandLine(jitter, set_str_ansi) def kernel32_GetCommandLineW(jitter): kernel32_GetCommandLine(jitter, set_str_unic) def shell32_CommandLineToArgvW(jitter): ret_ad, args = jitter.func_args_stdcall(["pcmd", "pnumargs"]) cmd = jitter.get_str_unic(args.pcmd) log.info("CommandLineToArgv %r", cmd) tks = cmd.split(' ') addr = winobjs.heap.alloc(jitter, len(cmd) * 2 + 4 * len(tks)) addr_ret = winobjs.heap.alloc(jitter, 4 * (len(tks) + 1)) o = 0 for i, t in enumerate(tks): jitter.set_str_unic(addr + o, t) jitter.vm.set_mem(addr_ret + 4 * i, pck32(addr + o)) o += len(t)*2 + 2 jitter.vm.set_mem(addr_ret + 4 * i, pck32(0)) jitter.vm.set_mem(args.pnumargs, pck32(len(tks))) jitter.func_ret_stdcall(ret_ad, addr_ret) def cryptdll_MD5Init(jitter): ret_ad, args = jitter.func_args_stdcall(["ad_ctx"]) index = len(winobjs.cryptdll_md5_h) h = MD5.new() winobjs.cryptdll_md5_h[index] = h jitter.vm.set_mem(args.ad_ctx, pck32(index)) jitter.func_ret_stdcall(ret_ad, 0) def cryptdll_MD5Update(jitter): ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_input", "inlen"]) index = jitter.vm.get_mem(args.ad_ctx, 4) index = upck32(index) if not index in winobjs.cryptdll_md5_h: raise ValueError('unknown h context', index) data = jitter.vm.get_mem(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_mem(args.ad_ctx, 4) index = upck32(index) if not index in winobjs.cryptdll_md5_h: raise ValueError('unknown h context', index) h = winobjs.cryptdll_md5_h[index].digest() jitter.vm.set_mem(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 = jitter.get_str_ansi(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_mem(args.phout, pck32(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 = upck32(jitter.vm.get_mem(args.ad_ad_ch, 4)) ch = ord(jitter.vm.get_mem(ad_ch, 1)) jitter.vm.set_mem(args.ad_ad_ch, pck32(ad_ch + 1)) jitter.func_ret_stdcall(ret_ad, ch) def ntdll_RtlFindCharInUnicodeString(jitter): ret_ad, args = jitter.func_args_stdcall(["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_mem(args.pos_ad, pck32(0)) else: ret = 0 jitter.vm.set_mem(args.pos_ad, pck32(pos)) jitter.func_ret_stdcall(ret_ad, ret) def ntdll_RtlComputeCrc32(jitter): ret_ad, args = jitter.func_args_stdcall(["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_mem(args.my_event, pck32(winobjs.win_event_num)) winobjs.win_event_num += 1 jitter.func_ret_stdcall(ret_ad, 0) def ntoskrnl_RtlGetVersion(jitter): ret_ad, args = jitter.func_args_stdcall(['ptr_version']) s = struct.pack("IIIII", 0x114, # struct size 0x5, # maj vers 0x2, # min vers 0x666, # build nbr 0x2, # platform id ) + jitter.set_str_unic("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) & 0xFFFFFFFFL) / 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), str(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_str_unic(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, "\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 = jitter.get_str_unic(args.ptr_str1) s2 = jitter.get_str_unic(args.ptr_str2) log.debug("%s('%s','%s')" % (whoami(), s1, s2)) jitter.func_ret_cdecl(ret_ad, cmp(s1, s2)) def msvcrt__wcsicmp(jitter): ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"]) s1 = jitter.get_str_unic(args.ptr_str1) s2 = jitter.get_str_unic(args.ptr_str2) log.debug("%s('%s','%s')" % (whoami(), s1, s2)) jitter.func_ret_cdecl(ret_ad, cmp(s1.lower(), s2.lower())) def msvcrt__wcsnicmp(jitter): ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2", "count"]) s1 = jitter.get_str_unic(args.ptr_str1) s2 = jitter.get_str_unic(args.ptr_str2) log.debug("%s('%s','%s',%d)" % (whoami(), s1, s2, args.count)) jitter.func_ret_cdecl(ret_ad, cmp(s1.lower()[:args.count], s2.lower()[:args.count])) def msvcrt_wcsncpy(jitter): ret_ad, args = jitter.func_args_cdecl(["dst", "src", "n"]) src = jitter.get_str_unic(args.src) dst = src[:args.n] dst += "\x00\x00" * (args.n-len(dst)+1) jitter.vm.set_mem(args.dst, dst) jitter.func_ret_cdecl(ret_ad, args.dst) def kernel32_lstrcmpA(jitter): my_lstrcmp(jitter, whoami(), jitter.get_str_ansi) def kernel32_lstrcmpiA(jitter): my_lstrcmp(jitter, whoami(), lambda x: jitter.get_str_ansi(x).lower()) def kernel32_lstrcmpW(jitter): my_lstrcmp(jitter, whoami(), jitter.get_str_unic) def kernel32_lstrcmpiW(jitter): my_lstrcmp(jitter, whoami(), lambda x: jitter.get_str_unic(x).lower()) def kernel32_lstrcmpi(jitter): my_lstrcmp(jitter, whoami(), lambda x: jitter.get_str_ansi(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(), jitter.get_str_unic, jitter.set_str_unic) def kernel32_lstrcpyA(jitter): my_strcpy(jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi) def kernel32_lstrcpy(jitter): my_strcpy(jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi) def msvcrt__mbscpy(jitter): ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"]) s2 = jitter.get_str_unic(args.ptr_str2) jitter.set_str_unic(args.ptr_str1, s2) 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 = jitter.get_str_ansi(args.ptr_str2) if len(s2) >= args.mlen: s2 = s2[:args.mlen - 1] log.info("Copy '%r'", s2) jitter.set_str_ansi(args.ptr_str1, s2) jitter.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(), jitter.get_str_ansi, len) def kernel32_lstrlenW(jitter): my_strlen(jitter, whoami(), jitter.get_str_unic, len) def kernel32_lstrlen(jitter): my_strlen(jitter, whoami(), jitter.get_str_ansi, len) def my_lstrcat(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) jitter.vm.set_mem(args.ptr_str1, s1 + s2) jitter.func_ret_stdcall(ret_ad, args.ptr_str1) def kernel32_lstrcatA(jitter): my_lstrcat(jitter, whoami(), jitter.get_str_ansi) def kernel32_lstrcatW(jitter): my_lstrcat(jitter, whoami(), jitter.get_str_unic) 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) if args.lpvolumenamebuffer: s = "volumename" s = s[:args.nvolumenamesize] set_str(args.lpvolumenamebuffer, s) if args.lpvolumeserialnumber: jitter.vm.set_mem(args.lpvolumeserialnumber, pck32(11111111)) if args.lpmaximumcomponentlength: jitter.vm.set_mem(args.lpmaximumcomponentlength, pck32(0xff)) if args.lpfilesystemflags: jitter.vm.set_mem(args.lpfilesystemflags, pck32(22222222)) if 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(), jitter.get_str_ansi, jitter.set_str_ansi) def kernel32_GetVolumeInformationW(jitter): my_GetVolumeInformation(jitter, whoami(), jitter.get_str_unic, jitter.set_str_unic) def kernel32_MultiByteToWideChar(jitter): ret_ad, args = jitter.func_args_stdcall(["codepage", "dwflags", "lpmultibytestr", "cbmultibyte", "lpwidecharstr", "cchwidechar"]) src = jitter.get_str_ansi(args.lpmultibytestr) + '\x00' l = len(src) src = "\x00".join(list(src)) jitter.vm.set_mem(args.lpwidecharstr, src) jitter.func_ret_stdcall(ret_ad, l) def my_GetEnvironmentVariable(jitter, funcname, get_str, set_str, mylen): ret_ad, args = jitter.func_args_stdcall(["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(), jitter.get_str_ansi, jitter.set_str_ansi, len) def kernel32_GetEnvironmentVariableW(jitter): my_GetEnvironmentVariable(jitter, whoami(), jitter.get_str_unic, jitter.set_str_ansi, 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(), jitter.set_str_ansi) def kernel32_GetSystemDirectoryW(jitter): my_GetSystemDirectory(jitter, whoami(), jitter.set_str_unic) 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(), jitter.get_str_unic) def kernel32_CreateDirectoryA(jitter): my_CreateDirectory(jitter, whoami(), jitter.get_str_ansi) 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)) def kernel32_CreateEventA(jitter): my_CreateEvent(jitter, whoami(), jitter.get_str_ansi) def kernel32_CreateEventW(jitter): my_CreateEvent(jitter, whoami(), jitter.get_str_unic) 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 winobjs.events_pool.iteritems(): 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_str_ansi(jitter, args.lpfilename) ret = 1 else: ret = 0 jitter.vm.set_mem(tib_address + 0x34, pck32(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 += "\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 = upck32(jitter.vm.get_mem(args.lppvoid, 4)) # 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_mem(args.lpfloldprotect, pck32(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 = upck32(jitter.vm.get_mem(args.pdwsize, 4)) 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], "\x00" * dwsize, "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) jitter.vm.set_mem(args.lppvoid, pck32(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 = jitter.get_str_ansi(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 = jitter.get_str_ansi(p_src) s = ("\x00".join(s + "\x00")) l = len(s) + 1 if args.alloc_str: alloc_addr = winobjs.heap.next_addr(l) jitter.vm.add_memory_page( alloc_addr, PAGE_READ | PAGE_WRITE, "\x00" * l, "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) else: alloc_addr = p_src jitter.vm.set_mem(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 = jitter.get_str_unic(p_src) libname = s.lower() ad = winobjs.runtime_dll.lib_get_add_base(libname) jitter.vm.set_mem(args.modhandle, pck32(ad)) jitter.func_ret_stdcall(ret_ad, 0) def ntdll_RtlFreeUnicodeString(jitter): ret_ad, args = jitter.func_args_stdcall(['src']) # l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8)) # s = get_str_unic(jitter, p_src) jitter.func_ret_stdcall(ret_ad, 0) def ntdll_LdrGetProcedureAddress(jitter): ret_ad, args = jitter.func_args_stdcall(["libbase", "pfname", "opt", "p_ad"]) l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.pfname, 0x8)) fname = jitter.get_str_ansi(p_src) ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname) jitter.add_breakpoint(ad, jitter.handle_lib) jitter.vm.set_mem(args.p_ad, pck32(ad)) jitter.func_ret_stdcall(ret_ad, 0) def ntdll_memset(jitter): ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size']) jitter.vm.set_mem(args.addr, chr(args.c) * args.size) jitter.func_ret_cdecl(ret_ad, args.addr) def msvcrt_memset(jitter): ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size']) jitter.vm.set_mem(args.addr, chr(args.c) * args.size) jitter.func_ret_cdecl(ret_ad, args.addr) def msvcrt_strrchr(jitter): ret_ad, args = jitter.func_args_cdecl(['pstr','c']) s = jitter.get_str_ansi(args.pstr) c = chr(args.c) 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 = jitter.get_str_unic(args.pstr) c = chr(args.c) 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) #log.info("memcpy buf %s" % s.encode("hex")) 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 = jitter.get_str_ansi(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 = jitter.get_str_unic(args.path_ad) i = path.rfind('\\') if i == -1: i = 0 jitter.vm.set_mem(args.path_ad + i * 2, "\x00\x00") path = jitter.get_str_unic(args.path_ad) jitter.func_ret_stdcall(ret_ad, 1) def shlwapi_PathIsPrefixW(jitter): ret_ad, args = jitter.func_args_stdcall(['ptr_prefix', 'ptr_path']) prefix = jitter.get_str_unic(args.ptr_prefix) path = jitter.get_str_unic(args.ptr_path) 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 = jitter.get_str_unic(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(), jitter.get_str_ansi) def shlwapi_PathGetDriveNumberW(jitter): shlwapi_PathGetDriveNumber(jitter, whoami(), jitter.get_str_unic) def shlwapi_PathIsFileSpecA(jitter): shlwapi_PathIsFileSpec(jitter, whoami(), jitter.get_str_ansi) def shlwapi_PathIsFileSpecW(jitter): shlwapi_PathIsFileSpec(jitter, whoami(), jitter.get_str_unic) def shlwapi_StrToIntA(jitter): ret_ad, args = jitter.func_args_stdcall(['i_str_ad']) i_str = jitter.get_str_ansi(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(), jitter.get_str_ansi) def shlwapi_StrToInt64ExW(jitter): shlwapi_StrToInt64Ex(jitter, whoami(), jitter.get_str_unic) def user32_IsCharAlpha(jitter, funcname, get_str): ret_ad, args = jitter.func_args_stdcall(["c"]) try: c = chr(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(), jitter.get_str_ansi) def user32_IsCharAlphaW(jitter): user32_IsCharAlpha(jitter, whoami(), jitter.get_str_unic) def user32_IsCharAlphaNumericA(jitter): ret_ad, args = jitter.func_args_stdcall(["c"]) c = chr(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, jitter.get_str_ansi) ret = len(output) log.info("sprintf() = '%s'" % (output)) jitter.vm.set_mem(args.string, output + '\x00') 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, jitter.get_str_unic) ret = len(output) log.info("swprintf('%s') = '%s'" % (jitter.get_str_unic(args.fmt), output)) jitter.vm.set_mem(args.string, output.encode("utf-16le") + '\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) ret = len(output) log.info("fprintf(%x, '%s') = '%s'" % (args.file, jitter.get_str_ansi(args.fmt), output)) fd = upck32(jitter.vm.get_mem(args.file + 0x10, 4)) 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 = jitter.get_str_ansi(args.ptr_str1).lower() s2 = jitter.get_str_ansi(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 = jitter.get_str_unic(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_mem(args.phandle, pck32(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_) jitter.vm.set_mem(args.buf, dir_[:args.size-1] + "\x00") 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_mem(args.phandle, pck32(ret_hkey)) jitter.func_ret_stdcall(ret_ad, ret) def advapi32_RegOpenKeyExA(jitter): advapi32_RegOpenKeyEx(jitter, whoami(), jitter.get_str_ansi) def advapi32_RegOpenKeyExW(jitter): advapi32_RegOpenKeyEx(jitter, whoami(), jitter.get_str_unic) 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(), jitter.get_str_ansi) def advapi32_RegSetValueExW(jitter): advapi32_RegOpenKeyEx(jitter, whoami(), jitter.get_str_unic) def advapi32_RegSetValueA(jitter): advapi32_RegSetValue(jitter, whoami(), jitter.get_str_ansi) def advapi32_RegSetValueW(jitter): advapi32_RegSetValue(jitter, whoami(), jitter.get_str_unic) 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, jitter.get_str_unic) def kernel32_SetCurrentDirectoryA(jitter): return kernel32_SetCurrentDirectory(jitter, jitter.get_str_ansi) def msvcrt_wcscat(jitter): ret_ad, args = jitter.func_args_cdecl(['ptr_str1', 'ptr_str2']) s1 = jitter.get_str_unic(args.ptr_str1) s2 = jitter.get_str_unic(args.ptr_str2) log.info("strcat('%s','%s')" % (s1,s2)) jitter.vm.set_mem(args.ptr_str1, (s1 + s2).encode("utf-16le") + "\x00\x00") jitter.func_ret_cdecl(ret_ad, args.ptr_str1) 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(), jitter.set_str_ansi) def kernel32_GetLocaleInfoW(jitter): kernel32_GetLocaleInfo(jitter, whoami(), jitter.set_str_unic) 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) def kernel32_GetStartupInfo(jitter, funcname, set_str): ret_ad, args = jitter.func_args_stdcall(["ptr"]) s = "\x00" * 0x2c + "\x81\x00\x00\x00" + "\x0a" jitter.vm.set_mem(args.ptr, s) jitter.func_ret_stdcall(ret_ad, args.ptr) def kernel32_GetStartupInfoA(jitter): kernel32_GetStartupInfo(jitter, whoami(), jitter.set_str_ansi) def kernel32_GetStartupInfoW(jitter): kernel32_GetStartupInfo(jitter, whoami(), jitter.set_str_unic) 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, "\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(), jitter.get_str_ansi) def kernel32_CreateFileMappingW(jitter): kernel32_CreateFileMapping(jitter, whoami(), jitter.get_str_unic) 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(), jitter.get_str_ansi) def kernel32_GetDriveTypeW(jitter): kernel32_GetDriveType(jitter, whoami(), jitter.get_str_unic) def kernel32_GetDiskFreeSpace(jitter, funcname, get_str): ret_ad, args = jitter.func_args_stdcall(["lprootpathname", "lpsectorpercluster", "lpbytespersector", "lpnumberoffreeclusters", "lptotalnumberofclusters"]) jitter.vm.set_mem(args.lpsectorpercluster, pck32(8)) jitter.vm.set_mem(args.lpbytespersector, pck32(0x200)) jitter.vm.set_mem(args.lpnumberoffreeclusters, pck32(0x222222)) jitter.vm.set_mem(args.lptotalnumberofclusters, pck32(0x333333)) jitter.func_ret_stdcall(ret_ad, 1) def kernel32_GetDiskFreeSpaceA(jitter): kernel32_GetDiskFreeSpace(jitter, whoami(), jitter.get_str_ansi) def kernel32_GetDiskFreeSpaceW(jitter): kernel32_GetDiskFreeSpace(jitter, whoami(), jitter.get_str_unic) 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 all_mem.iteritems(): 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_mem(args.procaffmask, pck32(1)) jitter.vm.set_mem(args.systemaffmask, pck32(1)) jitter.func_ret_stdcall(ret_ad, 1) def msvcrt_rand(jitter): ret_ad, _ = 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 = jitter.get_str_unic(args.pwstr) jitter.func_ret_cdecl(ret_ad, len(s)) def kernel32_SetFilePointer(jitter): ret_ad, args = jitter.func_args_stdcall(["hwnd", "distance", "p_distance_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.distance, args.movemethod) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] wh.info.seek(args.distance, args.movemethod) else: raise ValueError('unknown filename') jitter.func_ret_stdcall(ret_ad, args.distance) def kernel32_SetFilePointerEx(jitter): ret_ad, args = jitter.func_args_stdcall(["hwnd", "distance_l", "distance_h", "pnewfileptr", "movemethod"]) distance = args.distance_l | (args.distance_h << 32) if distance: 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(distance, args.movemethod) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] wh.info.seek(distance, 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_mem(args.lpnumberofbyteswrite, pck32(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 = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") o = winobjs.handle_pool[fd] o.info.seek(args.offset, args.orig) jitter.func_ret_cdecl(ret_ad, 0) def msvcrt_ftell(jitter): ret_ad, args = jitter.func_args_cdecl(["stream"]) fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") o = winobjs.handle_pool[fd] off = o.info.tell() jitter.func_ret_cdecl(ret_ad, off) def msvcrt_rewind(jitter): ret_ad, args = jitter.func_args_cdecl(["stream"]) fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") o = winobjs.handle_pool[fd] # off = o.info.seek(0, 0) jitter.func_ret_cdecl(ret_ad, 0) def msvcrt_fread(jitter): ret_ad, args = jitter.func_args_cdecl(["buf", "size", "nmemb", "stream"]) fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") data = winobjs.handle_pool[fd].info.read(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 = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) 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 = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") o = winobjs.handle_pool[fd] # off = o.info.close() 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 = jitter.get_str_ansi(args.lptext) caption = jitter.get_str_ansi(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, jitter.set_str_ansi) def kernel32_GetTempPathW(jitter): kernel32_myGetTempPath(jitter, jitter.set_str_unic) 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 = jitter.get_str_ansi(args.ext) if args.ext else 'tmp' path = jitter.get_str_ansi(args.path) if args.path else "xxx" fname = path + "\\" + "temp%.4d" % temp_num + "." + ext jitter.vm.set_mem(args.buf, fname) jitter.func_ret_stdcall(ret_ad, 0) class win32_find_data: 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 kargs.items(): setattr(self, k, v) def toStruct(self): s = struct.pack('=IQQQIIII', self.fileattrib, self.creationtime, self.lastaccesstime, self.lastwritetime, self.filesizehigh, self.filesizelow, self.dwreserved0, self.dwreserved1) fname = self.cfilename + '\x00' * MAX_PATH fname = fname[:MAX_PATH] s += fname fname = self.alternamefilename + '\x00' * 14 fname = fname[:14] s += fname return s class find_data_mngr: 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 kernel32_FindFirstFileA(jitter): ret_ad, args = jitter.func_args_stdcall(["pfilepattern", "pfindfiledata"]) filepattern = jitter.get_str_ansi(args.pfilepattern) h = winobjs.find_data.findfirst(filepattern) fname = winobjs.find_data.findnext(h) fdata = win32_find_data(cfilename=fname) jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct()) jitter.func_ret_stdcall(ret_ad, h) def kernel32_FindNextFileA(jitter): ret_ad, args = jitter.func_args_stdcall(["handle", "pfindfiledata"]) fname = winobjs.find_data.findnext(args.handle) if fname is None: ret = 0 else: ret = 1 fdata = win32_find_data(cfilename=fname) jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct()) jitter.func_ret_stdcall(ret_ad, ret) 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.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) jitter.vm.set_mem(args.p, jitter.set_str_unic(s + "\x00")) 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, jitter.get_str_unic) def msvcrt_fopen(jitter): msvcrt_myfopen(jitter, jitter.get_str_ansi) def msvcrt_strlen(jitter): ret_ad, args = jitter.func_args_cdecl(["src"]) s = jitter.get_str_ansi(args.src) jitter.func_ret_cdecl(ret_ad, len(s))
Module variables
var ACCESS_DICT
var ACCESS_DICT_INV
var DATE_1601_TO_1970
var MAX_PATH
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;
var PAGE_EXEC
var PAGE_READ
var PAGE_WRITE
var console_handler
var digs
var log
var process_list
var temp_num
var tib_address
var winobjs
Functions
def ad2mdl(
ad)
def ad2mdl(ad): return ((ad - winobjs.nt_mdl_ad) & 0xFFFFFFFFL) / 0x10
def advapi32_CryptAcquireContext(
jitter, funcname, get_str)
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_mem(args.phprov, pck32(winobjs.cryptcontext_hwnd)) jitter.func_ret_stdcall(ret_ad, 1)
def advapi32_CryptAcquireContextA(
jitter)
def advapi32_CryptAcquireContextA(jitter): advapi32_CryptAcquireContext(jitter, whoami(), jitter.get_str_ansi)
def advapi32_CryptAcquireContextW(
jitter)
def advapi32_CryptAcquireContextW(jitter): advapi32_CryptAcquireContext(jitter, whoami(), jitter.get_str_unic)
def advapi32_CryptCreateHash(
jitter)
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_mem( args.phhash, pck32(winobjs.cryptcontext_bnum + winobjs.cryptcontext_num) ) winobjs.cryptcontext[ winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj() winobjs.cryptcontext[ winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = MD5.new() elif args.algid == 0x00008004: log.debug('algo is SHA1') jitter.vm.set_mem( args.phhash, pck32(winobjs.cryptcontext_bnum + winobjs.cryptcontext_num) ) winobjs.cryptcontext[ winobjs.cryptcontext_bnum + winobjs.cryptcontext_num] = hobj() winobjs.cryptcontext[ winobjs.cryptcontext_bnum + winobjs.cryptcontext_num].h = SHA.new() else: raise ValueError('un impl algo1') jitter.func_ret_stdcall(ret_ad, 1)
def advapi32_CryptDecrypt(
jitter)
def advapi32_CryptDecrypt(jitter): # ret_ad, _ = jitter.func_args_stdcall(["hkey", "hhash", "final", # "dwflags", "pbdata", # "pdwdatalen"]) raise ValueError("Not implemented")
def advapi32_CryptDeriveKey(
jitter)
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_mem(args.phkey, pck32(args.hbasedata)) jitter.func_ret_stdcall(ret_ad, 1)
def advapi32_CryptDestroyHash(
jitter)
def advapi32_CryptDestroyHash(jitter): ret_ad, _ = jitter.func_args_stdcall(["hhash"]) jitter.func_ret_stdcall(ret_ad, 1)
def advapi32_CryptGetHashParam(
jitter)
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: # XXX todo: save h state? h = winobjs.cryptcontext[args.hhash].h.digest() else: raise ValueError('not impl', args.param) jitter.vm.set_mem(args.pbdata, h) jitter.vm.set_mem(args.dwdatalen, pck32(len(h))) jitter.func_ret_stdcall(ret_ad, 1)
def advapi32_CryptHashData(
jitter)
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[:10]) + "...") winobjs.cryptcontext[args.hhash].h.update(data) jitter.func_ret_stdcall(ret_ad, 1)
def advapi32_CryptReleaseContext(
jitter)
def advapi32_CryptReleaseContext(jitter): ret_ad, _ = jitter.func_args_stdcall(["hhash", "flags"]) jitter.func_ret_stdcall(ret_ad, 0)
def advapi32_RegCloseKey(
jitter)
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_RegCreateKeyW(
jitter)
def advapi32_RegCreateKeyW(jitter): ret_ad, args = jitter.func_args_stdcall(["hkey", "subkey", "phandle"]) s_subkey = jitter.get_str_unic(args.subkey).lower() if args.subkey else "" 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_mem(args.phandle, pck32(ret_hkey)) jitter.func_ret_stdcall(ret_ad, ret)
def advapi32_RegOpenKeyEx(
jitter, funcname, get_str)
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_mem(args.phandle, pck32(ret_hkey)) jitter.func_ret_stdcall(ret_ad, ret)
def advapi32_RegOpenKeyExA(
jitter)
def advapi32_RegOpenKeyExA(jitter): advapi32_RegOpenKeyEx(jitter, whoami(), jitter.get_str_ansi)
def advapi32_RegOpenKeyExW(
jitter)
def advapi32_RegOpenKeyExW(jitter): advapi32_RegOpenKeyEx(jitter, whoami(), jitter.get_str_unic)
def advapi32_RegSetValue(
jitter, funcname, get_str)
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_RegSetValueA(
jitter)
def advapi32_RegSetValueA(jitter): advapi32_RegSetValue(jitter, whoami(), jitter.get_str_ansi)
def advapi32_RegSetValueEx(
jitter, funcname, get_str)
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_RegSetValueExA(
jitter)
def advapi32_RegSetValueExA(jitter): advapi32_RegSetValueEx(jitter, whoami(), jitter.get_str_ansi)
def advapi32_RegSetValueExW(
jitter)
def advapi32_RegSetValueExW(jitter): advapi32_RegOpenKeyEx(jitter, whoami(), jitter.get_str_unic)
def advapi32_RegSetValueW(
jitter)
def advapi32_RegSetValueW(jitter): advapi32_RegSetValue(jitter, whoami(), jitter.get_str_unic)
def cryptdll_MD5Final(
jitter)
def cryptdll_MD5Final(jitter): ret_ad, args = jitter.func_args_stdcall(["ad_ctx"]) index = jitter.vm.get_mem(args.ad_ctx, 4) index = upck32(index) if not index in winobjs.cryptdll_md5_h: raise ValueError('unknown h context', index) h = winobjs.cryptdll_md5_h[index].digest() jitter.vm.set_mem(args.ad_ctx + 88, h) jitter.func_ret_stdcall(ret_ad, 0)
def cryptdll_MD5Init(
jitter)
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_mem(args.ad_ctx, pck32(index)) jitter.func_ret_stdcall(ret_ad, 0)
def cryptdll_MD5Update(
jitter)
def cryptdll_MD5Update(jitter): ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_input", "inlen"]) index = jitter.vm.get_mem(args.ad_ctx, 4) index = upck32(index) if not index in winobjs.cryptdll_md5_h: raise ValueError('unknown h context', index) data = jitter.vm.get_mem(args.ad_input, args.inlen) winobjs.cryptdll_md5_h[index].update(data) log.debug(hexdump(data)) jitter.func_ret_stdcall(ret_ad, 0)
def datetime_to_systemtime(
curtime)
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 filetime_to_unixtime(
filetime)
Convert filetime to unixtime
https://msdn.microsoft.com/en-us/library/ms724228
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 get_current_filetime(
)
Get current filetime https://msdn.microsoft.com/en-us/library/ms724228
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 get_fmt_args(
jitter, fmt, cur_arg, get_str)
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 hal_ExAcquireFastMutex(
jitter)
def hal_ExAcquireFastMutex(jitter): ret_ad, _ = jitter.func_args_stdcall(0) jitter.func_ret_stdcall(ret_ad, 0)
def hal_ExReleaseFastMutex(
jitter)
def hal_ExReleaseFastMutex(jitter): ret_ad, _ = jitter.func_args_stdcall(0) jitter.func_ret_stdcall(ret_ad, 0)
def int2base(
x, base)
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 kernel32_CloseHandle(
jitter)
def kernel32_CloseHandle(jitter): ret_ad, _ = jitter.func_args_stdcall(["hwnd"]) jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_CreateDirectoryA(
jitter)
def kernel32_CreateDirectoryA(jitter): my_CreateDirectory(jitter, whoami(), jitter.get_str_ansi)
def kernel32_CreateDirectoryW(
jitter)
def kernel32_CreateDirectoryW(jitter): my_CreateDirectory(jitter, whoami(), jitter.get_str_unic)
def kernel32_CreateEventA(
jitter)
def kernel32_CreateEventA(jitter): my_CreateEvent(jitter, whoami(), jitter.get_str_ansi)
def kernel32_CreateEventW(
jitter)
def kernel32_CreateEventW(jitter): my_CreateEvent(jitter, whoami(), jitter.get_str_unic)
def kernel32_CreateFile(
jitter, funcname, get_str)
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: # sandox path sb_fname = windows_to_sbpath(fname) if args.access & 0x80000000 or args.access == 1: # read 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: h = open(sb_fname, 'r+b') ret = winobjs.handle_pool.add(sb_fname, h) else: log.warning("FILE %r DOES NOT EXIST!", 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, 'w').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: # write 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, 'r+b') 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, 'w') 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)
def kernel32_CreateFileA(jitter): kernel32_CreateFile(jitter, whoami(), jitter.get_str_ansi)
def kernel32_CreateFileMapping(
jitter, funcname, get_str)
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)
def kernel32_CreateFileMappingA(jitter): kernel32_CreateFileMapping(jitter, whoami(), jitter.get_str_ansi)
def kernel32_CreateFileMappingW(
jitter)
def kernel32_CreateFileMappingW(jitter): kernel32_CreateFileMapping(jitter, whoami(), jitter.get_str_unic)
def kernel32_CreateFileW(
jitter)
def kernel32_CreateFileW(jitter): kernel32_CreateFile(jitter, whoami(), jitter.get_str_unic)
def kernel32_CreateMutex(
jitter, funcname, get_str)
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) ret = winobjs.mutex[name] else: if name in winobjs.mutex: raise NotImplementedError("Untested case") # ret = 0 else: winobjs.mutex[name] = id(name) ret = winobjs.mutex[name] jitter.func_ret_stdcall(ret_ad, ret)
def kernel32_CreateMutexA(
jitter)
def kernel32_CreateMutexA(jitter): kernel32_CreateMutex(jitter, whoami(), jitter.get_str_ansi)
def kernel32_CreateMutexW(
jitter)
def kernel32_CreateMutexW(jitter): kernel32_CreateMutex(jitter, whoami(), jitter.get_str_unic)
def kernel32_CreateToolhelp32Snapshot(
jitter)
def kernel32_CreateToolhelp32Snapshot(jitter): ret_ad, _ = jitter.func_args_stdcall(["dwflags", "th32processid"]) jitter.func_ret_stdcall(ret_ad, winobjs.handle_toolhelpsnapshot)
def kernel32_FindFirstFileA(
jitter)
def kernel32_FindFirstFileA(jitter): ret_ad, args = jitter.func_args_stdcall(["pfilepattern", "pfindfiledata"]) filepattern = jitter.get_str_ansi(args.pfilepattern) h = winobjs.find_data.findfirst(filepattern) fname = winobjs.find_data.findnext(h) fdata = win32_find_data(cfilename=fname) jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct()) jitter.func_ret_stdcall(ret_ad, h)
def kernel32_FindNextFileA(
jitter)
def kernel32_FindNextFileA(jitter): ret_ad, args = jitter.func_args_stdcall(["handle", "pfindfiledata"]) fname = winobjs.find_data.findnext(args.handle) if fname is None: ret = 0 else: ret = 1 fdata = win32_find_data(cfilename=fname) jitter.vm.set_mem(args.pfindfiledata, fdata.toStruct()) jitter.func_ret_stdcall(ret_ad, ret)
def kernel32_FlushFileBuffers(
jitter)
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_FlushInstructionCache(
jitter)
def kernel32_FlushInstructionCache(jitter): ret_ad, _ = jitter.func_args_stdcall(["hprocess", "lpbasead", "dwsize"]) jitter.func_ret_stdcall(ret_ad, 0x1337)
def kernel32_GetCommandLine(
jitter, set_str)
def kernel32_GetCommandLine(jitter, set_str): ret_ad, _ = jitter.func_args_stdcall(0) alloc_addr = winobjs.heap.alloc(jitter, 0x1000) s = set_str('"%s"' % winobjs.module_path) jitter.vm.set_mem(alloc_addr, s) jitter.func_ret_stdcall(ret_ad, alloc_addr)
def kernel32_GetCommandLineA(
jitter)
def kernel32_GetCommandLineA(jitter): kernel32_GetCommandLine(jitter, set_str_ansi)
def kernel32_GetCommandLineW(
jitter)
def kernel32_GetCommandLineW(jitter): kernel32_GetCommandLine(jitter, set_str_unic)
def kernel32_GetCurrentDirectoryA(
jitter)
def kernel32_GetCurrentDirectoryA(jitter): ret_ad, args = jitter.func_args_stdcall(["size","buf"]) dir_ = winobjs.cur_dir log.debug("GetCurrentDirectory() = '%s'" % dir_) jitter.vm.set_mem(args.buf, dir_[:args.size-1] + "\x00") ret = len(dir_) if args.size <= len(dir_): ret += 1 jitter.func_ret_stdcall(ret_ad, ret)
def kernel32_GetCurrentProcess(
jitter)
def kernel32_GetCurrentProcess(jitter): ret_ad, _ = jitter.func_args_stdcall(0) jitter.func_ret_stdcall(ret_ad, winobjs.handle_curprocess)
def kernel32_GetCurrentProcessId(
jitter)
def kernel32_GetCurrentProcessId(jitter): ret_ad, _ = jitter.func_args_stdcall(0) jitter.func_ret_stdcall(ret_ad, winobjs.dw_pid_cur)
def kernel32_GetCurrentThreadId(
jitter)
def kernel32_GetCurrentThreadId(jitter): ret_ad, _ = jitter.func_args_stdcall(0) jitter.func_ret_stdcall(ret_ad, 0x113377)
def kernel32_GetDiskFreeSpace(
jitter, funcname, get_str)
def kernel32_GetDiskFreeSpace(jitter, funcname, get_str): ret_ad, args = jitter.func_args_stdcall(["lprootpathname", "lpsectorpercluster", "lpbytespersector", "lpnumberoffreeclusters", "lptotalnumberofclusters"]) jitter.vm.set_mem(args.lpsectorpercluster, pck32(8)) jitter.vm.set_mem(args.lpbytespersector, pck32(0x200)) jitter.vm.set_mem(args.lpnumberoffreeclusters, pck32(0x222222)) jitter.vm.set_mem(args.lptotalnumberofclusters, pck32(0x333333)) jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_GetDiskFreeSpaceA(
jitter)
def kernel32_GetDiskFreeSpaceA(jitter): kernel32_GetDiskFreeSpace(jitter, whoami(), jitter.get_str_ansi)
def kernel32_GetDiskFreeSpaceW(
jitter)
def kernel32_GetDiskFreeSpaceW(jitter): kernel32_GetDiskFreeSpace(jitter, whoami(), jitter.get_str_unic)
def kernel32_GetDriveType(
jitter, funcname, get_str)
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)
def kernel32_GetDriveTypeA(jitter): kernel32_GetDriveType(jitter, whoami(), jitter.get_str_ansi)
def kernel32_GetDriveTypeW(
jitter)
def kernel32_GetDriveTypeW(jitter): kernel32_GetDriveType(jitter, whoami(), jitter.get_str_unic)
def kernel32_GetEnvironmentVariableA(
jitter)
def kernel32_GetEnvironmentVariableA(jitter): my_GetEnvironmentVariable(jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi, len)
def kernel32_GetEnvironmentVariableW(
jitter)
def kernel32_GetEnvironmentVariableW(jitter): my_GetEnvironmentVariable(jitter, whoami(), jitter.get_str_unic, jitter.set_str_ansi, len)
def kernel32_GetFileSize(
jitter)
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).read()) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] ret = len(open(wh.name).read()) else: raise ValueError('unknown hwnd!') if args.lpfilesizehight != 0: jitter.vm.set_mem(args.lpfilesizehight, pck32(ret)) jitter.func_ret_stdcall(ret_ad, ret)
def kernel32_GetFileSizeEx(
jitter)
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).read()) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] l = len(open(wh.name).read()) else: raise ValueError('unknown hwnd!') if 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_GetLastError(
jitter)
def kernel32_GetLastError(jitter): ret_ad, _ = jitter.func_args_stdcall(0) jitter.func_ret_stdcall(ret_ad, winobjs.lastwin32error)
def kernel32_GetLocalTime(
jitter)
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_GetLocaleInfo(
jitter, funcname, set_str)
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)
def kernel32_GetLocaleInfoA(jitter): kernel32_GetLocaleInfo(jitter, whoami(), jitter.set_str_ansi)
def kernel32_GetLocaleInfoW(
jitter)
def kernel32_GetLocaleInfoW(jitter): kernel32_GetLocaleInfo(jitter, whoami(), jitter.set_str_unic)
def kernel32_GetModuleFileName(
jitter, funcname, set_str)
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 winobjs.runtime_dll.name2off.values()): name_inv = dict([(x[1], x[0]) for x in winobjs.runtime_dll.name2off.items()]) 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)
def kernel32_GetModuleFileNameA(jitter): kernel32_GetModuleFileName(jitter, whoami(), jitter.set_str_ansi)
def kernel32_GetModuleFileNameW(
jitter)
def kernel32_GetModuleFileNameW(jitter): kernel32_GetModuleFileName(jitter, whoami(), jitter.set_str_unic)
def kernel32_GetModuleHandle(
jitter, funcname, get_str)
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)
def kernel32_GetModuleHandleA(jitter): kernel32_GetModuleHandle(jitter, whoami(), jitter.get_str_ansi)
def kernel32_GetModuleHandleW(
jitter)
def kernel32_GetModuleHandleW(jitter): kernel32_GetModuleHandle(jitter, whoami(), jitter.get_str_unic)
def kernel32_GetNativeSystemInfo(
jitter)
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 kernel32_GetPriorityClass(
jitter)
def kernel32_GetPriorityClass(jitter): ret_ad, _ = jitter.func_args_stdcall(["hwnd"]) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_GetProcAddress(
jitter)
def kernel32_GetProcAddress(jitter): ret_ad, args = jitter.func_args_stdcall(["libbase", "fname"]) fname = args.fname if fname < 0x10000: fname = fname else: fname = jitter.get_str_ansi(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_GetProcessAffinityMask(
jitter)
def kernel32_GetProcessAffinityMask(jitter): ret_ad, args = jitter.func_args_stdcall(["hprocess", "procaffmask", "systemaffmask"]) jitter.vm.set_mem(args.procaffmask, pck32(1)) jitter.vm.set_mem(args.systemaffmask, pck32(1)) jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_GetStartupInfo(
jitter, funcname, set_str)
def kernel32_GetStartupInfo(jitter, funcname, set_str): ret_ad, args = jitter.func_args_stdcall(["ptr"]) s = "\x00" * 0x2c + "\x81\x00\x00\x00" + "\x0a" jitter.vm.set_mem(args.ptr, s) jitter.func_ret_stdcall(ret_ad, args.ptr)
def kernel32_GetStartupInfoA(
jitter)
def kernel32_GetStartupInfoA(jitter): kernel32_GetStartupInfo(jitter, whoami(), jitter.set_str_ansi)
def kernel32_GetStartupInfoW(
jitter)
def kernel32_GetStartupInfoW(jitter): kernel32_GetStartupInfo(jitter, whoami(), jitter.set_str_unic)
def kernel32_GetSystemDefaultLangID(
jitter)
def kernel32_GetSystemDefaultLangID(jitter): ret_ad, _ = jitter.func_args_stdcall(0) jitter.func_ret_stdcall(ret_ad, 0x409) # encglish
def kernel32_GetSystemDirectoryA(
jitter)
def kernel32_GetSystemDirectoryA(jitter): my_GetSystemDirectory(jitter, whoami(), jitter.set_str_ansi)
def kernel32_GetSystemDirectoryW(
jitter)
def kernel32_GetSystemDirectoryW(jitter): my_GetSystemDirectory(jitter, whoami(), jitter.set_str_unic)
def kernel32_GetSystemInfo(
jitter)
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_GetSystemTime(
jitter)
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_GetSystemTimeAsFileTime(
jitter)
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_GetTempFileNameA(
jitter)
def kernel32_GetTempFileNameA(jitter): global temp_num ret_ad, args = jitter.func_args_stdcall(["path", "ext", "unique", "buf"]) temp_num += 1 ext = jitter.get_str_ansi(args.ext) if args.ext else 'tmp' path = jitter.get_str_ansi(args.path) if args.path else "xxx" fname = path + "\\" + "temp%.4d" % temp_num + "." + ext jitter.vm.set_mem(args.buf, fname) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_GetTempPathA(
jitter)
def kernel32_GetTempPathA(jitter): kernel32_myGetTempPath(jitter, jitter.set_str_ansi)
def kernel32_GetTempPathW(
jitter)
def kernel32_GetTempPathW(jitter): kernel32_myGetTempPath(jitter, jitter.set_str_unic)
def kernel32_GetThreadLocale(
jitter)
def kernel32_GetThreadLocale(jitter): ret_ad, _ = jitter.func_args_stdcall(0) jitter.func_ret_stdcall(ret_ad, 0x40c)
def kernel32_GetTickCount(
jitter)
def kernel32_GetTickCount(jitter): ret_ad, _ = jitter.func_args_stdcall(0) winobjs.tickcount += 1 jitter.func_ret_stdcall(ret_ad, winobjs.tickcount)
def kernel32_GetUserGeoID(
jitter)
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 kernel32_GetVersion(
jitter)
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, set_str)
def kernel32_GetVersionEx(jitter, str_size, set_str): ret_ad, args = jitter.func_args_stdcall(["ptr_struct"]) size = upck32(jitter.vm.get_mem(args.ptr_struct, 4)) 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 set_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)
def kernel32_GetVersionExA(
jitter)
kernel32_GetVersionExA = lambda jitter: kernel32_GetVersionEx(jitter, 128, set_str_ansi)
def kernel32_GetVersionExW(
jitter)
kernel32_GetVersionExW = lambda jitter: kernel32_GetVersionEx(jitter, 256, set_str_unic)
def kernel32_GetVolumeInformationA(
jitter)
def kernel32_GetVolumeInformationA(jitter): my_GetVolumeInformation( jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi)
def kernel32_GetVolumeInformationW(
jitter)
def kernel32_GetVolumeInformationW(jitter): my_GetVolumeInformation(jitter, whoami(), jitter.get_str_unic, jitter.set_str_unic)
def kernel32_GlobalAlloc(
jitter)
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_GlobalFree(
jitter)
def kernel32_GlobalFree(jitter): ret_ad, _ = jitter.func_args_stdcall(["addr"]) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_HeapAlloc(
jitter)
def kernel32_HeapAlloc(jitter): ret_ad, args = jitter.func_args_stdcall(["heap", "flags", "size"]) alloc_addr = winobjs.heap.alloc(jitter, args.size) jitter.func_ret_stdcall(ret_ad, alloc_addr)
def kernel32_HeapFree(
jitter)
def kernel32_HeapFree(jitter): ret_ad, _ = jitter.func_args_stdcall(["heap", "flags", "pmem"]) jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_InitializeCriticalSection(
jitter)
def kernel32_InitializeCriticalSection(jitter): ret_ad, _ = jitter.func_args_stdcall(["lpcritic"]) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_IsBadReadPtr(
jitter)
def kernel32_IsBadReadPtr(jitter): ret_ad, _ = jitter.func_args_stdcall(['lp', 'ucb']) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_IsDebuggerPresent(
jitter)
def kernel32_IsDebuggerPresent(jitter): ret_ad, _ = jitter.func_args_stdcall(0) jitter.func_ret_stdcall(ret_ad, winobjs.dbg_present)
def kernel32_IsWow64Process(
jitter)
def kernel32_IsWow64Process(jitter): ret_ad, args = jitter.func_args_stdcall(["process", "bool_ptr"]) jitter.vm.set_mem(args.bool_ptr, pck32(0)) jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_LoadLibrary(
jitter, get_str)
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)
def kernel32_LoadLibraryA(jitter): kernel32_LoadLibrary(jitter, jitter.get_str_ansi)
def kernel32_LoadLibraryEx(
jitter, get_str)
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)
def kernel32_LoadLibraryExA(jitter): kernel32_LoadLibraryEx(jitter, jitter.get_str_ansi)
def kernel32_LoadLibraryExW(
jitter)
def kernel32_LoadLibraryExW(jitter): kernel32_LoadLibraryEx(jitter, jitter.get_str_unic)
def kernel32_LoadLibraryW(
jitter)
def kernel32_LoadLibraryW(jitter): kernel32_LoadLibrary(jitter, jitter.get_str_unic)
def kernel32_LocalAlloc(
jitter)
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 kernel32_LocalFree(
jitter)
def kernel32_LocalFree(jitter): ret_ad, _ = jitter.func_args_stdcall(["lpvoid"]) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_MapViewOfFile(
jitter)
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_MultiByteToWideChar(
jitter)
def kernel32_MultiByteToWideChar(jitter): ret_ad, args = jitter.func_args_stdcall(["codepage", "dwflags", "lpmultibytestr", "cbmultibyte", "lpwidecharstr", "cchwidechar"]) src = jitter.get_str_ansi(args.lpmultibytestr) + '\x00' l = len(src) src = "\x00".join(list(src)) jitter.vm.set_mem(args.lpwidecharstr, src) jitter.func_ret_stdcall(ret_ad, l)
def kernel32_Process32First(
jitter)
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] 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)
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] jitter.vm.set_mem(args.ad_pentry, pentry) jitter.func_ret_stdcall(ret_ad, ret)
def kernel32_ReadFile(
jitter)
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_mem(args.lpnumberofbytesread, pck32(len(data))) jitter.vm.set_mem(args.lpbuffer, data) jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_RestoreLastError(
jitter)
def kernel32_RestoreLastError(jitter): kernel32_SetLastError(jitter)
def kernel32_RtlMoveMemory(
jitter)
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 kernel32_SHGetPathFromIDList(
jitter, funcname, set_str)
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 kernel32_SetCurrentDirectory(
jitter, get_str)
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_SetCurrentDirectoryA(
jitter)
def kernel32_SetCurrentDirectoryA(jitter): return kernel32_SetCurrentDirectory(jitter, jitter.get_str_ansi)
def kernel32_SetCurrentDirectoryW(
jitter)
def kernel32_SetCurrentDirectoryW(jitter): return kernel32_SetCurrentDirectory(jitter, jitter.get_str_unic)
def kernel32_SetEndOfFile(
jitter)
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_SetFileAttributesA(
jitter)
def kernel32_SetFileAttributesA(jitter): ret_ad, args = jitter.func_args_stdcall(["lpfilename", "dwfileattributes"]) if args.lpfilename: # fname = get_str_ansi(jitter, args.lpfilename) ret = 1 else: ret = 0 jitter.vm.set_mem(tib_address + 0x34, pck32(3)) jitter.func_ret_stdcall(ret_ad, ret)
def kernel32_SetFilePointer(
jitter)
def kernel32_SetFilePointer(jitter): ret_ad, args = jitter.func_args_stdcall(["hwnd", "distance", "p_distance_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.distance, args.movemethod) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] wh.info.seek(args.distance, args.movemethod) else: raise ValueError('unknown filename') jitter.func_ret_stdcall(ret_ad, args.distance)
def kernel32_SetFilePointerEx(
jitter)
def kernel32_SetFilePointerEx(jitter): ret_ad, args = jitter.func_args_stdcall(["hwnd", "distance_l", "distance_h", "pnewfileptr", "movemethod"]) distance = args.distance_l | (args.distance_h << 32) if distance: 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(distance, args.movemethod) elif args.hwnd in winobjs.handle_pool: wh = winobjs.handle_pool[args.hwnd] wh.info.seek(distance, args.movemethod) else: raise ValueError('unknown filename') jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_SetLastError(
jitter)
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_SetPriorityClass(
jitter)
def kernel32_SetPriorityClass(jitter): ret_ad, _ = jitter.func_args_stdcall(["hwnd", "dwpclass"]) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_Sleep(
jitter)
def kernel32_Sleep(jitter): ret_ad, _ = jitter.func_args_stdcall(['t']) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_TlsAlloc(
jitter)
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)
def kernel32_TlsFree(jitter): ret_ad, _ = jitter.func_args_stdcall(["tlsindex"]) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_TlsGetValue(
jitter)
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 kernel32_TlsSetValue(
jitter)
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_UnmapViewOfFile(
jitter)
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_VirtualAlloc(
jitter)
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) jitter.vm.add_memory_page( alloc_addr, ACCESS_DICT[args.flprotect], "\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) # alloc_addr = args.lpvoid jitter.vm.add_memory_page( alloc_addr, ACCESS_DICT[args.flprotect], "\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)
def kernel32_VirtualFree(jitter): ret_ad, _ = jitter.func_args_stdcall(["lpvoid", "dwsize", "alloc_type"]) jitter.func_ret_stdcall(ret_ad, 0)
def kernel32_VirtualLock(
jitter)
def kernel32_VirtualLock(jitter): ret_ad, _ = jitter.func_args_stdcall(["lpaddress", "dwsize"]) jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_VirtualProtect(
jitter)
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_mem(args.lpfloldprotect, pck32(ACCESS_DICT_INV[old])) for addr in jitter.vm.get_all_memory(): # Multi-page if args.lpvoid <= addr < args.lpvoid + args.dwsize: jitter.vm.set_mem_access(addr, ACCESS_DICT[flnewprotect]) jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_VirtualQuery(
jitter)
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 all_mem.iteritems(): 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_WaitForSingleObject(
jitter)
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 winobjs.events_pool.iteritems(): 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_WriteFile(
jitter)
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_mem(args.lpnumberofbyteswrite, pck32(len(data))) jitter.func_ret_stdcall(ret_ad, 1)
def kernel32_lstrcatA(
jitter)
def kernel32_lstrcatA(jitter): my_lstrcat(jitter, whoami(), jitter.get_str_ansi)
def kernel32_lstrcatW(
jitter)
def kernel32_lstrcatW(jitter): my_lstrcat(jitter, whoami(), jitter.get_str_unic)
def kernel32_lstrcmpA(
jitter)
def kernel32_lstrcmpA(jitter): my_lstrcmp(jitter, whoami(), jitter.get_str_ansi)
def kernel32_lstrcmpW(
jitter)
def kernel32_lstrcmpW(jitter): my_lstrcmp(jitter, whoami(), jitter.get_str_unic)
def kernel32_lstrcmpi(
jitter)
def kernel32_lstrcmpi(jitter): my_lstrcmp(jitter, whoami(), lambda x: jitter.get_str_ansi(x).lower())
def kernel32_lstrcmpiA(
jitter)
def kernel32_lstrcmpiA(jitter): my_lstrcmp(jitter, whoami(), lambda x: jitter.get_str_ansi(x).lower())
def kernel32_lstrcmpiW(
jitter)
def kernel32_lstrcmpiW(jitter): my_lstrcmp(jitter, whoami(), lambda x: jitter.get_str_unic(x).lower())
def kernel32_lstrcpy(
jitter)
def kernel32_lstrcpy(jitter): my_strcpy(jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi)
def kernel32_lstrcpyA(
jitter)
def kernel32_lstrcpyA(jitter): my_strcpy(jitter, whoami(), jitter.get_str_ansi, jitter.set_str_ansi)
def kernel32_lstrcpyW(
jitter)
def kernel32_lstrcpyW(jitter): my_strcpy(jitter, whoami(), jitter.get_str_unic, jitter.set_str_unic)
def kernel32_lstrcpyn(
jitter)
def kernel32_lstrcpyn(jitter): ret_ad, args = jitter.func_args_stdcall(["ptr_str1", "ptr_str2", "mlen"]) s2 = jitter.get_str_ansi(args.ptr_str2) if len(s2) >= args.mlen: s2 = s2[:args.mlen - 1] log.info("Copy '%r'", s2) jitter.set_str_ansi(args.ptr_str1, s2) jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
def kernel32_lstrlen(
jitter)
def kernel32_lstrlen(jitter): my_strlen(jitter, whoami(), jitter.get_str_ansi, len)
def kernel32_lstrlenA(
jitter)
def kernel32_lstrlenA(jitter): my_strlen(jitter, whoami(), jitter.get_str_ansi, len)
def kernel32_lstrlenW(
jitter)
def kernel32_lstrlenW(jitter): my_strlen(jitter, whoami(), jitter.get_str_unic, len)
def kernel32_myGetTempPath(
jitter, set_str)
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 mdl2ad(
n)
def mdl2ad(n): return winobjs.nt_mdl_ad + 0x10 * n
def msvcrt_??2@YAPAXI@Z(
jitter)
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)
def msvcrt_??3@YAXPAX@Z(
jitter)
def msvcrt_delete(jitter): ret_ad, args = jitter.func_args_cdecl(["ptr"]) jitter.func_ret_cdecl(ret_ad, 0)
def msvcrt__mbscpy(
jitter)
def msvcrt__mbscpy(jitter): ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"]) s2 = jitter.get_str_unic(args.ptr_str2) jitter.set_str_unic(args.ptr_str1, s2) jitter.func_ret_cdecl(ret_ad, args.ptr_str1)
def msvcrt__ultow(
jitter)
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) jitter.vm.set_mem(args.p, jitter.set_str_unic(s + "\x00")) jitter.func_ret_cdecl(ret_ad, args.p)
def msvcrt__wcsicmp(
jitter)
def msvcrt__wcsicmp(jitter): ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"]) s1 = jitter.get_str_unic(args.ptr_str1) s2 = jitter.get_str_unic(args.ptr_str2) log.debug("%s('%s','%s')" % (whoami(), s1, s2)) jitter.func_ret_cdecl(ret_ad, cmp(s1.lower(), s2.lower()))
def msvcrt__wcsnicmp(
jitter)
def msvcrt__wcsnicmp(jitter): ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2", "count"]) s1 = jitter.get_str_unic(args.ptr_str1) s2 = jitter.get_str_unic(args.ptr_str2) 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__wfopen(
jitter)
def msvcrt__wfopen(jitter): msvcrt_myfopen(jitter, jitter.get_str_unic)
def msvcrt_atexit(
jitter)
def msvcrt_atexit(jitter): ret_ad, _ = jitter.func_args_cdecl(["func"]) jitter.func_ret_cdecl(ret_ad, 0)
def msvcrt_delete(
jitter)
def msvcrt_delete(jitter): ret_ad, args = jitter.func_args_cdecl(["ptr"]) jitter.func_ret_cdecl(ret_ad, 0)
def msvcrt_fclose(
jitter)
def msvcrt_fclose(jitter): ret_ad, args = jitter.func_args_cdecl(['stream']) fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") o = winobjs.handle_pool[fd] # off = o.info.close() jitter.func_ret_cdecl(ret_ad, 0)
def msvcrt_fopen(
jitter)
def msvcrt_fopen(jitter): msvcrt_myfopen(jitter, jitter.get_str_ansi)
def msvcrt_fprintf(
jitter)
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) ret = len(output) log.info("fprintf(%x, '%s') = '%s'" % (args.file, jitter.get_str_ansi(args.fmt), output)) fd = upck32(jitter.vm.get_mem(args.file + 0x10, 4)) 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 msvcrt_fread(
jitter)
def msvcrt_fread(jitter): ret_ad, args = jitter.func_args_cdecl(["buf", "size", "nmemb", "stream"]) fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") data = winobjs.handle_pool[fd].info.read(args.size * args.nmemb) jitter.vm.set_mem(args.buf, data) jitter.func_ret_cdecl(ret_ad, args.nmemb)
def msvcrt_free(
jitter)
def msvcrt_free(jitter): ret_ad, _ = jitter.func_args_cdecl(["ptr"]) jitter.func_ret_cdecl(ret_ad, 0)
def msvcrt_fseek(
jitter)
def msvcrt_fseek(jitter): ret_ad, args = jitter.func_args_cdecl(['stream', 'offset', 'orig']) fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") o = winobjs.handle_pool[fd] o.info.seek(args.offset, args.orig) jitter.func_ret_cdecl(ret_ad, 0)
def msvcrt_ftell(
jitter)
def msvcrt_ftell(jitter): ret_ad, args = jitter.func_args_cdecl(["stream"]) fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") o = winobjs.handle_pool[fd] off = o.info.tell() jitter.func_ret_cdecl(ret_ad, off)
def msvcrt_fwrite(
jitter)
def msvcrt_fwrite(jitter): ret_ad, args = jitter.func_args_cdecl(["buf", "size", "nmemb", "stream"]) fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("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_malloc(
jitter)
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_memcmp(
jitter)
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 msvcrt_memcpy(
jitter)
def msvcrt_memcpy(jitter): ret_ad, args = jitter.func_args_cdecl(['dst', 'src', 'size']) s = jitter.vm.get_mem(args.src, args.size) #log.info("memcpy buf %s" % s.encode("hex")) jitter.vm.set_mem(args.dst, s) jitter.func_ret_cdecl(ret_ad, args.dst)
def msvcrt_memset(
jitter)
def msvcrt_memset(jitter): ret_ad, args = jitter.func_args_cdecl(['addr', 'c', 'size']) jitter.vm.set_mem(args.addr, chr(args.c) * args.size) jitter.func_ret_cdecl(ret_ad, args.addr)
def msvcrt_myfopen(
jitter, get_str)
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_new(
jitter)
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)
def msvcrt_rand(
jitter)
def msvcrt_rand(jitter): ret_ad, _ = jitter.func_args_cdecl(0) jitter.func_ret_stdcall(ret_ad, 0x666)
def msvcrt_realloc(
jitter)
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_rewind(
jitter)
def msvcrt_rewind(jitter): ret_ad, args = jitter.func_args_cdecl(["stream"]) fd = upck32(jitter.vm.get_mem(args.stream + 0x10, 4)) if not fd in winobjs.handle_pool: raise NotImplementedError("Untested case") o = winobjs.handle_pool[fd] # off = o.info.seek(0, 0) jitter.func_ret_cdecl(ret_ad, 0)
def msvcrt_sprintf(
jitter)
def msvcrt_sprintf(jitter): ret_ad, args, output = msvcrt_sprintf_str(jitter, jitter.get_str_ansi) ret = len(output) log.info("sprintf() = '%s'" % (output)) jitter.vm.set_mem(args.string, output + '\x00') return jitter.func_ret_cdecl(ret_ad, ret)
def msvcrt_sprintf_str(
jitter, get_str)
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_srand(
jitter)
def msvcrt_srand(jitter): ret_ad, _ = jitter.func_args_cdecl(['seed']) jitter.func_ret_stdcall(ret_ad, 0)
def msvcrt_strlen(
jitter)
def msvcrt_strlen(jitter): ret_ad, args = jitter.func_args_cdecl(["src"]) s = jitter.get_str_ansi(args.src) jitter.func_ret_cdecl(ret_ad, len(s))
def msvcrt_strrchr(
jitter)
def msvcrt_strrchr(jitter): ret_ad, args = jitter.func_args_cdecl(['pstr','c']) s = jitter.get_str_ansi(args.pstr) c = chr(args.c) 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_swprintf(
jitter)
def msvcrt_swprintf(jitter): ret_ad, args = jitter.func_args_cdecl(['string', 'fmt']) cur_arg, fmt = 2, args.fmt output = get_fmt_args(jitter, fmt, cur_arg, jitter.get_str_unic) ret = len(output) log.info("swprintf('%s') = '%s'" % (jitter.get_str_unic(args.fmt), output)) jitter.vm.set_mem(args.string, output.encode("utf-16le") + '\x00\x00') return jitter.func_ret_cdecl(ret_ad, ret)
def msvcrt_wcscat(
jitter)
def msvcrt_wcscat(jitter): ret_ad, args = jitter.func_args_cdecl(['ptr_str1', 'ptr_str2']) s1 = jitter.get_str_unic(args.ptr_str1) s2 = jitter.get_str_unic(args.ptr_str2) log.info("strcat('%s','%s')" % (s1,s2)) jitter.vm.set_mem(args.ptr_str1, (s1 + s2).encode("utf-16le") + "\x00\x00") jitter.func_ret_cdecl(ret_ad, args.ptr_str1)
def msvcrt_wcscmp(
jitter)
def msvcrt_wcscmp(jitter): ret_ad, args = jitter.func_args_cdecl(["ptr_str1", "ptr_str2"]) s1 = jitter.get_str_unic(args.ptr_str1) s2 = jitter.get_str_unic(args.ptr_str2) log.debug("%s('%s','%s')" % (whoami(), s1, s2)) jitter.func_ret_cdecl(ret_ad, cmp(s1, s2))
def msvcrt_wcscpy(
jitter)
def msvcrt_wcscpy(jitter): return msvcrt__mbscpy(jitter)
def msvcrt_wcslen(
jitter)
def msvcrt_wcslen(jitter): ret_ad, args = jitter.func_args_cdecl(["pwstr"]) s = jitter.get_str_unic(args.pwstr) jitter.func_ret_cdecl(ret_ad, len(s))
def msvcrt_wcsncpy(
jitter)
def msvcrt_wcsncpy(jitter): ret_ad, args = jitter.func_args_cdecl(["dst", "src", "n"]) src = jitter.get_str_unic(args.src) dst = src[:args.n] dst += "\x00\x00" * (args.n-len(dst)+1) jitter.vm.set_mem(args.dst, dst) jitter.func_ret_cdecl(ret_ad, args.dst)
def msvcrt_wcsrchr(
jitter)
def msvcrt_wcsrchr(jitter): ret_ad, args = jitter.func_args_cdecl(['pstr','c']) s = jitter.get_str_unic(args.pstr) c = chr(args.c) 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 my_CreateDirectory(
jitter, funcname, get_str)
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 my_CreateEvent(
jitter, funcname, get_str)
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))
def my_GetEnvironmentVariable(
jitter, funcname, get_str, set_str, mylen)
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 my_GetSystemDirectory(
jitter, funcname, set_str)
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 my_GetVolumeInformation(
jitter, funcname, get_str, set_str)
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) if args.lpvolumenamebuffer: s = "volumename" s = s[:args.nvolumenamesize] set_str(args.lpvolumenamebuffer, s) if args.lpvolumeserialnumber: jitter.vm.set_mem(args.lpvolumeserialnumber, pck32(11111111)) if args.lpmaximumcomponentlength: jitter.vm.set_mem(args.lpmaximumcomponentlength, pck32(0xff)) if args.lpfilesystemflags: jitter.vm.set_mem(args.lpfilesystemflags, pck32(22222222)) if args.lpfilesystemnamebuffer: s = "filesystemname" s = s[:args.nfilesystemnamesize] set_str(args.lpfilesystemnamebuffer, s) jitter.func_ret_stdcall(ret_ad, 1)
def my_lstrcat(
jitter, funcname, get_str)
def my_lstrcat(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) jitter.vm.set_mem(args.ptr_str1, s1 + s2) jitter.func_ret_stdcall(ret_ad, args.ptr_str1)
def my_lstrcmp(
jitter, funcname, get_str)
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 my_strcpy(
jitter, funcname, get_str, set_str)
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 my_strlen(
jitter, funcname, get_str, mylen)
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 ntdll_LdrGetProcedureAddress(
jitter)
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 = jitter.get_str_ansi(p_src) ad = winobjs.runtime_dll.lib_get_add_func(args.libbase, fname) jitter.add_breakpoint(ad, jitter.handle_lib) jitter.vm.set_mem(args.p_ad, pck32(ad)) jitter.func_ret_stdcall(ret_ad, 0)
def ntdll_LdrLoadDll(
jitter)
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 = jitter.get_str_unic(p_src) libname = s.lower() ad = winobjs.runtime_dll.lib_get_add_base(libname) jitter.vm.set_mem(args.modhandle, pck32(ad)) jitter.func_ret_stdcall(ret_ad, 0)
def ntdll_RtlAnsiCharToUnicodeChar(
jitter)
def ntdll_RtlAnsiCharToUnicodeChar(jitter): ret_ad, args = jitter.func_args_stdcall(['ad_ad_ch']) ad_ch = upck32(jitter.vm.get_mem(args.ad_ad_ch, 4)) ch = ord(jitter.vm.get_mem(ad_ch, 1)) jitter.vm.set_mem(args.ad_ad_ch, pck32(ad_ch + 1)) jitter.func_ret_stdcall(ret_ad, ch)
def ntdll_RtlAnsiStringToUnicodeString(
jitter)
def ntdll_RtlAnsiStringToUnicodeString(jitter): ret_ad, args = jitter.func_args_stdcall(["dst", "src", "alloc_str"]) l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8)) s = jitter.get_str_ansi(p_src) s = ("\x00".join(s + "\x00")) l = len(s) + 1 if args.alloc_str: alloc_addr = winobjs.heap.next_addr(l) jitter.vm.add_memory_page( alloc_addr, PAGE_READ | PAGE_WRITE, "\x00" * l, "Alloc in %s ret 0x%X" % (whoami(), ret_ad)) else: alloc_addr = p_src jitter.vm.set_mem(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_RtlCompareMemory(
jitter)
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 ntdll_RtlComputeCrc32(
jitter)
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_RtlEnlargedUnsignedMultiply(
jitter)
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_RtlExtendedIntegerMultiply(
jitter)
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_RtlFindCharInUnicodeString(
jitter)
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_mem(args.pos_ad, pck32(0)) else: ret = 0 jitter.vm.set_mem(args.pos_ad, pck32(pos)) jitter.func_ret_stdcall(ret_ad, ret)
def ntdll_RtlFreeUnicodeString(
jitter)
def ntdll_RtlFreeUnicodeString(jitter): ret_ad, args = jitter.func_args_stdcall(['src']) # l1, l2, p_src = struct.unpack('HHI', jitter.vm.get_mem(args.src, 0x8)) # s = get_str_unic(jitter, p_src) jitter.func_ret_stdcall(ret_ad, 0)
def ntdll_RtlHashUnicodeString(
jitter)
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_mem(args.phout, pck32(hv)) jitter.func_ret_stdcall(ret_ad, 0)
def ntdll_RtlInitAnsiString(
jitter)
def ntdll_RtlInitAnsiString(jitter): ret_ad, args = jitter.func_args_stdcall(["ad_ctx", "ad_str"]) s = jitter.get_str_ansi(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_RtlInitString(
jitter)
def ntdll_RtlInitString(jitter): ret_ad, args = jitter.func_args_stdcall(["pstring", "source"]) s = jitter.get_str_ansi(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_RtlLargeIntegerAdd(
jitter)
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)
def ntdll_RtlLargeIntegerShiftRight(jitter): ret_ad, args = jitter.func_args_stdcall(['a_low', 'a_high', 's_count'])