根据代码顺序,挂钩 sendto() 会导致崩溃

Posted

技术标签:

【中文标题】根据代码顺序,挂钩 sendto() 会导致崩溃【英文标题】:Hooking sendto() causes crash depending on code ordering 【发布时间】:2011-08-04 22:51:44 【问题描述】:

我正在使用 DLL 注入器来注入一个 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)  

【问题讨论】:

请定义有效无效 另外,如果您愿意,请显示de_sendto 函数的来源。 不工作,因为在调用 sendto() 函数时主机应用程序崩溃。 de_sendto 为空,即:DWORD WINAPI de_sendto(LPVOID args) 您确定my_sendtosendto 具有相同的调用约定吗?当我钩住东西时,这可能是我崩溃的最大原因。 【参考方案1】:

您的调用约定不正确。 C++ 的默认调用约定是__cdecl,但sendto 的调用约定是__stdcall。将 my_sendto 的调用约定更改为 __stdcall 以修复崩溃。

【讨论】:

@Mark 我只是猜到了,因为这让我头疼了好几个小时。一定喜欢从 Delphi 模拟 __thiscall

以上是关于根据代码顺序,挂钩 sendto() 会导致崩溃的主要内容,如果未能解决你的问题,请参考以下文章

什么会导致 iPad(第 3 代)在启动时崩溃但在模拟器中工作?

根据恒定条件调用反应挂钩是不是安全?

调用 `reloadItems(at:)` 会导致程序崩溃

什么会导致 Windows 取消挂钩低级别(全局)键盘挂钩?

反应挂钩以根据先前的状态值更新状态[重复]

为啥程序退出时全局或静态对象会导致崩溃?