diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 1e2114d..f7c3058 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,12 +1,12 @@
# Contributing guidelines
-**English** | [русский](../../wiki/CONTRIBUTING-(русский)) | [Français](../../wiki/CONTRIBUTING-(Français)) | [Deutsch](../../wiki/CONTRIBUTING-(Deutsch)) | [Magyar](../../wiki/CONTRIBUTING-(Magyar)) | [Português Brasileiro](../../wiki/CONTRIBUTING-(Português-Brasileiro)) | [Italiano](../../wiki/CONTRIBUTING-(Italiano)) | [Español](../../wiki/CONTRIBUTING-(Español))
+**English** | [Community translations](https://github.com/zeffy/wufuc/wiki)
## Reporting an issue [](https://isitmaintained.com/project/zeffy/wufuc)
#### Before you create an issue, please make sure of the following:
-- Are you using at least the [latest stable version](../../releases/latest)?
+- Are you using at least the [latest stable version](https://github.com/zeffy/wufuc/releases/latest)?
- Have you tried restarting your computer?
#### After you've confirmed those things, please create an issue and include the following information:
diff --git a/DONATE.md b/DONATE.md
index cbe58e8..40b0f75 100644
--- a/DONATE.md
+++ b/DONATE.md
@@ -1,13 +1,14 @@
# Help support the development of wufuc
-Thanks for showing an interest in donating to the development of wufuc!
-While any support is very highly appreciated please keep in mind that donating will not guarantee you better support or other perks, just a warm fuzzy feeling knowing you really helped me out. :)
+Thanks for showing an interest in donating!
+
+While any support is very highly appreciated, please keep in mind that donations should be considered gifts for my past efforts towards this project, and not made with the assumption of continued support. All donations go to the project maintainer, [**@zeffy**](https://github.com/zeffy).
## Donate Bitcoin
-- [**Donate Bitcoin on
**](https://admin.gear.mycelium.com/gateways/3554/orders/new)
+- [**Donate Bitcoin on Mycelium Gear**](https://admin.gear.mycelium.com/gateways/3554/orders/new)
## Other donation options
-Currently I'm only accepting Bitcoin, but I'm open to adding other ways of donating as long as they respect my privacy.
-If you know of a donation platform that fits this criteria and would like me to include it as an option, feel free to [create an issue](https://github.com/zeffy/wufuc/issues/new) and I will look into it.
+Currently I'm only accepting Bitcoin, but I'm open to adding other ways of donating.
+If you know of a good donation platform, feel free to [create an issue](https://github.com/zeffy/wufuc/issues/new) and I will look into it.
diff --git a/README.md b/README.md
index 62f45d9..d9305db 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,23 @@
-# wufuc [](https://ci.appveyor.com/project/zeffy/wufuc) [](https://isitmaintained.com/project/zeffy/wufuc)
+# wufuc
+[](https://admin.gear.mycelium.com/gateways/3554/orders/new) [](https://ci.appveyor.com/project/zeffy/wufuc) [](https://t.me/joinchat/HEo6LUvV_83O92WzbYXLeQ) [](https://github.com/zeffy/wufuc/releases/latest)
-**English** | [русский](../../wiki/README-(русский)) | [Français](../../wiki/README-(Français)) | [Deutsch](../../wiki/README-(Deutsch)) | [Magyar](../../wiki/README-(Magyar)) | [Português Brasileiro](../../wiki/README-(Português-Brasileiro)) | [Italiano](../../wiki/README-(Italiano)) | [Español](../../wiki/README-(Español))
+**English** | [Community translations](https://github.com/zeffy/wufuc/wiki)
Disables the "Unsupported Hardware" message in Windows Update, and allows you to continue installing updates on Windows 7 and 8.1 systems with Intel Kaby Lake, AMD Ryzen, or other unsupported processors.
-## Downloads [](../../releases)
+## Downloads
-- [**Click here for the latest stable version**](../../releases/latest)
+[**Latest stable build**](https://github.com/zeffy/wufuc/releases/latest)
-- [~~Unstable builds~~](https://ci.appveyor.com/project/zeffy/wufuc) **Discontinued until AppVeyor adds WDK support for Visual Studio 2017 ([appveyor/ci#1554](https://github.com/appveyor/ci/issues/1554))**
+[Unstable builds](https://ci.appveyor.com/project/zeffy/wufuc)
+
+## Donate
+
+[**Click here for donation options!**](https://github.com/zeffy/wufuc/blob/master/DONATE.md)
## Preface
-The changelog for Windows updates KB4012218 and KB4012219 included the following:
+The release notes for Windows updates KB4012218 and KB4012219 included the following:
> Enabled detection of processor generation and hardware support when PC tries to scan or download updates through Windows Update.
@@ -23,17 +28,17 @@ This was essentially a big middle finger to anyone who decides to not "upgrade"
I've received user reports of the following CPUs all being blocked from receiving updates:
-- [Intel Atom Z530](../../issues/7)
-- [Intel Atom D525](../../issues/34)
-- [Intel Core i5-M 560](../../issues/23)
-- [Intel Core i5-4300M](../../issues/24)
-- [Intel Pentium B940](../../issues/63)
-- [AMD FX-8350](../../issues/32)
-- [AMD Turion 64 Mobile Technology ML-34](../../issues/80)
+- [Intel Atom Z530](https://github.com/zeffy/wufuc/issues/7)
+- [Intel Atom D525](https://github.com/zeffy/wufuc/issues/34)
+- [Intel Core i5-M 560](https://github.com/zeffy/wufuc/issues/23)
+- [Intel Core i5-4300M](https://github.com/zeffy/wufuc/issues/24)
+- [Intel Pentium B940](https://github.com/zeffy/wufuc/issues/63)
+- [AMD FX-8350](https://github.com/zeffy/wufuc/issues/32)
+- [AMD Turion 64 Mobile Technology ML-34](https://github.com/zeffy/wufuc/issues/80)
## Bad Microsoft!
-If you are interested, you can read my original write up on discovering the CPU check [here](../../tree/old-kb4012218-19).
+If you are interested, you can read my original write up on discovering the CPU check [here](https://github.com/zeffy/wufuc/tree/old-kb4012218-19).
## Features
@@ -42,7 +47,7 @@ If you are interested, you can read my original write up on discovering the CPU
- Completely free (as in freedom) software.
- Does not modify any system files.
- Byte pattern-based patching, which means it will usually keep working even after new updates come out.
-- Absolutely zero dependencies.
+- No dependencies.
## How it works
@@ -50,18 +55,21 @@ Basically, inside a system file called `wuaueng.dll` there are two functions res
`IsDeviceServiceable` simply calls `IsCPUSupported` once, and then re-uses the result that it receives on subsequent calls.
My patch takes advantage of this behavior by patching a couple of boolean values and basically making Windows Update think that it has already checked your processor, and the result was that it is indeed supported.
-- The installer registers wufuc as a custom Application Verifier provider.
-- When a `svchost.exe` process starts, the Windows PE loader automatically loads wufuc into its virtual address space.
-- After that, wufuc will then check the command line of the process it was loaded into, then install some API hooks when appropriate:
- * `LoadLibraryExW` hook will automatically patch `wuaueng.dll` as soon as it is loaded.
- * `RegQueryValueExW` hook is necessary to provide compatibility with attempts by other third-parties at bypassing the CPU check. (see issue [#100](../../issues/100))
-- If wufuc gets loaded by a `svchost.exe` process that isn't related to Windows Update, it goes into a dormant state and no hooks are applied.
+- The installer registers a scheduled task that automatically starts wufuc on system boot/user log on.
+- Depending on how the Windows Update service is configured to run, wufuc will:
+ * **Shared process**: inject itself into the service host process that Windows Update will run in when it starts.
+ * **Own process**: wait for the Windows Update service to start and then inject into it.
+- After that, wufuc will install some API hooks when appropriate:
+ * `LoadLibraryExW` hook will automatically hook the `IsDeviceServiceable()` function inside `wuaueng.dll` when it is loaded.
+ * `RegQueryValueExW` hook is necessary to provide compatibility with [UpdatePack7R2](../../issues/100). This hook not applied when `wuauserv` is configured to run in its own process.
-## How to deploy wufuc using Group Policy
+## FAQ
+
+### How to deploy wufuc using Group Policy
[There is a tutorial on the Advanced Installer website that explains how to do this](http://www.advancedinstaller.com/user-guide/tutorial-gpo.html).
-## How to use unattended feature in the batch setup scripts
+### How to use unattended feature in the batch setup scripts
`install_wufuc.bat` and `uninstall_wufuc.bat` both support two command line parameters that can be used alone, or combined to change the behavior of the scripts:
@@ -70,22 +78,21 @@ My patch takes advantage of this behavior by patching a couple of boolean values
These must be used from an elevated command line prompt.
-## What to do if you get stuck on a black screen with just a cursor after the Windows boot animation
+### How to manually remove wufuc v0.8.0.x when it is impossible to uninstall it normally
-This will happen if wufuc somehow manages to crash the `svchost.exe` process that is responsible for displaying the login screen.
-Normally this should **never ever** happen, because wufuc goes dormant in `svchost.exe` processes that are unrelated to Windows Update.
-I have only encountered this during development with very unstable code, or by causing it intentionally.
+This only applies to wufuc version 0.8.0.x, which was only available for download for a short period of time. Other versions are unaffected.
-However, just in case this does happen to someone, here is how to fix it:
+There was a fundamental issue with the method I tried using in this version that caused very serious system instability, such as User Account Control breaking, getting a black screen with just a cursor at boot or after logging out, or very slow overall system performance from multiple services crashing repeatedly which would eventually end in a blue screen of death. Many of these issues unfortunately made uninstalling wufuc nearly impossible. I apologize for any inconvenience this version of wufuc may have caused.
+
+#### To manually uninstall wufuc v0.8.0.x:
1. [Boot into Safe Mode with Command Prompt](https://support.microsoft.com/en-us/help/17419/windows-7-advanced-startup-options-safe-mode).
2. In the command prompt type `regedit` and press enter.
3. Navigate to the key `HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options`
4. Expand the `Image File Execution Options` tree.
5. Locate the `svchost.exe` sub key, right-click it and press **Delete**.
-6. Reboot.
-7. You should be able to log in normally again.
-8. **If this happens to you, please report it in the issues tab so I can try to figure out what is causing the crash!**
+6. Reboot, and you should be able to log in normally again.
+7. Open Add and Remove Programs, locate and run the normal wufuc uninstaller to complete the removal process.
## Sponsors
@@ -96,6 +103,5 @@ Advanced Installer's intuitive and friendly user interface allowed me to quickly
## Special thanks
-- Alex Ionescu ([@ionescu007](https://github.com/ionescu007)) for his [_"Hooking Nirvana"_ presentation at REcon 2015](https://www.youtube.com/watch?v=bqU0y4FzvT0) and its corresponding [repository of example code](https://github.com/ionescu007/HookingNirvana).
- Wen Jia Liu ([@wj32](https://github.com/wj32)) for his awesome program [Process Hacker](https://github.com/processhacker2/processhacker) which has been absolutely instrumental in the development of wufuc, and also for his [`phnt`](https://github.com/processhacker2/processhacker/tree/master/phnt) headers.
- Duncan Ogilvie ([@mrexodia](https://github.com/mrexodia)) for his [`patternfind.cpp`](https://github.com/x64dbg/x64dbg/blob/development/src/dbg/patternfind.cpp) algorithm from [x64dbg](https://github.com/x64dbg/x64dbg).
diff --git a/phnt/README.md b/inc/phnt/README.md
similarity index 100%
rename from phnt/README.md
rename to inc/phnt/README.md
diff --git a/phnt/include/ntdbg.h b/inc/phnt/ntdbg.h
similarity index 100%
rename from phnt/include/ntdbg.h
rename to inc/phnt/ntdbg.h
diff --git a/phnt/include/ntexapi.h b/inc/phnt/ntexapi.h
similarity index 95%
rename from phnt/include/ntexapi.h
rename to inc/phnt/ntexapi.h
index 7602609..033d796 100644
--- a/phnt/include/ntexapi.h
+++ b/inc/phnt/ntexapi.h
@@ -833,7 +833,8 @@ typedef enum _WNF_DATA_SCOPE
WnfDataScopeSystem,
WnfDataScopeSession,
WnfDataScopeUser,
- WnfDataScopeProcess
+ WnfDataScopeProcess,
+ WnfDataScopeMachine // REDSTONE3
} WNF_DATA_SCOPE;
typedef struct _WNF_TYPE_ID
@@ -1194,7 +1195,6 @@ NtAllocateUuids(
// rev
// private
-// source:http://www.microsoft.com/whdc/system/Sysinternals/MoreThan64proc.mspx
typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation, // q: SYSTEM_BASIC_INFORMATION
@@ -1241,12 +1241,12 @@ typedef enum _SYSTEM_INFORMATION_CLASS
SystemVerifierRemoveDriverInformation, // s (requires SeDebugPrivilege)
SystemProcessorIdleInformation, // q: SYSTEM_PROCESSOR_IDLE_INFORMATION
SystemLegacyDriverInformation, // q: SYSTEM_LEGACY_DRIVER_INFORMATION
- SystemCurrentTimeZoneInformation, // q
+ SystemCurrentTimeZoneInformation, // q; s: RTL_TIME_ZONE_INFORMATION
SystemLookasideInformation, // q: SYSTEM_LOOKASIDE_INFORMATION
SystemTimeSlipNotification, // s (requires SeSystemtimePrivilege)
SystemSessionCreate, // not implemented
SystemSessionDetach, // not implemented
- SystemSessionInformation, // not implemented
+ SystemSessionInformation, // not implemented (SYSTEM_SESSION_INFORMATION)
SystemRangeStartInformation, // q: SYSTEM_RANGE_START_INFORMATION // 50
SystemVerifierInformation, // q: SYSTEM_VERIFIER_INFORMATION; s (requires SeDebugPrivilege)
SystemVerifierThunkExtend, // s (kernel-mode only)
@@ -1266,8 +1266,8 @@ typedef enum _SYSTEM_INFORMATION_CLASS
SystemBigPoolInformation, // q: SYSTEM_BIGPOOL_INFORMATION
SystemSessionPoolTagInformation, // q: SYSTEM_SESSION_POOLTAG_INFORMATION
SystemSessionMappedViewInformation, // q: SYSTEM_SESSION_MAPPED_VIEW_INFORMATION
- SystemHotpatchInformation, // q; s
- SystemObjectSecurityMode, // q // 70
+ SystemHotpatchInformation, // q; s: SYSTEM_HOTPATCH_CODE_INFORMATION
+ SystemObjectSecurityMode, // q: ULONG // 70
SystemWatchdogTimerHandler, // s (kernel-mode only)
SystemWatchdogTimerInformation, // q (kernel-mode only); s (kernel-mode only)
SystemLogicalProcessorInformation, // q: SYSTEM_LOGICAL_PROCESSOR_INFORMATION
@@ -1390,6 +1390,9 @@ typedef enum _SYSTEM_INFORMATION_CLASS
SystemCodeIntegrityUnlockInformation, // SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION // 190
SystemIntegrityQuotaInformation,
SystemFlushInformation, // q: SYSTEM_FLUSH_INFORMATION
+ SystemProcessorIdleMaskInformation, // since REDSTONE3
+ SystemSecureDumpEncryptionInformation,
+ SystemWriteConstraintInformation, // SYSTEM_WRITE_CONSTRAINT_INFORMATION
MaxSystemInfoClass
} SYSTEM_INFORMATION_CLASS;
@@ -1576,7 +1579,9 @@ typedef struct _SYSTEM_PROCESS_INFORMATION
LARGE_INTEGER ReadTransferCount;
LARGE_INTEGER WriteTransferCount;
LARGE_INTEGER OtherTransferCount;
- SYSTEM_THREAD_INFORMATION Threads[1];
+ SYSTEM_THREAD_INFORMATION Threads[1]; // SystemProcessInformation
+ // SYSTEM_EXTENDED_THREAD_INFORMATION Threads[1]; // SystemExtendedProcessinformation
+ // SYSTEM_EXTENDED_THREAD_INFORMATION + SYSTEM_PROCESS_INFORMATION_EXTENSION // SystemFullProcessInformation
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
typedef struct _SYSTEM_CALL_COUNT_INFORMATION
@@ -1790,12 +1795,25 @@ typedef struct _SYSTEM_QUERY_TIME_ADJUST_INFORMATION
BOOLEAN Enable;
} SYSTEM_QUERY_TIME_ADJUST_INFORMATION, *PSYSTEM_QUERY_TIME_ADJUST_INFORMATION;
+typedef struct _SYSTEM_QUERY_TIME_ADJUST_INFORMATION_PRECISE
+{
+ ULONGLONG TimeAdjustment;
+ ULONGLONG TimeIncrement;
+ BOOLEAN Enable;
+} SYSTEM_QUERY_TIME_ADJUST_INFORMATION_PRECISE, *PSYSTEM_QUERY_TIME_ADJUST_INFORMATION_PRECISE;
+
typedef struct _SYSTEM_SET_TIME_ADJUST_INFORMATION
{
ULONG TimeAdjustment;
BOOLEAN Enable;
} SYSTEM_SET_TIME_ADJUST_INFORMATION, *PSYSTEM_SET_TIME_ADJUST_INFORMATION;
+typedef struct _SYSTEM_SET_TIME_ADJUST_INFORMATION_PRECISE
+{
+ ULONGLONG TimeAdjustment;
+ BOOLEAN Enable;
+} SYSTEM_SET_TIME_ADJUST_INFORMATION_PRECISE, *PSYSTEM_SET_TIME_ADJUST_INFORMATION_PRECISE;
+
typedef enum _EVENT_TRACE_INFORMATION_CLASS
{
EventTraceKernelVersionInformation, // EVENT_TRACE_VERSION_INFORMATION
@@ -1817,6 +1835,8 @@ typedef enum _EVENT_TRACE_INFORMATION_CLASS
EventTraceStackCachingInformation, // EVENT_TRACE_STACK_CACHING_INFORMATION
EventTraceObjectTypeFilterInformation, // EVENT_TRACE_TAG_FILTER_INFORMATION
EventTraceSoftRestartInformation, // EVENT_TRACE_SOFT_RESTART_INFORMATION
+ EventTraceLastBranchConfigurationInformation, // REDSTONE3
+ EventTraceLastBranchEventListInformation,
MaxEventTraceInfoClass
} EVENT_TRACE_INFORMATION_CLASS;
@@ -2149,6 +2169,7 @@ typedef struct _SYSTEM_SESSION_MAPPED_VIEW_INFORMATION
SIZE_T NumberOfBytesAvailableContiguous;
} SYSTEM_SESSION_MAPPED_VIEW_INFORMATION, *PSYSTEM_SESSION_MAPPED_VIEW_INFORMATION;
+#if (PHNT_MODE != PHNT_MODE_KERNEL)
// private
typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION
{
@@ -2166,6 +2187,7 @@ typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION
ULONG TableBufferLength;
UCHAR TableBuffer[1];
} SYSTEM_FIRMWARE_TABLE_INFORMATION, *PSYSTEM_FIRMWARE_TABLE_INFORMATION;
+#endif
// private
typedef struct _SYSTEM_MEMORY_LIST_INFORMATION
@@ -2221,16 +2243,6 @@ typedef struct _SYSTEM_PROCESS_ID_INFORMATION
UNICODE_STRING ImageName;
} SYSTEM_PROCESS_ID_INFORMATION, *PSYSTEM_PROCESS_ID_INFORMATION;
-#if (PHNT_MODE == PHNT_MODE_KERNEL)
-typedef enum _FIRMWARE_TYPE
-{
- FirmwareTypeUnknown,
- FirmwareTypeBios,
- FirmwareTypeUefi,
- FirmwareTypeMax
-} FIRMWARE_TYPE, *PFIRMWARE_TYPE;
-#endif
-
// private
typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
{
@@ -2273,13 +2285,20 @@ typedef struct _SYSTEM_SYSTEM_DISK_INFORMATION
UNICODE_STRING SystemDisk;
} SYSTEM_SYSTEM_DISK_INFORMATION, *PSYSTEM_SYSTEM_DISK_INFORMATION;
-// private
+// private (Windows 8.1 and above)
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT
{
- ULONGLONG Hits; // ULONG in WIN8
+ ULONGLONG Hits;
UCHAR PercentFrequency;
} SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT, *PSYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT;
+// private (Windows 7 and Windows 8)
+typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT_WIN8
+{
+ ULONG Hits;
+ UCHAR PercentFrequency;
+} SYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT_WIN8, *PSYSTEM_PROCESSOR_PERFORMANCE_HITCOUNT_WIN8;
+
// private
typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_STATE_DISTRIBUTION
{
@@ -2662,7 +2681,7 @@ typedef struct _PROCESS_DISK_COUNTERS
} PROCESS_DISK_COUNTERS, *PPROCESS_DISK_COUNTERS;
// private
-typedef struct _ENERGY_STATE_DURATION
+typedef union _ENERGY_STATE_DURATION
{
union
{
@@ -2696,8 +2715,8 @@ typedef struct _PROCESS_ENERGY_VALUES
ULONG CompositionDirtyGenerated;
ULONG CompositionDirtyPropagated;
ULONG Reserved1;
- ULONGLONG AttributedCycles[2][4];
- ULONGLONG WorkOnBehalfCycles[2][4];
+ ULONGLONG AttributedCycles[4][2];
+ ULONGLONG WorkOnBehalfCycles[4][2];
} PROCESS_ENERGY_VALUES, *PPROCESS_ENERGY_VALUES;
typedef struct _TIMELINE_BITMAP
@@ -2711,7 +2730,7 @@ typedef struct _PROCESS_ENERGY_VALUES_EXTENSION
{
union
{
- TIMELINE_BITMAP Timelines[9];
+ TIMELINE_BITMAP Timelines[14]; // 9 for REDSTONE2, 14 for REDSTONE3
struct
{
TIMELINE_BITMAP CpuTimeline;
@@ -2723,8 +2742,29 @@ typedef struct _PROCESS_ENERGY_VALUES_EXTENSION
TIMELINE_BITMAP CompositionRenderedTimeline;
TIMELINE_BITMAP CompositionDirtyGeneratedTimeline;
TIMELINE_BITMAP CompositionDirtyPropagatedTimeline;
+ TIMELINE_BITMAP InputTimeline; // REDSTONE3
+ TIMELINE_BITMAP AudioInTimeline;
+ TIMELINE_BITMAP AudioOutTimeline;
+ TIMELINE_BITMAP DisplayRequiredTimeline;
+ TIMELINE_BITMAP KeyboardInputTimeline;
};
};
+
+ union // REDSTONE3
+ {
+ ENERGY_STATE_DURATION Durations[5];
+ struct
+ {
+ ENERGY_STATE_DURATION InputDuration;
+ ENERGY_STATE_DURATION AudioInDuration;
+ ENERGY_STATE_DURATION AudioOutDuration;
+ ENERGY_STATE_DURATION DisplayRequiredDuration;
+ ENERGY_STATE_DURATION PSMBackgroundDuration;
+ };
+ };
+
+ ULONG KeyboardInput;
+ ULONG MouseInput;
} PROCESS_ENERGY_VALUES_EXTENSION, *PPROCESS_ENERGY_VALUES_EXTENSION;
typedef struct _PROCESS_EXTENDED_ENERGY_VALUES
@@ -2733,6 +2773,16 @@ typedef struct _PROCESS_EXTENDED_ENERGY_VALUES
PROCESS_ENERGY_VALUES_EXTENSION Extension;
} PROCESS_EXTENDED_ENERGY_VALUES, *PPROCESS_EXTENDED_ENERGY_VALUES;
+// private
+typedef enum _SYSTEM_PROCESS_CLASSIFICATION
+{
+ SystemProcessClassificationNormal,
+ SystemProcessClassificationSystem,
+ SystemProcessClassificationSecureSystem,
+ SystemProcessClassificationMemCompression,
+ SystemProcessClassificationMaximum
+} SYSTEM_PROCESS_CLASSIFICATION;
+
// private
typedef struct _SYSTEM_PROCESS_INFORMATION_EXTENSION
{
@@ -2744,7 +2794,7 @@ typedef struct _SYSTEM_PROCESS_INFORMATION_EXTENSION
struct
{
ULONG HasStrongId : 1;
- ULONG Classification : 4;
+ ULONG Classification : 4; // SYSTEM_PROCESS_CLASSIFICATION
ULONG BackgroundActivityModerated : 1;
ULONG Spare : 26;
};
@@ -2887,7 +2937,7 @@ typedef struct _SYSTEM_SECUREBOOT_POLICY_FULL_INFORMATION
typedef struct _SYSTEM_ROOT_SILO_INFORMATION
{
ULONG NumberOfSilos;
- HANDLE SiloIdList[1];
+ ULONG SiloIdList[1];
} SYSTEM_ROOT_SILO_INFORMATION, *PSYSTEM_ROOT_SILO_INFORMATION;
// private
@@ -2968,13 +3018,28 @@ typedef enum _SYSTEM_ACTIVITY_MODERATION_STATE
MaxSystemActivityModerationState
} SYSTEM_ACTIVITY_MODERATION_STATE;
-// private
-typedef struct _SYSTEM_ACTIVITY_MODERATION_EXE_STATE
+// private - REDSTONE2
+typedef struct _SYSTEM_ACTIVITY_MODERATION_EXE_STATE // REDSTONE3: Renamed SYSTEM_ACTIVITY_MODERATION_INFO
{
UNICODE_STRING ExePathNt;
SYSTEM_ACTIVITY_MODERATION_STATE ModerationState;
} SYSTEM_ACTIVITY_MODERATION_EXE_STATE, *PSYSTEM_ACTIVITY_MODERATION_EXE_STATE;
+typedef enum _SYSTEM_ACTIVITY_MODERATION_APP_TYPE
+{
+ SystemActivityModerationAppTypeClassic,
+ SystemActivityModerationAppTypePackaged,
+ MaxSystemActivityModerationAppType
+} SYSTEM_ACTIVITY_MODERATION_APP_TYPE;
+
+// private - REDSTONE3
+typedef struct _SYSTEM_ACTIVITY_MODERATION_INFO
+{
+ UNICODE_STRING Identifier;
+ SYSTEM_ACTIVITY_MODERATION_STATE ModerationState;
+ SYSTEM_ACTIVITY_MODERATION_APP_TYPE AppType;
+} SYSTEM_ACTIVITY_MODERATION_INFO, *PSYSTEM_ACTIVITY_MODERATION_INFO;
+
// private
typedef struct _SYSTEM_ACTIVITY_MODERATION_USER_SETTINGS
{
@@ -3006,6 +3071,13 @@ typedef struct _SYSTEM_FLUSH_INFORMATION
ULONGLONG Reserved[2];
} SYSTEM_FLUSH_INFORMATION, *PSYSTEM_FLUSH_INFORMATION;
+// private
+typedef struct _SYSTEM_WRITE_CONSTRAINT_INFORMATION
+{
+ ULONG WriteConstraintPolicy;
+ ULONG Reserved;
+} SYSTEM_WRITE_CONSTRAINT_INFORMATION, *PSYSTEM_WRITE_CONSTRAINT_INFORMATION;
+
#if (PHNT_MODE != PHNT_MODE_KERNEL)
NTSYSCALLAPI
@@ -3153,35 +3225,31 @@ typedef struct _SYSDBG_TRIAGE_DUMP
} SYSDBG_TRIAGE_DUMP, *PSYSDBG_TRIAGE_DUMP;
// private
-typedef struct _SYSDBG_LIVEDUMP_CONTROL_FLAGS
+typedef union _SYSDBG_LIVEDUMP_CONTROL_FLAGS
{
- union
+ struct
{
- struct
- {
- ULONG UseDumpStorageStack : 1;
- ULONG CompressMemoryPagesData : 1;
- ULONG IncludeUserSpaceMemoryPages : 1;
- ULONG Reserved : 28;
- };
- ULONG AsUlong;
+ ULONG UseDumpStorageStack : 1;
+ ULONG CompressMemoryPagesData : 1;
+ ULONG IncludeUserSpaceMemoryPages : 1;
+ ULONG Reserved : 29;
};
+ ULONG AsUlong;
} SYSDBG_LIVEDUMP_CONTROL_FLAGS, *PSYSDBG_LIVEDUMP_CONTROL_FLAGS;
// private
-typedef struct _SYSDBG_LIVEDUMP_CONTROL_ADDPAGES
+typedef union _SYSDBG_LIVEDUMP_CONTROL_ADDPAGES
{
- union
+ struct
{
- struct
- {
- ULONG HypervisorPages : 1;
- ULONG Reserved : 31;
- };
- ULONG AsUlong;
+ ULONG HypervisorPages : 1;
+ ULONG Reserved : 31;
};
+ ULONG AsUlong;
} SYSDBG_LIVEDUMP_CONTROL_ADDPAGES, *PSYSDBG_LIVEDUMP_CONTROL_ADDPAGES;
+#define SYSDBG_LIVEDUMP_CONTROL_VERSION 1
+
// private
typedef struct _SYSDBG_LIVEDUMP_CONTROL
{
@@ -3299,7 +3367,7 @@ typedef struct _KUSER_SHARED_DATA
LONG TimeZoneBiasStamp;
ULONG NtBuildNumber;
- ULONG NtProductType;
+ NT_PRODUCT_TYPE NtProductType;
BOOLEAN ProductTypeIsValid;
UCHAR Reserved0[1];
USHORT NativeProcessorArchitecture;
@@ -3364,7 +3432,8 @@ typedef struct _KUSER_SHARED_DATA
ULONG DbgSecureBootEnabled : 1;
ULONG DbgMultiSessionSku : 1;
ULONG DbgMultiUsersInSessionSku : 1;
- ULONG SpareBits : 22;
+ ULONG DbgStateSeparationEnabled : 1;
+ ULONG SpareBits : 21;
};
};
ULONG DataFlagsPad[1];
@@ -3397,7 +3466,9 @@ typedef struct _KUSER_SHARED_DATA
USHORT UnparkedProcessorCount;
ULONG EnclaveFeatureMask[4];
- ULONG Reserved8;
+
+ ULONG TelemetryCoverageRound;
+
USHORT UserModeGlobalLogger[16];
ULONG ImageFileExecutionOptions;
@@ -3459,7 +3530,7 @@ C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, SystemCallPad) == 0x310);
C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TickCount) == 0x320);
C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, TickCountQuad) == 0x320);
C_ASSERT(FIELD_OFFSET(KUSER_SHARED_DATA, XState) == 0x3d8);
-//C_ASSERT(sizeof(KUSER_SHARED_DATA) == 0x708); // Visual Studio has a problem with this
+C_ASSERT(sizeof(KUSER_SHARED_DATA) == 0x708);
#define USER_SHARED_DATA ((KUSER_SHARED_DATA * const)0x7ffe0000)
diff --git a/phnt/include/ntgdi.h b/inc/phnt/ntgdi.h
similarity index 100%
rename from phnt/include/ntgdi.h
rename to inc/phnt/ntgdi.h
diff --git a/phnt/include/ntioapi.h b/inc/phnt/ntioapi.h
similarity index 99%
rename from phnt/include/ntioapi.h
rename to inc/phnt/ntioapi.h
index c13aa19..158e3b0 100644
--- a/phnt/include/ntioapi.h
+++ b/inc/phnt/ntioapi.h
@@ -242,6 +242,7 @@ typedef enum _FILE_INFORMATION_CLASS
FileRenameInformationExBypassAccessCheck,
FileDesiredStorageClassInformation, // FILE_DESIRED_STORAGE_CLASS_INFORMATION // since REDSTONE2
FileStatInformation, // FILE_STAT_INFORMATION
+ FileMemoryPartitionInformation, // FILE_MEMORY_PARTITION_INFORMATION // since REDSTONE3
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
@@ -679,6 +680,7 @@ typedef struct _FILE_ID_EXTD_BOTH_DIR_INFORMATION
WCHAR FileName[1];
} FILE_ID_EXTD_BOTH_DIR_INFORMATION, *PFILE_ID_EXTD_BOTH_DIR_INFORMATION;
+// private
typedef struct _FILE_STAT_INFORMATION
{
LARGE_INTEGER FileId;
@@ -694,6 +696,21 @@ typedef struct _FILE_STAT_INFORMATION
ULONG EffectiveAccess;
} FILE_STAT_INFORMATION, *PFILE_STAT_INFORMATION;
+// private
+typedef struct _FILE_MEMORY_PARTITION_INFORMATION
+{
+ HANDLE OwnerPartitionHandle;
+ union
+ {
+ struct
+ {
+ UCHAR NoCrossPartitionAccess;
+ UCHAR Spare[3];
+ };
+ ULONG AllFlags;
+ } Flags;
+} FILE_MEMORY_PARTITION_INFORMATION, *PFILE_MEMORY_PARTITION_INFORMATION;
+
// NtQueryDirectoryFile types
typedef struct _FILE_DIRECTORY_INFORMATION
diff --git a/phnt/include/ntkeapi.h b/inc/phnt/ntkeapi.h
similarity index 100%
rename from phnt/include/ntkeapi.h
rename to inc/phnt/ntkeapi.h
diff --git a/phnt/include/ntldr.h b/inc/phnt/ntldr.h
similarity index 93%
rename from phnt/include/ntldr.h
rename to inc/phnt/ntldr.h
index 6ec947c..37ed1d7 100644
--- a/phnt/include/ntldr.h
+++ b/inc/phnt/ntldr.h
@@ -76,6 +76,8 @@ typedef enum _LDR_DLL_LOAD_REASON
LoadReasonDynamicLoad,
LoadReasonAsImageLoad,
LoadReasonAsDataLoad,
+ LoadReasonEnclavePrimary, // REDSTONE3
+ LoadReasonEnclaveDependency,
LoadReasonUnknown = -1
} LDR_DLL_LOAD_REASON, *PLDR_DLL_LOAD_REASON;
@@ -471,9 +473,25 @@ LdrUnregisterDllNotification(
// private
typedef struct _PS_MITIGATION_OPTIONS_MAP
{
- ULONG_PTR Map[2];
+ union
+ {
+ ULONG_PTR Map[2]; // REDSTONE2
+ //struct
+ //{
+ // ULONG_PTR Depth : 16; // REDSTONE3
+ // ULONG_PTR Sequence : 48;
+ // ULONG_PTR Reserved : 4;
+ // ULONG_PTR NextEntry : 60;
+ //};
+ };
} PS_MITIGATION_OPTIONS_MAP, *PPS_MITIGATION_OPTIONS_MAP;
+// private
+typedef struct _PS_MITIGATION_AUDIT_OPTIONS_MAP
+{
+ ULONG_PTR Map[2];
+} PS_MITIGATION_AUDIT_OPTIONS_MAP, *PPS_MITIGATION_AUDIT_OPTIONS_MAP;
+
// private
typedef struct _PS_SYSTEM_DLL_INIT_BLOCK
{
@@ -496,6 +514,7 @@ typedef struct _PS_SYSTEM_DLL_INIT_BLOCK
ULONG_PTR CfgBitMapSize;
ULONG_PTR Wow64CfgBitMap;
ULONG_PTR Wow64CfgBitMapSize;
+ PS_MITIGATION_AUDIT_OPTIONS_MAP MitigationAuditOptionsMap; // REDSTONE3
} PS_SYSTEM_DLL_INIT_BLOCK, *PPS_SYSTEM_DLL_INIT_BLOCK;
#if (PHNT_VERSION >= PHNT_THRESHOLD)
@@ -552,6 +571,26 @@ LdrDisableThreadCalloutsForDll(
_In_ PVOID DllImageBase
);
+// Resources
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+LdrAccessResource(
+ _In_ PVOID BaseAddress,
+ _In_ PIMAGE_RESOURCE_DATA_ENTRY ResourceDataEntry,
+ _Out_opt_ PVOID *ResourceBuffer,
+ _Out_opt_ ULONG *ResourceLength
+ );
+
+NTSYSAPI
+NTSTATUS
+NTAPI
+LdrFindEntryForAddress(
+ _In_ PVOID BaseAddress,
+ _Out_ PLDR_DATA_TABLE_ENTRY *Entry
+ );
+
#endif // (PHNT_MODE != PHNT_MODE_KERNEL)
// Module information
diff --git a/phnt/include/ntlpcapi.h b/inc/phnt/ntlpcapi.h
similarity index 100%
rename from phnt/include/ntlpcapi.h
rename to inc/phnt/ntlpcapi.h
diff --git a/phnt/include/ntmisc.h b/inc/phnt/ntmisc.h
similarity index 100%
rename from phnt/include/ntmisc.h
rename to inc/phnt/ntmisc.h
diff --git a/phnt/include/ntmmapi.h b/inc/phnt/ntmmapi.h
similarity index 89%
rename from phnt/include/ntmmapi.h
rename to inc/phnt/ntmmapi.h
index 9499ee2..2ae1234 100644
--- a/phnt/include/ntmmapi.h
+++ b/inc/phnt/ntmmapi.h
@@ -24,7 +24,7 @@
#define PAGE_ENCLAVE_UNVALIDATED 0x20000000
// Region and section constants
-
+#if (PHNT_MODE != PHNT_MODE_KERNEL)
#define MEM_COMMIT 0x1000
#define MEM_RESERVE 0x2000
#define MEM_DECOMMIT 0x4000
@@ -34,19 +34,26 @@
#define MEM_MAPPED 0x40000
#define MEM_RESET 0x80000
#define MEM_TOP_DOWN 0x100000
+#endif
#define MEM_WRITE_WATCH 0x200000
#define MEM_PHYSICAL 0x400000
#define MEM_ROTATE 0x800000
#define MEM_DIFFERENT_IMAGE_BASE_OK 0x800000
+#if (PHNT_MODE != PHNT_MODE_KERNEL)
#define MEM_RESET_UNDO 0x1000000
+#endif
#define MEM_LARGE_PAGES 0x20000000
#define MEM_4MB_PAGES 0x80000000
+#if (PHNT_MODE != PHNT_MODE_KERNEL)
#define SEC_FILE 0x800000
+#endif
#define SEC_IMAGE 0x1000000
#define SEC_PROTECTED_IMAGE 0x2000000
+#if (PHNT_MODE != PHNT_MODE_KERNEL)
#define SEC_RESERVE 0x4000000
#define SEC_COMMIT 0x8000000
+#endif
#define SEC_NOCACHE 0x10000000
#define SEC_WRITECOMBINE 0x40000000
#define SEC_LARGE_PAGES 0x80000000
@@ -55,6 +62,7 @@
#endif
+#if (PHNT_MODE != PHNT_MODE_KERNEL)
// private
typedef enum _MEMORY_INFORMATION_CLASS
{
@@ -66,21 +74,22 @@ typedef enum _MEMORY_INFORMATION_CLASS
MemorySharedCommitInformation, // MEMORY_SHARED_COMMIT_INFORMATION
MemoryImageInformation, // MEMORY_IMAGE_INFORMATION
MemoryRegionInformationEx,
- MemoryPrivilegedBasicInformation
+ MemoryPrivilegedBasicInformation,
+ MemoryEnclaveImageInformation, // since REDSTONE3
+ MemoryBasicInformationCapped
} MEMORY_INFORMATION_CLASS;
-
-#if (PHNT_MODE == PHNT_MODE_KERNEL)
-
-typedef struct _MEMORY_BASIC_INFORMATION
-{
- PVOID BaseAddress;
- PVOID AllocationBase;
- ULONG AllocationProtect;
- SIZE_T RegionSize;
- ULONG State;
- ULONG Protect;
- ULONG Type;
-} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;
+#else
+#define MemoryBasicInformation 0x0
+#define MemoryWorkingSetInformation 0x1
+#define MemoryMappedFilenameInformation 0x2
+#define MemoryRegionInformation 0x3
+#define MemoryWorkingSetExInformation 0x4
+#define MemorySharedCommitInformation 0x5
+#define MemoryImageInformation 0x6
+#define MemoryRegionInformationEx 0x7
+#define MemoryPrivilegedBasicInformation 0x8
+#define MemoryEnclaveImageInformation 0x9
+#define MemoryBasicInformationCapped 0xA
#endif
typedef struct _MEMORY_WORKING_SET_BLOCK
@@ -118,7 +127,9 @@ typedef struct _MEMORY_REGION_INFORMATION
ULONG MappedPageFile : 1;
ULONG MappedPhysical : 1;
ULONG DirectMapped : 1;
- ULONG Reserved : 26;
+ ULONG SoftwareEnclave : 1; //REDSTONE3
+ ULONG PageSize64K : 1;
+ ULONG Reserved : 24;
};
};
SIZE_T RegionSize;
@@ -196,6 +207,7 @@ typedef struct _MEMORY_IMAGE_INFORMATION
{
ULONG ImagePartialMap : 1;
ULONG ImageNotExecutable : 1;
+ ULONG ImageSigningLevel : 1; // REDSTONE3
ULONG Reserved : 30;
};
};
@@ -296,8 +308,8 @@ typedef struct _MMPFN_MEMSNAP_INFORMATION
typedef enum _SECTION_INFORMATION_CLASS
{
- SectionBasicInformation,
- SectionImageInformation,
+ SectionBasicInformation, // q; SECTION_BASIC_INFORMATION
+ SectionImageInformation, // q; SECTION_IMAGE_INFORMATION
SectionRelocationInformation, // name:wow64:whNtQuerySection_SectionRelocationInformation
SectionOriginalBaseInformation, // PVOID BaseAddress
SectionInternalImageInformation, // SECTION_INTERNAL_IMAGE_INFORMATION // since REDSTONE2
@@ -369,10 +381,8 @@ typedef struct _SECTION_INTERNAL_IMAGE_INFORMATION
ULONG ExtendedFlags;
struct
{
- ULONG ImageReturnFlowGuardEnabled : 1;
- ULONG ImageReturnFlowGuardStrict : 1;
ULONG ImageExportSuppressionEnabled : 1;
- ULONG Reserved : 29;
+ ULONG Reserved : 31;
};
};
} SECTION_INTERNAL_IMAGE_INFORMATION, *PSECTION_INTERNAL_IMAGE_INFORMATION;
@@ -471,12 +481,13 @@ NtQueryVirtualMemory(
#endif
// begin_private
-
+#if (PHNT_MODE != PHNT_MODE_KERNEL)
typedef enum _VIRTUAL_MEMORY_INFORMATION_CLASS
{
- VmPrefetchInformation,
+ VmPrefetchInformation, // ULONG
VmPagePriorityInformation,
- VmCfgCallTargetInformation
+ VmCfgCallTargetInformation, // CFG_CALL_TARGET_LIST_INFORMATION // REDSTONE2
+ VmPageDirtyStateInformation // REDSTONE3
} VIRTUAL_MEMORY_INFORMATION_CLASS;
typedef struct _MEMORY_RANGE_ENTRY
@@ -485,6 +496,14 @@ typedef struct _MEMORY_RANGE_ENTRY
SIZE_T NumberOfBytes;
} MEMORY_RANGE_ENTRY, *PMEMORY_RANGE_ENTRY;
+typedef struct _CFG_CALL_TARGET_LIST_INFORMATION
+{
+ ULONG NumberOfEntries;
+ ULONG Reserved;
+ PULONG NumberOfEntriesProcessed;
+ PCFG_CALL_TARGET_INFO CallTargetInfo;
+} CFG_CALL_TARGET_LIST_INFORMATION, *PCFG_CALL_TARGET_LIST_INFORMATION;
+#endif
// end_private
#if (PHNT_MODE != PHNT_MODE_KERNEL)
@@ -619,6 +638,14 @@ NtAreMappedFilesTheSame(
// Partitions
+#ifndef MEMORY_PARTITION_QUERY_ACCESS
+#define MEMORY_PARTITION_QUERY_ACCESS 0x0001
+#define MEMORY_PARTITION_MODIFY_ACCESS 0x0002
+#define MEMORY_PARTITION_ALL_ACCESS \
+ (STANDARD_RIGHTS_REQUIRED | SYNCHRONIZE | \
+ MEMORY_PARTITION_QUERY_ACCESS | MEMORY_PARTITION_MODIFY_ACCESS)
+#endif
+
// private
typedef enum _MEMORY_PARTITION_INFORMATION_CLASS
{
@@ -646,10 +673,11 @@ typedef struct _MEMORY_PARTITION_CONFIGURATION_INFORMATION
ULONG_PTR ZeroPages;
ULONG_PTR FreePages;
ULONG_PTR StandbyPages;
- ULONG StandbyPageCountByPriority[8]; // since REDSTONE2
- ULONG RepurposedPagesByPriority[8];
- ULONG MaximumCommitLimit;
- ULONG DonatedPagesToPartitions;
+ ULONG_PTR StandbyPageCountByPriority[8]; // since REDSTONE2
+ ULONG_PTR RepurposedPagesByPriority[8];
+ ULONG_PTR MaximumCommitLimit;
+ ULONG_PTR DonatedPagesToPartitions;
+ ULONG PartitionId; // since REDSTONE3
} MEMORY_PARTITION_CONFIGURATION_INFORMATION, *PMEMORY_PARTITION_CONFIGURATION_INFORMATION;
// private
@@ -704,7 +732,13 @@ typedef struct _MEMORY_PARTITION_MEMORY_EVENTS_INFORMATION
ULONG Spare : 31;
};
ULONG AllFlags;
- };
+ } Flags;
+
+ ULONG HandleAttributes;
+ ULONG DesiredAccess;
+ HANDLE LowCommitCondition; // \KernelObjects\LowCommitCondition
+ HANDLE HighCommitCondition; // \KernelObjects\HighCommitCondition
+ HANDLE MaximumCommitCondition; // \KernelObjects\MaximumCommitCondition
} MEMORY_PARTITION_MEMORY_EVENTS_INFORMATION, *PMEMORY_PARTITION_MEMORY_EVENTS_INFORMATION;
#if (PHNT_MODE != PHNT_MODE_KERNEL)
diff --git a/phnt/include/ntnls.h b/inc/phnt/ntnls.h
similarity index 100%
rename from phnt/include/ntnls.h
rename to inc/phnt/ntnls.h
diff --git a/phnt/include/ntobapi.h b/inc/phnt/ntobapi.h
similarity index 100%
rename from phnt/include/ntobapi.h
rename to inc/phnt/ntobapi.h
diff --git a/phnt/include/ntpebteb.h b/inc/phnt/ntpebteb.h
similarity index 90%
rename from phnt/include/ntpebteb.h
rename to inc/phnt/ntpebteb.h
index 6169a18..7114a1b 100644
--- a/phnt/include/ntpebteb.h
+++ b/inc/phnt/ntpebteb.h
@@ -4,6 +4,16 @@
typedef struct _RTL_USER_PROCESS_PARAMETERS *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _RTL_CRITICAL_SECTION *PRTL_CRITICAL_SECTION;
+// private
+typedef struct _ACTIVATION_CONTEXT_STACK
+{
+ struct _RTL_ACTIVATION_CONTEXT_STACK_FRAME* ActiveFrame;
+ LIST_ENTRY FrameListCache;
+ ULONG Flags;
+ ULONG NextCookieSequenceNumber;
+ ULONG StackId;
+} ACTIVATION_CONTEXT_STACK, *PACTIVATION_CONTEXT_STACK;
+
// symbols
typedef struct _PEB
{
@@ -62,9 +72,11 @@ typedef struct _PEB
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[2];
- PVOID ReadOnlySharedMemoryBase;
- PVOID HotpatchInformation;
+
+ PVOID ReadOnlySharedMemoryBase;
+ PVOID SharedData; // HotpatchInformation
PVOID *ReadOnlyStaticServerData;
+
PVOID AnsiCodePageData; // PCPTABLEINFO
PVOID OemCodePageData; // PCPTABLEINFO
PVOID UnicodeCaseTableData; // PNLSTABLEINFO
@@ -127,7 +139,7 @@ typedef struct _PEB
PVOID WerRegistrationData;
PVOID WerShipAssertPtr;
- PVOID pContextData;
+ PVOID pUnused; // pContextData
PVOID pImageHeaderHash;
union
{
@@ -144,6 +156,8 @@ typedef struct _PEB
PVOID TppWorkerpListLock;
LIST_ENTRY TppWorkerpList;
PVOID WaitOnAddressHashTable[128];
+ PVOID TelemetryCoverageHeader; // REDSTONE3
+ ULONG CloudFileFlags;
} PEB, *PPEB;
#define GDI_BATCH_BUFFER_SIZE 310
@@ -188,17 +202,33 @@ typedef struct _TEB
LCID CurrentLocale;
ULONG FpSoftwareStatusRegister;
PVOID ReservedForDebuggerInstrumentation[16];
- PVOID SystemReserved1[37];
+#ifdef _WIN64
+ PVOID SystemReserved1[30];
+#else
+ PVOID SystemReserved1[26];
+#endif
+
+ CHAR PlaceholderCompatibilityMode;
+ CHAR PlaceholderReserved[11];
+ ULONG ProxiedProcessId;
+ ACTIVATION_CONTEXT_STACK ActivationStack;
+
UCHAR WorkingOnBehalfTicket[8];
NTSTATUS ExceptionCode;
- PVOID ActivationContextStackPointer;
+ PACTIVATION_CONTEXT_STACK ActivationContextStackPointer;
ULONG_PTR InstrumentationCallbackSp;
ULONG_PTR InstrumentationCallbackPreviousPc;
ULONG_PTR InstrumentationCallbackPreviousSp;
+#ifdef _WIN64
ULONG TxFsContext;
+#endif
BOOLEAN InstrumentationCallbackDisabled;
+#ifndef _WIN64
+ UCHAR SpareBytes[23];
+ ULONG TxFsContext;
+#endif
GDI_TEB_BATCH GdiTebBatch;
CLIENT_ID RealClientId;
HANDLE GdiCachedProcessHandle;
diff --git a/phnt/include/ntpfapi.h b/inc/phnt/ntpfapi.h
similarity index 100%
rename from phnt/include/ntpfapi.h
rename to inc/phnt/ntpfapi.h
diff --git a/phnt/include/ntpnpapi.h b/inc/phnt/ntpnpapi.h
similarity index 100%
rename from phnt/include/ntpnpapi.h
rename to inc/phnt/ntpnpapi.h
diff --git a/phnt/include/ntpoapi.h b/inc/phnt/ntpoapi.h
similarity index 100%
rename from phnt/include/ntpoapi.h
rename to inc/phnt/ntpoapi.h
diff --git a/phnt/include/ntpsapi.h b/inc/phnt/ntpsapi.h
similarity index 91%
rename from phnt/include/ntpsapi.h
rename to inc/phnt/ntpsapi.h
index cc957c2..5135051 100644
--- a/phnt/include/ntpsapi.h
+++ b/inc/phnt/ntpsapi.h
@@ -180,6 +180,13 @@ typedef enum _PROCESSINFOCLASS
ProcessDisableSystemAllowedCpuSets,
ProcessWakeInformation, // PROCESS_WAKE_INFORMATION
ProcessEnergyTrackingState, // PROCESS_ENERGY_TRACKING_STATE
+ ProcessManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
+ ProcessCaptureTrustletLiveDump,
+ ProcessTelemetryCoverage,
+ ProcessEnclaveInformation,
+ ProcessEnableReadWriteVmLogging, // PROCESS_READWRITEVM_LOGGING_INFORMATION
+ ProcessUptimeInformation, // PROCESS_UPTIME_INFORMATION
+ ProcessImageSection,
MaxProcessInfoClass
} PROCESSINFOCLASS;
#endif
@@ -235,6 +242,8 @@ typedef enum _THREADINFOCLASS
ThreadSubsystemInformation, // q: SUBSYSTEM_INFORMATION_TYPE // since REDSTONE2
ThreadDbgkWerReportActive,
ThreadAttachContainer,
+ ThreadManageWritesToExecutableMemory, // MANAGE_WRITES_TO_EXECUTABLE_MEMORY // since REDSTONE3
+ ThreadPowerThrottlingState, // THREAD_POWER_THROTTLING_STATE
MaxThreadInfoClass
} THREADINFOCLASS;
#endif
@@ -578,6 +587,9 @@ typedef struct _PROCESS_MITIGATION_POLICY_INFORMATION
PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY SignaturePolicy;
PROCESS_MITIGATION_FONT_DISABLE_POLICY FontDisablePolicy;
PROCESS_MITIGATION_IMAGE_LOAD_POLICY ImageLoadPolicy;
+ PROCESS_MITIGATION_SYSTEM_CALL_FILTER_POLICY SystemCallFilterPolicy;
+ PROCESS_MITIGATION_PAYLOAD_RESTRICTION_POLICY PayloadRestrictionPolicy;
+ PROCESS_MITIGATION_CHILD_PROCESS_POLICY ChildProcessPolicy;
};
} PROCESS_MITIGATION_POLICY_INFORMATION, *PPROCESS_MITIGATION_POLICY_INFORMATION;
@@ -716,7 +728,9 @@ typedef struct _PROCESS_JOB_MEMORY_INFO
typedef struct _PROCESS_CHILD_PROCESS_INFORMATION
{
BOOLEAN ProhibitChildProcesses;
- BOOLEAN EnableAutomaticOverride;
+ //BOOLEAN EnableAutomaticOverride; // REDSTONE2
+ BOOLEAN AlwaysAllowSecureChildProcess; // REDSTONE3
+ BOOLEAN AuditProhibitChildProcesses;
} PROCESS_CHILD_PROCESS_INFORMATION, *PPROCESS_CHILD_PROCESS_INFORMATION;
typedef struct _PROCESS_WAKE_INFORMATION
@@ -735,6 +749,45 @@ typedef struct _PROCESS_ENERGY_TRACKING_STATE
WCHAR Tag[64];
} PROCESS_ENERGY_TRACKING_STATE, *PPROCESS_ENERGY_TRACKING_STATE;
+typedef struct _MANAGE_WRITES_TO_EXECUTABLE_MEMORY
+{
+ ULONG Version : 8;
+ ULONG ProcessEnableWriteExceptions : 1;
+ ULONG ThreadAllowWrites : 1;
+ ULONG Spare : 22;
+} MANAGE_WRITES_TO_EXECUTABLE_MEMORY, *PMANAGE_WRITES_TO_EXECUTABLE_MEMORY;
+
+typedef struct _PROCESS_READWRITEVM_LOGGING_INFORMATION
+{
+ union
+ {
+ BOOLEAN Flags;
+ struct
+ {
+ BOOLEAN EnableReadVmLogging : 1;
+ BOOLEAN EnableWriteVmLogging : 1;
+ BOOLEAN Unused : 6;
+ };
+ };
+} PROCESS_READWRITEVM_LOGGING_INFORMATION, *PPROCESS_READWRITEVM_LOGGING_INFORMATION;
+
+typedef struct _PROCESS_UPTIME_INFORMATION
+{
+ ULONGLONG QueryInterruptTime;
+ ULONGLONG QueryUnbiasedTime;
+ ULONGLONG EndInterruptTime;
+ ULONGLONG TimeSinceCreation;
+ ULONGLONG Uptime;
+ ULONGLONG SuspendedTime;
+ union
+ {
+ ULONG HangCount : 4;
+ ULONG GhostCount : 4;
+ ULONG Crashed : 1;
+ ULONG Terminated : 1;
+ };
+} PROCESS_UPTIME_INFORMATION, *PPROCESS_UPTIME_INFORMATION;
+
// end_private
#endif
@@ -1249,6 +1302,7 @@ typedef enum _PS_ATTRIBUTE_NUM
PsAttributeSafeOpenPromptOriginClaim,
PsAttributeBnoIsolation, // PS_BNO_ISOLATION_PARAMETERS
PsAttributeDesktopAppPolicy, // in ULONG
+ PsAttributeChpe, // since REDSTONE3
PsAttributeMax
} PS_ATTRIBUTE_NUM;
@@ -1400,7 +1454,15 @@ typedef enum _PS_MITIGATION_OPTION
PS_MITIGATION_OPTION_RETURN_FLOW_GUARD,
PS_MITIGATION_OPTION_LOADER_INTEGRITY_CONTINUITY,
PS_MITIGATION_OPTION_STRICT_CONTROL_FLOW_GUARD,
- PS_MITIGATION_OPTION_RESTRICT_SET_THREAD_CONTEXT
+ PS_MITIGATION_OPTION_RESTRICT_SET_THREAD_CONTEXT,
+ PS_MITIGATION_OPTION_ROP_STACKPIVOT, // since REDSTONE3
+ PS_MITIGATION_OPTION_ROP_CALLER_CHECK,
+ PS_MITIGATION_OPTION_ROP_SIMEXEC,
+ PS_MITIGATION_OPTION_EXPORT_ADDRESS_FILTER,
+ PS_MITIGATION_OPTION_EXPORT_ADDRESS_FILTER_PLUS,
+ PS_MITIGATION_OPTION_RESTRICT_CHILD_PROCESS_CREATION,
+ PS_MITIGATION_OPTION_IMPORT_ADDRESS_FILTER,
+ PS_MITIGATION_OPTION_MODULE_TAMPERING_PROTECTION
} PS_MITIGATION_OPTION;
// windows-internals-book:"Chapter 5"
@@ -1562,52 +1624,53 @@ NtCreateThreadEx(
#if (PHNT_MODE != PHNT_MODE_KERNEL)
// JOBOBJECTINFOCLASS
-#define JobObjectBasicAccountingInformation 1
-#define JobObjectBasicLimitInformation 2
-#define JobObjectBasicProcessIdList 3
-#define JobObjectBasicUIRestrictions 4
-#define JobObjectSecurityLimitInformation 5
-#define JobObjectEndOfJobTimeInformation 6
-#define JobObjectAssociateCompletionPortInformation 7
-#define JobObjectBasicAndIoAccountingInformation 8
-#define JobObjectExtendedLimitInformation 9
-#define JobObjectJobSetInformation 10
-#define JobObjectGroupInformation 11
-#define JobObjectNotificationLimitInformation 12
-#define JobObjectLimitViolationInformation 13
-#define JobObjectGroupInformationEx 14
-#define JobObjectCpuRateControlInformation 15
+// Note: We don't use an enum since it conflicts with the Windows SDK.
+#define JobObjectBasicAccountingInformation 1 // JOBOBJECT_BASIC_ACCOUNTING_INFORMATION
+#define JobObjectBasicLimitInformation 2 // JOBOBJECT_BASIC_LIMIT_INFORMATION
+#define JobObjectBasicProcessIdList 3 // JOBOBJECT_BASIC_PROCESS_ID_LIST
+#define JobObjectBasicUIRestrictions 4 // JOBOBJECT_BASIC_UI_RESTRICTIONS
+#define JobObjectSecurityLimitInformation 5 // JOBOBJECT_SECURITY_LIMIT_INFORMATION
+#define JobObjectEndOfJobTimeInformation 6 // JOBOBJECT_END_OF_JOB_TIME_INFORMATION
+#define JobObjectAssociateCompletionPortInformation 7 // JOBOBJECT_ASSOCIATE_COMPLETION_PORT
+#define JobObjectBasicAndIoAccountingInformation 8 // JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION
+#define JobObjectExtendedLimitInformation 9 // JOBOBJECT_EXTENDED_LIMIT_INFORMATION
+#define JobObjectJobSetInformation 10 // JOBOBJECT_JOBSET_INFORMATION
+#define JobObjectGroupInformation 11 // USHORT
+#define JobObjectNotificationLimitInformation 12 // JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION
+#define JobObjectLimitViolationInformation 13 // JOBOBJECT_LIMIT_VIOLATION_INFORMATION
+#define JobObjectGroupInformationEx 14 // GROUP_AFFINITY (ARRAY)
+#define JobObjectCpuRateControlInformation 15 // JOBOBJECT_CPU_RATE_CONTROL_INFORMATION
#define JobObjectCompletionFilter 16
#define JobObjectCompletionCounter 17
-#define JobObjectFreezeInformation 18
-#define JobObjectExtendedAccountingInformation 19
-#define JobObjectWakeInformation 20
+#define JobObjectFreezeInformation 18 // JOBOBJECT_FREEZE_INFORMATION
+#define JobObjectExtendedAccountingInformation 19 // JOBOBJECT_EXTENDED_ACCOUNTING_INFORMATION
+#define JobObjectWakeInformation 20 // JOBOBJECT_WAKE_INFORMATION
#define JobObjectBackgroundInformation 21
#define JobObjectSchedulingRankBiasInformation 22
#define JobObjectTimerVirtualizationInformation 23
#define JobObjectCycleTimeNotification 24
#define JobObjectClearEvent 25
-#define JobObjectInterferenceInformation 26
+#define JobObjectInterferenceInformation 26 // JOBOBJECT_INTERFERENCE_INFORMATION
#define JobObjectClearPeakJobMemoryUsed 27
-#define JobObjectMemoryUsageInformation 28
+#define JobObjectMemoryUsageInformation 28 // JOBOBJECT_MEMORY_USAGE_INFORMATION // JOBOBJECT_MEMORY_USAGE_INFORMATION_V2
#define JobObjectSharedCommit 29
#define JobObjectContainerId 30
#define JobObjectIoRateControlInformation 31
-#define JobObjectNetRateControlInformation 32
-#define JobObjectNotificationLimitInformation2 33
-#define JobObjectLimitViolationInformation2 34
+#define JobObjectNetRateControlInformation 32 // JOBOBJECT_NET_RATE_CONTROL_INFORMATION
+#define JobObjectNotificationLimitInformation2 33 // JOBOBJECT_NOTIFICATION_LIMIT_INFORMATION_2
+#define JobObjectLimitViolationInformation2 34 // JOBOBJECT_LIMIT_VIOLATION_INFORMATION_2
#define JobObjectCreateSilo 35
-#define JobObjectSiloBasicInformation 36
-#define JobObjectSiloRootDirectory 37
-#define JobObjectServerSiloBasicInformation 38
-#define JobObjectServerSiloUserSharedData 39
+#define JobObjectSiloBasicInformation 36 // SILOOBJECT_BASIC_INFORMATION
+#define JobObjectSiloRootDirectory 37 // SILOOBJECT_ROOT_DIRECTORY
+#define JobObjectServerSiloBasicInformation 38 // SERVERSILO_BASIC_INFORMATION
+#define JobObjectServerSiloUserSharedData 39 // SILO_USER_SHARED_DATA
#define JobObjectServerSiloInitialize 40
#define JobObjectServerSiloRunningState 41
#define JobObjectIoAttribution 42
#define JobObjectMemoryPartitionInformation 43
#define JobObjectContainerTelemetryId 44
#define JobObjectSiloSystemRoot 45
-#define JobObjectEnergyTrackingState 46
+#define JobObjectEnergyTrackingState 46 // JOBOBJECT_ENERGY_TRACKING_STATE
#define JobObjectThreadImpersonationInformation 47
#define MaxJobObjectInfoClass 48
diff --git a/phnt/include/ntregapi.h b/inc/phnt/ntregapi.h
similarity index 97%
rename from phnt/include/ntregapi.h
rename to inc/phnt/ntregapi.h
index d5d8741..da9bc24 100644
--- a/phnt/include/ntregapi.h
+++ b/inc/phnt/ntregapi.h
@@ -120,6 +120,7 @@ typedef enum _KEY_SET_INFORMATION_CLASS
KeySetVirtualizationInformation, // KEY_SET_VIRTUALIZATION_INFORMATION
KeySetDebugInformation,
KeySetHandleTagsInformation, // KEY_HANDLE_TAGS_INFORMATION
+ KeySetLayerInformation, // KEY_SET_LAYER_INFORMATION
MaxKeySetInfoClass
} KEY_SET_INFORMATION_CLASS;
@@ -138,6 +139,15 @@ typedef struct _KEY_HANDLE_TAGS_INFORMATION
ULONG HandleTags;
} KEY_HANDLE_TAGS_INFORMATION, *PKEY_HANDLE_TAGS_INFORMATION;
+typedef struct _KEY_SET_LAYER_INFORMATION
+{
+ ULONG IsTombstone : 1;
+ ULONG IsSupersedeLocal : 1;
+ ULONG IsSupersedeTree : 1;
+ ULONG ClassIsInherited : 1;
+ ULONG Reserved : 28;
+} KEY_SET_LAYER_INFORMATION, *PKEY_SET_LAYER_INFORMATION;
+
typedef struct _KEY_CONTROL_FLAGS_INFORMATION
{
ULONG ControlFlags;
diff --git a/phnt/include/ntrtl.h b/inc/phnt/ntrtl.h
similarity index 99%
rename from phnt/include/ntrtl.h
rename to inc/phnt/ntrtl.h
index 0cfd67a..4d505b1 100644
--- a/phnt/include/ntrtl.h
+++ b/inc/phnt/ntrtl.h
@@ -4562,6 +4562,12 @@ typedef struct _RTL_BITMAP
PULONG Buffer;
} RTL_BITMAP, *PRTL_BITMAP;
+typedef struct _RTL_BITMAP_EX
+{
+ ULONG64 SizeOfBitMap;
+ PULONG64 Buffer;
+} RTL_BITMAP_EX, *PRTL_BITMAP_EX;
+
NTSYSAPI
VOID
NTAPI
diff --git a/phnt/include/ntsam.h b/inc/phnt/ntsam.h
similarity index 100%
rename from phnt/include/ntsam.h
rename to inc/phnt/ntsam.h
diff --git a/phnt/include/ntseapi.h b/inc/phnt/ntseapi.h
similarity index 100%
rename from phnt/include/ntseapi.h
rename to inc/phnt/ntseapi.h
diff --git a/phnt/include/ntsmss.h b/inc/phnt/ntsmss.h
similarity index 100%
rename from phnt/include/ntsmss.h
rename to inc/phnt/ntsmss.h
diff --git a/phnt/include/nttmapi.h b/inc/phnt/nttmapi.h
similarity index 100%
rename from phnt/include/nttmapi.h
rename to inc/phnt/nttmapi.h
diff --git a/phnt/include/nttp.h b/inc/phnt/nttp.h
similarity index 100%
rename from phnt/include/nttp.h
rename to inc/phnt/nttp.h
diff --git a/phnt/include/ntwow64.h b/inc/phnt/ntwow64.h
similarity index 99%
rename from phnt/include/ntwow64.h
rename to inc/phnt/ntwow64.h
index 16948f9..4317ab0 100644
--- a/phnt/include/ntwow64.h
+++ b/inc/phnt/ntwow64.h
@@ -167,6 +167,7 @@ typedef struct _LDR_DATA_TABLE_ENTRY32
ULONG ImplicitPathOptions;
ULONG ReferenceCount;
ULONG DependentLoadFlags;
+ UCHAR SigningLevel; // since REDSTONE2
} LDR_DATA_TABLE_ENTRY32, *PLDR_DATA_TABLE_ENTRY32;
typedef struct _CURDIR32
diff --git a/phnt/include/ntxcapi.h b/inc/phnt/ntxcapi.h
similarity index 100%
rename from phnt/include/ntxcapi.h
rename to inc/phnt/ntxcapi.h
diff --git a/phnt/include/ntzwapi.h b/inc/phnt/ntzwapi.h
similarity index 99%
rename from phnt/include/ntzwapi.h
rename to inc/phnt/ntzwapi.h
index d8c445a..48eb7f8 100644
--- a/phnt/include/ntzwapi.h
+++ b/inc/phnt/ntzwapi.h
@@ -1537,17 +1537,6 @@ ZwExtendSection(
_Inout_ PLARGE_INTEGER NewSectionSize
);
-NTSYSCALLAPI
-NTSTATUS
-NTAPI
-ZwFilterBootOption(
- _In_ FILTER_BOOT_OPTION_OPERATION FilterOperation,
- _In_ ULONG ObjectType,
- _In_ ULONG ElementType,
- _In_reads_bytes_opt_(DataSize) PVOID Data,
- _In_ ULONG DataSize
- );
-
NTSYSCALLAPI
NTSTATUS
NTAPI
diff --git a/phnt/include/phnt.h b/inc/phnt/phnt.h
similarity index 98%
rename from phnt/include/phnt.h
rename to inc/phnt/phnt.h
index 42bf2a9..924b09b 100644
--- a/phnt/include/phnt.h
+++ b/inc/phnt/phnt.h
@@ -35,6 +35,7 @@
#define PHNT_THRESHOLD2 101
#define PHNT_REDSTONE 102
#define PHNT_REDSTONE2 103
+#define PHNT_REDSTONE3 104
#ifndef PHNT_MODE
#define PHNT_MODE PHNT_MODE_USER
diff --git a/phnt/include/phnt_ntdef.h b/inc/phnt/phnt_ntdef.h
similarity index 100%
rename from phnt/include/phnt_ntdef.h
rename to inc/phnt/phnt_ntdef.h
diff --git a/phnt/include/phnt_windows.h b/inc/phnt/phnt_windows.h
similarity index 100%
rename from phnt/include/phnt_windows.h
rename to inc/phnt/phnt_windows.h
diff --git a/phnt/include/subprocesstag.h b/inc/phnt/subprocesstag.h
similarity index 100%
rename from phnt/include/subprocesstag.h
rename to inc/phnt/subprocesstag.h
diff --git a/phnt/include/winsta.h b/inc/phnt/winsta.h
similarity index 100%
rename from phnt/include/winsta.h
rename to inc/phnt/winsta.h
diff --git a/phnt/zw_options.txt b/phnt/zw_options.txt
deleted file mode 100644
index ed0c2e6..0000000
--- a/phnt/zw_options.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-base=include
-in=ntdbg.h;ntexapi.h;ntgdi.h;ntioapi.h;ntkeapi.h;ntldr.h;ntlpcapi.h;ntmisc.h;ntmmapi.h;ntnls.h;ntobapi.h;ntpebteb.h;ntpfapi.h;ntpnpapi.h;ntpoapi.h;ntpsapi.h;ntregapi.h;ntrtl.h;ntsam.h;ntseapi.h;nttmapi.h;nttp.h;ntwow64.h;ntxcapi.h
-out=ntzwapi.h
-header=#ifndef _NTZWAPI_H\r\n#define _NTZWAPI_H\r\n\r\n// This file was automatically generated. Do not edit.\r\n\r\n
-footer=#endif\r\n
\ No newline at end of file
diff --git a/wufuc.sln b/wufuc.sln
index acdd8d1..e60c59b 100644
--- a/wufuc.sln
+++ b/wufuc.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
-VisualStudioVersion = 15.0.26730.16
+VisualStudioVersion = 15.0.27004.2008
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wufuc", "wufuc\wufuc.vcxproj", "{00F96695-CE41-4C2F-A344-6219DFB4F887}"
EndProject
@@ -20,7 +20,7 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Documentation", "Documentation", "{65210B26-9B74-4B7E-B777-7A2EE4162595}"
ProjectSection(SolutionItems) = preProject
CONTRIBUTING.md = CONTRIBUTING.md
- DONATIONS.md = DONATIONS.md
+ DONATE.md = DONATE.md
LICENSE = LICENSE
README.md = README.md
EndProjectSection
diff --git a/wufuc/appverifier.h b/wufuc/appverifier.h
deleted file mode 100644
index 51dbac2..0000000
--- a/wufuc/appverifier.h
+++ /dev/null
@@ -1,45 +0,0 @@
-#pragma once
-
-#include
-
-#define DLL_PROCESS_VERIFIER 4
-
-typedef VOID(NTAPI *RTL_VERIFIER_DLL_LOAD_CALLBACK)(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved);
-typedef VOID(NTAPI *RTL_VERIFIER_DLL_UNLOAD_CALLBACK)(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved);
-typedef VOID(NTAPI *RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK)(PVOID AllocationBase, SIZE_T AllocationSize);
-
-typedef struct tagRTL_VERIFIER_THUNK_DESCRIPTOR
-{
- PCHAR ThunkName;
- PVOID ThunkOldAddress;
- PVOID ThunkNewAddress;
-} RTL_VERIFIER_THUNK_DESCRIPTOR, *PRTL_VERIFIER_THUNK_DESCRIPTOR;
-
-typedef struct tagRTL_VERIFIER_DLL_DESCRIPTOR
-{
- PWCHAR DllName;
- DWORD DllFlags;
- PVOID DllAddress;
- PRTL_VERIFIER_THUNK_DESCRIPTOR DllThunks;
-} RTL_VERIFIER_DLL_DESCRIPTOR, *PRTL_VERIFIER_DLL_DESCRIPTOR;
-
-typedef struct tagRTL_VERIFIER_PROVIDER_DESCRIPTOR
-{
- DWORD Length;
- PRTL_VERIFIER_DLL_DESCRIPTOR ProviderDlls;
- RTL_VERIFIER_DLL_LOAD_CALLBACK ProviderDllLoadCallback;
- RTL_VERIFIER_DLL_UNLOAD_CALLBACK ProviderDllUnloadCallback;
- PWSTR VerifierImage;
- DWORD VerifierFlags;
- DWORD VerifierDebug;
- PVOID RtlpGetStackTraceAddress;
- PVOID RtlpDebugPageHeapCreate;
- PVOID RtlpDebugPageHeapDestroy;
- RTL_VERIFIER_NTDLLHEAPFREE_CALLBACK ProviderNtdllHeapFreeCallback;
-} RTL_VERIFIER_PROVIDER_DESCRIPTOR, *PRTL_VERIFIER_PROVIDER_DESCRIPTOR;
-
-typedef LSTATUS(WINAPI *LPFN_REGQUERYVALUEEXW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
-typedef HMODULE(WINAPI *LPFN_LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
-
-extern LPFN_REGQUERYVALUEEXW *g_plpfnRegQueryValueExW;
-extern LPFN_LOADLIBRARYEXW *g_plpfnLoadLibraryExW;
diff --git a/wufuc/callbacks.c b/wufuc/callbacks.c
index 987fbee..9d29ae0 100644
--- a/wufuc/callbacks.c
+++ b/wufuc/callbacks.c
@@ -1,15 +1,22 @@
+#include "stdafx.h"
#include "callbacks.h"
+#include "helpers.h"
+#include
-#include "tracing.h"
-
-#include
-
-VOID NTAPI VerifierDllLoadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved)
+VOID CALLBACK ServiceNotifyCallback(PSERVICE_NOTIFYW pNotifyBuffer)
{
- trace(L"dll load %ls, DllBase=%p, DllSize=%Iu", DllName, DllBase, DllSize);
-}
+ HMODULE hModule;
-VOID NTAPI VerifierDllUnloadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved)
-{
- trace(L"dll unload %ls, DllBase=%p, DllSize=%Iu", DllName, DllBase, DllSize);
+ switch ( pNotifyBuffer->dwNotificationStatus ) {
+ case ERROR_SUCCESS:
+ if ( inject_self_into_process(pNotifyBuffer->ServiceStatus.dwProcessId, &hModule) ) {
+
+ }
+ break;
+ case ERROR_SERVICE_MARKED_FOR_DELETE:
+ SetEvent((HANDLE)pNotifyBuffer->pContext);
+ break;
+ }
+ if ( pNotifyBuffer->pszServiceNames )
+ LocalFree((HLOCAL)pNotifyBuffer->pszServiceNames);
}
diff --git a/wufuc/callbacks.h b/wufuc/callbacks.h
index 49c8ccd..6a57f58 100644
--- a/wufuc/callbacks.h
+++ b/wufuc/callbacks.h
@@ -2,5 +2,4 @@
#include
-VOID NTAPI VerifierDllLoadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved);
-VOID NTAPI VerifierDllUnloadCallback(PWSTR DllName, PVOID DllBase, SIZE_T DllSize, PVOID Reserved);
+VOID CALLBACK ServiceNotifyCallback(PSERVICE_NOTIFYW pNotifyBuffer);
diff --git a/wufuc/dllmain.c b/wufuc/dllmain.c
index c39d2cd..06ee1d6 100644
--- a/wufuc/dllmain.c
+++ b/wufuc/dllmain.c
@@ -1,68 +1,15 @@
-#include "appverifier.h"
-#include "hooks.h"
-#include "callbacks.h"
-#include "helpers.h"
-
-#include
-
-#include
-#include
-
-RTL_VERIFIER_THUNK_DESCRIPTOR g_vfThunkDescriptors[] = {
- { "RegQueryValueExW", NULL, (PVOID)&RegQueryValueExW_Hook },
- { "LoadLibraryExW", NULL, (PVOID)&LoadLibraryExW_Hook },
- { 0 } };
-
-RTL_VERIFIER_DLL_DESCRIPTOR g_vfDllDescriptors[2];
-
-RTL_VERIFIER_PROVIDER_DESCRIPTOR g_vfProviderDescriptor = {
- sizeof(RTL_VERIFIER_PROVIDER_DESCRIPTOR),
- g_vfDllDescriptors/*,
- (RTL_VERIFIER_DLL_LOAD_CALLBACK)&VerifierDllLoadCallback,
- (RTL_VERIFIER_DLL_UNLOAD_CALLBACK)&VerifierDllUnloadCallback*/ };
-
-LPFN_REGQUERYVALUEEXW *g_plpfnRegQueryValueExW;
-LPFN_LOADLIBRARYEXW *g_plpfnLoadLibraryExW;
+#include "stdafx.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch ( ul_reason_for_call ) {
case DLL_PROCESS_ATTACH:
- LdrDisableThreadCalloutsForDll((PVOID)hModule);
+ DisableThreadLibraryCalls(hModule);
break;
case DLL_PROCESS_DETACH:
break;
- case DLL_PROCESS_VERIFIER:
- if ( verify_win7() || verify_win81() ) {
- UNICODE_STRING ImagePath;
- RtlInitUnicodeString(&ImagePath, NULL);
-
- RTL_QUERY_REGISTRY_TABLE QueryTable[2];
- RtlSecureZeroMemory(&QueryTable, sizeof(QueryTable));
- QueryTable[0].Name = L"ImagePath";
- QueryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT;
- QueryTable[0].EntryContext = &ImagePath;
-
- if ( RtlQueryRegistryValues(RTL_REGISTRY_SERVICES, L"wuauserv", QueryTable, NULL, NULL) == STATUS_SUCCESS
- && !RtlCompareUnicodeString(&NtCurrentPeb()->ProcessParameters->CommandLine, &ImagePath, TRUE) ) {
-
- if ( verify_win7() )
- g_vfDllDescriptors[0].DllName = L"kernel32.dll";
- else if ( verify_win81() )
- g_vfDllDescriptors[0].DllName = L"kernelbase.dll";
-
- g_vfDllDescriptors[0].DllThunks = g_vfThunkDescriptors;
-
- g_plpfnRegQueryValueExW = (LPFN_REGQUERYVALUEEXW *)&g_vfThunkDescriptors[0].ThunkOldAddress;
- g_plpfnLoadLibraryExW = (LPFN_LOADLIBRARYEXW *)&g_vfThunkDescriptors[1].ThunkOldAddress;
- }
- RtlFreeUnicodeString(&ImagePath);
- }
- *(PRTL_VERIFIER_PROVIDER_DESCRIPTOR *)lpReserved = &g_vfProviderDescriptor;
- break;
default:
break;
}
-
return TRUE;
}
diff --git a/wufuc/exports.def b/wufuc/exports.def
index 3b360ea..288118e 100644
--- a/wufuc/exports.def
+++ b/wufuc/exports.def
@@ -1,4 +1,5 @@
LIBRARY
EXPORTS
- RUNDLL32_LegacyUnloadW @1
- RUNDLL32_DeleteFileW @2
+ RUNDLL32_StartW @3
+ RUNDLL32_UnloadW @4
+ RUNDLL32_DeleteFileW @5
\ No newline at end of file
diff --git a/wufuc/helpers.c b/wufuc/helpers.c
index 3f2b74b..dc6beb5 100644
--- a/wufuc/helpers.c
+++ b/wufuc/helpers.c
@@ -1,104 +1,163 @@
+#include "stdafx.h"
#include "helpers.h"
+#include
-#include
-#include
-
-#include
-#include
-
-bool verify_winver(
- DWORD dwMajorVersion,
- DWORD dwMinorVersion,
- DWORD dwBuildNumber,
- WORD wServicePackMajor,
- WORD wServicePackMinor,
- BYTE MajorVersionCondition,
- BYTE MinorVersionCondition,
- BYTE BuildNumberCondition,
- BYTE ServicePackMajorCondition,
- BYTE ServicePackMinorCondition
-)
+bool create_exclusive_mutex(const wchar_t *name, HANDLE *pmutex)
{
- RTL_OSVERSIONINFOEXW osvi = { 0 };
- osvi.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);
+ HANDLE mutex;
- osvi.dwMajorVersion = dwMajorVersion;
- osvi.dwMinorVersion = dwMinorVersion;
- osvi.dwBuildNumber = dwBuildNumber;
- osvi.wServicePackMajor = wServicePackMajor;
- osvi.wServicePackMinor = wServicePackMinor;
-
- ULONGLONG ConditionMask = 0;
- ULONG TypeMask = 0;
- if ( MajorVersionCondition ) {
- TypeMask |= VER_MAJORVERSION;
- VER_SET_CONDITION(ConditionMask, VER_MAJORVERSION, MajorVersionCondition);
+ mutex = CreateMutexW(NULL, TRUE, name);
+ if ( mutex ) {
+ if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
+ CloseHandle(mutex);
+ return false;
+ }
+ *pmutex = mutex;
+ return true;
}
- if ( MinorVersionCondition ) {
- TypeMask |= VER_MINORVERSION;
- VER_SET_CONDITION(ConditionMask, VER_MINORVERSION, MinorVersionCondition);
- }
- if ( BuildNumberCondition ) {
- TypeMask |= VER_BUILDNUMBER;
- VER_SET_CONDITION(ConditionMask, VER_BUILDNUMBER, BuildNumberCondition);
- }
- if ( ServicePackMajorCondition ) {
- TypeMask |= VER_SERVICEPACKMAJOR;
- VER_SET_CONDITION(ConditionMask, VER_SERVICEPACKMAJOR, ServicePackMajorCondition);
- }
- if ( ServicePackMinorCondition ) {
- TypeMask |= VER_SERVICEPACKMINOR;
- VER_SET_CONDITION(ConditionMask, VER_SERVICEPACKMINOR, ServicePackMinorCondition);
- }
- return RtlVerifyVersionInfo(&osvi, TypeMask, ConditionMask) == STATUS_SUCCESS;
+ return false;
}
-bool verify_win7(void)
+bool create_event_with_security_descriptor(const wchar_t *descriptor, bool manualreset, bool initialstate, const wchar_t *name, HANDLE *pevent)
{
- static bool a, b;
- if ( !a ) {
- b = verify_winver(6, 1, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0);
- a = true;
+ SECURITY_ATTRIBUTES sa = { sizeof sa };
+ HANDLE event;
+
+ if ( ConvertStringSecurityDescriptorToSecurityDescriptorW(descriptor, SDDL_REVISION_1, &sa.lpSecurityDescriptor, NULL) ) {
+ event = CreateEventW(&sa, manualreset, initialstate, name);
+ if ( event ) {
+ *pevent = event;
+ return true;
+ }
}
- return b;
+ return false;
}
-bool verify_win81(void)
+bool inject_self_into_process(DWORD dwProcessId, HMODULE *phModule)
{
- static bool a, b;
- if ( !a ) {
- b = verify_winver(6, 3, 0, 0, 0, VER_EQUAL, VER_EQUAL, 0, 0, 0);
- a = true;
+ wchar_t szFilename[MAX_PATH];
+ DWORD nLength;
+
+ nLength = GetModuleFileNameW(PIMAGEBASE, szFilename, _countof(szFilename));
+
+ if ( nLength )
+ return inject_dll_into_process(dwProcessId, szFilename, nLength, phModule);
+
+ return false;
+}
+
+bool inject_dll_into_process(DWORD dwProcessId, const wchar_t *pszFilename, size_t nLength, HMODULE *phModule)
+{
+ bool result = false;
+ HANDLE hProcess;
+ NTSTATUS Status;
+ LPVOID pBaseAddress;
+ HANDLE hThread;
+ HANDLE hModule = NULL;
+
+ hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
+ if ( !hProcess ) return result;
+
+ Status = NtSuspendProcess(hProcess);
+ if ( !NT_SUCCESS(Status) ) goto L1;
+
+ pBaseAddress = VirtualAllocEx(hProcess, NULL, nLength + (sizeof *pszFilename), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
+ if ( !pBaseAddress ) goto L2;
+
+ if ( WriteProcessMemory(hProcess, pBaseAddress, pszFilename, nLength, NULL)
+ && (hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)LoadLibraryW, pBaseAddress, 0, NULL)) ) {
+
+ WaitForSingleObject(hThread, INFINITE);
+ if ( sizeof(DWORD) < sizeof hModule ) {
+
+ } else {
+ GetExitCodeThread(hThread, (LPDWORD)&hModule);
+ }
+ if ( hModule ) {
+ result = true;
+ *phModule = hModule;
+ }
+ CloseHandle(hThread);
}
- return b;
+ VirtualFreeEx(hProcess, pBaseAddress, 0, MEM_RELEASE);
+L2: NtResumeProcess(hProcess);
+L1: CloseHandle(hProcess);
+ return result;
}
-wchar_t *find_fname(wchar_t *pPath)
+const wchar_t *path_find_fname(const wchar_t *path)
{
- wchar_t *pwc = wcsrchr(pPath, L'\\');
- if ( pwc && *(++pwc) )
- return pwc;
+ const wchar_t *pwc = NULL;
+ if ( path )
+ pwc = (const wchar_t *)wcsrchr(path, L'\\');
- return pPath;
+ return (pwc && *(++pwc)) ? pwc : path;
}
-bool file_exists(const wchar_t *path)
+bool path_change_fname(const wchar_t *srcpath, const wchar_t *fname, wchar_t *dstpath, size_t size)
+{
+ bool result;
+ wchar_t drive[_MAX_DRIVE];
+ wchar_t dir[_MAX_DIR];
+
+ result = !_wsplitpath_s(srcpath, drive, _countof(drive), dir, _countof(dir), NULL, 0, NULL, 0);
+ if ( result )
+ result = !_wmakepath_s(dstpath, size, drive, dir, fname, NULL);
+ return result;
+}
+
+bool path_file_exists(const wchar_t *path)
{
return GetFileAttributesW(path) != INVALID_FILE_ATTRIBUTES;
}
-int compare_versions(
- WORD wMajorA, WORD wMinorA, WORD wBuildA, WORD wRevisionA,
- WORD wMajorB, WORD wMinorB, WORD wBuildB, WORD wRevisionB
-)
+bool path_expand_file_exists(const wchar_t *path)
{
- if ( wMajorA < wMajorB ) return -1;
- if ( wMajorA > wMajorB ) return 1;
- if ( wMinorA < wMinorB ) return -1;
- if ( wMinorA > wMinorB ) return 1;
- if ( wBuildA < wBuildB ) return -1;
- if ( wBuildA > wBuildB ) return 1;
- if ( wRevisionA < wRevisionB ) return -1;
- if ( wRevisionA > wRevisionB ) return 1;
+ bool result;
+ wchar_t *dst;
+ DWORD buffersize;
+ DWORD size;
+
+ dst = NULL;
+ size = 0;
+ do {
+ if ( size ) {
+ if ( dst )
+ free(dst);
+ dst = calloc(size, sizeof *dst);
+ }
+ buffersize = size;
+ size = ExpandEnvironmentStringsW(path, dst, buffersize);
+ } while ( buffersize < size );
+
+ result = path_file_exists(dst);
+ free(dst);
+ return result;
+}
+
+int ffi_ver_compare(VS_FIXEDFILEINFO *pffi, WORD wMajor, WORD wMinor, WORD wBuild, WORD wRev)
+{
+ if ( HIWORD(pffi->dwProductVersionMS) < wMajor ) return -1;
+ if ( HIWORD(pffi->dwProductVersionMS) > wMajor ) return 1;
+ if ( LOWORD(pffi->dwProductVersionMS) < wMinor ) return -1;
+ if ( LOWORD(pffi->dwProductVersionMS) > wMinor ) return 1;
+ if ( HIWORD(pffi->dwProductVersionLS) < wBuild ) return -1;
+ if ( HIWORD(pffi->dwProductVersionLS) > wBuild ) return 1;
+ if ( LOWORD(pffi->dwProductVersionLS) < wRev ) return -1;
+ if ( LOWORD(pffi->dwProductVersionLS) > wRev ) return 1;
return 0;
}
+
+size_t find_argv_option(const wchar_t **argv, size_t argc, const wchar_t *option)
+{
+ size_t index = -1;
+
+ for ( size_t i = 1; i < argc; i++ ) {
+ if ( !_wcsicmp(argv[i], option) )
+ index = i;
+ }
+ if ( index == -1 )
+ return index;
+
+ return ++index < argc ? index : -1;
+}
diff --git a/wufuc/helpers.h b/wufuc/helpers.h
index 43c4bfb..8d51e94 100644
--- a/wufuc/helpers.h
+++ b/wufuc/helpers.h
@@ -1,26 +1,13 @@
#pragma once
-#include
+bool create_exclusive_mutex(const wchar_t *name, HANDLE *pmutex);
+bool create_event_with_security_descriptor(const wchar_t *descriptor, bool manualreset, bool initialstate, const wchar_t *name, HANDLE *pevent);
-#include
+bool inject_self_into_process(DWORD dwProcessId, HMODULE *phModule);
+bool inject_dll_into_process(DWORD dwProcessId, const wchar_t *pszFilename, size_t nLength, HMODULE *phModule);
-bool verify_winver(
- DWORD dwMajorVersion,
- DWORD dwMinorVersion,
- DWORD dwBuildNumber,
- WORD wServicePackMajor,
- WORD wServicePackMinor,
- BYTE MajorVersionCondition,
- BYTE MinorVersionCondition,
- BYTE BuildNumberCondition,
- BYTE ServicePackMajorCondition,
- BYTE ServicePackMinorCondition
-);
-bool verify_win7(void);
-bool verify_win81(void);
-
-wchar_t *find_fname(wchar_t *pPath);
-bool file_exists(const wchar_t *path);
-int compare_versions(
- WORD wMajorA, WORD wMinorA, WORD wBuildA, WORD wRevisionA,
- WORD wMajorB, WORD wMinorB, WORD wBuildB, WORD wRevisionB);
+const wchar_t *path_find_fname(const wchar_t *path);
+bool path_change_fname(const wchar_t *srcpath, const wchar_t *fname, wchar_t *dstpath, size_t size);
+bool path_file_exists(const wchar_t *path);
+bool path_expand_file_exists(const wchar_t *path);
+int ffi_ver_compare(VS_FIXEDFILEINFO *pffi, WORD wMajor, WORD wMinor, WORD wBuild, WORD wRev);
\ No newline at end of file
diff --git a/wufuc/hooks.c b/wufuc/hooks.c
index 9a7bf2b..a0989bc 100644
--- a/wufuc/hooks.c
+++ b/wufuc/hooks.c
@@ -1,156 +1,144 @@
+#include "stdafx.h"
#include "hooks.h"
-
-#include "appverifier.h"
#include "patchwua.h"
#include "helpers.h"
-#include "tracing.h"
-#include "rtl_malloc.h"
-#include
-#include
-#include
-
-#include
-#include
#include
+LPFN_REGQUERYVALUEEXW g_pfnRegQueryValueExW;
+LPFN_LOADLIBRARYEXW g_pfnLoadLibraryExW;
-LSTATUS WINAPI RegQueryValueExW_Hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
+LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
{
LSTATUS result;
+ DWORD cbData;
+ NTSTATUS Status;
+ ULONG ResultLength;
+ PKEY_NAME_INFORMATION pkni;
+ size_t BufferCount;
+ int current;
+ int pos;
+ wchar_t *tmp;
+ size_t MaxCount;
+ size_t cbLength;
if ( (lpData && lpcbData)
&& (lpValueName && !_wcsicmp(lpValueName, L"ServiceDll")) ) {
// store original lpData buffer size
- DWORD cbData = *lpcbData;
+ cbData = *lpcbData;
// this way the dll path is guaranteed to be null-terminated
result = RegGetValueW(hKey, NULL, lpValueName, RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, lpType, lpData, lpcbData);
+ if ( result != ERROR_SUCCESS )
+ goto L1;
- NTSTATUS Status;
- ULONG ResultLength;
- if ( result != ERROR_SUCCESS
- || (Status = NtQueryKey((HANDLE)hKey, KeyNameInformation, NULL, 0, &ResultLength),
- Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL) )
- goto L_ret;
-
- PKEY_NAME_INFORMATION pkni = rtl_malloc(ResultLength);
-
- if ( NtQueryKey((HANDLE)hKey, KeyNameInformation, (PVOID)pkni, ResultLength, &ResultLength) != STATUS_SUCCESS )
- goto L_free_pkni;
-
- size_t BufferCount = pkni->NameLength / sizeof(wchar_t);
+ pkni = NULL;
+ ResultLength = 0;
+ do {
+ if ( ResultLength ) {
+ if ( pkni )
+ free(pkni);
+ pkni = malloc(ResultLength);
+ }
+ Status = NtQueryKey((HANDLE)hKey, KeyNameInformation, pkni, ResultLength, &ResultLength);
+ } while ( Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL );
+ if ( !NT_SUCCESS(Status) )
+ goto L2;
+ BufferCount = pkni->NameLength / sizeof(wchar_t);
// change key name to lower-case because there is no case-insensitive version of _snwscanf_s
- for ( size_t i = 0; i < BufferCount; i++ )
- pkni->Name[i] = towlower(pkni->Name[i]);
-
- int current, pos;
- if ( _snwscanf_s(pkni->Name, BufferCount,
- L"\\registry\\machine\\system\\controlset%03d\\services\\wuauserv\\parameters%n", ¤t, &pos) == 1
+ if ( !_wcslwr_s(pkni->Name, BufferCount) && _snwscanf_s(pkni->Name, BufferCount,
+ L"\\registry\\machine\\system\\controlset%03d\\services\\wuauserv\\parameters%n", ¤t, &pos) == 1
&& pos == BufferCount ) {
- wchar_t drive[_MAX_DRIVE], dir[_MAX_DIR], fname[_MAX_FNAME], ext[_MAX_EXT];
- _wsplitpath_s((wchar_t *)lpData,
- drive, _countof(drive),
- dir, _countof(dir),
- fname, _countof(fname),
- ext, _countof(ext));
+ const wchar_t *fname = path_find_fname((wchar_t *)lpData);
- if ( !_wcsicmp(ext, L".dll")
- && (!_wcsicmp(fname, L"wuaueng2") // UpdatePack7R2
- || !_wcsicmp(fname, L"WuaCpuFix64") // WuaCpuFix
- || !_wcsicmp(fname, L"WuaCpuFix")) ) {
+ if ( !_wcsicmp(fname, L"wuaueng2.dll") // UpdatePack7R2
+ || !_wcsicmp(fname, L"WuaCpuFix64.dll") // WuaCpuFix
+ || !_wcsicmp(fname, L"WuaCpuFix.dll") ) {
- wchar_t *tmp = rtl_malloc(cbData);
+ MaxCount = cbData / sizeof(wchar_t);
+ tmp = malloc(cbData);
+ path_change_fname((wchar_t *)lpData, L"wuaueng.dll", tmp, MaxCount);
+ if ( path_expand_file_exists(tmp)
+ && !wcscpy_s((wchar_t *)lpData, MaxCount, tmp)
+ && SUCCEEDED(StringCbLengthW((PNZWCH)lpData, cbData, &cbLength)) ) {
- size_t MaxCount = cbData / sizeof(wchar_t);
- _wmakepath_s(tmp, MaxCount, drive, dir, L"wuaueng", ext);
- DWORD nSize = ExpandEnvironmentStringsW(tmp, NULL, 0);
-
- wchar_t *lpDst = rtl_calloc(nSize, sizeof(wchar_t));
- ExpandEnvironmentStringsW(tmp, lpDst, nSize);
-
- rtl_free(tmp);
-
- if ( file_exists(lpDst) ) {
- _wmakepath_s((wchar_t *)lpData, MaxCount, drive, dir, L"wuaueng", ext);
- *lpcbData = (DWORD)((wcslen((wchar_t *)lpData) + 1) * sizeof(wchar_t));
- trace(L"Fixed wuauserv %ls path: %ls", lpValueName, lpDst);
+ *lpcbData = (DWORD)(cbLength + (sizeof UNICODE_NULL));
}
- rtl_free(lpDst);
+ free(tmp);
}
}
-L_free_pkni:
- rtl_free(pkni);
+L2: free(pkni);
} else {
// handle normally
- result = (*g_plpfnRegQueryValueExW)(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
+ result = g_pfnRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
}
-L_ret:
- return result;
+L1: return result;
}
-HMODULE WINAPI LoadLibraryExW_Hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags)
+HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags)
{
- HMODULE result = (*g_plpfnLoadLibraryExW)(lpFileName, hFile, dwFlags);
+ HMODULE result;
+ DWORD dwLen;
+ LPVOID pBlock;
+ PLANGANDCODEPAGE ptl;
+ UINT cb;
+ wchar_t lpSubBlock[38];
+ wchar_t *lpszInternalName;
+ UINT uLen;
+ VS_FIXEDFILEINFO *pffi;
+ wchar_t path[MAX_PATH];
+ const wchar_t *fname;
+ MODULEINFO modinfo;
+
+ result = g_pfnLoadLibraryExW(lpFileName, hFile, dwFlags);
if ( !result ) {
trace(L"Failed to load library: %ls (error code=%08X)", lpFileName, GetLastError());
- goto L_ret;
+ goto L1;
}
trace(L"Loaded library: %ls", lpFileName);
- DWORD dwLen = GetFileVersionInfoSizeW(lpFileName, NULL);
+ dwLen = GetFileVersionInfoSizeW(lpFileName, NULL);
if ( !dwLen )
- goto L_ret;
-
- LPVOID pBlock = rtl_malloc(dwLen);
+ goto L1;
+
+ pBlock = malloc(dwLen);
- PLANGANDCODEPAGE ptl;
- UINT cb;
if ( !GetFileVersionInfoW(lpFileName, 0, dwLen, pBlock)
|| !VerQueryValueW(pBlock, L"\\VarFileInfo\\Translation", (LPVOID *)&ptl, &cb) )
- goto L_free_pBlock;
+ goto L2;
- wchar_t lpSubBlock[38];
for ( size_t i = 0; i < (cb / sizeof(LANGANDCODEPAGE)); i++ ) {
swprintf_s(lpSubBlock, _countof(lpSubBlock),
- L"\\StringFileInfo\\%04x%04x\\InternalName",
- ptl[i].wLanguage,
+ L"\\StringFileInfo\\%04x%04x\\InternalName",
+ ptl[i].wLanguage,
ptl[i].wCodePage);
-
- wchar_t *lpszInternalName;
- UINT uLen;
+
if ( VerQueryValueW(pBlock, lpSubBlock, (LPVOID *)&lpszInternalName, &uLen)
&& !_wcsicmp(lpszInternalName, L"wuaueng.dll") ) {
- VS_FIXEDFILEINFO *pffi;
VerQueryValueW(pBlock, L"\\", (LPVOID *)&pffi, &uLen);
- WORD wMajor = HIWORD(pffi->dwProductVersionMS);
- WORD wMinor = LOWORD(pffi->dwProductVersionMS);
- WORD wBuild = HIWORD(pffi->dwProductVersionLS);
- WORD wRevision = LOWORD(pffi->dwProductVersionLS);
-
- wchar_t path[MAX_PATH];
GetModuleFileNameW(result, path, _countof(path));
- wchar_t *fname = find_fname(path);
+ fname = path_find_fname(path);
- if ( (verify_win7() && compare_versions(wMajor, wMinor, wBuild, wRevision, 7, 6, 7601, 23714) != -1)
- || (verify_win81() && compare_versions(wMajor, wMinor, wBuild, wRevision, 7, 9, 9600, 18621) != -1) ) {
+ if ( (/*verify_win7() &&*/ ffi_ver_compare(pffi, 7, 6, 7601, 23714) != -1)
+ || (/*verify_win81() &&*/ ffi_ver_compare(pffi, 7, 9, 9600, 18621) != -1) ) {
- trace(L"%ls version: %d.%d.%d.%d", fname, wMajor, wMinor, wBuild, wRevision);
- MODULEINFO modinfo;
if ( GetModuleInformation(GetCurrentProcess(), result, &modinfo, sizeof(MODULEINFO)) ) {
if ( !patch_wua(modinfo.lpBaseOfDll, modinfo.SizeOfImage, fname) )
trace(L"Failed to patch %ls!", fname);
- } else trace(L"Failed to get module information for %ls (%p) (couldn't patch)", fname, result);
- } else trace(L"Unsupported %ls version: %d.%d.%d.%d (patching skipped)", fname, wMajor, wMinor, wBuild, wRevision);
+ }
+ }
break;
}
}
-L_free_pBlock:
- rtl_free(pBlock);
-L_ret:
- return result;
+L2: free(pBlock);
+L1: return result;
+}
+
+BOOL WINAPI IsDeviceServiceable_hook(void)
+{
+ return TRUE;
}
diff --git a/wufuc/hooks.h b/wufuc/hooks.h
index 2eddadd..f0a1932 100644
--- a/wufuc/hooks.h
+++ b/wufuc/hooks.h
@@ -8,5 +8,11 @@ typedef struct tagLANGANDCODEPAGE
WORD wCodePage;
} LANGANDCODEPAGE, *PLANGANDCODEPAGE;
-LSTATUS WINAPI RegQueryValueExW_Hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData);
-HMODULE WINAPI LoadLibraryExW_Hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags);
+typedef LSTATUS(WINAPI *LPFN_REGQUERYVALUEEXW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
+typedef HMODULE(WINAPI *LPFN_LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
+
+extern LPFN_REGQUERYVALUEEXW g_pfnRegQueryValueExW;
+extern LPFN_LOADLIBRARYEXW g_pfnLoadLibraryExW;
+
+LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData);
+HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags);
diff --git a/wufuc/patchwua.c b/wufuc/patchwua.c
index 7258785..e3a3ef9 100644
--- a/wufuc/patchwua.c
+++ b/wufuc/patchwua.c
@@ -1,14 +1,6 @@
+#include "stdafx.h"
#include "patchwua.h"
-
-#include "helpers.h"
#include "patternfind.h"
-#include "tracing.h"
-
-#include
-#include
-
-#include
-#include
#ifdef _M_AMD64
static const PatchSet X64PatchSet = { "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????", 0xA, 0x12 };
@@ -31,48 +23,48 @@ bool calculate_pointers(uintptr_t lpfn, const PatchSet *ps, LPBOOL *ppba, LPBOOL
return false;
}
-bool patch_wua(void *lpBaseOfDll, size_t SizeOfImage, wchar_t *fname)
+bool patch_wua(void *lpBaseOfDll, size_t SizeOfImage, const wchar_t *fname)
{
bool result = false;
- const PatchSet *pps;
+ const PatchSet *pps = NULL;
#ifdef _M_AMD64
pps = &X64PatchSet;
#elif defined(_M_IX86)
- if ( verify_win7() )
+ if ( 1/*verify_win7()*/ )
pps = &Win7X86PatchSet;
- else if ( verify_win81() )
+ else if ( 1/*verify_win81()*/ )
pps = &Win81X86PatchSet;
- else
- goto L_ret;
+ else
+ goto L1;
#endif
- unsigned char *ptr = patternfind(lpBaseOfDll, SizeOfImage, pps->Pattern);
- if ( !ptr ) {
+ size_t offset = patternfind(lpBaseOfDll, SizeOfImage, pps->Pattern);
+ if ( offset == -1 ) {
trace(L"No pattern match! (couldn't patch)");
- goto L_ret;
+ goto L1;
}
+ uintptr_t ptr = (uintptr_t)lpBaseOfDll + offset;
LPBOOL pba, pbb;
if ( calculate_pointers((uintptr_t)ptr, pps, &pba, &pbb) ) {
DWORD flOldProtect;
if ( *pba == TRUE ) {
- if ( VirtualProtect(pba, sizeof(BOOL), PAGE_READWRITE, &flOldProtect) ) {
+ if ( VirtualProtect(pba, sizeof *pba, PAGE_READWRITE, &flOldProtect) ) {
*pba = FALSE;
trace(L"Patched value #1 at %ls!%p: %08X", fname, pba, *pba);
- if ( !VirtualProtect(pba, sizeof(BOOL), flOldProtect, &flOldProtect) )
+ if ( !VirtualProtect(pba, sizeof *pba, flOldProtect, &flOldProtect) )
trace(L"Failed to restore memory region permissions at %ls!%p (error code=%08X)", fname, pba, GetLastError());
} else trace(L"Failed to change memory region permissions at %ls!%p (error code=%08X)", fname, pba, GetLastError());
}
if ( *pbb == FALSE ) {
- if ( VirtualProtect(pbb, sizeof(BOOL), PAGE_READWRITE, &flOldProtect) ) {
+ if ( VirtualProtect(pbb, sizeof *pbb, PAGE_READWRITE, &flOldProtect) ) {
*pbb = TRUE;
trace(L"Patched value #2 at %ls!%p: %08X", fname, pbb, *pbb);
- if ( !VirtualProtect(pbb, sizeof(BOOL), flOldProtect, &flOldProtect) )
+ if ( !VirtualProtect(pbb, sizeof *pbb, flOldProtect, &flOldProtect) )
trace(L"Failed to restore memory region permissions at %ls!%p: (error code=%08X)", fname, pbb, GetLastError());
} else trace(L"Failed to change memory region permissions at %ls!%p (error code=%08X)", fname, pbb, GetLastError());
}
result = !*pba && *pbb;
}
-L_ret:
- return result;
+L1: return result;
}
diff --git a/wufuc/patchwua.h b/wufuc/patchwua.h
index c997f8a..ab647c4 100644
--- a/wufuc/patchwua.h
+++ b/wufuc/patchwua.h
@@ -12,4 +12,4 @@ typedef struct tagPatchSet
} PatchSet;
bool calculate_pointers(uintptr_t lpfn, const PatchSet *ps, LPBOOL *ppba, LPBOOL *ppbb);
-bool patch_wua(void *lpBaseOfDll, size_t SizeOfImage, wchar_t *fname);
+bool patch_wua(void *lpBaseOfDll, size_t SizeOfImage, const wchar_t *fname);
diff --git a/wufuc/patternfind.c b/wufuc/patternfind.c
index 966821e..0936c9d 100644
--- a/wufuc/patternfind.c
+++ b/wufuc/patternfind.c
@@ -1,11 +1,6 @@
+#include "stdafx.h"
#include "patternfind.h"
-#include "rtl_malloc.h"
-
-#include
-#include
-#include
-
static inline bool isHex(char ch)
{
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');
@@ -51,14 +46,14 @@ static inline size_t formathexpattern(const char *patterntext, char *formattext,
bool patterntransform(const char *patterntext, PatternByte *pattern, size_t patternsize)
{
- memset(pattern, 0, patternsize * sizeof(PatternByte));
+ memset(pattern, 0, patternsize * (sizeof *pattern));
size_t len = formathexpattern(patterntext, NULL, 0);
if ( !len || len / 2 > patternsize )
return false;
size_t size = len + 1;
- char *formattext = rtl_malloc(size);
+ char *formattext = malloc(size);
formathexpattern(patterntext, formattext, size);
PatternByte newByte;
@@ -76,20 +71,21 @@ bool patterntransform(const char *patterntext, PatternByte *pattern, size_t patt
pattern[k++] = newByte;
}
}
+ free(formattext);
return true;
}
-static inline bool patternmatchbyte(unsigned char byte, const PatternByte pbyte)
+static inline bool patternmatchbyte(uint8_t byte, const PatternByte pbyte)
{
int matched = 0;
- unsigned char n1 = (byte >> 4) & 0xF;
+ uint8_t n1 = (byte >> 4) & 0xF;
if ( pbyte.nibble[0].wildcard )
matched++;
else if ( pbyte.nibble[0].data == n1 )
matched++;
- unsigned char n2 = byte & 0xF;
+ uint8_t n2 = byte & 0xF;
if ( pbyte.nibble[1].wildcard )
matched++;
else if ( pbyte.nibble[1].data == n2 )
@@ -98,20 +94,22 @@ static inline bool patternmatchbyte(unsigned char byte, const PatternByte pbyte)
return (matched == 2);
}
-unsigned char *patternfind(unsigned char *data, size_t datasize, const char *pattern)
+__declspec(noinline)
+size_t patternfind(uint8_t *data, size_t datasize, const char *pattern)
{
size_t searchpatternsize = formathexpattern(pattern, NULL, 0) / 2;
- PatternByte *searchpattern = rtl_calloc(searchpatternsize, sizeof(PatternByte));
+ PatternByte *searchpattern = calloc(searchpatternsize, sizeof(PatternByte));
- unsigned char *result = NULL;
+ size_t result = -1;
if ( patterntransform(pattern, searchpattern, searchpatternsize) )
- result = patternfind3(data, datasize, searchpattern, searchpatternsize);
-
- rtl_free(searchpattern);
+ result = patternfind_pbyte(data, datasize, searchpattern, searchpatternsize);
+
+ free(searchpattern);
return result;
}
-unsigned char *patternfind2(unsigned char *data, size_t datasize, unsigned char *pattern, size_t patternsize)
+__declspec(noinline)
+size_t patternfind_bytes(uint8_t *data, size_t datasize, const uint8_t *pattern, size_t patternsize)
{
if ( patternsize > datasize )
patternsize = datasize;
@@ -119,19 +117,20 @@ unsigned char *patternfind2(unsigned char *data, size_t datasize, unsigned char
if ( data[i] == pattern[pos] ) {
pos++;
if ( pos == patternsize )
- return &data[i - patternsize + 1];
+ return i - patternsize + 1;
} else if ( pos > 0 ) {
i -= pos;
pos = 0; //reset current pattern position
}
}
- return NULL;
+ return -1;
}
-static inline void patternwritebyte(unsigned char *byte, const PatternByte pbyte)
+static inline void patternwritebyte(uint8_t *byte, const PatternByte pbyte)
{
- unsigned char n1 = (*byte >> 4) & 0xF;
- unsigned char n2 = *byte & 0xF;
+ uint8_t n1 = (*byte >> 4) & 0xF;
+ uint8_t n2 = *byte & 0xF;
+
if ( !pbyte.nibble[0].wildcard )
n1 = pbyte.nibble[0].data;
if ( !pbyte.nibble[1].wildcard )
@@ -139,41 +138,44 @@ static inline void patternwritebyte(unsigned char *byte, const PatternByte pbyte
*byte = ((n1 << 4) & 0xF0) | (n2 & 0xF);
}
-void patternwrite(unsigned char *data, size_t datasize, const char *pattern)
+void patternwrite(uint8_t *data, size_t datasize, const char *pattern)
{
size_t writepatternsize = formathexpattern(pattern, NULL, 0) / 2;
- PatternByte *writepattern = rtl_calloc(writepatternsize, sizeof(PatternByte));
+ PatternByte *writepattern = calloc(writepatternsize, sizeof(PatternByte));
if ( patterntransform(pattern, writepattern, writepatternsize) ) {
+ DWORD OldProtect;
+ BOOL result = VirtualProtect(data, writepatternsize, PAGE_READWRITE, &OldProtect);
if ( writepatternsize > datasize )
writepatternsize = datasize;
for ( size_t i = 0; i < writepatternsize; i++ )
patternwritebyte(&data[i], writepattern[i]);
+ result = VirtualProtect(data, writepatternsize, OldProtect, &OldProtect);
}
- rtl_free(writepattern);
+ free(writepattern);
}
-bool patternsnr(unsigned char *data, size_t datasize, const char *searchpattern, const char *replacepattern)
+bool patternsnr(uint8_t *data, size_t datasize, const char *searchpattern, const char *replacepattern)
{
- unsigned char *found = patternfind(data, datasize, searchpattern);
- if ( !found )
+ size_t found = patternfind(data, datasize, searchpattern);
+ if ( found == -1 )
return false;
- patternwrite(found, datasize - (found - data), replacepattern);
+ patternwrite(data + found, found - datasize, replacepattern);
return true;
}
-unsigned char *patternfind3(unsigned char *data, size_t datasize, const PatternByte *pattern, size_t searchpatternsize)
+size_t patternfind_pbyte(uint8_t *data, size_t datasize, const PatternByte *pattern, size_t searchpatternsize)
{
for ( size_t i = 0, pos = 0; i < datasize; i++ ) { //search for the pattern
if ( patternmatchbyte(data[i], pattern[pos]) ) { //check if our pattern matches the current byte
pos++;
if ( pos == searchpatternsize ) //everything matched
- return &data[i - searchpatternsize + 1];
+ return i - searchpatternsize + 1;
} else if ( pos > 0 ) { //fix by Computer_Angel
i -= pos;
pos = 0; //reset current pattern position
}
}
- return NULL;
+ return -1;
}
diff --git a/wufuc/patternfind.h b/wufuc/patternfind.h
index b22613a..d3c5fa4 100644
--- a/wufuc/patternfind.h
+++ b/wufuc/patternfind.h
@@ -1,42 +1,42 @@
#pragma once
-
-#include
+#include
+#include
#include
-typedef struct tagPatternByte
+typedef struct
{
struct PatternNibble
{
- unsigned char data;
+ uint8_t data;
bool wildcard;
} nibble[2];
} PatternByte;
-//returns: pointer to data when found, NULL when not found
-unsigned char *patternfind(
- unsigned char *data, //data
+//returns: offset to data when found, -1 when not found
+size_t patternfind(
+ uint8_t *data, //data
size_t datasize, //size of data
const char *pattern //pattern to search
);
-//returns: pointer to data when found, NULL when not found
-unsigned char *patternfind2(
- unsigned char *data, //data
+//returns: offset to data when found, -1 when not found
+size_t patternfind_bytes(
+ uint8_t *data, //data
size_t datasize, //size of data
- unsigned char *pattern, //bytes to search
+ const uint8_t *pattern, //bytes to search
size_t patternsize //size of bytes to search
);
//returns: nothing
void patternwrite(
- unsigned char *data, //data
+ uint8_t *data, //data
size_t datasize, //size of data
const char *pattern //pattern to write
);
//returns: true on success, false on failure
bool patternsnr(
- unsigned char *data, //data
+ uint8_t *data, //data
size_t datasize, //size of data
const char *searchpattern, //pattern to search
const char *replacepattern //pattern to write
@@ -49,9 +49,9 @@ bool patterntransform(
size_t patternsize //size of pattern
);
-//returns: pointer to data when found, NULL when not found
-unsigned char *patternfind3(
- unsigned char *data, //data
+//returns: offset to data when found, -1 when not found
+size_t patternfind_pbyte(
+ uint8_t *data, //data
size_t datasize, //size of data
const PatternByte *pattern, //pattern to search
size_t searchpatternsize //size of pattern to search
diff --git a/wufuc/rtl_malloc.c b/wufuc/rtl_malloc.c
deleted file mode 100644
index 626c53c..0000000
--- a/wufuc/rtl_malloc.c
+++ /dev/null
@@ -1,70 +0,0 @@
-#include "rtl_malloc.h"
-
-#include
-#include
-
-void *rtl_malloc(size_t size)
-{
- return RtlAllocateHeap(RtlProcessHeap(), 0, size);
-}
-
-void rtl_free(void *memblock)
-{
- RtlFreeHeap(RtlProcessHeap(), 0, memblock);
-}
-
-void *rtl_calloc(size_t num, size_t size)
-{
- return RtlAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, num * size);
-}
-
-void *rtl_realloc(void *memblock, size_t size)
-{
- if ( !memblock )
- return rtl_malloc(size);
-
- if ( !size ) {
- rtl_free(memblock);
- return NULL;
- }
-
- return RtlReAllocateHeap(RtlProcessHeap(), 0, memblock, size);
-}
-
-void *_rtl_recalloc(void *memblock, size_t num, size_t size)
-{
- if ( !memblock )
- return rtl_calloc(num, size);
-
- if ( !num || !size ) {
- rtl_free(memblock);
- return NULL;
- }
-
- return RtlReAllocateHeap(RtlProcessHeap(), HEAP_ZERO_MEMORY, memblock, num * size);
-}
-
-
-void *_rtl_expand(void *memblock, size_t size)
-{
- return RtlReAllocateHeap(RtlProcessHeap(), HEAP_REALLOC_IN_PLACE_ONLY, memblock, size);
-}
-
-size_t _rtl_msize(void *memblock)
-{
- return RtlSizeHeap(RtlProcessHeap(), 0, memblock);
-}
-
-int _rtl_heapchk(void)
-{
- if ( !RtlValidateHeap(RtlProcessHeap(), 0, NULL) )
- return -1;
- return 0;
-}
-
-int _rtl_heapmin(void)
-{
- if ( !RtlCompactHeap(RtlProcessHeap(), 0) )
- return -1;
- return 0;
-}
diff --git a/wufuc/rtl_malloc.h b/wufuc/rtl_malloc.h
deleted file mode 100644
index 1505dac..0000000
--- a/wufuc/rtl_malloc.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-#include
-
-void *rtl_malloc(size_t size);
-
-void rtl_free(void *memblock);
-
-void *rtl_calloc(size_t num, size_t size);
-
-void *rtl_realloc(void *memblock, size_t size);
-
-void *_rtl_recalloc(void *memblock, size_t num, size_t size);
-
-void *_rtl_expand(void *memblock, size_t size);
-
-size_t _rtl_msize(void *memblock);
-
-int _rtl_heapchk(void);
-
-int _rtl_heapmin(void);
diff --git a/wufuc/rundll32.c b/wufuc/rundll32.c
index 845bd63..5670cbe 100644
--- a/wufuc/rundll32.c
+++ b/wufuc/rundll32.c
@@ -1,26 +1,81 @@
-#include
-#include
+#include "stdafx.h"
+#include "callbacks.h"
+#include "helpers.h"
+
+void CALLBACK RUNDLL32_StartW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
+{
+ HANDLE hMutex;
+ HANDLE hEvent;
+ bool Unloading;
+ bool Lagging;
+ SC_HANDLE hSCM;
+ SC_HANDLE hService;
+ SERVICE_NOTIFYW NotifyBuffer;
+
+ if ( !create_exclusive_mutex(L"Global\\{25020063-B5A7-4227-9FDF-25CB75E8C645}", &hMutex) )
+ return;
+
+ if ( !create_event_with_security_descriptor(L"D:(A;;0x001F0003;;;BA)", true, false, L"Global\\wufuc_UnloadEvent", &hEvent) )
+ goto L1;
+
+ Unloading = false;
+ do {
+ Lagging = false;
+ hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
+ if ( !hSCM ) goto L2;
+
+ hService = OpenServiceW(hSCM, L"wuauserv", SERVICE_QUERY_STATUS);
+ if ( !hService ) goto L3;
+
+ ZeroMemory(&NotifyBuffer, sizeof NotifyBuffer);
+ NotifyBuffer.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
+ NotifyBuffer.pfnNotifyCallback = ServiceNotifyCallback;
+ NotifyBuffer.pContext = (PVOID)hEvent;
+ while ( !Unloading && !Lagging ) {
+ switch ( NotifyServiceStatusChangeW(hService,
+ SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING,
+ &NotifyBuffer) ) {
+ case ERROR_SUCCESS:
+ Unloading = WaitForSingleObjectEx(hEvent, INFINITE, TRUE) == WAIT_OBJECT_0;
+ break;
+ case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
+ trace(L"Client lagging!");
+ Lagging = true;
+ break;
+ default:
+ Unloading = true;
+ break;
+ }
+ }
+ CloseServiceHandle(hService);
+L3: CloseServiceHandle(hSCM);
+ } while ( Lagging );
+L2: CloseHandle(hEvent);
+L1: ReleaseMutex(hMutex);
+ CloseHandle(hMutex);
+}
+
+void CALLBACK RUNDLL32_UnloadW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
+{
+ HANDLE event;
+
+ event = OpenEventW(EVENT_MODIFY_STATE, FALSE, L"Global\\wufuc_UnloadEvent");
+ if ( event ) {
+ SetEvent(event);
+ CloseHandle(event);
+ }
+}
void CALLBACK RUNDLL32_DeleteFileW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
{
int argc;
- wchar_t **argv = CommandLineToArgvW(lpszCmdLine, &argc);
+ LPWSTR *argv;
+ argv = CommandLineToArgvW(lpszCmdLine, &argc);
if ( argv ) {
- if ( !DeleteFileW(argv[0])
- && GetLastError() == ERROR_ACCESS_DENIED )
+ if ( !DeleteFileW(argv[0]) && GetLastError() == ERROR_ACCESS_DENIED )
MoveFileExW(argv[0], NULL, MOVEFILE_DELAY_UNTIL_REBOOT);
LocalFree((HLOCAL)argv);
}
-
-}
-
-void CALLBACK RUNDLL32_LegacyUnloadW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
-{
- HANDLE Event = OpenEventW(EVENT_MODIFY_STATE, FALSE, L"Global\\wufuc_UnloadEvent");
- if ( Event ) {
- SetEvent(Event);
- CloseHandle(Event);
- }
}
diff --git a/wufuc/rundll32.h b/wufuc/rundll32.h
new file mode 100644
index 0000000..18f937d
--- /dev/null
+++ b/wufuc/rundll32.h
@@ -0,0 +1,11 @@
+#pragma once
+
+#ifdef UNICODE
+#define RUNDLL32_Start RUNDLL32_StartW
+#define RUNDLL32_Unload RUNDLL32_UnloadW
+#define RUNDLL32_DeleteFile RUNDLL32_DeleteFileW
+#else
+#define RUNDLL32_Start RUNDLL32_StartA
+#define RUNDLL32_Unload RUNDLL32_UnloadA
+#define RUNDLL32_DeleteFile RUNDLL32_DeleteFileA
+#endif // !UNICODE
diff --git a/wufuc/stdafx.c b/wufuc/stdafx.c
new file mode 100644
index 0000000..1ac636b
--- /dev/null
+++ b/wufuc/stdafx.c
@@ -0,0 +1,7 @@
+// stdafx.c : source file that includes just the standard includes
+// stdafx.obj will contain the pre-compiled type information
+
+#include "stdafx.h"
+
+// TODO: reference any additional headers you need in STDAFX.H
+// and not in this file
diff --git a/wufuc/stdafx.h b/wufuc/stdafx.h
new file mode 100644
index 0000000..9afbd93
--- /dev/null
+++ b/wufuc/stdafx.h
@@ -0,0 +1,17 @@
+#pragma once
+#include "targetver.h"
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "tracing.h"
+
+extern IMAGE_DOS_HEADER __ImageBase;
+#define PIMAGEBASE ((HMODULE)&__ImageBase)
diff --git a/wufuc/targetver.h b/wufuc/targetver.h
new file mode 100644
index 0000000..fc708e3
--- /dev/null
+++ b/wufuc/targetver.h
@@ -0,0 +1,9 @@
+#pragma once
+
+// Including SDKDDKVer.h defines the highest available Windows platform.
+
+// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and
+// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h.
+
+#define _WIN32_WINNT _WIN32_WINNT_WIN7
+#include
diff --git a/wufuc/tracing.c b/wufuc/tracing.c
index 0fdac19..f174b49 100644
--- a/wufuc/tracing.c
+++ b/wufuc/tracing.c
@@ -1,63 +1,14 @@
+#include "stdafx.h"
#include "tracing.h"
-#include "helpers.h"
-#include "rtl_malloc.h"
-
-#include
-#include
-#include
-
-#include
-#include
-
-void trace_sysinfo(void)
-{
- RTL_OSVERSIONINFOW osvi = { 0 };
- osvi.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOW);
- NTSTATUS status = RtlGetVersion(&osvi);
- if ( NT_SUCCESS(status) ) {
- trace(L"Windows version: %d.%d.%d (%Iu-bit)",
- osvi.dwMajorVersion,
- osvi.dwMinorVersion,
- osvi.dwBuildNumber,
- sizeof(uintptr_t) * 8);
- } else trace(L"Failed to get Windows version (status=%08X)", status);
-
- int CPUInfo[4];
- __cpuidex(CPUInfo, 0x80000000, 0);
- if ( CPUInfo[0] < 0x80000004 ) {
- trace(L"This processor does not support the brand identification feature.");
- return;
- }
- char brand[0x31];
- uint32_t *u32ptr = (uint32_t *)&brand;
- for ( int func = 0x80000002; func <= 0x80000004; func++ ) {
- __cpuidex(CPUInfo, func, 0);
- for ( int i = 0; i < 4; i++ )
- *(u32ptr++) = CPUInfo[i];
- }
- size_t c = 0;
- do {
- if ( !isspace(brand[c]) )
- break;
- c++;
- } while ( c < _countof(brand) );
- trace(L"Processor: %hs", &brand[c]);
-}
-
void trace_(const wchar_t *const format, ...)
{
- static int shown_sysinfo = 0;
- if ( !shown_sysinfo ) {
- shown_sysinfo = 1;
- trace_sysinfo();
- }
va_list argptr;
va_start(argptr, format);
int count = _vscwprintf(format, argptr) + 1;
- wchar_t *buffer = rtl_calloc(count, sizeof(wchar_t));
+ wchar_t *buffer = calloc(count, sizeof(wchar_t));
vswprintf_s(buffer, count, format, argptr);
va_end(argptr);
OutputDebugStringW(buffer);
- rtl_free(buffer);
+ free(buffer);
}
diff --git a/wufuc/wufuc.rch b/wufuc/wufuc.rch
index 0ae9794..48ba6c2 100644
--- a/wufuc/wufuc.rch
+++ b/wufuc/wufuc.rch
@@ -2,10 +2,10 @@
#define WUFUC_RCH_INCLUDED
#pragma once
#ifndef BUILD_COMMIT_VERSION
-#define BUILD_COMMIT_VERSION 0.8.0.0
+#define BUILD_COMMIT_VERSION 1.0.0.0
#endif
#ifndef BUILD_VERSION_COMMA
-#define BUILD_VERSION_COMMA 0,8,0,0
+#define BUILD_VERSION_COMMA 1,0,0,0
#endif
#define STRINGIZE_(x) #x
#define STRINGIZE(x) STRINGIZE_(x)
diff --git a/wufuc/wufuc.vcxproj b/wufuc/wufuc.vcxproj
index 87e8e8e..e87bb99 100644
--- a/wufuc/wufuc.vcxproj
+++ b/wufuc/wufuc.vcxproj
@@ -19,11 +19,11 @@
-
-
-
+
+
+
@@ -31,9 +31,14 @@
-
-
+
+ Create
+ Create
+ Create
+ Create
+
+
@@ -53,7 +58,7 @@
{00F96695-CE41-4C2F-A344-6219DFB4F887}
Win32Proj
wufuc
- 10.0.15063.0
+ 10.0.16299.0
@@ -106,7 +111,8 @@
$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\
$(ProjectName)$(PlatformArchitecture)
false
- $(SolutionDir)phnt\include;$(IncludePath)
+ $(SolutionDir)inc\phnt;$(SolutionDir)inc\detours;$(IncludePath)
+ $(SolutionDir)lib\detours;$(LibraryPath)
true
@@ -114,7 +120,8 @@
$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\
$(ProjectName)$(PlatformArchitecture)
false
- $(SolutionDir)phnt\include;$(IncludePath)
+ $(SolutionDir)inc\phnt;$(SolutionDir)inc\detours;$(IncludePath)
+ $(SolutionDir)lib\detours;$(LibraryPath)
false
@@ -122,7 +129,8 @@
$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\
$(ProjectName)$(PlatformArchitecture)
false
- $(SolutionDir)phnt\include;$(IncludePath)
+ $(SolutionDir)inc\phnt;$(SolutionDir)inc\detours;$(IncludePath)
+ $(SolutionDir)lib\detours;$(LibraryPath)
false
@@ -130,26 +138,27 @@
$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\
$(ProjectName)$(PlatformArchitecture)
false
- $(SolutionDir)phnt\include;$(IncludePath)
+ $(SolutionDir)inc\phnt;$(SolutionDir)inc\detours;$(IncludePath)
+ $(SolutionDir)lib\detours;$(LibraryPath)
Level3
Disabled
- WIN32;_DEBUG;_WINDOWS;_USRDLL;WUFUC_EXPORTS;_NO_CRT_STDIO_INLINE;%(PreprocessorDefinitions)
+ WIN32;_DEBUG;WUFUC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
CompileAsC
- false
+ true
+ Use
+ MultiThreadedDebug
+ ProgramDatabase
Windows
exports.def
- DllMain
- ntdll.lib;ntdllp.lib;version.lib;%(AdditionalDependencies)
-
-
- true
+
+
+ ntdll.lib;version.lib;detours.X86.MTd.lib;%(AdditionalDependencies)
-
X86;%(PreprocessorDefinitions)
@@ -158,20 +167,20 @@
Level3
Disabled
- _DEBUG;_WINDOWS;_USRDLL;WUFUC_EXPORTS;_NO_CRT_STDIO_INLINE;%(PreprocessorDefinitions)
+ _DEBUG;WUFUC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
CompileAsC
- false
+ true
+ Use
+ MultiThreadedDebug
+ ProgramDatabase
Windows
- ntdll.lib;ntdllp.lib;version.lib;%(AdditionalDependencies)
exports.def
- DllMain
-
-
- true
+
+
+ ntdll.lib;version.lib;detours.X64.MTd.lib;%(AdditionalDependencies)
-
X64;%(PreprocessorDefinitions)
@@ -182,10 +191,12 @@
Full
true
true
- WIN32;NDEBUG;_WINDOWS;_USRDLL;WUFUC_EXPORTS;_NO_CRT_STDIO_INLINE;%(PreprocessorDefinitions)
+ WIN32;NDEBUG;WUFUC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
CompileAsC
- Size
- false
+ true
+ Use
+ MultiThreaded
+ None
BUILD_COMMIT_VERSION=$(BUILD_COMMIT_VERSION);BUILD_VERSION_COMMA=$(BUILD_VERSION_COMMA);$(PreprocessorDefinitions)
@@ -196,17 +207,11 @@
true
false
exports.def
- DllMain
- ntdll.lib;ntdllp.lib;version.lib;%(AdditionalDependencies)
-
-
- true
+
+
+ ntdll.lib;version.lib;detours.X86.MT.lib;%(AdditionalDependencies)
+ true
-
-
-
-
-
X86;%(PreprocessorDefinitions)
@@ -214,13 +219,15 @@
Level3
- Full
+ MaxSpeed
true
true
- NDEBUG;_WINDOWS;_USRDLL;WUFUC_EXPORTS;_NO_CRT_STDIO_INLINE;%(PreprocessorDefinitions)
+ NDEBUG;WUFUC_EXPORTS;_WINDOWS;_USRDLL;%(PreprocessorDefinitions)
CompileAsC
- Size
- false
+ Use
+ true
+ MultiThreaded
+ None
BUILD_COMMIT_VERSION=$(BUILD_COMMIT_VERSION);BUILD_VERSION_COMMA=$(BUILD_VERSION_COMMA);$(PreprocessorDefinitions)
@@ -230,18 +237,10 @@
true
true
false
- ntdll.lib;ntdllp.lib;version.lib;%(AdditionalDependencies)
exports.def
- DllMain
-
-
- true
+ ntdll.lib;version.lib;detours.X64.MT.lib;%(AdditionalDependencies)
+ true
-
-
-
-
-
X64;%(PreprocessorDefinitions)
diff --git a/wufuc/wufuc.vcxproj.filters b/wufuc/wufuc.vcxproj.filters
index 0f24ba8..51237b9 100644
--- a/wufuc/wufuc.vcxproj.filters
+++ b/wufuc/wufuc.vcxproj.filters
@@ -24,19 +24,19 @@
Header Files
-
- Header Files
-
Header Files
Header Files
-
+
Header Files
-
+
+ Header Files
+
+
Header Files
@@ -53,19 +53,19 @@
Source Files
-
- Source Files
-
Source Files
Source Files
-
+
Source Files
-
+
+ Source Files
+
+
Source Files
diff --git a/wufuc_setup/wufuc_setup.aip b/wufuc_setup/wufuc_setup.aip
index 6855e15..19b268c 100644
--- a/wufuc_setup/wufuc_setup.aip
+++ b/wufuc_setup/wufuc_setup.aip
@@ -1,5 +1,5 @@
-
+
@@ -8,7 +8,7 @@
-
+
diff --git a/wufuc_setup/wufuc_setup.aiproj b/wufuc_setup/wufuc_setup.aiproj
index 5c86eac..0cb30c6 100644
--- a/wufuc_setup/wufuc_setup.aiproj
+++ b/wufuc_setup/wufuc_setup.aiproj
@@ -22,5 +22,6 @@
Code
-
+
+
\ No newline at end of file