hook connect异步的问题,写个简单的代理,hook connect,然后修改ip和端口,连接到socks5,但是 connect时候返回-1、
// dllmain.cpp : 定义 DLL 应用程序的入口点。
#include <WinSock2.h>
#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>
#include "targetver.h"
#pragma comment(lib,"ws2_32.lib")
//本dll的handle
HANDLE g_hInstance=NULL;
//修改API入口为 mov eax, 00400000;jmp eax是程序能跳转到自己的函数
BYTE g_btNewBytes[8]={0xB8,0x0,0x0,0x40,0x0,0xFF,0xE0,0};
//保存原 API入口的 8 个字节
DWORD g_dwOldBytes[5][2] = {0x0,0x0,0x0,0x0};
//钩子句柄
HHOOK g_hOldHook=NULL;
//API中 send函数的地址
DWORD g_pSend=0;
DWORD g_pRecv=0;
DWORD g_pConnect=0;
DWORD g_pWSAConnect=0;
DWORD g_pSocket=0;
//事务,解决同步问题
HANDLE g_hSendEvent=NULL;
//自己的函数地址,参数必须与 API 的 send 函数地址相同
int _stdcall hook_connect(SOCKET s, struct sockaddr *name, int namelen);
int _stdcall hook_WSAConnect(SOCKET s,const struct sockaddr FAR * name, int namelen,\
LPWSABUF lpCallerData,LPWSABUF lpCalleeData,LPQOS lpSQOS,LPQOS lpGQOS);
int ConnectTcpToSocks5(char* UserName,char*PassWord,int GameServerPort,char *GameServerIP,SOCKET sClient);
int _stdcall hook_Socket(int af, int type,int p);
//要 Hook 的进程和主线程 ID 号
DWORD g_dwProcessID=0;
DWORD g_dwThreadID=0;
//维护注入进程的socket
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
{
g_hInstance = hModule;
g_hSendEvent = CreateEvent(0,0,1,0);
HMODULE hWsock=LoadLibrary("ws2_32.dll");
g_pConnect = (DWORD)GetProcAddress(hWsock,"connect");
//保存原始字节
ReadProcessMemory(INVALID_HANDLE_VALUE,(void*)g_pConnect,\
(void*)g_dwOldBytes[2],sizeof(DWORD)*2,NULL);
*(DWORD*)(g_btNewBytes+1)=(DWORD)hook_connect;
//写入新地址
WriteProcessMemory(INVALID_HANDLE_VALUE,(void*)g_pConnect,\
(void*)g_btNewBytes,sizeof(DWORD)*2,NULL);
g_pWSAConnect = (DWORD)GetProcAddress(hWsock,"WSAConnect");
//保存原始字节
ReadProcessMemory(INVALID_HANDLE_VALUE,(void*)g_pWSAConnect,\
(void*)g_dwOldBytes[3],sizeof(DWORD)*2,NULL);
*(DWORD*)(g_btNewBytes+1)=(DWORD)hook_WSAConnect;
//写入新地址
WriteProcessMemory(INVALID_HANDLE_VALUE,(void*)g_pWSAConnect,\
(void*)g_btNewBytes,sizeof(DWORD)*2,NULL);
}
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
int _stdcall hook_connect(SOCKET s, struct sockaddr *name, int namelen)
{
//int Ret;
WaitForSingleObject(g_hSendEvent,INFINITE);
//恢复 API 头 8 个字节
WriteProcessMemory(INVALID_HANDLE_VALUE,(void*)g_pConnect,\
(void*)g_dwOldBytes[2],sizeof(DWORD)*2,NULL);
//分析sock数据
SOCKADDR_IN* addr =(SOCKADDR_IN*)name;
DWORD GameServerPort;
char GameServerIP[128];
GameServerPort = ntohs(addr->sin_port);
strcpy(GameServerIP,inet_ntoa(addr->sin_addr));
SOCKADDR_IN AddrSock;
AddrSock.sin_addr.S_un.S_addr=inet_addr("192.168.1.103");
AddrSock.sin_port = htons(1080);
AddrSock.sin_family = AF_INET;
int errorx = GetLastError();
unsigned long ul = 0;
int ret = ioctlsocket (s, FIONBIO, (unsigned long*)&ul);
int i = connect(s,(SOCKADDR*)&AddrSock,namelen);
if(i)
{
errorx = GetLastError();
char yy[25];
sprintf(yy,"%d",errorx);
::MessageBoxA(0,yy,0,0);
}
*(DWORD*)(g_btNewBytes+1)=(DWORD)hook_connect;
//继续hook
WriteProcessMemory(INVALID_HANDLE_VALUE,(void*)g_pConnect,\
(void*)g_btNewBytes,sizeof(DWORD)*2,NULL);
ul = 1;
ret = ioctlsocket (s, FIONBIO, (unsigned long*)&ul);
ConnectTcpToSocks5(0,0,GameServerPort,GameServerIP,s);
SetEvent(g_hSendEvent);
return true;
}
int _stdcall hook_WSAConnect(SOCKET s,const struct sockaddr FAR * name, int namelen,\
LPWSABUF lpCallerData,LPWSABUF lpCalleeData,LPQOS lpSQOS,LPQOS lpGQOS)
{
int Ret;
WaitForSingleObject(g_hSendEvent,INFINITE);
//恢复API入口
//分析sock数据
SOCKADDR_IN* addr =(SOCKADDR_IN*)name;
char text[255]={0};
sprintf(text,"IP:%s\nPort:%d",inet_ntoa(addr->sin_addr),ntohs(addr->sin_port));
//::MessageBox(0,text,"有连接建立,IP和端口如下",0);
WriteProcessMemory(INVALID_HANDLE_VALUE,(void*)g_pWSAConnect,\
(void*)g_dwOldBytes[3],sizeof(DWORD)*2,NULL);
Ret = WSAConnect(s,name,namelen,lpCallerData,lpCalleeData,lpSQOS,lpGQOS);
//继续hook
*(DWORD*)(g_btNewBytes+1)=(DWORD)hook_WSAConnect;
WriteProcessMemory(INVALID_HANDLE_VALUE,(void*)g_pWSAConnect,\
(void*)g_btNewBytes,sizeof(DWORD)*2,NULL);
SetEvent(g_hSendEvent);
return Ret;
}
static LRESULT WINAPI HookProc(int nCode,WPARAM wParam,LPARAM lParam)
{
return CallNextHookEx(g_hOldHook,nCode,wParam,lParam);
}
extern "C"_declspec(dllexport)BOOL StartHook(HWND hWnd)
{
//通过传入的窗口句柄获取线程句柄
g_dwThreadID=GetWindowThreadProcessId(hWnd,&g_dwProcessID);
//WH_CALLWNDPROC类型的 Hook
g_hOldHook=SetWindowsHookEx(WH_CALLWNDPROC,HookProc,(HINSTANCE)g_hInstance,g_dwThreadID);
if(g_hOldHook==NULL)
return FALSE;
return TRUE;
}
extern "C"_declspec(dllexport)void StopHook(void)
{
if(g_hOldHook != NULL)
{
WaitForSingleObject(g_hSendEvent,INFINITE);
HANDLE hProcess = NULL;
hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,g_dwProcessID);
DWORD dwOldProc;
DWORD dwNewProc;
//改变页面属性为读写
VirtualProtectEx(hProcess,(void*)g_pSend,8,PAGE_READWRITE,&dwOldProc);
//回复函数入口地址
WriteProcessMemory(hProcess,(void*)g_pSend,(void*)g_dwOldBytes[0],sizeof(DWORD)*2,NULL);
WriteProcessMemory(hProcess,(void*)g_pRecv,(void*)g_dwOldBytes[1],sizeof(DWORD)*2,NULL);
WriteProcessMemory(hProcess,(void*)g_pConnect,(void*)g_dwOldBytes[2],sizeof(DWORD)*2,NULL);
WriteProcessMemory(hProcess,(void*)g_pWSAConnect,(void*)g_dwOldBytes[3],sizeof(DWORD)*2,NULL);
//恢复页面文件的属性
VirtualProtectEx(hProcess,(void*)g_pSend,8,dwOldProc,&dwNewProc);
CloseHandle(g_hSendEvent);
int i = UnhookWindowsHookEx(g_hOldHook);
if(!i)
::MessageBox(NULL,"卸载模块失败,我感觉你可以重启了","",NULL);
}
}
//使用TCP连接sock5服务器
int ConnectTcpToSocks5(char* UserName,char*PassWord,int GameServerPort,char *GameServerIP,SOCKET sClient)
{
unsigned long ul = 0;
ioctlsocket (sClient, FIONBIO, (unsigned long*)&ul);
//::MessageBoxA(0,"进入链接代理",0,0);
//向服务器发送请求,用于确定连接方式
char buffer[1024];
int bufferlen=1023;
int ret;
sock5req1 *m_proxyreq1;
/*struct sock5req1
{
char Ver; //版本
char nMethods; //方式数目
char Methods[255]; //请求连接方式
};*/
m_proxyreq1=(sock5req1 *)buffer;
m_proxyreq1->Ver=SOCKS_VER;
m_proxyreq1->nMethods=2;
m_proxyreq1->Methods[0]=METHOD_AUTH_NO;
m_proxyreq1->Methods[1]=METHOD_AUTH;
//send请求
ret=send(sClient,buffer,4,0);
if(ret==SOCKET_ERROR)
{
int errorx = GetLastError();
char yy[25];
sprintf(yy,"%d",errorx);
::MessageBoxA(0,yy,0,0);
closesocket(sClient);
return 0;
}
//send后接收服务器返回
ret=recv(sClient,buffer,bufferlen,0);
if(ret==SOCKET_ERROR)
{
int errorx = GetLastError();
char yy[25];
sprintf(yy,"%d",errorx);
::MessageBoxA(0,yy,0,0);
closesocket(sClient);
return 0;
}
sock5ans1 *m_proxyans1;
m_proxyans1=(sock5ans1 *)buffer;
/*struct sock5ans1
{
char Ver; //版本
char Method; //允许的连接方式
};
*/
if(m_proxyans1->Ver==SOCKS_VER && m_proxyans1->Method==METHOD_AUTH_NO && m_proxyans1->Method==METHOD_AUTH)
{
//closesocket(sClient);
}
//返回0x02请求,需要进行密码账户验证
if(m_proxyans1->Method==METHOD_AUTH)
{
char AuthName[255] = "jiahui";
char AuthPasswd[255]= "123123";
socks5authreq *m_authreq;
int iNameLen=strlen(AuthName);
int iPasswd=strlen(AuthPasswd);
m_authreq=(socks5authreq *)buffer;
m_authreq->Ver=SOCKS_AUTH_VER;
m_authreq->other[0]=iNameLen;
strcpy(m_authreq->other+1,AuthName);
m_authreq->other[iNameLen+1]=iPasswd;
strcpy(m_authreq->other+iNameLen+2,AuthPasswd);
//把账户密码发送到服务器进行验证
ret=send(sClient,buffer,3+iNameLen+iPasswd,0);
if(ret==SOCKET_ERROR)
{
int errorx = GetLastError();
char yy[25];
sprintf(yy,"%d",errorx);
::MessageBoxA(0,yy,0,0);
closesocket(sClient);
return 0;
}
//接收申请的返回
ret=recv(sClient,buffer,bufferlen,0);
if(ret==SOCKET_ERROR)
{
int errorx = GetLastError();
char yy[25];
sprintf(yy,"%d",errorx);
::MessageBoxA(0,yy,0,0);
closesocket(sClient);
return 0;
}
socks5authans *m_authans;
m_authans=(socks5authans *)buffer;
if(m_authans->Ver!=SOCKS_AUTH_VER && m_authans->Status!=SOCKS_AUTH_OK)
{
int errorx = GetLastError();
char yy[25];
sprintf(yy,"%d",errorx);
::MessageBoxA(0,yy,0,0);
closesocket(sClient);
return 0;
}
}
//char *DestAddr=m_DestAddr.GetBuffer(0);
//将目的IP和端口发给服务器
sock5req2 *m_proxyreq2;
unsigned short pt = htons(GameServerPort);
//in_addr goal=GetIpByHost(DestAddr);
in_addr goal;
goal.S_un.S_addr = inet_addr(GameServerIP);
int len;
m_proxyreq2 = (sock5req2 *)buffer;
m_proxyreq2->Ver=SOCKS_VER;
m_proxyreq2->Cmd=CMD_CONNECT;
m_proxyreq2->Rsv=FIELD_RSV;
if(goal.s_addr!=INADDR_NONE)
{
m_proxyreq2->Atyp=ATYP_IPV4;
CopyMemory(&m_proxyreq2->other[0],&goal,4);
CopyMemory(&m_proxyreq2->other[4],&pt,2);
len=10;
}
/*else
{
m_proxyreq2->Atyp=ATYP_DOMAINNAME;
len=m_DestAddr.GetLength();
m_proxyreq2->other[0]=len;
CopyMemory(&m_proxyreq2->other[1],DestAddr,len);
CopyMemory(&m_proxyreq2->other[1]+len,&pt,2);
len+=7;
}*/
//发送目标IP和端口
ret=send(sClient,buffer,len,0);
if(ret==SOCKET_ERROR)
{
int errorx = GetLastError();
char yy[25];
sprintf(yy,"%d",errorx);
::MessageBoxA(0,yy,0,0);
closesocket(sClient);
return 0;
}
//接收申请后的返回
ret=recv(sClient,buffer,bufferlen,0);
if(ret==SOCKET_ERROR)
{
int errorx = GetLastError();
char yy[25];
sprintf(yy,"%d",errorx);
::MessageBoxA(0,yy,0,0);
closesocket(sClient);
return 0;
}
sock5ans2 *m_proxyans2;
m_proxyans2 = (sock5ans2 *)buffer;
if(m_proxyans2->Rep!=REP_SUCCESS)
{
int errorx = GetLastError();
char yy[25];
sprintf(yy,"%d",errorx);
::MessageBoxA(0,yy,0,0);
closesocket(sClient);
return 0;
}
ul = 1;
ioctlsocket (sClient, FIONBIO, (unsigned long*)&ul);
//::MessageBoxA(0,"到此代理已经建立",0,0);
return true;
}