首先对被我误导的人说声对不起了。我在论坛中发的那篇贴(用户态隐藏进程的通用版本)真是乱七八糟(-_-我也是受害者)。在XP和WINDOWS 2003中用那种方法都是行不通的,而且在20043中的偏移也是错的。这里我先把XPSP2和2003中的EPROCESS整理出来给大家看一下:
typedef struct _EPROCESS_2K3 { /*+0x000*/ KPROCESS_2K3 Pcb; /*+0x06c*/ EX_PUSH_LOCK ProcessLock; /*+0x070*/ LARGE_INTEGER CreateTime; /*+0x078*/ LARGE_INTEGER ExitTime; /*+0x080*/ EX_RUNDOWN_REF RundownProtect; /*+0x084*/ PVOID UniqueProcessId; /*+0x088*/ LIST_ENTRY ActiveProcessLinks; /*+0x090*/ ULONG QuotaUsage[3]; /*+0x09c*/ ULONG QuotaPeak[3]; /*+0x0a8*/ ULONG CommitCharge; /*+0x0ac*/ ULONG PeakVirtualSize; /*+0x0b0*/ ULONG VirtualSize; /*+0x0b4*/ LIST_ENTRY SessionProcessLinks; /*+0x0bc*/ PVOID DebugPort; /*+0x0c0*/ PVOID ExceptionPort; /*+0x0c4*/ PHANDLE_TABLE ObjectTable; /*+0x0c8*/ EX_FAST_REF Token; /*+0x0cc*/ ULONG WorkingSetPage; /*+0x0d0*/ KGUARDED_MUTEX AddressCreationLock; /*+0x0f0*/ KSPIN_LOCK HyperSpaceLock; /*+0x0f4*/ PETHREAD_2K3 ForkInProgress; /*+0x0f8*/ ULONG HardwareTrigger; /*+0x0fc*/ PMM_AVL_TABLE PhysicalVadRoot; /*+0x100*/ PVOID CloneRoot; /*+0x104*/ ULONG NumberOfPrivatePages; /*+0x108*/ ULONG NumberOfLockedPages; /*+0x10c*/ PVOID Win32Process; /*+0x110*/ PEJOB Job; /*+0x114*/ PSECTION_OBJECT SectionObject; /*+0x118*/ PVOID SectionBaseAddress; /*+0x11c*/ PEPROCESS_QUOTA_BLOCK QuotaBlock; /*+0x120*/ PPAGEFAULT_HISTORY WorkingSetWatch; /*+0x124*/ PVOID Win32WindowStation; /*+0x128*/ PVOID InheritedFromUniqueProcessId; /*+0x12c*/ PVOID LdtInformation; /*+0x130*/ PVOID VadFreeHint; /*+0x134*/ PVOID VdmObjects; /*+0x138*/ PVOID DeviceMap; /*+0x13c*/ PVOID Spare0[3]; union { /*+0x148*/HARDWARE_PTE PageDirectoryPte; /*+0x148*/ULONGLONG Filler; }; /*+0x150*/ PVOID Session; /*+0x154*/ UCHAR ImageFileName[16]; /*+0x164*/ LIST_ENTRY JobLinks; /*+0x16c*/ PVOID LockedPagesList; /*+0x170*/ LIST_ENTRY ThreadListHead; /*+0x178*/ PVOID SecurityPort; /*+0x17c*/ PVOID PaeTop; /*+0x180*/ ULONG ActiveThreads; /*+0x184*/ ULONG GrantedAccess; /*+0x188*/ ULONG DefaultHardErrorProcessing; /*+0x18c*/ NTSTATUS LastThreadExitStatus; /*+0x190*/ PPEB Peb; /*+0x194*/ EX_FAST_REF PrefetchTrace; /*+0x198*/ LARGE_INTEGER ReadOperationCount; /*+0x1a0*/ LARGE_INTEGER WriteOperationCount; /*+0x1a8*/ LARGE_INTEGER OtherOperationCount; /*+0x1b0*/ LARGE_INTEGER ReadTransferCount; /*+0x1b8*/ LARGE_INTEGER WriteTransferCount; /*+0x1c0*/ LARGE_INTEGER OtherTransferCount; /*+0x1c8*/ ULONG CommitChargeLimit; /*+0x1cc*/ ULONG CommitChargePeak; /*+0x1d0*/ PVOID AweInfo; /*+0x1d4*/ SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo; /*+0x1d8*/ MMSUPPORT_2K3 Vm; /*+0x238*/ LIST_ENTRY MmProcessLinks; /*+0x240*/ ULONG ModifiedPageCount; /*+0x244*/ ULONG JobStatus; union{ /*+0x248*/ ULONG Flags; struct{ /*+0x248*/ ULONG CreateReported : 1; /*+0x248*/ ULONG NoDebugInherit : 1; /*+0x248*/ ULONG ProcessExiting : 1; /*+0x248*/ ULONG ProcessDelete : 1; /*+0x248*/ ULONG Wow64SplitPages : 1; /*+0x248*/ ULONG VmDeleted : 1; /*+0x248*/ ULONG OutswapEnabled : 1; /*+0x248*/ ULONG Outswapped : 1; /*+0x248*/ ULONG ForkFailed : 1; /*+0x248*/ ULONG Wow64VaSpace4Gb : 1; /*+0x248*/ ULONG AddressSpaceInitialized :2; /*+0x248*/ ULONG SetTimerResolution : 1; /*+0x248*/ ULONG BreakOnTermination : 1; /*+0x248*/ ULONG SessionCreationUnderway :1; /*+0x248*/ ULONG WriteWatch : 1; /*+0x248*/ ULONG ProcessInSession : 1; /*+0x248*/ ULONG OverrideAddressSpace : 1; /*+0x248*/ ULONG HasAddressSpace : 1; /*+0x248*/ ULONG LaunchPrefetched : 1; /*+0x248*/ ULONG InjectInpageErrors : 1; /*+0x248*/ ULONG VmTopDown : 1; /*+0x248*/ ULONG ImageNotifyDone : 1; /*+0x248*/ ULONG PdeUpdateNeeded : 1; /*+0x248*/ ULONG VdmAllowed : 1; /*+0x248*/ ULONG Unused : 7; }; }; /*+0x24c*/ NTSTATUS ExitStatus; /*+0x250*/ USHORT NextPageColor; union { struct { /*+0x252*/ UCHAR SubSystemMinorVersion; /*+0x253*/ UCHAR SubSystemMajorVersion; }; /*+0x252*/ USHORT SubSystemVersion; };
/*+0x254*/ UCHAR PriorityClass; /*+0x258*/ MM_AVL_TABLE VadRoot; } EPROCESS_2K3, *PEPROCESS_2K3;
typedef struct _EPROCESS_XP_SP2 { /*+0x000*/_KPROCESS_XP Pcb; /*+0x06c*/_EX_PUSH_LOCK ProcessLock; /*+0x070*/_LARGE_INTEGER CreateTime; /*+0x078*/_LARGE_INTEGER ExitTime; /*+0x080*/_EX_RUNDOWN_REF RundownProtect; /*+0x084*/PVOID UniqueProcessId; /*+0x088*/_LIST_ENTRY ActiveProcessLinks; /*+0x090*/ULONG QuotaUsage[3]; /*+0x09c*/ULONG QuotaPeak[3]; /*+0x0a8*/ULONG CommitCharge; /*+0x0ac*/ULONG PeakVirtualSize; /*+0x0b0*/ULONG VirtualSize; /*+0x0b4*/_LIST_ENTRY SessionProcessLinks; /*+0x0bc*/PVOID DebugPort; /*+0x0c0*/PVOID ExceptionPort; /*+0x0c4*/PHANDLE_TABLE ObjectTable; /*+0x0c8*/_EX_FAST_REF Token; /*+0x0cc*/_FAST_MUTEX WorkingSetLock; /*+0x0ec*/ULONG WorkingSetPage; /*+0x0f0*/_FAST_MUTEX AddressCreationLock; /*+0x110*/ULONG HyperSpaceLock; /*+0x114*/PETHREAD ForkInProgress; /*+0x118*/ULONG HardwareTrigger; /*+0x11c*/PVOID VadRoot; /*+0x120*/PVOID VadHint; /*+0x124*/PVOID CloneRoot; /*+0x128*/ULONG NumberOfPrivatePages; /*+0x12c*/ULONG NumberOfLockedPages; /*+0x130*/PVOID Win32Process; /*+0x134*/PEJOB Job; /*+0x138*/PVOID SectionObject; /*+0x13c*/PVOID SectionBaseAddress; /*+0x140*/PEPROCESS_QUOTA_BLOCK QuotaBlock; /*+0x144*/PPAGEFAULT_HISTORY WorkingSetWatch; /*+0x148*/PVOID Win32WindowStation; /*+0x14c*/PVOID InheritedFromUniqueProcessId; /*+0x150*/PVOID LdtInformation; /*+0x154*/PVOID VadFreeHint; /*+0x158*/PVOID VdmObjects; /*+0x15c*/PVOID DeviceMap; /*+0x160*/_LIST_ENTRY PhysicalVadList; /*+0x168*/_HARDWARE_PTE PageDirectoryPte; /*+0x168*/Uint8B Filler; /*+0x170*/PVOID Session; /*+0x174*/UChar ImageFileName[16]; /*+0x184*/_LIST_ENTRY JobLinks; /*+0x18c*/PVOID LockedPagesList; /*+0x190*/_LIST_ENTRY ThreadListHead; /*+0x198*/PVOID SecurityPort; /*+0x19c*/PVOID PaeTop; /*+0x1a0*/ULONG ActiveThreads; /*+0x1a4*/ULONG GrantedAccess; /*+0x1a8*/ULONG DefaultHardErrorProcessing; /*+0x1ac*/Int4B LastThreadExitStatus; /*+0x1b0*/Ptr32 _PEB Peb; /*+0x1b4*/_EX_FAST_REF PrefetchTrace; /*+0x1b8*/_LARGE_INTEGER ReadOperationCount; /*+0x1c0*/_LARGE_INTEGER WriteOperationCount; /*+0x1c8*/_LARGE_INTEGER OtherOperationCount; /*+0x1d0*/_LARGE_INTEGER ReadTransferCount; /*+0x1d8*/_LARGE_INTEGER WriteTransferCount; /*+0x1e0*/_LARGE_INTEGER OtherTransferCount; /*+0x1e8*/ULONG CommitChargeLimit; /*+0x1ec*/ULONG CommitChargePeak; /*+0x1f0*/PVOID AweInfo; /*+0x1f4*/_SE_AUDIT_PROCESS_CREATION_INFO SeAuditProcessCreationInfo; /*+0x1f8*/_MMSUPPORT Vm; /*+0x238*/ULONG LastFaultCount; /*+0x23c*/ULONG ModifiedPageCount; /*+0x240*/ULONG NumberOfVads; /*+0x244*/ULONG JobStatus; /*+0x248*/ULONG Flags; /*+0x248*/ULONG CreateReported : 1; /*+0x248*/ULONG NoDebugInherit : 1; /*+0x248*/ULONG ProcessExiting : 1; /*+0x248*/ULONG ProcessDelete : 1; /*+0x248*/ULONG Wow64SplitPages : 1; /*+0x248*/ULONG VmDeleted : 1; /*+0x248*/ULONG OutswapEnabled : 1; /*+0x248*/ULONG Outswapped : 1; /*+0x248*/ULONG ForkFailed : 1; /*+0x248*/ULONG HasPhysicalVad : 1; /*+0x248*/ULONG AddressSpaceInitialized : 2; /*+0x248*/ULONG SetTimerResolution : 1; /*+0x248*/ULONG BreakOnTermination : 1; /*+0x248*/ULONG SessionCreationUnderway : 1; /*+0x248*/ULONG WriteWatch : 1; /*+0x248*/ULONG ProcessInSession : 1; /*+0x248*/ULONG OverrideAddressSpace : 1; /*+0x248*/ULONG HasAddressSpace : 1; /*+0x248*/ULONG LaunchPrefetched : 1; /*+0x248*/ULONG InjectInpageErrors : 1; /*+0x248*/ULONG VmTopDown : 1; /*+0x248*/ULONG Unused3 : 1; /*+0x248*/ULONG Unused4 : 1; /*+0x248*/ULONG VdmAllowed : 1; /*+0x248*/ULONG Unused : 5; /*+0x248*/ULONG Unused1 : 1; /*+0x248*/ULONG Unused2 : 1; /*+0x24c*/Int4B ExitStatus; /*+0x250*/Uint2B NextPageColor; /*+0x252*/UChar SubSystemMinorVersion; /*+0x253*/UChar SubSystemMajorVersion; /*+0x252*/Uint2B SubSystemVersion; /*+0x254*/UChar PriorityClass; /*+0x255*/UChar WorkingSetAcquiredUnsafe; /*+0x258*/ULONG Cookie; }EPROCESS_XP_SP2, *PEPROCESS_XP_SP2
关于如何在xp和2003中读写内核空间,TK大哥已经说的很清楚了,用ZwSystemDebugControl函数的8,9调用号就可以了。 这里给大家一个写的示例程序,大家改一下放到程序中,再做一下系统的判断就可以达到通用性了。
/* Write data in kernel POC Author:ZwelL Idea from:TK */ #include <windows.h> #include <Aclapi.h> #include <stdio.h>
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) typedef LONG NTSTATUS;
typedef struct _MEMORY_CHUNKS { ULONG Address; PVOID Data; ULONG Length; }MEMORY_CHUNKS, *PMEMORY_CHUNKS;
typedef NTSTATUS (NTAPI * PZwSystemDebugControl) ( int ControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, PULONG ReturnLength );
HMODULE g_hNtDLL = NULL;
PZwSystemDebugControl ZwSystemDebugControl = NULL;
BOOL InitNTDLL() { g_hNtDLL = LoadLibrary( "ntdll.dll" ); if ( !g_hNtDLL ) { return FALSE; }
ZwSystemDebugControl = (PZwSystemDebugControl)GetProcAddress (g_hNtDLL, "ZwSystemDebugControl");
return TRUE; }
VOID CloseNTDLL() { if(g_hNtDLL != NULL) { FreeLibrary(g_hNtDLL); } }
BOOL EnablePrivilege (PCSTR name) { HANDLE hToken; BOOL rv; TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} }; LookupPrivilegeValue ( 0, name, &priv.Privileges[0].Luid ); OpenProcessToken( GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, &hToken ); AdjustTokenPrivileges ( hToken, FALSE, &priv, sizeof priv, 0, 0 ); rv = GetLastError () == ERROR_SUCCESS; CloseHandle (hToken); return rv; }
int main(int argc, char **argv) { if (InitNTDLL()) { EnablePrivilege(SE_DEBUG_NAME); MEMORY_CHUNKS QueryBuff; ULONG ReturnLength; char *Buff= "\x11\x11\x11\x11";
QueryBuff.Address = (ULONG)0x804ed5cc; //在2003中是第一个服务调用号的函数指针,指向80592290 //大家可以改成链表的地址 QueryBuff.Data = Buff; QueryBuff.Length = 0x4; ZwSystemDebugControl ( 0x9, &QueryBuff, sizeof(MEMORY_CHUNKS), //必须是0x0C NULL, 0, &ReturnLength ); CloseNTDLL(); }
return 0; }
这里我还对TK大哥在04峰会上讲的内容做了验证,发现SessionProcessLinks在XP和2003中都是可以用来权举进程的,但是在2000中都为0x00000000, 也就是说,在2000中不能通过它进行进程检查了,只能通过WorkingSetExpansionLinks来权举进程。这里TK大哥也没做说明,前面一直没怀疑过TK大哥的准确性, 花了很长时间去执行,都没成功,用WINDBG一看就出来了。哎,看来什么事还得自己验证一下啊。5555。。。下面是对TK大哥讲的内容的实现代码:
/* 用ring3代码枚举Windows进程的演示代码 Enum process in ring3 POC Author:ZwelL Idea from:TK */ #include <windows.h> #include <Aclapi.h> #include <stdio.h>
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) #define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L) #define BASEADDRLEN 10
#define W2K_SESSION_LST_OFFSET 0X118 #define WXP_SESSION_LST_OFFSET 0X0b4 #define W2K3_SESSION_LST_OFFSET 0X0b4
#define W2K_ACTIVE_LST_OFFSET 0X0a0 #define WXP_ACTIVE_LST_OFFSET 0X088 #define W2K3_ACTIVE_LST_OFFSET 0X088
#define W2K_SESSION_TO_NAME_OFFSET 0X1fc-0x118 #define WXP_SESSION_TO_NAME_OFFSET 0X0C0 #define W2K3_SESSION_TO_NAME_OFFSET 0X154-0XB4
#define W2K_ACTIVE_LST_TO_NAME_OFFSET W2K_SESSION_TO_NAME_OFFSET+W2K_SESSION_LST_OFFSET-W2K_ACTIVE_LST_OFFSET #define WXP_ACTIVE_LST_TO_NAME_OFFSET WXP_SESSION_TO_NAME_OFFSET+WXP_SESSION_LST_OFFSET-WXP_ACTIVE_LST_OFFSET #define W2K3_ACTIVE_LST_TO_NAME_OFFSET W2K3_SESSION_TO_NAME_OFFSET+W2K3_SESSION_LST_OFFSET-W2K3_ACTIVE_LST_OFFSET
#define W2K_WORK_LST_OFFSET 0X0f4 #define W2K_IMAGE_NAME_OFFSET 0X1fc
typedef LONG NTSTATUS;
typedef struct _UNICODE_STRING { USHORT Length; USHORT MaximumLength; PWSTR Buffer; } UNICODE_STRING, *PUNICODE_STRING;
typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; PVOID SecurityQualityOfService; } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
typedef struct _SYSTEM_MODULE_INFORMATION { ULONG Reserved[2]; PVOID Base; ULONG Size; ULONG Flags; USHORT Index; USHORT Unknown; USHORT LoadCount; USHORT ModuleNameOffset; CHAR ImageName[256]; } SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct _MEMORY_CHUNKS { ULONG Address; PVOID Data; ULONG Length; }MEMORY_CHUNKS, *PMEMORY_CHUNKS;
typedef enum _SYSDBG_COMMAND { //以下5个在Windows NT各个版本上都有 SysDbgGetTraceInformation = 1, SysDbgSetInternalBreakpoint = 2, SysDbgSetSpecialCall = 3, SysDbgClearSpecialCalls = 4, SysDbgQuerySpecialCalls = 5,
// 以下是NT 5.1 新增的 SysDbgDbgBreakPointWithStatus = 6,
//获取KdVersionBlock SysDbgSysGetVersion = 7,
//从内核空间拷贝到用户空间,或者从用户空间拷贝到用户空间 //但是不能从用户空间拷贝到内核空间 SysDbgCopyMemoryChunks_0 = 8, //SysDbgReadVirtualMemory = 8,
//从用户空间拷贝到内核空间,或者从用户空间拷贝到用户空间 //但是不能从内核空间拷贝到用户空间 SysDbgCopyMemoryChunks_1 = 9, //SysDbgWriteVirtualMemory = 9,
//从物理地址拷贝到用户空间,不能写到内核空间 SysDbgCopyMemoryChunks_2 = 10, //SysDbgReadVirtualMemory = 10,
//从用户空间拷贝到物理地址,不能读取内核空间 SysDbgCopyMemoryChunks_3 = 11, //SysDbgWriteVirtualMemory = 11,
//读写处理器相关控制块 SysDbgSysReadControlSpace = 12, SysDbgSysWriteControlSpace = 13,
//读写端口 SysDbgSysReadIoSpace = 14, SysDbgSysWriteIoSpace = 15,
//分别调用RDMSR@4和_WRMSR@12 SysDbgSysReadMsr = 16, SysDbgSysWriteMsr = 17,
//读写总线数据 SysDbgSysReadBusData = 18, SysDbgSysWriteBusData = 19,
SysDbgSysCheckLowMemory = 20,
// 以下是NT 5.2 新增的
//分别调用_KdEnableDebugger@0和_KdDisableDebugger@0 SysDbgEnableDebugger = 21, SysDbgDisableDebugger = 22, //获取和设置一些调试相关的变量 SysDbgGetAutoEnableOnEvent = 23, SysDbgSetAutoEnableOnEvent = 24, SysDbgGetPitchDebugger = 25, SysDbgSetDbgPrintBufferSize = 26, SysDbgGetIgnoreUmExceptions = 27, SysDbgSetIgnoreUmExceptions = 28 } SYSDBG_COMMAND, *PSYSDBG_COMMAND;
typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, SystemProcessorInformation, SystemPerformanceInformation, SystemTimeOfDayInformation, SystemNotImplemented1, SystemProcessesAndThreadsInformation, SystemCallCounts, SystemConfigurationInformation, SystemProcessorTimes, SystemGlobalFlag, SystemNotImplemented2, SystemModuleInformation, SystemLockInformation, SystemNotImplemented3, SystemNotImplemented4, SystemNotImplemented5, SystemHandleInformation, SystemObjectInformation, SystemPagefileInformation, SystemInstructionEmulationCounts, SystemInvalidInfoClass1, SystemCacheInformation, SystemPoolTagInformation, SystemProcessorStatistics, SystemDpcInformation, SystemNotImplemented6, SystemLoadImage, SystemUnloadImage, SystemTimeAdjustment, SystemNotImplemented7, SystemNotImplemented8, SystemNotImplemented9, SystemCrashDumpInformation, SystemExceptionInformation, SystemCrashDumpStateInformation, SystemKernelDebuggerInformation, SystemContextSwitchInformation, SystemRegistryQuotaInformation, SystemLoadAndCallImage, SystemPrioritySeparation, SystemNotImplemented10, SystemNotImplemented11, SystemInvalidInfoClass2, SystemInvalidInfoClass3, SystemTimeZoneInformation, SystemLookasideInformation, SystemSetTimeSlipEvent, SystemCreateSession, SystemDeleteSession, SystemInvalidInfoClass4, SystemRangeStartInformation, SystemVerifierInformation, SystemAddVerifier, SystemSessionProcessesInformation } SYSTEM_INFORMATION_CLASS;
typedef NTSTATUS ( __stdcall *ZWQUERYSYSTEMINFORMATION ) ( IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength OPTIONAL );
typedef NTSTATUS (CALLBACK* ZWOPENSECTION)( OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes );
typedef VOID (CALLBACK* RTLINITUNICODESTRING)( IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString );
typedef NTSTATUS (NTAPI * PZwSystemDebugControl) ( SYSDBG_COMMAND ControlCode, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength, PULONG ReturnLength );
ZWQUERYSYSTEMINFORMATION ZwQuerySystemInformation = NULL; RTLINITUNICODESTRING RtlInitUnicodeString; ZWOPENSECTION ZwOpenSection; HMODULE g_hNtDLL = NULL; PVOID g_pMapPhysicalMemory = NULL; HANDLE g_hMPM = NULL;
PZwSystemDebugControl ZwSystemDebugControl = NULL;
BOOL InitNTDLL() { g_hNtDLL = LoadLibrary( "ntdll.dll" ); if ( !g_hNtDLL ) { return FALSE; }
RtlInitUnicodeString = (RTLINITUNICODESTRING)GetProcAddress( g_hNtDLL, "RtlInitUnicodeString");
ZwOpenSection = (ZWOPENSECTION)GetProcAddress( g_hNtDLL, "ZwOpenSection");
ZwQuerySystemInformation = ( ZWQUERYSYSTEMINFORMATION )GetProcAddress( g_hNtDLL, "ZwQuerySystemInformation" );
ZwSystemDebugControl = (PZwSystemDebugControl)GetProcAddress (g_hNtDLL, "ZwSystemDebugControl");
return TRUE; }
VOID CloseNTDLL() { if(g_hNtDLL != NULL) { FreeLibrary(g_hNtDLL); } }
HANDLE OpenPhysicalMemory() { NTSTATUS status; UNICODE_STRING physmemString; OBJECT_ATTRIBUTES attributes; RtlInitUnicodeString( &physmemString, L"\\Device\\PhysicalMemory" ); attributes.Length = sizeof(OBJECT_ATTRIBUTES); attributes.RootDirectory = NULL; attributes.ObjectName = &physmemString; attributes.Attributes = 0; attributes.SecurityDescriptor = NULL; attributes.SecurityQualityOfService = NULL; status = ZwOpenSection(&g_hMPM,SECTION_MAP_READ|SECTION_MAP_WRITE,&attributes); if(status == STATUS_ACCESS_DENIED){ status = ZwOpenSection(&g_hMPM,READ_CONTROL|WRITE_DAC,&attributes); //SetPhyscialMemorySectionCanBeWrited(g_hMPM); CloseHandle(g_hMPM); status =ZwOpenSection(&g_hMPM,SECTION_MAP_READ|SECTION_MAP_WRITE,&attributes); } if( !NT_SUCCESS( status )) { return NULL; } g_pMapPhysicalMemory = MapViewOfFile( g_hMPM, 4, 0, 0x30000, 0x1000); if( g_pMapPhysicalMemory == NULL ) { return NULL; } return g_hMPM; }
PVOID LinearToPhys(PULONG BaseAddress,PVOID addr) { ULONG VAddr=(ULONG)addr,PGDE,PTE,PAddr; if(VAddr>=0x80000000 && VAddr<0xa0000000) { PAddr=VAddr-0x80000000; return (PVOID)PAddr; } PGDE=BaseAddress[VAddr>>22]; if ((PGDE&1)!=0) { ULONG tmp=PGDE&0x00000080; if (tmp!=0) { PAddr=(PGDE&0xFFC00000)+(VAddr&0x003FFFFF); } else { PGDE=(ULONG)MapViewOfFile(g_hMPM, FILE_MAP_ALL_ACCESS, 0, PGDE & 0xfffff000, 0x1000); PTE=((PULONG)PGDE)[(VAddr&0x003FF000)>>12]; if ((PTE&1)!=0) { PAddr=(PTE&0xFFFFF000)+(VAddr&0x00000FFF); UnmapViewOfFile((PVOID)PGDE); } else return 0; } } else return 0;
return (PVOID)PAddr; }
BOOL EnablePrivilege (PCSTR name) { HANDLE hToken; BOOL rv; TOKEN_PRIVILEGES priv = { 1, {0, 0, SE_PRIVILEGE_ENABLED} }; LookupPrivilegeValue ( 0, name, &priv.Privileges[0].Luid ); OpenProcessToken( GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES, &hToken ); AdjustTokenPrivileges ( hToken, FALSE, &priv, sizeof priv, 0, 0 ); rv = GetLastError () == ERROR_SUCCESS; CloseHandle (hToken); return rv; }
void GetString(PVOID addr, char *returnstr) { OSVERSIONINFO OSVersionInfo; PCHAR ret;
OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&OSVersionInfo); if (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && OSVersionInfo.dwMajorVersion >= 5 && OSVersionInfo.dwMinorVersion >= 1) //Windows XP以上 { MEMORY_CHUNKS QueryBuff; ULONG ReturnLength; char Buff[0x30] = {0};
QueryBuff.Address = (ULONG)addr; QueryBuff.Data = Buff; //在此是读出缓冲 QueryBuff.Length = sizeof(Buff);
EnablePrivilege(SE_DEBUG_NAME);
ZwSystemDebugControl ( SysDbgCopyMemoryChunks_0, &QueryBuff, sizeof(MEMORY_CHUNKS), //必须是0x0C NULL, 0, &ReturnLength );
strcpy(returnstr, Buff); } else { ULONG phys=(ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory,(PVOID)addr); PULONG tmp=(PULONG)MapViewOfFile(g_hMPM, FILE_MAP_ALL_ACCESS, 0, phys & 0xfffff000, 0x1000); if (tmp==0) { printf("getdata wrong\n"); return; } strcpy(returnstr, (PCHAR)&tmp[(phys & 0xFFF)>>2]); UnmapViewOfFile(tmp); } }
ULONG GetData(PVOID addr) { OSVERSIONINFO OSVersionInfo; ULONG ret;
OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&OSVersionInfo); if (OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && OSVersionInfo.dwMajorVersion >= 5 && OSVersionInfo.dwMinorVersion >= 1) //Windows XP以上 { MEMORY_CHUNKS QueryBuff; ULONG ReturnLength; char Buff[0x300] = {0};
QueryBuff.Address = (ULONG)addr; QueryBuff.Data = Buff; //在此是读出缓冲 QueryBuff.Length = sizeof(Buff);
EnablePrivilege(SE_DEBUG_NAME);
ZwSystemDebugControl ( SysDbgCopyMemoryChunks_0, &QueryBuff, sizeof(MEMORY_CHUNKS), //必须是0x0C NULL, 0, &ReturnLength ); ret = *(PULONG)Buff; } else { ULONG phys=(ULONG)LinearToPhys((PULONG)g_pMapPhysicalMemory,(PVOID)addr); PULONG tmp=(PULONG)MapViewOfFile(g_hMPM, FILE_MAP_ALL_ACCESS, 0, phys & 0xfffff000, 0x1000); if (tmp==0) { printf("getdata wrong\n"); return 0; } ret=tmp[(phys & 0xFFF)>>2]; UnmapViewOfFile(tmp); } return ret; }
DWORD MyGetModuleBaseAddress( char * pModuleName) { PSYSTEM_MODULE_INFORMATION pSysModule;
ULONG uReturn; ULONG uCount; PCHAR pBuffer = NULL; PCHAR pName = NULL; NTSTATUS status; UINT ui;
CHAR szBuffer[BASEADDRLEN]; DWORD pBaseAddress;
status = ZwQuerySystemInformation( SystemModuleInformation, szBuffer, BASEADDRLEN, &uReturn );
pBuffer = ( PCHAR )malloc(uReturn);
if ( pBuffer ) { status = ZwQuerySystemInformation( SystemModuleInformation, pBuffer, uReturn, &uReturn );
if( NT_SUCCESS(status) ) { uCount = ( ULONG )*( ( ULONG * )pBuffer ); pSysModule = ( PSYSTEM_MODULE_INFORMATION )( pBuffer + sizeof( ULONG ) );
if(pModuleName == NULL) { for ( ui = 0; ui < uCount; ui++ ) { printf("%s \n\tBase address: 0x%08x\n", pSysModule->ImageName, pSysModule->Base);
pSysModule ++; } } else {
for ( ui = 0; ui < uCount; ui++ ) { pName = strstr( pSysModule->ImageName, pModuleName );
if( pName ) { //printf("%s \n\tBase address: 0x%08x\n", pSysModule->ImageName, pSysModule->Base); pBaseAddress = (DWORD)pSysModule->Base; free( pBuffer ); return pBaseAddress; } pSysModule ++; } } }
free( pBuffer ); }
return NULL; }
int main(int argc, char **argv) { int SESSION_TO_NAME_OFFSET=0; int SESSION_LST_OFFSET=0; int ACTIVE_LST_TO_NAME_OFFSET=0; int ACTIVE_LST_OFFSET=0; char imagename[0x30]; OSVERSIONINFO OSVersionInfo; HMODULE hDll; LPVOID lpps; PVOID firstaddr; PVOID nowaddr;
if (InitNTDLL()) { OSVersionInfo.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); GetVersionEx (&OSVersionInfo);
if (OSVersionInfo.dwMajorVersion == 5) { if(OSVersionInfo.dwMinorVersion == 0) { //SESSION_TO_NAME_OFFSET=W2K_SESSION_TO_NAME_OFFSET; //SESSION_LST_OFFSET=W2K_SESSION_LST_OFFSET; //ACTIVE_LST_TO_NAME_OFFSET=W2K_ACTIVE_LST_TO_NAME_OFFSET; //ACTIVE_LST_OFFSET=W2K_ACTIVE_LST_OFFSET; //如果用SESSIONLST的话,将会读到0x00000000 SESSION_TO_NAME_OFFSET=W2K_IMAGE_NAME_OFFSET-W2K_WORK_LST_OFFSET; SESSION_LST_OFFSET=W2K_WORK_LST_OFFSET; ACTIVE_LST_TO_NAME_OFFSET=W2K_ACTIVE_LST_TO_NAME_OFFSET; ACTIVE_LST_OFFSET=W2K_ACTIVE_LST_OFFSET;
if (OpenPhysicalMemory()==0) { printf("OpenPhysicalMemory wrong\n"); return -1; } } else if(OSVersionInfo.dwMinorVersion == 1) { SESSION_TO_NAME_OFFSET=WXP_SESSION_TO_NAME_OFFSET; SESSION_LST_OFFSET=WXP_SESSION_LST_OFFSET; ACTIVE_LST_TO_NAME_OFFSET=WXP_ACTIVE_LST_TO_NAME_OFFSET; ACTIVE_LST_OFFSET=WXP_ACTIVE_LST_OFFSET; } else if(OSVersionInfo.dwMinorVersion == 2) { SESSION_TO_NAME_OFFSET=W2K3_SESSION_TO_NAME_OFFSET; SESSION_LST_OFFSET=W2K3_SESSION_LST_OFFSET; ACTIVE_LST_TO_NAME_OFFSET=W2K3_ACTIVE_LST_TO_NAME_OFFSET; ACTIVE_LST_OFFSET=W2K3_ACTIVE_LST_OFFSET; } } else { printf("The OS version is not be supported...\n"); return -1; }
hDll = LoadLibrary("ntoskrnl.exe"); lpps = GetProcAddress(hDll, "PsInitialSystemProcess"); lpps=(LPVOID)(MyGetModuleBaseAddress("ntoskrnl.exe")+(DWORD)lpps-(DWORD)hDll); printf("PsInitialSystemProcess address : 0x%08X\n\n", lpps); FreeLibrary(hDll);
printf("OS version: %1d.%1d\n", OSVersionInfo.dwMajorVersion, OSVersionInfo.dwMinorVersion); printf("ActiveProcessLinks Offset : 0x%03X\n", ACTIVE_LST_OFFSET); if(OSVersionInfo.dwMinorVersion == 0) printf("SessionProcessLinks Offset : 0x%03X\n", SESSION_LST_OFFSET); else printf("WorkingSetExpansionLinks Offset : 0x%03X\n", SESSION_LST_OFFSET); printf("ImageFileName Offset : 0x%03X\n\n", ACTIVE_LST_OFFSET+ACTIVE_LST_TO_NAME_OFFSET); firstaddr=(LPVOID)(GetData(lpps)+ACTIVE_LST_OFFSET); //GetString((PVOID)((DWORD)firstaddr+ACTIVE_LST_TO_NAME_OFFSET),imagename); //printf("EPROCESS : 0x%08X : %s\n", (DWORD)firstaddr-ACTIVE_LST_OFFSET, imagename); if(OSVersionInfo.dwMinorVersion == 0) { firstaddr=(LPVOID)((DWORD)firstaddr-ACTIVE_LST_OFFSET+SESSION_LST_OFFSET); } else { firstaddr=(LPVOID)(GetData(firstaddr)); GetString((PVOID)((DWORD)firstaddr+ACTIVE_LST_TO_NAME_OFFSET),imagename); printf("EPROCESS : 0x%08X : %s\n", (DWORD)firstaddr-ACTIVE_LST_OFFSET, imagename); firstaddr=(LPVOID)(GetData(firstaddr)); firstaddr=(LPVOID)((DWORD)firstaddr-ACTIVE_LST_OFFSET+SESSION_LST_OFFSET); }
nowaddr=firstaddr; do { if((DWORD)nowaddr>0xffff0000) break; GetString((PVOID)((DWORD)nowaddr+SESSION_TO_NAME_OFFSET), imagename); printf("EPROCESS : 0x%08X : %s\n", (DWORD)nowaddr-SESSION_LST_OFFSET, imagename); nowaddr=(LPVOID)GetData(nowaddr); } while(firstaddr!=nowaddr && nowaddr>0); getchar(); UnmapViewOfFile(g_pMapPhysicalMemory); CloseHandle(g_hMPM); CloseNTDLL(); }
return 0; }
参考资料: 1. 用ring3代码可靠地枚举Windows进程 -TK http://www.xfocus.net/projects/Xcon/2004/Xcon2004_tk.pdf

|