我正在使用wpe-pro,我可以捕获数据包并将其发回。我尝试使用winsock 2(和wpe-pro使用的库相同),但我不知道如何像wpe-pro那样将数据包发送到现有的TCP连接。
http://wpepro.net/index.php?categoryid=2
我该怎么做?
最佳答案
你是在问如何让其他人的程序通过其现有的winsock连接发送数据?
我已经做到了,但不幸的是,目前没有手头的代码。如果你给我一两个小时,我可以用c来举一个工作示例;如果你需要一个,请告诉我,我会的。
编辑:如果你或者其他人想的话,可以在页面底部测试示例dll;我不能。我只知道它是编译的。你只需要下载(或者写!)一个免费的dll注入器程序来测试它;有很多。
同时,你需要研究的是:
关于如何执行exe的基本知识。
dll注入
API挂钩
Windows套接字API
1。关于如何执行exe的基本知识:
我要向你们解释的整个过程,归结起来就是这个原理。双击可执行文件时,windows会对其进行解析并将其代码等加载到内存中。这是钥匙。编译后的代码都被放入ram中。这意味着什么?好吧,如果应用程序的代码都在ram中,我们可以在应用程序运行时通过改变一些内存来改变它的代码吗?毕竟,这只是一堆指令。
答案是肯定的,并将为我们提供与另一个应用程序打交道的方法——在本例中,告诉它通过其打开的套接字发送一些数据。
(这个原则也是你必须小心用低级语言编写程序的原因,比如C语言,因为如果你把坏东西放在RAM的坏部分,它可能会使程序崩溃或打开你的外壳代码漏洞)。
2。dll注入:
问题是,我们如何知道要覆盖哪个内存?我们是否可以访问该程序的内存,特别是包含要更改的指令的部分?您可以写入另一个进程的内存,但它更复杂。更改内存的最简单方法(同样,当我说内存时,我们指的是正在执行的机器代码指令)是在该进程中加载并运行一个dll。把你的dll想象成一个.c文件,你可以添加到另一个程序并编写你自己的代码:你可以访问程序的变量,调用它的函数,任何东西;因为它在进程中运行。
dll注入可以通过多种方法完成。通常是通过调用createRemoteThread()api函数。在谷歌上搜索一下。
三。API钩子
什么是API挂钩?更一般地说,这是“函数挂接”,我们只是碰巧对挂接api调用感兴趣;在这种情况下,用于套接字的调用(socket()、send()等)。
我们举个例子。使用winsock用c编写的目标应用程序。让我们看看他们在做什么,然后展示一个我们想让他们做什么的例子:
他们最初的源代码创建了一个套接字:
SOCKET ConnectSocket = INVALID_SOCKET;
ConnectSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
现在,这是原始程序的源代码。我们的dll无法访问它,因为它是在一个exe中加载的,并且一个exe被编译(duh!)。所以假设在编译为机器代码(程序集)之后,它们对socket()的调用看起来像这样。我一点也不懂组装,但这只是为了说明:
装配/机器代码:
PUSH 06 ; IPPROTO_TCP
PUSH 01 ; SOCK_STREAM
PUSH 02 ; AF_INET
CALL WS2_32.socket ; This is one of the parts our DLL will need to intercept ("hook").
为了让程序发送数据(使用我们的dll),我们需要知道套接字的句柄。所以我们需要拦截他们对
socket
函数的调用。以下是一些注意事项:最后一条指令需要更改为:
CALL OurOwnDLL.socket
。指令只是内存中某个地方的一个值(还记得吗?)所以我们可以用writeprocessmemory来实现这一点。我们会解决的。我们想要控制目标程序,而不是使其崩溃或使其行为异常。所以我们的代码必须是透明的。我们将注入的dll需要有一个与原始函数相同的
CALL
函数,返回相同的值等。唯一的区别是,我们将记录返回值(socket
),以便稍后在发送数据时使用它。我们还需要知道套接字是否连接/何时连接,因为除非连接,否则我们无法发送数据(假设我们像大多数应用程序一样使用TCP)。这意味着我们还需要钩住winsock
SocketHandle
api函数,并将其复制到我们的dll中。要插入和监视
connect
和socket
函数的dll(未测试):这个C DLL将拥有所有可以挂接和取消挂接函数的功能。我现在不能测试它,我甚至不是一个C程序员,所以如果遇到任何问题,请告诉我。
将其编译为不使用Unicode的Windows dll,并将其注入到使用ws2_32的socket()和connect()函数的进程中,然后让我知道它是否工作。对不起,我没办法测试。如果您需要进一步的帮助或修复,请告诉我。
/*
SocketHookDLL.c
Author: Daniel Elkins
License: Public Domain
Version: 1.0.0
Created: May 14th, 2014 at 12:23 AM
Updated: [Never]
Summary:
1. Link to the Winsock library so we can use its functions.
2. Export our own `socket` and `connect` functions so that
they can be called by the target application instead of
the original ones from WS2_32.
3. "Hook" the socket APIs by writing over the target's memory,
causing `CALL WS2_32.socket` to `CALL SocketHookDLL.socket`, using
WriteProcessMemory.
4. Make sure to keep a copy of the original memory for when we no
no longer want to hook those socket functions (i.e. DLL detaching).
*/
#pragma comment(lib, "WS2_32.lib")
#include <WinSock2.h>
/* These functions hook and un-hook an API function. */
unsigned long hookFunction (const char * dllModule, const char * apiFunction, unsigned char * memoryBackup);
unsigned int unHookFunction (const char * dllModule, const char * apiFunction, unsigned char * memoryBackup);
/*
These functions (the ones we want to hook) are copies of the original Winsock's functions from Winsock2.h.
1. Calls OurDLL.hooked_socket() (unknowingly).
2. OurDLL.hooked_socket() calls the original Winsock.socket() function.
3. We take note of the returned SOCKET handle so we can use it later to send data.
4. OurDLL.hooked_socket() returns the SOCKET back to the target app so everthing works as it should (hopefully!).
Note: You can change return values, parameters (like data being sent/received like WPE does), just be aware it will
also (hopefully, intendingly) change the behavior of the target application.
*/
SOCKET WSAAPI hooked_socket (int af, int type, int protocol);
int WSAAPI hooked_connect (SOCKET s, const struct sockaddr FAR * name, int namelen);
/* Backups of the original memory; need one for each API function you hook (if you want to unhook it later). */
unsigned char backupSocket[6];
unsigned char backupConnect[6];
/* Our SOCKET handle used by the target application. */
SOCKET targetsSocket = INVALID_SOCKET;
/* This is the very first code that gets executed once our DLL is injected: */
BOOL APIENTRY DllMain (HMODULE moduleHandle, DWORD reason, LPVOID reserved)
{
/*
We will hook the desired Socket APIs when attaching
to target EXE and UN-hook them when being detached.
*/
switch (reason)
{
case DLL_PROCESS_ATTACH:
/* Here goes nothing! */
hookFunction ("WS2_32.DLL", "socket", backupSocket);
hookFunction ("WS2_32.DLL", "connect", backupConnect);
break;
case DLL_THREAD_ATTACH:
break;
case DLL_PROCESS_DETACH:
unHookFunction ("WS2_32.DLL", "socket", backupSocket);
unHookFunction ("WS2_32.DLL", "connect", backupConnect);
break;
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
unsigned long hookFunction (const char * dllModule, const char * apiFunction, unsigned char * memoryBackup)
{
/*
Hook an API function:
=====================
1. Build the necessary assembly (machine code) opcodes to get our DLL called!
2. Get a handle to the API we're hooking.
3. Use ReadProcessMemory() to backup the original memory to un-hook the function later.
4. Use WriteProcessMemory to make changes to the instructions in memory.
*/
HANDLE thisTargetProcess;
HMODULE dllModuleHandle;
unsigned long apiAddress;
unsigned long memoryWritePosition;
unsigned char newOpcodes[6] = {
0xE9, 0x00, 0x00, 0x00, 0x00, 0xC3 // Step #1.
};
thisTargetProcess = GetCurrentProcess ();
// Step #2.
dllModuleHandle = GetModuleHandle (dllModule);
if (!dllModuleHandle)
return 0;
apiAddress = (unsigned long) GetProcAddress (dllModuleHandle, apiFunction);
if (!apiAddress)
return 0;
// Step #3.
ReadProcessMemory (thisTargetProcess, (void *) apiAddress, memoryBackup, 6, 0);
memoryWritePosition = ((unsigned long) apiFunction - apiAddress - 5);
memcpy (&newOpcodes[1], &apiAddress, 4);
// Step #4.
WriteProcessMemory (thisTargetProcess, (void *) apiAddress, newOpcodes, 6, 0);
return apiAddress;
}
unsigned int unHookFunction (const char * dllModule, const char * apiFunction, unsigned char * memoryBackup)
{
HANDLE thisTargetProcess;
HMODULE dllModuleHandle;
unsigned long apiAddress;
unsigned long memoryWritePosition;
thisTargetProcess = GetCurrentProcess ();
dllModuleHandle = GetModuleHandleA (dllModule);
if (!dllModuleHandle)
return 0;
apiAddress = (unsigned long) GetProcAddress (dllModuleHandle, apiFunction);
if (!apiAddress)
return 0;
if (WriteProcessMemory (thisTargetProcess, (void *) apiAddress, memoryBackup, 6, 0))
return 1;
return 0;
}
/* You may want to use a log file instead of a MessageBox due to time-outs, etc. */
SOCKET WSAAPI hooked_socket (int af, int type, int protocol)
{
targetsSocket = socket (af, type, protocol);
MessageBox (NULL, "(Close this quickly)\r\n\r\nThe target's socket was hooked successfully!", "Hooked SOCKET", MB_OK);
return targetsSocket;
}
int WSAAPI hooked_connect (SOCKET s, const struct sockaddr FAR * name, int namelen)
{
MessageBox (NULL, "(Close this quickly)\r\n\r\nThe target just connected to a remote address.", "Target Connected", MB_OK);
return connect (s, name, namelen);
}
关于windows - 使用现有的TCP连接发送数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23620434/