绕行 GetComputerNameW
Detour GetComputerNameW
您好,我正在尝试使用 Microsoft 绕道拦截 GetComputerNameW,但这似乎不可能。我已经设法绕过 GetVolumeInforation 但这个似乎有所不同。
我正在尝试将计算机名称从 DKKKK 更改为 ABCDE。
不走弯路的结果
结果附带弯路
我错过了什么?
#include <detours.h>
#pragma comment(lib,"detours.lib")
HMODULE hLib = GetModuleHandle(L"Kernel32.dll");
typedef BOOL (WINAPI *CPNMPtr)(LPWSTR lpBuffer,LPDWORD &lpnSize);
CPNMPtr pCPNM = (CPNMPtr)GetProcAddress(hLib, "GetComputerNameW");
BOOL WINAPI MyGetComputerNameW(LPWSTR a0, LPDWORD a1)
{
BOOL rv = 0;
rv = pCPNM(a0, a1);
wchar_t* wcBuff = L"ABCDE";
a0 = wcBuff;
printf("GetComputerNameW(%ls,) -> %p\n", a0, rv);
return rv;
}
int _tmain(int argc, _TCHAR* argv[])
{
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pCPNM, MyGetComputerNameW);
DetourTransactionCommit();
WCHAR wzComputerName[MAX_COMPUTERNAME_LENGTH+1];
DWORD dwSize = sizeof(wzComputerName)/sizeof(wzComputerName[0]);
if (GetComputerName(wzComputerName, &dwSize))
printf ("GetComputerName returned %S of length %u\n", wzComputerName, dwSize);
}
您只是覆盖了 a0
的本地指针值,而您应该覆盖它的内容。
试试这个:
wcsncpy(a0, L"ABCDE", *a1);
*a1 = wcslen(a0);
正如 Remy Lebeau 指出的那样:您对原始 GetComputerNameW()
的调用将修改 *a1
的值,因此您可以先复制它的值。
无论如何,由于您是自己生成名称,所以我认为没有理由调用原始名称 GetComputerNameW()
。
除了 Wouter 所说的,您对 MyGetComputerNameW()
的实现还有其他一些逻辑漏洞。即,滥用 wcsncpy()
的输入值,并且在复制修改后的数据后不更新 a1
的值。
试试像这样的东西:
BOOL WINAPI MyGetComputerNameW(LPWSTR a0, LPDWORD a1)
{
DWORD size = *a1;
BOOL rv = pCPNM(a0, a1);
if (rv)
{
//if (wcscmp(a0, L"DKKKK") == 0)
{
if (size > 5)
{
wcsncpy(a0, L"ABCDE", size);
*a1 = 5;
}
else
{
*a1 = 6;
SetLastError(ERROR_BUFFER_OVERFLOW);
rv = FALSE;
}
}
}
return rv;
}
您好,我正在尝试使用 Microsoft 绕道拦截 GetComputerNameW,但这似乎不可能。我已经设法绕过 GetVolumeInforation 但这个似乎有所不同。 我正在尝试将计算机名称从 DKKKK 更改为 ABCDE。
不走弯路的结果
结果附带弯路
我错过了什么?
#include <detours.h>
#pragma comment(lib,"detours.lib")
HMODULE hLib = GetModuleHandle(L"Kernel32.dll");
typedef BOOL (WINAPI *CPNMPtr)(LPWSTR lpBuffer,LPDWORD &lpnSize);
CPNMPtr pCPNM = (CPNMPtr)GetProcAddress(hLib, "GetComputerNameW");
BOOL WINAPI MyGetComputerNameW(LPWSTR a0, LPDWORD a1)
{
BOOL rv = 0;
rv = pCPNM(a0, a1);
wchar_t* wcBuff = L"ABCDE";
a0 = wcBuff;
printf("GetComputerNameW(%ls,) -> %p\n", a0, rv);
return rv;
}
int _tmain(int argc, _TCHAR* argv[])
{
DetourRestoreAfterWith();
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)pCPNM, MyGetComputerNameW);
DetourTransactionCommit();
WCHAR wzComputerName[MAX_COMPUTERNAME_LENGTH+1];
DWORD dwSize = sizeof(wzComputerName)/sizeof(wzComputerName[0]);
if (GetComputerName(wzComputerName, &dwSize))
printf ("GetComputerName returned %S of length %u\n", wzComputerName, dwSize);
}
您只是覆盖了 a0
的本地指针值,而您应该覆盖它的内容。
试试这个:
wcsncpy(a0, L"ABCDE", *a1);
*a1 = wcslen(a0);
正如 Remy Lebeau 指出的那样:您对原始 GetComputerNameW()
的调用将修改 *a1
的值,因此您可以先复制它的值。
无论如何,由于您是自己生成名称,所以我认为没有理由调用原始名称 GetComputerNameW()
。
除了 Wouter 所说的,您对 MyGetComputerNameW()
的实现还有其他一些逻辑漏洞。即,滥用 wcsncpy()
的输入值,并且在复制修改后的数据后不更新 a1
的值。
试试像这样的东西:
BOOL WINAPI MyGetComputerNameW(LPWSTR a0, LPDWORD a1)
{
DWORD size = *a1;
BOOL rv = pCPNM(a0, a1);
if (rv)
{
//if (wcscmp(a0, L"DKKKK") == 0)
{
if (size > 5)
{
wcsncpy(a0, L"ABCDE", size);
*a1 = 5;
}
else
{
*a1 = 6;
SetLastError(ERROR_BUFFER_OVERFLOW);
rv = FALSE;
}
}
}
return rv;
}