用vc编写任务管理器杀不掉的进程

      记得自己上高中的时候,我们上微机课,那时候每个机子都有个监控程序,很麻烦,老师上课了机子就被锁住了,什么也做不了,很不爽,那时候大家都知道用任务管理器结束进程,但是偏偏这个进程结束不了,后来我找到了个方法,在cmd下运行ntsd -c q -p 进程ID,这样这个监控程序就会结束了。那时候只知道这个方法,但不知道为什么任务管理器无法结束那个进程。现在我们也来写一个任务管理器杀不掉的进程吧。

       #include "stdafx.h" #include #include "tlhelp32.h" using namespace std; #pragma data_seg("YCIShared") DWORD id=0; HHOOK h=0; #pragma data_seg() HMODULE hh; typedef int (WINAPI *msg)(HWND,LPCSTR,LPCSTR,UINT); typedef FARPROC (WINAPI *gpa)(HMODULE,LPCSTR); PROC gmsg=(PROC)MessageBoxA; PROC ggpa=(PROC)GetProcAddress; int WINAPI a(HWND h,LPCSTR l1,LPCSTR l2,UINT i){ return ((msg)gmsg)(0,"win","win",0); } PROC op=(PROC)GetProcAddress(GetModuleHandle("Kernel32.dll"),"OpenProcess"); typedef HANDLE (WINAPI *myopenprocess)(DWORD,BOOL,DWORD); HANDLE WINAPI mop(DWORD dw,BOOL flag,DWORD pid){ if(pid==id){ return 0; }else{ return ((myopenprocess)op)(dw,flag,pid); } } FARPROC WINAPI a1(HMODULE h,LPCSTR l){ if(stricmp(l,"openprocess")==0){ return (PROC)mop; }else{ return ((gpa)ggpa)(h,l); } } LRESULT CALLBACK hook(int code,WPARAM w,LPARAM l){ return CallNextHookEx(h,code,w,l); } static HMODULE ModuleFromAddress(PVOID pv) { MEMORY_BASIC_INFORMATION mbi; return((VirtualQuery(pv, &mbi, sizeof(mbi)) != 0) ? (HMODULE) mbi.AllocationBase : NULL); } class hookapi{ public: hookapi(char* _module,char* _oldfunstr,PROC _oldfun,PROC _newfun); static void init(char* _module,char* _oldfunstr,PROC _oldfun,PROC _newfun,bool flag=true); static void _hookapi(HMODULE hm,char* _module,char* _oldfunstr,PROC _oldfun,PROC _newfun,bool flag); ~hookapi(); private: char* module; char* oldfunstr; PROC oldfun; PROC newfun; }; hookapi::hookapi(char* _module,char* _oldfunstr,PROC _oldfun,PROC _newfun){ module=new char[strlen(_module)+1]; strcpy(module,_module); oldfunstr=new char[strlen(_oldfunstr)+1]; strcpy(oldfunstr,_oldfunstr); oldfun=_oldfun; newfun=_newfun; init(module,oldfunstr,oldfun,newfun,true); } void hookapi::init(char* _module,char* _oldfunstr,PROC _oldfun,PROC _newfun,bool flag){ HMODULE hthis=ModuleFromAddress(init); HANDLE hs=CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,GetCurrentProcessId()); MODULEENTRY32 me={sizeof(MODULEENTRY32)}; bool ok=Module32First(hs,&me); while(ok){ if(me.hModule!=hthis){ _hookapi(me.hModule, _module, _oldfunstr, _oldfun, _newfun,flag); } ok=Module32Next(hs,&me); } CloseHandle(hs); } void hookapi::_hookapi(HMODULE hm,char* module,char* oldfunstr,PROC oldfun,PROC newfun,bool flag){ IMAGE_DOS_HEADER* pdos=(IMAGE_DOS_HEADER*)hm; IMAGE_OPTIONAL_HEADER* po=(IMAGE_OPTIONAL_HEADER*)((BYTE*)hm+pdos->e_lfanew+24); IMAGE_IMPORT_DESCRIPTOR* pimg=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hm+po->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); if(pimg==0){ return; } while(pimg->Name){ char* dllname=(char*)((BYTE*)hm+pimg->Name); if(lstrcmpiA(dllname,module)==0){ break; } pimg++; } if(pimg->Name==0){ return; } IMAGE_THUNK_DATA* pt=(IMAGE_THUNK_DATA*)((BYTE*)hm+pimg->OriginalFirstThunk); int n=0; while(pt->u1.Function){ if ((pt->u1.Ordinal & IMAGE_ORDINAL_FLAG) != IMAGE_ORDINAL_FLAG) { char *pfn=(char*)((BYTE*)hm+(DWORD)pt->u1.AddressOfData+2); PDWORD lpaddr=(DWORD*)((BYTE*)hm+pimg->FirstThunk)+n; try{ if(stricmp(pfn,oldfunstr)==0){ // MessageBox(0,oldfunstr,oldfunstr,0); DWORD dw; MEMORY_BASIC_INFORMATION mbi; VirtualQuery(lpaddr,&mbi,sizeof(mbi)); VirtualProtect(lpaddr,sizeof(DWORD),PAGE_EXECUTE_READWRITE,&dw); if(flag){ WriteProcessMemory(GetCurrentProcess(),lpaddr,&newfun,sizeof(DWORD),0); // *lpaddr=(DWORD)(DWORD*)newfun; }else{ WriteProcessMemory(GetCurrentProcess(),lpaddr,&oldfun,sizeof(DWORD),0); // *lpaddr=(DWORD)oldfun; } VirtualProtect(lpaddr,sizeof(DWORD),dw,0); break; } }catch(...){ } } n++; pt++; } } hookapi::~hookapi(){ init(module,oldfunstr,oldfun,newfun,false); delete[] module; delete[] oldfunstr; } hookapi *aa,*aaa; BOOL APIENTRY DllMain( HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved ) { switch(ul_reason_for_call){ case DLL_PROCESS_ATTACH: //MessageBox(0,"a","a",0); //init("user32.dll","messageboxw",(PROC)MessageBoxW,(PROC)a,true); hh=(HMODULE)hModule; aa=new hookapi("Kernel32.dll","openprocess",(PROC)OpenProcess,(PROC)mop); //aaa=new hookapi(hh); //aaa->init("Kernel32.dll","getprocaddress",ggpa,(PROC)a1); break; case DLL_PROCESS_DETACH: // init("user32.dll","messageboxa",gmsg,(PROC)a,false); // init("user32.dll","messageboxw",(PROC)MessageBoxW,(PROC)a,false); delete aa; // delete aaa; break; } return TRUE; } void sethook(bool f,DWORD pid){ if(f){ h=SetWindowsHookEx(WH_SHELL,hook,hh,0); id=pid; }else{ UnhookWindowsHookEx(h); } }

     上面的代码是在我前一篇的基础上,做了些修改,让它更容易使用,并且修正了一些错误。大家可以写个exe调用上面的dll,看看效果啊。

      当然,ring0级的工具结束上面的程序还是很easy的。其实上面的程序只是给大家做了个演示,告诉那些杀不掉的进程是怎么样实现的,不论是ring0还是ring3,都离不开api的hook。

       实验中也发现ring3下的IAT hook不是很稳定,容易使程序崩溃,而且如果对方程序事先获得了调用函数的真实地址,你修改了IAT是没用的,(即便你hook了getprocaddress,当然inline hook除外)。有可能是我代码的问题吧,这只是我个人的一些观点。(感觉那些成熟的安全软件都是写驱动的,估计是自己认识太少吧)

       文章有哪些不足之处,还望大家多多指正。

你可能感兴趣的:(c++)