tdifw是windows防火墙软件(TDI层驱动过滤),负责监控网络监听与连接、以及过滤信息。
源码在src目录, 程序在Bin目录,执行根目录下的批处理文件也可以,
具体步骤如下:
1. 运行install.bat
2. 根据你机器的配置情况,编辑%SystemRoot%system32driversetc difw.conf配置文件
3. 重新启动计算机
主程序源码是win32的,就9个目标文件,不包含驱动部分,项目如图:
程序主要源码分析:
- 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> ");
- 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> ");
- return -1;
- }
- if (start(argv[2]))
- {
- printf("press enter to exit... ");
- getchar();
- printf("exiting... ");
- //停止 释放资源
- 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 ");
- }
- }
- else
- {
- g_console = FALSE;
- // 连接程序主线程到服务控制管理程序
- if (!StartServiceCtrlDispatcher(dispatch_table))
- winerr("main: StartServiceCtrlDispatcher");
- }
- return 0;
- }
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> "); 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> "); return -1; } if (start(argv[2])) { printf("press enter to exit... "); getchar(); printf("exiting... "); //停止 释放资源 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 "); } } else { g_console = FALSE; // 连接程序主线程到服务控制管理程序 if (!StartServiceCtrlDispatcher(dispatch_table)) winerr("main: StartServiceCtrlDispatcher"); } return 0; }
- //获得驱动文件所在路径 则开启 否则退出
- 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 ");
- if (!add_config_info(schService, config))
- fprintf(stderr, "Can't store config info! Service will use defaults. ");
- CloseServiceHandle(schService);
- } else
- winerr("install_service: CreateService");
- CloseServiceHandle(schSCManager);
- }
- else
- winerr("install_service: OpenSCManager");
- }
//获得驱动文件所在路径 则开启 否则退出 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 "); if (!add_config_info(schService, config)) fprintf(stderr, "Can't store config info! Service will use defaults. "); CloseServiceHandle(schService); } else winerr("install_service: CreateService"); CloseServiceHandle(schSCManager); } else winerr("install_service: OpenSCManager"); }
- //移除服务 关闭驱动
- 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(" ");
- if (ssStatus.dwCurrentState == SERVICE_STOPPED)
- printf("stopped ");
- else
- printf("failed to stop ");
- }
- // now remove the service
- if (DeleteService(schService))
- printf("service has been removed ");
- else
- winerr("install_service: DeleteService");
- CloseServiceHandle(schService);
- }
- else
- winerr("install_service: OpenService");
- CloseServiceHandle(schSCManager);
- }
- else
- winerr("install_service: OpenSCManager");
- }
//移除服务 关闭驱动 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(" "); if (ssStatus.dwCurrentState == SERVICE_STOPPED) printf("stopped "); else printf("failed to stop "); } // now remove the service if (DeleteService(schService)) printf("service has been removed "); else winerr("install_service: DeleteService"); CloseServiceHandle(schService); } else winerr("install_service: OpenService"); CloseServiceHandle(schSCManager); } else winerr("install_service: OpenSCManager"); }
- // 从驱动程序中获得网络监听对象
- 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 Address:Port Process (pid) ");
- printf("------- ------------ --------------------------------------------- ");
- //显示
- 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] = ' ';
- printf("%s %d.%d.%d.%d:%d %s (%d) ",
- 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);
- }
// 从驱动程序中获得网络监听对象 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 Address:Port Process (pid) "); printf("------- ------------ --------------------------------------------- "); //显示 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] = ' '; printf("%s %d.%d.%d.%d:%d %s (%d) ", 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); }
- // 从驱动程序中获得网络连接信息
- 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] = ' ';
- printf("%s %d.%d.%d.%d:%d %d.%d.%d.%d:%d %s (%d) %u/%u ",
- 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(
- " "
- "Traffic counters (out/in): "
- " Total: %I64u/%I64u "
- " Counted: %I64u/%I64u ",
- 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);
- }
// 从驱动程序中获得网络连接信息 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] = ' '; printf("%s %d.%d.%d.%d:%d %d.%d.%d.%d:%d %s (%d) %u/%u ", 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( " " "Traffic counters (out/in): " " Total: %I64u/%I64u " " Counted: %I64u/%I64u ", 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个目标文件,如图:
- /* 驱动入口 */
- 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! "));
- #endif
- status = ot_init();
- if (status != STATUS_SUCCESS) {
- KdPrint(("[tdi_fw] DriverEntry: ot_init: 0x%x ", status));
- goto done;
- }
- //过滤器初始化
- status = filter_init();
- if (status != STATUS_SUCCESS) {
- KdPrint(("[tdi_fw] DriverEntry: filter_init: 0x%x ", status));
- goto done;
- }
- //连接状态初始化
- status = conn_state_init();
- if (status != STATUS_SUCCESS) {
- KdPrint(("[tdi_fw] DriverEntry: conn_state_init: 0x%x ", 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! ", status));
- goto done;
- }
- RtlInitUnicodeString(&linkname, L"\??\tdifw");
- //创建了一个符号连接
- status = IoCreateSymbolicLink(&linkname, &name);
- if (status != STATUS_SUCCESS) {
- KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x! ", 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! ", status));
- goto done;
- }
- RtlInitUnicodeString(&linkname, L"\??\tdifw_nfo");
- //创建了一个符号连接
- status = IoCreateSymbolicLink(&linkname, &name);
- if (status != STATUS_SUCCESS) {
- KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x! ", 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 ", 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 ", 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 ", 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 ", 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 ", 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 ", 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 ", status));
- goto done;
- }
- g_hooked = TRUE;
- #endif /* USE_TDI_HOOKING */
- status = STATUS_SUCCESS;
- done:
- if (status != STATUS_SUCCESS) {
- // cleanup
- OnUnload(theDriverObject);
- }
- return status;
- }
/* 驱动入口 */ 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! ")); #endif status = ot_init(); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] DriverEntry: ot_init: 0x%x ", status)); goto done; } //过滤器初始化 status = filter_init(); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] DriverEntry: filter_init: 0x%x ", status)); goto done; } //连接状态初始化 status = conn_state_init(); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] DriverEntry: conn_state_init: 0x%x ", 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! ", status)); goto done; } RtlInitUnicodeString(&linkname, L"\??\tdifw"); //创建了一个符号连接 status = IoCreateSymbolicLink(&linkname, &name); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x! ", 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! ", status)); goto done; } RtlInitUnicodeString(&linkname, L"\??\tdifw_nfo"); //创建了一个符号连接 status = IoCreateSymbolicLink(&linkname, &name); if (status != STATUS_SUCCESS) { KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x! ", 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 ", 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 ", 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 ", 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 ", 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 ", 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 ", 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 ", 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模式。源码如下:
- //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 ",
- 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 ",
- 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 ",
- 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 ", irps->FileObject));
- // passthrough IRP
- status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW,
- completion.routine, completion.context);
- 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 ", 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 ", 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 ", 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 ", irps->FileObject)); // passthrough IRP status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW, completion.routine, completion.context); break;
- //设备过滤操作模式
- 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);
//设备过滤操作模式 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);
学习的目的是成熟!~