-
Notifications
You must be signed in to change notification settings - Fork 60
Initial support for WMI value spoofing #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: capemon
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,11 @@ | ||
| #include <stdio.h> | ||
| #include "log.h" | ||
| #include "misc.h" | ||
| #include "config.h" | ||
|
|
||
| static int g_last_seen_disk_query = 0; | ||
| static int g_last_seen_physicalmemory = 0; | ||
|
|
||
|
|
||
| HOOKDEF(HRESULT, WINAPI, WMI_Get, | ||
| PVOID _this, | ||
|
|
@@ -10,7 +16,79 @@ HOOKDEF(HRESULT, WINAPI, WMI_Get, | |
| LONG* plFlavor | ||
| ) { | ||
| HRESULT ret; | ||
| lasterror_t lasterror; | ||
|
|
||
| ret = Old_WMI_Get(_this, wszName, lFlags, pVal, pType, plFlavor); | ||
|
|
||
| get_lasterrors(&lasterror); | ||
| __try { | ||
| if (!ret && !g_config.no_stealth && pVal && wszName) { | ||
| if (pVal->vt == VT_BSTR) { | ||
| if (!wcsicmp(wszName, L"TotalPhysicalMemory")) { | ||
| unsigned long long actualMemory = wcstoull(pVal->bstrVal, NULL, 10); | ||
| if (actualMemory < SPOOFED_RAM) { | ||
| wchar_t wszMemory[16]; | ||
| memset(wszMemory, 0x0, sizeof(wszMemory)); | ||
| swprintf_s(wszMemory, sizeof(wszMemory), L"%llu", SPOOFED_RAM); | ||
| SysFreeString(pVal->bstrVal); | ||
| pVal->bstrVal = SysAllocString(wszMemory); | ||
| } | ||
| } | ||
| else if (!wcsicmp(wszName, L"TotalVisibleMemorySize")) { | ||
| unsigned long long actualMemory = wcstoull(pVal->bstrVal, NULL, 10); | ||
| // actualMemory is in Kilobytes, our spoofed values are in bytes | ||
| if (actualMemory < (SPOOFED_RAM / 1024)) { | ||
| wchar_t wszMemory[16]; | ||
| memset(wszMemory, 0x0, sizeof(wszMemory)); | ||
| swprintf_s(wszMemory, sizeof(wszMemory), L"%llu", (SPOOFED_RAM / 1024)); | ||
| SysFreeString(pVal->bstrVal); | ||
| pVal->bstrVal = SysAllocString(wszMemory); | ||
| } | ||
| } | ||
| else if (g_last_seen_disk_query && !wcsicmp(wszName, L"Size")) { | ||
| unsigned long long lSize = wcstoull(pVal->bstrVal, NULL, 10); | ||
| if (lSize < SPOOFED_DISK_SIZE - RECOVERY_PARTITION_SIZE) { | ||
| wchar_t newSize[16]; | ||
| memset(newSize, 0x0, sizeof(newSize)); | ||
| swprintf_s(newSize, sizeof(newSize), L"%llu", SPOOFED_DISK_SIZE - RECOVERY_PARTITION_SIZE); | ||
| SysFreeString(pVal->bstrVal); | ||
| pVal->bstrVal = SysAllocString(newSize); | ||
| } | ||
| } | ||
| else if (g_last_seen_physicalmemory && !wcsicmp(wszName, L"Capacity")) { | ||
| unsigned long long actualMemory = wcstoull(pVal->bstrVal, NULL, 10); | ||
| if (actualMemory < SPOOFED_RAM) { | ||
| wchar_t wszMemory[16]; | ||
| memset(wszMemory, 0x0, sizeof(wszMemory)); | ||
| swprintf_s(wszMemory, sizeof(wszMemory), L"%llu", SPOOFED_RAM); | ||
| SysFreeString(pVal->bstrVal); | ||
| pVal->bstrVal = SysAllocString(wszMemory); | ||
| } | ||
| } | ||
| } | ||
| else if (pVal->vt == VT_I4) { | ||
| if (!wcsicmp(wszName, L"NumberOfCores")) { | ||
| if (pVal->lVal < SPOOFED_CPU_CORE_NUM) | ||
| pVal->lVal = SPOOFED_CPU_CORE_NUM; | ||
| } | ||
| else if (!wcsicmp(wszName, L"AdapterRAM")) { | ||
| if (pVal->lVal < SPOOFED_GPU_RAM) { | ||
| pVal->lVal = SPOOFED_GPU_RAM_WMI; | ||
| } | ||
| } | ||
| else if (!wcsicmp(wszName, L"MaxRefreshRate")) { | ||
| if (pVal->lVal < SPOOFED_REFRESH_RATE) { | ||
| pVal->lVal = SPOOFED_REFRESH_RATE; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| } | ||
| __except (EXCEPTION_EXECUTE_HANDLER) { | ||
| ; | ||
| } | ||
| set_lasterrors(&lasterror); | ||
|
|
||
| LOQ_hresult("system", "un", "Name", wszName, "Value", pVal); | ||
| return ret; | ||
| } | ||
|
|
@@ -24,7 +102,23 @@ HOOKDEF_NOTAIL(WINAPI, WMI_ExecQuery, | |
| PVOID* ppEnum | ||
| ) { | ||
| HRESULT ret = 0; | ||
| LOQ_hresult("system", "u", "Query", strQuery); | ||
|
|
||
| // Reset these on new query | ||
| g_last_seen_disk_query = 0; | ||
| g_last_seen_physicalmemory = 0; | ||
|
|
||
| if (!ret && !g_config.no_stealth && strQuery) { | ||
| if (!_wcsnicmp(strQuery, L"SELECT ", 7)) { | ||
| if (wcsistr(strQuery, L" FROM Win32_LogicalDisk")) { | ||
| g_last_seen_disk_query = 1; | ||
| //pipe("INFO:setting g_last_seen_disk_query"); | ||
| } | ||
| else if (wcsistr(strQuery, L" FROM Win32_PhysicalMemory")) { | ||
| g_last_seen_physicalmemory = 1; | ||
| } | ||
| } | ||
| } | ||
| LOQ_hresult("system", "uu", "Query", strQuery, "QueryLanguage", strQueryLanguage); | ||
| return 0; | ||
|
Comment on lines
104
to
122
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The As a consequence, the logic in To fix this,
I've provided a suggested implementation for the function body below. Note that this also requires changing HRESULT ret;
// Reset these on new query
g_last_seen_disk_query = 0;
g_last_seen_physicalmemory = 0;
if (!g_config.no_stealth && strQuery) {
if (!_wcsnicmp(strQuery, L"SELECT ", 7)) {
if (wcsistr(strQuery, L" FROM Win32_LogicalDisk")) {
g_last_seen_disk_query = 1;
//pipe("INFO:setting g_last_seen_disk_query");
}
else if (wcsistr(strQuery, L" FROM Win32_PhysicalMemory")) {
g_last_seen_physicalmemory = 1;
}
}
}
ret = Old_WMI_ExecQuery(_this, strQueryLanguage, strQuery, lFlags, pCtx, ppEnum);
LOQ_hresult("system", "uu", "Query", strQuery, "QueryLanguage", strQueryLanguage);
return ret; |
||
| } | ||
|
|
||
|
|
@@ -66,7 +160,6 @@ HOOKDEF_NOTAIL(WINAPI, WMI_ExecMethodAsync, | |
| PVOID pResponseHandler | ||
| ) { | ||
| HRESULT ret = 0; | ||
| LOQ_hresult("system", "uu", "ObjectPath", strObjectPath, "MethodName", strMethodName); | ||
| return 0; | ||
| } | ||
|
|
||
|
|
@@ -82,7 +175,7 @@ HOOKDEF_NOTAIL(WINAPI, WMI_GetObject, | |
| if (strObjectPath && SysStringLen(strObjectPath) > 0) | ||
| LOQ_hresult("system", "u", "ObjectPath", strObjectPath); | ||
| else | ||
| LOQ_hresult("system", "u", "ObjectPath", L"[NULL or Empty]"); | ||
| LOQ_hresult("system", "u", "ObjectPath", L""); | ||
| return 0; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a lot of duplicated code for handling
VT_BSTRspoofing. The logic for converting a spoofed value to aBSTRand replacing the existing one is repeated multiple times.To improve maintainability and reduce redundancy, you could extract this logic into a helper function. For example:
Then you can simplify the code like this:
This would make the code much cleaner and easier to maintain.