一、配置
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
MAKEFILE:
!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\
其中引入了ldasm.c 和 ldasm.h 和list.h 文件
贴出来代码太长了,下载吧,少年:点击打开链接
代码:
其实主要就是:
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;
}
但是还是少了两个进程:system 和 system ldle process,理由在某个博客上找到了:空闲进程是无法用HandleTable枚举出来的。。
空闲进程无法检测出来,这个还是达不到要求。。
换种思路:
五、“凭空”出现的指令
题目:SOURCES没搞好,导致出现了以下的指令:
函数头处.text:00011D7B mov eax, ___security_cookie
.text:00011D80 xor eax, ebp
.text:00011D82 mov [ebp+var_28], eax
函数尾处
.text:000120D9 mov ecx, [ebp+var_28]
.text:000120DC xor ecx, ebp ; cookie
.text:000120DE call @__security_check_cookie@4
.text:0001310F @__security_check_cookie@4 proc near
.text:0001310F
.text:0001310F cookie = ecx
.text:0001310F cmp cookie, ___security_cookie
.text:00013115 jnz short failure
.text:00013117 retn 0
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