当前位置:文档之家› 在Delphi中隐藏程序进程的方法

在Delphi中隐藏程序进程的方法

在Delphi中隐藏程序进程方法[1]主要需要解决两个问题,即隐藏窗口和设定热键。

一. 隐藏窗口通过API函数GETACTIVEWINDOW获取当前窗口;函数ShowWindow(HWND,nCmdShow)的参数nCmdShow取SW_HIDE时将之隐藏,取SW_SHOW时将之显示。

例如:showwindow(getactivewindow,sw_hide)。

隐藏好窗体后,须记住窗体句柄以便恢复。

二. 键盘监控为了实现键盘监控须用到钩子。

以下是程序的源文件:一、创建一个动态链接库unit HKHide; //链接库中的Unit文件interfaceusesWindows, Messages, sysutils;varhNextHookHide: HHook;HideSaveExit: Pointer;hbefore:longint;function KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM): LRESULT; stdcall; export;function EnableHideHook: BOOL; export;function DisableHideHook: BOOL; export;procedure HideHookExit; far;implementationfunction KeyboardHookHandler(iCode: Integer;wParam: WPARAM;lParam: LPARAM): LRESULT; stdcall; export;const _KeyPressMask = $80000000;varf:textfile;temp:string;beginResult := 0;If iCode < 0 ThenbeginResult := CallNextHookEx(hNextHookHide, iCode, wParam, lParam); Exit;end;//侦测 Ctrl + Alt + F12 组合键if ((lParam and _KeyPressMask) = 0) //按下时生效and (GetKeyState(vk_Control) < 0)and (getkeystate(vk_menu)<0)and (wParam = vk_F12) thenbeginResult := 1;//文件不存在则创建if not fileexists('c:\test.txt') thenbeginassignfile(f,'c:\test.txt');rewrite(f);writeln(f,0);closefile(f);endelsebeginassignfile(f,'c:\test.txt');reset(f);readln(f,temp);hbefore:=strtoint(temp);beginhbefore:=getactivewindow;temp:=inttostr(hbefore);rewrite(f);writeln(f,temp);closefile(f);ShowWindow(hbefore, SW_HIDE);end;end; //end if FileExists(....)endelse beginshowwindow(hbefore,SW_SHOW);rewrite(f);writeln(f,0);closefile(f);end;//end if Ctrl+Alt+F12按键end;function EnableHideHook: BOOL; export;beginResult := False;if hNextHookHide <> 0 then Exit;// 挂上 WH_KEYBOARD 这型的 HOOK, 同时, 传回值必须保留下 // 来, 免得 HOOK 呼叫链结断掉hNextHookHide := SetWindowsHookEx(WH_KEYBOARD,KeyboardHookHandler,HInstance,0);Result := hNextHookHide <> 0;end;function DisableHideHook: BOOL; export;beginif hNextHookHide <> 0 thenbeginResult:=True;UnhookWindowshookEx(hNextHookHide); // 解除 Keyboard Hook hNextHookHide:=0;endelseResult:=False;end;procedure HideHookExit;begin// 如果忘了解除 HOOK, 自动代理解除的动作if hNextHookHide <> 0 then DisableHideHook;ExitProc := HideSaveExit;end;end.library HKPHide; //动态链接库工程文件usesHKHide in HKHide.pas;exportsEnableHideHook,DisableHideHook;beginhNextHookHide := 0;hbefore:=0;HideSaveExit := ExitProc;ExitProc := @HideHookExit;end.//文件制作好后先Build All编译成HKPHide.dll。

二、新建一个测试工程TestPrjunit Unit1;//这是测试工程的窗体单元interfaceusesWindows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls;typeTForm1 = class(TForm)Button1: TButton;Button2: TButton;procedure Button1Click(Sender: TObject);procedure Button2Click(Sender: TObject);private{ Private declarations }public{ Public declarations }end;varForm1: TForm1;implementation{$R *.DFM}function EnableHideHook: BOOL; external 'HKPHide.DLL'; function DisableHideHook: BOOL; external 'HKPHide.DLL';procedure TForm1.Button1Click(Sender: TObject);beginif EnableHideHook thenShowMessage('HotKey Testing...');end;procedure TForm1.Button2Click(Sender: TObject);beginif DisableHideHook thenShowMessage('HotKey Testing..., DONE!);end;end.DELPHI中隐藏程序进程,纯DELPHI代码方式,我在XP下通过测试。

下面是隐藏进程的unit HideProcessunit HideProcess;interfacefunction MyHideProcess: Boolean;implementationusesWindows, SysUtils, Variants, Classes, AclAPI, accCtrl;typeNTSTATUS = LongInt;const//NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)STATUS_INFO_LENGTH_MISMATCH = NTSTATUS($C0000004);STATUS_ACCESS_DENIED = NTSTATUS($C0000022);OBJ_INHERIT = $00000002;OBJ_PERMANENT = $00000010;OBJ_EXCLUSIVE = $00000020;OBJ_CASE_INSENSITIVE = $00000040;OBJ_OPENIF = $00000080;OBJ_OPENLINK = $00000100;OBJ_KERNEL_HANDLE = $00000200;OBJ_VALID_ATTRIBUTES = $000003F2;typePIO_STATUS_BLOCK = ^IO_STATUS_BLOCK;IO_STATUS_BLOCK = recordStatus: NTSTATUS;FObject: DWORD;end;PUNICODE_STRING = ^UNICODE_STRING;UNICODE_STRING = recordLength: Word;MaximumLength: Word;Buffer: PWideChar;end;POBJECT_ATTRIBUTES = ^OBJECT_ATTRIBUTES;OBJECT_ATTRIBUTES = recordLength: DWORD;RootDirectory: Pointer;ObjectName: PUNICODE_STRING;Attributes: DWORD;SecurityDescriptor: Pointer;SecurityQualityOfService: Pointer;end;TZwOpenSection = function(SectionHandle: PHandle;DesiredAccess: ACCESS_MASK;ObjectAttributes: POBJECT_ATTRIBUTES): NTSTATUS; stdcall;TRTLINITUNICODESTRING = procedure(DestinationString: PUNICODE_STRING; SourceString: PWideChar); stdcall;varRtlInitUnicodeString: TRTLINITUNICODESTRING = nil;ZwOpenSection: TZwOpenSection = nil;g_hNtDLL: THandle = 0;g_pMapPhysicalMemory: Pointer = nil;g_hMPM: THandle = 0;g_hMPM2: THandle = 0;g_osvi: OSVERSIONINFO;b_hide: Boolean = false;//---------------------------------------------------------------------------function InitNTDLL: Boolean;beging_hNtDLL := LoadLibrary('ntdll.dll');if 0 = g_hNtDLL thenbeginResult := false;Exit;end;RtlInitUnicodeString := GetProcAddress(g_hNtDLL, 'RtlInitUnicodeString'); ZwOpenSection := GetProcAddress(g_hNtDLL, 'ZwOpenSection');Result := True;end;//---------------------------------------------------------------------------procedure CloseNTDLL;beginif (0 <> g_hNtDLL) thenFreeLibrary(g_hNtDLL);g_hNtDLL := 0;end;//---------------------------------------------------------------------------procedure SetPhyscialMemorySectionCanBeWrited(hSection: THandle);varpDacl: PACL;pSD: PPSECURITY_DESCRIPTOR;pNewDacl: PACL;dwRes: DWORD;ea: EXPLICIT_ACCESS;beginpDacl := nil;pSD := nil;pNewDacl := nil;dwRes := GetSecurityInfo(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, pDacl, nil, pSD);if ERROR_SUCCESS <> dwRes thenbeginif Assigned(pSD) thenLocalFree(Hlocal(pSD^));if Assigned(pNewDacl) thenLocalFree(HLocal(pNewDacl));end;ZeroMemory(@ea, sizeof(EXPLICIT_ACCESS));ea.grfAccessPermissions := SECTION_MAP_WRITE;ea.grfAccessMode := GRANT_ACCESS;ea.grfInheritance := NO_INHERITANCE;ea.Trustee.TrusteeForm := TRUSTEE_IS_NAME;ea.Trustee.TrusteeType := TRUSTEE_IS_USER;ea.Trustee.ptstrName := 'CURRENT_USER';dwRes := SetEntriesInAcl(1, @ea, pDacl, pNewDacl);if ERROR_SUCCESS <> dwRes thenbeginif Assigned(pSD) thenLocalFree(Hlocal(pSD^));if Assigned(pNewDacl) thenLocalFree(HLocal(pNewDacl));end;dwRes := SetSecurityInfo(hSection, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, nil, nil, pNewDacl, nil);if ERROR_SUCCESS <> dwRes thenbeginif Assigned(pSD) thenLocalFree(Hlocal(pSD^));if Assigned(pNewDacl) thenLocalFree(HLocal(pNewDacl));end;end;//---------------------------------------------------------------------------function OpenPhysicalMemory: THandle;varstatus: NTSTATUS;physmemString: UNICODE_STRING;attributes: OBJECT_ATTRIBUTES;PhyDirectory: DWORD;beging_osvi.dwOSVersionInfoSize := sizeof(OSVERSIONINFO);GetVersionEx(g_osvi);if (5 <> g_osvi.dwMajorVersion) thenbeginResult := 0;Exit;end;case g_osvi.dwMinorVersion of0: PhyDirectory := $30000;1: PhyDirectory := $39000;elsebeginResult := 0;Exit;end;end;RtlInitUnicodeString(@physmemString, '\Device\PhysicalMemory');attributes.Length := SizeOf(OBJECT_ATTRIBUTES);attributes.RootDirectory := nil;attributes.ObjectName := @physmemString;attributes.Attributes := 0;attributes.SecurityDescriptor := nil;attributes.SecurityQualityOfService := nil;status := ZwOpenSection(@g_hMPM, SECTION_MAP_READ or SECTION_MAP_WRITE, @attributes);if (status = STATUS_ACCESS_DENIED) thenbeginZwOpenSection(@g_hMPM, READ_CONTROL or WRITE_DAC, @attributes); SetPhyscialMemorySectionCanBeWrited(g_hMPM);CloseHandle(g_hMPM);status := ZwOpenSection(@g_hMPM, SECTION_MAP_READ or SECTION_MAP_WRITE,@attributes);end;if not (LongInt(status) >= 0) thenbeginResult := 0;Exit;end;g_pMapPhysicalMemory := MapViewOfFile(g_hMPM,FILE_MAP_READ or FILE_MAP_WRITE, 0, PhyDirectory, $1000);if (g_pMapPhysicalMemory = nil) thenbeginResult := 0;Exit;end;Result := g_hMPM;end;//--------------------------------------------------------------------------- function LinearToPhys(BaseAddress: PULONG; addr: Pointer): Pointer;varVAddr, PGDE, PTE, PAddr, tmp: DWORD;beginVAddr := DWORD(addr);// PGDE := BaseAddress[VAddr shr 22];PGDE := PULONG(DWORD(BaseAddress) + (VAddr shr 22) * SizeOf(ULONG))^; // Modify by dot.if 0 = (PGDE and 1) thenbeginResult := nil;Exit;end;tmp := PGDE and $00000080;if (0 <> tmp) thenbeginPAddr := (PGDE and $FFC00000) + (VAddr and $003FFFFF);endelsebeginPGDE := DWORD(MapViewOfFile(g_hMPM, 4, 0, PGDE and $FFFFF000, $1000));// PTE := (PDWORD(PGDE))[(VAddr and $003FF000) shr 12];PTE := PDWORD(PGDE + ((VAddr and $003FF000) shr 12) * SizeOf(DWord))^; // Modify by dot.if (0 = (PTE and 1)) thenbeginResult := nil;Exit;end;PAddr := (PTE and $FFFFF000) + (VAddr and $00000FFF);UnmapViewOfFile(Pointer(PGDE));end;Result := Pointer(PAddr);end;//---------------------------------------------------------------------------function GetData(addr: Pointer): DWORD;varphys, ret: DWORD;tmp: PDWORD;beginphys := ULONG(LinearToPhys(g_pMapPhysicalMemory, Pointer(addr)));tmp := PDWORD(MapViewOfFile(g_hMPM, FILE_MAP_READ or FILE_MAP_WRITE, 0,phys and $FFFFF000, $1000));if (nil = tmp) thenbeginResult := 0;Exit;end;// ret := tmp[(phys and $FFF) shr 2];ret := PDWORD(DWORD(tmp) + ((phys and $FFF) shr 2) * SizeOf(DWord))^; // Modify by dot.UnmapViewOfFile(tmp);Result := ret;end;//---------------------------------------------------------------------------function SetData(addr: Pointer; data: DWORD): Boolean;varphys: DWORD;tmp: PDWORD;beginphys := ULONG(LinearToPhys(g_pMapPhysicalMemory, Pointer(addr)));tmp := PDWORD(MapViewOfFile(g_hMPM, FILE_MAP_WRITE, 0, phys and $FFFFF000, $1000));if (nil = tmp) thenbeginResult := false;Exit;end;// tmp[(phys and $FFF) shr 2] := data;PDWORD(DWORD(tmp) + ((phys and $FFF) shr 2) * SizeOf(DWord))^ := data; // Modify by dot.UnmapViewOfFile(tmp);Result := TRUE;end;//--------------------------------------------------------------------------- {long __stdcall exeception(struct _EXCEPTION_POINTERS *tmp)beginExitProcess(0);return 1 ;end }//---------------------------------------------------------------------------function YHideProcess: Boolean;varthread, process: DWORD;fw, bw: DWORD;begin// SetUnhandledExceptionFilter(exeception);if (FALSE = InitNTDLL) thenbeginResult := FALSE;Exit;end;if (0 = OpenPhysicalMemory) thenbeginResult := FALSE;Exit;end;thread := GetData(Pointer($FFDFF124)); //ktebprocess := GetData(Pointer(thread + $44)); //kpebif (0 = g_osvi.dwMinorVersion) thenbeginfw := GetData(Pointer(process + $A0));bw := GetData(Pointer(process + $A4));SetData(Pointer(fw + 4), bw);SetData(Pointer(bw), fw);Result := TRUE;endelse if (1 = g_osvi.dwMinorVersion) thenbeginfw := GetData(Pointer(process + $88));bw := GetData(Pointer(process + $8C));SetData(Pointer(fw + 4), bw);SetData(Pointer(bw), fw);Result := TRUE;endelsebeginResult := False;end;CloseHandle(g_hMPM);CloseNTDLL;end;function MyHideProcess: Boolean; beginif not b_hide thenbeginb_hide := YHideProcess;end;Result := b_hide;end;end.用法:implementationuses HideProcess;过程调用beginMyHideProcess;....end;异常死亡进程的自动复活[作者: 上海三吉电子工程有限公司卓乃奇]一、问题的产生我们或多或少都有这样的经历,在Windows上运行的应用程序常常会异常终止,需要通过手工重新将其启动起来。

相关主题