本帖最后由 yangjt 于 2009-7-13 10:49 编辑
其实都是很简单的……高手飞过就可以了……
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 //用户进程参数块
我们看到好东西了……进程参数ProcessParameters,看看它里面……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
}
ImagePathName...好东西啊……直接抹就可以了……问题不是很大……还有命令行……
至于PEB的获取用内联汇编就好…… _asm
{
mov eax,fs:0x30
mov dwPEB,eax
}
再来看EPROCESS
首先复习一下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的结构……
首先要获得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;
}
很显然,改这一个UniqueProcessId 就可以实现进程的保护了…… MEMORY_CHUNKS datas;
datas.Address = dwEPROCESS+0x084;
int i= -1;
datas.Data =&i;
datas.Length = 4;
OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1);
其中OperateSystemMemory需要调用到ZwSystemDebugControl,因为这个函数在2003以上的系统里无法从R3调用……所以说这种保护方法是几乎已经没落的了……
新时代写驱动才是王道 这个东西算是我学习驱动前的一个热身了……
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)
其中第一个参数SYSDBG_COMMAND我们这里只需要用到两个typedef enum _SYSDBG_COMMAND {
//从内核空间拷贝到用户空间,或者从用户空间拷贝到用户空间
//但是不能从用户空间拷贝到内核空间
SysDbgCopyMemoryChunks_0 = 8,
//SysDbgReadVirtualMemory = 8,
//从用户空间拷贝到内核空间,或者从用户空间拷贝到用户空间
//但是不能从内核空间拷贝到用户空间
SysDbgCopyMemoryChunks_1 = 9,
//SysDbgWriteVirtualMemory = 9,
} SYSDBG_COMMAND, *PSYSDBG_COMMAND;
OperateSystemMemory长成这个样子……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;
}
当然还可以把_DISPATCHER_HEADER抹掉……这个结构位于EPROCESS起始的_KPROCESS里……nt!_KPROCESS
+0x000 Header : _DISPATCHER_HEADER
+0x010 ProfileListHead : _LIST_ENTRY
很显然……这个_DISPATCHER_HEADER有0x10这么大……当然抹之前要保存的……要不然在进程退出的时候就崩掉了 datas.Address = dwEPROCESS;
datas.Data =&dwTmp;
datas.Length = 16;
OperateSystemMemory(datas,SysDbgCopyMemoryChunks_0);
这段代码可以用来保存_DISPATCHER_HEADER在进程处理结束消息的时候恢复回来 datas.Address = dwEPROCESS;
datas.Data = dwTmp;
datas.Length = 16;
OperateSystemMemory(datas,SysDbgCopyMemoryChunks_1);
当然有兴趣还可以抹ImageFileName……但是要注意大小,0x10个字……= =别抹多了……要不然蓝色的背景和白色的文字将爬上你的屏幕
最后要说的也就是比较麻烦的一种方法……ActiveProcessLinks 断链
ActiveProcessLinks是一个双向链表,断链的话当然要Flink->Blink=Blink
Blink->Flink = Flink
这里还需要一步Blink =dwSelfEPROCESS;
Flink = dwSelfEPROCESS;
也就是把自己 ActiveProcessLinks的Blink和Flink都指向自己……否则退出进程的时候就蓝掉
这段代码可以写成 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);
文章写得很烂……凑合能看懂就好……
看好未来的系统……
好好学习天天向上……
祝各位这个星期有个好心情 |