仲介DLLによるlisten関数の書き換え
Posted: 2010年5月24日(月) 23:27
仲介DLLを作って、wsock32.dllのlistenが呼ばれたら、
特定のサーバーに接続するようにしたいです。
listexp2.exeにより、仲介DLLを作って、VC++2008で
listenを書き換えようとしましたが、
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _WSAGetLastError@0 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _connect@12 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _closesocket@4 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _WSAAsyncSelect@16 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _gethostbyname@4 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _htons@4 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _socket@12 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
とのエラーがでました、
以下がVC++2008のプロジェクトのうち改変した部分ですです。
==========_dwsock32_dummy.cpp==============================================
// _dwsock32.dll_dummy.cpp : デフォルトの処理を行うエクスポート関数
//
#include <windows.h>
#include "_dwsock32.dll.h"
__declspec( naked ) void WINAPI d_accept() { _asm{ jmp p_accept } }
__declspec( naked ) void WINAPI d_bind() { _asm{ jmp p_bind } }
__declspec( naked ) void WINAPI d_closesocket() { _asm{ jmp p_closesocket } }
__declspec( naked ) void WINAPI d_connect() { _asm{ jmp p_connect } }
__declspec( naked ) void WINAPI d_getpeername() { _asm{ jmp p_getpeername } }
__declspec( naked ) void WINAPI d_getsockname() { _asm{ jmp p_getsockname } }
__declspec( naked ) void WINAPI d_getsockopt() { _asm{ jmp p_getsockopt } }
__declspec( naked ) void WINAPI d_htonl() { _asm{ jmp p_htonl } }
__declspec( naked ) void WINAPI d_htons() { _asm{ jmp p_htons } }
__declspec( naked ) void WINAPI d_inet_addr() { _asm{ jmp p_inet_addr } }
__declspec( naked ) void WINAPI d_inet_ntoa() { _asm{ jmp p_inet_ntoa } }
__declspec( naked ) void WINAPI d_ioctlsocket() { _asm{ jmp p_ioctlsocket } }
__declspec( dllexport ) void WINAPI d_listen(int sockfd, int backlog);
//↑ここを書き換えた
__declspec( naked ) void WINAPI d_listen() { _asm{ jmp p_listen } }
__declspec( naked ) void WINAPI d_ntohl() { _asm{ jmp p_ntohl } }
__declspec( naked ) void WINAPI d_ntohs() { _asm{ jmp p_ntohs } }
~~~中略~~~~~
__declspec( naked ) void WINAPI d_NONAME1138() { _asm{ jmp p_NONAME1138 } }
__declspec( naked ) void WINAPI d_TransmitFile() { _asm{ jmp p_TransmitFile } }
__declspec( naked ) void WINAPI d_AcceptEx() { _asm{ jmp p_AcceptEx } }
__declspec( naked ) void WINAPI d_GetAcceptExSockaddrs() { _asm{ jmp p_GetAcceptExSockaddrs } }
__declspec( dllexport ) void WINAPI d_listen(int sockfd, int backlog){
// SendMessage(hWnd,IDB_CONNECT,0,0);
#define WM_SOCKET (WM_USER+1) //ソケット用メッセージ
unsigned short PORT=12345;
HWND hWnd;
HOSTENT *phe; //HOSTENT構造体
SOCKET sock = INVALID_SOCKET; //ソケット
SOCKET sv_sock = INVALID_SOCKET; //サーバ用ソケット
SOCKADDR_IN sv_sin; //SOCKADDR_IN構造体
SOCKADDR_IN cl_sin; //SOCKADDR_IN構造体
//ソケットを開く
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //ソケット作成失敗
memset(&cl_sin, 0x00, sizeof(cl_sin)); //構造体初期化
cl_sin.sin_family = AF_INET; //インターネット
cl_sin.sin_port = htons(PORT); //ポート番号指定
phe=gethostbyname("localhost");
memcpy(&cl_sin.sin_addr, phe->h_addr, phe->h_length); //アドレス値格納
//非同期モード (接続)
if(WSAAsyncSelect(sock, hWnd, WM_SOCKET, FD_CONNECT)==SOCKET_ERROR){
closesocket(sock);
sock=INVALID_SOCKET;
MessageBox(hWnd, "WSAAsyncSelect() failed", "Error",
MB_OK|MB_ICONEXCLAMATION);
}
//接続処理
if(connect(sock, (LPSOCKADDR)&cl_sin, sizeof(cl_sin))==SOCKET_ERROR){
if(WSAGetLastError()!=WSAEWOULDBLOCK){
closesocket(sock);
sock=INVALID_SOCKET;
MessageBox(hWnd, "connect() failed", "Error",
MB_OK|MB_ICONEXCLAMATION);
}
}
}
==========ここまで==============================================================
コレで大丈夫だと思ったのですが・・・・
どこがまずいのでしょう。
特定のサーバーに接続するようにしたいです。
listexp2.exeにより、仲介DLLを作って、VC++2008で
listenを書き換えようとしましたが、
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _WSAGetLastError@0 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _connect@12 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _closesocket@4 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _WSAAsyncSelect@16 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _gethostbyname@4 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _htons@4 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
1>_dwsock32.dll_dummy.obj : error LNK2019: 未解決の外部シンボル _socket@12 が関数 "void __stdcall d_listen(int,int)" (?d_listen@@YGXHH@Z) で参照されました。
とのエラーがでました、
以下がVC++2008のプロジェクトのうち改変した部分ですです。
==========_dwsock32_dummy.cpp==============================================
// _dwsock32.dll_dummy.cpp : デフォルトの処理を行うエクスポート関数
//
#include <windows.h>
#include "_dwsock32.dll.h"
__declspec( naked ) void WINAPI d_accept() { _asm{ jmp p_accept } }
__declspec( naked ) void WINAPI d_bind() { _asm{ jmp p_bind } }
__declspec( naked ) void WINAPI d_closesocket() { _asm{ jmp p_closesocket } }
__declspec( naked ) void WINAPI d_connect() { _asm{ jmp p_connect } }
__declspec( naked ) void WINAPI d_getpeername() { _asm{ jmp p_getpeername } }
__declspec( naked ) void WINAPI d_getsockname() { _asm{ jmp p_getsockname } }
__declspec( naked ) void WINAPI d_getsockopt() { _asm{ jmp p_getsockopt } }
__declspec( naked ) void WINAPI d_htonl() { _asm{ jmp p_htonl } }
__declspec( naked ) void WINAPI d_htons() { _asm{ jmp p_htons } }
__declspec( naked ) void WINAPI d_inet_addr() { _asm{ jmp p_inet_addr } }
__declspec( naked ) void WINAPI d_inet_ntoa() { _asm{ jmp p_inet_ntoa } }
__declspec( naked ) void WINAPI d_ioctlsocket() { _asm{ jmp p_ioctlsocket } }
__declspec( dllexport ) void WINAPI d_listen(int sockfd, int backlog);
//↑ここを書き換えた
__declspec( naked ) void WINAPI d_listen() { _asm{ jmp p_listen } }
__declspec( naked ) void WINAPI d_ntohl() { _asm{ jmp p_ntohl } }
__declspec( naked ) void WINAPI d_ntohs() { _asm{ jmp p_ntohs } }
~~~中略~~~~~
__declspec( naked ) void WINAPI d_NONAME1138() { _asm{ jmp p_NONAME1138 } }
__declspec( naked ) void WINAPI d_TransmitFile() { _asm{ jmp p_TransmitFile } }
__declspec( naked ) void WINAPI d_AcceptEx() { _asm{ jmp p_AcceptEx } }
__declspec( naked ) void WINAPI d_GetAcceptExSockaddrs() { _asm{ jmp p_GetAcceptExSockaddrs } }
__declspec( dllexport ) void WINAPI d_listen(int sockfd, int backlog){
// SendMessage(hWnd,IDB_CONNECT,0,0);
#define WM_SOCKET (WM_USER+1) //ソケット用メッセージ
unsigned short PORT=12345;
HWND hWnd;
HOSTENT *phe; //HOSTENT構造体
SOCKET sock = INVALID_SOCKET; //ソケット
SOCKET sv_sock = INVALID_SOCKET; //サーバ用ソケット
SOCKADDR_IN sv_sin; //SOCKADDR_IN構造体
SOCKADDR_IN cl_sin; //SOCKADDR_IN構造体
//ソケットを開く
sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //ソケット作成失敗
memset(&cl_sin, 0x00, sizeof(cl_sin)); //構造体初期化
cl_sin.sin_family = AF_INET; //インターネット
cl_sin.sin_port = htons(PORT); //ポート番号指定
phe=gethostbyname("localhost");
memcpy(&cl_sin.sin_addr, phe->h_addr, phe->h_length); //アドレス値格納
//非同期モード (接続)
if(WSAAsyncSelect(sock, hWnd, WM_SOCKET, FD_CONNECT)==SOCKET_ERROR){
closesocket(sock);
sock=INVALID_SOCKET;
MessageBox(hWnd, "WSAAsyncSelect() failed", "Error",
MB_OK|MB_ICONEXCLAMATION);
}
//接続処理
if(connect(sock, (LPSOCKADDR)&cl_sin, sizeof(cl_sin))==SOCKET_ERROR){
if(WSAGetLastError()!=WSAEWOULDBLOCK){
closesocket(sock);
sock=INVALID_SOCKET;
MessageBox(hWnd, "connect() failed", "Error",
MB_OK|MB_ICONEXCLAMATION);
}
}
}
==========ここまで==============================================================
コレで大丈夫だと思ったのですが・・・・
どこがまずいのでしょう。