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!
This commit is contained in:
45
wufuc/core.c
45
wufuc/core.c
@@ -5,6 +5,7 @@
|
|||||||
#include <sddl.h>
|
#include <sddl.h>
|
||||||
#include "service.h"
|
#include "service.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "patternfind.h"
|
||||||
#include "core.h"
|
#include "core.h"
|
||||||
|
|
||||||
DWORD WINAPI NewThreadProc(LPVOID lpParam) {
|
DWORD WINAPI NewThreadProc(LPVOID lpParam) {
|
||||||
@@ -46,7 +47,7 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
|
|||||||
get_svcdll(_T("wuauserv"), lpServiceDll, _countof(lpServiceDll));
|
get_svcdll(_T("wuauserv"), lpServiceDll, _countof(lpServiceDll));
|
||||||
|
|
||||||
HMODULE hwu = GetModuleHandle(lpServiceDll);
|
HMODULE hwu = GetModuleHandle(lpServiceDll);
|
||||||
if (hwu && PatchWUModule(hwu)) {
|
if (hwu && PatchWUAgentHMODULE(hwu)) {
|
||||||
_tdbgprintf(_T("Patched previously loaded Windows Update module!"));
|
_tdbgprintf(_T("Patched previously loaded Windows Update module!"));
|
||||||
}
|
}
|
||||||
ResumeAndCloseThreads(lphThreads, cb);
|
ResumeAndCloseThreads(lphThreads, cb);
|
||||||
@@ -66,35 +67,20 @@ DWORD WINAPI NewThreadProc(LPVOID lpParam) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL PatchWUModule(HMODULE hModule) {
|
BOOL PatchWUAgentHMODULE(HMODULE hModule) {
|
||||||
LPSTR lpszPattern;
|
LPSTR lpszPattern;
|
||||||
SIZE_T n1, n2;
|
SIZE_T n1, n2;
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
lpszPattern =
|
lpszPattern = "FFF3 4883EC?? 33DB 391D???????? 7508 8B05????????";
|
||||||
"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;
|
n1 = 10;
|
||||||
n2 = 18;
|
n2 = 18;
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
if (WindowsVersionCompare(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
|
if (WindowsVersionCompare(VER_EQUAL, 6, 1, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
|
||||||
lpszPattern =
|
lpszPattern = "833D????????00 743E E8???????? A3????????";
|
||||||
"833D????????00" // cmp dword ptr ds:[????????],0
|
|
||||||
"743E" // je $+3E
|
|
||||||
"E8????????" // call <wuaueng.IsCPUSupported>
|
|
||||||
"A3????????"; // mov dword ptr ds:[????????],eax
|
|
||||||
n1 = 2;
|
n1 = 2;
|
||||||
n2 = 15;
|
n2 = 15;
|
||||||
} else if (WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
|
} else if (WindowsVersionCompare(VER_EQUAL, 6, 3, 0, 0, VER_MAJORVERSION | VER_MINORVERSION)) {
|
||||||
lpszPattern =
|
lpszPattern = "8BFF 51 833D????????00 7507 A1????????";
|
||||||
"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;
|
n1 = 5;
|
||||||
n2 = 13;
|
n2 = 13;
|
||||||
}
|
}
|
||||||
@@ -105,20 +91,21 @@ BOOL PatchWUModule(HMODULE hModule) {
|
|||||||
MODULEINFO modinfo;
|
MODULEINFO modinfo;
|
||||||
GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
|
GetModuleInformation(GetCurrentProcess(), hModule, &modinfo, sizeof(MODULEINFO));
|
||||||
|
|
||||||
SIZE_T rva;
|
SIZE_T rva = patternfind(modinfo.lpBaseOfDll, modinfo.SizeOfImage, 0, lpszPattern);
|
||||||
if (!FindPattern(modinfo.lpBaseOfDll, modinfo.SizeOfImage, lpszPattern, 0, &rva)) {
|
if (rva == -1) {
|
||||||
_tdbgprintf(_T("No pattern match!"));
|
_tdbgprintf(_T("No pattern match!"));
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIZE_T fpIsDeviceServiceable = (SIZE_T)modinfo.lpBaseOfDll + rva;
|
SIZE_T fpIsDeviceServiceable = (SIZE_T)modinfo.lpBaseOfDll + rva;
|
||||||
_tdbgprintf(_T("Pattern match at offset %p."), fpIsDeviceServiceable);
|
_tdbgprintf(_T("Pattern match at offset %p."), fpIsDeviceServiceable);
|
||||||
|
|
||||||
BOOL result = FALSE;
|
BOOL result = FALSE;
|
||||||
|
|
||||||
|
DWORD flOldProtect;
|
||||||
|
DWORD flNewProtect = PAGE_READWRITE;
|
||||||
BOOL *lpbNotRunOnce = (BOOL *)(fpIsDeviceServiceable + n1 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n1));
|
BOOL *lpbNotRunOnce = (BOOL *)(fpIsDeviceServiceable + n1 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n1));
|
||||||
if (*lpbNotRunOnce) {
|
if (*lpbNotRunOnce) {
|
||||||
DWORD flOldProtect;
|
|
||||||
DWORD flNewProtect = PAGE_READWRITE;
|
|
||||||
VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flNewProtect, &flOldProtect);
|
VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flNewProtect, &flOldProtect);
|
||||||
*lpbNotRunOnce = FALSE;
|
*lpbNotRunOnce = FALSE;
|
||||||
VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flOldProtect, &flNewProtect);
|
VirtualProtect(lpbNotRunOnce, sizeof(BOOL), flOldProtect, &flNewProtect);
|
||||||
@@ -128,8 +115,6 @@ BOOL PatchWUModule(HMODULE hModule) {
|
|||||||
|
|
||||||
BOOL *lpbCachedResult = (BOOL *)(fpIsDeviceServiceable + n2 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n2));
|
BOOL *lpbCachedResult = (BOOL *)(fpIsDeviceServiceable + n2 + sizeof(DWORD) + *(DWORD *)(fpIsDeviceServiceable + n2));
|
||||||
if (!*lpbCachedResult) {
|
if (!*lpbCachedResult) {
|
||||||
DWORD flOldProtect;
|
|
||||||
DWORD flNewProtect = PAGE_READWRITE;
|
|
||||||
VirtualProtect(lpbCachedResult, sizeof(BOOL), flNewProtect, &flOldProtect);
|
VirtualProtect(lpbCachedResult, sizeof(BOOL), flNewProtect, &flOldProtect);
|
||||||
*lpbCachedResult = TRUE;
|
*lpbCachedResult = TRUE;
|
||||||
VirtualProtect(lpbCachedResult, sizeof(BOOL), flOldProtect, &flNewProtect);
|
VirtualProtect(lpbCachedResult, sizeof(BOOL), flOldProtect, &flNewProtect);
|
||||||
@@ -145,14 +130,14 @@ HMODULE WINAPI _LoadLibraryExA(
|
|||||||
_In_ DWORD dwFlags
|
_In_ DWORD dwFlags
|
||||||
) {
|
) {
|
||||||
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
|
HMODULE result = LoadLibraryExA(lpFileName, hFile, dwFlags);
|
||||||
_dbgprintf("Loaded %s.", lpFileName);
|
|
||||||
if (result) {
|
if (result) {
|
||||||
|
_dbgprintf("Loaded %s.", lpFileName);
|
||||||
CHAR path[MAX_PATH + 1];
|
CHAR path[MAX_PATH + 1];
|
||||||
if (!get_svcdllA("wuauserv", path, _countof(path))) {
|
if (!get_svcdllA("wuauserv", path, _countof(path))) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_stricmp(lpFileName, path) && PatchWUModule(result)) {
|
if (!_stricmp(lpFileName, path) && PatchWUAgentHMODULE(result)) {
|
||||||
_dbgprintf("Patched Windows Update module!");
|
_dbgprintf("Patched Windows Update module!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -165,14 +150,14 @@ HMODULE WINAPI _LoadLibraryExW(
|
|||||||
_In_ DWORD dwFlags
|
_In_ DWORD dwFlags
|
||||||
) {
|
) {
|
||||||
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
|
HMODULE result = LoadLibraryExW(lpFileName, hFile, dwFlags);
|
||||||
_wdbgprintf(L"Loaded library: %s.", lpFileName);
|
|
||||||
if (result) {
|
if (result) {
|
||||||
|
_wdbgprintf(L"Loaded library: %s.", lpFileName);
|
||||||
WCHAR path[MAX_PATH + 1];
|
WCHAR path[MAX_PATH + 1];
|
||||||
if (!get_svcdllW(L"wuauserv", path, _countof(path))) {
|
if (!get_svcdllW(L"wuauserv", path, _countof(path))) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_wcsicmp(lpFileName, path) && PatchWUModule(result)) {
|
if (!_wcsicmp(lpFileName, path) && PatchWUAgentHMODULE(result)) {
|
||||||
_wdbgprintf(L"Patched Windows Update module!");
|
_wdbgprintf(L"Patched Windows Update module!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
DWORD WINAPI NewThreadProc(LPVOID lpParam);
|
DWORD WINAPI NewThreadProc(LPVOID lpParam);
|
||||||
|
|
||||||
BOOL PatchWUModule(HMODULE hModule);
|
BOOL PatchWUAgentHMODULE(HMODULE hModule);
|
||||||
|
|
||||||
HMODULE WINAPI _LoadLibraryExA(
|
HMODULE WINAPI _LoadLibraryExA(
|
||||||
_In_ LPCSTR lpFileName,
|
_In_ LPCSTR lpFileName,
|
||||||
|
118
wufuc/patternfind.c
Normal file
118
wufuc/patternfind.c
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
#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 ch) {
|
||||||
|
int result = -1;
|
||||||
|
if (ch >= '0' && ch <= '9') {
|
||||||
|
result = ch - '0';
|
||||||
|
} else if (ch >= 'A' && ch <= 'F') {
|
||||||
|
result = ch - 'A' + 10;
|
||||||
|
} else if (ch >= 'a' && ch <= 'f') {
|
||||||
|
result = ch - '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) / 2) {
|
||||||
|
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 / 2;
|
||||||
|
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
16
wufuc/patternfind.h
Normal 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);
|
41
wufuc/util.c
41
wufuc/util.c
@@ -38,47 +38,6 @@ LPVOID *FindIAT(HMODULE hModule, LPSTR lpFunctionName) {
|
|||||||
return NULL;
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
|
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb) {
|
||||||
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
|
||||||
THREADENTRY32 te;
|
THREADENTRY32 te;
|
||||||
|
@@ -14,8 +14,6 @@ VOID DetourIAT(HMODULE hModule, LPSTR lpFuncName, LPVOID *lpOldAddress, LPVOID l
|
|||||||
|
|
||||||
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName);
|
LPVOID *FindIAT(HMODULE hModule, LPSTR lpFuncName);
|
||||||
|
|
||||||
BOOL FindPattern(LPCBYTE lpBytes, SIZE_T nNumberOfBytes, LPSTR lpszPattern, SIZE_T nStart, SIZE_T *lpOffset);
|
|
||||||
|
|
||||||
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);
|
VOID SuspendProcessThreads(DWORD dwProcessId, DWORD dwThreadId, HANDLE *lphThreads, SIZE_T dwSize, SIZE_T *lpcb);
|
||||||
|
|
||||||
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize);
|
VOID ResumeAndCloseThreads(HANDLE *lphThreads, SIZE_T dwSize);
|
||||||
|
@@ -177,6 +177,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClCompile Include="core.c" />
|
<ClCompile Include="core.c" />
|
||||||
<ClCompile Include="dllmain.c" />
|
<ClCompile Include="dllmain.c" />
|
||||||
|
<ClCompile Include="patternfind.c" />
|
||||||
<ClCompile Include="rundll32.c" />
|
<ClCompile Include="rundll32.c" />
|
||||||
<ClCompile Include="service.c" />
|
<ClCompile Include="service.c" />
|
||||||
<ClCompile Include="util.c" />
|
<ClCompile Include="util.c" />
|
||||||
@@ -186,6 +187,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="core.h" />
|
<ClInclude Include="core.h" />
|
||||||
|
<ClInclude Include="patternfind.h" />
|
||||||
<ClInclude Include="service.h" />
|
<ClInclude Include="service.h" />
|
||||||
<ClInclude Include="shellapihelper.h" />
|
<ClInclude Include="shellapihelper.h" />
|
||||||
<ClInclude Include="util.h" />
|
<ClInclude Include="util.h" />
|
||||||
|
Reference in New Issue
Block a user