Как я могу получить Winsock2 WSASend()
Буфер в строку?
Это код, который у меня есть в настоящее время, и он пишет только много I
персонажи.
int WINAPI Hook_WSASend(SOCKET a0, LPWSABUF a1, DWORD a2, LPDWORD a3, DWORD a4, LPWSAOVERLAPPED a5, LPWSAOVERLAPPED_COMPLETION_ROUTINE a6)
{
int rv = 0;
char * buf = "";
WSABUF * wb = a1;
for(int i = 0; i == a2; i++){
strcpy_s(buf, wb[i].len, wb[i].buf);
}
fopen_s(&pWSASendLogFile, "C:\\WSASendLog.txt", "a+");
fprintf(pWSASendLogFile, "%s\n", buf);
fclose(pWSASendLogFile);
rv = Real_WSASend(a0,a1,a2,a3,a4,a5,a6);
return rv;
}
Как спросил Реми Лебо, я добавляю больше информации о том, чего мне нужно достичь.
Мне нужно иметь буфер внутри строки, потому что:
Я должен искать определенную строку в буфере, прежде чем делать что-либо, что строка должна начинаться с <TalkMsg
,
Затем, я должен отправить буфер через NamedPipe, у меня уже есть мои функции, обрабатывающие это.
Просто чтобы лучше объяснить, что я делаю, это код, который у меня есть для Winsock send()
, Я должен сделать то же самое с WSASend()
,
int WINAPI Hook_Send(SOCKET s, const char* buf, int len, int flags)
{
/*
fopen_s(&pSendLogFile, "C:\\SendLog.txt", "a+");
fprintf(pSendLogFile, "%s\n", buf);
fclose(pSendLogFile);
*/
curSocket = s;
if(Filtering){
PipeHeader ph;
string p(buf);
if(p.find("<TalkMsg") == 0){
ph.command = 5;
ph.sockid = s;
ph.datasize = len;
if(SendPipeHeader((char*)&ph, sizeof(ph))){
if(SendPipeData(buf, len)){
return len;
}
}
}
}
return Real_Send(s, buf, len, flags);
}
Как сказал @enhzflep в комментариях, вы не управляете своим buf
переменная правильно. И даже не нужно это вообще. Просто напишите исходные буферы как есть непосредственно в файл:
int WINAPI Hook_WSASend(SOCKET a0, LPWSABUF a1, DWORD a2, LPDWORD a3, DWORD a4, LPWSAOVERLAPPED a5, LPWSAOVERLAPPED_COMPLETION_ROUTINE a6)
{
fopen_s(&pWSASendLogFile, "C:\\WSASendLog.txt", "a+");
for(DWORD i = 0; i < a2; i++)
fwrite(a1[i].buf, 1, a1[i].len, pWSASendLogFile);
fprintf(pWSASendLogFile, "\n");
fclose(pWSASendLogFile);
int rv = Real_WSASend(a0,a1,a2,a3,a4,a5,a6);
return rv;
}
Обновить: ваш send()
крюк предполагает, что buf
всегда заканчивается нулем, но это не так. Вы должны использовать предоставленный len
при копировании buf
данные в строку:
int WINAPI Hook_Send(SOCKET s, const char* buf, int len, int flags)
{
/*
fopen_s(&pSendLogFile, "C:\\SendLog.txt", "a+");
fwrite(buf, 1, len, pSendLogFile);
fprintf(pSendLogFile, "\n");
fclose(pSendLogFile);
*/
curSocket = s;
if(Filtering){
PipeHeader ph;
string p(buf, len); // <-- here
if(p.find("<TalkMsg") == 0){
ph.command = 5;
ph.sockid = s;
ph.datasize = len;
if(SendPipeHeader((char*)&ph, sizeof(ph))){
if(SendPipeData(buf, len)){
return len;
}
}
}
}
return Real_Send(s, buf, len, flags);
}
Вы должны сделать что-то подобное в вашем WSASend()
крюк, принимая общую длину всех WSABUF
буферы во внимание:
int WINAPI Hook_WSASend(SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount, LPDWORD lpNumberOfBytesSent, DWORD dwFlags, LPWSAOVERLAPPED lpOverlapped, LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
{
/*
fopen_s(&pWSASendLogFile, "C:\\WSASendLog.txt", "a+");
for(DWORD i = 0; i < dwBufferCount; i++)
fwrite(lpBuffers[i].buf, 1, lpBuffers[i].len, pWSASendLogFile);
fprintf(pWSASendLogFile, "\n");
fclose(pWSASendLogFile);
*/
curSocket = s;
if(Filtering){
PipeHeader ph;
string p;
size_t len = 0;
for(DWORD i = 0; i < dwBufferCount; i++) {
len += lpBuffers[i].len;
}
p.reserve(len);
for(DWORD i = 0; i < dwBufferCount; i++) {
p.append(lpBuffers[i].buf, lpBuffers[i].len);
}
if(p.find("<TalkMsg") == 0){
ph.command = 5;
ph.sockid = s;
ph.datasize = len;
if(SendPipeHeader((char*)&ph, sizeof(ph))){
if(SendPipeData(p.c_str(), len)){
if (lpNumberOfBytesSent){
*lpNumberOfBytesSent = len;
}
if (lpCompletionRoutine) {
lpCompletionRoutine(0, len, lpOverlapped, 0);
}
return 0;
}
}
}
}
return Real_WSASend(s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine);
}
Тем не менее, этот вид кода фильтрации не очень надежен из-за потоковой природы TCP. Нет гарантии, что входные данные будут представлять полное сообщение за один раз, когда "<TalkMsg"
присутствует или даже что "<TalkMsg"
само будет завершено за один раз. Вместо этого вам действительно нужно сохранить исходящие данные «как есть» в буфере для каждого сокета, а затем проанализировать буфер для поиска полных сообщений, передавая только полные сообщения в ваш канал и удаляя их из буфера, оставляя частичные данные в буфер должен быть завершен последующими посылками.