程序用内核驱动的方式进入ring0,然后访问EPROCESS结构,在EPROCESS结构中找到进程链,从而可实现进程的枚举,但是由于PID 为0的系统进程Idle并没有在这个链上.所以通过这种方法自然也就找不出它来.程序输出可以用softice或DebugView工具查看. 本程序只在XP下调试通过.
****************************************************************************************************
Author:dge/D哥
Date :2006.5.1
****************************************************************************************************
;@echo off
;goto make
;***************************************************************************************************
.386
.model flat, stdcall
option casemap:none
;***************************************************************************************************
; I N C L U D E F I L E S
;***************************************************************************************************
include d:/masm32/include/w2k/ntstatus.inc
include d:/masm32/include/w2k/ntddk.inc
include d:/masm32/include/w2k/ntoskrnl.inc
include d:/masm32/include/w2k/w2kundoc.inc
includelib d:/masm32/lib/w2k/ntoskrnl.lib
include d:/masm32/Macros/Strings.mac
_DriverUnload proto :PDRIVER_OBJECT
_DispatchControl proto :PDEVICE_OBJECT,:PIRP
_DispatchControlIo proto :PDEVICE_OBJECT,:PIRP
;***************************************************************************************************
; C O N S T A N T S
;***************************************************************************************************
.const
CCOUNTED_UNICODE_STRING "//Device//devEnum", g_usDeviceName, 4
CCOUNTED_UNICODE_STRING "//??//slEnum", g_usSymbolicLinkName, 4
;***************************************************************************************************
; N O N D I S C A R D A B L E C O D E
;***************************************************************************************************
.code
DriverEntry proc uses ebx edi esi, pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING
local status:NTSTATUS
local pDeviceObject:PDEVICE_OBJECT
local dwId,lpEprocess
local ListOffset,NameOffset
local Version
;int 3
;invoke DbgPrint,$CTA0("/n/nEntry DriverEntry/n/n")
mov status,STATUS_DEVICE_CONFIGURATION_ERROR
invoke IoCreateDevice,pDriverObject,0,addr g_usDeviceName,FILE_DEVICE_UNKNOWN,0,FALSE,addr pDeviceObject
.if eax==STATUS_SUCCESS
invoke IoCreateSymbolicLink,addr g_usSymbolicLinkName,addr g_usDeviceName
.if eax == STATUS_SUCCESS
mov eax,pDriverObject
assume eax:ptr DRIVER_OBJECT
mov [eax].DriverUnload, offset _DriverUnload
mov [eax].MajorFunction[IRP_MJ_Create*(sizeof PVOID)], offset _DispatchControlIo
mov [eax].MajorFunction[IRP_MJ_CLOSE*(sizeof PVOID)], offset _DispatchControlIo
mov [eax].MajorFunction[IRP_MJ_DEVICE_CONTROL*(sizeof PVOID)], offset _DispatchControlIo
assume eax:nothing
invoke PsGetVersion,NULL,addr Version,NULL,NULL ;获得得系统版本
mov eax,Version
cmp eax,0
jne @f
mov ListOffset,0A0h
mov NameOffset,1fch
jmp QQ
@@: cmp eax,1
jne exit
mov ListOffset,88h
mov NameOffset,174h
QQ: invoke PsGetCurrentProcessId
mov dwId,eax
invoke PsLookupProcessByProcessId,dwId,addr lpEprocess
mov esi,lpEprocess
add esi,ListOffset
mov edi,esi
assume edi:PLIST_ENTRY
assume esi:PLIST_ENTRY
invoke DbgPrint,$CTA0("/n/n************Enumerate Process Start ***********/n/n")
@@: mov edx,[esi].Flink
cmp edx,edi ;比较是否为最后一个EPROCESS
je @F
assume esi:nothing
sub esi,ListOffset
add esi,NameOffset
invoke DbgPrint,$CTA0("%s/n"),esi
sub esi,NameOffset ;恢复EPROCESS指针
add esi,ListOffset
assume esi:PLIST_ENTRY
mov esi,[esi].Flink
jmp @B
@@: invoke DbgPrint,$CTA0("/n/n************Enumerate Process Complete ***********/n/n")
assume esi:nothing
assume edi:nothing
mov status,STATUS_SUCCESS
.else
invoke IoDeleteDevice, pDeviceObject
.endif
.endif
mov eax,status
ret
exit: mov eax,STATUS_DEVICE_CONFIGURATION_ERROR
ret
DriverEntry endp
;***************************************************************************************************
; DispatchControlIo
;***************************************************************************************************
_DispatchControlIo proc pDeviceObject:PDEVICE_OBJECT, pIrp:PIRP
;int 3
;invoke DbgPrint,$CTA0("/n/nEntry DispatchCreateClose /n/n")
mov eax,pIrp
assume eax:ptr _IRP
mov [eax].IoStatus.Status,STATUS_SUCCESS
and [eax].IoStatus.Information,0
assume eax:nothing
invoke IoCompleteRequest,pIrp,IO_NO_INCREMENT
mov eax, STATUS_SUCCESS
ret
_DispatchControlIo endp
;***************************************************************************************************
; DriverUnload
;***************************************************************************************************
_DriverUnload proc pDriverObject:PDRIVER_OBJECT
;int 3
;invoke DbgPrint,$CTA0("/n/nEntry DriverUnload/n/n")
invoke IoDeleteSymbolicLink,addr g_usSymbolicLinkName ;清除符号连接
mov eax, pDriverObject ;删除在初始化创建的设备
invoke IoDeleteDevice,(DRIVER_OBJECT PTR [eax]).DeviceObject
ret
_DriverUnload endp
;***************************************************************************************************
; E N D
;***************************************************************************************************
end DriverEntry
;***************************************************************************************************
:make
set path=%path%;d:/masm32/bin
set drv=enum
ml /nologo /c /coff %drv%.bat
link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj
del %drv%.obj
echo.
pause
参考资料:
(1).一块三毛钱--监视远程线程的创建. http://www.zhongts.net/MyEssay/ThreadMonitor.htm
(2)ZwelL--对windows内核操作的一些说明. https://www.xfocus.net/bbs/index.php?act=SE&f=3&t=47208&p=192941
(3) KmdTut 中文翻译. http://asm.yeah.net
(4)Undocumented Windows NT