0

Hello I'm trying to intercept GetComputerNameW with microsoft detours however it seems not possible. I've already managed to detour GetVolumeInforation but this one seems different. I'm trying to change the Computer name from DKKKK to ABCDE.

Result without detours

Image without detours attached

Result with detours attached

Image with detours

What am I missing?

#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);
}
huysentruitw
  • 27,376
  • 9
  • 90
  • 133
Asmo
  • 27
  • 1
  • 9

2 Answers2

3

You are just overwriting the local pointer value of a0 while you should be overwriting its content instead.

Try this:

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

And as Remy Lebeau pointed out: your call to the original GetComputerNameW() will modify the value of *a1 so you might copy its value first.

Anyway, since you're generating the name yourself, I see no reason to call the original GetComputerNameW().

huysentruitw
  • 27,376
  • 9
  • 90
  • 133
  • Since the code is calling the original `GetComputerNameW()` before modifying the data in `a0`, `a1` will contain the modified buffer size before `wcsncpy()` is called. You need to specify the full buffer size instead (the value of `a1` before it is modified). Also, after calling `wcsncpy()`, you need to update `a1` to specify the actual number of characters copied. If the code is run on a computer whose real name is not 5 characters in length, the modified buffer data will not be interpreted correctly. – Remy Lebeau Dec 11 '15 at 01:00
1

In addition to what Wouter said, your implementation of MyGetComputerNameW() has some other logic holes in it. Namely, misusing the input values of wcsncpy(), and not updating the value of a1 after copying your modified data.

Try something more like this:

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;
}
Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770