本来指望放假抢分再混个啤酒瓶盖,结果若干牛人得分实在是过于恐怖,加上很多帖子不结贴,于是这个计划就浮云了……
  为了攒点RP值,收集了一下进程隐藏的若干方法,也顺便给哪位不结贴的朋友看看分享下。
  一、最为古老的DLL注入方法。
  虽说古老,但也经历了不少变动,最初的win9X的系统没有Psapi,没有进程快照,所以一般是三级跳。跳啊跳……NT下可以直接用OpenProcess打开进程(打不开的话,提权到Debug权限),利用LoadLibrary,并且申请远程地址空间,然后把DLL注入到目标EXE进程当中,可谓省时省力,这也是目前应用作为普遍的方法之一。
  典型代码:function 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,感谢各位能够耐心看完。