1、下载DDK 点击打开链接,并进行漫长的安装。下载Windbg,这个好下载,并安装完成。
2、VM(这里我用的是win2003当实验机)下在Power off的情况下设置setting:Edit virtual machine settings->hardware->add->next->serial port->output to named pipe-next.
3、选择:Named pipe \\.\pipe\com_1 end is the server the other end is an application
4、进入虚拟机修改boot.ini,目的是在进入系统前增加一个选择debug系统的选项。
[boot loader] timeout=30 default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS [operating systems] multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Standard" /noexecute=optout /fastdetect multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Standard - DEBUG" /noexecute=optout /fastdetect/bootlog /debug /debugport=COM1: /baudrate=115200
5、打开windbg,file-> kernel debug->com,Baud Rate设置为“115200”->port设置为“\\.\pipe\com_1”->勾选reconnect ->勾选pipe -> 等虚拟机选择debug系统后确定
连接成功:
Opened \\.\pipe\com_1
Waiting to reconnect...
Connected to Windows Server 2003 3790 x86 compatible target, ptr64 FALSE
Kernel Debugger connection established.
6、忽视它所说的 Debuggee not connected,其实Kernel Debugger connection established出现就表示已经连接好了。
7、如果没有符号symbol,windbg会出现一堆error,建议配置symbol:
新建文件夹:C:\MyCodesSymbols
运行WinDbg->菜单->File->Symbol File Path
在弹出的框框中:C:\MyCodesSymbols; SRV*C:\MyLocalSymbols*http://msdl.microsoft.com/download/symbols
然后再进行第5步,就会自动下载好。
1、在第一步中我们已经安装了ddk了,在ddk的\src\general\cancel\sys 文件夹中,有源代码,用Windows XP Checked Build Envionment 打开,进入到sys文件目录下,运行:build,再去../exe目录下:build,然后把生成的exe文件和sys文件放到VM中。
2、在VM跑起cancel.exe,就可以看到windbg与win2003的互动。
题目要求:作为入门,请编写一个简易的驱动程序,要求设备驱动的符号链接为ISCC2013Kernel1,每当创建一个该设备的句柄时在DbgView中输出 “create”;每次收到读写等其它控制指令时输出“other”;每当关闭一个该设备的句柄时输出“close”;卸载时输出“unload”。
1、驱动的符号链接
RtlInitUnicodeString(&symboliclinkname,L"\\??\\ISCC2013Kernel1");//初始化符号连接名称 //创建驱动设备符号链接 if(STATUS_SUCCESS == IoCreateSymbolicLink( &symboliclinkname,//符号链接名称 &devicename//设备名称 )) { DbgPrint("create a symbolicLink\n"); }
用winobj打开(成功):
2、什么是IRP
驱动程序与I/O管理器通信,使用的是IRP,即I/O请求包。IRP分为2部分:1)IRP首部;2)IRP堆栈。
在入口处声明派遣例程:
//设置IRP派遣例程 theDriverObject->MajorFunction[IRP_MJ_CREATE]= theDriverObject->MajorFunction[IRP_MJ_CLOSE] = theDriverObject->MajorFunction[IRP_MJ_WRITE] = theDriverObject->MajorFunction[IRP_MJ_READ] = theDriverObject->MajorFunction[IRP_MJ_CLOSE] = theDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = myDispatch;
实现myDispatch例程:
NTSTATUS myDispatch (IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp) { NTSTATUS ntStatus=STATUS_SUCCESS; PIO_STACK_LOCATION IrpStack=NULL; //IRP堆栈 ULONG IoControlCodes=0; //I/O控制代码 //设置IRP状态 pIrp->IoStatus.Status=STATUS_SUCCESS; pIrp->IoStatus.Information=0; IrpStack=IoGetCurrentIrpStackLocation(pIrp); //得到当前调用者的IRP switch (IrpStack->MajorFunction) { case IRP_MJ_CREATE: #ifdef DEBUGMSG DbgPrint("create\n"); #endif break; case IRP_MJ_CLOSE: #ifdef DEBUGMSG DbgPrint("close\n"); #endif break; default: DbgPrint("other\n"); break; } ntStatus=pIrp->IoStatus.Status; IoCompleteRequest(pIrp,IO_NO_INCREMENT);//返回IO管理器IRP报文 return ntStatus; }
全部代码:
SOURCES:
TARGETNAME=FirstDriver TARGETPATH=OBJ TARGETTYPE=DRIVER SOURCES=mydriver.c
!INCLUDE $(NTMAKEENV)\makefile.def
#include <ntddk.h> NTSTATUS myDispatch (IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp); VOID MyUnload(IN PDRIVER_OBJECT DriverObject0); NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath) { PDEVICE_OBJECT mydevice;//定义设备对象 UNICODE_STRING devicename;//定义设备名称 UNICODE_STRING symboliclinkname;//定义符号连接名称 RtlInitUnicodeString(&devicename,L"\\Device\\mydevice");//初始化设备名称 RtlInitUnicodeString(&symboliclinkname,L"\\??\\ISCC2013Kernel1");//初始化符号连接名称 //创建常规的设备对象 if(STATUS_SUCCESS == IoCreateDevice( theDriverObject,//驱动对象 0, &devicename,//设备名称 FILE_DEVICE_UNKNOWN,//类型 0, FALSE, &mydevice//设备对象 )) { DbgPrint("create a device\n"); } //创建驱动设备符号链接 if(STATUS_SUCCESS == IoCreateSymbolicLink( &symboliclinkname,//符号链接名称 &devicename//设备名称 )) { DbgPrint("create a symbolicLink\n"); } theDriverObject->DriverUnload = MyUnload; //设置IRP派遣例程和卸载例程 theDriverObject->MajorFunction[IRP_MJ_CREATE]= theDriverObject->MajorFunction[IRP_MJ_CLOSE] = theDriverObject->MajorFunction[IRP_MJ_WRITE] = theDriverObject->MajorFunction[IRP_MJ_READ] = theDriverObject->MajorFunction[IRP_MJ_CLOSE] = theDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = myDispatch; return STATUS_SUCCESS; } NTSTATUS myDispatch (IN PDEVICE_OBJECT DeviceObject,IN PIRP pIrp) { NTSTATUS ntStatus=STATUS_SUCCESS; PIO_STACK_LOCATION IrpStack=NULL; //IRP堆栈 ULONG IoControlCodes=0; //I/O控制代码 //设置IRP状态 pIrp->IoStatus.Status=STATUS_SUCCESS; pIrp->IoStatus.Information=0; IrpStack=IoGetCurrentIrpStackLocation(pIrp); //得到当前调用者的IRP switch (IrpStack->MajorFunction) { case IRP_MJ_CREATE: DbgPrint("create\n"); break; case IRP_MJ_CLOSE: DbgPrint("close\n"); break; default: DbgPrint("other\n"); break; } ntStatus=pIrp->IoStatus.Status; IoCompleteRequest(pIrp,IO_NO_INCREMENT); return ntStatus; } VOID MyUnload(IN PDRIVER_OBJECT DriverObject0) { //c语言变量一定要放最前面... PDEVICE_OBJECT temp1; PDEVICE_OBJECT temp2; UNICODE_STRING symboliclinkname;//定义符号连接名称 DbgPrint("unload\n"); RtlInitUnicodeString(&symboliclinkname,L"\\??\\ISCC2013Kernel1");//初始化连接符号 IoDeleteSymbolicLink(&symboliclinkname);//删除符号连接 if(DriverObject0) { temp1=DriverObject0->DeviceObject; //删除设备链表 while(temp1) { temp2=temp1; temp1=temp1->NextDevice; IoDeleteDevice(temp2);//删除设备 DbgPrint("upload a decive...\n"); } } }
晕,第一天竟然没过,然后找Danny大神问了下,发现是:
#ifdef DEBUGMSG DbgPrint("close\n"); #endif出错了,应该把预编译#ifdef DEBUGMSG 和 #endif去掉,哎,我太小白了。
因为#ifdef 是条件编译,只有满足该条件时,才会编译,也就是说,当DEBUGMSG被定义过,这段代码才会被编译。
而我前面没有定义过DEBUGMSG,所以就跪了。
然后就顺利PASS,,,
学习资料:
驱动程序简单入门
菜鸟也写驱动程序
驱动程序简单入门(另一篇)
DriverEntry 派遣函数
驱动牛逼例子,有各种定义
要打印出进程名字,首先得知道PEPROCESS结构中名字是什么吧?本人试了下ProcessName之类都不好使,
只能认真地找一个PEPROCESS数据结构定义,找了半天,感觉上在某个文件中有,但是好难找,不知道哪个文件有。
和内核有关吧,只知道这点。。。
终于在看雪找到了定义:
typedef struct _EPROCESS { KPROCESS Pcb; //+0x000 Pcb : _KPROCESS DWORD ProcessLock; //+0x06c ProcessLock : _EX_PUSH_LOCK LARGE_INTEGER CreateTime; //+0x070 CreateTime : _LARGE_INTEGER LARGE_INTEGER ExitTime; //+0x078 ExitTime : _LARGE_INTEGER DWORD RundownProtect; //+0x080 RundownProtect : _EX_RUNDOWN_REF DWORD UniqueProcessId; //+0x084 UniqueProcessId : Ptr32 Void LIST_ENTRY ActiveProcessLinks; //+0x088 ActiveProcessLinks : _LIST_ENTRY DWORD QuotaUsage[3]; //+0x090 QuotaUsage : [3] Uint4B DWORD QuotaPeak[3]; //+0x09c QuotaPeak : [3] Uint4B DWORD CommitCharge; //+0x0a8 CommitCharge : Uint4B DWORD PeakVirtualSize; //+0x0ac PeakVirtualSize : Uint4B DWORD VirtualSize; //+0x0b0 VirtualSize : Uint4B LIST_ENTRY SessionProcessLinks; //+0x0b4 SessionProcessLinks : _LIST_ENTRY PVOID DebugPort; //+0x0bc DebugPort : Ptr32 Void PVOID ExceptionPort; //+0x0c0 ExceptionPort : Ptr32 Void DWORD ObjectTable; //+0x0c4 ObjectTable : Ptr32 _HANDLE_TABLE DWORD Token; //+0x0c8 Token : _EX_FAST_REF DWORD WorkingSetLock[8];//+0x0cc WorkingSetLock : _FAST_MUTEX DWORD WorkingSetPage; //+0x0ec WorkingSetPage : Uint4B DWORD AddressCreationLock[8]; //+0x0f0 AddressCreationLock : _FAST_MUTEX DWORD HyperSpaceLock; //+0x110 HyperSpaceLock : Uint4B PVOID ForkInProgress; //+0x114 ForkInProgress : Ptr32 _ETHREAD DWORD HardwareTrigger; //+0x118 HardwareTrigger : Uint4B PVOID VadRoot; //+0x11c VadRoot : Ptr32 Void PVOID VadHint; //+0x120 VadHint : Ptr32 Void PVOID CloneRoot; //+0x124 CloneRoot : Ptr32 Void DWORD NumberOfPrivatePages; //+0x128 NumberOfPrivatePages : Uint4B DWORD NumberOfLockedPages; //+0x12c NumberOfLockedPages : Uint4B PVOID Win32Process; //+0x130 Win32Process : Ptr32 Void PVOID Job; //+0x134 Job : Ptr32 _EJOB PVOID SectionObject; //+0x138 SectionObject : Ptr32 Void PVOID SectionBaseAddress; //+0x13c SectionBaseAddress : Ptr32 Void PVOID QuotaBlock; //+0x140 QuotaBlock : Ptr32 _EPROCESS_QUOTA_BLOCK PVOID WorkingSetWatch; //+0x144 WorkingSetWatch : Ptr32 _PAGEFAULT_HISTORY PVOID Win32WindowStation; //+0x148 Win32WindowStation : Ptr32 Void PVOID InheritedFromUniqueProcessId; // +0x14c InheritedFromUniqueProcessId : Ptr32 Void PVOID LdtInformation; // +0x150 LdtInformation : Ptr32 Void PVOID VadFreeHint; // +0x154 VadFreeHint : Ptr32 Void PVOID VdmObjects; // +0x158 VdmObjects : Ptr32 Void PVOID DeviceMap; // +0x15c DeviceMap : Ptr32 Void LIST_ENTRY PhysicalVadList; // +0x160 PhysicalVadList : _LIST_ENTRY QWORD PageDirectoryPte; // +0x168 PageDirectoryPte : _HARDWARE_PTE PVOID Session; //+0x170 Session : Ptr32 Void char ImageFileName[16]; //+0x174 ImageFileName : [16] UChar LIST_ENTRY JobLinks; //+0x184 JobLinks : _LIST_ENTRY PVOID LockedPagesList; //+0x18c LockedPagesList : Ptr32 Void LIST_ENTRY ThreadListHead; //+0x190 ThreadListHead : _LIST_ENTRY PVOID SecurityPort; //+0x198 SecurityPort : Ptr32 Void PVOID PaeTop; //+0x19c PaeTop : Ptr32 Void DWORD ActiveThreads; //+0x1a0 ActiveThreads : Uint4B DWORD GrantedAccess; //+0x1a4 GrantedAccess : Uint4B DWORD DefaultHardErrorProcessing; //+0x1a8 DefaultHardErrorProcessing : Uint4B DWORD LastThreadExitStatus; //+0x1ac LastThreadExitStatus : Int4B PPEB Peb; //+0x1b0 Peb : Ptr32 _PEB PVOID PrefetchTrace; //+0x1b4 PrefetchTrace : _EX_FAST_REF LARGE_INTEGER ReadOperationCount; //+0x1b8 ReadOperationCount : _LARGE_INTEGER LARGE_INTEGER WriteOperationCount; //+0x1c0 WriteOperationCount : _LARGE_INTEGER LARGE_INTEGER OtherOperationCount; //+0x1c8 OtherOperationCount : _LARGE_INTEGER LARGE_INTEGER ReadTransferCount; //+0x1d0 ReadTransferCount : _LARGE_INTEGER LARGE_INTEGER WriteTransferCount; //+0x1d8 WriteTransferCount : _LARGE_INTEGER LARGE_INTEGER OtherTransferCount; //+0x1e0 OtherTransferCount : _LARGE_INTEGER DWORD CommitChargeLimit; //+0x1e8 CommitChargeLimit : Uint4B DWORD CommitChargePeak; //+0x1ec CommitChargePeak : Uint4B PVOID AweInfo; //+0x1f0 AweInfo : Ptr32 Void DWORD SeAuditProcessCreationInfo; //+0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO DWORD Vm[16]; //+0x1f8 Vm : _MMSUPPORT DWORD LastFaultCount; //+0x238 LastFaultCount : Uint4B DWORD ModifiedPageCount; //+0x23c ModifiedPageCount : Uint4B DWORD NumberOfVads; //+0x240 NumberOfVads : Uint4B DWORD JobStatus; //+0x244 JobStatus : Uint4B DWORD Flags; //+0x248 Flags : Uint4B DWORD ExitStatus; //+0x24c ExitStatus : Int4B WORD NextPageColor; //+0x250 NextPageColor : Uint2B //BYTE SubSystemMinorVersion; //+0x252 SubSystemMinorVersion : UChar //BYTE SubSystemMajorVersion; //+0x253 SubSystemMajorVersion : UChar WORD SubSystemVersion; //+0x252 SubSystemVersion : Uint2B BYTE PriorityClass; //+0x254 PriorityClass : UChar BYTE WorkingSetAcquiredUnsafe; //+0x255 WorkingSetAcquiredUnsafe : UChar DWORD Cookie; //+0x258 Cookie : Uint4B } EPROCESS,*PEPROCESS;
找到了这个PEPROCESS定义后,发现要用ImageFileName。
在打印ImageFileName的时候,失败了:1>mydriver.c(123) : error C2037: left of 'ImageFileName' specifies undefined struct/union '_EPROCESS'
苦逼啊,据说是MS很多细节没公开,导致只好硬编码啦(以下是xp pro sp2编译通过):
VOID PrintCurrentProcess() { char szImageFileName[16] = {0}; // EPROCESS的UCHAR ImageFileName[ 16 ]含结束符 PEPROCESS pCurrentProcess = PsGetCurrentProcess(); memcpy(szImageFileName, (char *)pCurrentProcess + 0x174, 16); KdPrint(("%s EPROCESS: %08x\n", szImageFileName, pCurrentProcess)); }
查表得:UniqueProcessId 是+0x84,因为是DWORD,取出来的内存,我把它放到UCHAR[4]中,要逆序以下,然后再转成DWORD。。
这里要有大端小端的注意点!!!搞了本人半天的。。
int chars2ULONG(UCHAR* a) { return a[0]+a[1]*(1<<8)+a[2]*(1<<16)+a[3]*(1<<24); }
MAKEFILE:
!INCLUDE $(NTMAKEENV)\makefile.def
SOURCES:
TARGETNAME=ThirdDriver TARGETPATH=OBJ TARGETTYPE=DRIVER SOURCES=mydriver.c\ ldasm.c\
贴出来代码太长了,下载吧,少年:点击打开链接
代码:
其实主要就是:
XPGetKiWaitListHead();
XPGetKiDispatcherReadyListHead();
ProcessListHead(KiWaitInListHead);
PrintList(KiWaitInListHead);
#include <ntddk.h> #include <ldasm.h> #include <list.h> #include <stdio.h> #include <winkernel.h> #include <NTSTATUS.H> VOID MyUnload(IN PDRIVER_OBJECT DriverObject0); PLIST_ENTRY KiWaitInListHead; PLIST_ENTRY KiDispatcherReadyListHead; void XPGetKiWaitListHead(); void XPGetKiDispatcherReadyListHead(); ULONG WaitProcOffset = 0x1C0; void _stdcall CollectProcess(PEPROCESS pEPROCESS); void ProcessListHead(PLIST_ENTRY ListHead); void PrintList(); ULONG flag[1024]; int isExist(ULONG *flag,ULONG x); PProcessList wLastItem = NULL; NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath) { theDriverObject->DriverUnload = MyUnload; XPGetKiWaitListHead(); XPGetKiDispatcherReadyListHead(); ProcessListHead(KiWaitInListHead); ProcessListHead(KiDispatcherReadyListHead); PrintList(); return STATUS_SUCCESS; } VOID MyUnload(IN PDRIVER_OBJECT DriverObject0) { return; } void XPGetKiWaitListHead() { PUCHAR cPtr, pOpcode; ULONG Length; for (cPtr = (PUCHAR)KeDelayExecutionThread; cPtr < (PUCHAR)KeDelayExecutionThread + PAGE_SIZE; cPtr += Length) { Length = SizeOfCode(cPtr, &pOpcode); if (!Length) break; if (*(PUSHORT)cPtr == 0x03C7 && *(PUSHORT)(pOpcode + 6) == 0x4389) { KiWaitInListHead = *(PLIST_ENTRY *)(pOpcode + 2); break; } } return; } void XPGetKiDispatcherReadyListHead() { PUCHAR cPtr, pOpcode; PUCHAR CallAddr = NULL; ULONG Length; for (cPtr = (PUCHAR)KiDispatchInterrupt; cPtr < (PUCHAR)KiDispatchInterrupt + PAGE_SIZE; cPtr += Length) { Length = SizeOfCode(cPtr, &pOpcode); if (!Length) return; if (*pOpcode == 0xE8 && *(PUSHORT)(pOpcode + 5) == 0x01B1) { CallAddr = (PUCHAR)(*(PULONG)(pOpcode + 1) + (ULONG)cPtr + Length); break; } } if (!CallAddr || !MmIsAddressValid(CallAddr)) return; for (cPtr = CallAddr; cPtr < CallAddr + PAGE_SIZE; cPtr += Length) { Length = SizeOfCode(cPtr, &pOpcode); if (!Length) return; if (*(PUSHORT)pOpcode == 0x148D && *(pOpcode + 2) == 0xCD && IsRelativeCmd(pOpcode + 7)) { KiDispatcherReadyListHead = *(PLIST_ENTRY *)(pOpcode + 3); break; } } return; } void ProcessListHead(PLIST_ENTRY ListHead) { PLIST_ENTRY Item; if (ListHead) { Item = ListHead->Flink; while (Item != ListHead) { CollectProcess(*(PEPROCESS *)((ULONG)Item + WaitProcOffset)); Item = Item->Flink; } } return; } int isExist(ULONG *flag,ULONG x) { int i=0; for(i=0;i<1024;i++) { if(flag[i] == x) return 1; } return 0; } int chars2ULONG(UCHAR* a) { return a[0]+a[1]*(1<<8)+a[2]*(1<<16)+a[3]*(1<<24); } void PrintList() { PProcessList temp = wLastItem; PEPROCESS p; PUCHAR szImageFileName; ULONG UniqueProcessId; UCHAR TMP[4]={0}; int count = 0; memset(flag,0,sizeof(flag)); while (temp) //遍历链表 { if (temp->pEPROCESS) { szImageFileName = (PUCHAR)((unsigned int)(temp->pEPROCESS) + 0x174); memcpy(TMP,(PUCHAR)((unsigned int)(temp->pEPROCESS) + 0x084),4); UniqueProcessId = chars2ULONG(TMP); //if(0 == isExist(flag,UniqueProcessId)) { flag[count++] = UniqueProcessId; DbgPrint("ProcessName = %s ,ProcessID = %ld\n",szImageFileName,UniqueProcessId); } } temp = temp->NextItem; } DbgPrint("Count is :%d\n",count); } void _stdcall CollectProcess(PEPROCESS pEPROCESS) { if (!IsAdded(wLastItem, pEPROCESS)) AddItem(&wLastItem, pEPROCESS); return; }
看来只能换个思路了:HandleTable枚举进程!
#include <ntddk.h> #include <ldasm.h> #include <list.h> #include <stdio.h> #include <winkernel.h> #include <NTSTATUS.H> VOID MyUnload(IN PDRIVER_OBJECT DriverObject0); PLIST_ENTRY HandleTableListHead; ULONG WaitProcOffset = 0x1C0; void _stdcall CollectProcess(PEPROCESS pEPROCESS); void ProcessListHead(PLIST_ENTRY ListHead); void PrintList(); ULONG flag[1024]; int isExist(ULONG *flag,ULONG x); PProcessList wLastItem = NULL; void GetHandleTableListHead(); PVOID GetInfoTable(ULONG ATableType); void ScanHandleTablesList(); ULONG HandleTableOffset=0xc4; ULONG HandleTableListOffset=0x01C;//win2000为0x054 ULONG QuotaProcessOffset = 0x04;//win2000为0x00c NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath) { theDriverObject->DriverUnload = MyUnload; GetHandleTableListHead(); ScanHandleTablesList(); PrintList(); return STATUS_SUCCESS; } VOID MyUnload(IN PDRIVER_OBJECT DriverObject0) { return; } PVOID GetInfoTable(ULONG ATableType) { ULONG mSize = 0x4000; PVOID mPtr = NULL; NTSTATUS St; do { mPtr = ExAllocatePool(PagedPool, mSize); memset(mPtr, 0, mSize); if (mPtr) { St = ZwQuerySystemInformation(ATableType, mPtr, mSize, NULL); } else return NULL; if (St == STATUS_INFO_LENGTH_MISMATCH) { ExFreePool(mPtr); mSize = mSize * 2; } } while (St == STATUS_INFO_LENGTH_MISMATCH); if (St == STATUS_SUCCESS) return mPtr; ExFreePool(mPtr); return NULL; } void GetHandleTableListHead() { PSYSTEM_MODULE_INFORMATION_EX Info = GetInfoTable(SystemModuleInformation); ULONG NtoskrnlBase = (ULONG)Info->Modules[0].Base; ULONG NtoskrnlSize = Info->Modules[0].Size; PHANDLE_TABLE HandleTable = *(PHANDLE_TABLE *)((ULONG)PsGetCurrentProcess() + HandleTableOffset); PLIST_ENTRY HandleTableList = (PLIST_ENTRY)((ULONG)HandleTable + HandleTableListOffset); PLIST_ENTRY CurrTable; ExFreePool(Info); for (CurrTable = HandleTableList->Flink; CurrTable != HandleTableList; CurrTable = CurrTable->Flink) { if ((ULONG)CurrTable > NtoskrnlBase && (ULONG)CurrTable < NtoskrnlBase + NtoskrnlSize) { HandleTableListHead = CurrTable; break; } } } void ScanHandleTablesList() { PLIST_ENTRY CurrTable; PEPROCESS QuotaProcess; if (HandleTableListHead) { CurrTable = HandleTableListHead->Flink;;; while (CurrTable != HandleTableListHead) { QuotaProcess = *(PEPROCESS *)((PUCHAR)CurrTable - HandleTableListOffset + QuotaProcessOffset); if (QuotaProcess) CollectProcess(QuotaProcess); CurrTable = CurrTable->Flink; } } return; } void ProcessListHead(PLIST_ENTRY ListHead) { PLIST_ENTRY Item; if (ListHead) { Item = ListHead->Flink; while (Item != ListHead) { CollectProcess(*(PEPROCESS *)((ULONG)Item + WaitProcOffset)); Item = Item->Flink; } } return; } int isExist(ULONG *flag,ULONG x) { int i=0; for(i=0;i<1024;i++) { if(flag[i] == x) return 1; } return 0; } int chars2ULONG(UCHAR* a) { return a[0]+a[1]*(1<<8)+a[2]*(1<<16)+a[3]*(1<<24); } void PrintList() { PProcessList temp = wLastItem; PEPROCESS p; PUCHAR szImageFileName; ULONG UniqueProcessId; UCHAR TMP[4]={0}; int count = 0; memset(flag,0,sizeof(flag)); while (temp) //遍历链表 { if (temp->pEPROCESS) { szImageFileName = (PUCHAR)((unsigned int)(temp->pEPROCESS) + 0x174); memcpy(TMP,(PUCHAR)((unsigned int)(temp->pEPROCESS) + 0x084),4); UniqueProcessId = chars2ULONG(TMP); //if(0 == isExist(flag,UniqueProcessId)) { flag[count++] = UniqueProcessId; DbgPrint("ProcessName = %s ,ProcessID = %ld\n",szImageFileName,UniqueProcessId); } } temp = temp->NextItem; } DbgPrint("Count is :%d\n",count); } void _stdcall CollectProcess(PEPROCESS pEPROCESS) { if (!IsAdded(wLastItem, pEPROCESS)) AddItem(&wLastItem, pEPROCESS); return; }
空闲进程无法检测出来,这个还是达不到要求。。
换种思路:
题目:SOURCES没搞好,导致出现了以下的指令:
函数头处SOURCES文件详解,半点没用!!!详解连这个参数都找不到。。。
SOURCES:
# $Id$ TARGETNAME=usbsamp TARGETTYPE=PROGRAM _NT_TARGET_VERSION= $(_NT_TARGET_VERSION_WINXP) USE_MSVCRT=1 UMTYPE=console UMBASE=0x01000000 # Create browse info #BROWSER_INFO=1 #BROWSERFILE=<some path> # Additional defines for the C/C++ preprocessor C_DEFINES=$(C_DEFINES) # If you uncomment the following line, the linker will not use buffer overflow # checking for the entry point and so on. Leave it commented if possible. #BUFFER_OVERFLOW_CHECKS=0 INCLUDES=$(DDK_INC_PATH);$(CRT_INC_PATH);$(SDK_INC_PATH);$(IFSKIT_INC) \ ..\..\usbsamp_new\usbsamp_new TARGETLIBS=D:\WINDDK\7600.16385.1\lib\wxp\i386\usbd.lib \ D:\WINDDK\7600.16385.1\lib\wxp\i386\setupapi.lib SOURCES= \ testapp.c \ testapp.rc