From 96c26a2a800932f54ca19e4991cb89437fee99d5 Mon Sep 17 00:00:00 2001 From: dmsft Date: Tue, 9 Apr 2024 22:05:03 +0200 Subject: [PATCH 1/5] Add API hook for msvcrt!_errno() --- speakeasy/winenv/api/usermode/msvcrt.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/speakeasy/winenv/api/usermode/msvcrt.py b/speakeasy/winenv/api/usermode/msvcrt.py index 82548b6..ab73f19 100644 --- a/speakeasy/winenv/api/usermode/msvcrt.py +++ b/speakeasy/winenv/api/usermode/msvcrt.py @@ -40,6 +40,7 @@ def __init__(self, emu): self.wintypes = windef self.tick_counter = TICK_BASE + self.errno_t = None super(Msvcrt, self).__get_hook_attrs__(self) @@ -1667,3 +1668,17 @@ def _snwprintf(self, emu, argv, ctx={}): argv = [buf, cnt, fmt] + argv argv[2] = fmt_str return len(fin) + + @apihook('_errno', argc=0) + def _errno(self, emu, argv, ctx={}): + ''' + ''' + _VAL = 0x0C + + if not self.errno_t: + self.errno_t = self.mem_alloc(4, tag='api.msvcrt._errno') + self.mem_write(self.errno_t, _VAL.to_bytes(4, 'little')) + + return self.errno_t + + From e3677a46ce8382845cd8a85c672b189bbb86561b Mon Sep 17 00:00:00 2001 From: dmsft Date: Tue, 9 Apr 2024 22:08:07 +0200 Subject: [PATCH 2/5] Add multiple API hooks CreateSemaphoreW SetThreadStackGuarantee SetThreadDescription InitOnceBeginInitialize These are just empty shells, enough to emulate through some samples. --- speakeasy/winenv/api/usermode/kernel32.py | 46 +++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/speakeasy/winenv/api/usermode/kernel32.py b/speakeasy/winenv/api/usermode/kernel32.py index 30dc5f1..71e5009 100644 --- a/speakeasy/winenv/api/usermode/kernel32.py +++ b/speakeasy/winenv/api/usermode/kernel32.py @@ -6064,3 +6064,49 @@ def WaitForSingleObjectEx(self, emu, argv, ctx={}): def GetProfileInt(self, emu, argv, ctx={}): _, _, nDefault = argv return nDefault + + @apihook('CreateSemaphoreW', argc=4) + def CreateSemaphoreW(self, emu, argv, ctx={}): + ''' + HANDLE CreateSemaphoreW( + [in, optional] LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, + [in] LONG lInitialCount, + [in] LONG lMaximumCount, + [in, optional] LPCWSTR lpName + ); + ''' + return 0 + + @apihook('SetThreadStackGuarantee', argc=1) + def SetThreadStackGuarantee(self, emu, argv, ctx={}): + ''' + BOOL SetThreadStackGuarantee( + [in, out] PULONG StackSizeInBytes + ); + ''' + return 1 + + @apihook('SetThreadDescription', argc=2) + def SetThreadDescription(self, emu, argv, ctx={}): + ''' + HRESULT SetThreadDescription( + [in] HANDLE hThread, + [in] PCWSTR lpThreadDescription + ); + ''' + return windefs.ERROR_SUCCESS + + @apihook('InitOnceBeginInitialize', argc=4) + def InitOnceBeginInitialize(self, emu, argv, ctx={}): + ''' + BOOL InitOnceBeginInitialize( + [in, out] LPINIT_ONCE lpInitOnce, + [in] DWORD dwFlags, + [out] PBOOL fPending, + [out, optional] LPVOID *lpContext + ); + ''' + # _, dwFlags, _, _ = argv + return 1 + + From 0b2fef2b7d503bf886eb6dcc5df8cab05384af9e Mon Sep 17 00:00:00 2001 From: dmsft Date: Tue, 9 Apr 2024 22:53:48 +0200 Subject: [PATCH 3/5] Add API fputc() --- speakeasy/winenv/api/usermode/msvcrt.py | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/speakeasy/winenv/api/usermode/msvcrt.py b/speakeasy/winenv/api/usermode/msvcrt.py index ab73f19..8325773 100644 --- a/speakeasy/winenv/api/usermode/msvcrt.py +++ b/speakeasy/winenv/api/usermode/msvcrt.py @@ -1680,5 +1680,14 @@ def _errno(self, emu, argv, ctx={}): self.mem_write(self.errno_t, _VAL.to_bytes(4, 'little')) return self.errno_t - - + + @apihook('fputc', argc=2) + def fputc(self, emu, argv, ctx={}): + ''' + int fputc( + int c, + FILE *stream + ); + ''' + c, _ = argv + return c From 9f5a6506df4c81e63fd0e4db08bdbd05ac62390c Mon Sep 17 00:00:00 2001 From: dmsft Date: Tue, 9 Apr 2024 23:36:36 +0200 Subject: [PATCH 4/5] Add API signal() --- speakeasy/winenv/api/usermode/msvcrt.py | 32 +++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/speakeasy/winenv/api/usermode/msvcrt.py b/speakeasy/winenv/api/usermode/msvcrt.py index 8325773..cd8c4be 100644 --- a/speakeasy/winenv/api/usermode/msvcrt.py +++ b/speakeasy/winenv/api/usermode/msvcrt.py @@ -16,6 +16,23 @@ RAND_BASE = 0 TICK_BASE = 86400000 # 1 day in millisecs +# Signal types +SIGINT = 2 # interrupt +SIGILL = 4 # illegal instruction - invalid function image +SIGFPE = 8 # floating point exception +SIGSEGV = 11 # segment violation +SIGTERM = 15 # Software termination signal from kill +SIGBREAK = 21 # Ctrl-Break sequence +SIGABRT = 22 # abnormal termination triggered by abort call + +# Signal action codes +SIG_DFL = 0 # default signal action +SIG_IGN = 1 # ignore signal +SIG_GET = 2 # return current value +SIG_SGE = 3 # signal gets error +SIG_ACK = 4 # acknowledge +SIG_ERR = -1 # signal error value + class Msvcrt(api.ApiHandler): """ @@ -1691,3 +1708,18 @@ def fputc(self, emu, argv, ctx={}): ''' c, _ = argv return c + + @apihook('signal', argc=2) + def signal(self, emu, argv, ctx={}): + ''' + void __cdecl *signal( + int sig, + int (*func)(int, int) + ); + ''' + sig, _ = argv + + if sig in [SIGINT, SIGILL, SIGFPE, SIGSEGV, SIGTERM, SIGBREAK, SIGABRT]: + return SIG_IGN + else: + return SIG_ERR \ No newline at end of file From ab563cb25c385759af2e48d551e228f13a86c538 Mon Sep 17 00:00:00 2001 From: dmsft Date: Thu, 11 Apr 2024 22:49:11 +0200 Subject: [PATCH 5/5] Update speakeasy/winenv/api/usermode/kernel32.py Co-authored-by: Willi Ballenthin --- speakeasy/winenv/api/usermode/kernel32.py | 1 - 1 file changed, 1 deletion(-) diff --git a/speakeasy/winenv/api/usermode/kernel32.py b/speakeasy/winenv/api/usermode/kernel32.py index 71e5009..fed76a7 100644 --- a/speakeasy/winenv/api/usermode/kernel32.py +++ b/speakeasy/winenv/api/usermode/kernel32.py @@ -6106,7 +6106,6 @@ def InitOnceBeginInitialize(self, emu, argv, ctx={}): [out, optional] LPVOID *lpContext ); ''' - # _, dwFlags, _, _ = argv return 1