Compare commits
5 Commits
master
...
v1.0.1.201
Author | SHA1 | Date | |
---|---|---|---|
![]() |
a52637d493 | ||
![]() |
5d20496f3a | ||
![]() |
cd5077ce82 | ||
![]() |
cc0428159f | ||
![]() |
e6da8ec18b |
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
|
||||||
|
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
|
||||||
|
|
||||||
|
39
README.md
39
README.md
@@ -41,13 +41,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 +50,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
|
||||||
|
10
appveyor.yml
10
appveyor.yml
@@ -1,7 +1,7 @@
|
|||||||
version: 1.0.1.{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,81 +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.
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
Portions of this software are Copyright (c) 2008-2009, Vyacheslav Patkov.
|
|
||||||
================================================================================
|
|
||||||
Hacker Disassembler Engine 32 C
|
|
||||||
Copyright (c) 2008-2009, Vyacheslav Patkov.
|
|
||||||
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 REGENTS 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.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Hacker Disassembler Engine 64 C
|
|
||||||
Copyright (c) 2008-2009, Vyacheslav Patkov.
|
|
||||||
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 REGENTS 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.
|
|
@@ -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, // SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION // 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;
|
||||||
ULONGLONG BootFlags;
|
union
|
||||||
|
{
|
||||||
|
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,21 @@ 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
|
// private
|
||||||
typedef struct _SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION
|
typedef struct _SYSTEM_HYPERVISOR_SHARED_PAGE_INFORMATION
|
||||||
{
|
{
|
||||||
@@ -3130,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
|
||||||
@@ -3284,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;
|
||||||
@@ -3980,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
|
||||||
@@ -216,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
|
||||||
@@ -663,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;
|
||||||
|
struct
|
||||||
{
|
{
|
||||||
BOOLEAN Flags;
|
UCHAR EnableReadVmLogging : 1;
|
||||||
struct
|
UCHAR EnableWriteVmLogging : 1;
|
||||||
{
|
UCHAR Unused : 6;
|
||||||
BOOLEAN EnableReadVmLogging : 1;
|
|
||||||
BOOLEAN EnableWriteVmLogging : 1;
|
|
||||||
BOOLEAN 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.
@@ -1,81 +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.
|
|
||||||
|
|
||||||
================================================================================
|
|
||||||
Portions of this software are Copyright (c) 2008-2009, Vyacheslav Patkov.
|
|
||||||
================================================================================
|
|
||||||
Hacker Disassembler Engine 32 C
|
|
||||||
Copyright (c) 2008-2009, Vyacheslav Patkov.
|
|
||||||
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 REGENTS 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.
|
|
||||||
|
|
||||||
-------------------------------------------------------------------------------
|
|
||||||
Hacker Disassembler Engine 64 C
|
|
||||||
Copyright (c) 2008-2009, Vyacheslav Patkov.
|
|
||||||
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 REGENTS 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.
|
|
@@ -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:{84169AC2-619B-4E39-ABAC-D97D0CCE52AA} 1028:{3242799A-EABC-4846-9FB2-9157464AC6B2} 1031:{15845A1D-9531-4B6B-B56E-93E56652876D} 1033:{02D77154-1789-4037-8157-4F9B400D184E} 1035:{2AB75127-0A1D-46C3-9939-7E1BEF4101F8} 1036:{E0275036-3F2B-44F3-BCDB-78C55071F41B} 1038:{66A9F4FC-8DB1-45AE-98A5-469F14DC2867} 1040:{A037A274-187E-4231-9857-17075F270D01} 1041:{8E027F22-470D-4800-B135-3661E11F1B2D} 1042:{0C7CB276-E4EB-4D99-BC4D-E362BD4AEA46} 1043:{DDD233EB-262F-42B5-BB37-61366CCB3AB7} 1045:{1008FE13-9C80-4061-BAF1-AFEFA3C322BE} 1046:{2C6C0A74-CDEE-4495-858D-EE570F1B14F0} 1049:{D86825C0-4294-441C-B200-3C7B1314FF10} 1060:{D475BE6D-DB4D-4783-8396-F96186694C6E} 2052:{BA2561A6-D217-400D-A2B0-A0AA07222A94} 2070:{3C2F9949-F866-45C9-BE0E-0D046934E2CF} 3082:{AB82F7D2-24EF-47C9-9978-A69CE1BE56B0} " 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.191" Type="32" TargetFile="wufuc64.dll"/>
|
<ROW Property="ProductVersion" Value="1.0.1.0" 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="Troubleshooting_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="{ED9F90C5-1984-48DE-B109-4AF6F12A2E8F}" 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_="Troubleshooting_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\Troubleshooting\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"/>
|
||||||
@@ -187,14 +168,8 @@
|
|||||||
<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_="Troubleshooting_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,26 @@
|
|||||||
<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="3073" 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="3073" Source="aicustact.dll" Target="StopWinService" Options="1" AdditionalSeq="AI_DATA_SETTER_2"/>
|
<ROW Action="StopWindowsUpdateService" Type="3137" 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="Readme.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="SHORTCUTDIR" 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="Troubleshooting_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="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="Readme.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="SHORTCUTDIR" 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="Troubleshooting_Dir" Section="InternetShortcut" Key="WorkingDirectory" Value="[Troubleshooting_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="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 +253,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 +279,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_="SHORTCUTDIR" Target="[CommonAppDataFolder]wufuc\wufuc.log" Hotkey="0" IconIndex="0" ShowCmd="1"/>
|
<ROW Shortcut="Openwufuclogfile" Directory_="Troubleshooting_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 service_notify_callback(PSERVICE_NOTIFYW pNotifyBuffer)
|
|
||||||
{
|
|
||||||
switch ( pNotifyBuffer->dwNotificationStatus ) {
|
|
||||||
case ERROR_SUCCESS:
|
|
||||||
if ( pNotifyBuffer->ServiceStatus.dwProcessId )
|
|
||||||
wufuc_inject(
|
|
||||||
pNotifyBuffer->ServiceStatus.dwProcessId,
|
|
||||||
(LPTHREAD_START_ROUTINE)thread_start_callback,
|
|
||||||
(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 thread_start_callback(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 crash 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 consistent
|
|
||||||
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_patch(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 service_notify_callback(PSERVICE_NOTIFYW pNotifyBuffer);
|
|
||||||
DWORD WINAPI thread_start_callback(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,14 +6,12 @@ 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;
|
||||||
}
|
}
|
||||||
return TRUE;
|
return TRUE;
|
||||||
|
@@ -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,93 +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;
|
|
||||||
|
|
||||||
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_patch(result);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
@@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
|
|
||||||
typedef LSTATUS(WINAPI *LPFN_REGQUERYVALUEEXW)(HKEY, LPCWSTR, LPDWORD, LPDWORD, LPBYTE, LPDWORD);
|
|
||||||
typedef HMODULE(WINAPI *LPFN_LOADLIBRARYEXW)(LPCWSTR, HANDLE, DWORD);
|
|
||||||
|
|
||||||
extern wchar_t *g_pszWUServiceDll;
|
|
||||||
|
|
||||||
extern LPFN_REGQUERYVALUEEXW g_pfnRegQueryValueExW;
|
|
||||||
extern LPFN_LOADLIBRARYEXW g_pfnLoadLibraryExW;
|
|
||||||
|
|
||||||
extern PVOID g_ptRegQueryValueExW;
|
|
||||||
extern PVOID g_ptLoadLibraryExW;
|
|
||||||
|
|
||||||
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);
|
|
162
src/wufuc/log.c
162
src/wufuc/log.c
@@ -1,162 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
#include <ShlObj.h>
|
|
||||||
|
|
||||||
static HANDLE m_hFile = INVALID_HANDLE_VALUE;
|
|
||||||
static DWORD m_dwProcessId;
|
|
||||||
static wchar_t m_szExeFilePath[MAX_PATH];
|
|
||||||
static wchar_t *m_pszExeName;
|
|
||||||
|
|
||||||
BOOL CALLBACK init_once_callback(
|
|
||||||
PINIT_ONCE InitOnce,
|
|
||||||
PVOID *Parameter,
|
|
||||||
PVOID *lpContext)
|
|
||||||
{
|
|
||||||
BOOL result;
|
|
||||||
HRESULT hr;
|
|
||||||
wchar_t *pszPath;
|
|
||||||
wchar_t szFilePath[MAX_PATH];
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
m_dwProcessId = GetCurrentProcessId();
|
|
||||||
if ( !GetModuleFileNameW(NULL, m_szExeFilePath, _countof(m_szExeFilePath)) ) {
|
|
||||||
log_debug(L"GetModuleFileNameW failed! (GLE=%lu)", GetLastError());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
m_pszExeName = PathFindFileNameW(m_szExeFilePath);
|
|
||||||
|
|
||||||
hr = SHGetKnownFolderPath(&FOLDERID_ProgramData, 0, NULL, &pszPath);
|
|
||||||
if ( hr != S_OK ) {
|
|
||||||
log_debug(L"SHGetKnownFolderPath failed! (HRESULT=0x%08X)", hr);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
ret = wcscpy_s(szFilePath, _countof(szFilePath), pszPath);
|
|
||||||
CoTaskMemFree(pszPath);
|
|
||||||
if ( ret ) {
|
|
||||||
log_debug(L"wcscpy_s failed! (Return value=%d)", ret);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if ( !PathAppendW(szFilePath, L"wufuc") ) {
|
|
||||||
append_fail:
|
|
||||||
log_debug(L"PathAppendW failed!");
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if ( !CreateDirectoryW(szFilePath, NULL)
|
|
||||||
&& GetLastError() != ERROR_ALREADY_EXISTS ) {
|
|
||||||
|
|
||||||
log_debug(L"CreateDirectoryW failed! (GLE=%lu)", GetLastError());
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
if ( !PathAppendW(szFilePath, L"wufuc.1.log") )
|
|
||||||
goto append_fail;
|
|
||||||
|
|
||||||
m_hFile = CreateFileW(szFilePath,
|
|
||||||
FILE_APPEND_DATA,
|
|
||||||
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
|
||||||
NULL,
|
|
||||||
OPEN_ALWAYS,
|
|
||||||
FILE_ATTRIBUTE_NORMAL,
|
|
||||||
NULL);
|
|
||||||
|
|
||||||
result = m_hFile != INVALID_HANDLE_VALUE;
|
|
||||||
if ( !result )
|
|
||||||
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;
|
|
||||||
BOOL bStatus;
|
|
||||||
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;
|
|
||||||
int size;
|
|
||||||
char *buf3;
|
|
||||||
DWORD written;
|
|
||||||
|
|
||||||
bStatus = InitOnceExecuteOnce(&InitOnce, init_once_callback, NULL, NULL);
|
|
||||||
|
|
||||||
if ( _wstrdate_s(datebuf, _countof(datebuf))
|
|
||||||
|| _wstrtime_s(timebuf, _countof(timebuf)) )
|
|
||||||
return;
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
ret = _vscwprintf(format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if ( ret == -1 ) return;
|
|
||||||
count = ret + 1;
|
|
||||||
|
|
||||||
buf1 = calloc(count, sizeof *buf1);
|
|
||||||
if ( !buf1 ) return;
|
|
||||||
|
|
||||||
va_start(ap, format);
|
|
||||||
ret = vswprintf_s(buf1, count, format, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if ( ret == -1 ) goto free_buf1;
|
|
||||||
|
|
||||||
ret = _scwprintf(fmt, datebuf, timebuf, m_pszExeName, m_dwProcessId, buf1);
|
|
||||||
if ( ret == -1 ) goto free_buf1;
|
|
||||||
count = ret + 1;
|
|
||||||
|
|
||||||
buf2 = calloc(count, sizeof *buf2);
|
|
||||||
if ( !buf2 ) goto free_buf1;
|
|
||||||
|
|
||||||
ret = swprintf_s(buf2, count, fmt, datebuf, timebuf, m_pszExeName, m_dwProcessId, buf1);
|
|
||||||
if ( ret == -1 ) goto free_buf2;
|
|
||||||
|
|
||||||
if ( bStatus ) {
|
|
||||||
size = WideCharToMultiByte(CP_UTF8, 0, buf2, ret, NULL, 0, NULL, NULL);
|
|
||||||
if ( !size ) goto fallback;
|
|
||||||
|
|
||||||
buf3 = malloc(size);
|
|
||||||
if ( !buf3 ) goto fallback;
|
|
||||||
|
|
||||||
ret = WideCharToMultiByte(CP_UTF8, 0, buf2, ret, buf3, size, NULL, NULL)
|
|
||||||
&& WriteFile(m_hFile, buf3, size, &written, NULL);
|
|
||||||
free(buf3);
|
|
||||||
if ( !ret ) goto fallback;
|
|
||||||
} else {
|
|
||||||
fallback:
|
|
||||||
OutputDebugStringW(buf2);
|
|
||||||
}
|
|
||||||
free_buf2:
|
|
||||||
free(buf2);
|
|
||||||
free_buf1:
|
|
||||||
free(buf1);
|
|
||||||
}
|
|
||||||
|
|
||||||
void log_close(void)
|
|
||||||
{
|
|
||||||
if ( m_hFile != INVALID_HANDLE_VALUE )
|
|
||||||
CloseHandle(m_hFile);
|
|
||||||
}
|
|
@@ -1,10 +0,0 @@
|
|||||||
#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_(__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__)
|
|
99
src/wufuc/logger.c
Normal file
99
src/wufuc/logger.c
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
#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;
|
||||||
|
|
||||||
|
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 ) {
|
||||||
|
|
||||||
|
s_hFile = CreateFileW(file,
|
||||||
|
FILE_APPEND_DATA,
|
||||||
|
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
|
||||||
|
NULL,
|
||||||
|
OPEN_ALWAYS,
|
||||||
|
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,
|
|
||||||
OffsetToPointer(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, ...);
|
|
@@ -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 = OffsetToPointer(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 = OffsetToPointer(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);
|
|
@@ -8,11 +8,11 @@
|
|||||||
#define BUILD_VERSION_COMMA 1,0,1,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,84 +0,0 @@
|
|||||||
#include "stdafx.h"
|
|
||||||
#include "resourcehelper.h"
|
|
||||||
#include "log.h"
|
|
||||||
|
|
||||||
void *res_get_version_info(HMODULE hModule)
|
|
||||||
{
|
|
||||||
HRSRC hResInfo;
|
|
||||||
DWORD dwSize;
|
|
||||||
HGLOBAL hResData;
|
|
||||||
LPVOID pRes;
|
|
||||||
void *result;
|
|
||||||
|
|
||||||
hResInfo = FindResourceW(hModule,
|
|
||||||
MAKEINTRESOURCEW(VS_VERSION_INFO),
|
|
||||||
MAKEINTRESOURCEW(RT_VERSION));
|
|
||||||
if ( !hResInfo ) return NULL;
|
|
||||||
|
|
||||||
dwSize = SizeofResource(hModule, hResInfo);
|
|
||||||
if ( !dwSize ) return NULL;
|
|
||||||
|
|
||||||
hResData = LoadResource(hModule, hResInfo);
|
|
||||||
if ( !hResData ) return NULL;
|
|
||||||
|
|
||||||
pRes = LockResource(hResData);
|
|
||||||
if ( !pRes ) return NULL;
|
|
||||||
|
|
||||||
result = malloc(dwSize);
|
|
||||||
if ( !result ) return NULL;
|
|
||||||
|
|
||||||
if ( memcpy_s(result, dwSize, pRes, dwSize) ) {
|
|
||||||
free(result);
|
|
||||||
result = NULL;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
wchar_t *res_query_string_file_info(const void *pBlock,
|
|
||||||
LANGANDCODEPAGE lcp,
|
|
||||||
const wchar_t *pszStringName,
|
|
||||||
size_t *pcchLength)
|
|
||||||
{
|
|
||||||
const wchar_t fmt[] = L"\\StringFileInfo\\%04x%04x\\%ls";
|
|
||||||
int ret;
|
|
||||||
int count;
|
|
||||||
wchar_t *pszSubBlock;
|
|
||||||
wchar_t *result = NULL;
|
|
||||||
UINT uLen;
|
|
||||||
|
|
||||||
ret = _scwprintf(fmt, lcp.wLanguage, lcp.wCodePage, pszStringName);
|
|
||||||
if ( ret == -1 ) return NULL;
|
|
||||||
|
|
||||||
count = ret + 1;
|
|
||||||
pszSubBlock = calloc(count, sizeof *pszSubBlock);
|
|
||||||
if ( !pszSubBlock ) return NULL;
|
|
||||||
|
|
||||||
ret = swprintf_s(pszSubBlock, count, fmt, lcp.wLanguage, lcp.wCodePage, pszStringName);
|
|
||||||
if ( ret != -1
|
|
||||||
&& VerQueryValueW(pBlock, pszSubBlock, &(LPVOID)result, &uLen)
|
|
||||||
&& pcchLength )
|
|
||||||
*pcchLength = uLen;
|
|
||||||
|
|
||||||
free(pszSubBlock);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
PLANGANDCODEPAGE res_query_var_file_info(const void *pBlock, size_t *pCount)
|
|
||||||
{
|
|
||||||
PLANGANDCODEPAGE result = NULL;
|
|
||||||
UINT uLen;
|
|
||||||
|
|
||||||
if ( VerQueryValueW(pBlock, L"\\VarFileInfo\\Translation", &(LPVOID)result, &uLen) )
|
|
||||||
*pCount = uLen / (sizeof *result);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
VS_FIXEDFILEINFO *res_query_fixed_file_info(const void *pBlock)
|
|
||||||
{
|
|
||||||
VS_FIXEDFILEINFO *result;
|
|
||||||
UINT uLen;
|
|
||||||
|
|
||||||
if ( VerQueryValueW(pBlock, L"\\", &(LPVOID)result, &uLen) )
|
|
||||||
return result;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
@@ -1,18 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
WORD wLanguage;
|
|
||||||
WORD wCodePage;
|
|
||||||
} LANGANDCODEPAGE, *PLANGANDCODEPAGE;
|
|
||||||
|
|
||||||
void *res_get_version_info(HMODULE hModule);
|
|
||||||
|
|
||||||
wchar_t *res_query_string_file_info(const void *pBlock,
|
|
||||||
LANGANDCODEPAGE lcp,
|
|
||||||
const wchar_t *pszStringName,
|
|
||||||
size_t *pcchLength);
|
|
||||||
|
|
||||||
PLANGANDCODEPAGE res_query_var_file_info(const void *pBlock, size_t *pcbData);
|
|
||||||
|
|
||||||
VS_FIXEDFILEINFO *res_query_fixed_file_info(const void *pBlock);
|
|
@@ -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)thread_start_callback, &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)service_notify_callback;
|
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 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,33 +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_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,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
int ver_compare_product_version(VS_FIXEDFILEINFO *pffi, WORD wMajor, WORD wMinor, WORD wBuild, WORD wRev);
|
|
||||||
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,222 +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 "resourcehelper.h"
|
|
||||||
#include "versionhelper.h"
|
|
||||||
|
|
||||||
#include <minhook.h>
|
|
||||||
|
|
||||||
HANDLE g_hMainMutex;
|
|
||||||
|
|
||||||
static 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool wufuc_get_patch_info(VS_FIXEDFILEINFO *pffi, PATCHINFO *ppi)
|
|
||||||
{
|
|
||||||
#ifdef _WIN64
|
|
||||||
if ( ver_verify_version_info(6, 1, 1) && 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 ) {
|
|
||||||
|
|
||||||
ppi->pattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????";
|
|
||||||
ppi->off1 = 0xa;
|
|
||||||
ppi->off2 = 0x12;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#elif _WIN32
|
|
||||||
if ( ver_verify_version_info(6, 1, 1)
|
|
||||||
&& ver_compare_product_version(pffi, 7, 6, 7601, 23714) != -1 ) {
|
|
||||||
|
|
||||||
ppi->pattern = "833D????????00 743E E8???????? A3????????";
|
|
||||||
ppi->off1 = 0x2;
|
|
||||||
ppi->off2 = 0xf;
|
|
||||||
return true;
|
|
||||||
} else if ( ver_verify_version_info(6, 3, 0)
|
|
||||||
&& ver_compare_product_version(pffi, 7, 9, 9600, 18621) != -1 ) {
|
|
||||||
|
|
||||||
ppi->pattern = "8BFF 51 833D????????00 7507 A1????????";
|
|
||||||
ppi->off1 = 0x5;
|
|
||||||
ppi->off2 = 0xd;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool wufuc_get_patch_ptrs(const PATCHINFO *ppi, uintptr_t pfn, PBOOL *ppval1, PBOOL *ppval2)
|
|
||||||
{
|
|
||||||
#ifdef _WIN64
|
|
||||||
*ppval1 = (PBOOL)(pfn + ppi->off1 + sizeof(uint32_t) + *(uint32_t *)(pfn + ppi->off1));
|
|
||||||
*ppval2 = (PBOOL)(pfn + ppi->off2 + sizeof(uint32_t) + *(uint32_t *)(pfn + ppi->off2));
|
|
||||||
return true;
|
|
||||||
#elif _WIN32
|
|
||||||
*ppval1 = (PBOOL)(*(uintptr_t *)(pfn + ppi->off1));
|
|
||||||
*ppval2 = (PBOOL)(*(uintptr_t *)(pfn + ppi->off2));
|
|
||||||
return true;
|
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void wufuc_patch(HMODULE hModule)
|
|
||||||
{
|
|
||||||
void *pBlock;
|
|
||||||
PATCHINFO pi;
|
|
||||||
size_t count;
|
|
||||||
PLANGANDCODEPAGE plcp;
|
|
||||||
wchar_t *pInternalName;
|
|
||||||
VS_FIXEDFILEINFO *pffi;
|
|
||||||
MODULEINFO modinfo;
|
|
||||||
size_t offset;
|
|
||||||
void *pfn;
|
|
||||||
DWORD fOldProtect;
|
|
||||||
PBOOL pval1;
|
|
||||||
PBOOL pval2;
|
|
||||||
|
|
||||||
pBlock = res_get_version_info(hModule);
|
|
||||||
if ( !pBlock ) return;
|
|
||||||
|
|
||||||
plcp = res_query_var_file_info(pBlock, &count);
|
|
||||||
if ( !plcp ) goto free_pBlock;
|
|
||||||
|
|
||||||
for ( size_t i = 0; i < count; i++ ) {
|
|
||||||
pInternalName = res_query_string_file_info(pBlock, plcp[i], L"InternalName", NULL);
|
|
||||||
if ( pInternalName && !_wcsicmp(pInternalName, L"wuaueng.dll") )
|
|
||||||
goto cont_patch;
|
|
||||||
}
|
|
||||||
goto free_pBlock;
|
|
||||||
|
|
||||||
cont_patch:
|
|
||||||
pffi = res_query_fixed_file_info(pBlock);
|
|
||||||
if ( !pffi ) goto free_pBlock;
|
|
||||||
|
|
||||||
if ( !wufuc_get_patch_info(pffi, &pi) ) {
|
|
||||||
log_warning(L"Unsupported Windows Update Agent version: %hu.%hu.%hu.%hu",
|
|
||||||
HIWORD(pffi->dwProductVersionMS),
|
|
||||||
LOWORD(pffi->dwProductVersionMS),
|
|
||||||
HIWORD(pffi->dwProductVersionLS),
|
|
||||||
LOWORD(pffi->dwProductVersionLS));
|
|
||||||
goto free_pBlock;
|
|
||||||
}
|
|
||||||
log_info(L"Supported Windows Update Agent version: %hu.%hu.%hu.%hu",
|
|
||||||
HIWORD(pffi->dwProductVersionMS),
|
|
||||||
LOWORD(pffi->dwProductVersionMS),
|
|
||||||
HIWORD(pffi->dwProductVersionLS),
|
|
||||||
LOWORD(pffi->dwProductVersionLS));
|
|
||||||
|
|
||||||
if ( !GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof modinfo) ) {
|
|
||||||
log_error(L"GetModuleInformation failed! (hModule=%p, GLE=%lu)", hModule, GetLastError());
|
|
||||||
goto free_pBlock;
|
|
||||||
}
|
|
||||||
offset = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, pi.pattern);
|
|
||||||
if ( offset == -1 ) {
|
|
||||||
log_info(L"Couldn't match IsDeviceServiceable function!");
|
|
||||||
goto free_pBlock;
|
|
||||||
}
|
|
||||||
pfn = OffsetToPointer(modinfo.lpBaseOfDll, offset);
|
|
||||||
log_info(L"Matched %ls!IsDeviceServiceable function! (Offset=%IX, Address=%p)",
|
|
||||||
PathFindFileNameW(g_pszWUServiceDll), offset, pfn);
|
|
||||||
|
|
||||||
if ( wufuc_get_patch_ptrs(&pi, (uintptr_t)pfn, &pval1, &pval2) ) {
|
|
||||||
if ( *pval1 && VirtualProtect(pval1, sizeof *pval1, PAGE_READWRITE, &fOldProtect) ) {
|
|
||||||
*pval1 = FALSE;
|
|
||||||
VirtualProtect(pval1, sizeof *pval1, fOldProtect, &fOldProtect);
|
|
||||||
log_info(L"Patched variable! (Address=%p)", pval1);
|
|
||||||
}
|
|
||||||
if ( !*pval2 && VirtualProtect(pval2, sizeof *pval2, PAGE_READWRITE, &fOldProtect) ) {
|
|
||||||
*pval2 = TRUE;
|
|
||||||
VirtualProtect(pval2, sizeof *pval2, fOldProtect, &fOldProtect);
|
|
||||||
log_info(L"Patched variable! (Address=%p)", pval2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
free_pBlock:
|
|
||||||
free(pBlock);
|
|
||||||
}
|
|
@@ -1,16 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
typedef struct _PATCHINFO
|
|
||||||
{
|
|
||||||
const char *pattern;
|
|
||||||
size_t off1;
|
|
||||||
size_t off2;
|
|
||||||
} PATCHINFO;
|
|
||||||
|
|
||||||
#define SVCHOST_CRASH_THRESHOLD 3
|
|
||||||
extern HANDLE g_hMainMutex;
|
|
||||||
|
|
||||||
bool wufuc_inject(DWORD dwProcessId,
|
|
||||||
LPTHREAD_START_ROUTINE pStartAddress,
|
|
||||||
ptrlist_t *list);
|
|
||||||
void wufuc_patch(HMODULE hModule);
|
|
@@ -19,36 +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="resourcehelper.h" />
|
<ClInclude Include="versioninfo.h" />
|
||||||
<ClInclude Include="servicehelper.h" />
|
<ClInclude Include="verify.h" />
|
||||||
<ClInclude Include="versionhelper.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="resourcehelper.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>
|
||||||
@@ -56,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" />
|
||||||
@@ -125,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>
|
||||||
@@ -134,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>
|
||||||
@@ -143,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>
|
||||||
@@ -152,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>
|
||||||
@@ -172,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>
|
||||||
@@ -195,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>
|
||||||
@@ -226,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>
|
||||||
@@ -263,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,47 +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>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="resourcehelper.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>
|
||||||
@@ -80,34 +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>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="resourcehelper.c">
|
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
@@ -116,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