34 Commits

Author SHA1 Message Date
zeffy
2c31ea2fe4 Update appveyor.yml 2017-06-14 03:34:13 -07:00
zeffy
cda46fbc9f 0.6.1
- fixed x86 support
- added june updates to supported updates
- minor changes
2017-06-14 03:29:14 -07:00
zeffy
c4a78a3e24 improve batch script installers
- remove annoying confirmations on disable/enable scripts
- fix disable script on x86
- make sure Schedule service is running before trying do anything with
schtasks
2017-06-13 04:08:22 -07:00
zeffy
3d0b322f1e add is64bitwindows helper 2017-06-13 03:58:42 -07:00
zeffy
2be1785509 new byte pattern search alg
Ported to C from @x64dbg's patternfind.cpp.
https://github.com/x64dbg/x64dbg/blob/development/src/dbg/patternfind.cpp

This one is much better than my previous implementation because now I
can use wildcards on single nibbles!
2017-06-13 01:43:27 -07:00
zeffy
c837bfec2f better OS version detection 2017-06-10 14:25:46 -07:00
zeffy
4ad3642db6 more debug 2017-06-10 11:38:57 -07:00
zeffy
0b86b8e9ab more error checking 2017-06-10 11:30:25 -07:00
zeffy
4b85cb18a6 Update README.md 2017-06-10 02:40:47 -07:00
zeffy
9badc6257e ctrl s 2017-06-10 02:40:30 -07:00
zeffy
7d30ebd048 Rename entrypoint.c -> rundll32.c [skip ci] 2017-06-09 15:35:37 -07:00
zeffy
196f4465a9 Update README.md 2017-06-08 21:41:16 -07:00
zeffy
1d9b47e602 better installer 2017-06-08 14:54:38 -07:00
zeffy
ce7e6dd166 more error checking 2017-06-08 13:44:03 -07:00
zeffy
080242cec9 Update README.md 2017-06-07 14:04:27 -07:00
zeffy
b7cff16081 Update README.md 2017-06-07 14:00:15 -07:00
zeffy
7e42fc54f3 fix wrong debug message function 2017-06-07 07:31:43 -07:00
zeffy
c8538b8ec3 slightly more strict wu module detection 2017-06-07 07:18:41 -07:00
zeffy
309981829e better logging 2017-06-07 06:05:27 -07:00
zeffy
8a5ef20488 clean up 2017-06-07 05:34:00 -07:00
zeffy
0f41968610 Update README.md 2017-06-06 20:58:52 -07:00
zeffy
c7a1e606ef Update appveyor.yml 2017-06-06 20:50:27 -07:00
zeffy
7d6baf8aac Update appveyor.yml 2017-06-06 20:44:55 -07:00
zeffy
50182997f2 Add appveyor.yml 2017-06-06 20:39:42 -07:00
zeffy
37c8bd8ae3 ok now 0.6.0.2 2017-06-06 16:12:00 -07:00
zeffy
a1a1fc0bd1 ??? logic 2017-06-06 15:46:16 -07:00
zeffy
0ce2cbfbc0 0.6.0.2 2017-06-06 15:21:10 -07:00
zeffy
be33bfb2d5 finish making msvc a static import 2017-06-06 14:12:03 -07:00
zeffy
549459ff58 Merge pull request #44 from navossoc/master
Remove MSVC run-time dependencies
2017-06-06 13:40:27 -07:00
Rafael Cossovan
ae8d48d365 Remove MSVC run-time dependencies (Microsoft Visual C++ 2017 Redistributable). 2017-06-06 15:52:07 -03:00
zeffy
a584e3a3a7 Update README.md 2017-06-05 19:51:12 -07:00
zeffy
07da645253 Update README.md 2017-06-05 18:21:53 -07:00
zeffy
642ed502d7 Update README.md 2017-06-05 18:11:07 -07:00
zeffy
fce0772996 fix comment spacing, variable names 2017-06-05 18:01:37 -07:00
20 changed files with 553 additions and 253 deletions

View File

@@ -1,7 +1,13 @@
# wufuc [![a.k.a. kb4012218-19](https://img.shields.io/badge/a.k.a.-kb4012218--19-blue.svg)](../../tree/old-kb4012218-19) [![downloads](https://img.shields.io/github/downloads/zeffy/wufuc/total.svg) ![downloads before v0.6](https://img.shields.io/badge/downloads%20before%20v0.6-13k-brightgreen.svg)](https://github.com/zeffy/wufuc/releases/latest)
# wufuc [![a.k.a. kb4012218-19](https://img.shields.io/badge/a.k.a.-kb4012218--19-blue.svg)](../../tree/old-kb4012218-19) [![Build status](https://ci.appveyor.com/api/projects/status/0s2unkpokttyslf0?svg=true)](https://ci.appveyor.com/project/zeffy/wufuc)
Disables the "Unsupported Hardware" message in Windows Update, and allows you to continue installing updates on Windows 7 and 8.1 systems with Intel Kaby Lake, AMD Ryzen, or other unsupported processors.
## Downloads [![Github All Releases](https://img.shields.io/github/downloads/zeffy/wufuc/total.svg)](../../releases)
### You can get the latest stable version [here](../../releases/latest)!
If you are feeling brave, you can try the latest unstable builds [here](https://ci.appveyor.com/project/zeffy/wufuc). **Use these at your own risk!**
## Preface
The changelog for Windows updates KB4012218 and KB4012219 included the following:
@@ -34,19 +40,27 @@ My patch takes advantage of this result caching behavior by setting the "hasn't
- **No system files are modified!**
- Heuristic-based patching, which means it will usually keep working even after updates.
- C is best language.
- No external dependencies except for Microsoft Visual C++ 2017 Redistributable.
- No external dependencies.
### How to install/uninstall?
Just download the [latest release](https://github.com/zeffy/wufuc/releases/latest), and extract the `wufuc` folder to a permanent location (like `C:\Program Files\wufuc`) and then run `install_wufuc.bat` as administrator.
Just download the [latest release](../../releases/latest), and extract the `wufuc` folder to a permanent location (like `C:\Program Files\wufuc`) and then run `install_wufuc.bat` as administrator.
To uninstall run `uninstall_wufuc.bat` as administrator.
To uninstall run `uninstall_wufuc.bat` as administrator.
To temporarily disable the patch, just go to the Task Scheduler and disable the `wufuc.{72EEE38B-9997-42BD-85D3-2DD96DA17307}` task, then restart your computer.
### How to update when a new version comes out?
Unless otherwise noted, you should only have to:
- Run `disable_wufuc.bat` as administrator.
- Copy the new files into the install folder, overwriting the old ones.
- Run the new `install_wufuc.bat` as administrator.
If you run into problems, try doing a full uninstall/reinstall.
### How do I remove your old patch and use this instead?
I've included a utility script called `repair_wuaueng.dll.bat` that will initiate an sfc scan and revert any changes made to `wuaueng.dll`.
I've included a utility script called `repair_wuaueng.dll.bat`. When you run it, it will initiate an `sfc` scan and revert any changes made to `wuaueng.dll`.
### How to see wufuc's debugging message output?
@@ -54,9 +68,7 @@ You will need to download [DebugView](https://technet.microsoft.com/en-us/sysint
The best way to get a log of the entire life-cycle of wufuc is to do the following:
1. Disable wufuc in Task Scheduler.
2. Restart your computer.
3. Start `DebugView.exe` as administrator and check `Capture -> Capture Global Win32`.
4. Enable wufuc in Task Scheduler.
5. Run wufuc in Task Scheduler.
6. Output will be shown in DebugView.
1. Disable wufuc by running `disable_wufuc.bat` as administrator.
2. Start `Dbgview.exe` as administrator and check `Capture -> Capture Global Win32`.
3. Enable wufuc by running `enable_wufuc.bat` as administrator.
4. Output will be shown in DebugView.

28
appveyor.yml Normal file
View File

@@ -0,0 +1,28 @@
version: 0.6.1.{build}
skip_commits:
files:
- README.md
image: Visual Studio 2017
configuration: Release
platform:
- x86
- x64
build:
verbosity: minimal
after_build:
- cmd: >-
set "ZIP_NAME=..\%APPVEYOR_PROJECT_NAME%_v%APPVEYOR_BUILD_VERSION%-%APPVEYOR_REPO_COMMIT:~0,8%_%PLATFORM%.zip"
cd "%APPVEYOR_BUILD_FOLDER%\install"
unix2dos "COPYING.txt"
for /R %%G in (*.bat) do unix2dos "%%G"
7z a "%ZIP_NAME%" "..\install"
7z rn "%ZIP_NAME%" "install" "wufuc"
artifacts:
- path: '*.zip'

View File

@@ -1,5 +1,5 @@
@echo off
title wufuc installer - v0.6.0.1
title wufuc installer
:: Copyright (C) 2017 zeffy
:: This program is free software: you can redistribute it and/or modify
@@ -36,27 +36,34 @@ if /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
goto :is_x64
)
if /I "%PROCESSOR_ARCHITECTURE%"=="x86" (
set "WINDOWS_ARCHITECTURE=x86"
set "wufuc_dll=%~dp0wufuc32.dll"
goto :check_ver
goto :is_x86
)
)
goto :unsupported_os
:is_x86
set "WINDOWS_ARCHITECTURE=x86"
set "wufuc_dll=%~dp0wufuc32.dll"
goto :get_ver
:is_x64
set "WINDOWS_ARCHITECTURE=x64"
set "wufuc_dll=%~dp0wufuc64.dll"
:get_ver
for /f "tokens=*" %%i in ('wmic /output:stdout datafile where "name='%wufuc_dll:\=\\%'" get Version /value ^| find "="') do set "%%i"
title wufuc installer - v%Version%
:check_ver
wmic /output:stdout os get version | findstr "^6\.1\." >nul && (
set "WINDOWS_VER=6.1"
set "SUPPORTED_HOTFIXES=KB4019265 KB4019264 KB4015552 KB4015549 KB4015546 KB4012218"
set "SUPPORTED_HOTFIXES=KB4022722 KB4022719 KB4019265 KB4019264 KB4015552 KB4015549 KB4015546 KB4012218"
echo Detected supported operating system: Windows 7 %WINDOWS_ARCHITECTURE%
goto :check_hotfix
)
wmic /output:stdout os get version | findstr "^6\.3\." >nul && (
set "WINDOWS_VER=8.1"
set "SUPPORTED_HOTFIXES=KB4019217 KB4019215 KB4015553 KB4015550 KB4015547 KB4012219"
set "SUPPORTED_HOTFIXES=KB4022726 KB4022717 KB4019217 KB4019215 KB4015553 KB4015550 KB4015547 KB4012219"
echo Detected supported operating system: Windows 8.1 %WINDOWS_ARCHITECTURE%
goto :check_hotfix
)
@@ -80,22 +87,17 @@ for %%a in (%SUPPORTED_HOTFIXES%) do (
goto :confirmation
)
)
wmic /output:stdout qfe get /value 2>&1 | find "No Instance(s) Available" >nul && (
echo WARNING - wmic qfe is broken, can't check installed updates...
goto :confirmation
)
echo.
echo WARNING - Detected that no supported updates are installed!
echo WARNING - Detected that no supported updates are installed.
echo.
echo This can be a false warning, sometimes it is caused by the WMI
echo Win32_QuickFixEngineering class being broken. If you are certain
echo that you need wufuc, then you can continue ^(there should be no
echo side effects even if you don't need it^).
echo.
echo This warning could also mean that a new update came out and the
echo installer script's list of updates hasn't been updated yet. If
echo this is the case and you know which update it is, feel free to
echo create an issue. https://github.com/zeffy/wufuc/issues
set /p CONTINUE=Enter 'Y' if you still want to continue:
if /I not "%CONTINUE%"=="Y" goto :cancel
echo This warning could also mean that a new update came out and the
echo wufuc installer script's list of updates hasn't been updated yet.
echo If this is definitely the case and you know which update it is,
echo feel free to create an issue. https://github.com/zeffy/wufuc/issues
:confirmation
echo.
@@ -103,26 +105,15 @@ echo wufuc disables the "Unsupported Hardware" message in Windows Update,
echo and allows you to continue installing updates on Windows 7 and 8.1
echo systems with Intel Kaby Lake, AMD Ryzen, or other unsupported processors.
echo.
set /p CONTINUE=Enter 'Y' if you want to install wufuc:
if /I not "%CONTINUE%"=="Y" goto :cancel
echo Please be absolutely sure you really need wufuc before continuing.
echo.
set "vcredist_path=%~dp0_Redist\vcredist_%WINDOWS_ARCHITECTURE%.exe"
if exist "%vcredist_path%" (
echo Installing Microsoft Visual C^+^+ 2017 Redistributable ^(%WINDOWS_ARCHITECTURE%^)...
"%vcredist_path%" /passive /norestart
goto :install
)
echo Couldn't locate and install Microsoft Visual C^+^+ 2017 Redistributable ^(%WINDOWS_ARCHITECTURE%^).
set /p CONTINUE=Enter 'Y' if you still want to continue:
set /p CONTINUE=Enter 'Y' if you want to install wufuc:
if /I not "%CONTINUE%"=="Y" goto :cancel
echo.
:install
set "wufuc_task=wufuc.{72EEE38B-9997-42BD-85D3-2DD96DA17307}"
net start Schedule
schtasks /Create /XML "%~dp0wufuc.xml" /TN "%wufuc_task%" /F
schtasks /Change /TN "%wufuc_task%" /TR "'%systemroot%\system32\rundll32.exe' """%wufuc_dll%""",Rundll32Entry"
schtasks /Change /TN "%wufuc_task%" /ENABLE

View File

@@ -1,5 +1,5 @@
@echo off
title wufuc uninstaller - v0.6.0.1
title wufuc uninstaller
:: Copyright (C) 2017 zeffy
:: This program is free software: you can redistribute it and/or modify
@@ -34,25 +34,32 @@ if /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
goto :is_x64
)
if /I "%PROCESSOR_ARCHITECTURE%"=="x86" (
set "WINDOWS_ARCHITECTURE=x86"
set "wufuc_dll=%~dp0wufuc32.dll"
goto :confirmation
goto :is_x86
)
)
goto :die
:is_x86
set "WINDOWS_ARCHITECTURE=x86"
set "wufuc_dll=%~dp0wufuc32.dll"
goto :get_ver
:is_x64
set "WINDOWS_ARCHITECTURE=x64"
set "wufuc_dll=%~dp0wufuc64.dll"
:get_ver
for /f "tokens=*" %%i in ('wmic /output:stdout datafile where "name='%wufuc_dll:\=\\%'" get Version /value ^| find "="') do set "%%i"
title wufuc uninstaller - v%Version%
:confirmation
set /p CONTINUE=Enter 'Y' if you want to uninstall wufuc:
if /I not "%CONTINUE%"=="Y" goto :cancel
echo.
:uninstall
set "wufuc_task=wufuc.{72EEE38B-9997-42BD-85D3-2DD96DA17307}"
rundll32 "%wufuc_dll%",Rundll32Unload
net start Schedule
schtasks /Delete /TN "%wufuc_task%" /F
echo.

View File

@@ -0,0 +1,61 @@
@echo off
title wufuc utility - disable task
:: Copyright (C) 2017 zeffy
:: This program is free software: you can redistribute it and/or modify
:: it under the terms of the GNU General Public License as published by
:: the Free Software Foundation, either version 3 of the License, or
:: (at your option) any later version.
:: This program is distributed in the hope that it will be useful,
:: but WITHOUT ANY WARRANTY; without even the implied warranty of
:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
:: GNU General Public License for more details.
:: You should have received a copy of the GNU General Public License
:: along with this program. If not, see <http://www.gnu.org/licenses/>.
echo Copyright ^(C^) 2017 zeffy
echo This program comes with ABSOLUTELY NO WARRANTY.
echo This is free software, and you are welcome to redistribute it
echo under certain conditions; see COPYING.txt for details.
echo.
fltmc >nul 2>&1 || (
echo This batch script requires administrator privileges. Right-click on
echo %~nx0 and select "Run as administrator".
goto :die
)
if /I "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
goto :is_x64
) else (
if /I "%PROCESSOR_ARCHITEW6432%"=="AMD64" (
goto :is_x64
)
if /I "%PROCESSOR_ARCHITECTURE%"=="x86" (
goto :is_x86
)
)
goto :die
:is_x86
set "wufuc_dll=%~dp0..\wufuc32.dll"
goto :disable
:is_x64
set "wufuc_dll=%~dp0..\wufuc64.dll"
:disable
set "wufuc_task=wufuc.{72EEE38B-9997-42BD-85D3-2DD96DA17307}"
rundll32 "%wufuc_dll%",Rundll32Unload
net start Schedule
schtasks /Change /TN "%wufuc_task%" /DISABLE
echo.
echo Disabled wufuc! You will still be able to check for updates until you restart.
:die
echo.
pause
exit

View File

@@ -0,0 +1,41 @@
@echo off
title wufuc utility - enable task
:: Copyright (C) 2017 zeffy
:: This program is free software: you can redistribute it and/or modify
:: it under the terms of the GNU General Public License as published by
:: the Free Software Foundation, either version 3 of the License, or
:: (at your option) any later version.
:: This program is distributed in the hope that it will be useful,
:: but WITHOUT ANY WARRANTY; without even the implied warranty of
:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
:: GNU General Public License for more details.
:: You should have received a copy of the GNU General Public License
:: along with this program. If not, see <http://www.gnu.org/licenses/>.
echo Copyright ^(C^) 2017 zeffy
echo This program comes with ABSOLUTELY NO WARRANTY.
echo This is free software, and you are welcome to redistribute it
echo under certain conditions; see COPYING.txt for details.
echo.
fltmc >nul 2>&1 || (
echo This batch script requires administrator privileges. Right-click on
echo %~nx0 and select "Run as administrator".
goto :die
)
set "wufuc_task=wufuc.{72EEE38B-9997-42BD-85D3-2DD96DA17307}"
net start Schedule
schtasks /Change /TN "%wufuc_task%" /ENABLE
schtasks /Run /TN "%wufuc_task%"
echo.
echo Enabled and started wufuc!
:die
echo.
pause
exit

View File

@@ -1,5 +1,5 @@
@echo off
title install wufuc ^(repair wuaueng.dll^) - v0.6.0.1
title wufuc utility - repair wuaueng.dll
:: Copyright (C) 2017 zeffy
:: This program is free software: you can redistribute it and/or modify
@@ -27,7 +27,6 @@ fltmc >nul 2>&1 || (
goto :die
)
:confirmation
echo You may want to use this script if you previously modified wuaueng.dll
echo with "aio-wuaueng.dll-patch.bat" or by other means.
echo.

View File

@@ -8,26 +8,23 @@ EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{8C2147FF-2B83-479B-813E-5ACB86F43042}"
ProjectSection(SolutionItems) = preProject
.gitignore = .gitignore
appveyor.yml = appveyor.yml
LICENSE = LICENSE
README.md = README.md
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{00F96695-CE41-4C2F-A344-6219DFB4F887}.Debug|Any CPU.ActiveCfg = Debug|Win32
{00F96695-CE41-4C2F-A344-6219DFB4F887}.Debug|x64.ActiveCfg = Debug|x64
{00F96695-CE41-4C2F-A344-6219DFB4F887}.Debug|x64.Build.0 = Debug|x64
{00F96695-CE41-4C2F-A344-6219DFB4F887}.Debug|x86.ActiveCfg = Debug|Win32
{00F96695-CE41-4C2F-A344-6219DFB4F887}.Debug|x86.Build.0 = Debug|Win32
{00F96695-CE41-4C2F-A344-6219DFB4F887}.Release|Any CPU.ActiveCfg = Release|Win32
{00F96695-CE41-4C2F-A344-6219DFB4F887}.Release|x64.ActiveCfg = Release|x64
{00F96695-CE41-4C2F-A344-6219DFB4F887}.Release|x64.Build.0 = Release|x64
{00F96695-CE41-4C2F-A344-6219DFB4F887}.Release|x86.ActiveCfg = Release|Win32

View File

@@ -1,13 +1,13 @@
#include <stdint.h>
#include <Windows.h>
#include <Psapi.h>
#include <TlHelp32.h>
#include <tchar.h>
#include <aclapi.h>
#include <sddl.h>
#include "core.h"
#include "process.h"
#include "service.h"
#include "util.h"
#include "patternfind.h"
#include "core.h"
DWORD WINAPI NewThreadProc(LPVOID lpParam) {
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
@@ -44,95 +44,81 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
DETOUR_IAT(hm, LoadLibraryExA);
DETOUR_IAT(hm, LoadLibraryExW);
HMODULE hwu = GetModuleHandle(_T("wuaueng.dll"));
if (hwu) {
PatchWUModule(hwu);
TCHAR lpServiceDll[MAX_PATH + 1];
get_svcdll(_T("wuauserv"), lpServiceDll, _countof(lpServiceDll));
HMODULE hwu = GetModuleHandle(lpServiceDll);
if (hwu && PatchWUAgentHMODULE(hwu)) {
_tdbgprintf(_T("Patched previously loaded Windows Update module!"));
}
ResumeAndCloseThreads(lphThreads, cb);
WaitForSingleObject(hEvent, INFINITE);
_tdbgprintf(_T("Received wufuc_UnloadEvent, removing hooks."));
_tdbgprintf(_T("Unload event was set."));
SuspendProcessThreads(dwProcessId, dwThreadId, lphThreads, _countof(lphThreads), &cb);
RESTORE_IAT(hm, LoadLibraryExA);
RESTORE_IAT(hm, LoadLibraryExW);
ResumeAndCloseThreads(lphThreads, cb);
_tdbgprintf(_T("Unloading library. Cya!"));
CloseHandle(hEvent);
_tdbgprintf(_T("See ya!"));
FreeLibraryAndExitThread(HINST_THISCOMPONENT, 0);
return 0;
}
BOOL IsWUModule(HMODULE hModule) {
TCHAR lpBaseName[MAX_PATH + 1];
GetModuleBaseName(GetCurrentProcess(), hModule, lpBaseName, _countof(lpBaseName));
return !_tcsicmp(lpBaseName, _T("wuaueng.dll"));
}
BOOL PatchWUModule(HMODULE hModule) {
if (!IsWindows7Or8Point1()) {
BOOL PatchWUAgentHMODULE(HMODULE hModule) {
LPSTR pattern;
SIZE_T offset00, offset01;
if (Is64BitWindows()) {
pattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????";
offset00 = 10;
offset01 = 18;
} else if (WindowsVersionCompare(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
pattern = "833D????????00 743E E8???????? A3????????";
offset00 = 2;
offset01 = 15;
} else if (WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
pattern = "8BFF 51 833D????????00 7507 A1????????";
offset00 = 5;
offset01 = 13;
} else {
return FALSE;
}
LPSTR lpszPattern;
SIZE_T n1, n2;
#ifdef _WIN64
lpszPattern =
"FFF3" // push rbx
"4883EC??" // sub rsp,??
"33DB" // xor ebx,ebx
"391D????????" // cmp dword ptr ds:[???????????],ebx
"7508" // jnz $+8
"8B05????????"; // mov eax,dword ptr ds:[???????????]
n1 = 10;
n2 = 18;
#elif defined(_WIN32)
if (IsWindows8Point1()) {
lpszPattern =
"8BFF" // mov edi,edi
"51" // push ecx
"833D????????00" // cmp dword ptr ds:[????????],0
"7507" // jnz $+7
"A1????????"; // mov eax,dword ptr ds:[????????]
n1 = 5;
n2 = 13;
} else if (IsWindows7()) {
lpszPattern =
"833D????????00" // cmp dword ptr ds:[????????],0
"743E" // je $+3E
"E8????????" // call <wuaueng.IsCPUSupported>
"A3????????"; // mov dword ptr ds:[????????],eax
n1 = 2;
n2 = 15;
}
#else
return FALSE;
#endif
MODULEINFO modinfo;
GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
SIZE_T offset;
if (!FindPattern(modinfo.lpBaseOfDll, modinfo.SizeOfImage, lpszPattern, 0, &offset)) {
SIZE_T rva = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, 0, pattern);
if (rva == -1) {
_tdbgprintf(_T("No pattern match!"));
return FALSE;
}
SIZE_T rva = (SIZE_T)modinfo.lpBaseOfDll + offset;
_tdbgprintf(_T("IsDeviceServiceable(void) matched at %p"), rva);
BOOL *lpbNotRunOnce = (BOOL *)(rva + n1 + sizeof(DWORD) + *(DWORD *)(rva + n1));
if (*lpbNotRunOnce) {
*lpbNotRunOnce = FALSE;
_tdbgprintf(_T("Patched %p=%d"), lpbNotRunOnce, *lpbNotRunOnce);
uintptr_t baseAddress = (uintptr_t)modinfo.lpBaseOfDll;
uintptr_t fpIsDeviceServiceable = baseAddress + rva;
_tdbgprintf(_T("Found address of IsDeviceServiceable. (%p)"), fpIsDeviceServiceable);
BOOL result = FALSE;
LPBOOL lpbFirstRun, lpbIsCPUSupportedResult;
if (Is64BitWindows()) {
lpbFirstRun = (LPBOOL)(fpIsDeviceServiceable + offset00 + sizeof(uint32_t) + *(uint32_t *)(fpIsDeviceServiceable + offset00));
lpbIsCPUSupportedResult = (LPBOOL)(fpIsDeviceServiceable + offset01 + sizeof(uint32_t) + *(uint32_t *)(fpIsDeviceServiceable + offset01));
} else {
lpbFirstRun = (LPBOOL)(*(uintptr_t *)(fpIsDeviceServiceable + offset00));
lpbIsCPUSupportedResult = (LPBOOL)(*(uintptr_t *)(fpIsDeviceServiceable + offset01));
}
BOOL *lpbCachedResult = (BOOL *)(rva + n2 + sizeof(DWORD) + *(DWORD *)(rva + n2));
if (!*lpbCachedResult) {
*lpbCachedResult = TRUE;
_tdbgprintf(_T("Patched %p=%d"), lpbCachedResult, *lpbCachedResult);
if (*lpbFirstRun) {
*lpbFirstRun = FALSE;
_tdbgprintf(_T("Changed first run to FALSE. (%p=%08x)"), lpbFirstRun, *lpbFirstRun);
result = TRUE;
}
return TRUE;
if (!*lpbIsCPUSupportedResult) {
*lpbIsCPUSupportedResult = TRUE;
_tdbgprintf(_T("Changed cached result to TRUE. (%p=%08x)."),
lpbIsCPUSupportedResult, *lpbIsCPUSupportedResult);
result = TRUE;
}
return result;
}
HMODULE WINAPI _LoadLibraryExA(
@@ -141,8 +127,16 @@ HMODULE WINAPI _LoadLibraryExA(
_In_ DWORD dwFlags
) {
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
if (IsWUModule(result)) {
PatchWUModule(result);
if (result) {
_dbgprintf("Loaded %s.", lpFileName);
CHAR path[MAX_PATH + 1];
if (!get_svcdllA("wuauserv", path, _countof(path))) {
return result;
}
if (!_stricmp(lpFileName, path) && PatchWUAgentHMODULE(result)) {
_dbgprintf("Patched Windows Update module!");
}
}
return result;
}
@@ -153,8 +147,16 @@ HMODULE WINAPI _LoadLibraryExW(
_In_ DWORD dwFlags
) {
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
if (IsWUModule(result)) {
PatchWUModule(result);
if (result) {
_wdbgprintf(L"Loaded library: %s.", lpFileName);
WCHAR path[MAX_PATH + 1];
if (!get_svcdllW(L"wuauserv", path, _countof(path))) {
return result;
}
if (!_wcsicmp(lpFileName, path) && PatchWUAgentHMODULE(result)) {
_wdbgprintf(L"Patched Windows Update module!");
}
}
return result;
};

View File

@@ -2,7 +2,7 @@
DWORD WINAPI NewThreadProc(LPVOID lpParam);
BOOL PatchWUModule(HMODULE hModule);
BOOL PatchWUAgentHMODULE(HMODULE hModule);
HMODULE WINAPI _LoadLibraryExA(
_In_ LPCSTR lpFileName,

View File

@@ -1,13 +1,18 @@
#include <Windows.h>
#include "core.h"
#include "util.h"
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
switch (ul_reason_for_call) {
case DLL_PROCESS_ATTACH:
{
DisableThreadLibraryCalls(hModule);
HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
CloseHandle(hThread);
if (WindowsVersionCompare(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)
|| WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
HANDLE hThread = CreateThread(NULL, 0, NewThreadProc, NULL, 0, NULL);
CloseHandle(hThread);
}
break;
}
case DLL_PROCESS_DETACH:

117
wufuc/patternfind.c Normal file
View File

@@ -0,0 +1,117 @@
#include <Windows.h>
#include "patternfind.h"
/* Work in progress. Ported to C from x64dbg's patternfind.cpp:
<https://github.com/x64dbg/x64dbg/blob/development/src/dbg/patternfind.cpp>
x64dbg license (GPL-3.0):
<https://github.com/x64dbg/x64dbg/blob/development/LICENSE> */
int hexchtoint(CHAR c) {
int result = -1;
if (c >= '0' && c <= '9') {
result = c - '0';
} else if (c >= 'A' && c <= 'F') {
result = c - 'A' + 10;
} else if (c >= 'a' && c <= 'f') {
result = c - 'a' + 10;
}
return result;
}
SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize) {
SIZE_T len = strlen(patterntext);
SIZE_T result = 0;
for (SIZE_T i = 0; i < len && (!formattext || result < formattextsize); i++) {
if (patterntext[i] == '?' || hexchtoint(patterntext[i]) != -1) {
if (formattext) {
formattext[result] = patterntext[i];
}
result++;
}
}
return result;
}
BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize) {
SIZE_T cb = formathexpattern(patterntext, NULL, 0);
if (!cb || cb > *patternsize) {
return FALSE;
}
LPSTR formattext = calloc(cb, sizeof(CHAR));
cb = formathexpattern(patterntext, formattext, cb);
if (cb % 2) {
formattext[cb++] = '?';
}
formattext[cb] = '\0';
for (SIZE_T i = 0, j = 0, k = 0; i < cb; i++, j ^= 1, k = (i - j) >> 1) {
if (formattext[i] == '?') {
pattern[k].nibble[j].wildcard = TRUE;
} else {
pattern[k].nibble[j].wildcard = FALSE;
pattern[k].nibble[j].data = hexchtoint(formattext[i]) & 0xf;
}
}
free(formattext);
*patternsize = cb >> 1;
return TRUE;
}
SIZE_T patternfind(LPCBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern) {
SIZE_T result = -1;
SIZE_T searchpatternsize = strlen(pattern);
LPPATTERNBYTE searchpattern = calloc(searchpatternsize, sizeof(PATTERNBYTE));
if (patterntransform(pattern, searchpattern, &searchpatternsize)) {
for (SIZE_T i = startindex, j = 0; i < datasize; i++) //search for the pattern
{
if ((searchpattern[j].nibble[0].wildcard || searchpattern[j].nibble[0].data == ((data[i] >> 4) & 0xf))
&& (searchpattern[j].nibble[1].wildcard || searchpattern[j].nibble[1].data == (data[i] & 0xf))) { //check if our pattern matches the current byte
if (++j == searchpatternsize) { //everything matched
result = i - searchpatternsize + 1;
break;
}
} else if (j > 0) { //fix by Computer_Angel
i -= j;
j = 0; //reset current pattern position
}
}
}
return result;
}
//VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte) {
// BYTE n1 = (*byte >> 4) & 0xf;
// BYTE n2 = *byte & 0xf;
// if (!pbyte->nibble[0].wildcard) {
// n1 = pbyte->nibble[0].data;
// }
// if (!pbyte->nibble[1].wildcard) {
// n2 = pbyte->nibble[1].data;
// }
// *byte = ((n1 << 4) & 0xf0) | (n2 & 0xf);
//}
//
//VOID patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern) {
// SIZE_T writepatternsize = strlen(pattern);
// if (writepatternsize > datasize) {
// writepatternsize = datasize;
// }
// LPPATTERNBYTE writepattern = calloc(writepatternsize, sizeof(PATTERNBYTE));
// if (!patterntransform(pattern, writepattern, &writepatternsize)) {
// return;
// }
// for (size_t i = 0; i < writepatternsize; i++) {
// patternwritebyte(&data[i], &writepattern[i]);
// }
//}
//
//SIZE_T patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern) {
// SIZE_T result = patternfind(data, datasize, startindex, searchpattern, NULL, 0);
// if (result == -1)
// return result;
// patternwrite(data + result, datasize - result, replacepattern);
// return result;
//}

16
wufuc/patternfind.h Normal file
View File

@@ -0,0 +1,16 @@
#pragma once
typedef struct _PATTERNBYTE {
struct _PATTERNNIBBLE {
BYTE data;
BOOL wildcard;
} nibble[2];
} PATTERNBYTE, *PPATTERNBYTE, *LPPATTERNBYTE;
int hexchtoint(CHAR ch);
SIZE_T formathexpattern(LPCSTR patterntext, LPSTR formattext, SIZE_T formattextsize);
BOOL patterntransform(LPCSTR patterntext, LPPATTERNBYTE pattern, SIZE_T *patternsize);
SIZE_T patternfind(LPCBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR pattern);
//VOID patternwritebyte(LPBYTE byte, LPPATTERNBYTE pbyte);
//VOID patternwrite(LPBYTE data, SIZE_T datasize, LPCSTR pattern)
//SIZE_T patternsnr(LPBYTE data, SIZE_T datasize, SIZE_T startindex, LPCSTR searchpattern, LPCSTR replacepattern);

View File

@@ -2,16 +2,24 @@
#include <TlHelp32.h>
#include <tchar.h>
#include "service.h"
#include "process.h"
#include "util.h"
void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
if (!WindowsVersionCompare(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)
&& !WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
return;
}
HANDLE hEvent = OpenEvent(SYNCHRONIZE, FALSE, _T("Global\\wufuc_UnloadEvent"));
if (hEvent) {
CloseHandle(hEvent);
return;
}
SC_HANDLE hSCManager = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT);
if (!hSCManager) {
return;
}
TCHAR lpGroupName[256];
DWORD dwProcessId;
BOOL result = get_svcpid(hSCManager, _T("wuauserv"), &dwProcessId);
@@ -26,15 +34,37 @@ void CALLBACK Rundll32Entry(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int n
GetModuleFileName(HINST_THISCOMPONENT, lpLibFileName, _countof(lpLibFileName));
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
if (!hProcess) {
return;
}
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, _countof(lpLibFileName) + 1, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (lpBaseAddress && WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, _countof(lpLibFileName), NULL)) {
InjectLibrary(hProcess, lpLibFileName, _countof(lpLibFileName));
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
if (hSnap) {
MODULEENTRY32 me;
me.dwSize = sizeof(me);
if (Module32First(hSnap, &me)) {
do {
if (!_tcsicmp(me.szModule, _T("kernel32.dll"))) {
break;
}
} while (Module32Next(hSnap, &me));
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(me.hModule, _CRT_STRINGIZE(LoadLibrary)), lpBaseAddress, 0, NULL);
CloseHandle(hThread);
}
CloseHandle(hSnap);
}
}
CloseHandle(hProcess);
}
void CALLBACK Rundll32Unload(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) {
HANDLE hEvent = OpenEvent(EVENT_MODIFY_STATE, FALSE, _T("Global\\wufuc_UnloadEvent"));
if (hEvent) {
_tdbgprintf(_T("Setting wufuc_UnloadEvent..."));
_tdbgprintf(_T("Setting unload event..."));
SetEvent(hEvent);
CloseHandle(hEvent);
}

View File

@@ -1,25 +1,33 @@
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "util.h"
#include "service.h"
#include "shellapihelper.h"
#include "service.h"
BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize) {
HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG);
if (!hService) {
return FALSE;
}
BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize) {
CHAR lpSubKey[MAX_PATH + 1];
sprintf_s(lpSubKey, _countof(lpSubKey), "SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName);
DWORD cbBytesNeeded;
QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded);
LPQUERY_SERVICE_CONFIG sc = malloc(cbBytesNeeded);
BOOL result = QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded);
CloseServiceHandle(hService);
if (result) {
_tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName);
}
free(sc);
return result;
DWORD uBytes = _MAX_PATH + 1;
LPBYTE pvData = malloc(uBytes);
RegGetValueA(HKEY_LOCAL_MACHINE, lpSubKey, "ServiceDll", RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, NULL, pvData, &uBytes);
ExpandEnvironmentStringsA((LPSTR)pvData, lpServiceDll, dwSize);
return TRUE;
}
BOOL get_svcdllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD dwSize) {
WCHAR lpSubKey[MAX_PATH + 1];
swprintf_s(lpSubKey, _countof(lpSubKey), L"SYSTEM\\CurrentControlSet\\services\\%s\\Parameters", lpServiceName);
DWORD uBytes = _MAX_PATH + 1;
LPBYTE pvData = malloc(uBytes);
RegGetValueW(HKEY_LOCAL_MACHINE, lpSubKey, L"ServiceDll", RRF_RT_REG_EXPAND_SZ | RRF_NOEXPAND, NULL, pvData, &uBytes);
ExpandEnvironmentStringsW((LPWSTR)pvData, lpServiceDll, dwSize);
return TRUE;
}
BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId) {
@@ -31,8 +39,11 @@ BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessI
SERVICE_STATUS_PROCESS lpBuffer;
DWORD cbBytesNeeded;
BOOL result = FALSE;
if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded) && lpBuffer.dwProcessId) {
if (QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)&lpBuffer, sizeof(lpBuffer), &cbBytesNeeded)
&& lpBuffer.dwProcessId) {
*lpdwProcessId = lpBuffer.dwProcessId;
_tdbgprintf(_T("Got pid for service %s: %d."), lpServiceName, *lpdwProcessId);
result = TRUE;
}
CloseServiceHandle(hService);
@@ -57,9 +68,9 @@ BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupNam
if (!_tcsicmp(fname, _T("svchost"))) {
LPWSTR *p = argv;
for (int i = 1; i < numArgs; i++) {
if (!_tcsicmp(*(p++), _T("-k"))) {
_tcscpy_s(lpGroupName, dwSize, *p);
if (!_tcsicmp(*(p++), _T("-k")) && !_tcscpy_s(lpGroupName, dwSize, *p)) {
result = TRUE;
_tdbgprintf(_T("Got group name of service %s: %s."), lpServiceName, lpGroupName);
break;
}
}
@@ -67,22 +78,40 @@ BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupNam
return result;
}
BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize) {
HANDLE hService = OpenService(hSCManager, lpServiceName, SERVICE_QUERY_CONFIG);
if (!hService) {
return FALSE;
}
DWORD cbBytesNeeded;
BOOL result = FALSE;
if (!QueryServiceConfig(hService, NULL, 0, &cbBytesNeeded) && GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
LPQUERY_SERVICE_CONFIG sc = malloc(cbBytesNeeded);
if (QueryServiceConfig(hService, sc, cbBytesNeeded, &cbBytesNeeded) && !_tcscpy_s(lpBinaryPathName, dwSize, sc->lpBinaryPathName)) {
result = TRUE;
}
free(sc);
}
CloseServiceHandle(hService);
return result;
}
BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId) {
DWORD uBytes = 0x100000;
LPBYTE pvData = malloc(uBytes);
RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"), lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes);
RegGetValue(HKEY_LOCAL_MACHINE, _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost"),
lpServiceGroupName, RRF_RT_REG_MULTI_SZ, NULL, pvData, &uBytes);
BOOL result = FALSE;
for (LPTSTR p = (LPTSTR)pvData; *p; p += _tcslen(p) + 1) {
DWORD dwProcessId;
TCHAR group[256];
if (get_svcpid(hSCManager, p, &dwProcessId)) {
get_svcgname(hSCManager, p, group, _countof(group));
result = !_tcsicmp(group, lpServiceGroupName);
}
if (result) {
if (get_svcpid(hSCManager, p, &dwProcessId)
&& (get_svcgname(hSCManager, p, group, _countof(group)) && !_tcsicmp(group, lpServiceGroupName))) {
*lpdwProcessId = dwProcessId;
result = TRUE;
_tdbgprintf(_T("Got pid for service group %s: %d."), lpServiceGroupName, *lpdwProcessId);
break;
}
}

View File

@@ -1,9 +1,20 @@
#pragma once
BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize);
BOOL get_svcdllA(LPCSTR lpServiceName, LPSTR lpServiceDll, DWORD dwSize);
BOOL get_svcdllW(LPCWSTR lpServiceName, LPWSTR lpServiceDll, DWORD dwSize);
#ifdef UNICODE
#define get_svcdll get_svcdllW
#else
#define get_svcdll get_svcdllA
#endif
BOOL get_svcpid(SC_HANDLE hSCManager, LPCTSTR lpServiceName, DWORD *lpdwProcessId);
BOOL get_svcgname(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpGroupName, SIZE_T dwSize);
BOOL get_svcpath(SC_HANDLE hSCManager, LPCTSTR lpServiceName, LPTSTR lpBinaryPathName, SIZE_T dwSize);
BOOL get_svcgpid(SC_HANDLE hSCManager, LPTSTR lpServiceGroupName, DWORD *lpdwProcessId);

View File

@@ -1,22 +1,9 @@
#include <Windows.h>
#include <stdio.h>
#include <VersionHelpers.h>
#include <TlHelp32.h>
#include <tchar.h>
#include "util.h"
BOOL IsWindows7Or8Point1(void) {
return IsWindows7() || IsWindows8Point1();
}
BOOL IsWindows7(void) {
return IsWindows7OrGreater() && !IsWindows8OrGreater();
}
BOOL IsWindows8Point1(void) {
return IsWindows8Point1OrGreater() && !IsWindows10OrGreater();
}
VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress) {
LPVOID *lpAddress = FindIAT(hModule, lpFuncName);
if (!lpAddress || *lpAddress == lpNewAddress) {
@@ -29,13 +16,13 @@ VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID l
if (lpOldAddress) {
*lpOldAddress = *lpAddress;
}
_dbgprintf("%s %p => %p", lpFuncName, *lpAddress, lpNewAddress);
_dbgprintf("Detoured %s from %p to %p.", lpFuncName, *lpAddress, lpNewAddress);
*lpAddress = lpNewAddress;
VirtualProtect(lpAddress, sizeof(LPVOID), flOldProtect, &flNewProtect);
}
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFunctionName) {
SIZE_T hm = (SIZE_T)hModule;
uintptr_t hm = (uintptr_t)hModule;
for (PIMAGE_IMPORT_DESCRIPTOR iid = (PIMAGE_IMPORT_DESCRIPTOR)(hm + ((PIMAGE_NT_HEADERS)(hm + ((PIMAGE_DOS_HEADER)hm)->e_lfanew))
->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); iid->Name; iid++) {
@@ -51,70 +38,6 @@ LPVOID *FindIAT(HMODULE hModule, LPSTR lpFunctionName) {
return NULL;
}
BOOL FindPattern(LPCBYTE pvData, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset) {
SIZE_T length = strlen(lpszPattern);
SIZE_T nBytes;
if (length % 2 || (nBytes = length / 2) > nNumberOfBytes) {
return FALSE;
}
LPBYTE lpBytes = malloc(nBytes * sizeof(BYTE));
BOOL *lpbwc = malloc(nBytes * sizeof(BOOL));
LPSTR p = lpszPattern;
BOOL valid = TRUE;
for (SIZE_T i = 0; i < nBytes; i++) {
if ((lpbwc[i] = strncmp(p, "??", 2)) && sscanf_s(p, "%2hhx", &lpBytes[i]) != 1) {
valid = FALSE;
break;
}
p += 2;
}
BOOL result = FALSE;
if (valid) {
for (SIZE_T i = nStart; i < nNumberOfBytes - nStart - (nBytes - 1); i++) {
BOOL found = TRUE;
for (SIZE_T j = 0; j < nBytes; j++) {
if (lpbwc[j] && pvData[i + j] != lpBytes[j]) {
found = FALSE;
break;
}
}
if (found) {
*lpOffset = i;
result = TRUE;
break;
}
}
}
free(lpBytes);
free(lpbwc);
return result;
}
BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb) {
LPVOID lpBaseAddress = VirtualAllocEx(hProcess, NULL, cb, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
if (!WriteProcessMemory(hProcess, lpBaseAddress, lpLibFileName, cb, NULL)) {
return FALSE;
}
DWORD dwProcessId = GetProcessId(hProcess);
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, dwProcessId);
MODULEENTRY32 me;
me.dwSize = sizeof(me);
Module32First(hSnap, &me);
do {
if (!_tcsicmp(me.szModule, _T("kernel32.dll"))) {
break;
}
} while (Module32Next(hSnap, &me));
CloseHandle(hSnap);
_tdbgprintf(_T("Injecting %s into process %d"), lpLibFileName, dwProcessId);
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(me.hModule, _CRT_STRINGIZE(LoadLibrary)), lpBaseAddress, 0, NULL);
CloseHandle(hThread);
return TRUE;
}
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
THREADENTRY32 te;
@@ -134,7 +57,7 @@ VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThrea
CloseHandle(hSnap);
*lpcb = count;
_tdbgprintf(_T("Suspended other threads."));
_tdbgprintf(_T("Suspended %d other threads."), count);
}
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
@@ -142,7 +65,38 @@ VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T cb) {
ResumeThread(lphThreads[i]);
CloseHandle(lphThreads[i]);
}
_tdbgprintf(_T("Resumed threads."));
_tdbgprintf(_T("Resumed %d other threads."), cb);
}
BOOL WindowsVersionCompare(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask) {
OSVERSIONINFOEX osvi;
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
osvi.dwMajorVersion = dwMajorVersion;
osvi.dwMinorVersion = dwMinorVersion;
osvi.wServicePackMajor = wServicePackMajor;
osvi.wServicePackMinor = wServicePackMinor;
DWORDLONG dwlConditionMask = 0;
VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, Operator);
VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, Operator);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMAJOR, Operator);
VER_SET_CONDITION(dwlConditionMask, VER_SERVICEPACKMINOR, Operator);
return VerifyVersionInfo(&osvi, dwTypeMask, dwlConditionMask);
}
BOOL Is64BitWindows(void) {
#if defined(_WIN64)
return TRUE; // 64-bit programs run only on Win64
#elif defined(_WIN32)
// 32-bit programs run on both 32-bit and 64-bit Windows
// so must sniff
BOOL f64 = FALSE;
return IsWow64Process(GetCurrentProcess(), &f64) && f64;
#else
return FALSE; // Win64 does not support Win16
#endif
}
VOID _wdbgprintf(LPCWSTR format, ...) {

View File

@@ -3,12 +3,6 @@
EXTERN_C IMAGE_DOS_HEADER __ImageBase;
#define HINST_THISCOMPONENT ((HINSTANCE)&__ImageBase)
BOOL IsWindows7Or8Point1(void);
BOOL IsWindows7(void);
BOOL IsWindows8Point1(void);
VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID lpNewAddress);
#define DETOUR_IAT(x, y) \
@@ -20,14 +14,14 @@ VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID l
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName);
BOOL FindPattern(LPCBYTE lpBytes, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset);
BOOL InjectLibrary(HANDLE hProcess, LPCTSTR lpLibFileName, DWORD cb);
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize);
BOOL WindowsVersionCompare(BYTE Operator, DWORD dwMajorVersion, DWORD dwMinorVersion, WORD wServicePackMajor, WORD wServicePackMinor, DWORD dwTypeMask);
BOOL Is64BitWindows(void);
VOID _wdbgprintf(LPCWSTR format, ...);
VOID _dbgprintf(LPCSTR format, ...);
//#ifdef _DEBUG

Binary file not shown.

View File

@@ -105,6 +105,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_USRDLL;WUFUC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -119,6 +120,7 @@
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<PreprocessorDefinitions>_DEBUG;_WINDOWS;_USRDLL;WUFUC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -135,6 +137,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_USRDLL;WUFUC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -157,6 +160,7 @@
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<PreprocessorDefinitions>NDEBUG;_WINDOWS;_USRDLL;WUFUC_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Windows</SubSystem>
@@ -173,7 +177,8 @@
<ItemGroup>
<ClCompile Include="core.c" />
<ClCompile Include="dllmain.c" />
<ClCompile Include="entrypoint.c" />
<ClCompile Include="patternfind.c" />
<ClCompile Include="rundll32.c" />
<ClCompile Include="service.c" />
<ClCompile Include="util.c" />
</ItemGroup>
@@ -182,6 +187,7 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="core.h" />
<ClInclude Include="patternfind.h" />
<ClInclude Include="service.h" />
<ClInclude Include="shellapihelper.h" />
<ClInclude Include="util.h" />