关于进程PEB结构前辈们给出了几篇比较详细的文章。
例如:
《JIURL玩玩Win2k进程线程篇 PEB》
《陆麟 的 WIN2000 SP1的PEB结构》
其中JIURL写的那篇是我到现在看到最详细的了。但是他们都没有给出具体的编程实现。所以在这里我就实现了一下PEB结构修改算是一个小小补充吧:)。下面是我的实现代码。关于原理我在里就不多说了,原理的东西可以看上面两个大牛的文章。
代码如下:
CODE:
WIN2K SP4+VC6
//
//write by Gxter
//peb.h
//
//以下就是PEB的数据组织结构了
typedef void (*PPEBLOCKROUTINE)(PVOID PebLock);
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _RTL_DRIVE_LETTER_CURDIR {
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
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_MODULE {
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
PVOID ConsoleHandle;
ULONG ConsoleFlags;
HANDLE StdInputHandle;
HANDLE StdOutputHandle;
HANDLE StdErrorHandle;
UNICODE_STRING CurrentDirectoryPath;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingPositionLeft;
ULONG StartingPositionTop;
ULONG Width;
ULONG Height;
ULONG CharWidth;
ULONG CharHeight;
ULONG ConsoleTextAttributes;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopName;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB_FREE_BLOCK {
struct _PEB_FREE_BLOCK *Next;
ULONG Size;
} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PPEBLOCKROUTINE FastPebLockRoutine;
PPEBLOCKROUTINE FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID *KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PPEB_FREE_BLOCK FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID *ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID **ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, *PPEB;
//------------------------------------------the--------------end------------
//
//write by Gxter
//peb.cpp
//
/*
PEB(Process Environment Block)——进程环境块,存放进程信息,每个进程都有自己的 PEB 信息。
在 Win 2000 下,进程环境块的地址对于每个进程来说是固定的,在 0x7FFDF000 处,这是用户区内存,
所以程序能够直接访问。准确的 PEB 地址应从系统的 EPROCESS 结构的 1b0H 偏移处获得,
但由于 EPROCESS 在进程的核心内存区,所以程序不能直接访问。
还可以通过 TEB 结构的偏移 30H 处获得 PEB 的位置,代码如下:
mov eax,fs:[18]
mov eax,[eax+30]
*/
#include "stdio.h"
#include "windows.h"
#include "winsvc.h"
#include "peb.h"
#define LISPORT 65371
#define PATHLEN 32
int main()
{
PPEB peb;
PLDR_MODULE pMod;
char systempAth[PATHLEN*2];
char tempsystempAth[PATHLEN*2];
int i;
LPTSTR PAth;
PAth=GetCommandLine();
GetSystemDirectory(tempsystempAth,PATHLEN);
strcat(tempsystempAth,"//svchost.exe");
printf("%s/n",tempsystempAth);
//把ASCII转换为UNICODE,字符
for (i=0;i<PATHLEN;i++)
{
systempAth[i*2] = tempsystempAth[i];
systempAth[i*2+1] = 0;
}
//printf("%S/n",systempAth);
//这个地方主要是找到PEB结构的入口点:通过 TEB 结构的偏移 30H 处获得 PEB 的位置
__asm
{
mov eax,fs:0x30
mov peb,eax
}
pMod = (LDR_MODULE*)peb->LoaderData->InLoadOrderModuleList.Flink;
printf("%d/n",pMod->FullDllName.MaximumLength);
printf("%d/n",pMod->FullDllName.Length);
printf("%S/n",pMod->FullDllName.Buffer);
pMod->FullDllName.MaximumLength = 202;
pMod->FullDllName.Length = 200;
pMod->FullDllName.Buffer = (unsigned short*)systempAth;
printf("%d/n",pMod->FullDllName.MaximumLength);
printf("%d/n",pMod->FullDllName.Length);
printf("%S/n",pMod->FullDllName.Buffer);
getchar();
return 0;
}
//----------------------------the---------end-------------
例如:
《JIURL玩玩Win2k进程线程篇 PEB》
《陆麟 的 WIN2000 SP1的PEB结构》
其中JIURL写的那篇是我到现在看到最详细的了。但是他们都没有给出具体的编程实现。所以在这里我就实现了一下PEB结构修改算是一个小小补充吧:)。下面是我的实现代码。关于原理我在里就不多说了,原理的东西可以看上面两个大牛的文章。
代码如下:
CODE:
WIN2K SP4+VC6
//
//write by Gxter
//peb.h
//
//以下就是PEB的数据组织结构了
typedef void (*PPEBLOCKROUTINE)(PVOID PebLock);
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef struct _RTL_DRIVE_LETTER_CURDIR {
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
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_MODULE {
LIST_ENTRY InLoadOrderModuleList;
LIST_ENTRY InMemoryOrderModuleList;
LIST_ENTRY InInitializationOrderModuleList;
PVOID BaseAddress;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
SHORT LoadCount;
SHORT TlsIndex;
LIST_ENTRY HashTableEntry;
ULONG TimeDateStamp;
} LDR_MODULE, *PLDR_MODULE;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
PVOID ConsoleHandle;
ULONG ConsoleFlags;
HANDLE StdInputHandle;
HANDLE StdOutputHandle;
HANDLE StdErrorHandle;
UNICODE_STRING CurrentDirectoryPath;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingPositionLeft;
ULONG StartingPositionTop;
ULONG Width;
ULONG Height;
ULONG CharWidth;
ULONG CharHeight;
ULONG ConsoleTextAttributes;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopName;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB_FREE_BLOCK {
struct _PEB_FREE_BLOCK *Next;
ULONG Size;
} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK;
typedef struct _PEB {
BOOLEAN InheritedAddressSpace;
BOOLEAN ReadImageFileExecOptions;
BOOLEAN BeingDebugged;
BOOLEAN Spare;
HANDLE Mutant;
PVOID ImageBaseAddress;
PPEB_LDR_DATA LoaderData;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
PVOID SubSystemData;
PVOID ProcessHeap;
PVOID FastPebLock;
PPEBLOCKROUTINE FastPebLockRoutine;
PPEBLOCKROUTINE FastPebUnlockRoutine;
ULONG EnvironmentUpdateCount;
PVOID *KernelCallbackTable;
PVOID EventLogSection;
PVOID EventLog;
PPEB_FREE_BLOCK FreeList;
ULONG TlsExpansionCounter;
PVOID TlsBitmap;
ULONG TlsBitmapBits[0x2];
PVOID ReadOnlySharedMemoryBase;
PVOID ReadOnlySharedMemoryHeap;
PVOID *ReadOnlyStaticServerData;
PVOID AnsiCodePageData;
PVOID OemCodePageData;
PVOID UnicodeCaseTableData;
ULONG NumberOfProcessors;
ULONG NtGlobalFlag;
BYTE Spare2[0x4];
LARGE_INTEGER CriticalSectionTimeout;
ULONG HeapSegmentReserve;
ULONG HeapSegmentCommit;
ULONG HeapDeCommitTotalFreeThreshold;
ULONG HeapDeCommitFreeBlockThreshold;
ULONG NumberOfHeaps;
ULONG MaximumNumberOfHeaps;
PVOID **ProcessHeaps;
PVOID GdiSharedHandleTable;
PVOID ProcessStarterHelper;
PVOID GdiDCAttributeList;
PVOID LoaderLock;
ULONG OSMajorVersion;
ULONG OSMinorVersion;
ULONG OSBuildNumber;
ULONG OSPlatformId;
ULONG ImageSubSystem;
ULONG ImageSubSystemMajorVersion;
ULONG ImageSubSystemMinorVersion;
ULONG GdiHandleBuffer[0x22];
ULONG PostProcessInitRoutine;
ULONG TlsExpansionBitmap;
BYTE TlsExpansionBitmapBits[0x80];
ULONG SessionId;
} PEB, *PPEB;
//------------------------------------------the--------------end------------
//
//write by Gxter
//peb.cpp
//
/*
PEB(Process Environment Block)——进程环境块,存放进程信息,每个进程都有自己的 PEB 信息。
在 Win 2000 下,进程环境块的地址对于每个进程来说是固定的,在 0x7FFDF000 处,这是用户区内存,
所以程序能够直接访问。准确的 PEB 地址应从系统的 EPROCESS 结构的 1b0H 偏移处获得,
但由于 EPROCESS 在进程的核心内存区,所以程序不能直接访问。
还可以通过 TEB 结构的偏移 30H 处获得 PEB 的位置,代码如下:
mov eax,fs:[18]
mov eax,[eax+30]
*/
#include "stdio.h"
#include "windows.h"
#include "winsvc.h"
#include "peb.h"
#define LISPORT 65371
#define PATHLEN 32
int main()
{
PPEB peb;
PLDR_MODULE pMod;
char systempAth[PATHLEN*2];
char tempsystempAth[PATHLEN*2];
int i;
LPTSTR PAth;
PAth=GetCommandLine();
GetSystemDirectory(tempsystempAth,PATHLEN);
strcat(tempsystempAth,"//svchost.exe");
printf("%s/n",tempsystempAth);
//把ASCII转换为UNICODE,字符
for (i=0;i<PATHLEN;i++)
{
systempAth[i*2] = tempsystempAth[i];
systempAth[i*2+1] = 0;
}
//printf("%S/n",systempAth);
//这个地方主要是找到PEB结构的入口点:通过 TEB 结构的偏移 30H 处获得 PEB 的位置
__asm
{
mov eax,fs:0x30
mov peb,eax
}
pMod = (LDR_MODULE*)peb->LoaderData->InLoadOrderModuleList.Flink;
printf("%d/n",pMod->FullDllName.MaximumLength);
printf("%d/n",pMod->FullDllName.Length);
printf("%S/n",pMod->FullDllName.Buffer);
pMod->FullDllName.MaximumLength = 202;
pMod->FullDllName.Length = 200;
pMod->FullDllName.Buffer = (unsigned short*)systempAth;
printf("%d/n",pMod->FullDllName.MaximumLength);
printf("%d/n",pMod->FullDllName.Length);
printf("%S/n",pMod->FullDllName.Buffer);
getchar();
return 0;
}
//----------------------------the---------end-------------