⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 invisibility.txt

📁 This is an example how one could hide a process on Windows based operation systems from task viewer
💻 TXT
字号:
Example code: Invisibility
-------------
by yoda (6th July 2k2)

tested on: WinME and Win2000

Intro
-----
This is an example how one could hide a process on Windows based
operation systems from task viewers like ProcDump (G-RoM, Lorian
& Stone) or ProcessExplorer (SysInternals).
It could e.g. be used as some kind of dump protection.
The way to get this done is very different on NT and 9x machines.

Win 95/98/ME
------------
On 9x we reach our goal by simply hooking the target Toolhelp32
APIs: Process32First/Process32Next.
If the hook routine decides that the CALLer is querying our
process we just perform a second Process32Next call on the
specified TH32 handle.

Additionally we wipe the process from the CTRL+ALT+DEL box by
using the undocumented but well known RegisterServiceProcess API:

BOOL STDCALL RegisterServiceProcess(DWORD dwProcessID, BOOL bHide);

ProcDump, LordPE, ProcessExplorer are fooled successfully. MS Spy snaps
the window names of our process but couldn't receive additional
information except the PID, in case of my system.

Win NT/2k/XP
------------
Here things get trickier. Because a ring3 process has nearly no
rights we transfer the action to a KMD.

At first we hook NtQuerySystemInformation. Does a thread call
it and specifies the query class 5 (SystemProcessInformation; thx
EliCZ) we modify the returned chain of process information structures.
In fact I don't overwrite the whole structure. I enlarge the
SYSTEM_PROCESS_INFORMATION.SizeOfBlock structure item of the process
block being before the block of our process.

This hook isn't realized by a redirection of the API EntryPoint but
by modifying the ServiceDescriptorTable whose address one can
get from a structure which is addressed by the
NtOsKrnl!KeServiceDescriptorTable export:

SSDT STRUCT
	pSSAT              LPVOID  ?      ; System Service Address Table   ( LPVOID[] )
	Obsolete           DWORD   ?      ; or maybe: API ID base
	dwAPICount         DWORD   ?
	pSSPT              LPVOID  ?      ; System Service Parameter Table ( BYTE[] )
SSDT ENDS 

Due to the fact that these Native API IDs differ from every NT OS and
also from service pack to service pack we need to find out the NT API
ID of NtQuerySystemInformation. For that purpose we pass the address
of NtDll!NtQuerySystemInformation to the driver which extracts the
Native API ID from there....

NtDll!NtQuerySystemInformation:
		mov	eax, 97h                   ; EAX == Native API ID
		lea	edx, [esp+arg_0]           ; EDX -> argument list
		int	2Eh                        ; perform Native API call
		retn	10h

The Native API ID is the index into the function address chain we find at
NtOsKrnl!KeServiceDescriptorTable.SSDT.pSSAT. We simply exchange the
function address of our target API with the linear address of our
hook procedure. In our case: pSSAT[ 0x97 ].

When we're finished with that the user can't see Invisibility.exe anymore
in the CTRL+ALT+DEL box of NT in the process tab. The next problem is
that there's also an entry of our process in the window tab of TaskMgr.exe...

TaskMgr.exe internally uses the user32!EnumWindows API to receive the
window handles and later the windows names so that it can show name/icon
in the window tab.

Because I didn't wanted to hook every User32.dll of every process separately
and keep track of every new process being created, I needed to hook the system
somewhere in the deeper core of NT.
EnumWindows is just a stub for a non-exported function with some more arguments
which is also called by User32!EnumChildWindows. This function uses the
following 3 Native APIs:

Win32k!NtUserBuildHwndList:          - called first
                                     - called only one time
                                     - ID: 0x112E on my system
                                     
Win32k!NtUserInternalGetWindowText:  - called several times
                                     - ID: 0x11B1 on my system
                                     
Win32k!NtUserQueryWindow:            - called several times
                                     - ID: 0x11D2 on my system
                                     
Hooking NtUserBuildHwndList sounds good for our purposes. NtUserBuildHwndList
has 7 arguments and its prototype looks something like:

NTSTATUS NTAPI
NtUserBuildHwndList(                                                   ; my guesses
	IN  ARGUMENT_1,                                                        
	IN  hParentHwnd,
	IN  BOOL,
	IN  ARGUMENT_4,
	IN  SpaceForHandlesInBufferCount,
	OUT pOutputBuffer,
	OUT pbResult
);

This function isn't exported from win32k.sys. So we need to find its Service-
DescriptorTable. There is an undocumented non-accessible descriptor. The so
called ServiceDescriptorTableShadow. I found it some bytes under the address
being exported as NtOsKrnl!KeServiceDescriptorTable.
Little memory snippet...

0x0000: SSDT structure for Native API IDs < 0x1000     ; non-shadow SSDT
0x0010: 00000000 00000000 00000000 00000000            ; table terminator
0x0020: 00000000 00000000 00000000 00000000
0x0030: 00000000 00000000 00000000 00000000
0x0040: 00000000 00000000 00000000 00000000
0x0050: SSDT structure for Native API IDs <  0x1000    ; KeServiceDescriptorTableShadow !
0x0060: SSDT structure for Native API IDs >= 0x1000    ; SSDT for win32k.sys
0x0070: 00000000 00000000 00000000 00000000            ; table terminator

Now we just need the Native API ID of NtUserBuildHwndList. We've luck.
IDA says:

[...]
sub_0_77E0678A	proc near
		mov	eax, 112Eh                         ; EAX == ID of win32k!NtUserBuildHwndList  !!!
		lea	edx, [esp+arg_0]
		int	2Eh
		retn	1Ch
sub_0_77E0678A	endp

EnumWindows	proc near
		xor	eax, eax
		push	eax
		push	eax
		push	[esp+8+arg_4]
		push	[esp+0Ch+arg_0]
		push	eax
		push	eax
		call	sub_0_77E06607
		retn	8
EnumWindows	endp
[...]

...so we can grab the Native API ID of the API directly from above EnumWindows,
replace the routine address in the SSDTS.pSSAT[ 0x112E ] and we've hooked the
routine successfully. 

We can use user32!GetWindowThreadProcessId to decide in KernelMode whether one
of the returned window handles belongs to our process or not because this API
doesn't call any second API but only the raw NT structures.

After modifying also the output of this API, TaskMgr.exe also doesn't list the
Invisibility message box caption in the window tab.

ProcDump, ProcessExplorer are tricked too. MS Snap finds/lists the Invisibility
windows !


Have a look at the source code for more information.

Acknowledgement/Greetz
----------------------
EliCZ           - skilled tips as usual...thx man
DAEMON          - ditto...


E-mail:  LordPE@gmx.net
WWW:     y0da.cjb.net

yoda

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -