其实都是很简单的……高手飞过就可以了……
R3进程保护扫盲帖
首先来看简单的PEB
复习PEB结构
代码:
nt!_PEB +0x000 InheritedAddressSpace : UChar +0x001 ReadImageFileExecOptions : UChar +0x002 BeingDebugged : UChar //IsDebugPresent所检查的标志位,是否被调试 +0x003 SpareBool : UChar +0x004 Mutant : Ptr32 Void +0x008 ImageBaseAddress : Ptr32 Void +0x00c Ldr : Ptr32 _PEB_LDR_DATA //所有加载模块构成的链表 +0x010 ProcessParameters : Ptr32 _RTL_USER_PROCESS_PARAMETERS //用户进程参数块
代码:
typedef struct _RTL_USER_PROCESS_PARAMETERS { CURDIR CurrentDirectory; // Specified in DOS-like symbolic link path, ex: "C:/WinNT/SYSTEM32" UNICODE_STRING DllPath; // DOS-like paths separated by ';' where system should search for DLL files. UNICODE_STRING ImagePathName; // Full path in DOS-like format to process'es file image. UNICODE_STRING CommandLine; // Command line }
至于PEB的获取用内联汇编就好……
代码:
_asm { mov eax,fs:0x30 mov dwPEB,eax }
首先复习一下EPROCESS和PEB的结构
代码:
nt!_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 //这个是PID +0x088 ActiveProcessLinks : _LIST_ENTRY //连接EPROCESS的双链,断链就是断这里 +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 //进程所属的JOB对象? +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 +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
首先要获得EPROCESS
代码:
HANDLE hProcess= NULL; DWORD dwPID = GetCurrentProcessId(); PSYSTEM_HANDLE_INFORMATION pHandleInfo = NULL; ULONG uObjCnt = 0; NTSTATUS status; DWORD buflen=0x10000,needlen=0; // DWORD dwBufLen = 0x10000; // DWORD dwRetLen = 0x10000; BOOL bRet = FALSE; GetProcAddress(LoadLibrary("kernel32.dll"),"OpenProcess"); __asm { push dwPID push 0 push PROCESS_ALL_ACCESS call eax mov hProcess,eax } //获得进程对象的地址 PBYTE pBuf = NULL; do { //申请查询句柄信息所需的内存 ZwAllocateVirtualMemory(GetCurrentProcess(),(PVOID*)&pBuf,0,&buflen,MEM_COMMIT,PAGE_READWRITE); //查询系统句柄信息,类型为16 status=ZwQuerySystemInformation(SystemHandleInformation,(PVOID)pBuf,buflen,&needlen); if (status==STATUS_SUCCESS) { break; } //不成功,则释放内存 //这里只要一块大内存够放这些内容就行,或者直接申请一块足够大的也可以 //返回的needlen可以做为参考 ZwFreeVirtualMemory(GetCurrentProcess(),(PVOID*)&pBuf,&buflen,MEM_RELEASE); //然后把要申请的内存大小乘2,直至成功为止 buflen*=2; pBuf=NULL; } while(TRUE); uObjCnt = (ULONG)*(ULONG*)pBuf; pHandleInfo = (PSYSTEM_HANDLE_INFORMATION)(pBuf+sizeof(ULONG)); if(NT_SUCCESS(status)) { for(int i=0;i<(int)uObjCnt;i++) { if(pHandleInfo->ProcessId==dwPID &&pHandleInfo->Handle==(USHORT)hProcess) { dwEPROCESS = (DWORD)pHandleInfo->Object; dwCurrentPID = pHandleInfo->ProcessId; break; } pHandleInfo++; } ZwFreeVirtualMemory(GetCurrentProcess(),(PVOID*)&pBuf,&buflen,MEM_RELEASE); ZwClose(hProcess); bRet = TRUE; }
代码:
MEMORY_CHUNKS datas; datas.Address = dwEPROCESS+0x084; int i= -1; datas.Data =&i; datas.Length = 4; OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1);
新时代写驱动才是王道

ZwSystemDebugControl在R3下的调用参数是
代码:
NTSYSAPI NTSTATUS NTAPI ZwSystemDebugControl ( IN SYSDBG_COMMAND Command,IN PVOID pInBuf,IN ULONG nInLen, OUT PVOID pOutBuf,IN ULONG nOutLen,OUT PULONG nRetLen OPTIONAL )
代码:
typedef enum _SYSDBG_COMMAND { //从内核空间拷贝到用户空间,或者从用户空间拷贝到用户空间 //但是不能从用户空间拷贝到内核空间 SysDbgCopyMemoryChunks_0 = 8, //SysDbgReadVirtualMemory = 8, //从用户空间拷贝到内核空间,或者从用户空间拷贝到用户空间 //但是不能从内核空间拷贝到用户空间 SysDbgCopyMemoryChunks_1 = 9, //SysDbgWriteVirtualMemory = 9, } SYSDBG_COMMAND, *PSYSDBG_COMMAND;
代码:
BOOL OperateSystemMemory(MEMORY_CHUNKS &datas,SYSDBG_COMMAND command) { NTSTATUS status; BOOL bRet = FALSE; //patch 内核 status = ZwSystemDebugControl(command,&datas,sizeof(MEMORY_CHUNKS),NULL,NULL,NULL); if(NT_SUCCESS(status)) bRet = TRUE; return bRet; }
代码:
nt!_KPROCESS +0x000 Header : _DISPATCHER_HEADER +0x010 ProfileListHead : _LIST_ENTRY
代码:
datas.Address = dwEPROCESS; datas.Data =&dwTmp; datas.Length = 16; OperateSystemMemory(datas,SysDbgCopyMemoryChunks_0);
代码:
datas.Address = dwEPROCESS; datas.Data = dwTmp; datas.Length = 16; OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1);
最后要说的也就是比较麻烦的一种方法……ActiveProcessLinks 断链
ActiveProcessLinks是一个双向链表,断链的话当然要
代码:
Flink->Blink=Blink Blink->Flink = Flink
代码:
Blink =dwSelfEPROCESS; Flink = dwSelfEPROCESS;
这段代码可以写成
代码:
datas.Address = dwEPROCESS+0x88; datas.Data =&link; datas.Length = 8; OperateSystemMemory(datas,SysDbgCopyMemoryChunks_0); datas.Address = link[0]+4; datas.Data =&link[1]; datas.Length = 4; OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1); datas.Address = link[1]; datas.Data =&link[0]; OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1); datas.Address = dwEPROCESS+0x088; datas.Data =&dwEPROCESS; datas.Length = 4; OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1); datas.Address = dwEPROCESS+0x08C; datas.Data =&dwEPROCESS; datas.Length = 4; OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1);
看好未来的系统……

祝各位这个星期有个好心情