Hi,
I need to make a serial port sniffer for Windows XP. What do I need to get started? I don't want to use any 3rd party drivers or libraries - I have to start from scratch. Any suggestions appreciated.
I need to make a serial port sniffer for Windows XP. What do I need to get started? I don't want to use any 3rd party drivers or libraries - I have to start from scratch. Any suggestions appreciated.
What exactly are you trying to sniff?
At work, we needed to reverse engineer a protocol that used RS232 as its channel. The idea was to pass the signal through a computer with two serial ports, and bounce the data while recording it. I have tried a few commercial programs and none worked for that purpose. Most of them only monitored serial traffic that originated from software. I have programmed a simple program for that purpose, and here it is:
At work, we needed to reverse engineer a protocol that used RS232 as its channel. The idea was to pass the signal through a computer with two serial ports, and bounce the data while recording it. I have tried a few commercial programs and none worked for that purpose. Most of them only monitored serial traffic that originated from software. I have programmed a simple program for that purpose, and here it is:
//###########################################################################
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
//###########################################################################
//###########################################################################
HANDLE com[2];
//###########################################################################
//###########################################################################
void swap(DWORD* a, DWORD* b) {
*a = *a ^ *b;
*b = *a ^ *b;
*a = *a ^ *b;
}
//###########################################################################
HANDLE openCommPort(const char* szCOMPort) {
HANDLE hComm; COMMTIMEOUTS ctos; DCB dcb;
hComm = CreateFile(szCOMPort, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
GetCommState(hComm, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.StopBits = ONESTOPBIT;
dcb.Parity = NOPARITY;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDsrSensitivity = FALSE;
dcb.fNull = FALSE;
dcb.fDtrControl = DTR_CONTROL_ENABLE;
dcb.fRtsControl = RTS_CONTROL_ENABLE;
dcb.XonChar = 0x02;
dcb.XoffChar = 0x03;
dcb.fOutX = FALSE;
SetCommState(hComm, &dcb);
memset(&ctos, 0, sizeof(ctos));
ctos.ReadIntervalTimeout = 10;
ctos.ReadTotalTimeoutMultiplier = 10;
ctos.ReadTotalTimeoutConstant = 10;
ctos.WriteTotalTimeoutMultiplier = 10;
ctos.WriteTotalTimeoutConstant = 10;
SetCommTimeouts(hComm, &ctos);
SetCommMask(hComm, EV_BREAK | EV_CTS | EV_DSR | EV_ERR | EV_RING | EV_RLSD | EV_RXCHAR | EV_RXFLAG | EV_TXEMPTY);
return hComm;
}
//###########################################################################
DWORD WINAPI CommThread(LPVOID lParam) {
HANDLE* context = (HANDLE*)lParam;
DWORD events, bytesRead, bytesWritten;
char value[0x10]; WORD colour;
HANDLE hEventRead, hEventWrite;
OVERLAPPED ovlp;
HANDLE hFileLog, hFileCombinedLog;
hFileLog = CreateFile((context[0] == com[0] ? "com1recv.raw" : "com2recv.raw"), GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_ALWAYS, 0, 0);
hFileCombinedLog = CreateFile("combined.raw", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_ALWAYS, 0, 0);
SetFilePointer(hFileLog, 0, 0, FILE_END);
hEventRead = CreateEvent(0, 0, 0, 0);
hEventWrite = CreateEvent(0, 0, 0, 0);
colour = FOREGROUND_INTENSITY;
colour |= (context[0] == com[0] ? (FOREGROUND_RED | FOREGROUND_GREEN) : (FOREGROUND_RED | FOREGROUND_BLUE));
while(WaitCommEvent(context[0], &events, 0)) {
memset(&ovlp, 0, sizeof(ovlp));
ovlp.hEvent = hEventRead;
ReadFile(context[0], value, sizeof(value), &bytesRead, &ovlp);
if (WaitForSingleObject(hEventRead, INFINITE) == WAIT_OBJECT_0) {
GetOverlappedResult(context[0], &ovlp, &bytesRead, 0);
if (bytesRead > 0) {
SetFilePointer(hFileCombinedLog, 0, 0, FILE_END);
WriteFile(hFileCombinedLog, value, bytesRead, &bytesWritten, 0);
WriteFile(hFileLog, value, bytesRead, &bytesWritten, 0);
memset(&ovlp, 0, sizeof(ovlp));
ovlp.hEvent = hEventWrite;
WriteFile(context[1], value, bytesRead, &bytesWritten, &ovlp);
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colour);
WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), value, bytesRead, &bytesWritten, 0);
}
}
}
CloseHandle(hEventWrite);
CloseHandle(hEventRead);
return 0;
}
//###########################################################################
int main(int argc, char* argv[]) {
HANDLE thread[2]; DWORD tid;
HANDLE context[2][2] = { { 0, 0 }, { 0, 0 } };
com[0] = openCommPort("COM1");
com[1] = openCommPort("COM2");
context[0][0] = com[0];
context[0][1] = com[1];
context[1][0] = com[1];
context[1][1] = com[0];
thread[0] = CreateThread(0, 0, &CommThread, context[0], 0, &tid);
thread[1] = CreateThread(0, 0, &CommThread, context[1], 0, &tid);
WaitForSingleObject(thread[0], INFINITE);
WaitForSingleObject(thread[1], INFINITE);
CloseHandle(thread[1]);
CloseHandle(thread[0]);
CloseHandle(com[1]);
CloseHandle(com[0]);
return 0;
}
//###########################################################################
//###########################################################################