PEB结构体
在fs寄存器所指的地址再偏移0x30就是该程序的PEB地址。其结构为
typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; PVOID Reserved4[3]; PVOID AtlThunkSListPtr; PVOID Reserved5; ULONG Reserved6; PVOID Reserved7; ULONG Reserved8; ULONG AtlThunkSListPtr32; PVOID Reserved9[45]; BYTE Reserved10[96]; PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE Reserved11[128]; PVOID Reserved12[1]; ULONG SessionId; } PEB, *PPEB;
这是官方的peb公布的数据,其实还有几个链表,官方并没有说出来,不过也够了
PEB_LDR_DATA结构体
这个结构体中,成员InmemoryOrderModuleList指向的是一个已加载模块的链表,其图可以看下这位师傅的博客
看了那位师傅的博客可以很容一直到,他指向的也是一个PEB_LDR_DATA的结构体,只不过是LDR_DATA_TABLE_ENTRY中的一个结构体,所以我们只要算出偏移即可(offset -0x8)
typedef struct _PEB_LDR_DATA { BYTE Reserved1[8]; PVOID Reserved2[3]; LIST_ENTRY InMemoryOrderModuleList; } PEB_LDR_DATA, *PPEB_LDR_DATA;
LDR_DATA_TABLE_ENTRY结构体
里面存着模块的名称
typedef struct _LDR_DATA_TABLE_ENTRY { PVOID Reserved1[2]; LIST_ENTRY InMemoryOrderLinks; PVOID Reserved2[2]; PVOID DllBase; PVOID EntryPoint; PVOID Reserved3; UNICODE_STRING FullDllName; BYTE Reserved4[8]; PVOID Reserved5[3]; union { ULONG CheckSum; PVOID Reserved6; }; ULONG TimeDateStamp; } LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
EPROCESS结构体
ntdll!_EPROCESS +0x000 Pcb : _KPROCESS +0x06c ProcessLock : _EX_PUSH_LOCK +0x070 CreateTime : _LARGE_INTEGER +0x078 ExitTime : _LARGE_INTEGER +0x080 RundownProtect : _EX_RUNDOWN_REF +0x084 UniqueProcessId : Ptr32 Void +0x088 ActiveProcessLinks : _LIST_ENTRY +0x090 QuotaUsage : [3] Uint4B +0x09c QuotaPeak : [3] Uint4B +0x0a8 CommitCharge : Uint4B +0x0ac PeakVirtualSize : Uint4B +0x0b0 VirtualSize : Uint4B +0x0b4 SessionProcessLinks : _LIST_ENTRY +0x0bc DebugPort : Ptr32 Void +0x0c0 ExceptionPort : Ptr32 Void +0x0c4 ObjectTable : Ptr32 _HANDLE_TABLE +0x0c8 Token : _EX_FAST_REF +0x0cc WorkingSetLock : _FAST_MUTEX +0x0ec WorkingSetPage : Uint4B +0x0f0 AddressCreationLock : _FAST_MUTEX +0x110 HyperSpaceLock : Uint4B +0x114 ForkInProgress : Ptr32 _ETHREAD +0x118 HardwareTrigger : Uint4B +0x11c VadRoot : Ptr32 Void +0x120 VadHint : Ptr32 Void +0x124 CloneRoot : Ptr32 Void +0x128 NumberOfPrivatePages : Uint4B +0x12c NumberOfLockedPages : Uint4B +0x130 Win32Process : Ptr32 Void +0x134 Job : Ptr32 _EJOB +0x138 SectionObject : Ptr32 Void +0x13c SectionBaseAddress : Ptr32 Void +0x140 QuotaBlock : Ptr32 _EPROCESS_QUOTA_BLOCK +0x144 WorkingSetWatch : Ptr32 _PAGEFAULT_HISTORY +0x148 Win32WindowStation : Ptr32 Void +0x14c InheritedFromUniqueProcessId : Ptr32 Void +0x150 LdtInformation : Ptr32 Void +0x154 VadFreeHint : Ptr32 Void +0x158 VdmObjects : Ptr32 Void +0x15c DeviceMap : Ptr32 Void +0x160 PhysicalVadList : _LIST_ENTRY +0x168 PageDirectoryPte : _HARDWARE_PTE_X86 +0x168 Filler : Uint8B +0x170 Session : Ptr32 Void +0x174 ImageFileName : [16] UChar +0x184 JobLinks : _LIST_ENTRY +0x18c LockedPagesList : Ptr32 Void +0x190 ThreadListHead : _LIST_ENTRY +0x198 SecurityPort : Ptr32 Void +0x19c PaeTop : Ptr32 Void +0x1a0 ActiveThreads : Uint4B +0x1a4 GrantedAccess : Uint4B +0x1a8 DefaultHardErrorProcessing : Uint4B +0x1ac LastThreadExitStatus : Int4B +0x1b0 Peb : Ptr32 _PEB +0x1b4 PrefetchTrace : _EX_FAST_REF +0x1b8 ReadOperationCount : _LARGE_INTEGER +0x1c0 WriteOperationCount : _LARGE_INTEGER +0x1c8 OtherOperationCount : _LARGE_INTEGER +0x1d0 ReadTransferCount : _LARGE_INTEGER +0x1d8 WriteTransferCount : _LARGE_INTEGER +0x1e0 OtherTransferCount : _LARGE_INTEGER +0x1e8 CommitChargeLimit : Uint4B +0x1ec CommitChargePeak : Uint4B +0x1f0 AweInfo : Ptr32 Void +0x1f4 SeAuditProcessCreationInfo : _SE_AUDIT_PROCESS_CREATION_INFO +0x1f8 Vm : _MMSUPPORT +0x238 LastFaultCount : Uint4B +0x23c ModifiedPageCount : Uint4B +0x240 NumberOfVads : Uint4B +0x244 JobStatus : Uint4B +0x248 Flags : Uint4B +0x248 CreateReported : Pos 0, 1 Bit +0x248 NoDebugInherit : Pos 1, 1 Bit +0x248 ProcessExiting : Pos 2, 1 Bit +0x248 ProcessDelete : Pos 3, 1 Bit +0x248 Wow64SplitPages : Pos 4, 1 Bit +0x248 VmDeleted : Pos 5, 1 Bit +0x248 OutswapEnabled : Pos 6, 1 Bit +0x248 Outswapped : Pos 7, 1 Bit +0x248 ForkFailed : Pos 8, 1 Bit +0x248 HasPhysicalVad : Pos 9, 1 Bit +0x248 AddressSpaceInitialized : Pos 10, 2 Bits +0x248 SetTimerResolution : Pos 12, 1 Bit +0x248 BreakOnTermination : Pos 13, 1 Bit +0x248 SessionCreationUnderway : Pos 14, 1 Bit +0x248 WriteWatch : Pos 15, 1 Bit +0x248 ProcessInSession : Pos 16, 1 Bit +0x248 OverrideAddressSpace : Pos 17, 1 Bit +0x248 HasAddressSpace : Pos 18, 1 Bit +0x248 LaunchPrefetched : Pos 19, 1 Bit +0x248 InjectInpageErrors : Pos 20, 1 Bit +0x248 VmTopDown : Pos 21, 1 Bit +0x248 Unused3 : Pos 22, 1 Bit +0x248 Unused4 : Pos 23, 1 Bit +0x248 VdmAllowed : Pos 24, 1 Bit +0x248 Unused : Pos 25, 5 Bits +0x248 Unused1 : Pos 30, 1 Bit +0x248 Unused2 : Pos 31, 1 Bit +0x24c ExitStatus : Int4B +0x250 NextPageColor : Uint2B +0x252 SubSystemMinorVersion : UChar +0x253 SubSystemMajorVersion : UChar +0x252 SubSystemVersion : Uint2B +0x254 PriorityClass : UChar +0x255 WorkingSetAcquiredUnsafe : UChar +0x258 Cookie : Uint4B
1、用OD附加记事本,然后查看记事本进程的PEB的BeingDebugged成员的值(注意:OD不要使用插件)
先查看器fs所指的位置
偏移为0x30处,所指地址为0x7ffdf000,这就是PEB
为True说明正在被调试
2、写程序获取PEB中的模块链表,找到kernel32.dll的基址(win7 xp通用)
我这里是通过调试找到的,不然需要比较UNicodeString字符串,所以我直接手动调试了
#include<stdio.h> #include<stdlib.h> #include<windows.h> #include<winternl.h> VOID FindProcessByPEB() { PEB* peb; __asm { mov eax,dword ptr fs:[0x30] mov peb,eax } PPEB_LDR_DATA pld=peb->Ldr; PLDR_DATA_TABLE_ENTRY pdte=(PLDR_DATA_TABLE_ENTRY)((DWORD)pld->InMemoryOrderModuleList.Flink-8); while((DWORD)pdte->InMemoryOrderLinks.Flink!=(DWORD)(&pld->InMemoryOrderModuleList)) { pdte=(PLDR_DATA_TABLE_ENTRY)((DWORD)pdte->InMemoryOrderLinks.Flink-8); } printf("%d",peb->BeingDebugged); } int main() { FindProcessByPEB(); while(1); }
3、用OD附加记事本,下断点,然后在windbg中清空EPROCESS中的DebugPort中的值,然后单步调试,观察结果.
附加
找到Eprocess
修改DebugPort
出现了报错
4、使用windbg对EPROCESS中的ActiveProcessLinks断链,然后在任务管理器中查找该进程。
运行驱动前
运行后
源代码
#include <ntddk.h> #include <ntstatus.h> VOID DriverUnload(PDRIVER_OBJECT pDriver) { DbgPrint("Driver unloaded. "); } NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING reg_path) { // HOOK PEPROCESS pEprocess, pCurProcess; pDriver->DriverUnload = DriverUnload; __asm { mov eax,fs:[0x124] mov eax,[eax+0x220] mov pEprocess,eax } pCurProcess=(PEPROCESS)(*(PULONG)((ULONG)pEprocess+0x88)-0x88); while(pCurProcess!=pEprocess) { PCHAR ImageFileName=(PCHAR)pCurProcess+0x174; if(strcmp(ImageFileName,"notepad.exe")==0) { PLIST_ENTRY pFEprocess,pBEprocess,cur; cur=(PLIST_ENTRY)((PCHAR)pCurProcess+0x88); pFEprocess=cur->Flink; pBEprocess=cur->Blink; pFEprocess->Blink=pBEprocess; pBEprocess->Flink=pFEprocess; } pCurProcess=(PEPROCESS)(*(PULONG)((ULONG)pCurProcess+0x88)-0x88); } return STATUS_SUCCESS; }