在监控病毒的时候,我们经常需要监控病毒创建的每一个进程,监控进程是如何实现的呢,
我们来见代码分析,实现监控系统的每一个进程的创建,
#include "stdafx.h" #include "resource.h" #define MAX_LOADSTRING 100 // 全局变量: HINSTANCE hInst; // 当前实例 TCHAR szTitle[MAX_LOADSTRING]; // 标题文本 TCHAR szWindowClass[MAX_LOADSTRING]; // 标题文本 // 包含的函数的声明 ATOM MyRegisterClass(HINSTANCE hInstance); BOOL InitInstance(HINSTANCE, int); LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK About(HWND, UINT, WPARAM, LPARAM); /* 加载驱动 */ void setup() { char namebuff[256]; //获取.sys文件所在的路径 GetModuleFileName(0,namebuff,256); DWORD a=strlen(namebuff); while(1) { if(namebuff[a]=='\\')break; a--; } a++; strcpy(&namebuff[a], "protector.sys"); //加载驱动protector.sys SC_HANDLE man=OpenSCManager(0,0,SC_MANAGER_ALL_ACCESS); SC_HANDLE t=CreateService(man,"protectorservice","protectorservice",SERVICE_START|SERVICE_STOP,SERVICE_KERNEL_DRIVER,SERVICE_DEMAND_START,SERVICE_ERROR_NORMAL,namebuff,0,0,0,0,0); StartService(t,0,0); CloseServiceHandle(t); } /* 卸载驱动 */ void cleanup() { SC_HANDLE man = OpenSCManager(0,0,SC_MANAGER_ALL_ACCESS); SERVICE_STATUS stat; SC_HANDLE t = OpenService(man,"protectorservice",SERVICE_ALL_ACCESS); ControlService(t,SERVICE_CONTROL_STOP,&stat); DeleteService(t); } HANDLE device; char outputbuff[256]; char * strings[256]; DWORD stringcount; /************************************************************************/ /* 创建一个线程,每隔10毫秒测试一下通信缓冲区. 如果发现驱动已经发送请求到缓冲区里,它就检查这个文件的名字和路径是否存在于机器上的"允许运行程序列表"中. 如果查找到了,它直接给一个OK的回应. 否则,它弹出一个消息框来询问用户是否允许运行这个可疑程序. 如果得到的答复是肯定的,那么将添加这个可疑程序到"允许运行软件列表"中. 最后,我们把用户的选择写进(通信)缓冲区里,即传给驱动程序. 因此,用户得到了在自己机器上面进程创建的全部控制权*/ /************************************************************************/ void thread() { DWORD a,x; char msgbuff[512]; while(1) { memmove(&a,&outputbuff[0],4); //如果缓冲区为空,则休眠10ms,继续检查 if(!a) { Sleep(10);continue; } // 如果文件的名字和路径在机器的运行进程列表中,则发送一个OK的回应 char*name=(char*)&outputbuff[8]; for(x=0;x<stringcount;x++) { if(!stricmp(name,strings[x])) { a=1; goto skip; } } //询问用户,是否运行该程序运行 strcpy(msgbuff, "Do you want to run "); strcat(msgbuff,&outputbuff[8]); // 如果用户同意,则添加该程序到信任列表里 if(IDYES==MessageBox(0, msgbuff,"WARNING",MB_YESNO|MB_ICONQUESTION|0x00200000L)) { a=1; strings[stringcount]=_strdup(name); stringcount++; } else a=0; // 把用户的选择写进通信缓冲区,驱动将接收 skip:memmove(&outputbuff[4],&a,4); //通知驱动继续进行运行 a=0; memmove(&outputbuff[0],&a,4); } } void go() { setup(); DWORD controlbuff[64]; DWORD dw; //创建处理的线程 CreateThread(0,0,(LPTHREAD_START_ROUTINE)thread,0,0,&dw); //打开设备 device=CreateFile("\\\\.\\PROTECTOR",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,0); //去的NtCreateSection的索引, 将它传给驱动, 也将缓冲区的地址传给驱动 DWORD * addr=(DWORD *)(1+(DWORD)GetProcAddress(GetModuleHandle("ntdll.dll"),"NtCreateSection")); ZeroMemory(outputbuff,256); controlbuff[0]=addr[0]; controlbuff[1]=(DWORD)&outputbuff[0]; DeviceIoControl(device,1000,controlbuff,256,controlbuff,256,&dw,0); } /************************************************************************/ /* 主程序入口 */ /************************************************************************/ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. MSG msg; HACCEL hAccelTable; //初始化全局变量 LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadString(hInstance, IDC_PROTECTOR, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); //应用程序初始化 if (!InitInstance (hInstance, nCmdShow)) { return FALSE; } hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_PROTECTOR); //主消息循环 while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return msg.wParam; } /************************************************************************/ /* 这个函数的主要作用是保证应用程序的图标在win32系统中正常显示 */ /************************************************************************/ ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEX wcex; wcex.cbSize = sizeof(WNDCLASSEX); wcex.style = CS_HREDRAW | CS_VREDRAW; wcex.lpfnWndProc = (WNDPROC)WndProc; wcex.cbClsExtra = 0; wcex.cbWndExtra = 0; wcex.hInstance = hInstance; wcex.hIcon = LoadIcon(hInstance, (LPCTSTR)IDI_PROTECTOR); wcex.hCursor = LoadCursor(NULL, IDC_ARROW); wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1); wcex.lpszMenuName = (LPCSTR)IDC_PROTECTOR; wcex.lpszClassName = szWindowClass; wcex.hIconSm = LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL); return RegisterClassEx(&wcex); } /************************************************************************/ /* 保存实例句柄并创建主窗口 在这个函数中,将实例句柄保存在一个全局变量中,并创建和显示主窗口 */ /************************************************************************/ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { HWND hWnd; hInst = hInstance; //将实例句柄保存在全局变量中 hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL); if (!hWnd) { return FALSE; } ShowWindow(hWnd, nCmdShow); UpdateWindow(hWnd); go(); return TRUE; } /************************************************************************/ /* 窗口处理过程函数 WM_COMMAND--处理应用程序的菜单项 WM_PAINT--绘制主窗口 WM_DESTROY--发送一个退出消息并返回 */ /************************************************************************/ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { int wmId, wmEvent; PAINTSTRUCT ps; HDC hdc; TCHAR szHello[MAX_LOADSTRING]; LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING); switch (message) { case WM_COMMAND: wmId = LOWORD(wParam); wmEvent = HIWORD(wParam); // 解析菜单项: switch (wmId) { case IDM_ABOUT: DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); break; case IDM_EXIT: DestroyWindow(hWnd); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } break; break; case WM_DESTROY: CloseHandle(device); cleanup(); PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; } // about提示框的消息句柄 LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; case WM_COMMAND: if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) { EndDialog(hDlg, LOWORD(wParam)); return TRUE; } break; } return FALSE; }