Compare commits
15 Commits
v1.0.0.191
...
micro
Author | SHA1 | Date | |
---|---|---|---|
![]() |
1f57b17357 | ||
![]() |
7cee1998b1 | ||
![]() |
6effa574f8 | ||
![]() |
a52637d493 | ||
![]() |
5d20496f3a | ||
![]() |
cd5077ce82 | ||
![]() |
cc0428159f | ||
![]() |
e6da8ec18b | ||
![]() |
35760a2546 | ||
![]() |
a8adfa3c08 | ||
![]() |
c7e94426a8 | ||
![]() |
220b2eeaff | ||
![]() |
c2069e3c69 | ||
![]() |
0523eb1b7b | ||
![]() |
8ccdd2a50b |
2
.github/ISSUE_TEMPLATE.md
vendored
2
.github/ISSUE_TEMPLATE.md
vendored
@@ -6,7 +6,7 @@ Then, make sure the following things are included in your issue:
|
|||||||
- Operating system version and Service Pack (including 32- or 64-bit).
|
- Operating system version and Service Pack (including 32- or 64-bit).
|
||||||
- Short description of the issue.
|
- Short description of the issue.
|
||||||
- Elaborate steps to reproduce the bug/issue being reported.
|
- Elaborate steps to reproduce the bug/issue being reported.
|
||||||
- Attach wufuc's log file (located at `C:\ProgramData\wufuc\wufuc.log`).
|
- Attach wufuc's log file (located at `C:\ProgramData\wufuc\wufuc.1.log`).
|
||||||
- Any supporting information that could help solve/understand the issue.
|
- Any supporting information that could help solve/understand the issue.
|
||||||
|
|
||||||
Any issues that do not include these, or go more than a week without a
|
Any issues that do not include these, or go more than a week without a
|
||||||
|
35
DONATE.md
35
DONATE.md
@@ -1,14 +1,33 @@
|
|||||||
# Help support the development of wufuc
|
# Donations
|
||||||
|
|
||||||
Thanks for showing an interest in donating!
|
> ## Why I'm asking for your support
|
||||||
|
>
|
||||||
|
> Although wufuc's code is relatively small, its reach has become quite large, having many users all across the world. Making it work smoothly in all kinds of different computing environments, from being installed by casual users to being deployed across large enterprise-scale domains, has turned out to be a very time-consuming task.
|
||||||
|
>
|
||||||
|
> ### A little backstory
|
||||||
|
>
|
||||||
|
> When I wrote the first iteration of wufuc (then known as [kb4012218-19](https://github.com/zeffy/wufuc/tree/old-kb4012218-19)) and published it on GitHub, I originally had intended for it to simply be a proof-of-concept that others could learn from. I had no way of anticipating that around April 18, 2017, several high-profile tech and gaming news websites would publish dozens of articles about my project, sending huge amounts of traffic to it.
|
||||||
|
>
|
||||||
|
> ### Many sleepless nights later
|
||||||
|
>
|
||||||
|
> It has now been over a year since I began this project, and since then it has undergone several major iterations. Thanks to the many hours I have spent doing research, writing and improving its code, I have learned a great deal that I likely would not have otherwise.
|
||||||
|
>
|
||||||
|
> ### There is still reality to contend with
|
||||||
|
>
|
||||||
|
> I glean no direct monetary benefit from this project, other than the contributions from generous users like you. If you're willing and able to, your support would be immensely appreciated. Contributions would be going towards my living expenses, computer upkeep, etc., so that I can spend more time doing what I love to do: making useful, free software for people like you.
|
||||||
|
>
|
||||||
|
> Thanks for your time and consideration! Have a great day.
|
||||||
|
>
|
||||||
|
> ---
|
||||||
|
>
|
||||||
|
> _Note: Please keep in mind that donations, etc. should be considered gifts towards my past development efforts, and not made with the assumption of continued support._
|
||||||
|
|
||||||
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).
|
## Donation options
|
||||||
|
|
||||||
## Donate Bitcoin
|
- [**Liberapay**](https://liberapay.com/zeffy) (Recurring payments, but can cancel any time. Accepts USD and EUR.)
|
||||||
|
|
||||||
- [**Donate Bitcoin on Mycelium Gear**](https://admin.gear.mycelium.com/gateways/3554/orders/new)
|
- [**Mycelium Gear**](https://admin.gear.mycelium.com/gateways/3554/orders/new) (One-off payments. Only accepts Bitcoin.)
|
||||||
|
|
||||||
## Other donation options
|
### Suggestions
|
||||||
|
|
||||||
Currently I'm only accepting Bitcoin, but I'm open to adding other ways of donating.
|
Know of a good donation platform? Let me know about it by [creating an issue](https://github.com/zeffy/wufuc/issues/new), and I will look into it.
|
||||||
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.
|
|
||||||
|
9
FAQ.md
9
FAQ.md
@@ -15,17 +15,12 @@ These must be used from an elevated command line prompt.
|
|||||||
|
|
||||||
## How to restore Windows Update to its default configuration
|
## How to restore Windows Update to its default configuration
|
||||||
|
|
||||||
Windows Update by default is configured to run as `SERVICE_WIN32_SHARE_PROCESS`, which means it shares a single `svchost.exe` process with several other Windows services.
|
If you have used another third-party solution for the CPU fix (such as UpdatePack7R2 or WuaCpuFix) either knowingly or unknowingly, wufuc may not function correctly.
|
||||||
It can also be configured as `SERVICE_WIN32_OWN_PROCESS`, which means it runs in its own process, which doesn't start until Windows Update does.
|
|
||||||
|
|
||||||
Normally, either of these configurations is supported.
|
|
||||||
|
|
||||||
However, if you have used another third-party solution for the CPU fix (such as UpdatePack7R2 or WuaCpuFix) either knowingly or unknowingly, wufuc will not function correctly if Windows Update is configured as `SERVICE_WIN32_OWN_PROCESS`.
|
|
||||||
|
|
||||||
You have two ways to work around this limitation, either:
|
You have two ways to work around this limitation, either:
|
||||||
|
|
||||||
- You can remove the other third-party solution yourself.
|
- You can remove the other third-party solution yourself.
|
||||||
- Alternatively, go to the directory that you installed wufuc to, open the `Troubleshooting` subdirectory, and merge the `Restore_wuauserv.reg` file with your registry by double-clicking it, and then restart your PC.
|
- Alternatively, go to the directory that you installed wufuc to, and merge the `Restore_wuauserv.reg` file with your registry by double-clicking it, and then restart your PC.
|
||||||
|
|
||||||
## How to manually remove wufuc v0.8.0.143 when it is impossible to uninstall it normally
|
## How to manually remove wufuc v0.8.0.143 when it is impossible to uninstall it normally
|
||||||
|
|
||||||
|
42
README.md
42
README.md
@@ -1,4 +1,5 @@
|
|||||||
# wufuc
|
# wufuc
|
||||||
|
[](https://liberapay.com/zeffy)
|
||||||
[](https://admin.gear.mycelium.com/gateways/3554/orders/new)
|
[](https://admin.gear.mycelium.com/gateways/3554/orders/new)
|
||||||
[][AppVeyor]
|
[][AppVeyor]
|
||||||
[][Latest]
|
[][Latest]
|
||||||
@@ -16,7 +17,7 @@ Disables the "Unsupported Hardware" message in Windows Update, and allows you to
|
|||||||
|
|
||||||
## Donate :heart:
|
## Donate :heart:
|
||||||
|
|
||||||
[**Click here for donation options!**](https://github.com/zeffy/wufuc/blob/master/DONATE.md)
|
[**Click here for donation options!**](https://github.com/zeffy/wufuc/blob/micro/DONATE.md)
|
||||||
|
|
||||||
## Background
|
## Background
|
||||||
|
|
||||||
@@ -41,13 +42,6 @@ Some people with older Intel and AMD processors are also affected! I've received
|
|||||||
- [AMD FX-8350](https://github.com/zeffy/wufuc/issues/32)
|
- [AMD FX-8350](https://github.com/zeffy/wufuc/issues/32)
|
||||||
- [AMD Turion 64 Mobile Technology ML-34](https://github.com/zeffy/wufuc/issues/80)
|
- [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](https://github.com/zeffy/wufuc/tree/old-kb4012218-19).
|
|
||||||
|
|
||||||
The tl;dr version is basically, inside a system file named `wuaueng.dll`, there are two functions responsible for the CPU check: `IsDeviceServiceable(void)` and `IsCPUSupported(void)`.
|
|
||||||
`IsDeviceServiceable` simply calls `IsCPUSupported` once, and then re-uses the result that it receives on subsequent calls.
|
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
- Enables Windows Update on PCs with unsupported processors.
|
- Enables Windows Update on PCs with unsupported processors.
|
||||||
@@ -57,34 +51,36 @@ The tl;dr version is basically, inside a system file named `wuaueng.dll`, there
|
|||||||
- Byte pattern-based patching, which means it will usually keep working even after new updates come out.
|
- Byte pattern-based patching, which means it will usually keep working even after new updates come out.
|
||||||
- No dependencies.
|
- No dependencies.
|
||||||
|
|
||||||
## Frequently Asked Questions
|
## How wufuc works
|
||||||
|
|
||||||
See [FAQ.md](https://github.com/zeffy/wufuc/blob/master/FAQ.md).
|
The tl;dr version is basically:
|
||||||
|
|
||||||
## How it works
|
* Inside a system file called `wuaueng.dll`, there are two functions responsible for the CPU check: `IsDeviceServiceable` and `IsCPUSupported`.
|
||||||
|
* `IsDeviceServiceable` simply calls `IsCPUSupported` once, and then saves the result and re-uses it on subsequent calls.
|
||||||
|
* I take advantage of this behavior in wufuc by patching the saved result so that it is always `TRUE`, or supported.
|
||||||
|
|
||||||
This is a basic run-down of what wufuc does when you install it:
|
If you would like more information, you can read my original write-up on discovering the CPU check [here](https://github.com/zeffy/wufuc/tree/old-kb4012218-19).
|
||||||
|
|
||||||
- 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:
|
## Building
|
||||||
* **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.
|
To build wufuc from source, you need to download and install the following:
|
||||||
- Once injected, wufuc will hook some functions where appropriate:
|
|
||||||
* `LoadLibraryExW` hook will automatically hook the `IsDeviceServiceable()` function inside `wuaueng.dll` when it is loaded.
|
1. [Visual Studio 2017](https://www.visualstudio.com/).
|
||||||
* `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.
|
2. [Windows Driver Kit (WDK)](https://docs.microsoft.com/en-us/windows-hardware/drivers/download-the-wdk).
|
||||||
|
3. (Optional, for MSI packages) [Advanced Installer](https://www.advancedinstaller.com/).
|
||||||
|
|
||||||
## Sponsors
|
## Sponsors
|
||||||
|
|
||||||
### [Advanced Installer](https://www.advancedinstaller.com/)
|
### [Advanced Installer](https://www.advancedinstaller.com/)
|
||||||
|
|
||||||
The installer packages are created with Advanced Installer using an [open source license](http://www.advancedinstaller.com/free-license.html).
|
The installer packages are created with Advanced Installer using an [open source license](https://www.advancedinstaller.com/free-license.html).
|
||||||
Advanced Installer's intuitive and friendly user interface allowed me to quickly create a feature complete installer with minimal effort. Check it out!
|
Advanced Installer's intuitive and friendly user interface allowed me to quickly create a feature complete installer with minimal effort. Check it out!
|
||||||
|
|
||||||
## Special thanks
|
## Special thanks
|
||||||
|
|
||||||
- Wen Jia Liu ([@wj32](https://github.com/wj32)) for his awesome program [Process Hacker](https://github.com/processhacker2/processhacker), and also for his [phnt headers](https://github.com/processhacker2/processhacker/tree/master/phnt).
|
- [**wj32**](https://github.com/wj32) for his awesome program [Process Hacker](https://github.com/processhacker2/processhacker), and also for his [phnt headers](https://github.com/processhacker2/processhacker/tree/master/phnt).
|
||||||
- Duncan Ogilvie ([@mrexodia](https://github.com/mrexodia)) for [x64dbg](https://github.com/x64dbg/x64dbg), its [`patternfind.cpp`](https://github.com/x64dbg/x64dbg/blob/development/src/dbg/patternfind.cpp) algorithm, and its issue template which I adapted for this project.
|
- [**mrexodia**](https://github.com/mrexodia) for [x64dbg](https://github.com/x64dbg/x64dbg), its [`patternfind.cpp`](https://github.com/x64dbg/x64dbg/blob/development/src/dbg/patternfind.cpp) algorithm, and its issue template which I adapted for this project.
|
||||||
- Tsuda Kageyu ([@TsudaKageyu](https://github.com/TsudaKageyu)) for his excellent [minhook](https://github.com/TsudaKageyu/minhook) library.
|
|
||||||
|
|
||||||
[Latest]: https://github.com/zeffy/wufuc/releases/latest
|
[Latest]: https://github.com/zeffy/wufuc/releases/latest
|
||||||
[AppVeyor]: https://ci.appveyor.com/project/zeffy/wufuc
|
[AppVeyor]: https://ci.appveyor.com/project/zeffy/wufuc
|
||||||
|
12
appveyor.yml
12
appveyor.yml
@@ -1,7 +1,7 @@
|
|||||||
version: 1.0.0.{build}
|
version: 1.0.1.{build}
|
||||||
branches:
|
branches:
|
||||||
only:
|
only:
|
||||||
- master
|
- micro
|
||||||
skip_commits:
|
skip_commits:
|
||||||
files:
|
files:
|
||||||
- '**/*.md'
|
- '**/*.md'
|
||||||
@@ -22,9 +22,9 @@ before_build:
|
|||||||
set "BUILD_ZIPFILE=%APPVEYOR_BUILD_FOLDER%\%APPVEYOR_PROJECT_NAME%_v%BUILD_COMMIT_VERSION%-%PLATFORM%.zip"
|
set "BUILD_ZIPFILE=%APPVEYOR_BUILD_FOLDER%\%APPVEYOR_PROJECT_NAME%_v%BUILD_COMMIT_VERSION%-%PLATFORM%.zip"
|
||||||
after_build:
|
after_build:
|
||||||
- cmd: >-
|
- cmd: >-
|
||||||
copy /Y "COPYING" "src\wufuc_setup_bat\COPYING.txt"
|
copy /Y "COPYING" "src\setup_bat\COPYING.txt"
|
||||||
|
|
||||||
cd "%APPVEYOR_BUILD_FOLDER%\src\wufuc_setup_bat"
|
cd "%APPVEYOR_BUILD_FOLDER%\src\setup_bat"
|
||||||
|
|
||||||
echo v%BUILD_COMMIT_VERSION%>version.txt
|
echo v%BUILD_COMMIT_VERSION%>version.txt
|
||||||
|
|
||||||
@@ -32,9 +32,9 @@ after_build:
|
|||||||
|
|
||||||
for /R %%i in (*.bat) do unix2dos "%%i"
|
for /R %%i in (*.bat) do unix2dos "%%i"
|
||||||
|
|
||||||
7z a "%BUILD_ZIPFILE%" "..\wufuc_setup_bat"
|
7z a "%BUILD_ZIPFILE%" "..\setup_bat"
|
||||||
|
|
||||||
7z rn "%BUILD_ZIPFILE%" "wufuc_setup_bat" "%APPVEYOR_PROJECT_NAME%"
|
7z rn "%BUILD_ZIPFILE%" "setup_bat" "%APPVEYOR_PROJECT_NAME%"
|
||||||
|
|
||||||
7z d "%BUILD_ZIPFILE%" "%APPVEYOR_PROJECT_NAME%\.gitignore"
|
7z d "%BUILD_ZIPFILE%" "%APPVEYOR_PROJECT_NAME%\.gitignore"
|
||||||
artifacts:
|
artifacts:
|
||||||
|
@@ -1,184 +0,0 @@
|
|||||||
/*
|
|
||||||
* MinHook - The Minimalistic API Hooking Library for x64/x86
|
|
||||||
* Copyright (C) 2009-2017 Tsuda Kageyu.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
*
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
|
||||||
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
|
|
||||||
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
|
||||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
|
||||||
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
|
||||||
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
|
||||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
||||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#if !(defined _M_IX86) && !(defined _M_X64) && !(defined __i386__) && !(defined __x86_64__)
|
|
||||||
#error MinHook supports only x86 and x64 systems.
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// MinHook Error Codes.
|
|
||||||
typedef enum MH_STATUS
|
|
||||||
{
|
|
||||||
// Unknown error. Should not be returned.
|
|
||||||
MH_UNKNOWN = -1,
|
|
||||||
|
|
||||||
// Successful.
|
|
||||||
MH_OK = 0,
|
|
||||||
|
|
||||||
// MinHook is already initialized.
|
|
||||||
MH_ERROR_ALREADY_INITIALIZED,
|
|
||||||
|
|
||||||
// MinHook is not initialized yet, or already uninitialized.
|
|
||||||
MH_ERROR_NOT_INITIALIZED,
|
|
||||||
|
|
||||||
// The hook for the specified target function is already created.
|
|
||||||
MH_ERROR_ALREADY_CREATED,
|
|
||||||
|
|
||||||
// The hook for the specified target function is not created yet.
|
|
||||||
MH_ERROR_NOT_CREATED,
|
|
||||||
|
|
||||||
// The hook for the specified target function is already enabled.
|
|
||||||
MH_ERROR_ENABLED,
|
|
||||||
|
|
||||||
// The hook for the specified target function is not enabled yet, or already
|
|
||||||
// disabled.
|
|
||||||
MH_ERROR_DISABLED,
|
|
||||||
|
|
||||||
// The specified pointer is invalid. It points the address of non-allocated
|
|
||||||
// and/or non-executable region.
|
|
||||||
MH_ERROR_NOT_EXECUTABLE,
|
|
||||||
|
|
||||||
// The specified target function cannot be hooked.
|
|
||||||
MH_ERROR_UNSUPPORTED_FUNCTION,
|
|
||||||
|
|
||||||
// Failed to allocate memory.
|
|
||||||
MH_ERROR_MEMORY_ALLOC,
|
|
||||||
|
|
||||||
// Failed to change the memory protection.
|
|
||||||
MH_ERROR_MEMORY_PROTECT,
|
|
||||||
|
|
||||||
// The specified module is not loaded.
|
|
||||||
MH_ERROR_MODULE_NOT_FOUND,
|
|
||||||
|
|
||||||
// The specified function is not found.
|
|
||||||
MH_ERROR_FUNCTION_NOT_FOUND
|
|
||||||
}
|
|
||||||
MH_STATUS;
|
|
||||||
|
|
||||||
// Can be passed as a parameter to MH_EnableHook, MH_DisableHook,
|
|
||||||
// MH_QueueEnableHook or MH_QueueDisableHook.
|
|
||||||
#define MH_ALL_HOOKS NULL
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Initialize the MinHook library. You must call this function EXACTLY ONCE
|
|
||||||
// at the beginning of your program.
|
|
||||||
MH_STATUS WINAPI MH_Initialize(VOID);
|
|
||||||
|
|
||||||
// Uninitialize the MinHook library. You must call this function EXACTLY
|
|
||||||
// ONCE at the end of your program.
|
|
||||||
MH_STATUS WINAPI MH_Uninitialize(VOID);
|
|
||||||
|
|
||||||
// Creates a Hook for the specified target function, in disabled state.
|
|
||||||
// Parameters:
|
|
||||||
// pTarget [in] A pointer to the target function, which will be
|
|
||||||
// overridden by the detour function.
|
|
||||||
// pDetour [in] A pointer to the detour function, which will override
|
|
||||||
// the target function.
|
|
||||||
// ppOriginal [out] A pointer to the trampoline function, which will be
|
|
||||||
// used to call the original target function.
|
|
||||||
// This parameter can be NULL.
|
|
||||||
MH_STATUS WINAPI MH_CreateHook(LPVOID pTarget, LPVOID pDetour, LPVOID *ppOriginal);
|
|
||||||
|
|
||||||
// Creates a Hook for the specified API function, in disabled state.
|
|
||||||
// Parameters:
|
|
||||||
// pszModule [in] A pointer to the loaded module name which contains the
|
|
||||||
// target function.
|
|
||||||
// pszTarget [in] A pointer to the target function name, which will be
|
|
||||||
// overridden by the detour function.
|
|
||||||
// pDetour [in] A pointer to the detour function, which will override
|
|
||||||
// the target function.
|
|
||||||
// ppOriginal [out] A pointer to the trampoline function, which will be
|
|
||||||
// used to call the original target function.
|
|
||||||
// This parameter can be NULL.
|
|
||||||
MH_STATUS WINAPI MH_CreateHookApi(
|
|
||||||
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal);
|
|
||||||
|
|
||||||
// Creates a Hook for the specified API function, in disabled state.
|
|
||||||
// Parameters:
|
|
||||||
// pszModule [in] A pointer to the loaded module name which contains the
|
|
||||||
// target function.
|
|
||||||
// pszTarget [in] A pointer to the target function name, which will be
|
|
||||||
// overridden by the detour function.
|
|
||||||
// pDetour [in] A pointer to the detour function, which will override
|
|
||||||
// the target function.
|
|
||||||
// ppOriginal [out] A pointer to the trampoline function, which will be
|
|
||||||
// used to call the original target function.
|
|
||||||
// This parameter can be NULL.
|
|
||||||
// ppTarget [out] A pointer to the target function, which will be used
|
|
||||||
// with other functions.
|
|
||||||
// This parameter can be NULL.
|
|
||||||
MH_STATUS WINAPI MH_CreateHookApiEx(
|
|
||||||
LPCWSTR pszModule, LPCSTR pszProcName, LPVOID pDetour, LPVOID *ppOriginal, LPVOID *ppTarget);
|
|
||||||
|
|
||||||
// Removes an already created hook.
|
|
||||||
// Parameters:
|
|
||||||
// pTarget [in] A pointer to the target function.
|
|
||||||
MH_STATUS WINAPI MH_RemoveHook(LPVOID pTarget);
|
|
||||||
|
|
||||||
// Enables an already created hook.
|
|
||||||
// Parameters:
|
|
||||||
// pTarget [in] A pointer to the target function.
|
|
||||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
|
||||||
// enabled in one go.
|
|
||||||
MH_STATUS WINAPI MH_EnableHook(LPVOID pTarget);
|
|
||||||
|
|
||||||
// Disables an already created hook.
|
|
||||||
// Parameters:
|
|
||||||
// pTarget [in] A pointer to the target function.
|
|
||||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
|
||||||
// disabled in one go.
|
|
||||||
MH_STATUS WINAPI MH_DisableHook(LPVOID pTarget);
|
|
||||||
|
|
||||||
// Queues to enable an already created hook.
|
|
||||||
// Parameters:
|
|
||||||
// pTarget [in] A pointer to the target function.
|
|
||||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
|
||||||
// queued to be enabled.
|
|
||||||
MH_STATUS WINAPI MH_QueueEnableHook(LPVOID pTarget);
|
|
||||||
|
|
||||||
// Queues to disable an already created hook.
|
|
||||||
// Parameters:
|
|
||||||
// pTarget [in] A pointer to the target function.
|
|
||||||
// If this parameter is MH_ALL_HOOKS, all created hooks are
|
|
||||||
// queued to be disabled.
|
|
||||||
MH_STATUS WINAPI MH_QueueDisableHook(LPVOID pTarget);
|
|
||||||
|
|
||||||
// Applies all queued changes in one go.
|
|
||||||
MH_STATUS WINAPI MH_ApplyQueued(VOID);
|
|
||||||
|
|
||||||
// Translates the MH_STATUS to its name as a string.
|
|
||||||
const char * WINAPI MH_StatusToString(MH_STATUS status);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
@@ -107,7 +107,8 @@ typedef struct _DBGUI_WAIT_STATE_CHANGE
|
|||||||
|
|
||||||
typedef enum _DEBUGOBJECTINFOCLASS
|
typedef enum _DEBUGOBJECTINFOCLASS
|
||||||
{
|
{
|
||||||
DebugObjectFlags = 1,
|
DebugObjectUnusedInformation,
|
||||||
|
DebugObjectKillProcessOnExitInformation,
|
||||||
MaxDebugObjectInfoClass
|
MaxDebugObjectInfoClass
|
||||||
} DEBUGOBJECTINFOCLASS, *PDEBUGOBJECTINFOCLASS;
|
} DEBUGOBJECTINFOCLASS, *PDEBUGOBJECTINFOCLASS;
|
||||||
|
|
||||||
|
@@ -1394,13 +1394,13 @@ typedef enum _SYSTEM_INFORMATION_CLASS
|
|||||||
SystemSecureDumpEncryptionInformation,
|
SystemSecureDumpEncryptionInformation,
|
||||||
SystemWriteConstraintInformation, // SYSTEM_WRITE_CONSTRAINT_INFORMATION
|
SystemWriteConstraintInformation, // SYSTEM_WRITE_CONSTRAINT_INFORMATION
|
||||||
SystemKernelVaShadowInformation, // SYSTEM_KERNEL_VA_SHADOW_INFORMATION
|
SystemKernelVaShadowInformation, // SYSTEM_KERNEL_VA_SHADOW_INFORMATION
|
||||||
SystemHypervisorSharedPageInformation, // REDSTONE4
|
SystemHypervisorSharedPageInformation, // SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION // since REDSTONE4
|
||||||
SystemFirmwareBootPerformanceInformation,
|
SystemFirmwareBootPerformanceInformation,
|
||||||
SystemCodeIntegrityVerificationInformation,
|
SystemCodeIntegrityVerificationInformation, // SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION
|
||||||
SystemFirmwarePartitionInformation, // 200
|
SystemFirmwarePartitionInformation, // 200
|
||||||
SystemSpeculationControlInformation, // SYSTEM_SPECULATION_CONTROL_INFORMATION // (CVE-2017-5715) REDSTONE3 and above.
|
SystemSpeculationControlInformation, // SYSTEM_SPECULATION_CONTROL_INFORMATION // (CVE-2017-5715) REDSTONE3 and above.
|
||||||
SystemDmaGuardPolicyInformation,
|
SystemDmaGuardPolicyInformation, // SYSTEM_DMA_GUARD_POLICY_INFORMATION
|
||||||
SystemEnclaveLaunchControlInformation,
|
SystemEnclaveLaunchControlInformation, // SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION
|
||||||
MaxSystemInfoClass
|
MaxSystemInfoClass
|
||||||
} SYSTEM_INFORMATION_CLASS;
|
} SYSTEM_INFORMATION_CLASS;
|
||||||
|
|
||||||
@@ -1424,7 +1424,7 @@ typedef struct _SYSTEM_PROCESSOR_INFORMATION
|
|||||||
USHORT ProcessorArchitecture;
|
USHORT ProcessorArchitecture;
|
||||||
USHORT ProcessorLevel;
|
USHORT ProcessorLevel;
|
||||||
USHORT ProcessorRevision;
|
USHORT ProcessorRevision;
|
||||||
USHORT ProcessorCount;
|
USHORT MaximumProcessors;
|
||||||
ULONG ProcessorFeatureBits;
|
ULONG ProcessorFeatureBits;
|
||||||
} SYSTEM_PROCESSOR_INFORMATION, *PSYSTEM_PROCESSOR_INFORMATION;
|
} SYSTEM_PROCESSOR_INFORMATION, *PSYSTEM_PROCESSOR_INFORMATION;
|
||||||
|
|
||||||
@@ -1845,6 +1845,11 @@ typedef enum _EVENT_TRACE_INFORMATION_CLASS
|
|||||||
EventTraceSoftRestartInformation, // EVENT_TRACE_SOFT_RESTART_INFORMATION
|
EventTraceSoftRestartInformation, // EVENT_TRACE_SOFT_RESTART_INFORMATION
|
||||||
EventTraceLastBranchConfigurationInformation, // REDSTONE3
|
EventTraceLastBranchConfigurationInformation, // REDSTONE3
|
||||||
EventTraceLastBranchEventListInformation,
|
EventTraceLastBranchEventListInformation,
|
||||||
|
EventTraceProfileSourceAddInformation, // EVENT_TRACE_PROFILE_ADD_INFORMATION // REDSTONE4
|
||||||
|
EventTraceProfileSourceRemoveInformation, // EVENT_TRACE_PROFILE_REMOVE_INFORMATION
|
||||||
|
EventTraceProcessorTraceConfigurationInformation,
|
||||||
|
EventTraceProcessorTraceEventListInformation,
|
||||||
|
EventTraceCoverageSamplerInformation, // EVENT_TRACE_COVERAGE_SAMPLER_INFORMATION
|
||||||
MaxEventTraceInfoClass
|
MaxEventTraceInfoClass
|
||||||
} EVENT_TRACE_INFORMATION_CLASS;
|
} EVENT_TRACE_INFORMATION_CLASS;
|
||||||
|
|
||||||
@@ -1955,6 +1960,36 @@ typedef struct _EVENT_TRACE_SOFT_RESTART_INFORMATION
|
|||||||
WCHAR FileName[1];
|
WCHAR FileName[1];
|
||||||
} EVENT_TRACE_SOFT_RESTART_INFORMATION, *PEVENT_TRACE_SOFT_RESTART_INFORMATION;
|
} EVENT_TRACE_SOFT_RESTART_INFORMATION, *PEVENT_TRACE_SOFT_RESTART_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _EVENT_TRACE_PROFILE_ADD_INFORMATION
|
||||||
|
{
|
||||||
|
EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass;
|
||||||
|
BOOLEAN PerfEvtEventSelect;
|
||||||
|
BOOLEAN PerfEvtUnitSelect;
|
||||||
|
ULONG PerfEvtType;
|
||||||
|
ULONG CpuInfoHierarchy[0x3];
|
||||||
|
ULONG InitialInterval;
|
||||||
|
BOOLEAN AllowsHalt;
|
||||||
|
BOOLEAN Persist;
|
||||||
|
WCHAR ProfileSourceDescription[0x1];
|
||||||
|
} EVENT_TRACE_PROFILE_ADD_INFORMATION, *PEVENT_TRACE_PROFILE_ADD_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _EVENT_TRACE_PROFILE_REMOVE_INFORMATION
|
||||||
|
{
|
||||||
|
EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass;
|
||||||
|
KPROFILE_SOURCE ProfileSource;
|
||||||
|
ULONG CpuInfoHierarchy[0x3];
|
||||||
|
} EVENT_TRACE_PROFILE_REMOVE_INFORMATION, *PEVENT_TRACE_PROFILE_REMOVE_INFORMATION;
|
||||||
|
|
||||||
|
typedef struct _EVENT_TRACE_COVERAGE_SAMPLER_INFORMATION
|
||||||
|
{
|
||||||
|
EVENT_TRACE_INFORMATION_CLASS EventTraceInformationClass;
|
||||||
|
BOOLEAN CoverageSamplerInformationClass;
|
||||||
|
UCHAR MajorVersion;
|
||||||
|
UCHAR MinorVersion;
|
||||||
|
UCHAR Reserved;
|
||||||
|
HANDLE SamplerHandle;
|
||||||
|
} EVENT_TRACE_COVERAGE_SAMPLER_INFORMATION, *PEVENT_TRACE_COVERAGE_SAMPLER_INFORMATION;
|
||||||
|
|
||||||
typedef struct _SYSTEM_EXCEPTION_INFORMATION
|
typedef struct _SYSTEM_EXCEPTION_INFORMATION
|
||||||
{
|
{
|
||||||
ULONG AlignmentFixupCount;
|
ULONG AlignmentFixupCount;
|
||||||
@@ -2256,7 +2291,17 @@ typedef struct _SYSTEM_BOOT_ENVIRONMENT_INFORMATION
|
|||||||
{
|
{
|
||||||
GUID BootIdentifier;
|
GUID BootIdentifier;
|
||||||
FIRMWARE_TYPE FirmwareType;
|
FIRMWARE_TYPE FirmwareType;
|
||||||
|
union
|
||||||
|
{
|
||||||
ULONGLONG BootFlags;
|
ULONGLONG BootFlags;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONGLONG DbgMenuOsSelection : 1; // REDSTONE4
|
||||||
|
ULONGLONG DbgHiberBoot : 1;
|
||||||
|
ULONGLONG DbgSoftBoot : 1;
|
||||||
|
ULONGLONG DbgMeasuredLaunch : 1;
|
||||||
|
};
|
||||||
|
};
|
||||||
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION, *PSYSTEM_BOOT_ENVIRONMENT_INFORMATION;
|
} SYSTEM_BOOT_ENVIRONMENT_INFORMATION, *PSYSTEM_BOOT_ENVIRONMENT_INFORMATION;
|
||||||
|
|
||||||
// private
|
// private
|
||||||
@@ -2788,6 +2833,7 @@ typedef enum _SYSTEM_PROCESS_CLASSIFICATION
|
|||||||
SystemProcessClassificationSystem,
|
SystemProcessClassificationSystem,
|
||||||
SystemProcessClassificationSecureSystem,
|
SystemProcessClassificationSecureSystem,
|
||||||
SystemProcessClassificationMemCompression,
|
SystemProcessClassificationMemCompression,
|
||||||
|
SystemProcessClassificationRegistry, // REDSTONE4
|
||||||
SystemProcessClassificationMaximum
|
SystemProcessClassificationMaximum
|
||||||
} SYSTEM_PROCESS_CLASSIFICATION;
|
} SYSTEM_PROCESS_CLASSIFICATION;
|
||||||
|
|
||||||
@@ -3007,6 +3053,7 @@ typedef struct _SYSTEM_MEMORY_USAGE_INFORMATION
|
|||||||
typedef struct _SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION
|
typedef struct _SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION
|
||||||
{
|
{
|
||||||
HANDLE ImageFile;
|
HANDLE ImageFile;
|
||||||
|
ULONG Type; // REDSTONE4
|
||||||
} SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION, *PSYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION;
|
} SYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION, *PSYSTEM_CODEINTEGRITY_CERTIFICATE_INFORMATION;
|
||||||
|
|
||||||
// private
|
// private
|
||||||
@@ -3021,8 +3068,8 @@ typedef struct _SYSTEM_PHYSICAL_MEMORY_INFORMATION
|
|||||||
typedef enum _SYSTEM_ACTIVITY_MODERATION_STATE
|
typedef enum _SYSTEM_ACTIVITY_MODERATION_STATE
|
||||||
{
|
{
|
||||||
SystemActivityModerationStateSystemManaged,
|
SystemActivityModerationStateSystemManaged,
|
||||||
SystemActivityModerationStateAlwaysThrottled,
|
SystemActivityModerationStateUserManagedAllowThrottling,
|
||||||
SystemActivityModerationStateNeverThrottled,
|
SystemActivityModerationStateUserManagedDisableThrottling,
|
||||||
MaxSystemActivityModerationState
|
MaxSystemActivityModerationState
|
||||||
} SYSTEM_ACTIVITY_MODERATION_STATE;
|
} SYSTEM_ACTIVITY_MODERATION_STATE;
|
||||||
|
|
||||||
@@ -3065,9 +3112,11 @@ typedef struct _SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION
|
|||||||
ULONG Locked : 1;
|
ULONG Locked : 1;
|
||||||
ULONG Unlockable : 1;
|
ULONG Unlockable : 1;
|
||||||
ULONG UnlockApplied : 1;
|
ULONG UnlockApplied : 1;
|
||||||
ULONG Reserved : 29;
|
ULONG UnlockIdValid : 1; // REDSTONE4
|
||||||
|
ULONG Reserved : 28;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
UCHAR UnlockId[32]; // REDSTONE4
|
||||||
} SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION, *PSYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION;
|
} SYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION, *PSYSTEM_CODEINTEGRITY_UNLOCK_INFORMATION;
|
||||||
|
|
||||||
// private
|
// private
|
||||||
@@ -3098,11 +3147,27 @@ typedef struct _SYSTEM_KERNEL_VA_SHADOW_INFORMATION
|
|||||||
ULONG KvaShadowUserGlobal : 1;
|
ULONG KvaShadowUserGlobal : 1;
|
||||||
ULONG KvaShadowPcid : 1;
|
ULONG KvaShadowPcid : 1;
|
||||||
ULONG KvaShadowInvpcid : 1;
|
ULONG KvaShadowInvpcid : 1;
|
||||||
ULONG Reserved : 28;
|
ULONG KvaShadowRequired : 1; // REDSTONE4
|
||||||
|
ULONG KvaShadowRequiredAvailable : 1;
|
||||||
|
ULONG Reserved : 26;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} SYSTEM_KERNEL_VA_SHADOW_INFORMATION, *PSYSTEM_KERNEL_VA_SHADOW_INFORMATION;
|
} SYSTEM_KERNEL_VA_SHADOW_INFORMATION, *PSYSTEM_KERNEL_VA_SHADOW_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION
|
||||||
|
{
|
||||||
|
HANDLE FileHandle;
|
||||||
|
ULONG ImageSize;
|
||||||
|
PVOID Image;
|
||||||
|
} SYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION, *PSYSTEM_CODEINTEGRITYVERIFICATION_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION
|
||||||
|
{
|
||||||
|
PVOID HypervisorSharedUserVa;
|
||||||
|
} SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION, *PSYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION;
|
||||||
|
|
||||||
// private
|
// private
|
||||||
typedef struct _SYSTEM_SPECULATION_CONTROL_INFORMATION
|
typedef struct _SYSTEM_SPECULATION_CONTROL_INFORMATION
|
||||||
{
|
{
|
||||||
@@ -3124,6 +3189,18 @@ typedef struct _SYSTEM_SPECULATION_CONTROL_INFORMATION
|
|||||||
};
|
};
|
||||||
} SYSTEM_SPECULATION_CONTROL_INFORMATION, *PSYSTEM_SPECULATION_CONTROL_INFORMATION;
|
} SYSTEM_SPECULATION_CONTROL_INFORMATION, *PSYSTEM_SPECULATION_CONTROL_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _SYSTEM_DMA_GUARD_POLICY_INFORMATION
|
||||||
|
{
|
||||||
|
BOOLEAN DmaGuardPolicyEnabled;
|
||||||
|
} SYSTEM_DMA_GUARD_POLICY_INFORMATION, *PSYSTEM_DMA_GUARD_POLICY_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION
|
||||||
|
{
|
||||||
|
UCHAR EnclaveLaunchSigner[32];
|
||||||
|
} SYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION, *PSYSTEM_ENCLAVE_LAUNCH_CONTROL_INFORMATION;
|
||||||
|
|
||||||
#if (PHNT_MODE != PHNT_MODE_KERNEL)
|
#if (PHNT_MODE != PHNT_MODE_KERNEL)
|
||||||
|
|
||||||
NTSYSCALLAPI
|
NTSYSCALLAPI
|
||||||
@@ -3278,7 +3355,8 @@ typedef union _SYSDBG_LIVEDUMP_CONTROL_FLAGS
|
|||||||
ULONG UseDumpStorageStack : 1;
|
ULONG UseDumpStorageStack : 1;
|
||||||
ULONG CompressMemoryPagesData : 1;
|
ULONG CompressMemoryPagesData : 1;
|
||||||
ULONG IncludeUserSpaceMemoryPages : 1;
|
ULONG IncludeUserSpaceMemoryPages : 1;
|
||||||
ULONG Reserved : 29;
|
ULONG AbortIfMemoryPressure : 1; // REDSTONE4
|
||||||
|
ULONG Reserved : 28;
|
||||||
};
|
};
|
||||||
ULONG AsUlong;
|
ULONG AsUlong;
|
||||||
} SYSDBG_LIVEDUMP_CONTROL_FLAGS, *PSYSDBG_LIVEDUMP_CONTROL_FLAGS;
|
} SYSDBG_LIVEDUMP_CONTROL_FLAGS, *PSYSDBG_LIVEDUMP_CONTROL_FLAGS;
|
||||||
@@ -3974,12 +4052,15 @@ NtDisplayString(
|
|||||||
_In_ PUNICODE_STRING String
|
_In_ PUNICODE_STRING String
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Boot graphics
|
||||||
|
|
||||||
#if (PHNT_VERSION >= PHNT_WIN7)
|
#if (PHNT_VERSION >= PHNT_WIN7)
|
||||||
|
// rev
|
||||||
NTSYSCALLAPI
|
NTSYSCALLAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
NtDrawText(
|
NtDrawText(
|
||||||
_In_ PUNICODE_STRING String
|
_In_ PUNICODE_STRING Text
|
||||||
);
|
);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@@ -243,6 +243,8 @@ typedef enum _FILE_INFORMATION_CLASS
|
|||||||
FileDesiredStorageClassInformation, // FILE_DESIRED_STORAGE_CLASS_INFORMATION // since REDSTONE2
|
FileDesiredStorageClassInformation, // FILE_DESIRED_STORAGE_CLASS_INFORMATION // since REDSTONE2
|
||||||
FileStatInformation, // FILE_STAT_INFORMATION
|
FileStatInformation, // FILE_STAT_INFORMATION
|
||||||
FileMemoryPartitionInformation, // FILE_MEMORY_PARTITION_INFORMATION // since REDSTONE3
|
FileMemoryPartitionInformation, // FILE_MEMORY_PARTITION_INFORMATION // since REDSTONE3
|
||||||
|
FileStatLxInformation, // FILE_STAT_LX_INFORMATION // since REDSTONE4
|
||||||
|
FileCaseSensitiveInformation, // FILE_CASE_SENSITIVE_INFORMATION
|
||||||
FileMaximumInformation
|
FileMaximumInformation
|
||||||
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
|
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
|
||||||
|
|
||||||
@@ -711,6 +713,34 @@ typedef struct _FILE_MEMORY_PARTITION_INFORMATION
|
|||||||
} Flags;
|
} Flags;
|
||||||
} FILE_MEMORY_PARTITION_INFORMATION, *PFILE_MEMORY_PARTITION_INFORMATION;
|
} FILE_MEMORY_PARTITION_INFORMATION, *PFILE_MEMORY_PARTITION_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _FILE_STAT_LX_INFORMATION
|
||||||
|
{
|
||||||
|
LARGE_INTEGER FileId;
|
||||||
|
LARGE_INTEGER CreationTime;
|
||||||
|
LARGE_INTEGER LastAccessTime;
|
||||||
|
LARGE_INTEGER LastWriteTime;
|
||||||
|
LARGE_INTEGER ChangeTime;
|
||||||
|
LARGE_INTEGER AllocationSize;
|
||||||
|
LARGE_INTEGER EndOfFile;
|
||||||
|
ULONG FileAttributes;
|
||||||
|
ULONG ReparseTag;
|
||||||
|
ULONG NumberOfLinks;
|
||||||
|
ULONG EffectiveAccess;
|
||||||
|
ULONG LxFlags;
|
||||||
|
ULONG LxUid;
|
||||||
|
ULONG LxGid;
|
||||||
|
ULONG LxMode;
|
||||||
|
ULONG LxDeviceIdMajor;
|
||||||
|
ULONG LxDeviceIdMinor;
|
||||||
|
} FILE_STAT_LX_INFORMATION, *PFILE_STAT_LX_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _FILE_CASE_SENSITIVE_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
} FILE_CASE_SENSITIVE_INFORMATION, *PFILE_CASE_SENSITIVE_INFORMATION;
|
||||||
|
|
||||||
// NtQueryDirectoryFile types
|
// NtQueryDirectoryFile types
|
||||||
|
|
||||||
typedef struct _FILE_DIRECTORY_INFORMATION
|
typedef struct _FILE_DIRECTORY_INFORMATION
|
||||||
|
@@ -720,6 +720,7 @@ LdrEnumerateLoadedModules(
|
|||||||
_In_ PVOID Context
|
_In_ PVOID Context
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
LdrOpenImageFileOptionsKey(
|
LdrOpenImageFileOptionsKey(
|
||||||
@@ -728,6 +729,7 @@ LdrOpenImageFileOptionsKey(
|
|||||||
_Out_ PHANDLE NewKeyHandle
|
_Out_ PHANDLE NewKeyHandle
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
LdrQueryImageFileKeyOption(
|
LdrQueryImageFileKeyOption(
|
||||||
@@ -739,6 +741,7 @@ LdrQueryImageFileKeyOption(
|
|||||||
_Out_opt_ PULONG ReturnedLength
|
_Out_opt_ PULONG ReturnedLength
|
||||||
);
|
);
|
||||||
|
|
||||||
|
NTSYSAPI
|
||||||
NTSTATUS
|
NTSTATUS
|
||||||
NTAPI
|
NTAPI
|
||||||
LdrQueryImageFileExecutionOptions(
|
LdrQueryImageFileExecutionOptions(
|
||||||
|
@@ -1,18 +1,6 @@
|
|||||||
#ifndef _NTMISC_H
|
#ifndef _NTMISC_H
|
||||||
#define _NTMISC_H
|
#define _NTMISC_H
|
||||||
|
|
||||||
// Boot graphics
|
|
||||||
|
|
||||||
#if (PHNT_VERSION >= PHNT_WIN7)
|
|
||||||
// rev
|
|
||||||
NTSYSCALLAPI
|
|
||||||
NTSTATUS
|
|
||||||
NTAPI
|
|
||||||
NtDrawText(
|
|
||||||
_In_ PUNICODE_STRING Text
|
|
||||||
);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Filter manager
|
// Filter manager
|
||||||
|
|
||||||
#define FLT_PORT_CONNECT 0x0001
|
#define FLT_PORT_CONNECT 0x0001
|
||||||
|
@@ -75,7 +75,7 @@ typedef enum _MEMORY_INFORMATION_CLASS
|
|||||||
MemoryImageInformation, // MEMORY_IMAGE_INFORMATION
|
MemoryImageInformation, // MEMORY_IMAGE_INFORMATION
|
||||||
MemoryRegionInformationEx,
|
MemoryRegionInformationEx,
|
||||||
MemoryPrivilegedBasicInformation,
|
MemoryPrivilegedBasicInformation,
|
||||||
MemoryEnclaveImageInformation, // since REDSTONE3
|
MemoryEnclaveImageInformation, // MEMORY_ENCLAVE_IMAGE_INFORMATION // since REDSTONE3
|
||||||
MemoryBasicInformationCapped
|
MemoryBasicInformationCapped
|
||||||
} MEMORY_INFORMATION_CLASS;
|
} MEMORY_INFORMATION_CLASS;
|
||||||
#else
|
#else
|
||||||
@@ -136,6 +136,15 @@ typedef struct _MEMORY_REGION_INFORMATION
|
|||||||
SIZE_T CommitSize;
|
SIZE_T CommitSize;
|
||||||
} MEMORY_REGION_INFORMATION, *PMEMORY_REGION_INFORMATION;
|
} MEMORY_REGION_INFORMATION, *PMEMORY_REGION_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef enum _MEMORY_WORKING_SET_EX_LOCATION
|
||||||
|
{
|
||||||
|
MemoryLocationInvalid,
|
||||||
|
MemoryLocationResident,
|
||||||
|
MemoryLocationPagefile,
|
||||||
|
MemoryLocationReserved
|
||||||
|
} MEMORY_WORKING_SET_EX_LOCATION;
|
||||||
|
|
||||||
// private
|
// private
|
||||||
typedef struct _MEMORY_WORKING_SET_EX_BLOCK
|
typedef struct _MEMORY_WORKING_SET_EX_BLOCK
|
||||||
{
|
{
|
||||||
@@ -207,12 +216,20 @@ typedef struct _MEMORY_IMAGE_INFORMATION
|
|||||||
{
|
{
|
||||||
ULONG ImagePartialMap : 1;
|
ULONG ImagePartialMap : 1;
|
||||||
ULONG ImageNotExecutable : 1;
|
ULONG ImageNotExecutable : 1;
|
||||||
ULONG ImageSigningLevel : 1; // REDSTONE3
|
ULONG ImageSigningLevel : 4; // REDSTONE3
|
||||||
ULONG Reserved : 30;
|
ULONG Reserved : 26;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
} MEMORY_IMAGE_INFORMATION, *PMEMORY_IMAGE_INFORMATION;
|
} MEMORY_IMAGE_INFORMATION, *PMEMORY_IMAGE_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _MEMORY_ENCLAVE_IMAGE_INFORMATION
|
||||||
|
{
|
||||||
|
MEMORY_IMAGE_INFORMATION ImageInfo;
|
||||||
|
UCHAR UniqueID[32];
|
||||||
|
UCHAR AuthorID[32];
|
||||||
|
} MEMORY_ENCLAVE_IMAGE_INFORMATION, *PMEMORY_ENCLAVE_IMAGE_INFORMATION;
|
||||||
|
|
||||||
#define MMPFNLIST_ZERO 0
|
#define MMPFNLIST_ZERO 0
|
||||||
#define MMPFNLIST_FREE 1
|
#define MMPFNLIST_FREE 1
|
||||||
#define MMPFNLIST_STANDBY 2
|
#define MMPFNLIST_STANDBY 2
|
||||||
@@ -654,7 +671,8 @@ typedef enum _MEMORY_PARTITION_INFORMATION_CLASS
|
|||||||
SystemMemoryPartitionAddPagefile, // s: MEMORY_PARTITION_PAGEFILE_INFORMATION
|
SystemMemoryPartitionAddPagefile, // s: MEMORY_PARTITION_PAGEFILE_INFORMATION
|
||||||
SystemMemoryPartitionCombineMemory, // q; s: MEMORY_PARTITION_PAGE_COMBINE_INFORMATION
|
SystemMemoryPartitionCombineMemory, // q; s: MEMORY_PARTITION_PAGE_COMBINE_INFORMATION
|
||||||
SystemMemoryPartitionInitialAddMemory, // q; s: MEMORY_PARTITION_INITIAL_ADD_INFORMATION
|
SystemMemoryPartitionInitialAddMemory, // q; s: MEMORY_PARTITION_INITIAL_ADD_INFORMATION
|
||||||
SystemMemoryPartitionGetMemoryEvents // MEMORY_PARTITION_MEMORY_EVENTS_INFORMATION // since REDSTONE2
|
SystemMemoryPartitionGetMemoryEvents, // MEMORY_PARTITION_MEMORY_EVENTS_INFORMATION // since REDSTONE2
|
||||||
|
SystemMemoryPartitionMax
|
||||||
} MEMORY_PARTITION_INFORMATION_CLASS;
|
} MEMORY_PARTITION_INFORMATION_CLASS;
|
||||||
|
|
||||||
// private
|
// private
|
||||||
|
@@ -84,8 +84,8 @@ typedef struct _PEB
|
|||||||
PVOID SubSystemData;
|
PVOID SubSystemData;
|
||||||
PVOID ProcessHeap;
|
PVOID ProcessHeap;
|
||||||
PRTL_CRITICAL_SECTION FastPebLock;
|
PRTL_CRITICAL_SECTION FastPebLock;
|
||||||
PVOID AtlThunkSListPtr;
|
|
||||||
PVOID IFEOKey;
|
PVOID IFEOKey;
|
||||||
|
PSLIST_HEADER AtlThunkSListPtr;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
ULONG CrossProcessFlags;
|
ULONG CrossProcessFlags;
|
||||||
@@ -193,19 +193,24 @@ typedef struct _PEB
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
ULONGLONG CsrServerReadOnlySharedMemoryBase;
|
ULONGLONG CsrServerReadOnlySharedMemoryBase;
|
||||||
PVOID TppWorkerpListLock;
|
PRTL_CRITICAL_SECTION TppWorkerpListLock;
|
||||||
LIST_ENTRY TppWorkerpList;
|
LIST_ENTRY TppWorkerpList;
|
||||||
PVOID WaitOnAddressHashTable[128];
|
PVOID WaitOnAddressHashTable[128];
|
||||||
PVOID TelemetryCoverageHeader; // REDSTONE3
|
PVOID TelemetryCoverageHeader; // REDSTONE3
|
||||||
ULONG CloudFileFlags;
|
ULONG CloudFileFlags;
|
||||||
|
ULONG CloudFileDiagFlags; // REDSTONE4
|
||||||
|
CHAR PlaceholderCompatibilityMode;
|
||||||
|
CHAR PlaceholderCompatibilityModeReserved[7];
|
||||||
} PEB, *PPEB;
|
} PEB, *PPEB;
|
||||||
|
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
C_ASSERT(FIELD_OFFSET(PEB, SessionId) == 0x2C0);
|
C_ASSERT(FIELD_OFFSET(PEB, SessionId) == 0x2C0);
|
||||||
C_ASSERT(sizeof(PEB) == 0x7B0);
|
//C_ASSERT(sizeof(PEB) == 0x7B0); // REDSTONE3
|
||||||
|
C_ASSERT(sizeof(PEB) == 0x7B8); // REDSTONE4
|
||||||
#else
|
#else
|
||||||
C_ASSERT(FIELD_OFFSET(PEB, SessionId) == 0x1D4);
|
C_ASSERT(FIELD_OFFSET(PEB, SessionId) == 0x1D4);
|
||||||
C_ASSERT(sizeof(PEB) == 0x468);
|
//C_ASSERT(sizeof(PEB) == 0x468); // REDSTONE3
|
||||||
|
C_ASSERT(sizeof(PEB) == 0x470);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define GDI_BATCH_BUFFER_SIZE 310
|
#define GDI_BATCH_BUFFER_SIZE 310
|
||||||
|
@@ -105,7 +105,7 @@ typedef enum _PROCESSINFOCLASS
|
|||||||
ProcessBasePriority, // s: KPRIORITY
|
ProcessBasePriority, // s: KPRIORITY
|
||||||
ProcessRaisePriority, // s: ULONG
|
ProcessRaisePriority, // s: ULONG
|
||||||
ProcessDebugPort, // q: HANDLE
|
ProcessDebugPort, // q: HANDLE
|
||||||
ProcessExceptionPort, // s: HANDLE
|
ProcessExceptionPort, // s: PROCESS_EXCEPTION_PORT
|
||||||
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
|
ProcessAccessToken, // s: PROCESS_ACCESS_TOKEN
|
||||||
ProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10
|
ProcessLdtInformation, // qs: PROCESS_LDT_INFORMATION // 10
|
||||||
ProcessLdtSize, // s: PROCESS_LDT_SIZE
|
ProcessLdtSize, // s: PROCESS_LDT_SIZE
|
||||||
@@ -132,12 +132,12 @@ typedef enum _PROCESSINFOCLASS
|
|||||||
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
|
ProcessHandleTracing, // q: PROCESS_HANDLE_TRACING_QUERY; s: size 0 disables, otherwise enables
|
||||||
ProcessIoPriority, // qs: IO_PRIORITY_HINT
|
ProcessIoPriority, // qs: IO_PRIORITY_HINT
|
||||||
ProcessExecuteFlags, // qs: ULONG
|
ProcessExecuteFlags, // qs: ULONG
|
||||||
ProcessResourceManagement,
|
ProcessResourceManagement, // ProcessTlsInformation // PROCESS_TLS_INFORMATION
|
||||||
ProcessCookie, // q: ULONG
|
ProcessCookie, // q: ULONG
|
||||||
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
|
ProcessImageInformation, // q: SECTION_IMAGE_INFORMATION
|
||||||
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA
|
ProcessCycleTime, // q: PROCESS_CYCLE_TIME_INFORMATION // since VISTA
|
||||||
ProcessPagePriority, // q: ULONG
|
ProcessPagePriority, // q: PAGE_PRIORITY_INFORMATION
|
||||||
ProcessInstrumentationCallback, // 40
|
ProcessInstrumentationCallback, // qs: PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION // 40
|
||||||
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
|
ProcessThreadStackAllocation, // s: PROCESS_STACK_ALLOCATION_INFORMATION, PROCESS_STACK_ALLOCATION_INFORMATION_EX
|
||||||
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
|
ProcessWorkingSetWatchEx, // q: PROCESS_WS_WATCH_INFORMATION_EX[]
|
||||||
ProcessImageFileNameWin32, // q: UNICODE_STRING
|
ProcessImageFileNameWin32, // q: UNICODE_STRING
|
||||||
@@ -146,7 +146,7 @@ typedef enum _PROCESSINFOCLASS
|
|||||||
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
|
ProcessMemoryAllocationMode, // qs: PROCESS_MEMORY_ALLOCATION_MODE
|
||||||
ProcessGroupInformation, // q: USHORT[]
|
ProcessGroupInformation, // q: USHORT[]
|
||||||
ProcessTokenVirtualizationEnabled, // s: ULONG
|
ProcessTokenVirtualizationEnabled, // s: ULONG
|
||||||
ProcessConsoleHostProcess, // q: ULONG_PTR
|
ProcessConsoleHostProcess, // q: ULONG_PTR // ProcessOwnerInformation
|
||||||
ProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50
|
ProcessWindowInformation, // q: PROCESS_WINDOW_INFORMATION // 50
|
||||||
ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
|
ProcessHandleInformation, // q: PROCESS_HANDLE_SNAPSHOT_INFORMATION // since WIN8
|
||||||
ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
|
ProcessMitigationPolicy, // s: PROCESS_MITIGATION_POLICY_INFORMATION
|
||||||
@@ -187,6 +187,9 @@ typedef enum _PROCESSINFOCLASS
|
|||||||
ProcessEnableReadWriteVmLogging, // PROCESS_READWRITEVM_LOGGING_INFORMATION
|
ProcessEnableReadWriteVmLogging, // PROCESS_READWRITEVM_LOGGING_INFORMATION
|
||||||
ProcessUptimeInformation, // PROCESS_UPTIME_INFORMATION
|
ProcessUptimeInformation, // PROCESS_UPTIME_INFORMATION
|
||||||
ProcessImageSection,
|
ProcessImageSection,
|
||||||
|
ProcessDebugAuthInformation, // since REDSTONE4
|
||||||
|
ProcessSystemResourceManagement, // PROCESS_SYSTEM_RESOURCE_MANAGEMENT
|
||||||
|
ProcessSequenceNumber, // q: ULONGLONG
|
||||||
MaxProcessInfoClass
|
MaxProcessInfoClass
|
||||||
} PROCESSINFOCLASS;
|
} PROCESSINFOCLASS;
|
||||||
#endif
|
#endif
|
||||||
@@ -353,6 +356,15 @@ typedef struct _POOLED_USAGE_AND_LIMITS
|
|||||||
SIZE_T PagefileLimit;
|
SIZE_T PagefileLimit;
|
||||||
} POOLED_USAGE_AND_LIMITS, *PPOOLED_USAGE_AND_LIMITS;
|
} POOLED_USAGE_AND_LIMITS, *PPOOLED_USAGE_AND_LIMITS;
|
||||||
|
|
||||||
|
#define PROCESS_EXCEPTION_PORT_ALL_STATE_BITS 0x00000003
|
||||||
|
#define PROCESS_EXCEPTION_PORT_ALL_STATE_FLAGS ((ULONG_PTR)((1UL << PROCESS_EXCEPTION_PORT_ALL_STATE_BITS) - 1))
|
||||||
|
|
||||||
|
typedef struct _PROCESS_EXCEPTION_PORT
|
||||||
|
{
|
||||||
|
_In_ HANDLE ExceptionPortHandle; // Handle to the exception port. No particular access required.
|
||||||
|
_Inout_ ULONG StateFlags; // Miscellaneous state flags to be cached along with the exception port in the kernel.
|
||||||
|
} PROCESS_EXCEPTION_PORT, *PPROCESS_EXCEPTION_PORT;
|
||||||
|
|
||||||
typedef struct _PROCESS_ACCESS_TOKEN
|
typedef struct _PROCESS_ACCESS_TOKEN
|
||||||
{
|
{
|
||||||
HANDLE Token; // needs TOKEN_ASSIGN_PRIMARY access
|
HANDLE Token; // needs TOKEN_ASSIGN_PRIMARY access
|
||||||
@@ -448,6 +460,8 @@ typedef struct _PROCESS_SESSION_INFORMATION
|
|||||||
ULONG SessionId;
|
ULONG SessionId;
|
||||||
} PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION;
|
} PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION;
|
||||||
|
|
||||||
|
#define PROCESS_HANDLE_EXCEPTIONS_ENABLED 0x00000001
|
||||||
|
|
||||||
#define PROCESS_HANDLE_RAISE_EXCEPTION_ON_INVALID_HANDLE_CLOSE_DISABLED 0x00000000
|
#define PROCESS_HANDLE_RAISE_EXCEPTION_ON_INVALID_HANDLE_CLOSE_DISABLED 0x00000000
|
||||||
#define PROCESS_HANDLE_RAISE_EXCEPTION_ON_INVALID_HANDLE_CLOSE_ENABLED 0x00000001
|
#define PROCESS_HANDLE_RAISE_EXCEPTION_ON_INVALID_HANDLE_CLOSE_ENABLED 0x00000001
|
||||||
|
|
||||||
@@ -487,6 +501,42 @@ typedef struct _PROCESS_HANDLE_TRACING_QUERY
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _THREAD_TLS_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
PVOID NewTlsData;
|
||||||
|
PVOID OldTlsData;
|
||||||
|
HANDLE ThreadId;
|
||||||
|
} THREAD_TLS_INFORMATION, *PTHREAD_TLS_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef enum _PROCESS_TLS_INFORMATION_TYPE
|
||||||
|
{
|
||||||
|
ProcessTlsReplaceIndex,
|
||||||
|
ProcessTlsReplaceVector,
|
||||||
|
MaxProcessTlsOperation
|
||||||
|
} PROCESS_TLS_INFORMATION_TYPE, *PPROCESS_TLS_INFORMATION_TYPE;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _PROCESS_TLS_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
ULONG OperationType;
|
||||||
|
ULONG ThreadDataCount;
|
||||||
|
ULONG TlsIndex;
|
||||||
|
ULONG PreviousCount;
|
||||||
|
THREAD_TLS_INFORMATION ThreadData[1];
|
||||||
|
} PROCESS_TLS_INFORMATION, *PPROCESS_TLS_INFORMATION;
|
||||||
|
|
||||||
|
// private
|
||||||
|
typedef struct _PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION
|
||||||
|
{
|
||||||
|
ULONG Version;
|
||||||
|
ULONG Reserved;
|
||||||
|
PVOID Callback;
|
||||||
|
} PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION, *PPROCESS_INSTRUMENTATION_CALLBACK_INFORMATION;
|
||||||
|
|
||||||
// private
|
// private
|
||||||
typedef struct _PROCESS_STACK_ALLOCATION_INFORMATION
|
typedef struct _PROCESS_STACK_ALLOCATION_INFORMATION
|
||||||
{
|
{
|
||||||
@@ -757,17 +807,19 @@ typedef struct _MANAGE_WRITES_TO_EXECUTABLE_MEMORY
|
|||||||
ULONG Spare : 22;
|
ULONG Spare : 22;
|
||||||
} MANAGE_WRITES_TO_EXECUTABLE_MEMORY, *PMANAGE_WRITES_TO_EXECUTABLE_MEMORY;
|
} MANAGE_WRITES_TO_EXECUTABLE_MEMORY, *PMANAGE_WRITES_TO_EXECUTABLE_MEMORY;
|
||||||
|
|
||||||
typedef struct _PROCESS_READWRITEVM_LOGGING_INFORMATION
|
#define PROCESS_READWRITEVM_LOGGING_ENABLE_READVM 1
|
||||||
|
#define PROCESS_READWRITEVM_LOGGING_ENABLE_WRITEVM 2
|
||||||
|
#define PROCESS_READWRITEVM_LOGGING_ENABLE_READVM_V 1UL
|
||||||
|
#define PROCESS_READWRITEVM_LOGGING_ENABLE_WRITEVM_V 2UL
|
||||||
|
|
||||||
|
typedef union _PROCESS_READWRITEVM_LOGGING_INFORMATION
|
||||||
{
|
{
|
||||||
union
|
UCHAR Flags;
|
||||||
{
|
|
||||||
BOOLEAN Flags;
|
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
BOOLEAN EnableReadVmLogging : 1;
|
UCHAR EnableReadVmLogging : 1;
|
||||||
BOOLEAN EnableWriteVmLogging : 1;
|
UCHAR EnableWriteVmLogging : 1;
|
||||||
BOOLEAN Unused : 6;
|
UCHAR Unused : 6;
|
||||||
};
|
|
||||||
};
|
};
|
||||||
} PROCESS_READWRITEVM_LOGGING_INFORMATION, *PPROCESS_READWRITEVM_LOGGING_INFORMATION;
|
} PROCESS_READWRITEVM_LOGGING_INFORMATION, *PPROCESS_READWRITEVM_LOGGING_INFORMATION;
|
||||||
|
|
||||||
@@ -788,6 +840,16 @@ typedef struct _PROCESS_UPTIME_INFORMATION
|
|||||||
};
|
};
|
||||||
} PROCESS_UPTIME_INFORMATION, *PPROCESS_UPTIME_INFORMATION;
|
} PROCESS_UPTIME_INFORMATION, *PPROCESS_UPTIME_INFORMATION;
|
||||||
|
|
||||||
|
typedef union _PROCESS_SYSTEM_RESOURCE_MANAGEMENT
|
||||||
|
{
|
||||||
|
ULONG Flags;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
ULONG Foreground : 1;
|
||||||
|
ULONG Reserved : 31;
|
||||||
|
};
|
||||||
|
} PROCESS_SYSTEM_RESOURCE_MANAGEMENT, *PPROCESS_SYSTEM_RESOURCE_MANAGEMENT;
|
||||||
|
|
||||||
// end_private
|
// end_private
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -1008,6 +1070,7 @@ NtResumeProcess(
|
|||||||
#define NtCurrentProcessToken() ((HANDLE)(LONG_PTR)-4)
|
#define NtCurrentProcessToken() ((HANDLE)(LONG_PTR)-4)
|
||||||
#define NtCurrentThreadToken() ((HANDLE)(LONG_PTR)-5)
|
#define NtCurrentThreadToken() ((HANDLE)(LONG_PTR)-5)
|
||||||
#define NtCurrentEffectiveToken() ((HANDLE)(LONG_PTR)-6)
|
#define NtCurrentEffectiveToken() ((HANDLE)(LONG_PTR)-6)
|
||||||
|
#define NtCurrentSilo() ((HANDLE)(LONG_PTR)-1)
|
||||||
|
|
||||||
// Not NT, but useful.
|
// Not NT, but useful.
|
||||||
#define NtCurrentProcessId() (NtCurrentTeb()->ClientId.UniqueProcess)
|
#define NtCurrentProcessId() (NtCurrentTeb()->ClientId.UniqueProcess)
|
||||||
@@ -1471,7 +1534,8 @@ typedef enum _PS_MITIGATION_OPTION
|
|||||||
PS_MITIGATION_OPTION_EXPORT_ADDRESS_FILTER_PLUS,
|
PS_MITIGATION_OPTION_EXPORT_ADDRESS_FILTER_PLUS,
|
||||||
PS_MITIGATION_OPTION_RESTRICT_CHILD_PROCESS_CREATION,
|
PS_MITIGATION_OPTION_RESTRICT_CHILD_PROCESS_CREATION,
|
||||||
PS_MITIGATION_OPTION_IMPORT_ADDRESS_FILTER,
|
PS_MITIGATION_OPTION_IMPORT_ADDRESS_FILTER,
|
||||||
PS_MITIGATION_OPTION_MODULE_TAMPERING_PROTECTION
|
PS_MITIGATION_OPTION_MODULE_TAMPERING_PROTECTION,
|
||||||
|
PS_MITIGATION_OPTION_RESTRICT_INDIRECT_BRANCH_PREDICTION
|
||||||
} PS_MITIGATION_OPTION;
|
} PS_MITIGATION_OPTION;
|
||||||
|
|
||||||
// windows-internals-book:"Chapter 5"
|
// windows-internals-book:"Chapter 5"
|
||||||
|
@@ -3236,6 +3236,15 @@ RtlDoesFileExists_U(
|
|||||||
_In_ PWSTR FileName
|
_In_ PWSTR FileName
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#if (PHNT_VERSION >= PHNT_REDSTONE2)
|
||||||
|
NTSYSAPI
|
||||||
|
PCWSTR
|
||||||
|
NTAPI
|
||||||
|
RtlGetNtSystemRoot(
|
||||||
|
VOID
|
||||||
|
);
|
||||||
|
#endif
|
||||||
|
|
||||||
// Heaps
|
// Heaps
|
||||||
|
|
||||||
typedef struct _RTL_HEAP_ENTRY
|
typedef struct _RTL_HEAP_ENTRY
|
||||||
|
@@ -36,6 +36,7 @@
|
|||||||
#define PHNT_REDSTONE 102
|
#define PHNT_REDSTONE 102
|
||||||
#define PHNT_REDSTONE2 103
|
#define PHNT_REDSTONE2 103
|
||||||
#define PHNT_REDSTONE3 104
|
#define PHNT_REDSTONE3 104
|
||||||
|
#define PHNT_REDSTONE4 105
|
||||||
|
|
||||||
#ifndef PHNT_MODE
|
#ifndef PHNT_MODE
|
||||||
#define PHNT_MODE PHNT_MODE_USER
|
#define PHNT_MODE PHNT_MODE_USER
|
||||||
|
@@ -213,6 +213,8 @@ typedef const OBJECT_ATTRIBUTES *PCOBJECT_ATTRIBUTES;
|
|||||||
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) { sizeof(OBJECT_ATTRIBUTES), NULL, n, a, NULL, NULL }
|
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a) { sizeof(OBJECT_ATTRIBUTES), NULL, n, a, NULL, NULL }
|
||||||
#define RTL_INIT_OBJECT_ATTRIBUTES(n, a) RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
|
#define RTL_INIT_OBJECT_ATTRIBUTES(n, a) RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
|
||||||
|
|
||||||
|
#define OBJ_NAME_PATH_SEPARATOR ((WCHAR)L'\\')
|
||||||
|
|
||||||
// Portability
|
// Portability
|
||||||
|
|
||||||
typedef struct _OBJECT_ATTRIBUTES64
|
typedef struct _OBJECT_ATTRIBUTES64
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -46,6 +46,8 @@
|
|||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
|
<OutDir>$(ProjectDir)bin\$(Configuration)\$(PlatformShortName)\</OutDir>
|
||||||
|
<IntDir>$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
@@ -93,7 +95,7 @@
|
|||||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||||
</Link>
|
</Link>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup\"</Command>
|
<Command>copy /Y "$(TargetPath)" "$(SolutionDir)setup_ai\"</Command>
|
||||||
<Message>Copy release binaries to the setup staging directory</Message>
|
<Message>Copy release binaries to the setup staging directory</Message>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
|
@@ -5,10 +5,7 @@
|
|||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiPropsComponent">
|
||||||
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
|
<ROW Property="AI_BITMAP_DISPLAY_MODE" Value="0"/>
|
||||||
<ROW Property="AI_CLEAN_RESOURCES_DISABLE_UPGRADE" Value="1"/>
|
|
||||||
<ROW Property="AI_CLEAN_RESOURCES_UNINSTALL" Value="1"/>
|
<ROW Property="AI_CLEAN_RESOURCES_UNINSTALL" Value="1"/>
|
||||||
<ROW Property="AI_CLEAN_RESOURCES_USER_PROMPT_BASIC_UI" Value="1"/>
|
|
||||||
<ROW Property="AI_CLEAN_RESOURCES_USER_PROMPT_FULL_UI" Value="1"/>
|
|
||||||
<ROW Property="AI_ThemeStyle" Value="aero" MsiKey="AI_ThemeStyle"/>
|
<ROW Property="AI_ThemeStyle" Value="aero" MsiKey="AI_ThemeStyle"/>
|
||||||
<ROW Property="ALLUSERS" Value="1"/>
|
<ROW Property="ALLUSERS" Value="1"/>
|
||||||
<ROW Property="ARPCOMMENTS" Value="Enables Windows Update on PCs with unsupported processors." ValueLocId="*"/>
|
<ROW Property="ARPCOMMENTS" Value="Enables Windows Update on PCs with unsupported processors." ValueLocId="*"/>
|
||||||
@@ -21,10 +18,10 @@
|
|||||||
<ROW Property="AiPreventAutoPin" Value="System.AppUserModel.ExcludeFromShowInNewInstall"/>
|
<ROW Property="AiPreventAutoPin" Value="System.AppUserModel.ExcludeFromShowInNewInstall"/>
|
||||||
<ROW Property="MSIFASTINSTALL" MultiBuildValue="x64Build:6#x86Build:6"/>
|
<ROW Property="MSIFASTINSTALL" MultiBuildValue="x64Build:6#x86Build:6"/>
|
||||||
<ROW Property="Manufacturer" Value="zeffy"/>
|
<ROW Property="Manufacturer" Value="zeffy"/>
|
||||||
<ROW Property="ProductCode" Value="1027:{F4D292D2-CE8F-4908-80AF-CB48B3E560CF} 1028:{66D6B564-B289-4F83-98E0-4296CDE37CB9} 1031:{F4662CF2-7D9F-4370-B45F-ADB021733AF9} 1033:{0DAE2218-2FB5-4AD0-9558-FA2F1B1E5ABF} 1035:{7A1DE4CB-ED5F-4EA0-B262-137BB5CDF2BF} 1036:{B2D2636D-2170-457A-A876-051F227DEEA2} 1038:{9D2917A0-8F1E-4E0F-AE62-1938BD4CED0E} 1040:{3BD98571-9F20-44F8-9162-62D664860999} 1041:{64C167D2-432B-4B82-B5AF-AF795C78F4A1} 1042:{8EAAC0A1-89E3-46B8-B101-E149E87F04F4} 1043:{8AB22455-426B-4757-B640-30729411FD11} 1045:{1CC402B6-02FD-4E14-BE66-10A12FA99106} 1046:{9E7919D2-D6AF-4864-A6C3-028F759BF307} 1049:{8FA26981-B9FF-4505-B547-4EFA9B5241C8} 1060:{3992ECFB-F774-49FE-8B7A-9C2F7B52B271} 2052:{75CEB203-1CE4-4B6F-A9DF-18D8B902C6B8} 2070:{8B6326BE-B5FE-46F3-BD61-1AC95EB0C1CA} 3082:{D564C11C-4870-43C1-BD62-F71DFC45FBF2} " Type="16"/>
|
<ROW Property="ProductCode" Value="1027:{8788C792-140E-41E9-B875-685F557ACEE6} 1028:{C3A9DFE3-DBAB-47BA-ABAD-804D54F0FBF4} 1031:{85F838D1-6E19-4D99-BEE8-3A46A6D52813} 1033:{F011FFEE-01E3-495E-80CA-10A640C55031} 1035:{03787122-8FC5-4BF2-B447-372148E7E0CD} 1036:{C83296AB-0CC4-4954-A218-3F76BE31C530} 1038:{8D87BFD2-FE05-4506-A1D8-62EE821DB623} 1040:{C48A5EF8-8DB1-4D08-B468-683879C807E3} 1041:{5CCB0BE8-E87D-4D8C-BD5F-B5A6E1CDDB4A} 1042:{2AE0CA07-01C9-4B29-A880-E52CE19EB157} 1043:{28C34648-07BD-463C-A61E-AE47525AF2D2} 1045:{F7E7320E-9EBF-44C5-97E7-E8FEB7A47613} 1046:{393B1C36-514F-4722-A577-408055568261} 1049:{13DAE24C-D5C2-443E-8105-8B3FE24C9370} 1060:{836B7413-1503-4164-9D21-87C28468AD61} 2052:{880E51E8-4243-42F4-BAA3-B32785746291} 2070:{E76212D9-7C99-4C47-9004-3F32D658D6A6} 3082:{CFE6B8E7-9D52-488C-BEA6-A7EE3306B20C} " Type="16"/>
|
||||||
<ROW Property="ProductLanguage" Value="1033"/>
|
<ROW Property="ProductLanguage" Value="1033"/>
|
||||||
<ROW Property="ProductName" Value="wufuc"/>
|
<ROW Property="ProductName" Value="wufuc"/>
|
||||||
<ROW Property="ProductVersion" Value="1.0.0.0" Type="32" TargetFile="wufuc64.dll"/>
|
<ROW Property="ProductVersion" Value="1.0.1.201" Type="32" TargetFile="wufuc64.dll"/>
|
||||||
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
|
<ROW Property="SecureCustomProperties" Value="OLDPRODUCTS;AI_NEWERPRODUCTFOUND"/>
|
||||||
<ROW Property="UpgradeCode" Value="{4C52972C-251E-4D1B-AD09-EAA765719DCC}"/>
|
<ROW Property="UpgradeCode" Value="{4C52972C-251E-4D1B-AD09-EAA765719DCC}"/>
|
||||||
<ROW Property="WindowsType9X" MultiBuildValue="x64Build:Windows 9x/ME#x86Build:Windows 9x/ME" ValueLocId="-"/>
|
<ROW Property="WindowsType9X" MultiBuildValue="x64Build:Windows 9x/ME#x86Build:Windows 9x/ME" ValueLocId="-"/>
|
||||||
@@ -43,36 +40,30 @@
|
|||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiDirsComponent">
|
||||||
<ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/>
|
<ROW Directory="APPDIR" Directory_Parent="TARGETDIR" DefaultDir="APPDIR:." IsPseudoRoot="1"/>
|
||||||
<ROW Directory="CommonAppDataFolder" Directory_Parent="TARGETDIR" DefaultDir="COMMON~1|CommonAppDataFolder" IsPseudoRoot="1"/>
|
|
||||||
<ROW Directory="SHORTCUTDIR" Directory_Parent="TARGETDIR" DefaultDir="SHORTC~1|SHORTCUTDIR" IsPseudoRoot="1"/>
|
<ROW Directory="SHORTCUTDIR" Directory_Parent="TARGETDIR" DefaultDir="SHORTC~1|SHORTCUTDIR" IsPseudoRoot="1"/>
|
||||||
<ROW Directory="TARGETDIR" DefaultDir="SourceDir"/>
|
<ROW Directory="TARGETDIR" DefaultDir="SourceDir"/>
|
||||||
<ROW Directory="Troubleshooting_1_Dir" Directory_Parent="APPDIR" DefaultDir="TROUBL~1|Troubleshooting"/>
|
<ROW Directory="HelpandSupport_Dir" Directory_Parent="SHORTCUTDIR" DefaultDir="HELPAN~1|Help and Support"/>
|
||||||
<ROW Directory="Troubleshooting_Dir" Directory_Parent="SHORTCUTDIR" DefaultDir="TROUBL~1|Troubleshooting"/>
|
|
||||||
<ROW Directory="X64FeatureItems_Dir" Directory_Parent="APPDIR" DefaultDir=".:X64FEA~1|X64FeatureItems"/>
|
<ROW Directory="X64FeatureItems_Dir" Directory_Parent="APPDIR" DefaultDir=".:X64FEA~1|X64FeatureItems"/>
|
||||||
<ROW Directory="X86FeatureItems_Dir" Directory_Parent="APPDIR" DefaultDir=".:X86FEA~1|X86FeatureItems"/>
|
<ROW Directory="X86FeatureItems_Dir" Directory_Parent="APPDIR" DefaultDir=".:X86FEA~1|X86FeatureItems"/>
|
||||||
<ROW Directory="wufuc_Dir" Directory_Parent="CommonAppDataFolder" DefaultDir="wufuc"/>
|
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiCompsComponent">
|
||||||
<ROW Component="COPYING" ComponentId="{6CA1ECA7-4C30-4BD0-A5E8-6B3E5BCBE31D}" Directory_="APPDIR" Attributes="0" KeyPath="COPYING" Type="0"/>
|
<ROW Component="COPYING" ComponentId="{6CA1ECA7-4C30-4BD0-A5E8-6B3E5BCBE31D}" Directory_="APPDIR" Attributes="0" KeyPath="COPYING" Type="0"/>
|
||||||
<ROW Component="ProductInformation" ComponentId="{75030EAB-5C17-4F84-B529-28003271CA3F}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
|
<ROW Component="ProductInformation" ComponentId="{75030EAB-5C17-4F84-B529-28003271CA3F}" Directory_="APPDIR" Attributes="4" KeyPath="Version"/>
|
||||||
<ROW Component="Restore_wuauserv.reg" ComponentId="{5CE5C35B-6B0E-4EE4-B92C-7B1D9882DFC0}" Directory_="Troubleshooting_1_Dir" Attributes="0" KeyPath="Restore_wuauserv.reg" Type="0"/>
|
|
||||||
<ROW Component="SHORTCUTDIR" ComponentId="{910396A4-AFDD-4E57-BF00-2FDD4108AC61}" Directory_="SHORTCUTDIR" Attributes="0"/>
|
<ROW Component="SHORTCUTDIR" ComponentId="{910396A4-AFDD-4E57-BF00-2FDD4108AC61}" Directory_="SHORTCUTDIR" Attributes="0"/>
|
||||||
<ROW Component="Troubleshooting" ComponentId="{D4F7163C-0FD7-4862-BF97-F1693236500C}" Directory_="Troubleshooting_Dir" Attributes="0"/>
|
<ROW Component="Troubleshooting" ComponentId="{D4F7163C-0FD7-4862-BF97-F1693236500C}" Directory_="HelpandSupport_Dir" Attributes="0"/>
|
||||||
<ROW Component="X64FeatureItems" ComponentId="{0E189A37-1F40-4756-ACB9-6511067D5B47}" Directory_="X64FeatureItems_Dir" Attributes="0"/>
|
<ROW Component="X64FeatureItems" ComponentId="{0E189A37-1F40-4756-ACB9-6511067D5B47}" Directory_="X64FeatureItems_Dir" Attributes="0"/>
|
||||||
<ROW Component="X86FeatureItems" ComponentId="{CBB84726-9EC3-4570-9012-37BA98719022}" Directory_="X86FeatureItems_Dir" Attributes="0"/>
|
<ROW Component="X86FeatureItems" ComponentId="{CBB84726-9EC3-4570-9012-37BA98719022}" Directory_="X86FeatureItems_Dir" Attributes="0"/>
|
||||||
<ROW Component="wufuc" ComponentId="{331CB0F5-F6E7-4712-9F97-3609A0D5AFE6}" Directory_="wufuc_Dir" Attributes="0"/>
|
|
||||||
<ROW Component="wufuc32.dll" ComponentId="{7FBEF396-DCBC-4838-A4EB-336F74A836C7}" Directory_="APPDIR" Attributes="0" KeyPath="wufuc32.dll"/>
|
<ROW Component="wufuc32.dll" ComponentId="{7FBEF396-DCBC-4838-A4EB-336F74A836C7}" Directory_="APPDIR" Attributes="0" KeyPath="wufuc32.dll"/>
|
||||||
<ROW Component="wufuc64.dll" ComponentId="{0407D471-998A-4FD3-BC2D-72EE56FBEEF4}" Directory_="APPDIR" Attributes="256" KeyPath="wufuc64.dll"/>
|
<ROW Component="wufuc64.dll" ComponentId="{0407D471-998A-4FD3-BC2D-72EE56FBEEF4}" Directory_="APPDIR" Attributes="256" KeyPath="wufuc64.dll"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiFeatsComponent">
|
||||||
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="COPYING ProductInformation Restore_wuauserv.reg SHORTCUTDIR Troubleshooting wufuc"/>
|
<ROW Feature="MainFeature" Title="MainFeature" Description="Description" Display="1" Level="1" Directory_="APPDIR" Attributes="0" Components="COPYING ProductInformation SHORTCUTDIR Troubleshooting"/>
|
||||||
<ROW Feature="X64Feature" Feature_Parent="MainFeature" Title="X64Feature" Display="0" Level="1" Directory_="APPDIR" Attributes="0" Components="X64FeatureItems wufuc64.dll" Builds="x64Build"/>
|
<ROW Feature="X64Feature" Feature_Parent="MainFeature" Title="X64Feature" Display="0" Level="1" Directory_="APPDIR" Attributes="0" Components="X64FeatureItems wufuc64.dll" Builds="x64Build"/>
|
||||||
<ROW Feature="X86Feature" Feature_Parent="MainFeature" Title="X86Feature" Display="0" Level="1" Directory_="APPDIR" Attributes="0" Components="X86FeatureItems wufuc32.dll" Builds="x86Build"/>
|
<ROW Feature="X86Feature" Feature_Parent="MainFeature" Title="X86Feature" Display="0" Level="1" Directory_="APPDIR" Attributes="0" Components="X86FeatureItems wufuc32.dll" Builds="x86Build"/>
|
||||||
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
<ATTRIBUTE name="CurrentFeature" value="MainFeature"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiFilesComponent">
|
||||||
<ROW File="COPYING" Component_="COPYING" FileName="COPYING.txt" Attributes="0" SourcePath="..\..\COPYING" SelfReg="false" NextFile="Restore_wuauserv.reg"/>
|
<ROW File="COPYING" Component_="COPYING" FileName="COPYING.txt" Attributes="0" SourcePath="..\..\COPYING" SelfReg="false"/>
|
||||||
<ROW File="Restore_wuauserv.reg" Component_="Restore_wuauserv.reg" FileName="RESTOR~1.REG|Restore_wuauserv.reg" Attributes="0" SourcePath="..\wufuc_setup_bat\Restore_wuauserv.reg" SelfReg="false"/>
|
|
||||||
<ROW File="wufuc32.dll" Component_="wufuc32.dll" FileName="wufuc32.dll" Attributes="0" SourcePath="wufuc32.dll" SelfReg="false" NextFile="wufuc64.dll"/>
|
<ROW File="wufuc32.dll" Component_="wufuc32.dll" FileName="wufuc32.dll" Attributes="0" SourcePath="wufuc32.dll" SelfReg="false" NextFile="wufuc64.dll"/>
|
||||||
<ROW File="wufuc64.dll" Component_="wufuc64.dll" FileName="wufuc64.dll" Attributes="0" SourcePath="wufuc64.dll" SelfReg="false" NextFile="COPYING"/>
|
<ROW File="wufuc64.dll" Component_="wufuc64.dll" FileName="wufuc64.dll" Attributes="0" SourcePath="wufuc64.dll" SelfReg="false" NextFile="COPYING"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
@@ -80,10 +71,6 @@
|
|||||||
<ROW MsiShortcutProperty="Uninstallwufuc1" Shortcut_="Uninstallwufuc" PropertyKey="[AiPreventAutoPin]" PropVariantValue="1"/>
|
<ROW MsiShortcutProperty="Uninstallwufuc1" Shortcut_="Uninstallwufuc" PropertyKey="[AiPreventAutoPin]" PropVariantValue="1"/>
|
||||||
<ROW MsiShortcutProperty="License1" Shortcut_="License" PropertyKey="[AiPreventAutoPin]" PropVariantValue="1"/>
|
<ROW MsiShortcutProperty="License1" Shortcut_="License" PropertyKey="[AiPreventAutoPin]" PropVariantValue="1"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.AiRemoveFileComponent">
|
|
||||||
<ROW RemoveFile="log" Condition="(AI_CLEAN_RESOURCES_UNINSTALL = "1") AND (NOT UPGRADINGPRODUCTCODE)" Options="1"/>
|
|
||||||
<ROW RemoveFile="_" Condition="(AI_CLEAN_RESOURCES_UNINSTALL = "1") AND (NOT UPGRADINGPRODUCTCODE)" Options="0"/>
|
|
||||||
</COMPONENT>
|
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.BootstrOptComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.BootstrOptComponent">
|
||||||
<ROW BootstrOptKey="GlobalOptions" DownloadFolder="[AppDataFolder][|Manufacturer]\[|ProductName]\prerequisites" Options="2"/>
|
<ROW BootstrOptKey="GlobalOptions" DownloadFolder="[AppDataFolder][|Manufacturer]\[|ProductName]\prerequisites" Options="2"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
@@ -128,11 +115,6 @@
|
|||||||
<ROW Fragment="WelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\WelcomeDlg.aip"/>
|
<ROW Fragment="WelcomeDlg.aip" Path="<AI_THEMES>classic\fragments\WelcomeDlg.aip"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiActionTextComponent">
|
||||||
<ROW Action="AI_AiRemoveFilesCommit" Description="Executing file removal operations" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesCommit" Template="Executing file removal: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesCommit"/>
|
|
||||||
<ROW Action="AI_AiRemoveFilesDeferred_Permanent" Description="Preparing files for removal" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesDeferred_Permanent" Template="Preparing file: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesDeferred_Permanent"/>
|
|
||||||
<ROW Action="AI_AiRemoveFilesDeferred_Undoable" Description="Preparing files for removal" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesDeferred_Undoable" Template="Preparing file: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesDeferred_Undoable"/>
|
|
||||||
<ROW Action="AI_AiRemoveFilesImmediate" Description="Preparing files for removal" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesImmediate" Template="Preparing file: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesImmediate"/>
|
|
||||||
<ROW Action="AI_AiRemoveFilesRollback" Description="Restoring removed files" DescriptionLocId="ActionText.Description.AI_AiRemoveFilesRollback" Template="Restoring file: [1]" TemplateLocId="ActionText.Template.AI_AiRemoveFilesRollback"/>
|
|
||||||
<ROW Action="AI_XmlCommit" Description="Committing XML file configurations." DescriptionLocId="ActionText.Description.AI_XmlCommit" Template="Committing XML file configurations." TemplateLocId="ActionText.Template.AI_XmlCommit"/>
|
<ROW Action="AI_XmlCommit" Description="Committing XML file configurations." DescriptionLocId="ActionText.Description.AI_XmlCommit" Template="Committing XML file configurations." TemplateLocId="ActionText.Template.AI_XmlCommit"/>
|
||||||
<ROW Action="AI_XmlConfig" Description="Executing XML file configurations" DescriptionLocId="ActionText.Description.AI_XmlConfig" Template="Configuring XML file: "[1]"" TemplateLocId="ActionText.Template.AI_XmlConfig"/>
|
<ROW Action="AI_XmlConfig" Description="Executing XML file configurations" DescriptionLocId="ActionText.Description.AI_XmlConfig" Template="Configuring XML file: "[1]"" TemplateLocId="ActionText.Template.AI_XmlConfig"/>
|
||||||
<ROW Action="AI_XmlInstall" Description="Generating actions to configure XML files" DescriptionLocId="ActionText.Description.AI_XmlInstall"/>
|
<ROW Action="AI_XmlInstall" Description="Generating actions to configure XML files" DescriptionLocId="ActionText.Description.AI_XmlInstall"/>
|
||||||
@@ -143,7 +125,6 @@
|
|||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiBinaryComponent">
|
||||||
<ROW Name="AdvancedInstallerHelper.dll" SourcePath="AdvancedInstallerHelper.dll"/>
|
<ROW Name="AdvancedInstallerHelper.dll" SourcePath="AdvancedInstallerHelper.dll"/>
|
||||||
<ROW Name="Prereq.dll" SourcePath="<AI_CUSTACTS>Prereq.dll"/>
|
<ROW Name="Prereq.dll" SourcePath="<AI_CUSTACTS>Prereq.dll"/>
|
||||||
<ROW Name="ResourceCleaner.dll" SourcePath="<AI_CUSTACTS>ResourceCleaner.dll"/>
|
|
||||||
<ROW Name="ShortcutFlags.dll" SourcePath="<AI_CUSTACTS>ShortcutFlags.dll"/>
|
<ROW Name="ShortcutFlags.dll" SourcePath="<AI_CUSTACTS>ShortcutFlags.dll"/>
|
||||||
<ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/>
|
<ROW Name="aicustact.dll" SourcePath="<AI_CUSTACTS>aicustact.dll"/>
|
||||||
<ROW Name="viewer.exe" SourcePath="<AI_CUSTACTS>viewer.exe"/>
|
<ROW Name="viewer.exe" SourcePath="<AI_CUSTACTS>viewer.exe"/>
|
||||||
@@ -186,15 +167,9 @@
|
|||||||
<ROW Directory_="SHORTCUTDIR" Component_="SHORTCUTDIR" ManualDelete="false"/>
|
<ROW Directory_="SHORTCUTDIR" Component_="SHORTCUTDIR" ManualDelete="false"/>
|
||||||
<ROW Directory_="X86FeatureItems_Dir" Component_="X86FeatureItems" ManualDelete="false"/>
|
<ROW Directory_="X86FeatureItems_Dir" Component_="X86FeatureItems" ManualDelete="false"/>
|
||||||
<ROW Directory_="X64FeatureItems_Dir" Component_="X64FeatureItems" ManualDelete="false"/>
|
<ROW Directory_="X64FeatureItems_Dir" Component_="X64FeatureItems" ManualDelete="false"/>
|
||||||
<ROW Directory_="Troubleshooting_Dir" Component_="Troubleshooting" ManualDelete="false"/>
|
<ROW Directory_="HelpandSupport_Dir" Component_="Troubleshooting" ManualDelete="false"/>
|
||||||
<ROW Directory_="wufuc_Dir" Component_="wufuc" ManualDelete="true"/>
|
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiCustActComponent">
|
||||||
<ROW Action="AI_AiRemoveFilesCommit" Type="11777" Source="ResourceCleaner.dll" Target="OnAiRemoveFilesCommit" WithoutSeq="true"/>
|
|
||||||
<ROW Action="AI_AiRemoveFilesDeferred_Permanent" Type="11265" Source="ResourceCleaner.dll" Target="OnAiRemoveFilesPermanent" WithoutSeq="true"/>
|
|
||||||
<ROW Action="AI_AiRemoveFilesDeferred_Undoable" Type="11265" Source="ResourceCleaner.dll" Target="OnAiRemoveFilesUndoable" WithoutSeq="true"/>
|
|
||||||
<ROW Action="AI_AiRemoveFilesImmediate" Type="1" Source="ResourceCleaner.dll" Target="OnAiRemoveFilesImmediate"/>
|
|
||||||
<ROW Action="AI_AiRemoveFilesRollback" Type="11521" Source="ResourceCleaner.dll" Target="OnAiUndoRemoveFiles"/>
|
|
||||||
<ROW Action="AI_AppSearchEx" Type="1" Source="Prereq.dll" Target="DoAppSearchEx"/>
|
<ROW Action="AI_AppSearchEx" Type="1" Source="Prereq.dll" Target="DoAppSearchEx"/>
|
||||||
<ROW Action="AI_ApplyShortcutFlags" Type="3073" Source="ShortcutFlags.dll" Target="UpdateShortcutFlags" WithoutSeq="true"/>
|
<ROW Action="AI_ApplyShortcutFlags" Type="3073" Source="ShortcutFlags.dll" Target="UpdateShortcutFlags" WithoutSeq="true"/>
|
||||||
<ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH_ORIGINAL" Target="[AI_SETUPEXEPATH]"/>
|
<ROW Action="AI_BACKUP_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH_ORIGINAL" Target="[AI_SETUPEXEPATH]"/>
|
||||||
@@ -211,7 +186,6 @@
|
|||||||
<ROW Action="AI_PinToStartScreen" Type="1025" Source="ShortcutFlags.dll" Target="PinToStartScreen" WithoutSeq="true"/>
|
<ROW Action="AI_PinToStartScreen" Type="1025" Source="ShortcutFlags.dll" Target="PinToStartScreen" WithoutSeq="true"/>
|
||||||
<ROW Action="AI_PinToTaskbar" Type="1025" Source="ShortcutFlags.dll" Target="PinToTaskbar" WithoutSeq="true"/>
|
<ROW Action="AI_PinToTaskbar" Type="1025" Source="ShortcutFlags.dll" Target="PinToTaskbar" WithoutSeq="true"/>
|
||||||
<ROW Action="AI_PrepareShortcutFlags" Type="1" Source="ShortcutFlags.dll" Target="PrepareActionData"/>
|
<ROW Action="AI_PrepareShortcutFlags" Type="1" Source="ShortcutFlags.dll" Target="PrepareActionData"/>
|
||||||
<ROW Action="AI_PromptUserBasicUI" Type="1" Source="ResourceCleaner.dll" Target="OnPromptUserBasicUI"/>
|
|
||||||
<ROW Action="AI_RESTORE_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH" Target="[AI_SETUPEXEPATH_ORIGINAL]"/>
|
<ROW Action="AI_RESTORE_AI_SETUPEXEPATH" Type="51" Source="AI_SETUPEXEPATH" Target="[AI_SETUPEXEPATH_ORIGINAL]"/>
|
||||||
<ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
|
<ROW Action="AI_RESTORE_LOCATION" Type="65" Source="aicustact.dll" Target="RestoreLocation"/>
|
||||||
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/>
|
<ROW Action="AI_ResolveKnownFolders" Type="1" Source="aicustact.dll" Target="AI_ResolveKnownFolders"/>
|
||||||
@@ -235,24 +209,24 @@
|
|||||||
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="x64Build:[ProgramFiles64Folder]\[ProductName]#x86Build:[ProgramFilesFolder]\[ProductName]"/>
|
<ROW Action="SET_APPDIR" Type="307" Source="APPDIR" Target="[ProgramFilesFolder][Manufacturer]\[ProductName]" MultiBuildTarget="x64Build:[ProgramFiles64Folder]\[ProductName]#x86Build:[ProgramFilesFolder]\[ProductName]"/>
|
||||||
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
|
<ROW Action="SET_SHORTCUTDIR" Type="307" Source="SHORTCUTDIR" Target="[ProgramMenuFolder][ProductName]"/>
|
||||||
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
<ROW Action="SET_TARGETDIR_TO_APPDIR" Type="51" Source="TARGETDIR" Target="[APPDIR]"/>
|
||||||
<ROW Action="SetRebootProperty" Type="51" Source="REBOOT" Target="Force"/>
|
<ROW Action="StartWindowsUpdateService" Type="3137" Source="aicustact.dll" Target="StartWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_3"/>
|
||||||
<ROW Action="StartWindowsUpdateService" Type="3073" Source="aicustact.dll" Target="StartWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_3"/>
|
<ROW Action="StopWindowsUpdateService" Type="3137" Source="aicustact.dll" Target="StopWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_2"/>
|
||||||
<ROW Action="StopWindowsUpdateService" Type="3073" Source="aicustact.dll" Target="StopWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_2"/>
|
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiIconsComponent">
|
||||||
<ROW Name="msiexec.exe" SourcePath="..\..\..\..\..\..\..\Windows\System32\msiexec.exe" Index="0"/>
|
<ROW Name="msiexec.exe" SourcePath="..\..\..\..\..\..\..\Windows\System32\msiexec.exe" Index="0"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiIniFileComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiIniFileComponent">
|
||||||
|
<ROW IniFile="ServiceDll" FileName="RESTOR~1.REG|Restore_wuauserv.reg" DirProperty="APPDIR" Section="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\wuauserv\Parameters" Key=""ServiceDll"" Value="hex(2):25,00,73,00,79,00,73,00,74,00,65,00,6d,00,72,00,6f,00,6f,\" Action="0" Component_="ProductInformation"/>
|
||||||
<ROW IniFile="URL" FileName="Donate.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/blob/master/DONATE.md" Action="0" Component_="SHORTCUTDIR"/>
|
<ROW IniFile="URL" FileName="Donate.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/blob/master/DONATE.md" Action="0" Component_="SHORTCUTDIR"/>
|
||||||
<ROW IniFile="URL_2" FileName="Readme.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/blob/master/README.md" Action="0" Component_="SHORTCUTDIR"/>
|
<ROW IniFile="URL_2" FileName="WUFUCO~1.URL|wufuc on GitHub.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc" Action="0" Component_="SHORTCUTDIR"/>
|
||||||
<ROW IniFile="URL_6" FileName="LATEST~1.URL|Latest Release.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/releases/latest" Action="0" Component_="SHORTCUTDIR"/>
|
<ROW IniFile="URL_6" FileName="LATEST~1.URL|Latest release.url" DirProperty="HelpandSupport_Dir" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/releases/latest" Action="0" Component_="SHORTCUTDIR"/>
|
||||||
<ROW IniFile="URL_7" FileName="REPORT~1.URL|Report an Issue.url" DirProperty="Troubleshooting_Dir" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/issues" Action="0" Component_="SHORTCUTDIR"/>
|
<ROW IniFile="URL_7" FileName="REPORT~1.URL|Report an issue.url" DirProperty="HelpandSupport_Dir" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/issues" Action="0" Component_="SHORTCUTDIR"/>
|
||||||
<ROW IniFile="URL_8" FileName="FAQ.url" DirProperty="Troubleshooting_Dir" Section="InternetShortcut" Key="URL" Value="https://github.com/zeffy/wufuc/blob/master/FAQ.md" Action="0" Component_="SHORTCUTDIR"/>
|
|
||||||
<ROW IniFile="WorkingDirectory" FileName="Donate.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
<ROW IniFile="WorkingDirectory" FileName="Donate.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
||||||
<ROW IniFile="WorkingDirectory_2" FileName="Readme.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
<ROW IniFile="WorkingDirectory_2" FileName="WUFUCO~1.URL|wufuc on GitHub.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
||||||
<ROW IniFile="WorkingDirectory_6" FileName="LATEST~1.URL|Latest Release.url" DirProperty="SHORTCUTDIR" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
<ROW IniFile="WorkingDirectory_6" FileName="LATEST~1.URL|Latest release.url" DirProperty="HelpandSupport_Dir" Section="InternetShortcut" Key="WorkingDirectory" Value="[SHORTCUTDIR]" Action="0" Component_="SHORTCUTDIR"/>
|
||||||
<ROW IniFile="WorkingDirectory_7" FileName="REPORT~1.URL|Report an Issue.url" DirProperty="Troubleshooting_Dir" Section="InternetShortcut" Key="WorkingDirectory" Value="[Troubleshooting_Dir]" Action="0" Component_="SHORTCUTDIR"/>
|
<ROW IniFile="WorkingDirectory_7" FileName="REPORT~1.URL|Report an issue.url" DirProperty="HelpandSupport_Dir" Section="InternetShortcut" Key="WorkingDirectory" Value="[HelpandSupport_Dir]" Action="0" Component_="SHORTCUTDIR"/>
|
||||||
<ROW IniFile="WorkingDirectory_8" FileName="FAQ.url" DirProperty="Troubleshooting_Dir" Section="InternetShortcut" Key="WorkingDirectory" Value="[Troubleshooting_Dir]" Action="0" Component_="SHORTCUTDIR"/>
|
<ROW IniFile="c00730079007300740065006d0033003200" FileName="RESTOR~1.REG|Restore_wuauserv.reg" DirProperty="APPDIR" Section="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\wuauserv\Parameters" Key="00,74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,\" Value="00,74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,\" Action="0" Component_="ProductInformation"/>
|
||||||
|
<ROW IniFile="e0067002e0064006c006c000000" FileName="RESTOR~1.REG|Restore_wuauserv.reg" DirProperty="APPDIR" Section="HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\wuauserv\Parameters" Key="77,00,75,00,61,00,75,00,65,00,6e,00,67,00,2e,00,64,00,6c,00,6c,00,00,00" Value="77,00,75,00,61,00,75,00,65,00,6e,00,67,00,2e,00,64,00,6c,00,6c,00,00,00" Action="0" Component_="ProductInformation"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstExSeqComponent">
|
||||||
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/>
|
<ROW Action="AI_DOWNGRADE" Condition="AI_NEWERPRODUCTFOUND AND (UILevel <> 5)" Sequence="210"/>
|
||||||
@@ -277,12 +251,8 @@
|
|||||||
<ROW Action="RunScheduledTask" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE <> "ALL" AND AI_INSTALL_MODE <> "Remove" ) )" Sequence="5827"/>
|
<ROW Action="RunScheduledTask" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE <> "ALL" AND AI_INSTALL_MODE <> "Remove" ) )" Sequence="5827"/>
|
||||||
<ROW Action="RunSFCScan" Sequence="3603"/>
|
<ROW Action="RunSFCScan" Sequence="3603"/>
|
||||||
<ROW Action="AI_AppSearchEx" Sequence="101"/>
|
<ROW Action="AI_AppSearchEx" Sequence="101"/>
|
||||||
<ROW Action="SetRebootProperty" Condition="NONDEFAULT_SERVICEDLL" Sequence="201"/>
|
|
||||||
<ROW Action="StartWindowsUpdateService" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE <> "ALL" AND AI_INSTALL_MODE <> "Remove" ) )" Sequence="6402"/>
|
<ROW Action="StartWindowsUpdateService" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE <> "ALL" AND AI_INSTALL_MODE <> "Remove" ) )" Sequence="6402"/>
|
||||||
<ROW Action="AI_DATA_SETTER_3" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE <> "ALL" AND AI_INSTALL_MODE <> "Remove" ) )" Sequence="6401"/>
|
<ROW Action="AI_DATA_SETTER_3" Condition="( ( NOT Installed ) OR ( Installed AND REMOVE <> "ALL" AND AI_INSTALL_MODE <> "Remove" ) )" Sequence="6401"/>
|
||||||
<ROW Action="AI_AiRemoveFilesImmediate" Sequence="3499"/>
|
|
||||||
<ROW Action="AI_AiRemoveFilesRollback" Sequence="3099"/>
|
|
||||||
<ROW Action="AI_PromptUserBasicUI" Condition="((REMOVE = "ALL") AND (NOT UPGRADINGPRODUCTCODE))" Sequence="2501"/>
|
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiInstallUISequenceComponent">
|
||||||
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
<ROW Action="AI_RESTORE_LOCATION" Condition="APPDIR=""" Sequence="749"/>
|
||||||
@@ -307,13 +277,9 @@
|
|||||||
<ROW Registry="Path" Root="-1" Key="Software\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
|
<ROW Registry="Path" Root="-1" Key="Software\[ProductName]" Name="Path" Value="[APPDIR]" Component_="ProductInformation"/>
|
||||||
<ROW Registry="Version" Root="-1" Key="Software\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
|
<ROW Registry="Version" Root="-1" Key="Software\[ProductName]" Name="Version" Value="[ProductVersion]" Component_="ProductInformation"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiRemoveFileComponent">
|
|
||||||
<ROW FileKey="_" Component_="ProductInformation" DirProperty="wufuc_Dir" InstallMode="2"/>
|
|
||||||
<ROW FileKey="log" Component_="ProductInformation" FileName="*.log" DirProperty="wufuc_Dir" InstallMode="2"/>
|
|
||||||
</COMPONENT>
|
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiShortsComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiShortsComponent">
|
||||||
<ROW Shortcut="License" Directory_="SHORTCUTDIR" Name="License" Component_="COPYING" Target="[#COPYING]" Hotkey="0" IconIndex="0" ShowCmd="1" WkDir="APPDIR"/>
|
<ROW Shortcut="License" Directory_="SHORTCUTDIR" Name="License" Component_="COPYING" Target="[#COPYING]" Hotkey="0" IconIndex="0" ShowCmd="1" WkDir="APPDIR"/>
|
||||||
<ROW Shortcut="Openwufuclogfile" Directory_="Troubleshooting_Dir" Name="OPENWU~1|Open wufuc log file" Component_="Restore_wuauserv.reg" Target="[CommonAppDataFolder]wufuc\wufuc.log" Hotkey="0" IconIndex="0" ShowCmd="1"/>
|
<ROW Shortcut="Openwufuclogfile" Directory_="HelpandSupport_Dir" Name="OPENWU~1|Open wufuc log file" Component_="SHORTCUTDIR" Target="[CommonAppDataFolder]wufuc\wufuc.1.log" Hotkey="0" IconIndex="0" ShowCmd="1"/>
|
||||||
<ROW Shortcut="Uninstallwufuc" Directory_="SHORTCUTDIR" Name="UNINST~2|Uninstall [|ProductName]" Component_="ProductInformation" Target="[SystemFolder]msiexec.exe" Arguments="/x [ProductCode]" Hotkey="0" Icon_="msiexec.exe" IconIndex="0" ShowCmd="1" CustomFlags="1"/>
|
<ROW Shortcut="Uninstallwufuc" Directory_="SHORTCUTDIR" Name="UNINST~2|Uninstall [|ProductName]" Component_="ProductInformation" Target="[SystemFolder]msiexec.exe" Arguments="/x [ProductCode]" Hotkey="0" Icon_="msiexec.exe" IconIndex="0" ShowCmd="1" CustomFlags="1"/>
|
||||||
</COMPONENT>
|
</COMPONENT>
|
||||||
<COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent">
|
<COMPONENT cid="caphyon.advinst.msicomp.MsiThemeComponent">
|
5
src/setup_bat/Donate.url
Normal file
5
src/setup_bat/Donate.url
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[{000214A0-0000-0000-C000-000000000046}]
|
||||||
|
Prop3=19,11
|
||||||
|
[InternetShortcut]
|
||||||
|
URL=https://github.com/zeffy/wufuc/blob/master/DONATE.md
|
||||||
|
IDList=
|
5
src/setup_bat/Help and Support/Latest release.url
Normal file
5
src/setup_bat/Help and Support/Latest release.url
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[{000214A0-0000-0000-C000-000000000046}]
|
||||||
|
Prop3=19,11
|
||||||
|
[InternetShortcut]
|
||||||
|
URL=https://github.com/zeffy/wufuc/releases/latest
|
||||||
|
IDList=
|
5
src/setup_bat/Help and Support/Report an issue.url
Normal file
5
src/setup_bat/Help and Support/Report an issue.url
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[{000214A0-0000-0000-C000-000000000046}]
|
||||||
|
Prop3=19,11
|
||||||
|
[InternetShortcut]
|
||||||
|
URL=https://github.com/zeffy/wufuc/issues
|
||||||
|
IDList=
|
Binary file not shown.
5
src/setup_bat/wufuc on GitHub.url
Normal file
5
src/setup_bat/wufuc on GitHub.url
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
[{000214A0-0000-0000-C000-000000000046}]
|
||||||
|
Prop3=19,11
|
||||||
|
[InternetShortcut]
|
||||||
|
URL=https://github.com/zeffy/wufuc
|
||||||
|
IDList=
|
@@ -5,12 +5,6 @@ VisualStudioVersion = 15.0.27130.2036
|
|||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wufuc", "wufuc\wufuc.vcxproj", "{00F96695-CE41-4C2F-A344-6219DFB4F887}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "wufuc", "wufuc\wufuc.vcxproj", "{00F96695-CE41-4C2F-A344-6219DFB4F887}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "wufuc_setup_bat", "wufuc_setup_bat", "{97E33D3C-9AA1-4B84-803A-1A6AE2C6F361}"
|
|
||||||
ProjectSection(SolutionItems) = preProject
|
|
||||||
wufuc_setup_bat\install_wufuc.bat = wufuc_setup_bat\install_wufuc.bat
|
|
||||||
wufuc_setup_bat\uninstall_wufuc.bat = wufuc_setup_bat\uninstall_wufuc.bat
|
|
||||||
EndProjectSection
|
|
||||||
EndProject
|
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdvancedInstallerHelper", "AdvancedInstallerHelper\AdvancedInstallerHelper.vcxproj", "{12498D61-02AF-4C13-925D-E130EEDE2543}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AdvancedInstallerHelper", "AdvancedInstallerHelper\AdvancedInstallerHelper.vcxproj", "{12498D61-02AF-4C13-925D-E130EEDE2543}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Repository Items", "Repository Items", "{E7EDB493-4D31-4646-8537-C515613689A6}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Repository Items", "Repository Items", "{E7EDB493-4D31-4646-8537-C515613689A6}"
|
||||||
|
121
src/wufuc/asprintf.c
Normal file
121
src/wufuc/asprintf.c
Normal file
@@ -0,0 +1,121 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "asprintf.h"
|
||||||
|
#include <locale.h>
|
||||||
|
|
||||||
|
int asprintf(char **strp, char const *const fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
result = vasprintf(strp, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vasprintf(char **strp, char const *const fmt, va_list ap)
|
||||||
|
{
|
||||||
|
return vasprintf_l(strp, fmt, _get_current_locale(), ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int asprintf_l(char **strp, char const *const fmt, _locale_t locale, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
va_start(ap, locale);
|
||||||
|
result = vasprintf_l(strp, fmt, locale, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vasprintf_l(char **strp, char const *const fmt, _locale_t locale, va_list ap)
|
||||||
|
{
|
||||||
|
va_list copy;
|
||||||
|
int result;
|
||||||
|
char *str;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
va_copy(copy, ap);
|
||||||
|
result = _vscprintf(fmt, copy);
|
||||||
|
va_end(copy);
|
||||||
|
|
||||||
|
if ( result == -1 )
|
||||||
|
return result;
|
||||||
|
|
||||||
|
str = calloc(result + 1, sizeof *str);
|
||||||
|
if ( !str )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
va_copy(copy, ap);
|
||||||
|
ret = _vsprintf_s_l(str, result + 1, fmt, locale, copy);
|
||||||
|
va_end(copy);
|
||||||
|
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
free(str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*strp = str;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int aswprintf(wchar_t **strp, wchar_t const *const fmt, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
va_start(ap, fmt);
|
||||||
|
result = vaswprintf(strp, fmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vaswprintf(wchar_t **strp, wchar_t const *const fmt, va_list ap)
|
||||||
|
{
|
||||||
|
return vaswprintf_l(strp, fmt, _get_current_locale(), ap);
|
||||||
|
}
|
||||||
|
|
||||||
|
int aswprintf_l(wchar_t **strp, wchar_t const *const fmt, _locale_t locale, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int result;
|
||||||
|
|
||||||
|
va_start(ap, locale);
|
||||||
|
result = vaswprintf_l(strp, fmt, locale, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vaswprintf_l(wchar_t **strp, wchar_t const *const fmt, _locale_t locale, va_list ap)
|
||||||
|
{
|
||||||
|
va_list copy;
|
||||||
|
int result;
|
||||||
|
wchar_t *str;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
va_copy(copy, ap);
|
||||||
|
result = _vscwprintf_l(fmt, locale, copy);
|
||||||
|
va_end(copy);
|
||||||
|
|
||||||
|
if ( result == -1 )
|
||||||
|
return result;
|
||||||
|
|
||||||
|
str = calloc(result + 1, sizeof *str);
|
||||||
|
if ( !str )
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
va_copy(copy, ap);
|
||||||
|
ret = _vswprintf_s_l(str, result + 1, fmt, locale, copy);
|
||||||
|
va_end(copy);
|
||||||
|
|
||||||
|
if ( ret == -1 ) {
|
||||||
|
free(str);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*strp = str;
|
||||||
|
return result;
|
||||||
|
}
|
17
src/wufuc/asprintf.h
Normal file
17
src/wufuc/asprintf.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
int asprintf(char **strp, char const *const fmt, ...);
|
||||||
|
|
||||||
|
int vasprintf(char **strp, char const *const fmt, va_list ap);
|
||||||
|
|
||||||
|
int asprintf_l(char **strp, char const *const fmt, _locale_t locale, ...);
|
||||||
|
|
||||||
|
int vasprintf_l(char **strp, char const *const fmt, _locale_t locale, va_list ap);
|
||||||
|
|
||||||
|
int aswprintf(wchar_t **strp, wchar_t const *const fmt, ...);
|
||||||
|
|
||||||
|
int vaswprintf(wchar_t **strp, wchar_t const *const fmt, va_list ap);
|
||||||
|
|
||||||
|
int aswprintf_l(wchar_t **strp, wchar_t const *const fmt, _locale_t locale, ...);
|
||||||
|
|
||||||
|
int vaswprintf_l(wchar_t **strp, wchar_t const *const fmt, _locale_t locale, va_list ap);
|
@@ -1,165 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "callbacks.h"
|
|
||||||
#include "hooks.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "modulehelper.h"
|
|
||||||
#include "registryhelper.h"
|
|
||||||
#include "servicehelper.h"
|
|
||||||
#include "versionhelper.h"
|
|
||||||
#include "ptrlist.h"
|
|
||||||
#include "wufuc.h"
|
|
||||||
|
|
||||||
#include <VersionHelpers.h>
|
|
||||||
#include <minhook.h>
|
|
||||||
|
|
||||||
VOID CALLBACK cb_service_notify(PSERVICE_NOTIFYW pNotifyBuffer)
|
|
||||||
{
|
|
||||||
switch ( pNotifyBuffer->dwNotificationStatus ) {
|
|
||||||
case ERROR_SUCCESS:
|
|
||||||
if ( pNotifyBuffer->ServiceStatus.dwProcessId )
|
|
||||||
wufuc_inject(
|
|
||||||
pNotifyBuffer->ServiceStatus.dwProcessId,
|
|
||||||
(LPTHREAD_START_ROUTINE)cb_start,
|
|
||||||
(ptrlist_t *)pNotifyBuffer->pContext);
|
|
||||||
break;
|
|
||||||
case ERROR_SERVICE_MARKED_FOR_DELETE:
|
|
||||||
SetEvent(ptrlist_at((ptrlist_t *)pNotifyBuffer->pContext, 0, NULL));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if ( pNotifyBuffer->pszServiceNames )
|
|
||||||
LocalFree((HLOCAL)pNotifyBuffer->pszServiceNames);
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI cb_start(HANDLE *pParam)
|
|
||||||
{
|
|
||||||
HANDLE handles[2];
|
|
||||||
HANDLE hCrashMutex;
|
|
||||||
HANDLE hProceedEvent;
|
|
||||||
SC_HANDLE hSCM;
|
|
||||||
SC_HANDLE hService;
|
|
||||||
DWORD dwProcessId;
|
|
||||||
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
|
||||||
DWORD dwServiceType;
|
|
||||||
const wchar_t szKernel32Dll[] = L"kernel32.dll";
|
|
||||||
const wchar_t szKernelBaseDll[] = L"KernelBase.dll";
|
|
||||||
const wchar_t *pszModule;
|
|
||||||
MH_STATUS status;
|
|
||||||
int tmp;
|
|
||||||
LPVOID pv1 = NULL;
|
|
||||||
LPVOID pv2 = NULL;
|
|
||||||
wchar_t *str;
|
|
||||||
HMODULE hModule;
|
|
||||||
|
|
||||||
if ( !pParam ) {
|
|
||||||
log_error(L"Parameter argument is null!");
|
|
||||||
goto unload;
|
|
||||||
}
|
|
||||||
handles[0] = pParam[0]; // main mutex
|
|
||||||
handles[1] = pParam[1]; // unload event
|
|
||||||
hCrashMutex = pParam[2]; // crash mutex
|
|
||||||
hProceedEvent = pParam[3]; // proceed event
|
|
||||||
if ( !VirtualFree(pParam, 0, MEM_RELEASE) )
|
|
||||||
log_warning(L"VirtualFree failed! (lpAddress=%p, GLE=%lu)", pParam, GetLastError());
|
|
||||||
|
|
||||||
// acquire child mutex, this should be immediate.
|
|
||||||
if ( WaitForSingleObject(hCrashMutex, 5000) != WAIT_OBJECT_0 ) {
|
|
||||||
log_error(L"Failed to acquire child mutex within five seconds. (%p)", hCrashMutex);
|
|
||||||
goto close_handles;
|
|
||||||
}
|
|
||||||
SetEvent(hProceedEvent);
|
|
||||||
CloseHandle(hProceedEvent);
|
|
||||||
|
|
||||||
hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_CONNECT);
|
|
||||||
if ( !hSCM ) {
|
|
||||||
log_error(L"Failed to open SCM. (GetLastError=%lu)", GetLastError());
|
|
||||||
goto release;
|
|
||||||
}
|
|
||||||
hService = OpenServiceW(hSCM, L"wuauserv", SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
|
|
||||||
dwProcessId = svc_heuristic_process_id(hSCM, hService);
|
|
||||||
pServiceConfig = svc_query_config_alloc(hSCM, hService, NULL);
|
|
||||||
dwServiceType = pServiceConfig->dwServiceType;
|
|
||||||
tmp = _wcsicmp(pServiceConfig->lpBinaryPathName, GetCommandLineW());
|
|
||||||
free(pServiceConfig);
|
|
||||||
CloseServiceHandle(hService);
|
|
||||||
CloseServiceHandle(hSCM);
|
|
||||||
|
|
||||||
if ( tmp || dwProcessId != GetCurrentProcessId() ) {
|
|
||||||
log_error(L"Injected into wrong process!");
|
|
||||||
goto release;
|
|
||||||
}
|
|
||||||
if ( !ver_verify_version_info(6, 1, 0) && !ver_verify_version_info(6, 3, 0) ) {
|
|
||||||
log_error(L"Unsupported operating system!");
|
|
||||||
goto release;
|
|
||||||
}
|
|
||||||
if ( dwServiceType == SERVICE_WIN32_SHARE_PROCESS ) {
|
|
||||||
// assume wuaueng.dll hasn't been loaded yet, apply
|
|
||||||
// RegQueryValueExW hook to fix incompatibility with
|
|
||||||
// UpdatePack7R2 and other patches that modify the
|
|
||||||
// Windows Update ServiceDll path in the registry.
|
|
||||||
pszModule = IsWindows8OrGreater()
|
|
||||||
? szKernelBaseDll
|
|
||||||
: szKernel32Dll;
|
|
||||||
status = MH_CreateHookApiEx(pszModule,
|
|
||||||
"RegQueryValueExW",
|
|
||||||
RegQueryValueExW_hook,
|
|
||||||
&(PVOID)g_pfnRegQueryValueExW,
|
|
||||||
&pv1);
|
|
||||||
if ( status == MH_OK ) {
|
|
||||||
status = MH_EnableHook(pv1);
|
|
||||||
if ( status == MH_OK )
|
|
||||||
log_info(L"Hooked RegQueryValueExW! (Module=%ls, Address=%p)", pszModule, pv1);
|
|
||||||
else log_error(L"Failed to enable RegQueryValueExW hook! (Status=%hs)", MH_StatusToString(status));
|
|
||||||
} else log_error(L"Failed to create RegQueryValueExW hook! (Status=%hs)", MH_StatusToString(status));
|
|
||||||
}
|
|
||||||
// query the ServiceDll path after applying our compat hook so that it
|
|
||||||
// is correct
|
|
||||||
str = (wchar_t *)reg_query_value_alloc(HKEY_LOCAL_MACHINE,
|
|
||||||
L"SYSTEM\\CurrentControlSet\\services\\wuauserv\\Parameters",
|
|
||||||
L"ServiceDll", NULL, NULL);
|
|
||||||
if ( !str ) {
|
|
||||||
abort_hook:
|
|
||||||
if ( pv1 )
|
|
||||||
MH_RemoveHook(pv1);
|
|
||||||
goto release;
|
|
||||||
}
|
|
||||||
g_pszWUServiceDll = env_expand_strings_alloc(str, NULL);
|
|
||||||
free(str);
|
|
||||||
if ( !g_pszWUServiceDll ) goto abort_hook;
|
|
||||||
|
|
||||||
status = MH_CreateHookApiEx(szKernelBaseDll,
|
|
||||||
"LoadLibraryExW",
|
|
||||||
LoadLibraryExW_hook,
|
|
||||||
&(PVOID)g_pfnLoadLibraryExW,
|
|
||||||
&pv2);
|
|
||||||
if ( status == MH_OK ) {
|
|
||||||
status = MH_EnableHook(pv2);
|
|
||||||
if ( status == MH_OK )
|
|
||||||
log_info(L"Hooked LoadLibraryExW! (Module=%ls, Address=%p)", szKernelBaseDll, pv2);
|
|
||||||
else log_error(L"Failed to enable LoadLibraryExW hook! (Status=%hs)", MH_StatusToString(status));
|
|
||||||
} else log_error(L"Failed to create LoadLibraryExW hook! (Status=%hs)", MH_StatusToString(status));
|
|
||||||
|
|
||||||
if ( GetModuleHandleExW(0, g_pszWUServiceDll, &hModule)
|
|
||||||
|| GetModuleHandleExW(0, PathFindFileNameW(g_pszWUServiceDll), &hModule) ) {
|
|
||||||
|
|
||||||
// hook IsDeviceServiceable if wuaueng.dll is already loaded
|
|
||||||
wufuc_hook(hModule);
|
|
||||||
FreeLibrary(hModule);
|
|
||||||
}
|
|
||||||
// wait for unload event or the main mutex to be released or abandoned,
|
|
||||||
// for example if the user killed rundll32.exe with task manager.
|
|
||||||
WaitForMultipleObjects(_countof(handles), handles, FALSE, INFINITE);
|
|
||||||
log_info(L"Unload condition has been met.");
|
|
||||||
|
|
||||||
MH_DisableHook(MH_ALL_HOOKS);
|
|
||||||
free(g_pszWUServiceDll);
|
|
||||||
release:
|
|
||||||
ReleaseMutex(hCrashMutex);
|
|
||||||
close_handles:
|
|
||||||
CloseHandle(hCrashMutex);
|
|
||||||
CloseHandle(handles[0]);
|
|
||||||
CloseHandle(handles[1]);
|
|
||||||
unload:
|
|
||||||
log_info(L"Unloading wufuc and exiting thread.");
|
|
||||||
FreeLibraryAndExitThread(PIMAGEBASE, 0);
|
|
||||||
}
|
|
||||||
|
|
@@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
VOID CALLBACK cb_service_notify(PSERVICE_NOTIFYW pNotifyBuffer);
|
|
||||||
DWORD WINAPI cb_start(HANDLE *pParam);
|
|
@@ -1,7 +1,4 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include <minhook.h>
|
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE hModule,
|
BOOL APIENTRY DllMain(HMODULE hModule,
|
||||||
DWORD ul_reason_for_call,
|
DWORD ul_reason_for_call,
|
||||||
@@ -9,13 +6,11 @@ BOOL APIENTRY DllMain(HMODULE hModule,
|
|||||||
{
|
{
|
||||||
switch ( ul_reason_for_call ) {
|
switch ( ul_reason_for_call ) {
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
MH_Initialize();
|
|
||||||
break;
|
|
||||||
case DLL_THREAD_ATTACH:
|
case DLL_THREAD_ATTACH:
|
||||||
case DLL_THREAD_DETACH:
|
case DLL_THREAD_DETACH:
|
||||||
break;
|
break;
|
||||||
case DLL_PROCESS_DETACH:
|
case DLL_PROCESS_DETACH:
|
||||||
MH_Uninitialize();
|
if ( !lpReserved )
|
||||||
log_close();
|
log_close();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@@ -1,23 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "eventhelper.h"
|
|
||||||
|
|
||||||
#include <sddl.h>
|
|
||||||
|
|
||||||
HANDLE event_create_with_string_security_descriptor(
|
|
||||||
bool ManualReset,
|
|
||||||
bool InitialState,
|
|
||||||
const wchar_t *Name,
|
|
||||||
const wchar_t *StringSecurityDescriptor)
|
|
||||||
{
|
|
||||||
SECURITY_ATTRIBUTES sa = { sizeof sa };
|
|
||||||
|
|
||||||
if ( ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
|
||||||
StringSecurityDescriptor,
|
|
||||||
SDDL_REVISION_1,
|
|
||||||
&sa.lpSecurityDescriptor,
|
|
||||||
NULL) ) {
|
|
||||||
|
|
||||||
return CreateEventW(&sa, ManualReset, InitialState, Name);
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@@ -1,7 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
HANDLE event_create_with_string_security_descriptor(
|
|
||||||
bool ManualReset,
|
|
||||||
bool InitialState,
|
|
||||||
const wchar_t *Name,
|
|
||||||
const wchar_t *StringSecurityDescriptor);
|
|
54
src/wufuc/helpers.c
Normal file
54
src/wufuc/helpers.c
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "helpers.h"
|
||||||
|
#include <sddl.h>
|
||||||
|
|
||||||
|
HANDLE CreateEventWithStringSecurityDescriptor(
|
||||||
|
LPCWSTR lpStringSecurityDescriptor,
|
||||||
|
BOOL bManualReset,
|
||||||
|
BOOL bInitialState,
|
||||||
|
LPCWSTR lpName)
|
||||||
|
{
|
||||||
|
SECURITY_ATTRIBUTES sa = { sizeof sa };
|
||||||
|
|
||||||
|
if ( ConvertStringSecurityDescriptorToSecurityDescriptorW(
|
||||||
|
lpStringSecurityDescriptor,
|
||||||
|
SDDL_REVISION_1,
|
||||||
|
&sa.lpSecurityDescriptor,
|
||||||
|
NULL) ) {
|
||||||
|
return CreateEventW(&sa, bManualReset, bInitialState, lpName);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE CreateNewMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
|
||||||
|
{
|
||||||
|
HANDLE result;
|
||||||
|
|
||||||
|
result = CreateMutexW(lpMutexAttributes, bInitialOwner, lpName);
|
||||||
|
if ( result ) {
|
||||||
|
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
|
||||||
|
CloseHandle(result);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL VerifyVersionInfoHelper(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
|
||||||
|
{
|
||||||
|
DWORDLONG dwlConditionMask = 0;
|
||||||
|
OSVERSIONINFOEXW osvi = { sizeof osvi };
|
||||||
|
|
||||||
|
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);
|
||||||
|
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL);
|
||||||
|
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
||||||
|
|
||||||
|
osvi.dwMajorVersion = wMajorVersion;
|
||||||
|
osvi.dwMinorVersion = wMinorVersion;
|
||||||
|
osvi.wServicePackMajor = wServicePackMajor;
|
||||||
|
|
||||||
|
return VerifyVersionInfoW(&osvi,
|
||||||
|
VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
|
||||||
|
dwlConditionMask);
|
||||||
|
}
|
11
src/wufuc/helpers.h
Normal file
11
src/wufuc/helpers.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
HANDLE CreateNewMutex(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName);
|
||||||
|
|
||||||
|
HANDLE CreateEventWithStringSecurityDescriptor(
|
||||||
|
LPCWSTR lpStringSecurityDescriptor,
|
||||||
|
BOOL bManualReset,
|
||||||
|
BOOL bInitialState,
|
||||||
|
LPCWSTR lpName);
|
||||||
|
|
||||||
|
BOOL VerifyVersionInfoHelper(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor);
|
@@ -1,100 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "hooks.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "registryhelper.h"
|
|
||||||
#include "ptrlist.h"
|
|
||||||
#include "wufuc.h"
|
|
||||||
|
|
||||||
wchar_t *g_pszWUServiceDll;
|
|
||||||
|
|
||||||
LPFN_REGQUERYVALUEEXW g_pfnRegQueryValueExW;
|
|
||||||
LPFN_LOADLIBRARYEXW g_pfnLoadLibraryExW;
|
|
||||||
LPFN_ISDEVICESERVICEABLE g_pfnIsDeviceServiceable;
|
|
||||||
|
|
||||||
LSTATUS WINAPI RegQueryValueExW_hook(HKEY hKey, LPCWSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, LPBYTE lpData, LPDWORD lpcbData)
|
|
||||||
{
|
|
||||||
wchar_t *pBuffer;
|
|
||||||
DWORD MaximumLength = 0;
|
|
||||||
LSTATUS result;
|
|
||||||
ULONG ResultLength;
|
|
||||||
PKEY_NAME_INFORMATION pkni;
|
|
||||||
size_t NameCount;
|
|
||||||
unsigned int current;
|
|
||||||
int pos;
|
|
||||||
wchar_t *fname;
|
|
||||||
const wchar_t realpath[] = L"%systemroot%\\system32\\wuaueng.dll";
|
|
||||||
wchar_t *expandedpath;
|
|
||||||
DWORD cchLength;
|
|
||||||
|
|
||||||
// save original buffer size
|
|
||||||
if ( lpData && lpcbData )
|
|
||||||
MaximumLength = *lpcbData;
|
|
||||||
result = g_pfnRegQueryValueExW(hKey, lpValueName, lpReserved, lpType, lpData, lpcbData);
|
|
||||||
|
|
||||||
if ( result != ERROR_SUCCESS
|
|
||||||
|| !MaximumLength
|
|
||||||
|| !lpValueName
|
|
||||||
|| (lpType && *lpType != REG_EXPAND_SZ)
|
|
||||||
|| _wcsicmp(lpValueName, L"ServiceDll") )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
pBuffer = (wchar_t *)lpData;
|
|
||||||
|
|
||||||
// get name of registry key being queried
|
|
||||||
pkni = reg_query_key_alloc((HANDLE)hKey, KeyNameInformation, &ResultLength);
|
|
||||||
if ( !pkni )
|
|
||||||
return result;
|
|
||||||
NameCount = pkni->NameLength / sizeof *pkni->Name;
|
|
||||||
|
|
||||||
// change key name to lower-case because there is no case-insensitive version of _snwscanf_s
|
|
||||||
for ( size_t i = 0; i < NameCount; i++ )
|
|
||||||
pkni->Name[i] = towlower(pkni->Name[i]);
|
|
||||||
|
|
||||||
if ( _snwscanf_s(pkni->Name, NameCount, L"\\registry\\machine\\system\\controlset%03u\\services\\wuauserv\\parameters%n", ¤t, &pos) == 1
|
|
||||||
&& pos == NameCount ) {
|
|
||||||
|
|
||||||
fname = PathFindFileNameW(pBuffer);
|
|
||||||
|
|
||||||
if ( (!_wcsicmp(fname, L"wuaueng2.dll") // UpdatePack7R2
|
|
||||||
|| !_wcsicmp(fname, L"WuaCpuFix64.dll") // WuaCpuFix
|
|
||||||
|| !_wcsicmp(fname, L"WuaCpuFix.dll")) ) {
|
|
||||||
|
|
||||||
expandedpath = env_expand_strings_alloc(realpath, &cchLength);
|
|
||||||
if ( expandedpath ) {
|
|
||||||
if ( PathFileExistsW(expandedpath)
|
|
||||||
&& SUCCEEDED(StringCbCopyW(pBuffer, MaximumLength, expandedpath)) ) {
|
|
||||||
|
|
||||||
*lpcbData = cchLength * (sizeof *expandedpath);
|
|
||||||
log_info(L"Fixed path to Windows Update service library.");
|
|
||||||
}
|
|
||||||
free(expandedpath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(pkni);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
HMODULE WINAPI LoadLibraryExW_hook(LPCWSTR lpFileName, HANDLE hFile, DWORD dwFlags)
|
|
||||||
{
|
|
||||||
HMODULE result;
|
|
||||||
|
|
||||||
result = g_pfnLoadLibraryExW(lpFileName, hFile, dwFlags);
|
|
||||||
if ( !result ) return result;
|
|
||||||
log_debug(L"Loaded library: %ls (%p)", lpFileName, result);
|
|
||||||
|
|
||||||
if ( dwFlags == LOAD_WITH_ALTERED_SEARCH_PATH
|
|
||||||
&& g_pszWUServiceDll
|
|
||||||
&& (!_wcsicmp(lpFileName, g_pszWUServiceDll)
|
|
||||||
|| !_wcsicmp(lpFileName, PathFindFileNameW(g_pszWUServiceDll))) ) {
|
|
||||||
|
|
||||||
wufuc_hook(result);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL WINAPI IsDeviceServiceable_hook(void)
|
|
||||||
{
|
|
||||||
log_debug(L"Entered stub function.");
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
typedef LSTATUS(WINAPI *LPFN_REGQUERYVALUEEXW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
|
|
||||||
typedef HMODULE(WINAPI *LPFN_LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
|
|
||||||
typedef BOOL(WINAPI *LPFN_ISDEVICESERVICEABLE)(void);
|
|
||||||
|
|
||||||
extern wchar_t *g_pszWUServiceDll;
|
|
||||||
|
|
||||||
extern LPFN_REGQUERYVALUEEXW g_pfnRegQueryValueExW;
|
|
||||||
extern LPFN_LOADLIBRARYEXW g_pfnLoadLibraryExW;
|
|
||||||
extern LPFN_ISDEVICESERVICEABLE g_pfnIsDeviceServiceable;
|
|
||||||
|
|
||||||
extern PVOID g_ptRegQueryValueExW;
|
|
||||||
extern PVOID g_ptLoadLibraryExW;
|
|
||||||
extern PVOID g_ptIsDeviceServiceable;
|
|
||||||
|
|
||||||
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);
|
|
||||||
BOOL WINAPI IsDeviceServiceable_hook(void);
|
|
153
src/wufuc/log.c
153
src/wufuc/log.c
@@ -1,153 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include <ShlObj.h>
|
|
||||||
|
|
||||||
HANDLE m_hFile = INVALID_HANDLE_VALUE;
|
|
||||||
|
|
||||||
BOOL CALLBACK init_file_handle(
|
|
||||||
PINIT_ONCE pInitOnce,
|
|
||||||
ParamData *pParam,
|
|
||||||
PVOID *ppContext)
|
|
||||||
{
|
|
||||||
BOOL result = FALSE;
|
|
||||||
HANDLE hFile;
|
|
||||||
HRESULT hr;
|
|
||||||
wchar_t *pszPath;
|
|
||||||
wchar_t szFilePath[MAX_PATH];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
pParam->dwProcessId = GetCurrentProcessId();
|
|
||||||
if ( !GetModuleFileNameW(NULL, pParam->szExeFilePath, _countof(pParam->szExeFilePath)) ) {
|
|
||||||
log_debug(L"GetModuleFileNameW failed! (GLE=%lu)", GetLastError());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
pParam->pszExeName = PathFindFileNameW(pParam->szExeFilePath);
|
|
||||||
|
|
||||||
hr = SHGetKnownFolderPath(&FOLDERID_ProgramData, 0, NULL, &pszPath);
|
|
||||||
if ( hr != S_OK ) {
|
|
||||||
log_debug(L"SHGetKnownFolderPath failed! (HRESULT=0x%08X)", hr);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
ret = wcscpy_s(szFilePath, _countof(szFilePath), pszPath);
|
|
||||||
CoTaskMemFree(pszPath);
|
|
||||||
if ( ret ) {
|
|
||||||
log_debug(L"wcscpy_s failed! (Return value=%d)", ret);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( !PathAppendW(szFilePath, L"wufuc") ) {
|
|
||||||
append_fail:
|
|
||||||
log_debug(L"PathAppendW failed!");
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if ( !CreateDirectoryW(szFilePath, NULL)
|
|
||||||
&& GetLastError() != ERROR_ALREADY_EXISTS ) {
|
|
||||||
|
|
||||||
log_debug(L"CreateDirectoryW failed! (GLE=%lu)", GetLastError());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
if ( !PathAppendW(szFilePath, L"wufuc.log") )
|
|
||||||
goto append_fail;
|
|
||||||
|
|
||||||
hFile = CreateFileW(szFilePath,
|
|
||||||
FILE_APPEND_DATA,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
||||||
NULL,
|
|
||||||
OPEN_ALWAYS,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if ( hFile != INVALID_HANDLE_VALUE ) {
|
|
||||||
*ppContext = (PVOID)hFile;
|
|
||||||
result = TRUE;
|
|
||||||
} else {
|
|
||||||
log_debug(L"CreateFileW failed! (GLE=%lu)", GetLastError());
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_debug_(const wchar_t *const format, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
wchar_t *buf;
|
|
||||||
int ret;
|
|
||||||
int count;
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
count = _vscwprintf(format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if ( count == -1 ) return;
|
|
||||||
|
|
||||||
buf = calloc(count + 1, sizeof *buf);
|
|
||||||
if ( !buf ) return;
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
ret = vswprintf_s(buf, count + 1, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if ( ret != -1 )
|
|
||||||
OutputDebugStringW(buf);
|
|
||||||
free(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_trace_(const wchar_t *const format, ...)
|
|
||||||
{
|
|
||||||
static INIT_ONCE InitOnce = INIT_ONCE_STATIC_INIT;
|
|
||||||
static ParamData data;
|
|
||||||
BOOL bStatus;
|
|
||||||
errno_t e;
|
|
||||||
wchar_t datebuf[9];
|
|
||||||
wchar_t timebuf[9];
|
|
||||||
va_list ap;
|
|
||||||
const wchar_t fmt[] = L"%ls %ls [%ls:%lu] %ls";
|
|
||||||
int count;
|
|
||||||
wchar_t *buf1;
|
|
||||||
int ret;
|
|
||||||
wchar_t *buf2;
|
|
||||||
DWORD written;
|
|
||||||
|
|
||||||
bStatus = InitOnceExecuteOnce(&InitOnce,
|
|
||||||
(PINIT_ONCE_FN)init_file_handle,
|
|
||||||
&data,
|
|
||||||
&(LPVOID)m_hFile);
|
|
||||||
|
|
||||||
e = _wstrdate_s(datebuf, _countof(datebuf));
|
|
||||||
if ( e ) return;
|
|
||||||
e = _wstrtime_s(timebuf, _countof(timebuf));
|
|
||||||
if ( e ) return;
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
count = _vscwprintf(format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if ( count == -1 ) return;
|
|
||||||
|
|
||||||
buf1 = calloc(count + 1, sizeof *buf1);
|
|
||||||
if ( !buf1 ) return;
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
ret = vswprintf_s(buf1, count + 1, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if ( ret == -1 ) goto free_buf1;
|
|
||||||
|
|
||||||
count = _scwprintf(fmt, datebuf, timebuf, data.pszExeName, data.dwProcessId, buf1);
|
|
||||||
if ( count == -1 ) goto free_buf1;
|
|
||||||
|
|
||||||
buf2 = calloc(count + 1, sizeof *buf2);
|
|
||||||
if ( !buf2 ) goto free_buf1;
|
|
||||||
|
|
||||||
ret = swprintf_s(buf2, count + 1, fmt, datebuf, timebuf, data.pszExeName, data.dwProcessId, buf1);
|
|
||||||
if ( ret == -1 ) goto free_buf2;
|
|
||||||
|
|
||||||
if ( !bStatus || !WriteFile(m_hFile, buf2, count * (sizeof *buf2), &written, NULL) )
|
|
||||||
OutputDebugStringW(buf2);
|
|
||||||
free_buf2:
|
|
||||||
free(buf2);
|
|
||||||
free_buf1:
|
|
||||||
free(buf1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_close(void)
|
|
||||||
{
|
|
||||||
if ( m_hFile != INVALID_HANDLE_VALUE )
|
|
||||||
CloseHandle(m_hFile);
|
|
||||||
}
|
|
@@ -1,17 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
DWORD dwProcessId;
|
|
||||||
wchar_t szExeFilePath[MAX_PATH];
|
|
||||||
wchar_t *pszExeName;
|
|
||||||
} ParamData;
|
|
||||||
|
|
||||||
void log_debug_(const wchar_t *const format, ...);
|
|
||||||
void log_trace_(const wchar_t *const format, ...);
|
|
||||||
void log_close(void);
|
|
||||||
|
|
||||||
#define log_debug(format, ...) log_debug_(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): [DEBUG] " format L"\r\n", ##__VA_ARGS__)
|
|
||||||
#define log_info(format, ...) log_trace_(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): [INFO] " format L"\r\n", ##__VA_ARGS__)
|
|
||||||
#define log_warning(format, ...) log_trace_(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): [WARNING] " format L"\r\n", ##__VA_ARGS__)
|
|
||||||
#define log_error(format, ...) log_trace_(__FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): [ERROR] " format L"\r\n", ##__VA_ARGS__)
|
|
109
src/wufuc/logger.c
Normal file
109
src/wufuc/logger.c
Normal file
@@ -0,0 +1,109 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "logger.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
#include <ShlObj.h>
|
||||||
|
|
||||||
|
static WCHAR s_szExeFilePath[MAX_PATH];
|
||||||
|
static LPWSTR s_pszExeFileName;
|
||||||
|
static HANDLE s_hFile = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
|
static BOOL CALLBACK init_once_callback(
|
||||||
|
PINIT_ONCE InitOnce,
|
||||||
|
PVOID *Parameter,
|
||||||
|
PVOID *lpContext)
|
||||||
|
{
|
||||||
|
PWSTR pszPath;
|
||||||
|
LPWSTR folder;
|
||||||
|
int count;
|
||||||
|
LPWSTR file;
|
||||||
|
WIN32_FILE_ATTRIBUTE_DATA fad;
|
||||||
|
ULARGE_INTEGER size;
|
||||||
|
DWORD dwCreationDisposition = OPEN_ALWAYS;
|
||||||
|
|
||||||
|
if ( !GetModuleFileNameW(NULL, s_szExeFilePath, _countof(s_szExeFilePath)) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
s_pszExeFileName = PathFindFileNameW(s_szExeFilePath);
|
||||||
|
|
||||||
|
if ( FAILED(SHGetKnownFolderPath(&FOLDERID_ProgramData, KF_FLAG_DEFAULT, NULL, &pszPath)) )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
count = aswprintf(&folder, L"%ls\\wufuc", pszPath);
|
||||||
|
CoTaskMemFree(pszPath);
|
||||||
|
|
||||||
|
if ( count == -1 )
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if ( (CreateDirectoryW(folder, NULL) || GetLastError() == ERROR_ALREADY_EXISTS)
|
||||||
|
&& aswprintf(&file, L"%ls\\wufuc.1.log", folder) != -1 ) {
|
||||||
|
|
||||||
|
if ( GetFileAttributesExW(file, GetFileExInfoStandard, &fad) ) {
|
||||||
|
size.HighPart = fad.nFileSizeHigh;
|
||||||
|
size.LowPart = fad.nFileSizeLow;
|
||||||
|
|
||||||
|
if ( size.QuadPart > (4 << 20) ) // 4 MiB
|
||||||
|
dwCreationDisposition = CREATE_ALWAYS;
|
||||||
|
}
|
||||||
|
s_hFile = CreateFileW(file,
|
||||||
|
FILE_APPEND_DATA,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
NULL,
|
||||||
|
dwCreationDisposition,
|
||||||
|
FILE_ATTRIBUTE_NORMAL,
|
||||||
|
NULL);
|
||||||
|
free(file);
|
||||||
|
}
|
||||||
|
free(folder);
|
||||||
|
return s_hFile != INVALID_HANDLE_VALUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_debug_(const wchar_t *const format, ...)
|
||||||
|
{
|
||||||
|
va_list ap;
|
||||||
|
int count;
|
||||||
|
wchar_t *buffer;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
count = vaswprintf(&buffer, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if ( count != -1 )
|
||||||
|
OutputDebugStringW(buffer);
|
||||||
|
free(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_trace_(const wchar_t *const format, ...)
|
||||||
|
{
|
||||||
|
static INIT_ONCE InitOnce = INIT_ONCE_STATIC_INIT;
|
||||||
|
BOOL status;
|
||||||
|
wchar_t datebuf[9];
|
||||||
|
wchar_t timebuf[9];
|
||||||
|
va_list ap;
|
||||||
|
int count;
|
||||||
|
wchar_t *buf1;
|
||||||
|
wchar_t *buf2;
|
||||||
|
|
||||||
|
status = InitOnceExecuteOnce(&InitOnce, init_once_callback, NULL, NULL);
|
||||||
|
|
||||||
|
if ( _wstrdate_s(datebuf, _countof(datebuf))
|
||||||
|
|| _wstrtime_s(timebuf, _countof(timebuf)) )
|
||||||
|
return;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
count = vaswprintf(&buf1, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
if ( count == -1 ) return;
|
||||||
|
|
||||||
|
count = aswprintf(&buf2, L"%ls %ls [%ls:%lu] %ls", datebuf, timebuf, s_pszExeFileName, GetCurrentProcessId(), buf1);
|
||||||
|
free(buf1);
|
||||||
|
if ( count == -1 ) return;
|
||||||
|
|
||||||
|
if ( !status || !UTF8WriteFile(s_hFile, buf2) )
|
||||||
|
OutputDebugStringW(buf2);
|
||||||
|
free(buf2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_close(void)
|
||||||
|
{
|
||||||
|
if ( s_hFile != INVALID_HANDLE_VALUE )
|
||||||
|
CloseHandle(s_hFile);
|
||||||
|
}
|
11
src/wufuc/logger.h
Normal file
11
src/wufuc/logger.h
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
void log_debug_(const wchar_t *const format, ...);
|
||||||
|
void log_trace_(const wchar_t *const format, ...);
|
||||||
|
void log_close(void);
|
||||||
|
|
||||||
|
#define log_debug(format, ...) log_debug_(L"[DEBUG] " __FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): " format L"\r\n", ##__VA_ARGS__)
|
||||||
|
#define log_info(format, ...) log_trace_(L"[INFO] " __FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): " format L"\r\n", ##__VA_ARGS__)
|
||||||
|
#define log_warning(format, ...) log_trace_(L"[WARNING] " __FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): " format L"\r\n", ##__VA_ARGS__)
|
||||||
|
#define log_error(format, ...) log_trace_(L"[ERROR] " __FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): " format L"\r\n", ##__VA_ARGS__)
|
||||||
|
#define log_gle(format, ...) log_trace_(L"[ERROR] " __FUNCTIONW__ L"(" _CRT_WIDE(_CRT_STRINGIZE(__LINE__)) L"): " format L" (LastError=%lu)\r\n", ##__VA_ARGS__, GetLastError())
|
8
src/wufuc/memory.c
Normal file
8
src/wufuc/memory.c
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
BOOL WriteProcessMemoryBOOL(HANDLE hProcess, LPBOOL lpBaseAddress, BOOL bValue)
|
||||||
|
{
|
||||||
|
return WriteProcessMemory(hProcess, lpBaseAddress, &bValue, sizeof bValue, NULL);
|
||||||
|
}
|
3
src/wufuc/memory.h
Normal file
3
src/wufuc/memory.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
BOOL WriteProcessMemoryBOOL(HANDLE hProcess, LPBOOL lpBaseAddress, BOOL bValue);
|
@@ -1,157 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "modulehelper.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
HMODULE mod_get_from_th32_snapshot(HANDLE hSnapshot, const wchar_t *pLibFileName)
|
|
||||||
{
|
|
||||||
MODULEENTRY32W me = { sizeof me };
|
|
||||||
if ( !Module32FirstW(hSnapshot, &me) )
|
|
||||||
return NULL;
|
|
||||||
do {
|
|
||||||
if ( !_wcsicmp(me.szExePath, pLibFileName) )
|
|
||||||
return me.hModule;
|
|
||||||
} while ( Module32NextW(hSnapshot, &me) );
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mod_inject_and_begin_thread(
|
|
||||||
HANDLE hProcess,
|
|
||||||
HMODULE hModule,
|
|
||||||
LPTHREAD_START_ROUTINE pStartAddress,
|
|
||||||
const void *pParam,
|
|
||||||
size_t cbParam)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
NTSTATUS Status;
|
|
||||||
LPVOID pBaseAddress = NULL;
|
|
||||||
SIZE_T cb;
|
|
||||||
HMODULE hRemoteModule = NULL;
|
|
||||||
uintptr_t offset;
|
|
||||||
HANDLE hThread;
|
|
||||||
|
|
||||||
Status = NtSuspendProcess(hProcess);
|
|
||||||
if ( !NT_SUCCESS(Status) ) return result;
|
|
||||||
|
|
||||||
if ( pParam ) {
|
|
||||||
// this will be VirtualFree()'d by the function at pStartAddress
|
|
||||||
pBaseAddress = VirtualAllocEx(hProcess,
|
|
||||||
NULL,
|
|
||||||
cbParam,
|
|
||||||
MEM_RESERVE | MEM_COMMIT,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
if ( !pBaseAddress ) goto resume_process;
|
|
||||||
|
|
||||||
if ( !WriteProcessMemory(hProcess, pBaseAddress, pParam, cbParam, &cb) )
|
|
||||||
goto virt_free;
|
|
||||||
}
|
|
||||||
if ( mod_inject_by_hmodule(hProcess, hModule, &hRemoteModule) ) {
|
|
||||||
offset = (uintptr_t)pStartAddress - (uintptr_t)hModule;
|
|
||||||
hThread = CreateRemoteThread(hProcess,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
(LPTHREAD_START_ROUTINE)RtlOffsetToPointer(hRemoteModule, offset),
|
|
||||||
pBaseAddress,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if ( hThread ) {
|
|
||||||
CloseHandle(hThread);
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
virt_free:
|
|
||||||
if ( !result && pBaseAddress )
|
|
||||||
VirtualFreeEx(hProcess, pBaseAddress, 0, MEM_RELEASE);
|
|
||||||
resume_process:
|
|
||||||
NtResumeProcess(hProcess);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mod_inject_by_hmodule(HANDLE hProcess, HMODULE hModule, HMODULE *phRemoteModule)
|
|
||||||
{
|
|
||||||
WCHAR Filename[MAX_PATH];
|
|
||||||
DWORD nLength;
|
|
||||||
|
|
||||||
nLength = GetModuleFileNameW(hModule, Filename, _countof(Filename));
|
|
||||||
if ( nLength ) {
|
|
||||||
return mod_inject(hProcess,
|
|
||||||
Filename,
|
|
||||||
nLength,
|
|
||||||
phRemoteModule);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool mod_inject(
|
|
||||||
HANDLE hProcess,
|
|
||||||
const wchar_t *pLibFilename,
|
|
||||||
size_t cchLibFilename,
|
|
||||||
HMODULE *phRemoteModule)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
DWORD dwProcessId;
|
|
||||||
NTSTATUS Status;
|
|
||||||
HANDLE hSnapshot;
|
|
||||||
SIZE_T nSize;
|
|
||||||
LPVOID pBaseAddress;
|
|
||||||
HANDLE hThread;
|
|
||||||
|
|
||||||
Status = NtSuspendProcess(hProcess);
|
|
||||||
if ( !NT_SUCCESS(Status) ) return result;
|
|
||||||
|
|
||||||
dwProcessId = GetProcessId(hProcess);
|
|
||||||
|
|
||||||
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
|
|
||||||
if ( !hSnapshot ) goto resume_process;
|
|
||||||
|
|
||||||
*phRemoteModule = mod_get_from_th32_snapshot(hSnapshot,
|
|
||||||
pLibFilename);
|
|
||||||
|
|
||||||
CloseHandle(hSnapshot);
|
|
||||||
|
|
||||||
// already injected... still sets *phRemoteModule
|
|
||||||
if ( *phRemoteModule ) goto resume_process;
|
|
||||||
|
|
||||||
nSize = (cchLibFilename + 1) * sizeof *pLibFilename;
|
|
||||||
pBaseAddress = VirtualAllocEx(hProcess,
|
|
||||||
NULL,
|
|
||||||
nSize,
|
|
||||||
MEM_RESERVE | MEM_COMMIT,
|
|
||||||
PAGE_READWRITE);
|
|
||||||
|
|
||||||
if ( !pBaseAddress ) goto resume_process;
|
|
||||||
|
|
||||||
if ( !WriteProcessMemory(hProcess, pBaseAddress, pLibFilename, nSize, NULL) )
|
|
||||||
goto virt_free;
|
|
||||||
|
|
||||||
hThread = CreateRemoteThread(hProcess,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
(LPTHREAD_START_ROUTINE)LoadLibraryW,
|
|
||||||
pBaseAddress,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
if ( !hThread ) goto virt_free;
|
|
||||||
|
|
||||||
WaitForSingleObject(hThread, INFINITE);
|
|
||||||
|
|
||||||
if ( sizeof *phRemoteModule > sizeof(DWORD) ) {
|
|
||||||
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
|
|
||||||
if ( hSnapshot ) {
|
|
||||||
*phRemoteModule = mod_get_from_th32_snapshot(
|
|
||||||
hSnapshot,
|
|
||||||
pLibFilename);
|
|
||||||
|
|
||||||
CloseHandle(hSnapshot);
|
|
||||||
result = *phRemoteModule != NULL;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
result = GetExitCodeThread(hThread, (LPDWORD)phRemoteModule) != FALSE;
|
|
||||||
}
|
|
||||||
CloseHandle(hThread);
|
|
||||||
virt_free:
|
|
||||||
VirtualFreeEx(hProcess, pBaseAddress, 0, MEM_RELEASE);
|
|
||||||
resume_process:
|
|
||||||
NtResumeProcess(hProcess);
|
|
||||||
return result;
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
HMODULE mod_get_from_th32_snapshot(HANDLE hSnapshot, const wchar_t *pLibFileName);
|
|
||||||
bool mod_inject_and_begin_thread(
|
|
||||||
HANDLE hProcess,
|
|
||||||
HMODULE hModule,
|
|
||||||
LPTHREAD_START_ROUTINE pStartAddress,
|
|
||||||
const void *pParam,
|
|
||||||
size_t cbParam);
|
|
||||||
bool mod_inject_by_hmodule(HANDLE hProcess, HMODULE hModule, HMODULE *phRemoteModule);
|
|
||||||
bool mod_inject(
|
|
||||||
HANDLE hProcess,
|
|
||||||
const wchar_t *pLibFilename,
|
|
||||||
size_t cchLibFilename,
|
|
||||||
HMODULE *phRemoteModule);
|
|
24
src/wufuc/modules.c
Normal file
24
src/wufuc/modules.c
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "modules.h"
|
||||||
|
|
||||||
|
HMODULE Toolhelp32GetModuleHandle(DWORD th32ProcessID, LPCWSTR lpModuleName)
|
||||||
|
{
|
||||||
|
HANDLE Snapshot;
|
||||||
|
MODULEENTRY32W me = { sizeof me };
|
||||||
|
HMODULE result = NULL;
|
||||||
|
|
||||||
|
Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, th32ProcessID);
|
||||||
|
if ( !Snapshot ) return NULL;
|
||||||
|
|
||||||
|
if ( Module32FirstW(Snapshot, &me) ) {
|
||||||
|
do {
|
||||||
|
if ( !_wcsicmp(me.szExePath, lpModuleName) ) {
|
||||||
|
result = me.hModule;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while ( Module32NextW(Snapshot, &me) );
|
||||||
|
}
|
||||||
|
CloseHandle(Snapshot);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
3
src/wufuc/modules.h
Normal file
3
src/wufuc/modules.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
HMODULE Toolhelp32GetModuleHandle(DWORD th32ProcessID, LPCWSTR lpModuleName);
|
@@ -1,41 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "mutexhelper.h"
|
|
||||||
|
|
||||||
#include <sddl.h>
|
|
||||||
|
|
||||||
HANDLE mutex_create_new(bool InitialOwner, const wchar_t *MutexName)
|
|
||||||
{
|
|
||||||
HANDLE hMutex;
|
|
||||||
|
|
||||||
hMutex = CreateMutexW(NULL, InitialOwner, MutexName);
|
|
||||||
if ( hMutex ) {
|
|
||||||
if ( GetLastError() == ERROR_ALREADY_EXISTS ) {
|
|
||||||
CloseHandle(hMutex);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
return hMutex;
|
|
||||||
}
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
HANDLE mutex_create_new_fmt(bool InitialOwner, const wchar_t *const NameFormat, ...)
|
|
||||||
{
|
|
||||||
HANDLE result = NULL;
|
|
||||||
va_list ap;
|
|
||||||
wchar_t *buffer;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
va_start(ap, NameFormat);
|
|
||||||
ret = _vscwprintf(NameFormat, ap) + 1;
|
|
||||||
va_end(ap);
|
|
||||||
buffer = calloc(ret, sizeof *buffer);
|
|
||||||
if ( buffer ) {
|
|
||||||
va_start(ap, NameFormat);
|
|
||||||
ret = vswprintf_s(buffer, ret, NameFormat, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if (ret != -1)
|
|
||||||
result = mutex_create_new(InitialOwner, buffer);
|
|
||||||
free(buffer);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
@@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
HANDLE mutex_create_new(bool InitialOwner, const wchar_t *MutexName);
|
|
||||||
HANDLE mutex_create_new_fmt(bool InitialOwner, const wchar_t *const NameFormat, ...);
|
|
@@ -3,7 +3,9 @@
|
|||||||
|
|
||||||
static inline bool isHex(char ch)
|
static inline bool isHex(char ch)
|
||||||
{
|
{
|
||||||
return (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F') || (ch >= 'a' && ch <= 'f');
|
return (ch >= '0' && ch <= '9')
|
||||||
|
|| (ch >= 'A' && ch <= 'F')
|
||||||
|
|| (ch >= 'a' && ch <= 'f');
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int hexchtoint(char ch)
|
static inline int hexchtoint(char ch)
|
||||||
@@ -17,10 +19,14 @@ static inline int hexchtoint(char ch)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline size_t formathexpattern(const char *patterntext, char *formattext, size_t formattextsize)
|
static inline size_t formathexpattern(const char *patterntext,
|
||||||
|
char *formattext,
|
||||||
|
size_t formattextsize)
|
||||||
{
|
{
|
||||||
size_t len = strlen(patterntext);
|
size_t len;
|
||||||
size_t result = 0;
|
size_t result = 0;
|
||||||
|
|
||||||
|
len = strlen(patterntext);
|
||||||
for ( size_t i = 0; i < len; i++ ) {
|
for ( size_t i = 0; i < len; i++ ) {
|
||||||
if ( patterntext[i] == '?' || hexchtoint(patterntext[i]) != -1 ) {
|
if ( patterntext[i] == '?' || hexchtoint(patterntext[i]) != -1 ) {
|
||||||
if ( formattext && result + 1 < formattextsize )
|
if ( formattext && result + 1 < formattextsize )
|
||||||
@@ -44,18 +50,24 @@ static inline size_t formathexpattern(const char *patterntext, char *formattext,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool patterntransform(const char *patterntext, PatternByte *pattern, size_t patternsize)
|
bool patterntransform(const char *patterntext,
|
||||||
|
PatternByte *pattern,
|
||||||
|
size_t patternsize)
|
||||||
{
|
{
|
||||||
|
size_t len;
|
||||||
|
size_t size;
|
||||||
|
char *formattext;
|
||||||
|
PatternByte newByte;
|
||||||
|
|
||||||
memset(pattern, 0, patternsize * (sizeof *pattern));
|
memset(pattern, 0, patternsize * (sizeof *pattern));
|
||||||
size_t len = formathexpattern(patterntext, NULL, 0);
|
len = formathexpattern(patterntext, NULL, 0);
|
||||||
|
|
||||||
if ( !len || len / 2 > patternsize )
|
if ( !len || len / 2 > patternsize )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
size_t size = len + 1;
|
size = len + 1;
|
||||||
char *formattext = malloc(size);
|
formattext = malloc(size);
|
||||||
formathexpattern(patterntext, formattext, size);
|
formathexpattern(patterntext, formattext, size);
|
||||||
PatternByte newByte;
|
|
||||||
|
|
||||||
for ( size_t i = 0, j = 0, k = 0; i < len && k <= patternsize; i++ ) {
|
for ( size_t i = 0, j = 0, k = 0; i < len && k <= patternsize; i++ ) {
|
||||||
if ( formattext[i] == '?' ) { //wildcard
|
if ( formattext[i] == '?' ) { //wildcard
|
||||||
@@ -78,14 +90,16 @@ bool patterntransform(const char *patterntext, PatternByte *pattern, size_t patt
|
|||||||
static inline bool patternmatchbyte(uint8_t byte, const PatternByte pbyte)
|
static inline bool patternmatchbyte(uint8_t byte, const PatternByte pbyte)
|
||||||
{
|
{
|
||||||
int matched = 0;
|
int matched = 0;
|
||||||
|
uint8_t n1;
|
||||||
|
uint8_t n2;
|
||||||
|
|
||||||
uint8_t n1 = (byte >> 4) & 0xF;
|
n1 = (byte >> 4) & 0xF;
|
||||||
if ( pbyte.nibble[0].wildcard )
|
if ( pbyte.nibble[0].wildcard )
|
||||||
matched++;
|
matched++;
|
||||||
else if ( pbyte.nibble[0].data == n1 )
|
else if ( pbyte.nibble[0].data == n1 )
|
||||||
matched++;
|
matched++;
|
||||||
|
|
||||||
uint8_t n2 = byte & 0xF;
|
n2 = byte & 0xF;
|
||||||
if ( pbyte.nibble[1].wildcard )
|
if ( pbyte.nibble[1].wildcard )
|
||||||
matched++;
|
matched++;
|
||||||
else if ( pbyte.nibble[1].data == n2 )
|
else if ( pbyte.nibble[1].data == n2 )
|
||||||
@@ -96,10 +110,13 @@ static inline bool patternmatchbyte(uint8_t byte, const PatternByte pbyte)
|
|||||||
|
|
||||||
size_t patternfind(uint8_t *data, size_t datasize, const char *pattern)
|
size_t patternfind(uint8_t *data, size_t datasize, const char *pattern)
|
||||||
{
|
{
|
||||||
size_t searchpatternsize = formathexpattern(pattern, NULL, 0) / 2;
|
size_t searchpatternsize;
|
||||||
PatternByte *searchpattern = calloc(searchpatternsize, sizeof(PatternByte));
|
PatternByte *searchpattern;
|
||||||
|
|
||||||
size_t result = -1;
|
size_t result = -1;
|
||||||
|
|
||||||
|
searchpatternsize = formathexpattern(pattern, NULL, 0) / 2;
|
||||||
|
searchpattern = calloc(searchpatternsize, sizeof *searchpattern);
|
||||||
|
|
||||||
if ( patterntransform(pattern, searchpattern, searchpatternsize) )
|
if ( patterntransform(pattern, searchpattern, searchpatternsize) )
|
||||||
result = patternfind_pbyte(data, datasize, searchpattern, searchpatternsize);
|
result = patternfind_pbyte(data, datasize, searchpattern, searchpatternsize);
|
||||||
|
|
||||||
@@ -108,7 +125,10 @@ size_t patternfind(uint8_t *data, size_t datasize, const char *pattern)
|
|||||||
}
|
}
|
||||||
|
|
||||||
__declspec(noinline)
|
__declspec(noinline)
|
||||||
size_t patternfind_bytes(uint8_t *data, size_t datasize, const uint8_t *pattern, size_t patternsize)
|
size_t patternfind_bytes(uint8_t *data,
|
||||||
|
size_t datasize,
|
||||||
|
const uint8_t *pattern,
|
||||||
|
size_t patternsize)
|
||||||
{
|
{
|
||||||
if ( patternsize > datasize )
|
if ( patternsize > datasize )
|
||||||
patternsize = datasize;
|
patternsize = datasize;
|
||||||
@@ -137,28 +157,38 @@ static inline void patternwritebyte(uint8_t *byte, const PatternByte pbyte)
|
|||||||
*byte = ((n1 << 4) & 0xF0) | (n2 & 0xF);
|
*byte = ((n1 << 4) & 0xF0) | (n2 & 0xF);
|
||||||
}
|
}
|
||||||
|
|
||||||
void patternwrite(uint8_t *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;
|
size_t writepatternsize;
|
||||||
PatternByte *writepattern = calloc(writepatternsize, sizeof(PatternByte));
|
PatternByte *writepattern;
|
||||||
|
DWORD fOldProtect;
|
||||||
|
|
||||||
|
writepatternsize = formathexpattern(pattern, NULL, 0) / 2;
|
||||||
|
writepattern = calloc(writepatternsize, sizeof *writepattern);
|
||||||
|
|
||||||
if ( patterntransform(pattern, writepattern, writepatternsize) ) {
|
if ( patterntransform(pattern, writepattern, writepatternsize) ) {
|
||||||
DWORD OldProtect;
|
VirtualProtect(data, writepatternsize, PAGE_EXECUTE_READWRITE, &fOldProtect);
|
||||||
BOOL result = VirtualProtect(data, writepatternsize, PAGE_EXECUTE_READWRITE, &OldProtect);
|
|
||||||
if ( writepatternsize > datasize )
|
if ( writepatternsize > datasize )
|
||||||
writepatternsize = datasize;
|
writepatternsize = datasize;
|
||||||
for ( size_t i = 0; i < writepatternsize; i++ )
|
for ( size_t i = 0; i < writepatternsize; i++ )
|
||||||
patternwritebyte(&data[i], writepattern[i]);
|
patternwritebyte(&data[i], writepattern[i]);
|
||||||
result = VirtualProtect(data, writepatternsize, OldProtect, &OldProtect);
|
VirtualProtect(data, writepatternsize, fOldProtect, &fOldProtect);
|
||||||
FlushInstructionCache(GetCurrentProcess(), data, datasize);
|
FlushInstructionCache(GetCurrentProcess(), data, datasize);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(writepattern);
|
free(writepattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool patternsnr(uint8_t *data, size_t datasize, const char *searchpattern, const char *replacepattern)
|
bool patternsnr(uint8_t *data,
|
||||||
|
size_t datasize,
|
||||||
|
const char *searchpattern,
|
||||||
|
const char *replacepattern)
|
||||||
{
|
{
|
||||||
size_t found = patternfind(data, datasize, searchpattern);
|
size_t found;
|
||||||
|
|
||||||
|
found = patternfind(data, datasize, searchpattern);
|
||||||
if ( found == -1 )
|
if ( found == -1 )
|
||||||
return false;
|
return false;
|
||||||
patternwrite(data + found, found - datasize, replacepattern);
|
patternwrite(data + found, found - datasize, replacepattern);
|
||||||
@@ -166,7 +196,10 @@ bool patternsnr(uint8_t *data, size_t datasize, const char *searchpattern, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
__declspec(noinline)
|
__declspec(noinline)
|
||||||
size_t patternfind_pbyte(uint8_t *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
|
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
|
if ( patternmatchbyte(data[i], pattern[pos]) ) { //check if our pattern matches the current byte
|
||||||
|
@@ -1,403 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "ptrlist.h"
|
|
||||||
|
|
||||||
void ptrlist_lock(ptrlist_t *list)
|
|
||||||
{
|
|
||||||
EnterCriticalSection(&list->criticalSection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ptrlist_unlock(ptrlist_t *list)
|
|
||||||
{
|
|
||||||
LeaveCriticalSection(&list->criticalSection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *ptrlist_at(ptrlist_t *list, size_t index, uint32_t *pTag)
|
|
||||||
{
|
|
||||||
void *result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
result = list->values[index];
|
|
||||||
if ( pTag )
|
|
||||||
*pTag = list->tags[index];
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ptrlist_create(ptrlist_t *list, size_t capacity, size_t maxCapacity)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
size_t c;
|
|
||||||
size_t vsize;
|
|
||||||
size_t tsize;
|
|
||||||
void *tmp;
|
|
||||||
|
|
||||||
if ( !list || capacity > maxCapacity )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
c = capacity ? capacity :
|
|
||||||
(maxCapacity ? min(maxCapacity, 16) : 16);
|
|
||||||
vsize = c * (sizeof *list->values);
|
|
||||||
tsize = c * (sizeof *list->tags);
|
|
||||||
|
|
||||||
InitializeCriticalSection(&list->criticalSection);
|
|
||||||
ptrlist_lock(list);
|
|
||||||
|
|
||||||
tmp = malloc(vsize + tsize);
|
|
||||||
if ( tmp ) {
|
|
||||||
ZeroMemory(tmp, vsize + tsize);
|
|
||||||
list->values = tmp;
|
|
||||||
list->tags = (uint32_t *)RtlOffsetToPointer(tmp, vsize);
|
|
||||||
list->capacity = c;
|
|
||||||
list->maxCapacity = maxCapacity;
|
|
||||||
list->count = 0;
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
if ( !result )
|
|
||||||
DeleteCriticalSection(&list->criticalSection);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ptrlist_destroy(ptrlist_t *list)
|
|
||||||
{
|
|
||||||
if ( !list ) return;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
|
|
||||||
free(list->values);
|
|
||||||
list->values = NULL;
|
|
||||||
list->tags = NULL;
|
|
||||||
|
|
||||||
list->count = 0;
|
|
||||||
list->capacity = 0;
|
|
||||||
list->maxCapacity = 0;
|
|
||||||
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
DeleteCriticalSection(&list->criticalSection);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ptrlist_index_of(ptrlist_t *list, void *value)
|
|
||||||
{
|
|
||||||
size_t result = -1;
|
|
||||||
|
|
||||||
if ( !list || !value )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
for ( size_t i = 0; i < list->count; i++ ) {
|
|
||||||
if ( list->values[i] == value ) {
|
|
||||||
result = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ptrlist_add(ptrlist_t *list, void *value, uint32_t tag)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
size_t newCapacity;
|
|
||||||
size_t diff;
|
|
||||||
size_t vsize;
|
|
||||||
size_t tsize;
|
|
||||||
void **tmp1;
|
|
||||||
uint32_t *tmp2;
|
|
||||||
|
|
||||||
if ( !list || !value )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
|
|
||||||
if ( list->count >= list->capacity ) {
|
|
||||||
newCapacity = list->count;
|
|
||||||
if ( list->maxCapacity ) {
|
|
||||||
diff = list->maxCapacity - list->capacity;
|
|
||||||
if ( !diff )
|
|
||||||
goto leave;
|
|
||||||
newCapacity += min(diff, 16);
|
|
||||||
} else {
|
|
||||||
newCapacity += 16;
|
|
||||||
}
|
|
||||||
vsize = newCapacity * (sizeof *list->values);
|
|
||||||
tsize = newCapacity * (sizeof *list->tags);
|
|
||||||
|
|
||||||
tmp1 = malloc(vsize + tsize);
|
|
||||||
|
|
||||||
if ( !tmp1 )
|
|
||||||
goto leave;
|
|
||||||
|
|
||||||
ZeroMemory(tmp1, vsize);
|
|
||||||
|
|
||||||
tmp2 = (uint32_t *)RtlOffsetToPointer(tmp1, vsize);
|
|
||||||
ZeroMemory(tmp2, tsize);
|
|
||||||
|
|
||||||
if ( memmove_s(tmp1, vsize, list->values, list->count * (sizeof *list->values))
|
|
||||||
|| memmove_s(tmp2, tsize, list->tags, list->count * (sizeof *list->tags)) ) {
|
|
||||||
|
|
||||||
free(tmp1);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
list->values = tmp1;
|
|
||||||
list->tags = tmp2;
|
|
||||||
list->capacity = newCapacity;
|
|
||||||
}
|
|
||||||
list->values[list->count] = value;
|
|
||||||
list->tags[list->count] = tag;
|
|
||||||
list->count++;
|
|
||||||
result = true;
|
|
||||||
leave:
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ptrlist_add_range(ptrlist_t *list, void **values, uint32_t *tags, size_t count)
|
|
||||||
{
|
|
||||||
bool result = true;
|
|
||||||
|
|
||||||
if ( !list || !values || !count )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
if ( list->count + count <= list->maxCapacity ) {
|
|
||||||
for ( size_t i = 0; result && i < count; i++ )
|
|
||||||
result = ptrlist_add(list, values[i], tags ? tags[i] : 0);
|
|
||||||
} else {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ptrlist_remove_at(ptrlist_t *list, size_t index)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if ( !list ) return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
if ( index <= list->count - 1 ) {
|
|
||||||
for ( size_t i = index; i < list->count - 1; i++ )
|
|
||||||
list->values[i] = list->values[i + 1];
|
|
||||||
|
|
||||||
list->values[list->count--] = NULL;
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ptrlist_remove(ptrlist_t *list, void *value)
|
|
||||||
{
|
|
||||||
size_t index;
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if ( !list || !value )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
index = ptrlist_index_of(list, value);
|
|
||||||
if ( index != -1 )
|
|
||||||
result = ptrlist_remove_at(list, index);
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ptrlist_remove_range(ptrlist_t *list, size_t index, size_t count)
|
|
||||||
{
|
|
||||||
bool result = true;
|
|
||||||
|
|
||||||
if ( !list || !count )
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
if ( index <= list->count - 1
|
|
||||||
&& index + count <= list->count ) {
|
|
||||||
|
|
||||||
for ( size_t i = 0; result && i < count; i++ )
|
|
||||||
result = ptrlist_remove_at(list, index);
|
|
||||||
} else {
|
|
||||||
result = false;
|
|
||||||
}
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ptrlist_clear(ptrlist_t *list)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
|
|
||||||
if ( !list ) return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
result = ptrlist_remove_range(list, 0, list->count);
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ptrlist_get_count(ptrlist_t *list)
|
|
||||||
{
|
|
||||||
size_t result = -1;
|
|
||||||
|
|
||||||
if ( !list ) return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
result = list->count;
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ptrlist_get_capacity(ptrlist_t *list)
|
|
||||||
{
|
|
||||||
size_t result = -1;
|
|
||||||
|
|
||||||
if ( !list ) return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
result = list->capacity;
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t ptrlist_get_max_capacity(ptrlist_t *list)
|
|
||||||
{
|
|
||||||
size_t result = -1;
|
|
||||||
|
|
||||||
if ( !list ) return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
result = list->maxCapacity;
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ptrlist_contains(ptrlist_t *list, void *value)
|
|
||||||
{
|
|
||||||
return ptrlist_index_of(list, value) != -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void **ptrlist_copy_values(ptrlist_t *list, size_t *count)
|
|
||||||
{
|
|
||||||
void **result = NULL;
|
|
||||||
size_t size;
|
|
||||||
size_t c;
|
|
||||||
|
|
||||||
if ( !list || !count )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
c = list->count;
|
|
||||||
if ( !c ) goto leave;
|
|
||||||
|
|
||||||
size = c * (sizeof *list->values);
|
|
||||||
result = malloc(c * (sizeof *list->values));
|
|
||||||
if ( result ) {
|
|
||||||
if ( !memcpy_s(result, size, list->values, size) ) {
|
|
||||||
*count = c;
|
|
||||||
} else {
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
leave:
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t *ptrlist_copy_tags(ptrlist_t *list, size_t *count)
|
|
||||||
{
|
|
||||||
uint32_t *result = NULL;
|
|
||||||
size_t size;
|
|
||||||
size_t c;
|
|
||||||
|
|
||||||
if ( !list || !count )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
c = list->count;
|
|
||||||
if ( !c ) goto leave;
|
|
||||||
|
|
||||||
size = c * (sizeof *list->tags);
|
|
||||||
result = malloc(c * (sizeof *list->tags));
|
|
||||||
if ( result ) {
|
|
||||||
if ( !memcpy_s(result, size, list->tags, size) ) {
|
|
||||||
*count = c;
|
|
||||||
} else {
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
leave:
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ptrlist_copy(ptrlist_t *list, void ***values, uint32_t **tags, size_t *count)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
void **v;
|
|
||||||
uint32_t *t;
|
|
||||||
size_t c;
|
|
||||||
|
|
||||||
if ( !values || !tags || !count )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
v = ptrlist_copy_values(list, &c);
|
|
||||||
if ( !v ) goto leave;
|
|
||||||
|
|
||||||
t = ptrlist_copy_tags(list, &c);
|
|
||||||
if ( !t ) {
|
|
||||||
free(v);
|
|
||||||
goto leave;
|
|
||||||
}
|
|
||||||
*values = v;
|
|
||||||
*tags = t;
|
|
||||||
*count = c;
|
|
||||||
result = true;
|
|
||||||
leave:
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ptrlist_for(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *))
|
|
||||||
{
|
|
||||||
if ( !list || !f ) return;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
if ( index + count <= list->count ) {
|
|
||||||
for ( size_t i = index; i < count; i++ )
|
|
||||||
f(list->values[i]);
|
|
||||||
}
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *))
|
|
||||||
{
|
|
||||||
if ( !list || !f ) return;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
ptrlist_for(list, 0, list->count, f);
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__stdcall *f)(void *))
|
|
||||||
{
|
|
||||||
if ( !list || !f ) return;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
if ( index + count <= list->count ) {
|
|
||||||
for ( size_t i = index; i < count; i++ )
|
|
||||||
f(list->values[i]);
|
|
||||||
}
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *))
|
|
||||||
{
|
|
||||||
if ( !list || !f ) return;
|
|
||||||
|
|
||||||
ptrlist_lock(list);
|
|
||||||
ptrlist_for_stdcall(list, 0, list->count, f);
|
|
||||||
ptrlist_unlock(list);
|
|
||||||
}
|
|
@@ -1,37 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
typedef struct ptrlist_t_
|
|
||||||
{
|
|
||||||
void **values;
|
|
||||||
uint32_t *tags;
|
|
||||||
size_t capacity;
|
|
||||||
size_t maxCapacity;
|
|
||||||
size_t count;
|
|
||||||
CRITICAL_SECTION criticalSection;
|
|
||||||
} ptrlist_t;
|
|
||||||
#pragma pack(pop)
|
|
||||||
|
|
||||||
void ptrlist_lock(ptrlist_t *list);
|
|
||||||
void ptrlist_unlock(ptrlist_t *list);
|
|
||||||
void *ptrlist_at(ptrlist_t *list, size_t index, uint32_t *pTag);
|
|
||||||
bool ptrlist_create(ptrlist_t *list, size_t capacity, size_t maxCapacity);
|
|
||||||
void ptrlist_destroy(ptrlist_t *list);
|
|
||||||
size_t ptrlist_index_of(ptrlist_t *list, void *value);
|
|
||||||
bool ptrlist_add(ptrlist_t *list, void *value, uint32_t tag);
|
|
||||||
bool ptrlist_add_range(ptrlist_t *list, void **values, uint32_t *tags, size_t count);
|
|
||||||
bool ptrlist_remove_at(ptrlist_t *list, size_t index);
|
|
||||||
bool ptrlist_remove(ptrlist_t *list, void *value);
|
|
||||||
bool ptrlist_remove_range(ptrlist_t *list, size_t index, size_t count);
|
|
||||||
bool ptrlist_clear(ptrlist_t *list);
|
|
||||||
size_t ptrlist_get_count(ptrlist_t *list);
|
|
||||||
size_t ptrlist_get_capacity(ptrlist_t *list);
|
|
||||||
size_t ptrlist_get_max_capacity(ptrlist_t *list);
|
|
||||||
bool ptrlist_contains(ptrlist_t *list, void *value);
|
|
||||||
void **ptrlist_copy_values(ptrlist_t *list, size_t *count);
|
|
||||||
uint32_t *ptrlist_copy_tags(ptrlist_t *list, size_t *count);
|
|
||||||
bool ptrlist_copy(ptrlist_t *list, void ***values, uint32_t **tags, size_t *count);
|
|
||||||
void ptrlist_for(ptrlist_t *list, size_t index, size_t count, void(__cdecl *f)(void *));
|
|
||||||
void ptrlist_for_each(ptrlist_t *list, void(__cdecl *f)(void *));
|
|
||||||
void ptrlist_for_stdcall(ptrlist_t *list, size_t index, size_t count, void(__stdcall *f)(void *));
|
|
||||||
void ptrlist_for_each_stdcall(ptrlist_t *list, void(__stdcall *f)(void *));
|
|
22
src/wufuc/registry.c
Normal file
22
src/wufuc/registry.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "registry.h"
|
||||||
|
|
||||||
|
DWORD RegGetValueAlloc(PVOID *ppvData, HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, DWORD dwFlags, LPDWORD pdwType)
|
||||||
|
{
|
||||||
|
DWORD result;
|
||||||
|
PVOID pvData;
|
||||||
|
|
||||||
|
if ( RegGetValueW(hKey, lpSubKey, lpValueName, dwFlags, pdwType, NULL, &result) != ERROR_SUCCESS )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
pvData = malloc(result);
|
||||||
|
if ( !pvData ) return 0;
|
||||||
|
|
||||||
|
if ( RegGetValueW(hKey, lpSubKey, lpValueName, dwFlags, pdwType, pvData, &result) == ERROR_SUCCESS ) {
|
||||||
|
*ppvData = pvData;
|
||||||
|
} else {
|
||||||
|
free(pvData);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
3
src/wufuc/registry.h
Normal file
3
src/wufuc/registry.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
DWORD RegGetValueAlloc(PVOID *ppvData, HKEY hKey, LPCWSTR lpSubKey, LPCWSTR lpValueName, DWORD dwFlags, LPDWORD pdwType);
|
@@ -1,118 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "registryhelper.h"
|
|
||||||
|
|
||||||
PVOID reg_get_value_alloc(
|
|
||||||
HKEY hKey,
|
|
||||||
LPCWSTR SubKey,
|
|
||||||
LPCWSTR Value,
|
|
||||||
DWORD dwFlags,
|
|
||||||
LPDWORD pdwType,
|
|
||||||
LPDWORD pcbData)
|
|
||||||
{
|
|
||||||
DWORD cbData = 0;
|
|
||||||
PVOID result = NULL;
|
|
||||||
|
|
||||||
if ( RegGetValueW(hKey, SubKey, Value, dwFlags, pdwType, NULL, &cbData) != ERROR_SUCCESS )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
result = malloc(cbData);
|
|
||||||
if ( !result ) return result;
|
|
||||||
|
|
||||||
if ( RegGetValueW(hKey, SubKey, Value, dwFlags, pdwType, result, &cbData) == ERROR_SUCCESS ) {
|
|
||||||
if ( pcbData )
|
|
||||||
*pcbData = cbData;
|
|
||||||
} else {
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPBYTE reg_query_value_alloc(
|
|
||||||
HKEY hKey,
|
|
||||||
LPCWSTR SubKey,
|
|
||||||
LPCWSTR Value,
|
|
||||||
LPDWORD pdwType,
|
|
||||||
LPDWORD pcbData)
|
|
||||||
{
|
|
||||||
HKEY hSubKey;
|
|
||||||
DWORD cbData = 0;
|
|
||||||
DWORD dwType;
|
|
||||||
LPBYTE result = NULL;
|
|
||||||
|
|
||||||
if ( SubKey && *SubKey ) {
|
|
||||||
if ( RegOpenKeyW(hKey, SubKey, &hSubKey) != ERROR_SUCCESS )
|
|
||||||
return result;
|
|
||||||
} else {
|
|
||||||
hSubKey = hKey;
|
|
||||||
}
|
|
||||||
if ( RegQueryValueExW(hSubKey, Value, NULL, &dwType, result, &cbData) != ERROR_SUCCESS )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
switch ( dwType ) {
|
|
||||||
case REG_SZ:
|
|
||||||
case REG_EXPAND_SZ:
|
|
||||||
cbData += sizeof UNICODE_NULL;
|
|
||||||
break;
|
|
||||||
case REG_MULTI_SZ:
|
|
||||||
cbData += (sizeof UNICODE_NULL) * 2;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result = malloc(cbData);
|
|
||||||
|
|
||||||
if ( !result ) return result;
|
|
||||||
ZeroMemory(result, cbData);
|
|
||||||
|
|
||||||
if ( RegQueryValueExW(hSubKey, Value, NULL, pdwType, result, &cbData) == ERROR_SUCCESS ) {
|
|
||||||
if ( pcbData )
|
|
||||||
*pcbData = cbData;
|
|
||||||
} else {
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PVOID reg_query_key_alloc(
|
|
||||||
HANDLE KeyHandle,
|
|
||||||
KEY_INFORMATION_CLASS KeyInformationClass,
|
|
||||||
PULONG pResultLength)
|
|
||||||
{
|
|
||||||
NTSTATUS Status;
|
|
||||||
ULONG ResultLength;
|
|
||||||
PVOID result = NULL;
|
|
||||||
|
|
||||||
Status = NtQueryKey(KeyHandle, KeyInformationClass, NULL, 0, &ResultLength);
|
|
||||||
if ( Status != STATUS_BUFFER_OVERFLOW && Status != STATUS_BUFFER_TOO_SMALL )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
result = malloc(ResultLength);
|
|
||||||
if ( !result ) return result;
|
|
||||||
|
|
||||||
Status = NtQueryKey(KeyHandle, KeyInformationClass, result, ResultLength, &ResultLength);
|
|
||||||
if ( NT_SUCCESS(Status) ) {
|
|
||||||
*pResultLength = ResultLength;
|
|
||||||
} else {
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPWSTR env_expand_strings_alloc(LPCWSTR Src, LPDWORD pcchLength)
|
|
||||||
{
|
|
||||||
LPWSTR result;
|
|
||||||
DWORD buffersize;
|
|
||||||
DWORD size;
|
|
||||||
|
|
||||||
buffersize = ExpandEnvironmentStringsW(Src, NULL, 0);
|
|
||||||
result = calloc(buffersize, sizeof *result);
|
|
||||||
size = ExpandEnvironmentStringsW(Src, result, buffersize);
|
|
||||||
if ( !size || size > buffersize ) {
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
} else if ( pcchLength ) {
|
|
||||||
*pcchLength = buffersize;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
@@ -1,20 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
PVOID reg_get_value_alloc(
|
|
||||||
HKEY hkey,
|
|
||||||
LPCWSTR pSubKey,
|
|
||||||
LPCWSTR pValue,
|
|
||||||
DWORD dwFlags,
|
|
||||||
LPDWORD pdwType,
|
|
||||||
LPDWORD pcbData);
|
|
||||||
LPBYTE reg_query_value_alloc(
|
|
||||||
HKEY hKey,
|
|
||||||
LPCWSTR pSubKey,
|
|
||||||
LPCWSTR pValueName,
|
|
||||||
LPDWORD pType,
|
|
||||||
LPDWORD pcbData);
|
|
||||||
PVOID reg_query_key_alloc(
|
|
||||||
HANDLE KeyHandle,
|
|
||||||
KEY_INFORMATION_CLASS KeyInformationClass,
|
|
||||||
PULONG pResultLength);
|
|
||||||
LPWSTR env_expand_strings_alloc(LPCWSTR Src, LPDWORD pcchLength);
|
|
@@ -1,18 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#ifndef BUILD_COMMIT_VERSION
|
#ifndef BUILD_COMMIT_VERSION
|
||||||
#define BUILD_COMMIT_VERSION 1.0.0.0
|
#define BUILD_COMMIT_VERSION 1.0.1.0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef BUILD_VERSION_COMMA
|
#ifndef BUILD_VERSION_COMMA
|
||||||
#define BUILD_VERSION_COMMA 1,0,0,0
|
#define BUILD_VERSION_COMMA 1,0,1,0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define S_(x) #x
|
#define STRINGIZE_(x) #x
|
||||||
#define S(x) S_(x)
|
#define STRINGIZE(x) STRINGIZE_(x)
|
||||||
|
|
||||||
#ifdef X64
|
#ifdef _WIN64
|
||||||
#define FILENAME "wufuc64.dll"
|
#define FILENAME "wufuc64.dll"
|
||||||
#elif defined(X86)
|
#else
|
||||||
#define FILENAME "wufuc32.dll"
|
#define FILENAME "wufuc32.dll"
|
||||||
#endif
|
#endif
|
||||||
|
Binary file not shown.
@@ -1,148 +1,261 @@
|
|||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#include "callbacks.h"
|
#include "memory.h"
|
||||||
#include "eventhelper.h"
|
#include "modules.h"
|
||||||
#include "log.h"
|
#include "patternfind.h"
|
||||||
#include "modulehelper.h"
|
#include "registry.h"
|
||||||
#include "mutexhelper.h"
|
#include "helpers.h"
|
||||||
#include "ptrlist.h"
|
#include "versioninfo.h"
|
||||||
#include "registryhelper.h"
|
|
||||||
#include "servicehelper.h"
|
|
||||||
#include "wufuc.h"
|
|
||||||
|
|
||||||
const wchar_t m_szUnloadEventName[] = L"Global\\wufuc_UnloadEvent";
|
static BOOL s_bWindowsSevenSP1;
|
||||||
|
static BOOL s_bWindowsEightPointOne;
|
||||||
|
|
||||||
void CALLBACK RUNDLL32_StartW(HWND hwnd,
|
static LPVOID ResolveAndTranslatePtr(LPVOID lpSrcImageBase, size_t Offset, LPVOID lpDstImageBase)
|
||||||
HINSTANCE hinst,
|
|
||||||
LPWSTR lpszCmdLine,
|
|
||||||
int nCmdShow)
|
|
||||||
{
|
{
|
||||||
ptrlist_t list;
|
LPVOID p = OffsetToPointer(lpSrcImageBase, Offset);
|
||||||
HANDLE hEvent;
|
|
||||||
DWORD dwDesiredAccess;
|
#ifdef _WIN64
|
||||||
|
return OffsetToPointer(lpDstImageBase, PointerToOffset(lpSrcImageBase, OffsetToPointer(p, sizeof(uint32_t) + *(uint32_t *)p)));
|
||||||
|
#else
|
||||||
|
return *(LPVOID *)p;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static VOID CALLBACK ServiceNotifyCallback(PVOID pParameter)
|
||||||
|
{
|
||||||
|
PSERVICE_NOTIFY pNotifyBuffer = pParameter;
|
||||||
|
DWORD dwProcessId = pNotifyBuffer->ServiceStatus.dwProcessId;
|
||||||
|
const DWORD dwDesiredAccess = PROCESS_SUSPEND_RESUME | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_READ | PROCESS_VM_WRITE;
|
||||||
|
LPWSTR fname;
|
||||||
|
HANDLE hProcess;
|
||||||
|
NTSTATUS Status;
|
||||||
|
LPWSTR lpwstrFilename;
|
||||||
|
LPVOID lpData;
|
||||||
|
PLANGANDCODEPAGE lpTranslate;
|
||||||
|
LPWSTR lpInternalName;
|
||||||
|
VS_FIXEDFILEINFO *lpffi;
|
||||||
|
const char *pattern;
|
||||||
|
size_t off1;
|
||||||
|
size_t off2;
|
||||||
|
HMODULE hModule;
|
||||||
|
MODULEINFO modinfo;
|
||||||
|
LPVOID lpBuffer;
|
||||||
|
SIZE_T NumberOfBytesRead;
|
||||||
|
size_t offset;
|
||||||
|
LPVOID lpAddress;
|
||||||
|
BOOL bValue;
|
||||||
|
|
||||||
|
switch ( pNotifyBuffer->dwNotificationStatus ) {
|
||||||
|
case ERROR_SUCCESS:
|
||||||
|
if ( !RegGetValueAlloc(&lpwstrFilename,
|
||||||
|
HKEY_LOCAL_MACHINE,
|
||||||
|
L"SYSTEM\\CurrentControlSet\\services\\wuauserv\\Parameters",
|
||||||
|
L"ServiceDll",
|
||||||
|
RRF_RT_REG_SZ,
|
||||||
|
NULL) ) {
|
||||||
|
log_gle(L"Failed to get wuauserv ServiceDll value!");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( !GetFileVersionInfoExAlloc(FILE_VER_GET_NEUTRAL, TRUE, lpwstrFilename, &lpData) ) {
|
||||||
|
log_gle(L"Failed to get file version information: lpwstrFilename=%ls", lpwstrFilename);
|
||||||
|
goto free_lpwstrFilename;
|
||||||
|
}
|
||||||
|
if ( !VerQueryTranslations(lpData, &lpTranslate) ) {
|
||||||
|
log_gle(L"Failed to get resource translations: pBlock=%p", lpData);
|
||||||
|
goto free_lpData;
|
||||||
|
}
|
||||||
|
if ( !VerQueryString(lpData, lpTranslate[0], L"InternalName", &lpInternalName) ) {
|
||||||
|
log_gle(L"Failed to get InternalName resource string: wLanguage=%04x wCodePage=%04x pBlock=%p",
|
||||||
|
lpTranslate[0].wLanguage, lpTranslate[0].wCodePage, lpData);
|
||||||
|
goto free_lpData;
|
||||||
|
}
|
||||||
|
if ( _wcsicmp(lpInternalName, L"wuaueng.dll") ) {
|
||||||
|
log_error(L"InternalName mismatch: lpInternalName=%ls", lpInternalName);
|
||||||
|
goto free_lpData;
|
||||||
|
}
|
||||||
|
if ( !VerQueryFileInfo(lpData, &lpffi) ) {
|
||||||
|
log_gle(L"Failed to get resource file info: pBlock=%p", lpData);
|
||||||
|
goto free_lpData;
|
||||||
|
}
|
||||||
|
#ifdef _WIN64
|
||||||
|
if ( (s_bWindowsSevenSP1 && vercmp(lpffi->dwProductVersionMS, lpffi->dwProductVersionLS, 7, 6, 7601, 23714) != -1)
|
||||||
|
|| (s_bWindowsEightPointOne && vercmp(lpffi->dwProductVersionMS, lpffi->dwProductVersionLS, 7, 9, 9600, 18621) != -1) ) {
|
||||||
|
// all x64
|
||||||
|
pattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????";
|
||||||
|
off1 = 0xa;
|
||||||
|
off2 = 0x12;
|
||||||
|
} else goto free_lpData;
|
||||||
|
#else
|
||||||
|
if ( s_bWindowsSevenSP1 && vercmp(lpffi->dwProductVersionMS, lpffi->dwProductVersionLS, 7, 6, 7601, 23714) != -1 ) {
|
||||||
|
// windows 7 x86
|
||||||
|
pattern = "833D????????00 743E E8???????? A3????????";
|
||||||
|
off1 = 0x2;
|
||||||
|
off2 = 0xf;
|
||||||
|
} else if ( s_bWindowsEightPointOne && vercmp(lpffi->dwProductVersionMS, lpffi->dwProductVersionLS, 7, 9, 9600, 18621) != -1 ) {
|
||||||
|
// windows 8.1 x86
|
||||||
|
pattern = "8BFF 51 833D????????00 7507 A1????????";
|
||||||
|
off1 = 0x5;
|
||||||
|
off2 = 0xd;
|
||||||
|
} else goto free_lpData;
|
||||||
|
#endif
|
||||||
|
fname = PathFindFileNameW(lpwstrFilename);
|
||||||
|
log_info(L"Supported version of %ls: %hu.%hu.%hu.%hu",
|
||||||
|
fname,
|
||||||
|
HIWORD(lpffi->dwProductVersionMS), LOWORD(lpffi->dwProductVersionMS),
|
||||||
|
HIWORD(lpffi->dwProductVersionLS), LOWORD(lpffi->dwProductVersionLS));
|
||||||
|
|
||||||
|
hProcess = OpenProcess(dwDesiredAccess, FALSE, dwProcessId);
|
||||||
|
if ( !hProcess ) {
|
||||||
|
log_gle(L"Failed to open target process: dwProcessId=%lu", dwProcessId);
|
||||||
|
goto free_lpData;
|
||||||
|
}
|
||||||
|
Status = NtSuspendProcess(hProcess);
|
||||||
|
if ( Status != STATUS_SUCCESS ) {
|
||||||
|
log_error(L"Failed to suspend target process: hProcess=%p (Status=%ld)", hProcess, Status);
|
||||||
|
goto close_hProcess;
|
||||||
|
}
|
||||||
|
hModule = Toolhelp32GetModuleHandle(dwProcessId, lpwstrFilename);
|
||||||
|
if ( !hModule ) {
|
||||||
|
log_gle(L"Failed to find target module in Toolhelp32 snapshot: th32ProcessId=%lu lpModuleName=%ls",
|
||||||
|
dwProcessId, lpwstrFilename);
|
||||||
|
goto resume_hProcess;
|
||||||
|
}
|
||||||
|
if ( !GetModuleInformation(hProcess, hModule, &modinfo, sizeof modinfo) ) {
|
||||||
|
log_error(L"Failed to get target module information: hProcess=%p hModule=%p", hProcess, hModule);
|
||||||
|
goto resume_hProcess;
|
||||||
|
}
|
||||||
|
lpBuffer = malloc(modinfo.SizeOfImage);
|
||||||
|
if ( !lpBuffer ) {
|
||||||
|
log_error(L"Failed to allocate memory for lpBuffer!");
|
||||||
|
goto resume_hProcess;
|
||||||
|
}
|
||||||
|
if ( !ReadProcessMemory(hProcess, modinfo.lpBaseOfDll, lpBuffer, modinfo.SizeOfImage, &NumberOfBytesRead) ) {
|
||||||
|
log_gle(L"Failed to read target process memory: hProcess=%p lpBaseAddress=%p nSize=%lu",
|
||||||
|
hProcess, modinfo.lpBaseOfDll, modinfo.SizeOfImage);
|
||||||
|
goto free_lpBuffer;
|
||||||
|
}
|
||||||
|
offset = patternfind(lpBuffer, NumberOfBytesRead, pattern);
|
||||||
|
if ( offset == -1 ) {
|
||||||
|
log_error(L"Failed to find IsDeviceServiceable pattern!");
|
||||||
|
goto free_lpBuffer;
|
||||||
|
}
|
||||||
|
log_info(L"Found IsDeviceServiceable function offset: %ls+0x%Ix", fname, offset);
|
||||||
|
|
||||||
|
lpAddress = ResolveAndTranslatePtr(lpBuffer, offset + off1, modinfo.lpBaseOfDll);
|
||||||
|
bValue = FALSE;
|
||||||
|
if ( WriteProcessMemory(hProcess, lpAddress, &bValue, sizeof bValue, NULL) )
|
||||||
|
log_info(L"Successfully wrote value to target process: lpAddress=%p", lpAddress);
|
||||||
|
else
|
||||||
|
log_gle(L"Failed to write value to target process: lpAddress=%p!", lpAddress);
|
||||||
|
|
||||||
|
lpAddress = ResolveAndTranslatePtr(lpBuffer, offset + off2, modinfo.lpBaseOfDll);
|
||||||
|
bValue = TRUE;
|
||||||
|
if ( WriteProcessMemory(hProcess, lpAddress, &bValue, sizeof bValue, NULL) )
|
||||||
|
log_info(L"Successfully wrote value to target process: lpAddress=%p", lpAddress);
|
||||||
|
else
|
||||||
|
log_gle(L"Failed to patch flag in target process at address %p!", lpAddress);
|
||||||
|
free_lpBuffer:
|
||||||
|
free(lpBuffer);
|
||||||
|
resume_hProcess:
|
||||||
|
NtResumeProcess(hProcess);
|
||||||
|
close_hProcess:
|
||||||
|
CloseHandle(hProcess);
|
||||||
|
free_lpData:
|
||||||
|
free(lpData);
|
||||||
|
free_lpwstrFilename:
|
||||||
|
free(lpwstrFilename);
|
||||||
|
break;
|
||||||
|
case ERROR_SERVICE_MARKED_FOR_DELETE:
|
||||||
|
*(bool *)pNotifyBuffer->pContext = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if ( pNotifyBuffer->pszServiceNames )
|
||||||
|
LocalFree((HLOCAL)pNotifyBuffer->pszServiceNames);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CALLBACK RUNDLL32_StartW(HWND hwnd, HINSTANCE hinst, LPWSTR lpszCmdLine, int nCmdShow)
|
||||||
|
{
|
||||||
|
HANDLE hMutex;
|
||||||
|
HANDLE hUnloadEvent;
|
||||||
bool Lagging;
|
bool Lagging;
|
||||||
SC_HANDLE hSCM;
|
SC_HANDLE hSCM;
|
||||||
SC_HANDLE hService;
|
SC_HANDLE hService;
|
||||||
DWORD dwProcessId;
|
|
||||||
SERVICE_NOTIFYW NotifyBuffer;
|
SERVICE_NOTIFYW NotifyBuffer;
|
||||||
bool Unloading = false;
|
DWORD Error;
|
||||||
DWORD e;
|
|
||||||
void **values;
|
|
||||||
uint32_t *tags;
|
|
||||||
size_t count;
|
|
||||||
DWORD r;
|
|
||||||
size_t index;
|
|
||||||
size_t crashes = 0;
|
|
||||||
bool Suspending = false;
|
|
||||||
|
|
||||||
g_hMainMutex = mutex_create_new(true,
|
hMutex = CreateNewMutex(NULL, TRUE, L"Global\\25020063-b5a7-4227-9fdf-25cb75e8c645");
|
||||||
L"Global\\25020063-b5a7-4227-9fdf-25cb75e8c645");
|
if ( !hMutex ) {
|
||||||
if ( !g_hMainMutex ) return;
|
log_error(L"Failed to create instance mutex!");
|
||||||
|
return;
|
||||||
if ( !ptrlist_create(&list, 0, MAXIMUM_WAIT_OBJECTS) ) goto release_mutex;
|
}
|
||||||
|
hUnloadEvent = CreateEventWithStringSecurityDescriptor(L"D:(A;;0x001F0003;;;BA)",
|
||||||
hEvent = event_create_with_string_security_descriptor(
|
TRUE, FALSE, L"Global\\wufuc_UnloadEvent");
|
||||||
true, false, m_szUnloadEventName, L"D:(A;;0x001F0003;;;BA)");
|
if ( !hUnloadEvent ) {
|
||||||
if ( !hEvent ) goto destroy_list;
|
log_gle(L"Failed to create unload event!");
|
||||||
if ( !ptrlist_add(&list, hEvent, 0) ) goto set_event;
|
goto release_mutex;
|
||||||
|
}
|
||||||
dwDesiredAccess = SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG;
|
s_bWindowsSevenSP1 = VerifyVersionInfoHelper(6, 1, 1);
|
||||||
|
if ( !s_bWindowsSevenSP1 ) {
|
||||||
|
s_bWindowsEightPointOne = VerifyVersionInfoHelper(6, 3, 0);
|
||||||
|
if ( !s_bWindowsEightPointOne ) {
|
||||||
|
log_error(L"Unsupported operating system!");
|
||||||
|
goto close_event;
|
||||||
|
}
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
Lagging = false;
|
Lagging = false;
|
||||||
hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
|
hSCM = OpenSCManagerW(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
|
||||||
if ( !hSCM ) goto set_event;
|
if ( !hSCM ) break;
|
||||||
|
|
||||||
hService = OpenServiceW(hSCM, L"wuauserv", dwDesiredAccess);
|
hService = OpenServiceW(hSCM, L"wuauserv", SERVICE_QUERY_STATUS);
|
||||||
if ( !hService ) goto close_scm;
|
if ( !hService ) {
|
||||||
|
CloseServiceHandle(hSCM);
|
||||||
if ( (dwDesiredAccess & SERVICE_QUERY_CONFIG) == SERVICE_QUERY_CONFIG ) {
|
break;
|
||||||
dwDesiredAccess &= ~SERVICE_QUERY_CONFIG;
|
|
||||||
|
|
||||||
dwProcessId = svc_heuristic_process_id(hSCM, hService);
|
|
||||||
if ( dwProcessId )
|
|
||||||
wufuc_inject(dwProcessId, (LPTHREAD_START_ROUTINE)cb_start, &list);
|
|
||||||
}
|
}
|
||||||
ZeroMemory(&NotifyBuffer, sizeof NotifyBuffer);
|
ZeroMemory(&NotifyBuffer, sizeof NotifyBuffer);
|
||||||
NotifyBuffer.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
|
NotifyBuffer.dwVersion = SERVICE_NOTIFY_STATUS_CHANGE;
|
||||||
NotifyBuffer.pfnNotifyCallback = (PFN_SC_NOTIFY_CALLBACK)cb_service_notify;
|
NotifyBuffer.pfnNotifyCallback = ServiceNotifyCallback;
|
||||||
NotifyBuffer.pContext = (PVOID)&list;
|
NotifyBuffer.pContext = &Lagging;
|
||||||
while ( !Unloading && !Lagging ) {
|
|
||||||
e = NotifyServiceStatusChangeW(hService,
|
while ( true ) {
|
||||||
|
Error = NotifyServiceStatusChangeW(hService,
|
||||||
SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING,
|
SERVICE_NOTIFY_START_PENDING | SERVICE_NOTIFY_RUNNING,
|
||||||
&NotifyBuffer);
|
&NotifyBuffer);
|
||||||
switch ( e ) {
|
switch ( Error ) {
|
||||||
case ERROR_SUCCESS:
|
case ERROR_SUCCESS:
|
||||||
do {
|
do {
|
||||||
if ( !ptrlist_copy(&list, &values, &tags, &count) ) {
|
Error = WaitForSingleObjectEx(hUnloadEvent, INFINITE, TRUE);
|
||||||
Unloading = true;
|
switch ( Error ) {
|
||||||
break;
|
case WAIT_OBJECT_0:
|
||||||
|
log_info(L"Unload event signaled!");
|
||||||
|
goto exit_loop;
|
||||||
|
case WAIT_FAILED:
|
||||||
|
log_error(L"WaitForSingleObjectEx failed! Error=%lu", Error);
|
||||||
|
goto exit_loop;
|
||||||
}
|
}
|
||||||
r = WaitForMultipleObjectsEx((DWORD)count,
|
} while ( Error != WAIT_IO_COMPLETION );
|
||||||
values, FALSE, INFINITE, TRUE);
|
|
||||||
|
|
||||||
if ( r >= WAIT_OBJECT_0 && r < WAIT_OBJECT_0 + count ) {
|
|
||||||
// object signaled
|
|
||||||
index = r - WAIT_OBJECT_0;
|
|
||||||
if ( !index ) {
|
|
||||||
// Unload event
|
|
||||||
Unloading = true;
|
|
||||||
} else {
|
|
||||||
// crash mutex was released cleanly
|
|
||||||
ptrlist_remove(&list, values[index]);
|
|
||||||
ReleaseMutex(values[index]);
|
|
||||||
CloseHandle(values[index]);
|
|
||||||
}
|
|
||||||
} else if ( r >= WAIT_ABANDONED_0 && r < WAIT_ABANDONED_0 + count ) {
|
|
||||||
// object abandoned
|
|
||||||
// crash mutex was abandoned, process has most likely crashed.
|
|
||||||
index = r - WAIT_ABANDONED_0;
|
|
||||||
|
|
||||||
ptrlist_remove(&list, values[index]);
|
|
||||||
ReleaseMutex(values[index]);
|
|
||||||
CloseHandle(values[index]);
|
|
||||||
|
|
||||||
crashes++;
|
|
||||||
log_warning(L"A process wufuc injected into has crashed %Iu time%ls! (ProcessId=%lu)",
|
|
||||||
crashes, crashes != 1 ? L"s" : L"", tags[index]);
|
|
||||||
|
|
||||||
if ( crashes >= SVCHOST_CRASH_THRESHOLD ) {
|
|
||||||
log_error(L"Crash threshold has been reached, disabling wufuc until next reboot!");
|
|
||||||
Unloading = true;
|
|
||||||
Suspending = true;
|
|
||||||
}
|
|
||||||
} else if ( r == WAIT_FAILED ) {
|
|
||||||
log_error(L"Wait function failed!");
|
|
||||||
Unloading = true;
|
|
||||||
}
|
|
||||||
free(values);
|
|
||||||
free(tags);
|
|
||||||
} while ( r != WAIT_IO_COMPLETION && !Unloading );
|
|
||||||
break;
|
break;
|
||||||
case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
|
case ERROR_SERVICE_NOTIFY_CLIENT_LAGGING:
|
||||||
log_warning(L"Client lagging!");
|
log_warning(L"The service notification client is lagging too far behind the current state of services in the machine.");
|
||||||
Lagging = true;
|
Lagging = true;
|
||||||
break;
|
goto exit_loop;
|
||||||
|
case ERROR_SERVICE_MARKED_FOR_DELETE:
|
||||||
|
log_warning(L"The specified service has been marked for deletion.");
|
||||||
|
Lagging = true;
|
||||||
|
goto exit_loop;
|
||||||
default:
|
default:
|
||||||
log_error(L"NotifyServiceStatusChange failed! (Return value=%lu)", e);
|
log_error(L"NotifyServiceStatusChange failed! Error=%lu", Error);
|
||||||
Unloading = true;
|
goto exit_loop;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
exit_loop:
|
||||||
CloseServiceHandle(hService);
|
CloseServiceHandle(hService);
|
||||||
close_scm:
|
|
||||||
CloseServiceHandle(hSCM);
|
CloseServiceHandle(hSCM);
|
||||||
} while ( Lagging );
|
} while ( Lagging );
|
||||||
set_event:
|
close_event:
|
||||||
// signal event in case it is open in any other processes
|
CloseHandle(hUnloadEvent);
|
||||||
SetEvent(hEvent);
|
|
||||||
destroy_list:
|
|
||||||
ptrlist_for_each_stdcall(&list, CloseHandle);
|
|
||||||
ptrlist_destroy(&list);
|
|
||||||
|
|
||||||
if ( Suspending )
|
|
||||||
NtSuspendProcess(NtCurrentProcess());
|
|
||||||
release_mutex:
|
release_mutex:
|
||||||
ReleaseMutex(g_hMainMutex);
|
ReleaseMutex(hMutex);
|
||||||
CloseHandle(g_hMainMutex);
|
CloseHandle(hMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CALLBACK RUNDLL32_UnloadW(
|
void CALLBACK RUNDLL32_UnloadW(
|
||||||
@@ -153,7 +266,7 @@ void CALLBACK RUNDLL32_UnloadW(
|
|||||||
{
|
{
|
||||||
HANDLE hEvent;
|
HANDLE hEvent;
|
||||||
|
|
||||||
hEvent = OpenEventW(EVENT_MODIFY_STATE, FALSE, m_szUnloadEventName);
|
hEvent = OpenEventW(EVENT_MODIFY_STATE, FALSE, L"Global\\wufuc_UnloadEvent");
|
||||||
if ( hEvent ) {
|
if ( hEvent ) {
|
||||||
SetEvent(hEvent);
|
SetEvent(hEvent);
|
||||||
CloseHandle(hEvent);
|
CloseHandle(hEvent);
|
||||||
|
@@ -1,209 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "servicehelper.h"
|
|
||||||
#include "registryhelper.h"
|
|
||||||
|
|
||||||
LPQUERY_SERVICE_CONFIGW svc_query_config_by_name_alloc(
|
|
||||||
SC_HANDLE hSCM,
|
|
||||||
const wchar_t *pServiceName,
|
|
||||||
LPDWORD pcbBufSize)
|
|
||||||
{
|
|
||||||
SC_HANDLE hService;
|
|
||||||
LPQUERY_SERVICE_CONFIGW result = NULL;
|
|
||||||
|
|
||||||
hService = OpenServiceW(hSCM, pServiceName, SERVICE_QUERY_CONFIG);
|
|
||||||
if ( !hService ) return result;
|
|
||||||
|
|
||||||
result = svc_query_config_alloc(hSCM, hService, pcbBufSize);
|
|
||||||
|
|
||||||
CloseServiceHandle(hService);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPQUERY_SERVICE_CONFIGW svc_query_config_alloc(
|
|
||||||
SC_HANDLE hSCM,
|
|
||||||
SC_HANDLE hService,
|
|
||||||
LPDWORD pcbBufSize)
|
|
||||||
{
|
|
||||||
DWORD cbBytesNeeded;
|
|
||||||
LPQUERY_SERVICE_CONFIGW result = NULL;
|
|
||||||
|
|
||||||
if ( !QueryServiceConfigW(hService, NULL, 0, &cbBytesNeeded)
|
|
||||||
&& GetLastError() == ERROR_INSUFFICIENT_BUFFER ) {
|
|
||||||
|
|
||||||
result = malloc(cbBytesNeeded);
|
|
||||||
if ( result ) {
|
|
||||||
if ( QueryServiceConfigW(hService, result, cbBytesNeeded, &cbBytesNeeded) ) {
|
|
||||||
if ( pcbBufSize )
|
|
||||||
*pcbBufSize = cbBytesNeeded;
|
|
||||||
} else {
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool svc_query_process_info_by_name(
|
|
||||||
SC_HANDLE hSCM,
|
|
||||||
const wchar_t *pServiceName,
|
|
||||||
LPSERVICE_STATUS_PROCESS pServiceStatus)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
SC_HANDLE hService;
|
|
||||||
DWORD cbBytesNeeded;
|
|
||||||
|
|
||||||
hService = OpenServiceW(hSCM, pServiceName, SERVICE_QUERY_STATUS);
|
|
||||||
if ( !hService )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
result = !!QueryServiceStatusEx(hService,
|
|
||||||
SC_STATUS_PROCESS_INFO,
|
|
||||||
(LPBYTE)pServiceStatus,
|
|
||||||
sizeof *pServiceStatus,
|
|
||||||
&cbBytesNeeded);
|
|
||||||
CloseServiceHandle(hService);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool svc_query_group_name(
|
|
||||||
const LPQUERY_SERVICE_CONFIGW pServiceConfig,
|
|
||||||
wchar_t **pGroupName,
|
|
||||||
HLOCAL *hMem)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
int NumArgs;
|
|
||||||
wchar_t **argv;
|
|
||||||
|
|
||||||
argv = CommandLineToArgvW(pServiceConfig->lpBinaryPathName, &NumArgs);
|
|
||||||
if ( argv ) {
|
|
||||||
if ( !_wcsicmp(PathFindFileNameW(argv[0]), L"svchost.exe") ) {
|
|
||||||
|
|
||||||
for ( int i = 1; (i + 1) < NumArgs; i++ ) {
|
|
||||||
if ( !_wcsicmp(argv[i], L"-k") ) {
|
|
||||||
*pGroupName = argv[++i];
|
|
||||||
*hMem = (HLOCAL)argv;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
LocalFree((HLOCAL)argv);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD svc_query_process_id(SC_HANDLE hSCM, SC_HANDLE hService)
|
|
||||||
{
|
|
||||||
DWORD result = 0;
|
|
||||||
SERVICE_STATUS_PROCESS ServiceStatus;
|
|
||||||
DWORD cbBytesNeeded;
|
|
||||||
|
|
||||||
if ( QueryServiceStatusEx(hService,
|
|
||||||
SC_STATUS_PROCESS_INFO,
|
|
||||||
(LPBYTE)&ServiceStatus,
|
|
||||||
sizeof ServiceStatus,
|
|
||||||
&cbBytesNeeded) ) {
|
|
||||||
|
|
||||||
result = ServiceStatus.dwProcessId;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD svc_query_process_id_by_name(SC_HANDLE hSCM, const wchar_t *pServiceName)
|
|
||||||
{
|
|
||||||
SERVICE_STATUS_PROCESS ServiceStatusProcess;
|
|
||||||
|
|
||||||
if ( svc_query_process_info_by_name(hSCM, pServiceName, &ServiceStatusProcess) )
|
|
||||||
return ServiceStatusProcess.dwProcessId;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD svc_heuristic_group_process_id(SC_HANDLE hSCM, const wchar_t *pGroupNameSearch)
|
|
||||||
{
|
|
||||||
wchar_t *pData;
|
|
||||||
DWORD result = 0;
|
|
||||||
DWORD dwProcessId;
|
|
||||||
DWORD cbBufSize;
|
|
||||||
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
|
||||||
bool success = false;
|
|
||||||
wchar_t *pGroupName;
|
|
||||||
HLOCAL hMem;
|
|
||||||
|
|
||||||
pData = reg_get_value_alloc(HKEY_LOCAL_MACHINE,
|
|
||||||
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost",
|
|
||||||
pGroupNameSearch,
|
|
||||||
RRF_RT_REG_MULTI_SZ,
|
|
||||||
NULL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
if ( !pData ) return result;
|
|
||||||
|
|
||||||
for ( wchar_t *pName = pData; *pName; pName += wcslen(pName) + 1 ) {
|
|
||||||
dwProcessId = svc_query_process_id_by_name(hSCM, pName);
|
|
||||||
if ( !dwProcessId ) continue;
|
|
||||||
|
|
||||||
pServiceConfig = svc_query_config_by_name_alloc(hSCM, pName, &cbBufSize);
|
|
||||||
if ( !pServiceConfig ) continue;
|
|
||||||
|
|
||||||
if ( pServiceConfig->dwServiceType == SERVICE_WIN32_SHARE_PROCESS
|
|
||||||
&& svc_query_group_name(pServiceConfig, &pGroupName, &hMem) ) {
|
|
||||||
|
|
||||||
success = !_wcsicmp(pGroupNameSearch, pGroupName);
|
|
||||||
LocalFree(hMem);
|
|
||||||
}
|
|
||||||
free(pServiceConfig);
|
|
||||||
if ( success ) {
|
|
||||||
result = dwProcessId;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free(pData);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD svc_heuristic_process_id(SC_HANDLE hSCM, SC_HANDLE hService)
|
|
||||||
{
|
|
||||||
DWORD result = 0;
|
|
||||||
LPQUERY_SERVICE_CONFIGW pServiceConfig;
|
|
||||||
wchar_t *pGroupName;
|
|
||||||
HLOCAL hMem;
|
|
||||||
|
|
||||||
result = svc_query_process_id(hSCM, hService);
|
|
||||||
if ( result )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
pServiceConfig = svc_query_config_alloc(hSCM, hService, NULL);
|
|
||||||
if ( pServiceConfig ) {
|
|
||||||
switch ( pServiceConfig->dwServiceType ) {
|
|
||||||
case SERVICE_WIN32_OWN_PROCESS:
|
|
||||||
// if the service isn't already running there's no
|
|
||||||
// way to accurately guess the PID when it is set to
|
|
||||||
// run in its own process. returns 0
|
|
||||||
break;
|
|
||||||
case SERVICE_WIN32_SHARE_PROCESS:
|
|
||||||
// when the service is configured to run in a shared
|
|
||||||
// process, it is possible to "guess" which svchost.exe
|
|
||||||
// it will eventually be loaded into by finding other
|
|
||||||
// services in the same group that are already running.
|
|
||||||
if ( svc_query_group_name(pServiceConfig, &pGroupName, &hMem) ) {
|
|
||||||
result = svc_heuristic_group_process_id(hSCM, pGroupName);
|
|
||||||
LocalFree(hMem);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(pServiceConfig);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD svc_heuristic_process_id_by_name(SC_HANDLE hSCM, const wchar_t *pServiceName)
|
|
||||||
{
|
|
||||||
DWORD result = 0;
|
|
||||||
SC_HANDLE hService;
|
|
||||||
|
|
||||||
hService = OpenServiceW(hSCM, pServiceName, SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG);
|
|
||||||
result = svc_heuristic_process_id(hSCM, hService);
|
|
||||||
CloseServiceHandle(hService);
|
|
||||||
return result;
|
|
||||||
|
|
||||||
}
|
|
@@ -1,23 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
LPQUERY_SERVICE_CONFIGW svc_query_config_by_name_alloc(
|
|
||||||
SC_HANDLE hSCM,
|
|
||||||
const wchar_t *pServiceName,
|
|
||||||
LPDWORD pcbBufSize);
|
|
||||||
LPQUERY_SERVICE_CONFIGW svc_query_config_alloc(
|
|
||||||
SC_HANDLE hSCM,
|
|
||||||
SC_HANDLE hService,
|
|
||||||
LPDWORD pcbBufSize);
|
|
||||||
bool svc_query_process_info_by_name(
|
|
||||||
SC_HANDLE hSCM,
|
|
||||||
const wchar_t *pServiceName,
|
|
||||||
LPSERVICE_STATUS_PROCESS pServiceStatus);
|
|
||||||
bool svc_query_group_name(
|
|
||||||
const LPQUERY_SERVICE_CONFIGW pServiceConfig,
|
|
||||||
wchar_t **pGroupName,
|
|
||||||
HLOCAL *hMem);
|
|
||||||
DWORD svc_query_process_id(SC_HANDLE hSCM, SC_HANDLE hService);
|
|
||||||
DWORD svc_query_process_id_by_name(SC_HANDLE hSCM, const wchar_t *pServiceName);
|
|
||||||
DWORD svc_heuristic_group_process_id(SC_HANDLE hSCM, const wchar_t *pGroupName);
|
|
||||||
DWORD svc_heuristic_process_id(SC_HANDLE hSCM, SC_HANDLE hService);
|
|
||||||
DWORD svc_heuristic_process_id_by_name(SC_HANDLE hSCM, const wchar_t *pServiceName);
|
|
@@ -11,15 +11,12 @@
|
|||||||
#include <phnt_windows.h>
|
#include <phnt_windows.h>
|
||||||
#include <phnt.h>
|
#include <phnt.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// TODO: reference additional headers your program requires here
|
// TODO: reference additional headers your program requires here
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <share.h>
|
|
||||||
|
|
||||||
#include <strsafe.h>
|
#include <strsafe.h>
|
||||||
#include <shellapi.h>
|
#include <shellapi.h>
|
||||||
@@ -27,6 +24,10 @@
|
|||||||
#include <Psapi.h>
|
#include <Psapi.h>
|
||||||
#include <TlHelp32.h>
|
#include <TlHelp32.h>
|
||||||
|
|
||||||
|
#include "asprintf.h"
|
||||||
|
#include "logger.h"
|
||||||
|
|
||||||
extern IMAGE_DOS_HEADER __ImageBase;
|
extern IMAGE_DOS_HEADER __ImageBase;
|
||||||
#define PIMAGEBASE ((HMODULE)&__ImageBase)
|
#define PIMAGEBASE ((HMODULE)&__ImageBase)
|
||||||
|
#define OffsetToPointer(Base, Offset) ((void *)(((uint8_t *)(Base)) + ((ptrdiff_t)(Offset))))
|
||||||
|
#define PointerToOffset(Base, Pointer) ((ptrdiff_t)(((uint8_t *)(Pointer)) - ((uint8_t *)(Base))))
|
||||||
|
26
src/wufuc/utf8.c
Normal file
26
src/wufuc/utf8.c
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
|
DWORD UTF8WriteFile(HANDLE hFile, LPCWSTR lpWideCharStr)
|
||||||
|
{
|
||||||
|
int cchWideChar;
|
||||||
|
int size;
|
||||||
|
char *buffer;
|
||||||
|
DWORD NumberOfBytesWritten = 0;
|
||||||
|
|
||||||
|
cchWideChar = lstrlenW(lpWideCharStr);
|
||||||
|
|
||||||
|
size = WideCharToMultiByte(CP_UTF8, 0, lpWideCharStr, cchWideChar, NULL, 0, NULL, NULL);
|
||||||
|
if ( !size )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
buffer = malloc(size);
|
||||||
|
if ( !buffer )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( WideCharToMultiByte(CP_UTF8, 0, lpWideCharStr, cchWideChar, buffer, size, NULL, NULL) )
|
||||||
|
WriteFile(hFile, buffer, size, &NumberOfBytesWritten, NULL);
|
||||||
|
|
||||||
|
free(buffer);
|
||||||
|
return NumberOfBytesWritten;
|
||||||
|
}
|
3
src/wufuc/utf8.h
Normal file
3
src/wufuc/utf8.h
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
DWORD UTF8WriteFile(HANDLE hFile, LPCWSTR lpWideCharStr);
|
@@ -1,108 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "versionhelper.h"
|
|
||||||
|
|
||||||
int ver_compare_product_version(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;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ver_get_version_info_from_hmodule(HMODULE hModule, const wchar_t *pszSubBlock, LPVOID pData, PUINT pcbData)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
UINT cbData;
|
|
||||||
HRSRC hResInfo;
|
|
||||||
DWORD dwSize;
|
|
||||||
HGLOBAL hResData;
|
|
||||||
LPVOID pRes;
|
|
||||||
LPVOID pCopy;
|
|
||||||
LPVOID pBuffer;
|
|
||||||
UINT uLen;
|
|
||||||
|
|
||||||
if ( !pcbData ) return result;
|
|
||||||
cbData = *pcbData;
|
|
||||||
|
|
||||||
hResInfo = FindResourceW(hModule,
|
|
||||||
MAKEINTRESOURCEW(VS_VERSION_INFO),
|
|
||||||
RT_VERSION);
|
|
||||||
if ( !hResInfo ) return result;
|
|
||||||
|
|
||||||
dwSize = SizeofResource(hModule, hResInfo);
|
|
||||||
if ( !dwSize ) return result;
|
|
||||||
|
|
||||||
hResData = LoadResource(hModule, hResInfo);
|
|
||||||
if ( !hResData ) return result;
|
|
||||||
|
|
||||||
pRes = LockResource(hResData);
|
|
||||||
if ( !pRes ) return result;
|
|
||||||
|
|
||||||
pCopy = malloc(dwSize);
|
|
||||||
if ( !pCopy ) return result;
|
|
||||||
|
|
||||||
if ( memcpy_s(pCopy, dwSize, pRes, dwSize)
|
|
||||||
|| !VerQueryValueW(pCopy, pszSubBlock, &pBuffer, &uLen) )
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if ( !_wcsnicmp(pszSubBlock, L"\\StringFileInfo\\", 16) )
|
|
||||||
*pcbData = uLen * sizeof(wchar_t);
|
|
||||||
else
|
|
||||||
*pcbData = uLen;
|
|
||||||
|
|
||||||
if ( !pData ) {
|
|
||||||
result = true;
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if ( cbData < *pcbData
|
|
||||||
|| memcpy_s(pData, cbData, pBuffer, *pcbData) )
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
result = true;
|
|
||||||
cleanup:
|
|
||||||
free(pCopy);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
LPVOID ver_get_version_info_from_hmodule_alloc(HMODULE hModule, const wchar_t *pszSubBlock, PUINT pcbData)
|
|
||||||
{
|
|
||||||
UINT cbData = 0;
|
|
||||||
LPVOID result = NULL;
|
|
||||||
|
|
||||||
if ( !ver_get_version_info_from_hmodule(hModule, pszSubBlock, NULL, &cbData) )
|
|
||||||
return result;
|
|
||||||
|
|
||||||
result = malloc(cbData);
|
|
||||||
if ( !result ) return result;
|
|
||||||
|
|
||||||
if ( ver_get_version_info_from_hmodule(hModule, pszSubBlock, result, &cbData) ) {
|
|
||||||
*pcbData = cbData;
|
|
||||||
} else {
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ver_verify_version_info(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
|
|
||||||
{
|
|
||||||
DWORDLONG dwlConditionMask = 0;
|
|
||||||
OSVERSIONINFOEXW osvi = { sizeof osvi };
|
|
||||||
|
|
||||||
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_EQUAL);
|
|
||||||
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_EQUAL);
|
|
||||||
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, VER_GREATER_EQUAL);
|
|
||||||
|
|
||||||
osvi.dwMajorVersion = wMajorVersion;
|
|
||||||
osvi.dwMinorVersion = wMinorVersion;
|
|
||||||
osvi.wServicePackMajor = wServicePackMajor;
|
|
||||||
|
|
||||||
return VerifyVersionInfoW(&osvi,
|
|
||||||
VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR,
|
|
||||||
dwlConditionMask) != FALSE;
|
|
||||||
}
|
|
@@ -1,6 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
int ver_compare_product_version(VS_FIXEDFILEINFO *pffi, WORD wMajor, WORD wMinor, WORD wBuild, WORD wRev);
|
|
||||||
bool ver_get_version_info_from_hmodule(HMODULE hModule, const wchar_t *pszSubBlock, LPVOID pData, PUINT pcbData);
|
|
||||||
LPVOID ver_get_version_info_from_hmodule_alloc(HMODULE hModule, const wchar_t *pszSubBlock, PUINT pcbData);
|
|
||||||
bool ver_verify_version_info(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor);
|
|
130
src/wufuc/versioninfo.c
Normal file
130
src/wufuc/versioninfo.c
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
#include "stdafx.h"
|
||||||
|
#include "versioninfo.h"
|
||||||
|
|
||||||
|
DWORD GetModuleVersionInfo(HMODULE hModule, LPVOID *lplpData)
|
||||||
|
{
|
||||||
|
HRSRC hResInfo;
|
||||||
|
DWORD result;
|
||||||
|
HGLOBAL hResData;
|
||||||
|
LPVOID pRes;
|
||||||
|
LPVOID lpData;
|
||||||
|
|
||||||
|
hResInfo = FindResourceW(hModule,
|
||||||
|
MAKEINTRESOURCEW(VS_VERSION_INFO),
|
||||||
|
MAKEINTRESOURCEW(RT_VERSION));
|
||||||
|
if ( !hResInfo ) return 0;
|
||||||
|
|
||||||
|
result = SizeofResource(hModule, hResInfo);
|
||||||
|
if ( !result ) return 0;
|
||||||
|
|
||||||
|
hResData = LoadResource(hModule, hResInfo);
|
||||||
|
if ( !hResData ) return 0;
|
||||||
|
|
||||||
|
pRes = LockResource(hResData);
|
||||||
|
if ( !pRes ) return 0;
|
||||||
|
|
||||||
|
lpData = malloc(result);
|
||||||
|
if ( !lpData ) return 0;
|
||||||
|
|
||||||
|
if ( !memcpy_s(lpData, result, pRes, result) ) {
|
||||||
|
*lplpData = lpData;
|
||||||
|
} else {
|
||||||
|
free(lpData);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
DWORD GetFileVersionInfoExAlloc(DWORD dwFlags, BOOL bPrefetched, LPCWSTR lpwstrFilename, LPVOID *lplpData)
|
||||||
|
{
|
||||||
|
DWORD result;
|
||||||
|
DWORD dwHandle;
|
||||||
|
LPVOID lpData;
|
||||||
|
|
||||||
|
result = GetFileVersionInfoSizeExW(dwFlags,
|
||||||
|
lpwstrFilename,
|
||||||
|
&dwHandle);
|
||||||
|
if ( !result ) return 0;
|
||||||
|
|
||||||
|
lpData = malloc(result);
|
||||||
|
if ( !lpData ) return 0;
|
||||||
|
|
||||||
|
if ( GetFileVersionInfoExW(bPrefetched ? (dwFlags | FILE_VER_GET_PREFETCHED) : dwFlags,
|
||||||
|
lpwstrFilename,
|
||||||
|
dwHandle,
|
||||||
|
result,
|
||||||
|
lpData) ) {
|
||||||
|
*lplpData = lpData;
|
||||||
|
} else {
|
||||||
|
free(lpData);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT VerQueryString(LPCVOID pBlock, LANGANDCODEPAGE LangCodePage, LPCWSTR lpName, LPWSTR *lplpString)
|
||||||
|
{
|
||||||
|
LPWSTR pszSubBlock;
|
||||||
|
LPVOID lpBuffer;
|
||||||
|
UINT result = 0;
|
||||||
|
|
||||||
|
if ( aswprintf(&pszSubBlock,
|
||||||
|
L"\\StringFileInfo\\%04x%04x\\%ls",
|
||||||
|
LangCodePage.wLanguage,
|
||||||
|
LangCodePage.wCodePage,
|
||||||
|
lpName) == -1 )
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if ( VerQueryValueW(pBlock, pszSubBlock, &lpBuffer, &result) )
|
||||||
|
*lplpString = (LPWSTR)lpBuffer;
|
||||||
|
|
||||||
|
free(pszSubBlock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT VerQueryTranslations(LPCVOID pBlock, PLANGANDCODEPAGE *lplpTranslate)
|
||||||
|
{
|
||||||
|
PLANGANDCODEPAGE lpTranslate;
|
||||||
|
UINT uLen;
|
||||||
|
|
||||||
|
if ( VerQueryValueW(pBlock, L"\\VarFileInfo\\Translation", &(LPVOID)lpTranslate, &uLen) ) {
|
||||||
|
*lplpTranslate = lpTranslate;
|
||||||
|
return uLen / (sizeof *lpTranslate);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT VerQueryFileInfo(LPCVOID pBlock, VS_FIXEDFILEINFO **lplpffi)
|
||||||
|
{
|
||||||
|
VS_FIXEDFILEINFO *lpffi;
|
||||||
|
UINT result;
|
||||||
|
|
||||||
|
if ( VerQueryValueW(pBlock, L"\\", &(LPVOID)lpffi, &result) ) {
|
||||||
|
*lplpffi = lpffi;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int vercmp(DWORD dwMS, DWORD dwLS, WORD wMajor, WORD wMinor, WORD wBuild, WORD wRev)
|
||||||
|
{
|
||||||
|
WORD w;
|
||||||
|
|
||||||
|
w = HIWORD(dwMS);
|
||||||
|
if ( w < wMajor ) return -1;
|
||||||
|
if ( w > wMajor ) return 1;
|
||||||
|
|
||||||
|
w = LOWORD(dwMS);
|
||||||
|
if ( w < wMinor ) return -1;
|
||||||
|
if ( w > wMinor ) return 1;
|
||||||
|
|
||||||
|
w = HIWORD(dwLS);
|
||||||
|
if ( w < wBuild ) return -1;
|
||||||
|
if ( w > wBuild ) return 1;
|
||||||
|
|
||||||
|
w = LOWORD(dwLS);
|
||||||
|
if ( w < wRev ) return -1;
|
||||||
|
if ( w > wRev ) return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
19
src/wufuc/versioninfo.h
Normal file
19
src/wufuc/versioninfo.h
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
WORD wLanguage;
|
||||||
|
WORD wCodePage;
|
||||||
|
} LANGANDCODEPAGE, *PLANGANDCODEPAGE;
|
||||||
|
|
||||||
|
DWORD GetModuleVersionInfo(HMODULE hModule, LPVOID *lplpData);
|
||||||
|
|
||||||
|
DWORD GetFileVersionInfoExAlloc(DWORD dwFlags, BOOL bPrefetched, LPCWSTR lpwstrFilename, LPVOID *lplpData);
|
||||||
|
|
||||||
|
UINT VerQueryString(LPCVOID pBlock, LANGANDCODEPAGE LangCodePage, LPCWSTR lpName, LPWSTR *lplpString);
|
||||||
|
|
||||||
|
UINT VerQueryTranslations(LPCVOID pBlock, PLANGANDCODEPAGE *lplpTranslate);
|
||||||
|
|
||||||
|
UINT VerQueryFileInfo(LPCVOID pBlock, VS_FIXEDFILEINFO **lplpffi);
|
||||||
|
|
||||||
|
int vercmp(DWORD dwMS, DWORD dwLS, WORD wMajor, WORD wMinor, WORD wBuild, WORD wRev);
|
@@ -1,194 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "ptrlist.h"
|
|
||||||
#include "wufuc.h"
|
|
||||||
#include "hooks.h"
|
|
||||||
#include "log.h"
|
|
||||||
#include "modulehelper.h"
|
|
||||||
#include "mutexhelper.h"
|
|
||||||
#include "patternfind.h"
|
|
||||||
#include "versionhelper.h"
|
|
||||||
|
|
||||||
#include <minhook.h>
|
|
||||||
|
|
||||||
HANDLE g_hMainMutex;
|
|
||||||
|
|
||||||
bool close_remote_handle(HANDLE hProcess, HANDLE hObject)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
DWORD ExitCode;
|
|
||||||
HANDLE hThread;
|
|
||||||
|
|
||||||
hThread = CreateRemoteThread(hProcess,
|
|
||||||
NULL,
|
|
||||||
0,
|
|
||||||
(LPTHREAD_START_ROUTINE)CloseHandle,
|
|
||||||
(LPVOID)hObject,
|
|
||||||
0,
|
|
||||||
NULL);
|
|
||||||
if ( hThread ) {
|
|
||||||
if ( WaitForSingleObject(hThread, INFINITE) == WAIT_OBJECT_0
|
|
||||||
&& GetExitCodeThread(hThread, &ExitCode) ) {
|
|
||||||
|
|
||||||
result = !!ExitCode;
|
|
||||||
}
|
|
||||||
CloseHandle(hThread);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wufuc_inject(DWORD dwProcessId,
|
|
||||||
LPTHREAD_START_ROUTINE pStartAddress,
|
|
||||||
ptrlist_t *list)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
HANDLE hCrashMutex;
|
|
||||||
HANDLE hProcess;
|
|
||||||
HANDLE h;
|
|
||||||
HANDLE hProceedEvent;
|
|
||||||
HANDLE p[4];
|
|
||||||
|
|
||||||
hCrashMutex = mutex_create_new_fmt(false, L"Global\\wufuc_CrashMutex*%08x", dwProcessId);
|
|
||||||
if ( !hCrashMutex ) return result;
|
|
||||||
if ( !ptrlist_add(list, hCrashMutex, dwProcessId) )
|
|
||||||
goto close_mutex;
|
|
||||||
|
|
||||||
hProceedEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
|
|
||||||
if ( !hProceedEvent ) goto close_mutex;
|
|
||||||
|
|
||||||
hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
|
|
||||||
if ( !hProcess ) goto close_pevent;
|
|
||||||
|
|
||||||
h = GetCurrentProcess();
|
|
||||||
if ( !DuplicateHandle(h, g_hMainMutex, hProcess, &p[0], SYNCHRONIZE, FALSE, 0) )
|
|
||||||
goto close_process;
|
|
||||||
if ( !DuplicateHandle(h, ptrlist_at(list, 0, NULL), hProcess, &p[1], SYNCHRONIZE, FALSE, 0) )
|
|
||||||
goto close_p0;
|
|
||||||
if ( !DuplicateHandle(h, hCrashMutex, hProcess, &p[2], 0, FALSE, DUPLICATE_SAME_ACCESS) )
|
|
||||||
goto close_p1;
|
|
||||||
if ( !DuplicateHandle(h, hProceedEvent, hProcess, &p[3], EVENT_MODIFY_STATE, FALSE, 0) )
|
|
||||||
goto close_p2;
|
|
||||||
|
|
||||||
result = mod_inject_and_begin_thread(hProcess, PIMAGEBASE, pStartAddress, p, sizeof p);
|
|
||||||
|
|
||||||
if ( result ) {
|
|
||||||
// wait for injected thread to signal that it has taken
|
|
||||||
// ownership of hCrashMutex before proceeding.
|
|
||||||
result = WaitForSingleObject(hProceedEvent, 5000) != WAIT_TIMEOUT;
|
|
||||||
} else {
|
|
||||||
close_remote_handle(hProcess, p[3]);
|
|
||||||
close_p2:
|
|
||||||
close_remote_handle(hProcess, p[2]);
|
|
||||||
close_p1:
|
|
||||||
close_remote_handle(hProcess, p[1]);
|
|
||||||
close_p0:
|
|
||||||
close_remote_handle(hProcess, p[0]);
|
|
||||||
}
|
|
||||||
close_process:
|
|
||||||
CloseHandle(hProcess);
|
|
||||||
close_pevent:
|
|
||||||
CloseHandle(hProceedEvent);
|
|
||||||
if ( !result ) {
|
|
||||||
close_mutex:
|
|
||||||
ptrlist_remove(list, hCrashMutex);
|
|
||||||
CloseHandle(hCrashMutex);
|
|
||||||
}
|
|
||||||
if ( result )
|
|
||||||
log_info(L"Successfully injected into process! (ProcessId=%lu)", dwProcessId);
|
|
||||||
else
|
|
||||||
log_warning(L"Failed to inject into process! (ProcessId=%lu)", dwProcessId);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool wufuc_hook(HMODULE hModule)
|
|
||||||
{
|
|
||||||
bool result = false;
|
|
||||||
PLANGANDCODEPAGE ptl;
|
|
||||||
HANDLE hProcess;
|
|
||||||
UINT cbtl;
|
|
||||||
wchar_t SubBlock[38];
|
|
||||||
wchar_t *pInternalName;
|
|
||||||
UINT cbInternalName;
|
|
||||||
VS_FIXEDFILEINFO *pffi;
|
|
||||||
UINT cbffi;
|
|
||||||
bool tmp;
|
|
||||||
MODULEINFO modinfo;
|
|
||||||
size_t offset;
|
|
||||||
LPVOID pTarget = NULL;
|
|
||||||
MH_STATUS status;
|
|
||||||
|
|
||||||
ptl = ver_get_version_info_from_hmodule_alloc(hModule, L"\\VarFileInfo\\Translation", &cbtl);
|
|
||||||
if ( !ptl ) {
|
|
||||||
log_error(L"ver_get_version_info_from_hmodule_alloc failed!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
hProcess = GetCurrentProcess();
|
|
||||||
|
|
||||||
for ( size_t i = 0, count = (cbtl / sizeof *ptl); i < count; i++ ) {
|
|
||||||
if ( swprintf_s(SubBlock,
|
|
||||||
_countof(SubBlock),
|
|
||||||
L"\\StringFileInfo\\%04x%04x\\InternalName",
|
|
||||||
ptl[i].wLanguage,
|
|
||||||
ptl[i].wCodePage) == -1 )
|
|
||||||
continue;
|
|
||||||
|
|
||||||
pInternalName = ver_get_version_info_from_hmodule_alloc(hModule, SubBlock, &cbInternalName);
|
|
||||||
if ( !pInternalName ) {
|
|
||||||
log_error(L"ver_get_version_info_from_hmodule_alloc failed!");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// identify wuaueng.dll by its resource data
|
|
||||||
if ( _wcsicmp(pInternalName, L"wuaueng.dll") ) {
|
|
||||||
log_error(L"Module internal name does not match! (InternalName=%ls)", pInternalName);
|
|
||||||
goto free_iname;
|
|
||||||
}
|
|
||||||
pffi = ver_get_version_info_from_hmodule_alloc(hModule, L"\\", &cbffi);
|
|
||||||
if ( !pffi ) {
|
|
||||||
log_error(L"ver_get_version_info_from_hmodule_alloc failed!");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
// assure wuaueng.dll version is supported
|
|
||||||
tmp = ((ver_verify_version_info(6, 1, 0) && ver_compare_product_version(pffi, 7, 6, 7601, 23714) != -1)
|
|
||||||
|| (ver_verify_version_info(6, 3, 0) && ver_compare_product_version(pffi, 7, 9, 9600, 18621) != -1));
|
|
||||||
|
|
||||||
log_info(L"%ls Windows Update Agent version: %hu.%hu.%hu.%hu",
|
|
||||||
tmp ? L"Supported" : L"Unsupported",
|
|
||||||
HIWORD(pffi->dwProductVersionMS),
|
|
||||||
LOWORD(pffi->dwProductVersionMS),
|
|
||||||
HIWORD(pffi->dwProductVersionLS),
|
|
||||||
LOWORD(pffi->dwProductVersionLS));
|
|
||||||
free(pffi);
|
|
||||||
if ( !tmp ) break;
|
|
||||||
|
|
||||||
if ( !GetModuleInformation(hProcess, hModule, &modinfo, sizeof modinfo) ) {
|
|
||||||
log_error(L"GetModuleInformation failed! (hModule=%p, GLE=%lu)",
|
|
||||||
hModule, GetLastError());
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
offset = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage,
|
|
||||||
#ifdef _WIN64
|
|
||||||
"FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????"
|
|
||||||
#else
|
|
||||||
ver_verify_version_info(6, 1, 0)
|
|
||||||
? "833D????????00 743E E8???????? A3????????"
|
|
||||||
: "8BFF 51 833D????????00 7507 A1????????"
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
if ( offset != -1 ) {
|
|
||||||
pTarget = (LPVOID)RtlOffsetToPointer(modinfo.lpBaseOfDll, offset);
|
|
||||||
log_info(L"Matched IsDeviceServiceable function! (Offset=%IX, Address=%p)", offset, pTarget);
|
|
||||||
|
|
||||||
status = MH_CreateHook(pTarget, IsDeviceServiceable_hook, NULL);
|
|
||||||
if ( status == MH_OK ) {
|
|
||||||
status = MH_EnableHook(pTarget);
|
|
||||||
if ( status == MH_OK )
|
|
||||||
log_info(L"Hooked IsDeviceServiceable! (Address=%p)", pTarget);
|
|
||||||
else log_error(L"Failed to enable IsDeviceServiceable hook! (Status=%hs)", MH_StatusToString(status));
|
|
||||||
} else log_error(L"Failed to create IsDeviceServiceable hook! (Status=%hs)", MH_StatusToString(status));
|
|
||||||
} else log_info(L"Couldn't match IsDeviceServiceable function! (Already patched?)");
|
|
||||||
free_iname:
|
|
||||||
free(pInternalName);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
free(ptl);
|
|
||||||
return result;
|
|
||||||
}
|
|
@@ -1,15 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
WORD wLanguage;
|
|
||||||
WORD wCodePage;
|
|
||||||
} LANGANDCODEPAGE, *PLANGANDCODEPAGE;
|
|
||||||
|
|
||||||
#define SVCHOST_CRASH_THRESHOLD 3
|
|
||||||
extern HANDLE g_hMainMutex;
|
|
||||||
|
|
||||||
bool wufuc_inject(DWORD dwProcessId,
|
|
||||||
LPTHREAD_START_ROUTINE pStartAddress,
|
|
||||||
ptrlist_t *list);
|
|
||||||
bool wufuc_hook(HMODULE hModule);
|
|
@@ -19,34 +19,27 @@
|
|||||||
</ProjectConfiguration>
|
</ProjectConfiguration>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="callbacks.h" />
|
<ClInclude Include="asprintf.h" />
|
||||||
<ClInclude Include="eventhelper.h" />
|
<ClInclude Include="logger.h" />
|
||||||
<ClInclude Include="mutexhelper.h" />
|
<ClInclude Include="memory.h" />
|
||||||
<ClInclude Include="ptrlist.h" />
|
<ClInclude Include="modules.h" />
|
||||||
<ClInclude Include="log.h" />
|
<ClInclude Include="registry.h" />
|
||||||
<ClInclude Include="modulehelper.h" />
|
<ClInclude Include="helpers.h" />
|
||||||
<ClInclude Include="registryhelper.h" />
|
<ClInclude Include="utf8.h" />
|
||||||
<ClInclude Include="servicehelper.h" />
|
<ClInclude Include="versioninfo.h" />
|
||||||
<ClInclude Include="versionhelper.h" />
|
<ClInclude Include="verify.h" />
|
||||||
<ClInclude Include="hooks.h" />
|
|
||||||
<ClInclude Include="patternfind.h" />
|
<ClInclude Include="patternfind.h" />
|
||||||
<ClInclude Include="stdafx.h" />
|
<ClInclude Include="stdafx.h" />
|
||||||
<ClInclude Include="targetver.h" />
|
<ClInclude Include="targetver.h" />
|
||||||
<ClInclude Include="wufuc.h" />
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="callbacks.c" />
|
<ClCompile Include="asprintf.c" />
|
||||||
<ClCompile Include="dllmain.c" />
|
<ClCompile Include="dllmain.c" />
|
||||||
<ClCompile Include="eventhelper.c" />
|
<ClCompile Include="logger.c" />
|
||||||
<ClCompile Include="ptrlist.c" />
|
<ClCompile Include="memory.c" />
|
||||||
<ClCompile Include="modulehelper.c" />
|
<ClCompile Include="modules.c" />
|
||||||
<ClCompile Include="registryhelper.c" />
|
|
||||||
<ClCompile Include="servicehelper.c" />
|
|
||||||
<ClCompile Include="mutexhelper.c" />
|
|
||||||
<ClCompile Include="versionhelper.c" />
|
|
||||||
<ClCompile Include="hooks.c" />
|
|
||||||
<ClCompile Include="log.c" />
|
|
||||||
<ClCompile Include="patternfind.c" />
|
<ClCompile Include="patternfind.c" />
|
||||||
|
<ClCompile Include="registry.c" />
|
||||||
<ClCompile Include="stdafx.c">
|
<ClCompile Include="stdafx.c">
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||||
@@ -54,7 +47,9 @@
|
|||||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="rundll32.c" />
|
<ClCompile Include="rundll32.c" />
|
||||||
<ClCompile Include="wufuc.c" />
|
<ClCompile Include="helpers.c" />
|
||||||
|
<ClCompile Include="utf8.c" />
|
||||||
|
<ClCompile Include="versioninfo.c" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<None Include="exports.def" />
|
<None Include="exports.def" />
|
||||||
@@ -123,8 +118,8 @@
|
|||||||
<IntDir>$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\</IntDir>
|
<IntDir>$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||||
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
<IncludePath>$(SolutionDir)..\inc\phnt;$(SolutionDir)..\inc\minhook;$(IncludePath)</IncludePath>
|
<IncludePath>$(SolutionDir)..\inc\phnt;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>$(SolutionDir)..\lib\minhook;$(LibraryPath)</LibraryPath>
|
<LibraryPath>$(SolutionDir)..\lib\x86;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<LinkIncremental>true</LinkIncremental>
|
<LinkIncremental>true</LinkIncremental>
|
||||||
@@ -132,8 +127,8 @@
|
|||||||
<IntDir>$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\</IntDir>
|
<IntDir>$(ProjectDir)$(BaseIntermediateOutputPath)$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||||
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
<IncludePath>$(SolutionDir)..\inc\phnt;$(SolutionDir)..\inc\minhook;$(IncludePath)</IncludePath>
|
<IncludePath>$(SolutionDir)..\inc\phnt;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>$(SolutionDir)..\lib\minhook;$(LibraryPath)</LibraryPath>
|
<LibraryPath>$(SolutionDir)..\lib\x64;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
@@ -141,8 +136,8 @@
|
|||||||
<IntDir>$(ProjectDir)obj\$(Configuration)\$(PlatformShortName)\</IntDir>
|
<IntDir>$(ProjectDir)obj\$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||||
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
<IncludePath>$(SolutionDir)..\inc\phnt;$(SolutionDir)..\inc\minhook;$(IncludePath)</IncludePath>
|
<IncludePath>$(SolutionDir)..\inc\phnt;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>$(SolutionDir)..\lib\minhook;$(LibraryPath)</LibraryPath>
|
<LibraryPath>$(SolutionDir)..\lib\x86;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
<LinkIncremental>false</LinkIncremental>
|
<LinkIncremental>false</LinkIncremental>
|
||||||
@@ -150,8 +145,8 @@
|
|||||||
<IntDir>$(ProjectDir)obj\$(Configuration)\$(PlatformShortName)\</IntDir>
|
<IntDir>$(ProjectDir)obj\$(Configuration)\$(PlatformShortName)\</IntDir>
|
||||||
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
<TargetName>$(ProjectName)$(PlatformArchitecture)</TargetName>
|
||||||
<GenerateManifest>false</GenerateManifest>
|
<GenerateManifest>false</GenerateManifest>
|
||||||
<IncludePath>$(SolutionDir)..\inc\phnt;$(SolutionDir)..\inc\minhook;$(IncludePath)</IncludePath>
|
<IncludePath>$(SolutionDir)..\inc\phnt;$(IncludePath)</IncludePath>
|
||||||
<LibraryPath>$(SolutionDir)..\lib\minhook;$(LibraryPath)</LibraryPath>
|
<LibraryPath>$(SolutionDir)..\lib\x64;$(LibraryPath)</LibraryPath>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -170,11 +165,9 @@
|
|||||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||||
<EntryPointSymbol>
|
<EntryPointSymbol>
|
||||||
</EntryPointSymbol>
|
</EntryPointSymbol>
|
||||||
<AdditionalDependencies>version.lib;Shlwapi.lib;libMinHook.x86.MTd.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
<AdditionalDependencies>version.lib;Shlwapi.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<ResourceCompile>
|
<ResourceCompile />
|
||||||
<PreprocessorDefinitions>X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -193,11 +186,9 @@
|
|||||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||||
<EntryPointSymbol>
|
<EntryPointSymbol>
|
||||||
</EntryPointSymbol>
|
</EntryPointSymbol>
|
||||||
<AdditionalDependencies>version.lib;Shlwapi.lib;libMinHook.x64.MTd.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
<AdditionalDependencies>version.lib;Shlwapi.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
||||||
</Link>
|
</Link>
|
||||||
<ResourceCompile>
|
<ResourceCompile />
|
||||||
<PreprocessorDefinitions>X64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
<ClCompile>
|
<ClCompile>
|
||||||
@@ -224,15 +215,13 @@
|
|||||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||||
<EntryPointSymbol>
|
<EntryPointSymbol>
|
||||||
</EntryPointSymbol>
|
</EntryPointSymbol>
|
||||||
<AdditionalDependencies>version.lib;Shlwapi.lib;libMinHook.x86.MT.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
<AdditionalDependencies>version.lib;Shlwapi.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
||||||
<SetChecksum>true</SetChecksum>
|
<SetChecksum>true</SetChecksum>
|
||||||
</Link>
|
</Link>
|
||||||
<ResourceCompile>
|
<ResourceCompile />
|
||||||
<PreprocessorDefinitions>X86;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ResourceCompile>
|
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup_bat\"
|
<Command>copy /Y "$(TargetPath)" "$(SolutionDir)setup_bat\"
|
||||||
copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup\"</Command>
|
copy /Y "$(TargetPath)" "$(SolutionDir)setup_ai\"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Message>Copy release binaries to the setup staging directories</Message>
|
<Message>Copy release binaries to the setup staging directories</Message>
|
||||||
@@ -261,15 +250,13 @@ copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup\"</Command>
|
|||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>false</GenerateDebugInformation>
|
<GenerateDebugInformation>false</GenerateDebugInformation>
|
||||||
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
<ModuleDefinitionFile>exports.def</ModuleDefinitionFile>
|
||||||
<AdditionalDependencies>version.lib;Shlwapi.lib;libMinHook.x64.MT.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
<AdditionalDependencies>version.lib;Shlwapi.lib;%(AdditionalDependencies);ntdll.lib</AdditionalDependencies>
|
||||||
<SetChecksum>true</SetChecksum>
|
<SetChecksum>true</SetChecksum>
|
||||||
</Link>
|
</Link>
|
||||||
<ResourceCompile>
|
<ResourceCompile />
|
||||||
<PreprocessorDefinitions>X64;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
</ResourceCompile>
|
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Command>copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup_bat\"
|
<Command>copy /Y "$(TargetPath)" "$(SolutionDir)setup_bat\"
|
||||||
copy /Y "$(TargetPath)" "$(SolutionDir)wufuc_setup\"</Command>
|
copy /Y "$(TargetPath)" "$(SolutionDir)setup_ai\"</Command>
|
||||||
</PostBuildEvent>
|
</PostBuildEvent>
|
||||||
<PostBuildEvent>
|
<PostBuildEvent>
|
||||||
<Message>Copy release binaries to the setup staging directories</Message>
|
<Message>Copy release binaries to the setup staging directories</Message>
|
||||||
|
@@ -15,12 +15,6 @@
|
|||||||
</Filter>
|
</Filter>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="callbacks.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="hooks.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="targetver.h">
|
<ClInclude Include="targetver.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -30,44 +24,38 @@
|
|||||||
<ClInclude Include="patternfind.h">
|
<ClInclude Include="patternfind.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="versionhelper.h">
|
<ClInclude Include="asprintf.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="servicehelper.h">
|
<ClInclude Include="versioninfo.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="registryhelper.h">
|
<ClInclude Include="verify.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="wufuc.h">
|
<ClInclude Include="registry.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="modulehelper.h">
|
<ClInclude Include="modules.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="log.h">
|
<ClInclude Include="logger.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="ptrlist.h">
|
<ClInclude Include="utf8.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="eventhelper.h">
|
<ClInclude Include="memory.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="mutexhelper.h">
|
<ClInclude Include="helpers.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="callbacks.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="dllmain.c">
|
<ClCompile Include="dllmain.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="hooks.c">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="rundll32.c">
|
<ClCompile Include="rundll32.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@@ -77,31 +65,28 @@
|
|||||||
<ClCompile Include="patternfind.c">
|
<ClCompile Include="patternfind.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="servicehelper.c">
|
<ClCompile Include="asprintf.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="versionhelper.c">
|
<ClCompile Include="versioninfo.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="registryhelper.c">
|
<ClCompile Include="modules.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="wufuc.c">
|
<ClCompile Include="registry.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="log.c">
|
<ClCompile Include="logger.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="modulehelper.c">
|
<ClCompile Include="utf8.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ptrlist.c">
|
<ClCompile Include="memory.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="mutexhelper.c">
|
<ClCompile Include="helpers.c">
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="eventhelper.c">
|
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -110,7 +95,7 @@
|
|||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
<None Include="resource.h">
|
<None Include="resource.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Resource Files</Filter>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
Reference in New Issue
Block a user