diff --git a/speakeasy/winenv/api/kernelmode/ntoskrnl.py b/speakeasy/winenv/api/kernelmode/ntoskrnl.py index ec86fff..4b2a184 100644 --- a/speakeasy/winenv/api/kernelmode/ntoskrnl.py +++ b/speakeasy/winenv/api/kernelmode/ntoskrnl.py @@ -11,6 +11,7 @@ import speakeasy.winenv.defs.registry.reg as regdefs import speakeasy.winenv.defs.windows.windows as windefs import speakeasy.winenv.defs.nt.ntoskrnl as ntos +import speakeasy.windows.objman as objman from speakeasy.const import FILE_OPEN, FILE_WRITE, FILE_READ, MEM_WRITE from speakeasy.errors import ApiEmuError from speakeasy.winenv.api import api @@ -2658,7 +2659,7 @@ def ZwOpenKey(self, emu, argv, ctx={}): hnd = self.reg_open_key(name, create=False) if not hnd: - rv = ddk.STATUS_INVALID_HANDLE + return ddk.STATUS_INVALID_HANDLE if phnd: self.mem_write(phnd, hnd.to_bytes(self.get_ptr_size(), 'little')) @@ -3232,3 +3233,81 @@ def RtlFreeHeap(self, emu, argv, ctx={}): self.mem_free(lpMem) return rv + + @apihook('ZwTerminateProcess', argc=2) + def ZwTerminateProcess(self, emu, argv, ctx={}): + ''' + NTSYSAPI NTSTATUS ZwTerminateProcess( + [in, optional] HANDLE ProcessHandle, + [in] NTSTATUS ExitStatus + ); + ''' + #Copied from TerminateProcess + hProcess, uExitCode = argv + rv = 0 + + proc = emu.get_object_from_handle(hProcess) + if not proc: + return rv + + emu.kill_process(proc) + rv = ddk.STATUS_SUCCESS + + @apihook('ZwOpenProcess', argc=4) + def ZwOpenProcess(self, emu, argv, ctx={}): + ''' + NTSYSAPI NTSTATUS ZwOpenProcess( + [out] PHANDLE ProcessHandle, + [in] ACCESS_MASK DesiredAccess, + [in] POBJECT_ATTRIBUTES ObjectAttributes, + [in, optional] PCLIENT_ID ClientId + + ); + ''' + (hnd, desAccess, pObject, cid) = argv + if not cid: + return ddk.STATUS_INVALID_PARAMETER + cid_obj = self.win.CLIENT_ID(emu.get_ptr_size()) + cid_obj = emu.mem_cast(cid_obj, cid) + oProc = emu.get_object_from_id(cid_obj.UniqueProcess) + hProc = emu.get_object_handle(oProc) + if hProc: + emu.mem_write(hnd,(hProc).to_bytes(4, "little")) + rv = ddk.STATUS_SUCCESS + else: + emu.mem_write(hnd,(0).to_bytes(4, "little")) + rv = ddk.STATUS_INVALID_PARAMETER + return rv + + @apihook('ZwDuplicateObject', argc=7) + def ZwDuplicateObject (self, emu, argv, ctx={}): + ''' + NTSYSAPI NTSTATUS ZwDuplicateObject( + [in] HANDLE SourceProcessHandle, + [in] HANDLE SourceHandle, + [in, optional] HANDLE TargetProcessHandle, + [out, optional] PHANDLE TargetHandle, + [in] ACCESS_MASK DesiredAccess, + [in] ULONG HandleAttributes, + [in] ULONG Options + ); + ''' + #Based on DublicateTokenEx + (hsProccessHandle, hsHandle, htProcessHandle,htHandle, mask, attr, opt) = argv + rv = 0 + + obj = self.get_object_from_handle(hsHandle) + + if obj: + + new_token = emu.new_object(objman.Token) + hnd_new_token = new_token.get_handle() + + if hnd_new_token: + hnd = (htHandle).to_bytes(self.get_ptr_size(), 'little') + self.mem_write(htHandle, hnd) + rv = ddk.STATUS_SUCCESS + else: + rv = ddk.STATUS_INVALID_PARAMETER + + return rv \ No newline at end of file diff --git a/speakeasy/winenv/api/usermode/ntdll.py b/speakeasy/winenv/api/usermode/ntdll.py index 3371974..c1fb308 100644 --- a/speakeasy/winenv/api/usermode/ntdll.py +++ b/speakeasy/winenv/api/usermode/ntdll.py @@ -8,7 +8,7 @@ import speakeasy.winenv.defs.nt.ddk as ddk import speakeasy.winenv.defs.nt.ntoskrnl as ntos import speakeasy.windows.common as winemu - +import speakeasy.winenv.arch as e_arch class Ntdll(api.ApiHandler): @@ -333,4 +333,73 @@ def LdrAccessResource(self, emu, argv, ctx={}): self.mem_write(Resource, offset.to_bytes(4, 'little')) return 0 + + @apihook('wcsstr', argc=2,conv=e_arch.CALL_CONV_CDECL) + def wcsstr(self, emu, argv, ctx={}): + """ + wchar_t *wcsstr( + const wchar_t *str, + const wchar_t *strSearch + ); + """ + #Copied from msvcrt + hay, needle = argv + + if hay: + _hay = self.read_mem_string(hay, 2) + argv[0] = _hay + + if needle: + needle = self.read_mem_string(needle, 2) + argv[1] = needle + + ret = _hay.find(needle) + if ret != -1: + ret = hay + ret + else: + ret = 0 + return ret + + @apihook('towlower', argc=1,conv=e_arch.CALL_CONV_CDECL) + def towlower(self, emu, argv, ctx={}): + """ + int tolower ( int c ); + """ + #Copied from msvcrt + c, = argv + return c | 0x20 + + @apihook('tolower', argc=1,conv=e_arch.CALL_CONV_CDECL) + def tolower(self, emu, argv, ctx={}): + """ + int tolower ( int c ); + """ + #Copied from msvcrt + c, = argv + return c | 0x20 + @apihook('strstr', argc=2, conv=e_arch.CALL_CONV_CDECL) + def strstr(self, emu, argv, ctx={}): + """ + char *strstr( + const char *str, + const char *strSearch + ); + """ + #Copied from msvcrt + hay, needle = argv + if hay: + _hay = self.read_mem_string(hay, 1) + argv[0] = _hay + + if needle: + needle = self.read_mem_string(needle, 1) + argv[1] = needle + + ret = _hay.find(needle) + if ret != -1: + ret = hay + ret + else: + ret = 0 + return ret + diff --git a/speakeasy/winenv/api/usermode/shell32.py b/speakeasy/winenv/api/usermode/shell32.py index eb2b683..b447cc4 100644 --- a/speakeasy/winenv/api/usermode/shell32.py +++ b/speakeasy/winenv/api/usermode/shell32.py @@ -261,3 +261,45 @@ def SHGetFolderPath(self, emu, argv, ctx={}): emu.write_mem_string(path, pszPath, self.get_char_width(ctx)) return 0 + + + @apihook('ShellExecuteExW', argc=1) + def ShellExecuteExW(self, emu, argv, ctx={}): + ''' + BOOL ShellExecuteExW( + [in, out] SHELLEXECUTEINFOW *pExecInfo + ); + ''' + #Based on ShellExecute + pExecInfo, = argv + + cw = self.get_char_width(ctx) + + fn = '' + param = '' + dn = '' + + p_op = int.from_bytes(self.mem_read(pExecInfo + 0xC, 4), "little") + if p_op: + op = self.read_mem_string(p_op, cw) + print(op) + p_fn = int.from_bytes(self.mem_read(pExecInfo + 0x10, 4), "little") + if p_fn: + fn = self.read_mem_string(p_fn, cw) + print(fn) + p_param = int.from_bytes(self.mem_read(pExecInfo + 0x14, 4),"little") + if p_param: + param = self.read_mem_string(p_param, cw) + print(param) + p_dn = int.from_bytes(self.mem_read(pExecInfo + 0x18,4), "little") + if p_dn: + dn = self.read_mem_string(p_dn, cw) + print(dn) + + if dn and fn: + fn = '%s\\%s' % (dn, fn) + + proc = emu.create_process(path=fn, cmdline=param) + self.log_process_event(proc, PROC_CREATE) + + return 33 \ No newline at end of file