[转载]PEB 改变进程名 实现“穿透”防火墙
<DIV class=postTitle>信息来源:<U><FONT color=#800080>ZwelL’s blog</FONT></U></DIV><DIV class=postTitle></DIV>
<DIV class=postTitle><A href="http://blog.donews.com/zwell/archive/2005/10/21/596154.aspx">通过 PEB 改变进程名,实现“穿透”防火墙</A> </DIV>
<DIV class=postText>
<P>作者:[四不象] </P>
<P class=text>PEB(Process Environment Block)——进程环境块,存放进程信息,每个进程都有自己的 PEB 信息。在 Win 2000 下,进程环境块的地址对于每个进程来说是固定的,在 0x7FFDF000 处,这是用户区内存,所以程序能够直接访问。准确的 PEB 地址应从系统的 EPROCESS 结构的 1b0H 偏移处获得,但由于 EPROCESS 在进程的核心内存区,所以程序不能直接访问。还可以通过 TEB 结构的偏移 30H 处获得 PEB 的位置,代码如下: <BR>mov eax,fs:[18]<BR>mov eax,[eax+30]<BR>PEB 及其相关结构如下:<BR>typedef void (*PPEBLOCKROUTINE)(PVOID PebLock); <BR><BR>typedef struct _UNICODE_STRING {<BR>USHORT Length;<BR>USHORT MaximumLength;<BR>PWSTR Buffer;<BR>} UNICODE_STRING, *PUNICODE_STRING;<BR><BR>typedef struct _RTL_DRIVE_LETTER_CURDIR {<BR>USHORT Flags;<BR>USHORT Length;<BR>ULONG TimeStamp;<BR>UNICODE_STRING DosPath;<BR>} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;<BR><BR>typedef struct _PEB_LDR_DATA {<BR>ULONG Length;<BR>BOOLEAN Initialized;<BR>PVOID SsHandle;<BR>LIST_ENTRY InLoadOrderModuleList;<BR>LIST_ENTRY InMemoryOrderModuleList;<BR>LIST_ENTRY InInitializationOrderModuleList;<BR>} PEB_LDR_DATA, *PPEB_LDR_DATA;<BR><BR>typedef struct _LDR_MODULE {<BR>LIST_ENTRY InLoadOrderModuleList;<BR>LIST_ENTRY InMemoryOrderModuleList;<BR>LIST_ENTRY InInitializationOrderModuleList;<BR>PVOID BaseAddress;<BR>PVOID EntryPoint;<BR>ULONG SizeOfImage;<BR>UNICODE_STRING FullDllName;<BR>UNICODE_STRING BaseDllName;<BR>ULONG Flags;<BR>SHORT LoadCount;<BR>SHORT TlsIndex;<BR>LIST_ENTRY HashTableEntry;<BR>ULONG TimeDateStamp;<BR>} LDR_MODULE, *PLDR_MODULE;<BR><BR>typedef struct _RTL_USER_PROCESS_PARAMETERS {<BR>ULONG MaximumLength;<BR>ULONG Length;<BR>ULONG Flags;<BR>ULONG DebugFlags;<BR>PVOID ConsoleHandle;<BR>ULONG ConsoleFlags;<BR>HANDLE StdInputHandle;<BR>HANDLE StdOutputHandle;<BR>HANDLE StdErrorHandle;<BR>UNICODE_STRING CurrentDirectoryPath;<BR>HANDLE CurrentDirectoryHandle;<BR>UNICODE_STRING DllPath;<BR>UNICODE_STRING ImagePathName;<BR>UNICODE_STRING CommandLine;<BR>PVOID Environment;<BR>ULONG StartingPositionLeft;<BR>ULONG StartingPositionTop;<BR>ULONG Width;<BR>ULONG Height;<BR>ULONG CharWidth;<BR>ULONG CharHeight;<BR>ULONG ConsoleTextAttributes;<BR>ULONG WindowFlags;<BR>ULONG ShowWindowFlags;<BR>UNICODE_STRING WindowTitle;<BR>UNICODE_STRING DesktopName;<BR>UNICODE_STRING ShellInfo;<BR>UNICODE_STRING RuntimeData;<BR>RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];<BR>} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;<BR><BR>typedef struct _PEB_FREE_BLOCK {<BR>struct _PEB_FREE_BLOCK *Next;<BR>ULONG Size;<BR>} PEB_FREE_BLOCK, *PPEB_FREE_BLOCK;<BR><BR>typedef struct _PEB {<BR>BOOLEAN InheritedAddressSpace;<BR>BOOLEAN ReadImageFileExecOptions;<BR>BOOLEAN BeingDebugged;<BR>BOOLEAN Spare;<BR>HANDLE Mutant;<BR>PVOID ImageBaseAddress;<BR>PPEB_LDR_DATA LoaderData;<BR>PRTL_USER_PROCESS_PARAMETERS ProcessParameters;<BR>PVOID SubSystemData;<BR>PVOID ProcessHeap;<BR>PVOID FastPebLock;<BR>PPEBLOCKROUTINE FastPebLockRoutine;<BR>PPEBLOCKROUTINE FastPebUnlockRoutine;<BR>ULONG EnvironmentUpdateCount;<BR>PVOID *KernelCallbackTable;<BR>PVOID EventLogSection;<BR>PVOID EventLog;<BR>PPEB_FREE_BLOCK FreeList;<BR>ULONG TlsExpansionCounter;<BR>PVOID TlsBitmap;<BR>ULONG TlsBitmapBits[0x2];<BR>PVOID ReadOnlySharedMemoryBase;<BR>PVOID ReadOnlySharedMemoryHeap;<BR>PVOID *ReadOnlyStaticServerData;<BR>PVOID AnsiCodePageData;<BR>PVOID OemCodePageData;<BR>PVOID UnicodeCaseTableData;<BR>ULONG NumberOfProcessors;<BR>ULONG NtGlobalFlag;<BR>BYTE Spare2[0x4];<BR>LARGE_INTEGER CriticalSectionTimeout;<BR>ULONG HeapSegmentReserve;<BR>ULONG HeapSegmentCommit;<BR>ULONG HeapDeCommitTotalFreeThreshold;<BR>ULONG HeapDeCommitFreeBlockThreshold;<BR>ULONG NumberOfHeaps;<BR>ULONG MaximumNumberOfHeaps;<BR>PVOID **ProcessHeaps;<BR>PVOID GdiSharedHandleTable;<BR>PVOID ProcessStarterHelper;<BR>PVOID GdiDCAttributeList;<BR>PVOID LoaderLock;<BR>ULONG OSMajorVersion;<BR>ULONG OSMinorVersion;<BR>ULONG OSBuildNumber;<BR>ULONG OSPlatformId;<BR>ULONG ImageSubSystem;<BR>ULONG ImageSubSystemMajorVersion;<BR>ULONG ImageSubSystemMinorVersion;<BR>ULONG GdiHandleBuffer[0x22];<BR>ULONG PostProcessInitRoutine;<BR>ULONG TlsExpansionBitmap;<BR>BYTE TlsExpansionBitmapBits[0x80];<BR>ULONG SessionId;<BR>} PEB, *PPEB;<BR><BR>PEB 结构中的 PPEB_LDR_DATA 是一个指向 PEB_LDR_DATA 的指针,PEB_LDR_DATA 结构中有 3 个 LIST_ENTRY 的指针,分别是 InLoadOrderModuleList; InMemoryOrderModuleList; InInitializationOrderModuleList,如此循环。可以通过这三个 LIST_ENTRY 结构来遍历进程加载的模块。LDR_MODULE 结构中的 FullDllName 成员便是一个包含模块名信息的 UNICODE_STRIN 结构,它的成员 Buffer 即是指向存放模块名的 UNICODE 字符串指针。还有要注意的是,RTL_USER_PROCESS_PARAMETERS 结构中的 ImagePathName.Buffer 和 LoaderData->InLoadOrderModuleList.Flink->FullDllName.Buffer 指向的其实是同一内存。 <BR><BR></P>
<CENTER><IMG alt="" src="http://www.20cn.net/%7Etabris17/article/p025%5B1%5D.jpg"></CENTER><BR><BR>在 Windows 2000 下,枚举系统进程的方法无外乎通过 Tool Help 函数,或是 PSAPI 函数。这两类函数虽然接口不同,但最后还是通过调用 NTDLL.DLL 中导出的 NtQuerySystemInformation 函数来实现的。这些函数最终是通过 LDR_MODULE 中指向的那些模块信息来实现进程和模块名字查询的。所以,只要修改 LDR_MODULE 指向的那些信息就能实现改变进程名或模块名。注意那些字符串都是 unicode 形式的,改的时候别忘了。 <BR><BR>
<CENTER><IMG alt="" src="http://www.20cn.net/%7Etabris17/article/p025%5B3%5D.jpg"></CENTER><BR><BR>这样改过之后虽然能够骗过 EnumProcessModules 和 Module32First、Module32Next 函数,但若使用 Process32Next、Process32First 函数,PROCESSENTRY32 结构中的 szExeFile 还是会如实的返回 EXE 文件名,如此一来,在“windows 任务管理器”里就穿邦了,即便你改了 BaseDllName 也没用。别急,当然还是有办法改的。不知诸位有没有注意到,用 Delphi 编译出来的可执行文件,如果你没改工程名的话,无论你怎么改可执行文件的文件名,在“windows 任务管理器”中总是显示“project1.exe”,具体什么原理我也不清楚。哪位有兴趣可以反汇编一下,看看具体是如何实现的,我的汇编功底太差了。 <BR><BR>
<CENTER><IMG alt="" src="http://www.20cn.net/%7Etabris17/article/p025%5B2%5D.jpg"></CENTER><BR><BR>不过这样就够了,你可以做个试验,用以上方法改变一个有上网请求的进程的 ImagePathName,然后看看防火墙有什么反映。果然,被骗过去了。用这个方法就可以“穿透”防火墙了。 <BR><BR>
<CENTER><IMG alt="" src="http://www.20cn.net/%7Etabris17/article/p025%5B4%5D.jpg"></CENTER><BR><BR>那具体应该改为哪个程序名呢?在 windows 2000 下,C:\WINNT\system32\services.exe 负责DNS解析等任务,总是被允许上网的,所以改成“C:\WINNT\system32\services.exe”就可以了。 <BR></DIV> 文章中提到的察看工具。MemNerv
页:
[1]