特定アプリの通信内容を見るためにフックするDLLを作成し、別アプリのリストコントロールに16進表示するのが目的です。
フックまでは出来ていて、これを16進数に変換して別アプリに送信できれば
問題解決なのですが、思った通りの結果が得られません。(正しい出力結果は分かっている)
sendに関しては正しい出力が
サイズ=5 ,内容=01 02 03 04 05 だとすると
サイズ=5 ,内容=01 02 0
になってしまっています。
recvに関しては全く予想していない結果が返ってきて
フック自体が正しいのか疑問になっています。
int WINAPI Hook_send(SOCKET s,const char FAR *buf,int len,int flags)
{
int i,j;
BYTE *pack_org = (BYTE *)buf;
BYTE pack[10000];
j=len;
for(i=0;i<j;i++){
pack[i * 2] = "0123456789ABCDEF"[pack_org[i] / 0x10];
pack[i * 2 + 1] = "0123456789ABCDEF"[pack_org[i] % 0x10];
}
pack[i * 2] = 0;
COPYDATASTRUCT cds;
cds.lpData = pack;
cds.cbData = len;
cds.dwData = 0;
if(PrehWnd)
SendMessage(PrehWnd, WM_COPYDATA, NULL, (LPARAM)&cds);
int nResult = ((PFNSEND)(PROC) g_send)
(s,buf, len, flags);
return nResult;
}
int WINAPI Hook_recv(SOCKET s,char *buf,int len,int flags)
{
int i,j;
BYTE *pack_org = (BYTE *)buf;
BYTE pack[10000];
memset(pack,0,10000);
j=len;
for(i=0;i<j;i++){
pack[i * 2] = "0123456789ABCDEF"[buf[i] / 0x10];
pack[i * 2 + 1] = "0123456789ABCDEF"[buf[i] % 0x10];
}
pack[i * 2] = 0;
COPYDATASTRUCT cds;
cds.lpData = pack;
cds.cbData = lstrlen((LPCSTR)pack);
cds.dwData = 1;
if(PrehWnd)
SendMessage(PrehWnd, WM_COPYDATA, NULL, (LPARAM)&cds);
int nResult = ((PFNRECV)(PROC) g_recv)
(s,buf, len, flags);
return nResult;
}
以下受け取りアプリのリストへ追加
BOOL HookDataAdd(WPARAM wp,PCOPYDATASTRUCT pcds){
LV_ITEM item;
char *time_org ="%02d:%02d:%02d";
char *len_org ="%d";
char *tmp_pack;
char ntime[9];
char nlen[16];
PSTR ptype;
time_t long_time;
struct tm *now_time;
int i,j;
//クリティカルセッション開始
EnterCriticalSection( &Critical_Se );
//HANDLE hMutex = OpenMutex(MUTEX_ALL_ACCESS , FALSE , MUTEX);
WaitForSingleObject(hMutex , INFINITE);
memset(pack,0,10000);
//現在時刻取得
time(&long_time);
now_time = localtime(&long_time);
wsprintf(ntime, time_org,now_time->tm_hour,now_time->tm_min, now_time->tm_sec);
//サイズ変換
wsprintf(nlen, len_org,pcds->cbData);
//種類変換
if(pcds->dwData==1) ptype="recv";
else ptype="send";
item.mask = LVIF_TEXT;
item.pszText = ntime;
item.iItem = ListIdx;
item.iSubItem = 0;
ListView_InsertItem(hListView, &item);
item.pszText = ptype;
item.iItem = ListIdx;
item.iSubItem = 1;
ListView_SetItem(hListView, &item);
item.pszText = nlen;
item.iItem = ListIdx;
item.iSubItem = 2;
ListView_SetItem(hListView, &item);
item.pszText = (LPSTR)pcds->lpData;
item.iItem = ListIdx;
item.iSubItem = 3;
ListView_SetItem(hListView, &item);
ListIdx++;
ReleaseMutex(hMutex);
CloseHandle(hMutex);
//クリティカルセッション終了
LeaveCriticalSection( &Critical_Se );
return TRUE;
}
COPYDATASTRUCT cds;
cds.lpData = pack;
cds.cbData = len; ← len*2じゃねぇの?
cds.dwData = 0;
if(PrehWnd)
SendMessage(PrehWnd, WM_COPYDATA, NULL, (LPARAM)&cds);
> cds.cbData = len; ← len*2じゃねぇの?
len*2+1 ではないでしょうか。
recv側の問題は実際の受信処理(g_recv)を行う前に、
アプリケーションから渡されたバッファの内容を
返してしまっていることが原因ですね。
sendに関してはお二人のご指摘通りcds.cbDataの値を変更して無事解決致しました。ありがとうございます。
>recv側の問題は実際の受信処理(g_recv)を行う前に、
>アプリケーションから渡されたバッファの内容を
>返してしまっていることが原因ですね。
以下の流れでのrecvフックを行っているのですが
g_recvを行う前にバッファを返しているということは
正規のrecvの書き換えに失敗しているということになるのでしょうか
またrecvに関してはこのフックの仕方では不可能なのでしょうか
SetWindowsHookEx
↓
モジュールリストを取得
↓
モジュールのインポートセクションのアドレスを取得
↓
インポートディスクリプタを検索
↓
インポートアドレステーブルを取得
↓
該当関数ならインポートセクションのアドレスを書き換える
いえ、Hook_recv関数内での話です。
実際にデータの受信を行っている部分は
> int nResult = ((PFNRECV)(PROC) g_recv)
> (s,buf, len, flags);
の所ですよね。
ですが、それより前にbufの内容を「別アプリ」へ
渡してしまっているので、受信前のバッファ内容(不定なデータ)が
表示されているのだと思います。
どうやら暑さで頭がトチ狂ってたみたいです。
recvしなきゃデータ受け取っていないのは当然ですね。
ツイート | ![]() |