tdifw是windows防火墙软件(TDI层驱动过滤),负责监控网络监听与连接、以及过滤信息。

源码在src目录, 程序在Bin目录,执行根目录下的批处理文件也可以,
具体步骤如下: 
1. 运行install.bat 
2. 根据你机器的配置情况,编辑%SystemRoot%\system32\drivers\etc\tdifw.conf配置文件 
3. 重新启动计算机

主程序源码是win32的,就9个目标文件,不包含驱动部分,项目如图:

程序主要源码分析:

  1. int main(int argc, char **argv)
  2. {
  3. static SERVICE_TABLE_ENTRY dispatch_table[] = {
  4. {"tdifw", service_main},
  5. {NULL, NULL}
  6. };
  7. _LEAK_CHECK;
  8. //模拟参数
  9. argc = 3;
  10. argv[0]="tdifw";
  11. argv[1]="install";
  12. argv[2]="tdifw_drv.sys";
  13. if (argc >= 2)
  14. {
  15. const char *param = argv[1];
  16. if (strcmp(param, "install") == 0)
  17. {
  18. if (argc < 3)
  19. {
  20. fprintf(stderr, "Use: tdifw install <config>\n");
  21. return -1;
  22. }
  23. //加载驱动服务
  24. install_service(argv[2]);
  25. }
  26. else if (strcmp(param, "remove") == 0)
  27. {
  28. //移除驱动服务
  29. remove_service();
  30. } else if (strcmp(param, "debug") == 0)
  31. {
  32. if (argc < 3)
  33. {
  34. fprintf(stderr, "Use: tdifw debug <config>\n");
  35. return -1;
  36. }
  37. if (start(argv[2]))
  38. {
  39. printf("press enter to exit...\n");
  40. getchar();
  41. printf("exiting...\n");
  42. //停止 释放资源
  43. stop();
  44. }
  45. } else if (strcmp(param, "listen") == 0)
  46. {       // tdifw specific
  47. //枚举监听
  48. enum_listen();
  49. } else if (strcmp(param, "conn") == 0)
  50. {       // tdifw specific
  51. //枚举连接
  52. enum_connect();
  53. } else
  54. {
  55. fprintf(stderr, "Use: tdifw install|remove|debug|listen|conn\n");
  56. }
  57. }
  58. else
  59. {
  60. g_console = FALSE;
  61. // 连接程序主线程到服务控制管理程序
  62. if (!StartServiceCtrlDispatcher(dispatch_table))
  63. winerr("main: StartServiceCtrlDispatcher");
  64. }
  65. return 0;
  66. }
int main(int argc, char **argv)
{
static SERVICE_TABLE_ENTRY dispatch_table[] = {
{"tdifw", service_main},
{NULL, NULL}
}; _LEAK_CHECK; //模拟参数
argc = 3;
argv[0]="tdifw";
argv[1]="install";
argv[2]="tdifw_drv.sys"; if (argc >= 2)
{
const char *param = argv[1]; if (strcmp(param, "install") == 0)
{
if (argc < 3)
{
fprintf(stderr, "Use: tdifw install <config>\n");
return -1;
} //加载驱动服务
install_service(argv[2]); }
else if (strcmp(param, "remove") == 0)
{
//移除驱动服务
remove_service();
} else if (strcmp(param, "debug") == 0)
{ if (argc < 3)
{
fprintf(stderr, "Use: tdifw debug <config>\n");
return -1;
} if (start(argv[2]))
{
printf("press enter to exit...\n");
getchar();
printf("exiting...\n");
//停止 释放资源
stop();
} } else if (strcmp(param, "listen") == 0)
{ // tdifw specific
//枚举监听
enum_listen();
} else if (strcmp(param, "conn") == 0)
{ // tdifw specific
//枚举连接
enum_connect();
} else
{
fprintf(stderr, "Use: tdifw install|remove|debug|listen|conn\n");
}
}
else
{
g_console = FALSE; // 连接程序主线程到服务控制管理程序
if (!StartServiceCtrlDispatcher(dispatch_table))
winerr("main: StartServiceCtrlDispatcher"); } return 0;
}
  1. //获得驱动文件所在路径 则开启 否则退出
  2. void install_service(const char *config)
  3. {
  4. SC_HANDLE   schService;
  5. SC_HANDLE   schSCManager;
  6. CHAR szPath[MAX_PATH];
  7. //从注册表中获得信息
  8. AddEventSource("tdifw");
  9. if (GetModuleFileName(NULL, szPath, sizeof(szPath)) == 0) {
  10. winerr("install_service: GetModuleFileName");
  11. return;
  12. }
  13. //建立了一个连接到服务控制管理器,并打开指定的数据库。
  14. schSCManager = OpenSCManager(
  15. NULL,                   // machine (NULL == local)
  16. NULL,                   // database (NULL == default)
  17. SC_MANAGER_ALL_ACCESS); // access required
  18. if (schSCManager != NULL) {
  19. //创建一个服务对象并且把它加入到服务管理数据库中
  20. schService = CreateService(
  21. schSCManager,               // SCManager database
  22. "tdifw",                    // name of service
  23. "TDI-based open source personal firewall",  // name to display
  24. SERVICE_ALL_ACCESS,         // desired access
  25. SERVICE_WIN32_OWN_PROCESS,  // service type
  26. SERVICE_AUTO_START,         // start type
  27. SERVICE_ERROR_NORMAL,       // error control type
  28. szPath,                     // service's binary
  29. NULL,                       // no load ordering group
  30. NULL,                       // no tag identifier
  31. NULL,                       // dependencies
  32. NULL,                       // LocalSystem account
  33. NULL);                      // no password
  34. if (schService != NULL) {
  35. printf("tdifw service has been installed\n");
  36. if (!add_config_info(schService, config))
  37. fprintf(stderr, "Can't store config info! Service will use defaults.\n");
  38. CloseServiceHandle(schService);
  39. } else
  40. winerr("install_service: CreateService");
  41. CloseServiceHandle(schSCManager);
  42. }
  43. else
  44. winerr("install_service: OpenSCManager");
  45. }
//获得驱动文件所在路径 则开启 否则退出
void install_service(const char *config)
{
SC_HANDLE schService;
SC_HANDLE schSCManager; CHAR szPath[MAX_PATH]; //从注册表中获得信息
AddEventSource("tdifw"); if (GetModuleFileName(NULL, szPath, sizeof(szPath)) == 0) {
winerr("install_service: GetModuleFileName");
return;
} //建立了一个连接到服务控制管理器,并打开指定的数据库。
schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS); // access required if (schSCManager != NULL) { //创建一个服务对象并且把它加入到服务管理数据库中
schService = CreateService(
schSCManager, // SCManager database
"tdifw", // name of service
"TDI-based open source personal firewall", // name to display
SERVICE_ALL_ACCESS, // desired access
SERVICE_WIN32_OWN_PROCESS, // service type
SERVICE_AUTO_START, // start type
SERVICE_ERROR_NORMAL, // error control type
szPath, // service's binary
NULL, // no load ordering group
NULL, // no tag identifier
NULL, // dependencies
NULL, // LocalSystem account
NULL); // no password if (schService != NULL) {
printf("tdifw service has been installed\n"); if (!add_config_info(schService, config))
fprintf(stderr, "Can't store config info! Service will use defaults.\n"); CloseServiceHandle(schService);
} else
winerr("install_service: CreateService"); CloseServiceHandle(schSCManager);
}
else
winerr("install_service: OpenSCManager");
}
  1. //移除服务 关闭驱动
  2. void remove_service(void)
  3. {
  4. SC_HANDLE   schService;
  5. SC_HANDLE   schSCManager;
  6. schSCManager = OpenSCManager(
  7. NULL,                   // machine (NULL == local)
  8. NULL,                   // database (NULL == default)
  9. SC_MANAGER_ALL_ACCESS); // access required
  10. if (schSCManager != NULL) {
  11. schService = OpenService(schSCManager, "tdifw", SERVICE_ALL_ACCESS);
  12. if (schService != NULL) {
  13. // try to stop the service
  14. if (ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus)) {
  15. printf("stopping...");
  16. Sleep(1000);
  17. while(QueryServiceStatus( schService, &ssStatus)) {
  18. if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) {
  19. printf(".");
  20. Sleep( 1000 );
  21. }
  22. else
  23. break;
  24. }
  25. printf("\n");
  26. if (ssStatus.dwCurrentState == SERVICE_STOPPED)
  27. printf("stopped\n");
  28. else
  29. printf("failed to stop\n");
  30. }
  31. // now remove the service
  32. if (DeleteService(schService))
  33. printf("service has been removed\n");
  34. else
  35. winerr("install_service: DeleteService");
  36. CloseServiceHandle(schService);
  37. }
  38. else
  39. winerr("install_service: OpenService");
  40. CloseServiceHandle(schSCManager);
  41. }
  42. else
  43. winerr("install_service: OpenSCManager");
  44. }
//移除服务 关闭驱动
void remove_service(void)
{
SC_HANDLE schService;
SC_HANDLE schSCManager; schSCManager = OpenSCManager(
NULL, // machine (NULL == local)
NULL, // database (NULL == default)
SC_MANAGER_ALL_ACCESS); // access required if (schSCManager != NULL) {
schService = OpenService(schSCManager, "tdifw", SERVICE_ALL_ACCESS); if (schService != NULL) { // try to stop the service
if (ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus)) {
printf("stopping...");
Sleep(1000); while(QueryServiceStatus( schService, &ssStatus)) {
if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) {
printf(".");
Sleep( 1000 );
}
else
break;
} printf("\n"); if (ssStatus.dwCurrentState == SERVICE_STOPPED)
printf("stopped\n");
else
printf("failed to stop\n");
} // now remove the service
if (DeleteService(schService))
printf("service has been removed\n");
else
winerr("install_service: DeleteService"); CloseServiceHandle(schService);
}
else
winerr("install_service: OpenService"); CloseServiceHandle(schSCManager);
}
else
winerr("install_service: OpenSCManager");
}
  1. // 从驱动程序中获得网络监听对象
  2. void enum_listen(void)
  3. {
  4. ULONG size;
  5. struct listen_nfo *ln = NULL;
  6. int i, n;
  7. // 从 psapi.dll 中获得链接EnumProcesses、EnumProcessModules、GetModuleFileNameExW函数地址
  8. link_psapi();
  9. /* connect with driver */
  10. g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,
  11. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
  12. if (g_device == INVALID_HANDLE_VALUE) {
  13. winerr(g_nfo_device_name);
  14. goto done;
  15. }
  16. /* get list of listening objects */
  17. size = sizeof(*ln) * 0x10000 * 3;   // this size is good enough :-)
  18. ln = (struct listen_nfo *)malloc(size);
  19. if (ln == NULL) {
  20. perror("malloc");
  21. goto done;
  22. }
  23. //与驱动交流 枚举监听操作 获取监听信息
  24. if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_LISTEN, NULL, 0,
  25. ln, size, &size, NULL)) {
  26. winerr("DeviceIoControl");
  27. goto done;
  28. }
  29. n = size / sizeof(*ln);
  30. // sort this list!
  31. qsort(ln, n, sizeof(*ln), compare_ln);
  32. printf("IPProto\tAddress:Port\tProcess (pid)\n");
  33. printf("-------\t------------\t---------------------------------------------\n");
  34. //显示
  35. for (i = 0; i < n ; i++) {
  36. char *proto, pname[MAX_PATH];
  37. if (ln[i].ipproto == IPPROTO_TCP)
  38. proto = "TCP";
  39. else if (ln[i].ipproto == IPPROTO_UDP)
  40. proto = "UDP";
  41. else if (ln[i].ipproto == IPPROTO_IP)
  42. proto = "RawIP";
  43. else
  44. proto = "?";
  45. // resolve pid!
  46. if (!get_pname_by_pid(ln[i].pid, pname, sizeof(pname)))
  47. pname[0] = '\0';
  48. printf("%s\t%d.%d.%d.%d:%d\t%s (%d)\n",
  49. proto, PRINT_IP_ADDR(ln[i].addr), ntohs(ln[i].port), pname, ln[i].pid);
  50. }
  51. done:
  52. free(ln);
  53. if (g_device != INVALID_HANDLE_VALUE)
  54. CloseHandle(g_device);
  55. }
// 从驱动程序中获得网络监听对象
void enum_listen(void)
{
ULONG size;
struct listen_nfo *ln = NULL;
int i, n; // 从 psapi.dll 中获得链接EnumProcesses、EnumProcessModules、GetModuleFileNameExW函数地址
link_psapi(); /* connect with driver */ g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (g_device == INVALID_HANDLE_VALUE) {
winerr(g_nfo_device_name);
goto done;
} /* get list of listening objects */ size = sizeof(*ln) * 0x10000 * 3; // this size is good enough :-)
ln = (struct listen_nfo *)malloc(size);
if (ln == NULL) {
perror("malloc");
goto done;
} //与驱动交流 枚举监听操作 获取监听信息
if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_LISTEN, NULL, 0,
ln, size, &size, NULL)) {
winerr("DeviceIoControl");
goto done;
} n = size / sizeof(*ln); // sort this list!
qsort(ln, n, sizeof(*ln), compare_ln); printf("IPProto\tAddress:Port\tProcess (pid)\n");
printf("-------\t------------\t---------------------------------------------\n"); //显示
for (i = 0; i < n ; i++) {
char *proto, pname[MAX_PATH]; if (ln[i].ipproto == IPPROTO_TCP)
proto = "TCP";
else if (ln[i].ipproto == IPPROTO_UDP)
proto = "UDP";
else if (ln[i].ipproto == IPPROTO_IP)
proto = "RawIP";
else
proto = "?"; // resolve pid!
if (!get_pname_by_pid(ln[i].pid, pname, sizeof(pname)))
pname[0] = '\0'; printf("%s\t%d.%d.%d.%d:%d\t%s (%d)\n",
proto, PRINT_IP_ADDR(ln[i].addr), ntohs(ln[i].port), pname, ln[i].pid);
} done:
free(ln);
if (g_device != INVALID_HANDLE_VALUE)
CloseHandle(g_device);
}
  1. // 从驱动程序中获得网络连接信息
  2. void enum_connect(void)
  3. {
  4. ULONG size;
  5. struct tcp_conn_nfo *tn = NULL;
  6. int i, n;
  7. unsigned __int64 traffic[TRAFFIC_MAX];
  8. // 从 psapi.dll 中获得链接EnumProcesses、EnumProcessModules、GetModuleFileNameExW函数地址
  9. link_psapi();
  10. /* connect with driver */
  11. g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,
  12. FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
  13. if (g_device == INVALID_HANDLE_VALUE) {
  14. winerr(g_nfo_device_name);
  15. goto done;
  16. }
  17. /* get list of listening objects */
  18. size = sizeof(*tn) * 0x10000 * 3;   // this size is good enough :-)
  19. tn = (struct tcp_conn_nfo *)malloc(size);
  20. if (tn == NULL) {
  21. perror("malloc");
  22. goto done;
  23. }
  24. //与驱动交流 枚举监听操作 获取连接信息
  25. if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_TCP_CONN, NULL, 0,
  26. tn, size, &size, NULL)) {
  27. winerr("DeviceIoControl");
  28. goto done;
  29. }
  30. n = size / sizeof(*tn);
  31. // sort this list!
  32. qsort(tn, n, sizeof(*tn), compare_tn);
  33. //顺序输出
  34. for (i = 0; i < n ; i++) {
  35. char pname[MAX_PATH];
  36. if (tn[i].state >= TCP_STATE_MAX)
  37. tn[i].state = 0;
  38. // resolve pid!
  39. if (!get_pname_by_pid(tn[i].pid, pname, sizeof(pname)))
  40. pname[0] = '\0';
  41. printf("%s\t%d.%d.%d.%d:%d\t%d.%d.%d.%d:%d\t%s (%d)\t%u/%u\n",
  42. g_tcp_states[tn[i].state],
  43. PRINT_IP_ADDR(tn[i].laddr), ntohs(tn[i].lport),
  44. PRINT_IP_ADDR(tn[i].raddr), ntohs(tn[i].rport),
  45. pname, tn[i].pid,
  46. tn[i].bytes_out, tn[i].bytes_in);
  47. }
  48. // output traffic counters
  49. get_traffic_stats(traffic);
  50. printf(
  51. "\n"
  52. "Traffic counters (out/in):\n"
  53. "    Total:   %I64u/%I64u\n"
  54. "    Counted: %I64u/%I64u\n",
  55. traffic[TRAFFIC_TOTAL_OUT], traffic[TRAFFIC_TOTAL_IN],
  56. traffic[TRAFFIC_COUNTED_OUT], traffic[TRAFFIC_COUNTED_IN]);
  57. done:
  58. free(tn);
  59. if (g_device != INVALID_HANDLE_VALUE)
  60. CloseHandle(g_device);
  61. }
// 从驱动程序中获得网络连接信息
void enum_connect(void)
{
ULONG size;
struct tcp_conn_nfo *tn = NULL;
int i, n;
unsigned __int64 traffic[TRAFFIC_MAX]; // 从 psapi.dll 中获得链接EnumProcesses、EnumProcessModules、GetModuleFileNameExW函数地址
link_psapi(); /* connect with driver */ g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
if (g_device == INVALID_HANDLE_VALUE) {
winerr(g_nfo_device_name);
goto done;
} /* get list of listening objects */ size = sizeof(*tn) * 0x10000 * 3; // this size is good enough :-)
tn = (struct tcp_conn_nfo *)malloc(size);
if (tn == NULL) {
perror("malloc");
goto done;
} //与驱动交流 枚举监听操作 获取连接信息
if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_TCP_CONN, NULL, 0,
tn, size, &size, NULL)) {
winerr("DeviceIoControl");
goto done;
} n = size / sizeof(*tn); // sort this list!
qsort(tn, n, sizeof(*tn), compare_tn); //顺序输出
for (i = 0; i < n ; i++) {
char pname[MAX_PATH]; if (tn[i].state >= TCP_STATE_MAX)
tn[i].state = 0; // resolve pid!
if (!get_pname_by_pid(tn[i].pid, pname, sizeof(pname)))
pname[0] = '\0'; printf("%s\t%d.%d.%d.%d:%d\t%d.%d.%d.%d:%d\t%s (%d)\t%u/%u\n",
g_tcp_states[tn[i].state],
PRINT_IP_ADDR(tn[i].laddr), ntohs(tn[i].lport),
PRINT_IP_ADDR(tn[i].raddr), ntohs(tn[i].rport),
pname, tn[i].pid,
tn[i].bytes_out, tn[i].bytes_in);
} // output traffic counters
get_traffic_stats(traffic); printf(
"\n"
"Traffic counters (out/in):\n"
" Total: %I64u/%I64u\n"
" Counted: %I64u/%I64u\n",
traffic[TRAFFIC_TOTAL_OUT], traffic[TRAFFIC_TOTAL_IN],
traffic[TRAFFIC_COUNTED_OUT], traffic[TRAFFIC_COUNTED_IN]); done:
free(tn);
if (g_device != INVALID_HANDLE_VALUE)
CloseHandle(g_device);
}

以上是主要程序的源码,驱动部分共有32个目标文件,如图:

  1. /* 驱动入口 */
  2. NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
  3. IN PUNICODE_STRING theRegistryPath)
  4. {
  5. NTSTATUS status = STATUS_SUCCESS;
  6. int i;
  7. UNICODE_STRING name, linkname;
  8. //内存跟踪初始化   调用了KeInitializeSpinLock(&guard);
  9. memtrack_init();
  10. //初始化锁
  11. KeInitializeSpinLock(&g_traffic_guard);
  12. #ifdef USE_TDI_HOOKING
  13. KdPrint(("[tdi_fw] WARNING! Using unstable working mode: TDI hooking!\n"));
  14. #endif
  15. status = ot_init();
  16. if (status != STATUS_SUCCESS) {
  17. KdPrint(("[tdi_fw] DriverEntry: ot_init: 0x%x\n", status));
  18. goto done;
  19. }
  20. //过滤器初始化
  21. status = filter_init();
  22. if (status != STATUS_SUCCESS) {
  23. KdPrint(("[tdi_fw] DriverEntry: filter_init: 0x%x\n", status));
  24. goto done;
  25. }
  26. //连接状态初始化
  27. status = conn_state_init();
  28. if (status != STATUS_SUCCESS) {
  29. KdPrint(("[tdi_fw] DriverEntry: conn_state_init: 0x%x\n", status));
  30. goto done;
  31. }
  32. //分发函数
  33. for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
  34. theDriverObject->MajorFunction[i] = DeviceDispatch;
  35. #if DBG
  36. // register UnLoad procedure
  37. theDriverObject->DriverUnload = OnUnload;
  38. #endif
  39. /* create control device and symbolic link */
  40. RtlInitUnicodeString(&name, L"\\Device\\tdifw");
  41. status = IoCreateDevice(theDriverObject,
  42. 0,
  43. &name,
  44. 0,
  45. 0,
  46. TRUE,       // exclusive!
  47. &g_devcontrol);
  48. if (status != STATUS_SUCCESS) {
  49. KdPrint(("[tdi_fw] DriverEntry: IoCreateDevice(control): 0x%x!\n", status));
  50. goto done;
  51. }
  52. RtlInitUnicodeString(&linkname, L"\\??\\tdifw");
  53. //创建了一个符号连接
  54. status = IoCreateSymbolicLink(&linkname, &name);
  55. if (status != STATUS_SUCCESS) {
  56. KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x!\n", status));
  57. goto done;
  58. }
  59. RtlInitUnicodeString(&name, L"\\Device\\tdifw_nfo");
  60. //创建设备对象
  61. status = IoCreateDevice(theDriverObject,
  62. 0,
  63. &name,
  64. 0,
  65. 0,
  66. FALSE,      // not exclusive!
  67. &g_devnfo);
  68. if (status != STATUS_SUCCESS) {
  69. KdPrint(("[tdi_fw] DriverEntry: IoCreateDevice(nfo): 0x%x!\n", status));
  70. goto done;
  71. }
  72. RtlInitUnicodeString(&linkname, L"\\??\\tdifw_nfo");
  73. //创建了一个符号连接
  74. status = IoCreateSymbolicLink(&linkname, &name);
  75. if (status != STATUS_SUCCESS) {
  76. KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x!\n", status));
  77. goto done;
  78. }
  79. #ifndef USE_TDI_HOOKING
  80. //绑定设备
  81. status = c_n_a_device(theDriverObject, &g_tcpfltobj, &g_tcpoldobj, L"\\Device\\Tcp");
  82. if (status != STATUS_SUCCESS) {
  83. KdPrint(("[tdi_fw] DriverEntry: c_n_a_device: 0x%x\n", status));
  84. goto done;
  85. }
  86. //绑定设备
  87. status = c_n_a_device(theDriverObject, &g_udpfltobj, &g_udpoldobj, L"\\Device\\Udp");
  88. if (status != STATUS_SUCCESS) {
  89. KdPrint(("[tdi_fw] DriverEntry: c_n_a_device: 0x%x\n", status));
  90. goto done;
  91. }
  92. //绑定设备
  93. status = c_n_a_device(theDriverObject, &g_ipfltobj, &g_ipoldobj, L"\\Device\\RawIp");
  94. if (status != STATUS_SUCCESS) {
  95. KdPrint(("[tdi_fw] DriverEntry: c_n_a_device: 0x%x\n", status));
  96. goto done;
  97. }
  98. #else   /* USE_TDI_HOOKING */
  99. /* get device objects for tcp/udp/ip */
  100. //获得tcp设备对象
  101. status = get_device_object(L"\\Device\\Tcp", &g_tcpfltobj);
  102. if (status != STATUS_SUCCESS) {
  103. KdPrint(("[tdi_fw] DriverEntry: get_device_object(tcp): 0x%x\n", status));
  104. goto done;
  105. }
  106. //获得Udp设备对象
  107. status = get_device_object(L"\\Device\\Udp", &g_udpfltobj);
  108. if (status != STATUS_SUCCESS) {
  109. KdPrint(("[tdi_fw] DriverEntry: get_device_object(udp): 0x%x\n", status));
  110. goto done;
  111. }
  112. //获得RawIp设备对象
  113. status = get_device_object(L"\\Device\\RawIp", &g_ipfltobj);
  114. if (status != STATUS_SUCCESS) {
  115. KdPrint(("[tdi_fw] DriverEntry: get_device_object(ip): 0x%x\n", status));
  116. goto done;
  117. }
  118. /* hook tcpip */
  119. //针对tcp下钩子
  120. status = hook_tcpip(&g_old_DriverObject, TRUE);
  121. if (status != STATUS_SUCCESS) {
  122. KdPrint(("[tdi_fw] DriverEntry: hook_driver: 0x%x\n", status));
  123. goto done;
  124. }
  125. g_hooked = TRUE;
  126. #endif  /* USE_TDI_HOOKING */
  127. status = STATUS_SUCCESS;
  128. done:
  129. if (status != STATUS_SUCCESS) {
  130. // cleanup
  131. OnUnload(theDriverObject);
  132. }
  133. return status;
  134. }
/* 驱动入口 */
NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
IN PUNICODE_STRING theRegistryPath)
{
NTSTATUS status = STATUS_SUCCESS;
int i;
UNICODE_STRING name, linkname; //内存跟踪初始化 调用了KeInitializeSpinLock(&guard);
memtrack_init(); //初始化锁
KeInitializeSpinLock(&g_traffic_guard); #ifdef USE_TDI_HOOKING
KdPrint(("[tdi_fw] WARNING! Using unstable working mode: TDI hooking!\n"));
#endif status = ot_init();
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: ot_init: 0x%x\n", status));
goto done;
} //过滤器初始化
status = filter_init();
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: filter_init: 0x%x\n", status));
goto done;
} //连接状态初始化
status = conn_state_init();
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: conn_state_init: 0x%x\n", status));
goto done;
} //分发函数
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
theDriverObject->MajorFunction[i] = DeviceDispatch; #if DBG
// register UnLoad procedure
theDriverObject->DriverUnload = OnUnload;
#endif /* create control device and symbolic link */ RtlInitUnicodeString(&name, L"\\Device\\tdifw"); status = IoCreateDevice(theDriverObject,
0,
&name,
0,
0,
TRUE, // exclusive!
&g_devcontrol);
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: IoCreateDevice(control): 0x%x!\n", status));
goto done;
} RtlInitUnicodeString(&linkname, L"\\??\\tdifw"); //创建了一个符号连接
status = IoCreateSymbolicLink(&linkname, &name);
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x!\n", status));
goto done;
} RtlInitUnicodeString(&name, L"\\Device\\tdifw_nfo"); //创建设备对象
status = IoCreateDevice(theDriverObject,
0,
&name,
0,
0,
FALSE, // not exclusive!
&g_devnfo);
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: IoCreateDevice(nfo): 0x%x!\n", status));
goto done;
} RtlInitUnicodeString(&linkname, L"\\??\\tdifw_nfo"); //创建了一个符号连接
status = IoCreateSymbolicLink(&linkname, &name);
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x!\n", status));
goto done;
} #ifndef USE_TDI_HOOKING //绑定设备
status = c_n_a_device(theDriverObject, &g_tcpfltobj, &g_tcpoldobj, L"\\Device\\Tcp");
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: c_n_a_device: 0x%x\n", status));
goto done;
} //绑定设备
status = c_n_a_device(theDriverObject, &g_udpfltobj, &g_udpoldobj, L"\\Device\\Udp");
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: c_n_a_device: 0x%x\n", status));
goto done;
} //绑定设备
status = c_n_a_device(theDriverObject, &g_ipfltobj, &g_ipoldobj, L"\\Device\\RawIp");
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: c_n_a_device: 0x%x\n", status));
goto done;
} #else /* USE_TDI_HOOKING */ /* get device objects for tcp/udp/ip */
//获得tcp设备对象
status = get_device_object(L"\\Device\\Tcp", &g_tcpfltobj);
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: get_device_object(tcp): 0x%x\n", status));
goto done;
}
//获得Udp设备对象
status = get_device_object(L"\\Device\\Udp", &g_udpfltobj);
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: get_device_object(udp): 0x%x\n", status));
goto done;
}
//获得RawIp设备对象
status = get_device_object(L"\\Device\\RawIp", &g_ipfltobj);
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: get_device_object(ip): 0x%x\n", status));
goto done;
} /* hook tcpip */
//针对tcp下钩子
status = hook_tcpip(&g_old_DriverObject, TRUE);
if (status != STATUS_SUCCESS) {
KdPrint(("[tdi_fw] DriverEntry: hook_driver: 0x%x\n", status));
goto done;
}
g_hooked = TRUE; #endif /* USE_TDI_HOOKING */ status = STATUS_SUCCESS; done:
if (status != STATUS_SUCCESS) {
// cleanup
OnUnload(theDriverObject);
} return status;
}

针对tcp或udp、ip等设备对象时的操作,操作分两种:设备过滤模式 和 TDI Hook模式。源码如下:

  1. //TDI Hook过滤模式
  2. case IRP_MJ_CREATE:     /* create fileobject */
  3. result = tdi_create(irp, irps, &completion);
  4. status = tdi_dispatch_complete(DeviceObject, irp, result,
  5. completion.routine, completion.context);
  6. break;
  7. case IRP_MJ_DEVICE_CONTROL:
  8. KdPrint(("[tdi_fw] DeviceDispatch: IRP_MJ_DEVICE_CONTROL, control 0x%x for 0x%08X\n",
  9. irps->Parameters.DeviceIoControl.IoControlCode, irps->FileObject));
  10. if (KeGetCurrentIrql() == PASSIVE_LEVEL) {
  11. /*
  12. * try to convert it to IRP_MJ_INTERNAL_DEVICE_CONTROL
  13. * (works on PASSIVE_LEVEL only!)
  14. */
  15. status = TdiMapUserRequest(DeviceObject, irp, irps);
  16. } else
  17. status = STATUS_NOT_IMPLEMENTED; // set fake status
  18. if (status != STATUS_SUCCESS) {
  19. void *buf = (irps->Parameters.DeviceIoControl.IoControlCode == IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER) ?
  20. irps->Parameters.DeviceIoControl.Type3InputBuffer : NULL;
  21. // send IRP to original driver
  22. status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW, NULL, NULL);
  23. if (buf != NULL && status == STATUS_SUCCESS) {
  24. g_TCPSendData = *(TCPSendData_t **)buf;
  25. KdPrint(("[tdi_fw] DeviceDispatch: IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER: TCPSendData = 0x%x\n",
  26. g_TCPSendData));
  27. *(TCPSendData_t **)buf = new_TCPSendData;
  28. }
  29. break;
  30. }
  31. // don't break! go to internal device control!
  32. case IRP_MJ_INTERNAL_DEVICE_CONTROL: {
  33. /*
  34. * Analyze ioctl for TDI driver
  35. */
  36. int i;
  37. for (i = 0; g_tdi_ioctls[i].MinorFunction != 0; i++)
  38. if (g_tdi_ioctls[i].MinorFunction == irps->MinorFunction) {
  39. #if DBG
  40. // print description
  41. KdPrint(("[tdi_fw] DeviceDispatch: %s (0x%x) for 0x%x\n",
  42. g_tdi_ioctls[i].desc,
  43. irps->MinorFunction,
  44. irps->FileObject));
  45. #endif
  46. if (g_tdi_ioctls[i].fn == NULL) {
  47. // send IRP to original driver
  48. status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW,
  49. NULL, NULL);
  50. break;
  51. }
  52. // call dispatch function
  53. result = g_tdi_ioctls[i].fn(irp, irps, &completion);
  54. // complete request
  55. status = tdi_dispatch_complete(DeviceObject, irp, result,
  56. completion.routine, completion.context);
  57. break;
  58. }
  59. // if dispatch function hasn't been found
  60. if (g_tdi_ioctls[i].MinorFunction == 0) {
  61. // send IRP to original driver
  62. status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW, NULL, NULL);
  63. }
  64. break;
  65. }
  66. case IRP_MJ_CLEANUP:        /* cleanup fileobject */
  67. result = tdi_cleanup(irp, irps, &completion);
  68. status = tdi_dispatch_complete(DeviceObject, irp, result,
  69. completion.routine, completion.context);
  70. break;
  71. case IRP_MJ_CLOSE:
  72. KdPrint(("[tdi_fw] DeviceDispatch: IRP_MJ_CLOSE fileobj 0x%x\n", irps->FileObject));
  73. // passthrough IRP
  74. status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW,
  75. completion.routine, completion.context);
  76. break;
		//TDI Hook过滤模式
case IRP_MJ_CREATE: /* create fileobject */ result = tdi_create(irp, irps, &completion); status = tdi_dispatch_complete(DeviceObject, irp, result,
completion.routine, completion.context); break; case IRP_MJ_DEVICE_CONTROL: KdPrint(("[tdi_fw] DeviceDispatch: IRP_MJ_DEVICE_CONTROL, control 0x%x for 0x%08X\n",
irps->Parameters.DeviceIoControl.IoControlCode, irps->FileObject)); if (KeGetCurrentIrql() == PASSIVE_LEVEL) {
/*
* try to convert it to IRP_MJ_INTERNAL_DEVICE_CONTROL
* (works on PASSIVE_LEVEL only!)
*/
status = TdiMapUserRequest(DeviceObject, irp, irps); } else
status = STATUS_NOT_IMPLEMENTED; // set fake status if (status != STATUS_SUCCESS) {
void *buf = (irps->Parameters.DeviceIoControl.IoControlCode == IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER) ?
irps->Parameters.DeviceIoControl.Type3InputBuffer : NULL; // send IRP to original driver
status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW, NULL, NULL); if (buf != NULL && status == STATUS_SUCCESS) { g_TCPSendData = *(TCPSendData_t **)buf; KdPrint(("[tdi_fw] DeviceDispatch: IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER: TCPSendData = 0x%x\n",
g_TCPSendData)); *(TCPSendData_t **)buf = new_TCPSendData;
} break;
} // don't break! go to internal device control! case IRP_MJ_INTERNAL_DEVICE_CONTROL: {
/*
* Analyze ioctl for TDI driver
*/
int i; for (i = 0; g_tdi_ioctls[i].MinorFunction != 0; i++)
if (g_tdi_ioctls[i].MinorFunction == irps->MinorFunction) { #if DBG
// print description
KdPrint(("[tdi_fw] DeviceDispatch: %s (0x%x) for 0x%x\n",
g_tdi_ioctls[i].desc,
irps->MinorFunction,
irps->FileObject));
#endif if (g_tdi_ioctls[i].fn == NULL) {
// send IRP to original driver
status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW,
NULL, NULL);
break;
} // call dispatch function result = g_tdi_ioctls[i].fn(irp, irps, &completion); // complete request
status = tdi_dispatch_complete(DeviceObject, irp, result,
completion.routine, completion.context); break;
} // if dispatch function hasn't been found
if (g_tdi_ioctls[i].MinorFunction == 0) {
// send IRP to original driver
status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW, NULL, NULL);
} break;
} case IRP_MJ_CLEANUP: /* cleanup fileobject */ result = tdi_cleanup(irp, irps, &completion); status = tdi_dispatch_complete(DeviceObject, irp, result,
completion.routine, completion.context);
break; case IRP_MJ_CLOSE:
KdPrint(("[tdi_fw] DeviceDispatch: IRP_MJ_CLOSE fileobj 0x%x\n", irps->FileObject)); // passthrough IRP
status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW,
completion.routine, completion.context); break;
  1. //设备过滤操作模式
  2. if (irps->MajorFunction == IRP_MJ_CREATE) {
  3. // initialize for user-mode part (exclusive access - 1 user-mode logging part)
  4. filter_init_2();
  5. g_got_log = TRUE;
  6. } else if (irps->MajorFunction == IRP_MJ_CLOSE) {
  7. // cleanup for user-mode logging part
  8. filter_free_2();
  9. g_got_log = FALSE;
  10. } if (irps->MajorFunction == IRP_MJ_DEVICE_CONTROL) {
  11. /*
  12. * control request
  13. */
  14. ULONG ioctl = irps->Parameters.DeviceIoControl.IoControlCode,
  15. len = irps->Parameters.DeviceIoControl.InputBufferLength,
  16. size = irps->Parameters.DeviceIoControl.OutputBufferLength;
  17. char *out_buf;
  18. if (IOCTL_TRANSFER_TYPE(ioctl) == METHOD_NEITHER) {
  19. // this type of transfer unsupported
  20. out_buf = NULL;
  21. } else
  22. out_buf = (char *)irp->AssociatedIrp.SystemBuffer;
  23. // process control request
  24. status = process_request(ioctl, out_buf, &len, size);
  25. irp->IoStatus.Information = len;
  26. }
  27. irp->IoStatus.Status = status;
  28. IoCompleteRequest(irp, IO_NO_INCREMENT);
		//设备过滤操作模式
if (irps->MajorFunction == IRP_MJ_CREATE) { // initialize for user-mode part (exclusive access - 1 user-mode logging part)
filter_init_2(); g_got_log = TRUE; } else if (irps->MajorFunction == IRP_MJ_CLOSE) { // cleanup for user-mode logging part
filter_free_2(); g_got_log = FALSE; } if (irps->MajorFunction == IRP_MJ_DEVICE_CONTROL) { /*
* control request
*/ ULONG ioctl = irps->Parameters.DeviceIoControl.IoControlCode,
len = irps->Parameters.DeviceIoControl.InputBufferLength,
size = irps->Parameters.DeviceIoControl.OutputBufferLength;
char *out_buf; if (IOCTL_TRANSFER_TYPE(ioctl) == METHOD_NEITHER) {
// this type of transfer unsupported
out_buf = NULL;
} else
out_buf = (char *)irp->AssociatedIrp.SystemBuffer; // process control request
status = process_request(ioctl, out_buf, &len, size); irp->IoStatus.Information = len; } irp->IoStatus.Status = status; IoCompleteRequest(irp, IO_NO_INCREMENT);

学习的目的是成熟!~

源码包下载

开源项目之防火墙 tdifw的更多相关文章

  1. 开源项目大全 >> ...

    http://www.isenhao.com/xueke/jisuanji/kaiyuan.php   监控系统-Nagios 网络流量监测图形分析工具-Cacti 分布式系统监视-zabbix 系统 ...

  2. JAVA上百实例源码以及开源项目

    简介 笔者当初为了学习JAVA,收集了很多经典源码,源码难易程度分为初级.中级.高级等,详情看源码列表,需要的可以直接下载! 这些源码反映了那时那景笔者对未来的盲目,对代码的热情.执着,对IT的憧憬. ...

  3. 一个P2P点播直播开源项目:P2PCenter

    最近跟着公司的项目走,我也研究了不少东西,尤其是在P2P方面,广泛涉猎各种开源项目,尤其是国外的开源项目,意外的发现了一个国内的项目,做的还不错,推荐一下.---------------------使 ...

  4. 开源项目live555学习心得

      推荐:伊朗美女找丈夫比找工作难女人婚前一定要看清三件事 × 登录注册   疯狂少男-IT技术的博客 http://blog.sina.com.cn/crazyboyzhaolei [订阅][手机订 ...

  5. 【转】10款GitHub上最火爆的国产开源项目

    将开源做到极致,提高效率方便更多用户 接触开源时间虽然比较短但是后续会努力为开源社区贡献自己微薄的力量 衡量一个开源产品好不好,看看产品在 GitHub 的 Star 数量就知道了.由此可见,GitH ...

  6. 点评10款Github上最火爆的国产开源项目

    衡量一个开源产品好不好,看看产品在Github的Star数量就知道了.由此可见,Github已经沦落为开源产品的“大众点评”了. 一个开源产品希望快速的被开发者知道.快速的获取反馈,放到Github上 ...

  7. 6个P2P流媒体开源项目介绍

    P2P流媒体开源项目介绍  1. PeerCast 2002年成立,最早的开源P2P流媒体项目.PeerCast把节点按树结构组织起来, 每个频道都是一个树, 直播源是根节点,父节点只给子节点提供数据 ...

  8. android 开源项目列表【持续整理中。。。】

    Android完整的开源项目,不包括各种组件的项目 社区客户端 oschina客户端:oschina网站的客户端,wp版,iOS版都有开源,一个社区型客户端,包括登录刷新各类视线 四次元新浪微博客户端 ...

  9. P2P流媒体开源项目介绍

    P2P流媒体开源项目介绍1. PeerCast 2002年成立,最早的开源P2P流媒体项目.PeerCast把节点按树结构组织起来, 每个频道都是一个树, 直播源是根节点,父节点只给子节点提供数据.节 ...

随机推荐

  1. jquery 使用整理

    1. 如何创建嵌套的过滤器 //允许你减少集合中的匹配元素的过滤器, //只剩下那些与给定的选择器匹配的部分.在这种情况下, //查询删除了任何没(:not)有(:has) //包含class为“se ...

  2. hexo&github博客搭建

    闲来无事,偶然看到hexo,便试着玩玩,hexo是一种静态博客工具,使用nodejs流生成静态博客,速度快,主题多,附地址:https://hexo.io/ 下面详细介绍如何使用hexo在github ...

  3. .NET MVC Scripts.Render 上下文不存在问题解决方法

    要想使用 @Scripts.Render(),就要用到 BundleConfig.cs 这个类,在App_Start目录下新建一下这个类, 类的内容如下: 使用这个类需要引入 using System ...

  4. css美化checkbox

  5. vue click事件获取当前元素属性

    Vue可以传递$event对象 <body id="app"> <ul> <li @click="say('hello!', $event) ...

  6. Android MediaPlayer播放音乐并实现进度条

    提前工作,往sd卡里放音乐文件 1.布局文件main.xml <?xml version="1.0" encoding="utf-8"?> < ...

  7. kafka leader平衡策略

    1.1个partition的默认leader是replicas中的第一个replica 2.kafka controller会启动一个定时的check线程,kafka默认是5min周期,mafka是3 ...

  8. 【Web】JavaScript 语法入门

    一. 简介 动态性和交互性 1.由浏览器解释执行 2.常见的脚本语言:JavaScript和VBScript P.S. Node.js 是使用JavaScript编写的服务器端框架. 二. JavaS ...

  9. QLocalServer和QLocalSocket单进程和进程通信

    QLocalServer 继承自QObject. QLocalServer提供了一个基于本地套接字(socket)的服务端(server).QLocalServer可以接受来自本地socket的连接. ...

  10. 电脑护眼小软件f.lux

    f.lux这软件用了能不能保护好视力不好说,反正我是用了以后这么多年一直都在用,狠不下心删去.至少安装后能让心里多一些安全感! 以前老控制不住长期坐在电脑前不动,太需要有这类软件来养护.用了没太明显的 ...