本来指望放假抢分再混个啤酒瓶盖,结果若干牛人得分实在是过于恐怖,加上很多帖子不结贴,于是这个计划就浮云了…… 为了攒点RP值,收集了一下进程隐藏的若干方法,也顺便给哪位不结贴的朋友看看分享下。 一、最为古老的DLL注入方法。 虽说古老,但也经历了不少变动,最初的win9X的系统没有Psapi,没有进程快照,所以一般是三级跳。跳啊跳……NT下可以直接用OpenProcess打开进程(打不开的话,提权到Debug权限),利用LoadLibrary,并且申请远程地址空间,然后把DLL注入到目标EXE进程当中,可谓省时省力,这也是目前应用作为普遍的方法之一。 典型代码:Delphi(Pascal) codefunction AttachToProcess(const HostFile, GuestFile: string; const PID: DWORD = 0): DWORD; var hRemoteProcess: THandle; dwRemoteProcessId: DWORD; cb: DWORD; pszLibFileRemote: Pointer; iReturnCode: Boolean; TempVar: DWORD; pfnStartAddr: TFNThreadStartRoutine; pszLibAFilename: PwideChar; begin Result := 0; EnabledDebugPrivilege(True); Getmem(pszLibAFilename, Length(GuestFile) * 2 + 1); StringToWideChar(GuestFile, pszLibAFilename, Length(GuestFile) * 2 + 1); if PID > 0 then dwRemoteProcessID := PID else FindAProcess(HostFile, False, dwRemoteProcessID); hRemoteProcess := OpenProcess(PROCESS_CREATE_THREAD + {允许远程创建线程} PROCESS_VM_OPERATION + {允许远程VM操作} PROCESS_VM_WRITE, {允许远程VM写} FALSE, dwRemoteProcessId); cb := (1 + lstrlenW(pszLibAFilename)) * sizeof(WCHAR); pszLibFileRemote := PWIDESTRING(VirtualAllocEx(hRemoteProcess, nil, cb, MEM_COMMIT, PAGE_READWRITE)); TempVar := 0; iReturnCode := WriteProcessMemory(hRemoteProcess, pszLibFileRemote, pszLibAFilename, cb, TempVar); if iReturnCode then begin pfnStartAddr := GetProcAddress(GetModuleHandle('Kernel32'), 'LoadLibraryW'); TempVar := 0; Result := CreateRemoteThread(hRemoteProcess, nil, 0, pfnStartAddr, pszLibFileRemote, 0, TempVar); end; Freemem(pszLibAFilename); end; 二、EXE注入。 比起上面的方法,更为暴力,直接将EXE作为一个模块强行附加到其它进程上面,由于注入的是EXE文件,需要考虑更多的东西,比如指针,比如映像基址,比如对应的EXE的内存映像的读写。当然,远程线程这一步是不可少的。 procedure Inject(ProcessHandle: longword; EntryPoint: pointer); var Module, NewModule: Pointer; Size, BytesWritten, TID: longword; Begin //这里得到的值为一个返回指针型变量,指向内容包括进程映像的基址 Module := Pointer(GetModuleHandle(nil)); / /得到内存映像的长度 Size:=PImageOptionalHeader (Pointer(integer(Module)+PImageDosHeader(Module)._lfanew+SizeOf(dword)+SizeOf(TImageFileHeader))).SizeOfImage; //在Exp进程的内存范围内分配一个足够长度的内存 VirtualFreeEx(ProcessHandle, Module, 0, MEM_RELEASE); //确定起始基址和内存映像基址的位置 NewModule := VirtualAllocEx(ProcessHandle, Module, Size, MEM_COMMIT or MEM_RESERVE, PAGE_EXECUTE_READWRITE); //开始写内存 WriteProcessMemory(ProcessHandle, NewModule, Module, Size, BytesWritten); //创建远程线程 CreateRemoteThread(ProcessHandle, nil, 0, EntryPoint, Module, 0, TID); end; 这种方法和DLL注入本质上没有太大差别,都是占了别人的坑,一旦目标EXE完蛋,他们也跟着88了,所以一些牛人又想出了新的方法。 三、和谐任务管理器。 这个不算什么进程隐藏的方法,不过还是说下,大多情况下,我们在任务管理器里面看进程,如果把任务管理器和谐掉,让它不显示这个进程就行了。简单来说就是过滤。 实现起来比较简单,找到任务管理器的句柄,获得目标Pid,读取进程名称,如果和目标进程相同,然后就使用WriteprocessMemroy把taskmgr相应的进程的名称改掉,比如把a.exe改成explorer.exe……当然,出现了几个explorer会让人产生怀疑的……而且这也不算隐藏,最多只是一个伪装…… 由于这种方法比较鸡肋,所以不给代码了,有兴趣的朋友自己试试吧…… 四、HOOK API(EProcess双向链表) 网上有流传很广的hideprocess.pas,就是利用EProcess的结构。双向链表,摘除链上的相应的两个偏移量,$88和$8C,这两个偏移量地址,然后就能隐藏进程了,C代码如下: http://www.codeproject.com/KB/system/preventclose.aspx 有基础的朋友可以看看,由于EProcess比较复杂,估计Delphi坛子里玩Ring0的也不多,所以也不多说了,如果想自己探索,有两个建议:1、学好汇编。2、善于利用WinDBG调试。 五、驱动……NtQuerySystemInformation Native API。内核啊内核……Liunx内核BT,Windows更抓狂……这也是方法之一,由于驱动大多是C编写的,用WDK的人很多,所以这方法大多可以搜到相应的资料,只不过Delphi不擅长写驱动,所以知道这种方法的Delphier一般很少,由于相关资料太少,给个地址吧……有部分源码,不过需要注册…… http://www.kmdkit4d.net/dispbbs.do?boardId=8&ID=52 我所知道的就这么多了,不知道哪位牛人还有更多方法,欢迎一同探讨,THX,感谢各位能够耐心看完。