diff options
| -rw-r--r-- | miasm/tools/seh_helper.py | 7 | ||||
| -rw-r--r-- | miasm/tools/to_c_helper.py | 22 | ||||
| -rw-r--r-- | miasm/tools/win_api.py | 515 |
3 files changed, 514 insertions, 30 deletions
diff --git a/miasm/tools/seh_helper.py b/miasm/tools/seh_helper.py index 6a05bd51..637d3d60 100644 --- a/miasm/tools/seh_helper.py +++ b/miasm/tools/seh_helper.py @@ -41,7 +41,7 @@ cur_seh_ad = FAKE_SEH_B_AD loaded_modules = ["win_dll/kernel32.dll", "win_dll/ntdll.dll"] main_pe = None -main_pe_name = "toto.exe" +main_pe_name = "c:\\xxx\\toto.exe" def build_fake_teb(): """ @@ -140,8 +140,7 @@ def build_fake_inordermodule(modules_name): +0x04c PatchInformation : Ptr32 Void """ - first_name = "\x00".join(main_pe_name+"\x00") - + first_name = "\x00".join(main_pe_name+"\x00\x00") offset_name = 0x700 o = "" @@ -174,7 +173,7 @@ def build_fake_inordermodule(modules_name): #fname = os.path.join('win_dll', m) fname = m bname = os.path.split(fname)[1].upper() - bname = "\x00".join(bname+"\x00") + bname = "\x00".join(bname+"\x00\x00") print "add module", repr(bname) print hex(in_load_order_module_1+i*0x1000) e = pe_init.PE(open(fname, 'rb').read()) diff --git a/miasm/tools/to_c_helper.py b/miasm/tools/to_c_helper.py index f29ccbd4..c65f5b2a 100644 --- a/miasm/tools/to_c_helper.py +++ b/miasm/tools/to_c_helper.py @@ -928,26 +928,32 @@ def updt_pe_from_emul(e): def updt_automod_code(known_blocs): w_ad, w_size = vm_get_last_write_ad(), vm_get_last_write_size() print hex(w_ad), hex(w_size) - #all_bloc_funcs = del_bloc_in_range([bn.b for bn in known_blocs], w_ad, w_ad+w_size/8) known_blocs = del_bloc_in_range(known_blocs, w_ad, w_ad+w_size/8) - code_addr = blocs_to_memory_ranges([bn.b for bn in known_blocs.values()]) merge_memory_ranges(code_addr) - reset_code_bloc_pool_py() + for a, b in code_addr: vm_add_code_bloc(a, b) - - #dump_code_bloc_pool_py() - vm_reset_exception() return known_blocs, code_addr -import random - +def flush_all_blocs(known_blocs): + for ad in known_blocs.keys(): + known_blocs = del_bloc_in_range(known_blocs, ad, ad+1) + code_addr = blocs_to_memory_ranges([bn.b for bn in known_blocs.values()]) + merge_memory_ranges(code_addr) + reset_code_bloc_pool_py() + + for a, b in code_addr: + vm_add_code_bloc(a, b) + vm_reset_exception() + return known_blocs, code_addr + +import random def c_emul_bloc(known_blocs, my_eip): if not my_eip in known_blocs: diff --git a/miasm/tools/win_api.py b/miasm/tools/win_api.py index f483dd19..b0894c4b 100644 --- a/miasm/tools/win_api.py +++ b/miasm/tools/win_api.py @@ -21,6 +21,9 @@ from Crypto.Hash import MD5 import inspect from zlib import crc32 import seh_helper +import os +import time + handle_toolhelpsnapshot = 0xaaaa00 toolhelpsnapshot_info = {} handle_curprocess = 0xaaaa01 @@ -118,7 +121,36 @@ def kernel32_GlobalAlloc(): msize = vm_pop_uint32_t() print whoami(), hex(ret_ad), '(', hex(uflags), hex(msize), ')' - max_ad = get_memory_page_from_min_ad_py(msize) + max_ad = vm_get_memory_page_max_address() + max_ad = (max_ad+0xfff) & 0xfffff000 + + vm_add_memory_page(max_ad, PAGE_READ|PAGE_WRITE, "\x00"*msize) + + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = max_ad + vm_set_gpreg(regs) + +def kernel32_LocalFree(): + ret_ad = vm_pop_uint32_t() + lpvoid = vm_pop_uint32_t() + + print whoami(), hex(ret_ad), '(', hex(lpvoid), ')' + + + regs = vm_get_gpreg() + regs['eip'] = ret_ad + vm_set_gpreg(regs) + + +def kernel32_LocalAlloc(): + ret_ad = vm_pop_uint32_t() + uflags = vm_pop_uint32_t() + msize = vm_pop_uint32_t() + + print whoami(), hex(ret_ad), '(', hex(uflags), hex(msize), ')' + max_ad = vm_get_memory_page_max_address() + max_ad = (max_ad+0xfff) & 0xfffff000 vm_add_memory_page(max_ad, PAGE_READ|PAGE_WRITE, "\x00"*msize) @@ -271,12 +303,11 @@ def kernel32_Process32Next(): vm_set_gpreg(regs) - + def kernel32_GetTickCount(): global tickcount ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' tickcount +=1 @@ -288,7 +319,6 @@ def kernel32_GetTickCount(): def kernel32_GetVersion(): ret_ad = vm_pop_uint32_t() - print whoami(), hex(ret_ad), '(', ')' regs = vm_get_gpreg() @@ -296,6 +326,30 @@ def kernel32_GetVersion(): regs['eax'] = getversion vm_set_gpreg(regs) +def my_GetVersionEx(funcname, set_str): + ret_ad = vm_pop_uint32_t() + ptr_struct = vm_pop_uint32_t() + + print funcname, hex(ret_ad), '(', ')' + + s = struct.pack("IIIII", + 0x114, # struct size + 0x5, # maj vers + 0x2, # min vers + 0x666, # build nbr + 0x2, # platform id + ) + set_str("Service pack 4") + vm_set_mem(ptr_struct, s) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = 1 + vm_set_gpreg(regs) + +def kernel32_GetVersionExA(): + my_GetVersionEx(whoami(), lambda x:x+'\x00') +def kernel32_GetVersionExW(): + my_GetVersionEx(whoami(), lambda x:"\x00".join(list(x+'\x00'))) + def kernel32_GetPriorityClass(): ret_ad = vm_pop_uint32_t() @@ -754,7 +808,9 @@ def user32_SetWindowLongA(): -def kernel32_GetModuleFileNameA(): + + +def my_GetModuleFileName(funcname, set_str): ret_ad = vm_pop_uint32_t() hmodule = vm_pop_uint32_t() lpfilename = vm_pop_uint32_t() @@ -769,19 +825,62 @@ def kernel32_GetModuleFileNameA(): if nsize < len(p): - eax = nsize p = p[:nsize] - else: - eax = len(p) + l = len(p) + print repr(p) - vm_set_mem(lpfilename, p) + vm_set_mem(lpfilename, set_str(p)) - regs = vm_get_gpreg() regs['eip'] = ret_ad regs['eax'] = nsize vm_set_gpreg(regs) + +def kernel32_GetModuleFileNameA(): + my_GetModuleFileName(whoami(), lambda x:x+'\x00') +def kernel32_GetModuleFileNameW(): + my_GetModuleFileName(whoami(), lambda x:"\x00".join(list(x+'\x00'))) + + +def shell32_SHGetSpecialFolderLocation(): + ret_ad = vm_pop_uint32_t() + hwndowner = vm_pop_uint32_t() + nfolder = vm_pop_uint32_t() + ppidl = vm_pop_uint32_t() + print whoami(), hex(hwndowner), hex(nfolder), hex(ppidl) + + vm_set_mem(ppidl, pdw(nfolder)) + + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = 0 + vm_set_gpreg(regs) + + +def my_SHGetPathFromIDListW(funcname, set_str): + ret_ad = vm_pop_uint32_t() + pidl = vm_pop_uint32_t() + ppath = vm_pop_uint32_t() + print whoami(), hex(pidl), hex(ppath) + + if pidl == 7:# CSIDL_STARTUP: + s = "c:\\doc\\user\\startmenu\\programs\\startup" + s = set_str(s) + else: + raise ValueError('pidl not implemented', pidl) + vm_set_mem(ppath, s) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = 1 + vm_set_gpreg(regs) + +def shell32_SHGetPathFromIDListW(): + my_SHGetPathFromIDListW(whoami(), lambda x:"\x00".join(list(x+'\x00'))) +def shell32_SHGetPathFromIDListW(): + my_SHGetPathFromIDListW(whoami(), lambda x:x+'\x00') + + lastwin32error = 0 def kernel32_GetLastError(): ret_ad = vm_pop_uint32_t() @@ -906,10 +1005,14 @@ def kernel32_GetCommandLineA(): ret_ad = vm_pop_uint32_t() print whoami(), hex(ret_ad) - + max_ad = vm_get_memory_page_max_address() + s = "c:\\test.exe"+"\x00" + + vm_add_memory_page(max_ad, PAGE_READ|PAGE_WRITE, s) + regs = vm_get_gpreg() regs['eip'] = ret_ad - regs['eax'] = 1 + regs['eax'] = max_ad vm_set_gpreg(regs) cryptdll_md5_h = {} @@ -999,7 +1102,7 @@ def ntdll_RtlAnsiStringToUnicodeString(): print s s = '\x00'.join(s) + "\x00\x00" if alloc_dst: - ad = get_memory_page_max_address_py() + ad = vm_get_memory_page_max_address() ad = (ad + 0xFFF) & ~0xFFF vm_add_memory_page(ad , PAGE_READ | PAGE_WRITE, s) @@ -1538,16 +1641,301 @@ def my_lstrcmp(funcname, get_str): vm_set_gpreg(regs) def kernel32_lstrcmpA(): - my_lstrcmp('lstrcmpA', get_str_ansi) + my_lstrcmp(whoami(), get_str_ansi) def kernel32_lstrcmpiA(): - my_lstrcmp('lstrcmpiA', lambda x: get_str_ansi(x).lower()) + my_lstrcmp(whoami(), lambda x: get_str_ansi(x).lower()) def kernel32_lstrcmpW(): - my_lstrcmp('lstrcmpA', get_str_unic) + my_lstrcmp(whoami(), get_str_unic) def kernel32_lstrcmpiW(): - my_lstrcmp('lstrcmpiW', lambda x: get_str_unic(x).lower()) + my_lstrcmp(whoami(), lambda x: get_str_unic(x).lower()) + + + +def my_strcpy(funcname, get_str, set_str): + ret_ad = vm_pop_uint32_t() + ptr_str1 = vm_pop_uint32_t() + ptr_str2 = vm_pop_uint32_t() + print "%s (%08x, %08x) (ret @ %08x)" % (funcname, + ptr_str1, ptr_str2, + ret_ad) + s2 = get_str(ptr_str2) + print '%s (%r)' % (funcname, s2) + vm_set_mem(ptr_str1, set_str(s2)) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = ptr_str1 + vm_set_gpreg(regs) + +def kernel32_lstrcpyW(): + my_strcpy(whoami(), get_str_unic, lambda x:x+"\x00\x00") + +def kernel32_lstrcpyA(): + my_strcpy(whoami(), get_str_ansi, lambda x:x+"\x00") + +def my_strlen(funcname, get_str, mylen): + ret_ad = vm_pop_uint32_t() + arg_src = vm_pop_uint32_t() + + print funcname, hex(ret_ad), '(', hex(arg_src), ')' + src = get_str(arg_src) + print funcname, repr(src) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = mylen(src) + vm_set_gpreg(regs) + +def kernel32_lstrlenA(): + my_strlen(whoami(), get_str_ansi, lambda x:len(x)) +def kernel32_lstrlenW(): + my_strlen(whoami(), get_str_unic, lambda x:len(x[::2])) + + +def my_lstrcat(funcname, get_str): + ret_ad = vm_pop_uint32_t() + ptr_str1 = vm_pop_uint32_t() + ptr_str2 = vm_pop_uint32_t() + print "%s (%08x, %08x) (ret @ %08x)" % (funcname, + ptr_str1, ptr_str2, + ret_ad) + s1 = get_str(ptr_str1) + s2 = get_str(ptr_str2) + print '%s (%r, %r)' % (whoami(), s1, s2) + + s = s1+s2 + print repr(s) + vm_set_mem(ptr_str1, s1+s2) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = ptr_str1 + vm_set_gpreg(regs) + +def kernel32_lstrcatA(): + my_lstrcat(whoami(), get_str_ansi) +def kernel32_lstrcatW(): + my_lstrcat(whoami(), get_str_unic) + + +def kernel32_GetUserGeoID(): + ret_ad = vm_pop_uint32_t() + geoclass = vm_pop_uint32_t() + print whoami(), hex(geoclass) + + if geoclass == 14: + ret = 12345678 + elif geoclass == 16: + ret = 55667788 + else: + raise ValueError('unknown geolcass') + + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = ret + vm_set_gpreg(regs) + + +def my_GetVolumeInformation(funcname, get_str, set_str): + ret_ad = vm_pop_uint32_t() + lprootpathname = vm_pop_uint32_t() + lpvolumenamebuffer = vm_pop_uint32_t() + nvolumenamesize = vm_pop_uint32_t() + lpvolumeserialnumber = vm_pop_uint32_t() + lpmaximumcomponentlength = vm_pop_uint32_t() + lpfilesystemflags = vm_pop_uint32_t() + lpfilesystemnamebuffer = vm_pop_uint32_t() + nfilesystemnamesize = vm_pop_uint32_t() + + print funcname,hex(lprootpathname),hex(lpvolumenamebuffer),hex(nvolumenamesize),hex(lpvolumeserialnumber),hex(lpmaximumcomponentlength),hex(lpfilesystemflags),hex(lpfilesystemnamebuffer),hex(nfilesystemnamesize) + + if lprootpathname: + s = get_str(lprootpathname) + print repr(s) + + if lpvolumenamebuffer: + s = "volumename" + s = s[:nvolumenamesize] + vm_set_mem(lpvolumenamebuffer, set_str(s)) + + if lpvolumeserialnumber: + vm_set_mem(lpvolumeserialnumber, pdw(11111111)) + if lpmaximumcomponentlength: + vm_set_mem(lpmaximumcomponentlength, pdw(0xff)) + if lpfilesystemflags: + vm_set_mem(lpfilesystemflags, pdw(22222222)) + + if lpfilesystemnamebuffer: + s = "filesystemname" + s = s[:nfilesystemnamesize] + vm_set_mem(lpfilesystemnamebuffer, set_str(s)) + + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = 1 + vm_set_gpreg(regs) + +def kernel32_GetVolumeInformationA(): + my_GetVolumeInformation(whoami(), get_str_ansi, lambda x:x+"\x00") +def kernel32_GetVolumeInformationW(): + my_GetVolumeInformation(whoami(), get_str_unic, lambda x:"\x00".join(list(x+'\x00'))) + +def kernel32_MultiByteToWideChar(): + ret_ad = vm_pop_uint32_t() + codepage = vm_pop_uint32_t() + dwflags = vm_pop_uint32_t() + lpmultibytestr = vm_pop_uint32_t() + cbmultibyte = vm_pop_uint32_t() + lpwidecharstr = vm_pop_uint32_t() + cchwidechar = vm_pop_uint32_t() + + print whoami(), hex(ret_ad), \ + hex(codepage),hex(dwflags),hex(lpmultibytestr),hex(cbmultibyte),hex(lpwidecharstr),hex(cchwidechar) + src = get_str_ansi(lpmultibytestr)+'\x00' + l = len(src) + print repr(src) + + src = "\x00".join(list(src)) + print repr(src), hex(len(src)) + vm_set_mem(lpwidecharstr, src) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = l + vm_set_gpreg(regs) + +env_variables = {} +def my_GetEnvironmentVariable(funcname, get_str, set_str, mylen): + global env_variables + ret_ad = vm_pop_uint32_t() + lpname = vm_pop_uint32_t() + lpbuffer = vm_pop_uint32_t() + nsize = vm_pop_uint32_t() + + print funcname,hex(lpname), hex(lpbuffer), hex(nsize) + s = get_str(lpname) + if get_str == get_str_unic: + s = s[::2] + if s in env_variables: + v = set_str(env_variables[s]) + else: + print 'WARNING unknown env variable', repr(s) + v = "" + print 'return', repr(v) + vm_set_mem(lpbuffer, v) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = mylen(v) + vm_set_gpreg(regs) + +def my_GetSystemDirectory(funcname, set_str): + ret_ad = vm_pop_uint32_t() + lpbuffer = vm_pop_uint32_t() + usize = vm_pop_uint32_t() + print "%s (%08x, %08x) (ret @ %08x)" % (whoami(), + lpbuffer,usize, + ret_ad) + + s = "c:\\windows\\system32" + l = len(s) + s = set_str(s) + vm_set_mem(lpbuffer, s) + + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = l + vm_set_gpreg(regs) + + +def kernel32_GetSystemDirectoryA(): + my_GetSystemDirectory(whoami(), lambda x:x+'\x00') +def kernel32_GetSystemDirectoryW(): + my_GetSystemDirectory(whoami(), lambda x:"\x00".join(list(x+'\x00'))) + + +def my_CreateDirectory(funcname, get_str): + ret_ad = vm_pop_uint32_t() + lppath = vm_pop_uint32_t() + secattrib = vm_pop_uint32_t() + print "%s (%08x, %08x) (ret @ %08x)" % (funcname, + lppath,secattrib, + ret_ad) + p = get_str(lppath) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = 0x1337 + vm_set_gpreg(regs) + +def kernel32_CreateDirectoryW(): + my_CreateDirectory(whoami(), get_str_unic) +def kernel32_CreateDirectoryW(): + my_CreateDirectory(whoami(), get_str_ansi) + + + +def kernel32_GetEnvironmentVariableA(): + my_GetEnvironmentVariable(whoami(), + get_str_ansi, + lambda x:x+"\x00", + lambda x:len(x)) + +def kernel32_GetEnvironmentVariableW(): + my_GetEnvironmentVariable(whoami(), + get_str_unic, + lambda x:"\x00".join(list(x+"\x00")), + lambda x:len(x[::2])) + + +events_pool = {} +def my_CreateEvent(funcname, get_str): + global events_pool + ret_ad = vm_pop_uint32_t() + lpeventattributes = vm_pop_uint32_t() + bmanualreset = vm_pop_uint32_t() + binitialstate = vm_pop_uint32_t() + lpname = vm_pop_uint32_t() + + print funcname, hex(lpeventattributes), hex(bmanualreset), hex(binitialstate), hex(lpname) + s = get_str(lpname) + print repr(s) + if not s in events_pool: + events_pool[s] = (bmanualreset, binitialstate) + else: + print 'WARNING: known event' + + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = id(s) + vm_set_gpreg(regs) + +def kernel32_CreateEventA(): + my_CreateEvent(whoami(), get_str_ansi) +def kernel32_CreateEventA(): + my_CreateEvent(whoami(), get_str_unic) + + + +def kernel32_WaitForSingleObject(): + ret_ad = vm_pop_uint32_t() + handle = vm_pop_uint32_t() + dwms = vm_pop_uint32_t() + + + t_start = time.time()*1000 + while True: + if dwms and dwms+t_start > time.time()*1000: + ret = 0x102 + break + for k, v in events_pool.items(): + if k != handle: + continue + if events_pool[k][1] == 1: + ret = 0 + break + time.sleep(0.1) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = ret + vm_set_gpreg(regs) def kernel32_SetFileAttributesA(): @@ -1563,7 +1951,6 @@ def kernel32_SetFileAttributesA(): else: eax = 0 vm_set_mem(seh_helper.FS_0_AD+0x34, pdw(3)) - regs = vm_get_gpreg() regs['eip'] = ret_ad @@ -1840,3 +2227,95 @@ def ntdll_memset(): regs['eip'] = ret_ad regs['eax'] = arg_addr vm_set_gpreg(regs) + + + +def shlwapi_PathFindExtensionA(): + ret_ad = vm_pop_uint32_t() + path_ad = vm_pop_uint32_t() + + print whoami(), hex(ret_ad), hex(path_ad) + path = get_str_ansi(path_ad) + print repr(path) + i = path.rfind('.') + if i == -1: + i = path_ad + len(path) + else: + i = path_ad + i + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = i + vm_set_gpreg(regs) + + + +def shlwapi_PathIsFileSpecA(): + ret_ad = vm_pop_uint32_t() + path_ad = vm_pop_uint32_t() + + print whoami(), hex(ret_ad), hex(path_ad) + path = get_str_ansi(path_ad) + print repr(path) + if path.find(':') != -1 and path.find('\\') != -1: + ret = 0 + else: + ret = 1 + + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = ret + vm_set_gpreg(regs) + + +def shlwapi_StrToIntA(): + ret_ad = vm_pop_uint32_t() + i_str_ad = vm_pop_uint32_t() + + print whoami(), hex(ret_ad), hex(i_str_ad) + i_str = get_str_ansi(i_str_ad) + print repr(i_str) + try: + i = int(i_str) + except: + print 'WARNING cannot convert int' + i = 0 + + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = i + vm_set_gpreg(regs) + + + +def user32_IsCharAlphaW(): + ret_ad = vm_pop_uint32_t() + c = vm_pop_uint32_t() + + print whoami(), hex(ret_ad), hex(c) + c = chr(c) + if c.isalpha(): + ret = 1 + else: + ret = 0 + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = ret + vm_set_gpreg(regs) + +def shlwapi_StrCmpNIA(): + ret_ad = vm_pop_uint32_t() + ptr_str1 = vm_pop_uint32_t() + ptr_str2 = vm_pop_uint32_t() + nchar = vm_pop_uint32_t() + print whoami(), hex(ptr_str1), hex(ptr_str2) + + s1 = get_str_ansi(ptr_str1).lower() + s2 = get_str_ansi(ptr_str2).lower() + s1 = s1[:nchar] + s2 = s2[:nchar] + + print repr(s1), repr(s2) + regs = vm_get_gpreg() + regs['eip'] = ret_ad + regs['eax'] = cmp(s1, s2) + vm_set_gpreg(regs) |