gpt4 book ai didi

c++ - 用户模式下可用的最低级别 WinSock API 是什么? (用于 API 注入(inject)蹦床。)

转载 作者:搜寻专家 更新时间:2023-10-31 02:10:45 35 4
gpt4 key购买 nike

我的目标是拦截来 self 没有源代码的定制应用程序的出站 TCP 数据包。我需要调整出站数据中的几个参数。这是一个较旧的应用程序,原来的公司不再销售并且开发人员不再可用。

所以我计划在 send() 中安装 API 注入(inject)蹦床从我的 DLL 中键入原始 WinSock API,我可以将其注入(inject)目标进程。但是在编写这样的 DLL 之前,我决定在我的本地进程中测试这个概念。所以我做了以下事情:

#ifdef _M_X64
//Simple code to install "API injection trampoline"
//Compiled as 64-bit process

static int WINAPI TestJump1(SOCKET s, const char *buf, int len, int flags);
{
//This part is just for debugging to make sure that my trampoline method is called
//The actual "working" trampoline will involve additional steps to insure that the original method is also called
::MessageBox(NULL, L"Injected method called!", L"Debugger Message", MB_OK);
return SOCKET_ERROR;
}


HMODULE hModWS2 = ::LoadLibrary(L"Ws2_32.dll");
if(hModWS2)
{
int (WINAPI *pfn_send)(SOCKET s, const char *buf, int len, int flags);
int (WINAPI *pfn_sendto)(SOCKET s, const char *buf, int len, int flags, const struct sockaddr *to, int tolen);

if(pfn_send &&
pfn_sendto)
{
//Long absolute JMP
//48 b8 xx xx xx xx xx xx xx xx mov rax, 0xxxx
//ff e0 jmp rax

BYTE subst[] = {
0x48, 0xb8,
0, 0, 0, 0,
0, 0, 0, 0,
0xff, 0xe0
};

HANDLE hProc = ::GetCurrentProcess();

VOID* pPtrAPI = pfn_send;
//Also tried with
//VOID* pPtrAPI = pfn_sendto;

//Make this address writable
DWORD dwOldProtect = 0;
if(::VirtualProtectEx(hProc, pPtrAPI, sizeof(subst), PAGE_EXECUTE_READWRITE, &dwOldProtect))
{
//Install JMP opcodes
VOID* pJumpPtr = TestJump1;
*(VOID**)(subst + 2) = pJumpPtr;
memcpy(pPtrAPI, subst, sizeof(subst));

//Reset it back
DWORD dwDummy;
if(::VirtualProtectEx(hProc, pPtrAPI, sizeof(subst), dwOldProtect, &dwDummy))
{
if(::FlushInstructionCache(hProc, pPtrAPI, sizeof(subst)))
{
//Try to call our method
//int rz = pfn_send(NULL, "", 0, 0); //This works!

//Try real test with the higher level API
//Download a web page into a file:
//This API must be calling raw sockets at some point internally...
//but my TestJump1() is never called from here...
HRESULT hr = URLDownloadToFile(NULL,
L"http://microsoft.com/",
L"C:\\Users\\User\\Desktop\\file.txt", 0, NULL);

}
}
}
}
}
#endif

所以代码工作正常,如果我显式调用 send 方法(如上所示),JMP trampoline 已安装并调用正常,但我进一步假设更高级别API(即 URLDownloadToFile)也会调用它,但似乎并不成立。从未从中调用我的蹦床方法。

那么我在这里缺少什么?是否有更低的 WinSock API?

最佳答案

send() 并不是唯一可用于在用户代码中使用 Winsock 发送 TCP 数据的函数。还有:

  • WSASend()
  • WSASendDisconnect()
  • WSASendMsg()
  • 传输文件()
  • TransmitPackets()
  • RIOSend/Ex()

至少,不使用 send() 的应用程序将通常使用 WSASend() 代替,以便与 Overlapped 一起使用I/O 或 I/O 完成端口。对于大多数情况,这通常就足够了。其他函数用得不多,但在某些确实需要更高性能的情况下可能会用到。

关于c++ - 用户模式下可用的最低级别 WinSock API 是什么? (用于 API 注入(inject)蹦床。),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44791084/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com