Question

I have a dll which hooks recv function of a network application. The code works just fine (it makes everything its suppossed to do), but if i add output logs to a file, the connection closes after some time working (the server side application throws the error "An existing connection was forcibly closed by the remote host").

That time isnt even always the same, sometimes it closes almost when initializing connection, other times i can use the connection for few secs before it gets closed. It does not give any error or warning message. If i remove the log code, the application runs fine. Any idea why is that happening? I run it in windows 8 x64

Also, even erasing the log code, the connection keeps being closed in windows xp x32.

Here is the recv hook code:

int __stdcall NewRecv(SOCKET socket, char *data, int datalen, int flags) {
    int result = 0;
    if(!IsLoginServerPacket(&socket)) {

        INT size = 0,opcode = 0,temp = 0,writer = 0,second_op = 0;
        do {
            size = 0;
            second_op = 0;
            temp = 0;
            writer = 0;

            while(temp < 2) {
                temp += recvPacket(socket,recv_gs_buffer+writer,2 - temp,flags);
                writer += temp;
            }

            size = (*(SHORT*)recv_gs_buffer) & 0xffff;

            // THIS IS THE LOG CODE
            FILE *f = fopen("debug.txt", "a");
            fprintf(f, "datalen=%d, size=%d\n", datalen, size);
            fclose(f);

            while(temp < size) {
                temp += recvPacket(socket,recv_gs_buffer+writer,size - temp,flags);
                writer += temp;
            }

            Decrypt(&gs_crypt,recv_gs_buffer+2,size-2);
            opcode = (*(recv_gs_buffer+2) & 0xff);

            if(opcode == EXTENDED_PROTOCOL) {
                second_op = *(SHORT*)(recv_gs_buffer + 3);
                second_op &= 0xffff;
                HandleGameServerPacket(second_op,recv_gs_buffer+2,size-2);
            }
        } while(second_op == 0x8a || second_op == 0x8b);

        if(opcode == 0x00) {
            SetKey(recv_gs_buffer+4,&gs_crypt);
            SetKey(recv_gs_buffer+4,&client_crypt);
        } else
            Crypt(&client_crypt,recv_gs_buffer+2,size-2);

        int i = 0;
        while(i < size) {
            data[i] = recv_gs_buffer[i];
            i++;
        }
        //memcpy(data,recv_gs_buffer,size);
        result = size;
    } else
        result = recvPacket(socket,data,datalen,flags);

    return result;
}
Was it helpful?

Solution

I just found the problem and its solution.

The injected app was configuring sockets on non blocking mode. Any little delay was making it throwing WSAEWOULDBLOCK (10035 error code). All i had to do to fix it was to retry the recv request if i get any error

INT val = 0;
while(temp < 2) {
    val = recvPacket(socket,recv_gs_buffer+writer,2 - temp,flags);
    if(val > 0) {
        temp += val;
                writer += temp;
    }
}

And

val = 0;
while(temp < size) {
    val = recvPacket(socket,recv_gs_buffer+writer,size - temp,flags);
    if(val > 0) {
        temp += val;
                writer += temp;
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top