#! /usr/bin/env python2 #-*- coding:utf-8 -*- import unittest import logging from miasm2.analysis.machine import Machine import miasm2.os_dep.win_api_x86_32 as winapi from miasm2.core.utils import pck32 from miasm2.jitter.csts import PAGE_READ, PAGE_WRITE machine = Machine("x86_32") jit = machine.jitter() jit.init_stack() heap = winapi.winobjs.heap class TestWinAPI(unittest.TestCase): def test_DebuggingFunctions(self): # BOOL WINAPI IsDebuggerPresent(void); jit.push_uint32_t(0) # @return winapi.kernel32_IsDebuggerPresent(jit) vBool = jit.cpu.EAX self.assertFalse(vBool) def test_msvcrt_sprintf(self): def alloc_str(s): s += "\x00" ptr = heap.alloc(jit, len(s)) jit.vm.set_mem(ptr, s) return ptr fmt = alloc_str("'%s' %d") str_ = alloc_str("coucou") buf = heap.alloc(jit,1024) jit.push_uint32_t(1111) jit.push_uint32_t(str_) jit.push_uint32_t(fmt) jit.push_uint32_t(buf) jit.push_uint32_t(0) # ret_ad winapi.msvcrt_sprintf(jit) ret = jit.get_str_ansi(buf) self.assertEqual(ret, "'coucou' 1111") def test_msvcrt_swprintf(self): def alloc_str(s): s = s.encode("utf-16le") s += "\x00\x00" ptr = heap.alloc(jit, len(s)) jit.vm.set_mem(ptr, s) return ptr fmt = alloc_str("'%s' %d") str_ = alloc_str("coucou") buf = heap.alloc(jit,1024) jit.push_uint32_t(1111) jit.push_uint32_t(str_) jit.push_uint32_t(fmt) jit.push_uint32_t(buf) jit.push_uint32_t(0) # ret_ad winapi.msvcrt_swprintf(jit) ret = jit.get_str_unic(buf) self.assertEqual(ret, "'coucou' 1111") def test_msvcrt_realloc(self): jit.push_uint32_t(10) jit.push_uint32_t(0) # ret_ad winapi.msvcrt_malloc(jit) ptr = jit.cpu.EAX jit.push_uint32_t(20) jit.push_uint32_t(ptr) jit.push_uint32_t(0) # ret_ad winapi.msvcrt_realloc(jit) ptr2 = jit.cpu.EAX self.assertNotEqual(ptr, ptr2) self.assertEqual(heap.get_size(jit.vm,ptr2), 20) def test_GetCurrentDirectory(self): # DWORD WINAPI GetCurrentDirectory(size, buf) # Test with a buffer long enough addr = 0x80000 size = len(winapi.winobjs.cur_dir)+1 jit.vm.add_memory_page(addr, PAGE_READ | PAGE_WRITE, "\x00" * (size), "") jit.push_uint32_t(addr) # buf jit.push_uint32_t(size) # size jit.push_uint32_t(0) # @return winapi.kernel32_GetCurrentDirectoryA(jit) dir_ = jit.get_str_ansi(addr) size_ret = jit.cpu.EAX self.assertEqual(len(dir_), size_ret) # Test with a buffer too small jit.vm.set_mem(addr, "\xFF"*size) jit.push_uint32_t(addr) # buf jit.push_uint32_t(5) # size jit.push_uint32_t(0) # @return winapi.kernel32_GetCurrentDirectoryA(jit) size_ret = jit.cpu.EAX self.assertEqual(len(dir_)+1, size_ret) dir_short = jit.get_str_ansi(addr) self.assertEqual(dir_short, dir_[:4]) def test_MemoryManagementFunctions(self): # HGLOBAL WINAPI GlobalAlloc(_In_ UINT uFlags, _In_ SIZE_T dwBytes); jit.push_uint32_t(10) # dwBytes jit.push_uint32_t(0) # uFlags jit.push_uint32_t(0) # @return winapi.kernel32_GlobalAlloc(jit) hMem = jit.cpu.EAX self.assertTrue(hMem) # HGLOBAL WINAPI GlobalFree(_In_ HGLOBAL hMem); jit.push_uint32_t(hMem) # hMem jit.push_uint32_t(0) # @return winapi.kernel32_GlobalFree(jit) hMem = jit.cpu.EAX self.assertFalse(hMem) # LPVOID WINAPI HeapAlloc(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ SIZE_T dwBytes); jit.push_uint32_t(10) # dwBytes jit.push_uint32_t(0) # dwFlags jit.push_uint32_t(0) # hHeap jit.push_uint32_t(0) # @return winapi.kernel32_HeapAlloc(jit) lpMem = jit.cpu.EAX self.assertTrue(lpMem) # BOOL WINAPI HeapFree(_In_ HANDLE hHeap, _In_ DWORD dwFlags, _In_ LPVOID lpMem); jit.push_uint32_t(lpMem) # lpMem jit.push_uint32_t(0) # dwFlags jit.push_uint32_t(0) # hHeap jit.push_uint32_t(0) # @return winapi.kernel32_HeapFree(jit) vBool = jit.cpu.EAX self.assertTrue(vBool) # HLOCAL WINAPI LocalAlloc(_In_ UINT uFlags, _In_ SIZE_T uBytes); jit.push_uint32_t(10) # uBytes jit.push_uint32_t(0) # uFlags jit.push_uint32_t(0) # @return winapi.kernel32_LocalAlloc(jit) hMem = jit.cpu.EAX self.assertTrue(hMem) # HLOCAL WINAPI LocalFree(_In_ HLOCAL hMem); jit.push_uint32_t(hMem) # hMem jit.push_uint32_t(0) # @return winapi.kernel32_LocalFree(jit) hMem = jit.cpu.EAX self.assertFalse(hMem) def test_ProcessAndThreadFunctions(self): # HANDLE WINAPI GetCurrentProcess(void); jit.push_uint32_t(0) # @return winapi.kernel32_GetCurrentProcess(jit) hProc = jit.cpu.EAX self.assertTrue(hProc) # DWORD WINAPI GetCurrentProcessId(void); jit.push_uint32_t(0) # @return winapi.kernel32_GetCurrentProcessId(jit) dwProc = jit.cpu.EAX self.assertTrue(dwProc) def test_SystemInformationFunctions(self): # DWORD WINAPI GetVersion(void); jit.push_uint32_t(0) # @return winapi.kernel32_GetVersion(jit) dwVer = jit.cpu.EAX self.assertTrue(dwVer) # BOOL WINAPI GetVersionEx(_Inout_ LPOSVERSIONINFO lpVersionInfo); jit.vm.set_mem(jit.stack_base, pck32(0x9c)) jit.push_uint32_t(jit.stack_base) # lpVersionInfo jit.push_uint32_t(0) # @return winapi.kernel32_GetVersionExA(jit) vBool = jit.cpu.EAX self.assertTrue(vBool) def test_TimeFunctions(self): # DWORD WINAPI GetTickCount(void); jit.push_uint32_t(0) # @return winapi.kernel32_GetTickCount(jit) dwTime = jit.cpu.EAX self.assertTrue(dwTime) def test_ToolHelpFunctions(self): # HANDLE WINAPI CreateToolhelp32Snapshot(_In_ DWORD dwFlags, _In_ DWORD th32ProcessID); jit.push_uint32_t(0) # th32ProcessID jit.push_uint32_t(0) # dwFlags jit.push_uint32_t(0) # @return winapi.kernel32_CreateToolhelp32Snapshot(jit) hSnap = jit.cpu.EAX self.assertTrue(hSnap) # BOOL WINAPI Process32First(_In_ HANDLE hSnapshot, _Inout_ LPPROCESSENTRY32 lppe); jit.push_uint32_t(jit.stack_base) # lppe jit.push_uint32_t(hSnap) # hSnapshot jit.push_uint32_t(0) # @return winapi.kernel32_Process32First(jit) vBool = jit.cpu.EAX self.assertTrue(vBool) # BOOL WINAPI Process32Next(_In_ HANDLE hSnapshot, _Out_ LPPROCESSENTRY32 lppe); for i in xrange(3, -1, -1): jit.push_uint32_t(jit.stack_base) # lppe jit.push_uint32_t(hSnap) # hSnapshot jit.push_uint32_t(0) # @return winapi.kernel32_Process32Next(jit) vBool = jit.cpu.EAX if i: self.assertTrue(vBool) else: self.assertFalse(vBool) if __name__ == '__main__': testsuite = unittest.TestLoader().loadTestsFromTestCase(TestWinAPI) report = unittest.TextTestRunner(verbosity=2).run(testsuite) exit(len(report.errors + report.failures))