Перехват sendto () вызывает сбой в зависимости от порядка кода - PullRequest
3 голосов
/ 05 августа 2011

Я использую DLL-инжектор, чтобы внедрить dll, который входит в IAT и заменяет системный вызов sendto () на мой собственный.

Это метод замены.

void replaceFunction(DWORD f, DWORD nf)
{
// Base address.
HMODULE hMod = GetModuleHandle(NULL);

// DOS Header.
PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)hMod;

// NT Header.
PIMAGE_NT_HEADERS ntHeader = MakePtr(PIMAGE_NT_HEADERS, dosHeader, dosHeader->e_lfanew);

// Import Table descriptor.
PIMAGE_IMPORT_DESCRIPTOR importDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, dosHeader,ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);

// Make writeable.
removeReadOnly(MakePtr(PIMAGE_THUNK_DATA, hMod, importDesc->FirstThunk));

while(importDesc->Name)
{
    PIMAGE_THUNK_DATA pThunk = MakePtr(PIMAGE_THUNK_DATA, dosHeader, importDesc->FirstThunk);

    while (pThunk->u1.Function)
    {
        if(pThunk->u1.Function == f)
        {
            pThunk->u1.Function = nf;
        }
        pThunk++;
    }

    importDesc++;
}
}

Вызывается:

// Get the Function Address
DWORD f = (DWORD)GetProcAddress(GetModuleHandleA("ws2_32.dll"),"sendto");
DWORD nf = (DWORD)&my_sendto;

// Save real sendto address.
real_sendto = (int (*)(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen))f;

// Replace function.
replaceFunction(f, nf);

Это работает:

int my_sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen)
{
    CreateThread(NULL, 0, de_sendto, NULL, 0, NULL);
    return real_sendto(s, buf, len, flags, to, tolen);
}

Это не работа:

int my_sendto(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen)
{
    int l = real_sendto(s, buf, len, flags, to, tolen);
    CreateThread(NULL, 0, de_sendto, NULL, 0, NULL);
    return l;
}

При использовании последней версии my_sendto () происходит сбой приложения хоста при вызове sendto ().

de_sendto определяется как:

DWORD WINAPI de_sendto(LPVOID args) { }

1 Ответ

3 голосов
/ 05 августа 2011

Ваше соглашение о вызовах неверно.Соглашение о вызовах по умолчанию для C ++ - __cdecl, но sendto - это __stdcall.Измените соглашение о вызовах с my_sendto на __stdcall, чтобы исправить ошибку.

...