diff options
| -rw-r--r-- | miasm2/os_dep/common.py | 30 | ||||
| -rw-r--r-- | miasm2/os_dep/win_api_x86_32.py | 177 |
2 files changed, 110 insertions, 97 deletions
diff --git a/miasm2/os_dep/common.py b/miasm2/os_dep/common.py index 41d24405..7f8caed1 100644 --- a/miasm2/os_dep/common.py +++ b/miasm2/os_dep/common.py @@ -1,10 +1,15 @@ +import os + from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE +BASE_SB_PATH = "file_sb" + + def get_str_ansi(jitter, ad_str, max_char=None): l = 0 tmp = ad_str while ((max_char is None or l < max_char) and - jitter.vm.get_mem(tmp, 1) != "\x00"): + jitter.vm.get_mem(tmp, 1) != "\x00"): tmp += 1 l += 1 return jitter.vm.get_mem(ad_str, l) @@ -14,7 +19,7 @@ def get_str_unic(jitter, ad_str, max_char=None): l = 0 tmp = ad_str while ((max_char is None or l < max_char) and - jitter.vm.get_mem(tmp, 2) != "\x00\x00"): + jitter.vm.get_mem(tmp, 2) != "\x00\x00"): tmp += 2 l += 2 s = jitter.vm.get_mem(ad_str, l) @@ -32,14 +37,13 @@ def set_str_unic(s): return "\x00".join(list(s)) + '\x00' * 3 - class heap(object): "Light heap simulation" addr = 0x20000000 align = 0x1000 size = 32 - mask = (1<< size) - 1 + mask = (1 << size) - 1 def next_addr(self, size): """ @@ -51,7 +55,6 @@ class heap(object): self.addr &= self.mask ^ (self.align - 1) return ret - def alloc(self, jitter, size): """ @jitter: a jitter instance @@ -62,3 +65,20 @@ class heap(object): jitter.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, "\x00" * size) return addr + +def windows_to_sbpath(path): + """Convert a Windows path to a valid filename within the sandbox + base directory. + + """ + path = [elt for elt in path.lower().replace('/', '_').split('\\') if elt] + return os.path.join(BASE_SB_PATH, *path) + + +def unix_to_sbpath(path): + """Convert a POSIX path to a valid filename within the sandbox + base directory. + + """ + path = [elt for elt in path.split('/') if elt] + return os.path.join(BASE_SB_PATH, *path) diff --git a/miasm2/os_dep/win_api_x86_32.py b/miasm2/os_dep/win_api_x86_32.py index 335bac7d..e30ff21f 100644 --- a/miasm2/os_dep/win_api_x86_32.py +++ b/miasm2/os_dep/win_api_x86_32.py @@ -31,8 +31,9 @@ except ImportError: from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE, PAGE_EXEC from miasm2.core.utils import pck16, pck32, upck32, hexdump -from miasm2.os_dep.common \ - import heap, set_str_ansi, set_str_unic, get_str_ansi, get_str_unic +from miasm2.os_dep.common import \ + heap, set_str_ansi, set_str_unic, get_str_ansi, get_str_unic, \ + windows_to_sbpath from miasm2.os_dep.win_api_x86_32_seh import FS_0_AD log = logging.getLogger("win_api_x86_32") @@ -247,8 +248,6 @@ class mdl: 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) @@ -521,69 +520,60 @@ def kernel32_CreateFile(jitter, funcname, get_str): "htemplatefile"]) fname = get_str(jitter, args.lpfilename) log.debug('fname %s', fname) - fname_o = fname[:] ret = 0xffffffff - # test if file is original binary - f = fname_o - """ - if "\\" in fname_o: - f = fname_o[fname_o.rfind('\\')+1:] - else: - f = fname_o - """ - log.debug("%r %r", f.lower(), winobjs.module_path.lower()) - is_original_file = f.lower() == winobjs.module_path.lower() + 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"]: pass elif fname.upper() in ['NUL']: ret = winobjs.module_cur_hwnd else: - # nuxify path - fname = fname.replace('\\', "/").lower() - # go in sandbox files - f = os.path.join('file_sb', fname) + # 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(f, os.R_OK): + if os.access(sb_fname, os.R_OK): # but file exist pass else: raise NotImplementedError("Untested case") # to test - # h = open(f, 'rb+') + # h = open(sb_fname, 'rb+') elif args.dwcreationdisposition == 3: # open_existing - if os.access(f, os.R_OK): - s = os.stat(f) + 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(f, 0x1337) + ret = winobjs.handle_pool.add(sb_fname, 0x1337) else: - h = open(f, 'r+b') - ret = winobjs.handle_pool.add(f, h) + 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(f, os.R_OK): + if os.access(sb_fname, os.R_OK): # file exist # ret = 80 winobjs.lastwin32error = 80 else: - open(f, 'w') - h = open(f, 'r+b') - ret = winobjs.handle_pool.add(f, h) + # 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(f, os.R_OK): - s = os.stat(f) + 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(f, 0x1337) + ret = winobjs.handle_pool.add(sb_fname, 0x1337) else: - h = open(f, 'r+b') - ret = winobjs.handle_pool.add(f, h) + h = open(sb_fname, 'r+b') + ret = winobjs.handle_pool.add(sb_fname, h) else: raise NotImplementedError("Untested case") else: @@ -595,14 +585,14 @@ def kernel32_CreateFile(jitter, funcname, get_str): if is_original_file: # cannot open self in write mode! pass - elif os.access(f, os.R_OK): - s = os.stat(f) + 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(f, 0x1337) + ret = winobjs.handle_pool.add(sb_fname, 0x1337) else: - h = open(f, 'r+b') - ret = winobjs.handle_pool.add(f, h) + 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: @@ -613,13 +603,13 @@ def kernel32_CreateFile(jitter, funcname, get_str): raise NotImplementedError("Untested case") # to test else: # raise NotImplementedError("Untested case") # to test - h = open(f, 'w') - ret = winobjs.handle_pool.add(f, h) + h = open(sb_fname, 'w') + ret = winobjs.handle_pool.add(sb_fname, h) else: raise NotImplementedError("Untested case") - # h = open(f, 'rb+') - # ret = winobjs.handle_pool.add(f, h) + # h = open(sb_fname, 'rb+') + # ret = winobjs.handle_pool.add(sb_fname, h) log.debug('ret %x', ret) jitter.func_ret_stdcall(ret_ad, ret) @@ -722,15 +712,16 @@ def kernel32_VirtualAlloc(jitter): ret_ad, args = jitter.func_args_stdcall(['lpvoid', 'dwsize', 'alloc_type', 'flprotect']) - 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, - 0x100: 0 - } + 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, + 0x100: 0, + } # access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()]) @@ -777,13 +768,13 @@ def kernel32_GetModuleFileName(jitter, funcname, set_str): if args.hmodule in [0, winobjs.hcurmodule]: p = winobjs.module_path[:] elif (winobjs.runtime_dll and - args.hmodule in winobjs.runtime_dll.name2off.values()): + args.hmodule in winobjs.runtime_dll.name2off.values()): name_inv = dict([(x[1], x[0]) for x in winobjs.runtime_dll.name2off.items()]) p = name_inv[args.hmodule] else: - log.warning(('Unknown module 0x%x.' + \ - 'Set winobjs.hcurmodule and retry'), args.hmodule) + log.warning(('Unknown module 0x%x.' + + 'Set winobjs.hcurmodule and retry'), args.hmodule) p = None if p is None: @@ -1692,15 +1683,16 @@ def ntdll_ZwAllocateVirtualMemory(jitter): # ad = upck32(jitter.vm.get_mem(args.lppvoid, 4)) dwsize = upck32(jitter.vm.get_mem(args.pdwsize, 4)) - 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, - 0x100: 0 - } + 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, + 0x100: 0, + } # access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()]) @@ -1853,10 +1845,9 @@ def shlwapi_PathIsDirectoryW(jitter): ret_ad, args = jitter.func_args_stdcall(['ptr_path']) fname = get_str_unic(jitter, args.ptr_path) - fname = fname.replace('\\', "/").lower() - f = os.path.join('file_sb', fname) + sb_fname = windows_to_sbpath(fname) - s = os.stat(f) + s = os.stat(sb_fname) ret = 0 if stat.S_ISDIR(s.st_mode): ret = 1 @@ -2214,15 +2205,16 @@ def kernel32_MapViewOfFile(jitter): length = len(data) log.debug('mapp total: %x', len(data)) - 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, - 0x100: 0 - } + 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, + 0x100: 0, + } # access_dict_inv = dict([(x[1], x[0]) for x in access_dict.items()]) if not args.flprotect in access_dict: @@ -2300,15 +2292,16 @@ def kernel32_GetDiskFreeSpaceW(jitter): def kernel32_VirtualQuery(jitter): ret_ad, args = jitter.func_args_stdcall(["ad", "lpbuffer", "dwl"]) - 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, - 0x100: 0 - } + 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, + 0x100: 0, + } access_dict_inv = dict([(x[1], x[0]) for x in access_dict.iteritems()]) all_mem = jitter.vm.get_all_memory() @@ -2723,25 +2716,25 @@ def msvcrt_myfopen(jitter, func): log.debug(rw) if rw in ['r', 'rb', 'wb+']: - fname = fname.replace('\\', "/").lower() - f = os.path.join('file_sb', fname) - h = open(f, rw) - eax = winobjs.handle_pool.add(f, h) + 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) #pdw(0x11112222) jitter.vm.set_mem(alloc_addr, pp) - else: - raise ValueError('unknown access mode %s'%rw) + raise ValueError('unknown access mode %s' % rw) jitter.func_ret_cdecl(ret_ad, alloc_addr) + def msvcrt__wfopen(jitter): msvcrt_myfopen(jitter, get_str_unic) + def msvcrt_fopen(jitter): msvcrt_myfopen(jitter, get_str_ansi) |