绕道GetComputerNameW

时间:2015-12-10 22:14:54

标签: c++ hook detours

您好我试图用微软绕道拦截GetComputerNameW,但似乎不可能。我已经设法绕开GetVolumeInforation,但这个似乎有所不同。 我正在尝试将计算机名称从DKKKK更改为ABCDE。

没有绕路的结果

Image without detours attached

附带绕路的结果

Image with detours

我错过了什么?

#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);
}

2 个答案:

答案 0 :(得分:3)

您只是覆盖了a0的本地指针值,而您应该覆盖其内容。

试试这个:

wcsncpy(a0, L"ABCDE", *a1);
*a1 = wcslen(a0);

正如Remy Lebeau所指出的那样:您对原始GetComputerNameW()的调用会修改*a1的值,因此您可以先复制其值。

无论如何,由于您自己生成了该名称,因此我认为没有理由拨打原始GetComputerNameW()

答案 1 :(得分:1)

除了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;
}