-
-
[原创]关于在Ring0中读取/修改PEB
-
发表于:
2008-8-22 15:35
13385
-
文章很菜,大牛飘过,如有纰漏,欢迎指正。
上次看到http://bbs.pediy.com/showthread.php?t=69730中的一些回复,说是在驱动中修改PEB是不行的。
我寻思着NtReadProcessMemory/NtWriteProcessMemory读写用户空间也是KeStackAttachProcess到目标进程然后RtlCopyMemory的,所以在驱动中,Attach到目标进程然后读取/写入PEB应该是可行的,许多Ring3的程序不就这么做么?
另外对用户空间的操作应该使用ProbeForRead/ProbeForWrite来检查一下~
本程序省略此步骤。
经过实验,证明是可行的。
代码如下:
//===============================
NTKERNELAPI
NTSTATUS
PsLookupProcessByProcessId(
HANDLE ProcessId,
PEPROCESS *Process
);
NTKERNELAPI
VOID
KeAttachProcess (
PEPROCESS Process
);
NTKERNELAPI
VOID
KeDetachProcess (
VOID
);
typedef struct _PEB_LDR_DATA {
ULONG Length;
BOOLEAN Initialized;
PVOID SsHandle;
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
typedef struct _LDR_DATA_TABLE_ENTRY {
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union {
LIST_ENTRY HashLinks;
struct {
PVOID SectionPointer;
ULONG CheckSum;
};
};
union {
struct {
ULONG TimeDateStamp;
};
struct {
PVOID LoadedImports;
};
};
struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
NTSTATUS ModifyModuleName()
{
NTSTATUS status;
PEPROCESS Process;
ULONG ulPEB;
PPEB_LDR_DATA pLdr;
PLDR_DATA_TABLE_ENTRY pLdt = NULL;
PLIST_ENTRY pList,pHead;
wchar_t wszFakePath[] = L"0GiNr.com";
status = PsLookupProcessByProcessId(
(HANDLE)1356,
&Process);//exporer.exe的pid
if ( !NT_SUCCESS(status) ) {
dprintf("PsLookupProcessByProcessId = 0x%08lX",status);
return status;
}
ObDereferenceObject(Process);
KeAttachProcess(Process);
dprintf("Process : 0x%08lX. \n",Process);
ulPEB = *(ULONG *)((ULONG)Process + 0x1B0);
dprintf("PEB : 0x%08lX. \n",ulPEB);
__try {
pLdr = *(PPEB_LDR_DATA *)(ulPEB + 0x00C);
dprintf("Ldr : 0x%08lX. \n",pLdr);
pHead = pLdr->InLoadOrderModuleList.Flink;
pList = pHead;
do {
pLdt = CONTAINING_RECORD(
pList,
LDR_DATA_TABLE_ENTRY,
InLoadOrderLinks);
if ( pLdt->EntryPoint &&
pLdt->FullDllName.Buffer &&
pLdt->BaseDllName.Buffer &&
pLdt->DllBase )
{
dprintf("FullDllName : %S \n",pLdt->FullDllName.Buffer);
dprintf("BaseDllName : %S \n",pLdt->BaseDllName.Buffer);
dprintf("DllBase : 0x%08lX. \n",pLdt->DllBase);
dprintf("DllSize : 0x%08lX. \n",pLdt->SizeOfImage);
dprintf("--------------");
//DllBase : 0x7C800000.
if ( (ULONG)pLdt->DllBase == 0x7C800000 ) {
dprintf("Modify.");
dprintf("--------------");
wcscpy(pLdt->FullDllName.Buffer,wszFakePath);
wcscpy(pLdt->BaseDllName.Buffer,wszFakePath);
//断链也是可以的。
/*pLdt->InLoadOrderLinks.Blink->Flink =
pLdt->InLoadOrderLinks.Flink;
pLdt->InLoadOrderLinks.Flink->Blink =
pLdt->InLoadOrderLinks.Blink;
pLdt->InInitializationOrderLinks.Blink->Flink =
pLdt->InInitializationOrderLinks.Flink;
pLdt->InInitializationOrderLinks.Flink->Blink =
pLdt->InInitializationOrderLinks.Blink;
pLdt->InMemoryOrderLinks.Blink->Flink =
pLdt->InMemoryOrderLinks.Flink;
pLdt->InMemoryOrderLinks.Flink->Blink =
pLdt->InMemoryOrderLinks.Blink;*/
}
}
pList = pList->Flink;
} while ( pList != pHead );
} __except(EXCEPTION_EXECUTE_HANDLER) {
status = GetExceptionCode();
dprintf("GetExceptionCode() = 0x%08lX. \n",status );
}
KeDetachProcess();
return status;
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)