开源项目之防火墙 tdifw

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.   
  8.     _LEAK_CHECK;  
  9.   
  10.     //模拟参数   
  11.     argc = 3;  
  12.     argv[0]="tdifw";  
  13.     argv[1]="install";  
  14.     argv[2]="tdifw_drv.sys";  
  15.   
  16.     if (argc >= 2)   
  17.     {  
  18.         const char *param = argv[1];  
  19.           
  20.         if (strcmp(param, "install") == 0)   
  21.         {  
  22.             if (argc < 3)   
  23.             {  
  24.                 fprintf(stderr, "Use: tdifw install <config>\n");  
  25.                 return -1;  
  26.             }  
  27.           
  28.             //加载驱动服务   
  29.             install_service(argv[2]);  
  30.           
  31.         }   
  32.         else if (strcmp(param, "remove") == 0)   
  33.         {  
  34.             //移除驱动服务   
  35.             remove_service();  
  36.         } else if (strcmp(param, "debug") == 0)   
  37.         {  
  38.   
  39.             if (argc < 3)   
  40.             {  
  41.                 fprintf(stderr, "Use: tdifw debug <config>\n");  
  42.                 return -1;  
  43.             }  
  44.   
  45.             if (start(argv[2]))   
  46.             {  
  47.                 printf("press enter to exit...\n");  
  48.                 getchar();  
  49.                 printf("exiting...\n");  
  50.                 //停止 释放资源   
  51.                 stop();  
  52.             }  
  53.   
  54.         } else if (strcmp(param, "listen") == 0)   
  55.         {       // tdifw specific   
  56.             //枚举监听   
  57.             enum_listen();  
  58.         } else if (strcmp(param, "conn") == 0)  
  59.         {       // tdifw specific   
  60.             //枚举连接   
  61.             enum_connect();  
  62.         } else   
  63.         {  
  64.             fprintf(stderr, "Use: tdifw install|remove|debug|listen|conn\n");  
  65.         }  
  66.     }  
  67.     else   
  68.     {  
  69.         g_console = FALSE;  
  70.   
  71.         // 连接程序主线程到服务控制管理程序   
  72.         if (!StartServiceCtrlDispatcher(dispatch_table))  
  73.             winerr("main: StartServiceCtrlDispatcher");  
  74.   
  75.     }  
  76.   
  77.     return 0;  
  78. }  
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.   
  7.     CHAR szPath[MAX_PATH];  
  8.   
  9.     //从注册表中获得信息   
  10.     AddEventSource("tdifw");  
  11.   
  12.     if (GetModuleFileName(NULL, szPath, sizeof(szPath)) == 0) {  
  13.         winerr("install_service: GetModuleFileName");  
  14.         return;  
  15.     }  
  16.   
  17.     //建立了一个连接到服务控制管理器,并打开指定的数据库。   
  18.     schSCManager = OpenSCManager(  
  19.                         NULL,                   // machine (NULL == local)   
  20.                         NULL,                   // database (NULL == default)   
  21.                         SC_MANAGER_ALL_ACCESS); // access required   
  22.   
  23.     if (schSCManager != NULL) {  
  24.   
  25.         //创建一个服务对象并且把它加入到服务管理数据库中   
  26.         schService = CreateService(  
  27.             schSCManager,               // SCManager database   
  28.             "tdifw",                    // name of service   
  29.             "TDI-based open source personal firewall",  // name to display   
  30.             SERVICE_ALL_ACCESS,         // desired access   
  31.             SERVICE_WIN32_OWN_PROCESS,  // service type   
  32.             SERVICE_AUTO_START,         // start type   
  33.             SERVICE_ERROR_NORMAL,       // error control type   
  34.             szPath,                     // service's binary   
  35.             NULL,                       // no load ordering group   
  36.             NULL,                       // no tag identifier   
  37.             NULL,                       // dependencies   
  38.             NULL,                       // LocalSystem account   
  39.             NULL);                      // no password   
  40.   
  41.         if (schService != NULL) {  
  42.             printf("tdifw service has been installed\n");  
  43.   
  44.             if (!add_config_info(schService, config))  
  45.                 fprintf(stderr, "Can't store config info! Service will use defaults.\n");  
  46.   
  47.             CloseServiceHandle(schService);  
  48.         } else  
  49.             winerr("install_service: CreateService");  
  50.   
  51.         CloseServiceHandle(schSCManager);  
  52.     }  
  53.     else  
  54.         winerr("install_service: OpenSCManager");  
  55. }  
//获得驱动文件所在路径 则开启 否则退出
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.   
  7.     schSCManager = OpenSCManager(  
  8.                         NULL,                   // machine (NULL == local)   
  9.                         NULL,                   // database (NULL == default)   
  10.                         SC_MANAGER_ALL_ACCESS); // access required   
  11.       
  12.     if (schSCManager != NULL) {  
  13.         schService = OpenService(schSCManager, "tdifw", SERVICE_ALL_ACCESS);  
  14.   
  15.         if (schService != NULL) {  
  16.   
  17.             // try to stop the service   
  18.             if (ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus)) {  
  19.                 printf("stopping...");  
  20.                 Sleep(1000);  
  21.   
  22.                 while(QueryServiceStatus( schService, &ssStatus)) {  
  23.                     if (ssStatus.dwCurrentState == SERVICE_STOP_PENDING) {  
  24.                         printf(".");  
  25.                         Sleep( 1000 );  
  26.                     }  
  27.                     else  
  28.                         break;  
  29.                 }  
  30.   
  31.                 printf("\n");  
  32.   
  33.                 if (ssStatus.dwCurrentState == SERVICE_STOPPED)  
  34.                     printf("stopped\n");  
  35.                 else  
  36.                     printf("failed to stop\n");  
  37.             }  
  38.   
  39.             // now remove the service   
  40.             if (DeleteService(schService))  
  41.                 printf("service has been removed\n");  
  42.             else  
  43.                 winerr("install_service: DeleteService");  
  44.   
  45.             CloseServiceHandle(schService);  
  46.         }  
  47.         else  
  48.             winerr("install_service: OpenService");  
  49.   
  50.         CloseServiceHandle(schSCManager);  
  51.     }  
  52.     else  
  53.         winerr("install_service: OpenSCManager");  
  54. }  
//移除服务 关闭驱动
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.   
  8.     // 从 psapi.dll 中获得链接EnumProcesses、EnumProcessModules、GetModuleFileNameExW函数地址   
  9.     link_psapi();  
  10.   
  11.     /* connect with driver */  
  12.       
  13.     g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,   
  14.         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);  
  15.     if (g_device == INVALID_HANDLE_VALUE) {  
  16.         winerr(g_nfo_device_name);  
  17.         goto done;  
  18.     }  
  19.   
  20.     /* get list of listening objects */  
  21.   
  22.     size = sizeof(*ln) * 0x10000 * 3;   // this size is good enough :-)   
  23.     ln = (struct listen_nfo *)malloc(size);  
  24.     if (ln == NULL) {  
  25.         perror("malloc");  
  26.         goto done;  
  27.     }  
  28.   
  29.     //与驱动交流 枚举监听操作 获取监听信息   
  30.     if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_LISTEN, NULL, 0,  
  31.         ln, size, &size, NULL)) {  
  32.         winerr("DeviceIoControl");  
  33.         goto done;  
  34.     }  
  35.   
  36.     n = size / sizeof(*ln);  
  37.   
  38.     // sort this list!    
  39.     qsort(ln, n, sizeof(*ln), compare_ln);  
  40.   
  41.     printf("IPProto\tAddress:Port\tProcess (pid)\n");  
  42.     printf("-------\t------------\t---------------------------------------------\n");  
  43.   
  44.     //显示   
  45.     for (i = 0; i < n ; i++) {  
  46.         char *proto, pname[MAX_PATH];  
  47.           
  48.         if (ln[i].ipproto == IPPROTO_TCP)  
  49.             proto = "TCP";  
  50.         else if (ln[i].ipproto == IPPROTO_UDP)  
  51.             proto = "UDP";  
  52.         else if (ln[i].ipproto == IPPROTO_IP)  
  53.             proto = "RawIP";  
  54.         else  
  55.             proto = "?";  
  56.   
  57.         // resolve pid!   
  58.         if (!get_pname_by_pid(ln[i].pid, pname, sizeof(pname)))  
  59.             pname[0] = '\0';  
  60.   
  61.         printf("%s\t%d.%d.%d.%d:%d\t%s (%d)\n",  
  62.             proto, PRINT_IP_ADDR(ln[i].addr), ntohs(ln[i].port), pname, ln[i].pid);  
  63.     }  
  64.   
  65. done:  
  66.     free(ln);  
  67.     if (g_device != INVALID_HANDLE_VALUE)  
  68.         CloseHandle(g_device);  
  69. }  
// 从驱动程序中获得网络监听对象
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.   
  9.     // 从 psapi.dll 中获得链接EnumProcesses、EnumProcessModules、GetModuleFileNameExW函数地址   
  10.     link_psapi();  
  11.   
  12.     /* connect with driver */  
  13.       
  14.     g_device = CreateFile(g_nfo_device_name, GENERIC_READ | GENERIC_WRITE,   
  15.         FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);  
  16.     if (g_device == INVALID_HANDLE_VALUE) {  
  17.         winerr(g_nfo_device_name);  
  18.         goto done;  
  19.     }  
  20.   
  21.     /* get list of listening objects */  
  22.   
  23.     size = sizeof(*tn) * 0x10000 * 3;   // this size is good enough :-)   
  24.     tn = (struct tcp_conn_nfo *)malloc(size);  
  25.     if (tn == NULL) {  
  26.         perror("malloc");  
  27.         goto done;  
  28.     }  
  29.   
  30.         //与驱动交流 枚举监听操作 获取连接信息   
  31.     if (!DeviceIoControl(g_device, IOCTL_CMD_ENUM_TCP_CONN, NULL, 0,  
  32.         tn, size, &size, NULL)) {  
  33.         winerr("DeviceIoControl");  
  34.         goto done;  
  35.     }  
  36.   
  37.     n = size / sizeof(*tn);  
  38.   
  39.     // sort this list!   
  40.     qsort(tn, n, sizeof(*tn), compare_tn);  
  41.   
  42.     //顺序输出   
  43.     for (i = 0; i < n ; i++) {  
  44.         char pname[MAX_PATH];  
  45.   
  46.         if (tn[i].state >= TCP_STATE_MAX)  
  47.             tn[i].state = 0;  
  48.           
  49.         // resolve pid!   
  50.         if (!get_pname_by_pid(tn[i].pid, pname, sizeof(pname)))  
  51.             pname[0] = '\0';  
  52.   
  53.         printf("%s\t%d.%d.%d.%d:%d\t%d.%d.%d.%d:%d\t%s (%d)\t%u/%u\n",  
  54.             g_tcp_states[tn[i].state],  
  55.             PRINT_IP_ADDR(tn[i].laddr), ntohs(tn[i].lport),  
  56.             PRINT_IP_ADDR(tn[i].raddr), ntohs(tn[i].rport),  
  57.             pname, tn[i].pid,  
  58.             tn[i].bytes_out, tn[i].bytes_in);  
  59.     }  
  60.   
  61.     // output traffic counters   
  62.     get_traffic_stats(traffic);  
  63.   
  64.     printf(  
  65.         "\n"  
  66.         "Traffic counters (out/in):\n"  
  67.         "    Total:   %I64u/%I64u\n"  
  68.         "    Counted: %I64u/%I64u\n",  
  69.         traffic[TRAFFIC_TOTAL_OUT], traffic[TRAFFIC_TOTAL_IN],  
  70.         traffic[TRAFFIC_COUNTED_OUT], traffic[TRAFFIC_COUNTED_IN]);  
  71.   
  72. done:  
  73.     free(tn);  
  74.     if (g_device != INVALID_HANDLE_VALUE)  
  75.         CloseHandle(g_device);  
  76. }  
// 从驱动程序中获得网络连接信息
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.   
  9.     //内存跟踪初始化   调用了KeInitializeSpinLock(&guard);   
  10.     memtrack_init();  
  11.   
  12.     //初始化锁   
  13.     KeInitializeSpinLock(&g_traffic_guard);  
  14.   
  15. #ifdef USE_TDI_HOOKING   
  16.     KdPrint(("[tdi_fw] WARNING! Using unstable working mode: TDI hooking!\n"));  
  17. #endif   
  18.   
  19.     status = ot_init();  
  20.     if (status != STATUS_SUCCESS) {  
  21.         KdPrint(("[tdi_fw] DriverEntry: ot_init: 0x%x\n", status));  
  22.         goto done;  
  23.     }  
  24.   
  25.     //过滤器初始化   
  26.     status = filter_init();  
  27.     if (status != STATUS_SUCCESS) {  
  28.         KdPrint(("[tdi_fw] DriverEntry: filter_init: 0x%x\n", status));  
  29.         goto done;  
  30.     }  
  31.   
  32.     //连接状态初始化   
  33.     status = conn_state_init();  
  34.     if (status != STATUS_SUCCESS) {  
  35.         KdPrint(("[tdi_fw] DriverEntry: conn_state_init: 0x%x\n", status));  
  36.         goto done;  
  37.     }  
  38.       
  39.     //分发函数   
  40.     for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)  
  41.         theDriverObject->MajorFunction[i] = DeviceDispatch;  
  42.   
  43. #if DBG   
  44.     // register UnLoad procedure   
  45.     theDriverObject->DriverUnload = OnUnload;  
  46. #endif   
  47.   
  48.     /* create control device and symbolic link */  
  49.   
  50.     RtlInitUnicodeString(&name, L"\\Device\\tdifw");  
  51.   
  52.     status = IoCreateDevice(theDriverObject,  
  53.                             0,  
  54.                             &name,  
  55.                             0,  
  56.                             0,  
  57.                             TRUE,       // exclusive!   
  58.                             &g_devcontrol);  
  59.     if (status != STATUS_SUCCESS) {  
  60.         KdPrint(("[tdi_fw] DriverEntry: IoCreateDevice(control): 0x%x!\n", status));  
  61.         goto done;  
  62.     }  
  63.   
  64.     RtlInitUnicodeString(&linkname, L"\\??\\tdifw");  
  65.   
  66.     //创建了一个符号连接   
  67.     status = IoCreateSymbolicLink(&linkname, &name);  
  68.     if (status != STATUS_SUCCESS) {  
  69.         KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x!\n", status));  
  70.         goto done;  
  71.     }  
  72.   
  73.     RtlInitUnicodeString(&name, L"\\Device\\tdifw_nfo");  
  74.   
  75.     //创建设备对象   
  76.     status = IoCreateDevice(theDriverObject,  
  77.                             0,  
  78.                             &name,  
  79.                             0,  
  80.                             0,  
  81.                             FALSE,      // not exclusive!   
  82.                             &g_devnfo);  
  83.     if (status != STATUS_SUCCESS) {  
  84.         KdPrint(("[tdi_fw] DriverEntry: IoCreateDevice(nfo): 0x%x!\n", status));  
  85.         goto done;  
  86.     }  
  87.   
  88.     RtlInitUnicodeString(&linkname, L"\\??\\tdifw_nfo");  
  89.   
  90.     //创建了一个符号连接   
  91.     status = IoCreateSymbolicLink(&linkname, &name);  
  92.     if (status != STATUS_SUCCESS) {  
  93.         KdPrint(("[tdi_fw] DriverEntry: IoCreateSymbolicLink: 0x%x!\n", status));  
  94.         goto done;  
  95.     }  
  96.   
  97. #ifndef USE_TDI_HOOKING   
  98.   
  99.     //绑定设备   
  100.     status = c_n_a_device(theDriverObject, &g_tcpfltobj, &g_tcpoldobj, L"\\Device\\Tcp");  
  101.     if (status != STATUS_SUCCESS) {  
  102.         KdPrint(("[tdi_fw] DriverEntry: c_n_a_device: 0x%x\n", status));  
  103.         goto done;  
  104.     }  
  105.   
  106.         //绑定设备   
  107.     status = c_n_a_device(theDriverObject, &g_udpfltobj, &g_udpoldobj, L"\\Device\\Udp");  
  108.     if (status != STATUS_SUCCESS) {  
  109.         KdPrint(("[tdi_fw] DriverEntry: c_n_a_device: 0x%x\n", status));  
  110.         goto done;  
  111.     }  
  112.   
  113.         //绑定设备   
  114.     status = c_n_a_device(theDriverObject, &g_ipfltobj, &g_ipoldobj, L"\\Device\\RawIp");  
  115.     if (status != STATUS_SUCCESS) {  
  116.         KdPrint(("[tdi_fw] DriverEntry: c_n_a_device: 0x%x\n", status));  
  117.         goto done;  
  118.     }  
  119.   
  120. #else   /* USE_TDI_HOOKING */   
  121.   
  122.     /* get device objects for tcp/udp/ip */  
  123.     //获得tcp设备对象   
  124.     status = get_device_object(L"\\Device\\Tcp", &g_tcpfltobj);  
  125.     if (status != STATUS_SUCCESS) {  
  126.         KdPrint(("[tdi_fw] DriverEntry: get_device_object(tcp): 0x%x\n", status));  
  127.         goto done;  
  128.     }  
  129.     //获得Udp设备对象   
  130.     status = get_device_object(L"\\Device\\Udp", &g_udpfltobj);  
  131.     if (status != STATUS_SUCCESS) {  
  132.         KdPrint(("[tdi_fw] DriverEntry: get_device_object(udp): 0x%x\n", status));  
  133.         goto done;  
  134.     }  
  135.     //获得RawIp设备对象   
  136.     status = get_device_object(L"\\Device\\RawIp", &g_ipfltobj);  
  137.     if (status != STATUS_SUCCESS) {  
  138.         KdPrint(("[tdi_fw] DriverEntry: get_device_object(ip): 0x%x\n", status));  
  139.         goto done;  
  140.     }  
  141.   
  142.     /* hook tcpip */  
  143.     //针对tcp下钩子   
  144.     status = hook_tcpip(&g_old_DriverObject, TRUE);  
  145.     if (status != STATUS_SUCCESS) {  
  146.         KdPrint(("[tdi_fw] DriverEntry: hook_driver: 0x%x\n", status));  
  147.         goto done;  
  148.     }  
  149.     g_hooked = TRUE;  
  150.   
  151. #endif  /* USE_TDI_HOOKING */   
  152.   
  153.     status = STATUS_SUCCESS;  
  154.   
  155. done:  
  156.     if (status != STATUS_SUCCESS) {  
  157.         // cleanup   
  158.         OnUnload(theDriverObject);  
  159.     }  
  160.   
  161.     return status;  
  162. }  
/* 驱动入口 */
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.               
  4.             result = tdi_create(irp, irps, &completion);  
  5.   
  6.             status = tdi_dispatch_complete(DeviceObject, irp, result,  
  7.                 completion.routine, completion.context);  
  8.               
  9.             break;  
  10.   
  11.         case IRP_MJ_DEVICE_CONTROL:  
  12.               
  13.             KdPrint(("[tdi_fw] DeviceDispatch: IRP_MJ_DEVICE_CONTROL, control 0x%x for 0x%08X\n",  
  14.                 irps->Parameters.DeviceIoControl.IoControlCode, irps->FileObject));  
  15.   
  16.             if (KeGetCurrentIrql() == PASSIVE_LEVEL) {  
  17.                 /* 
  18.                  * try to convert it to IRP_MJ_INTERNAL_DEVICE_CONTROL 
  19.                  * (works on PASSIVE_LEVEL only!) 
  20.                  */  
  21.                 status = TdiMapUserRequest(DeviceObject, irp, irps);  
  22.               
  23.             } else  
  24.                 status = STATUS_NOT_IMPLEMENTED; // set fake status   
  25.   
  26.             if (status != STATUS_SUCCESS) {  
  27.                 void *buf = (irps->Parameters.DeviceIoControl.IoControlCode == IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER) ?  
  28.                     irps->Parameters.DeviceIoControl.Type3InputBuffer : NULL;  
  29.   
  30.                 // send IRP to original driver   
  31.                 status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW, NULL, NULL);  
  32.   
  33.                 if (buf != NULL && status == STATUS_SUCCESS) {  
  34.   
  35.                     g_TCPSendData = *(TCPSendData_t **)buf;  
  36.   
  37.                     KdPrint(("[tdi_fw] DeviceDispatch: IOCTL_TDI_QUERY_DIRECT_SEND_HANDLER: TCPSendData = 0x%x\n",  
  38.                         g_TCPSendData));  
  39.   
  40.                     *(TCPSendData_t **)buf = new_TCPSendData;  
  41.                 }  
  42.   
  43.                 break;  
  44.             }  
  45.   
  46.             // don't break! go to internal device control!   
  47.           
  48.         case IRP_MJ_INTERNAL_DEVICE_CONTROL: {  
  49.             /* 
  50.              * Analyze ioctl for TDI driver 
  51.              */  
  52.             int i;  
  53.   
  54.             for (i = 0; g_tdi_ioctls[i].MinorFunction != 0; i++)  
  55.                 if (g_tdi_ioctls[i].MinorFunction == irps->MinorFunction) {  
  56.                       
  57. #if DBG   
  58.                     // print description   
  59.                     KdPrint(("[tdi_fw] DeviceDispatch: %s (0x%x) for 0x%x\n",  
  60.                         g_tdi_ioctls[i].desc,  
  61.                         irps->MinorFunction,  
  62.                         irps->FileObject));  
  63. #endif   
  64.   
  65.                     if (g_tdi_ioctls[i].fn == NULL) {  
  66.                         // send IRP to original driver   
  67.                         status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW,  
  68.                             NULL, NULL);  
  69.                         break;  
  70.                     }  
  71.   
  72.                     // call dispatch function   
  73.   
  74.                     result = g_tdi_ioctls[i].fn(irp, irps, &completion);  
  75.   
  76.                     // complete request   
  77.                     status = tdi_dispatch_complete(DeviceObject, irp, result,  
  78.                         completion.routine, completion.context);  
  79.   
  80.                     break;  
  81.                 }  
  82.       
  83.             // if dispatch function hasn't been found   
  84.             if (g_tdi_ioctls[i].MinorFunction == 0) {  
  85.                 // send IRP to original driver   
  86.                 status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW, NULL, NULL);  
  87.             }  
  88.   
  89.             break;  
  90.         }  
  91.   
  92.         case IRP_MJ_CLEANUP:        /* cleanup fileobject */  
  93.   
  94.             result = tdi_cleanup(irp, irps, &completion);  
  95.   
  96.             status = tdi_dispatch_complete(DeviceObject, irp, result,  
  97.                 completion.routine, completion.context);  
  98.             break;  
  99.   
  100.         case IRP_MJ_CLOSE:  
  101.             KdPrint(("[tdi_fw] DeviceDispatch: IRP_MJ_CLOSE fileobj 0x%x\n", irps->FileObject));  
  102.   
  103.             // passthrough IRP   
  104.             status = tdi_dispatch_complete(DeviceObject, irp, FILTER_ALLOW,  
  105.                 completion.routine, completion.context);  
  106.   
  107.             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.   
  4.     // initialize for user-mode part (exclusive access - 1 user-mode logging part)   
  5.     filter_init_2();  
  6.   
  7.     g_got_log = TRUE;  
  8.   
  9. else if (irps->MajorFunction == IRP_MJ_CLOSE) {  
  10.   
  11.     // cleanup for user-mode logging part   
  12.     filter_free_2();  
  13.   
  14.     g_got_log = FALSE;  
  15.   
  16. if (irps->MajorFunction == IRP_MJ_DEVICE_CONTROL) {  
  17.   
  18.     /* 
  19.      * control request 
  20.      */  
  21.   
  22.     ULONG ioctl = irps->Parameters.DeviceIoControl.IoControlCode,  
  23.         len = irps->Parameters.DeviceIoControl.InputBufferLength,  
  24.         size = irps->Parameters.DeviceIoControl.OutputBufferLength;  
  25.     char *out_buf;  
  26.   
  27.     if (IOCTL_TRANSFER_TYPE(ioctl) == METHOD_NEITHER) {  
  28.         // this type of transfer unsupported   
  29.         out_buf = NULL;  
  30.     } else  
  31.         out_buf = (char *)irp->AssociatedIrp.SystemBuffer;  
  32.   
  33.     // process control request   
  34.     status = process_request(ioctl, out_buf, &len, size);  
  35.   
  36.     irp->IoStatus.Information = len;  
  37.   
  38. }  
  39.   
  40. irp->IoStatus.Status = status;  
  41.   
  42. 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);


 

 

学习的目的是成熟!~

源码包下载

转载于:https://www.cnblogs.com/youlechang123/p/6821999.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值