Trao đổi với tôi

http://www.buidao.com

1/19/10

[MASM] A Expl to get Image Path Name from PEB

Author: Benina

Download Source : http://cid-ac1f6a5fa666a923.skydrive.live.com/self.aspx/.Public/vidupeb.rar

Một ví dụ khai thác dữ liệu từ cấu trúc PEB.

Bài viết này chỉ một ví dụ đơn giản cho việc chúng ta lấy tên đường dẫn của chính chương trình và hiển thị trong một hộp MessageBox.

Như ta biết PEB có cấu trúc như sau:

struct _PEB {

0x000 BYTE InheritedAddressSpace;

0x001 BYTE ReadImageFileExecOptions;

0x002 BYTE BeingDebugged;

0x003 BYTE SpareBool;

0x004 void* Mutant;

0x008 void* ImageBaseAddress;

0x00c _PEB_LDR_DATA* Ldr;

0x010 _RTL_USER_PROCESS_PARAMETERS* ProcessParameters;

0x014 void* SubSystemData;

0x018 void* ProcessHeap;

0x01c _RTL_CRITICAL_SECTION* FastPebLock;

0x020 void* FastPebLockRoutine;

0x024 void* FastPebUnlockRoutine;

0x028 DWORD EnvironmentUpdateCount;

0x02c void* KernelCallbackTable;

0x030 DWORD SystemReserved[1];

0x034 DWORD ExecuteOptions:2;

// bit offset: 34, len=2

0x034 DWORD SpareBits:30;

// bit offset: 34, len=30

0x038 _PEB_FREE_BLOCK* FreeList;

0x03c DWORD TlsExpansionCounter;

0x040 void* TlsBitmap;

0x044 DWORD TlsBitmapBits[2];

0x04c void* ReadOnlySharedMemoryBase;

0x050 void* ReadOnlySharedMemoryHeap;

0x054 void** ReadOnlyStaticServerData;

0x058 void* AnsiCodePageData;

0x05c void* OemCodePageData;

0x060 void* UnicodeCaseTableData;

0x064 DWORD NumberOfProcessors;

0x068 DWORD NtGlobalFlag;

0x070 _LARGE_INTEGER CriticalSectionTimeout;

0x078 DWORD HeapSegmentReserve;

0x07c DWORD HeapSegmentCommit;

0x080 DWORD HeapDeCommitTotalFreeThreshold;

0x084 DWORD HeapDeCommitFreeBlockThreshold;

0x088 DWORD NumberOfHeaps;

0x08c DWORD MaximumNumberOfHeaps;

0x090 void** ProcessHeaps;

0x094 void* GdiSharedHandleTable;

0x098 void* ProcessStarterHelper;

0x09c DWORD GdiDCAttributeList;

0x0a0 void* LoaderLock;

0x0a4 DWORD OSMajorVersion;

0x0a8 DWORD OSMinorVersion;

0x0ac WORD OSBuildNumber;

0x0ae WORD OSCSDVersion;

0x0b0 DWORD OSPlatformId;

0x0b4 DWORD ImageSubsystem;

0x0b8 DWORD ImageSubsystemMajorVersion;

0x0bc DWORD ImageSubsystemMinorVersion;

0x0c0 DWORD ImageProcessAffinityMask;

0x0c4 DWORD GdiHandleBuffer[34];

0x14c void (*PostProcessInitRoutine)();

0x150 void* TlsExpansionBitmap;

0x154 DWORD TlsExpansionBitmapBits[32];

0x1d4 DWORD SessionId;

0x1d8 _ULARGE_INTEGER AppCompatFlags;

0x1e0 _ULARGE_INTEGER AppCompatFlagsUser;

0x1e8 void* pShimData;

0x1ec void* AppCompatInfo;

0x1f0 _UNICODE_STRING CSDVersion;

0x1f8 void* ActivationContextData;

0x1fc void* ProcessAssemblyStorageMap;

0x200 void* SystemDefaultActivationContextData;

0x204 void* SystemAssemblyStorageMap;

0x208 DWORD MinimumStackCommit;

};

Theo bài viết “PEB & TEB STRUCTURE” mà tôi đã viết muốn tìm base addr của PEB ta có thể coding như sau:

;-------------------------

;Get PEB of this proc

;-------------------------

assume fs: nothing

mov eax,fs:[18h]

mov edx,dword ptr [eax+30h]

Trong cấu trúc PEB, chúng ta chú ý đến thành phần:

0x010 _RTL_USER_PROCESS_PARAMETERS* ProcessParameters;

Thành phần này có cấu trúc như sau:

kd> dt nt!_RTL_USER_PROCESS_PARAMETERS

+0x000 MaximumLength : Uint4B

+0x004 Length : Uint4B

+0x008 Flags : Uint4B

+0x00c DebugFlags : Uint4B

+0x010 ConsoleHandle : Ptr32 Void

+0x014 ConsoleFlags : Uint4B

+0x018 StandardInput : Ptr32 Void

+0x01c StandardOutput : Ptr32 Void

+0x020 StandardError : Ptr32 Void

+0x024 CurrentDirectory : _CURDIR

+0x030 DllPath : _UNICODE_STRING

+0x038 ImagePathName : _UNICODE_STRING

+0x040 CommandLine : _UNICODE_STRING

+0x048 Environment : Ptr32 Void

+0x04c StartingX : Uint4B

+0x050 StartingY : Uint4B

+0x054 CountX : Uint4B

+0x058 CountY : Uint4B

+0x05c CountCharsX : Uint4B

+0x060 CountCharsY : Uint4B

+0x064 FillAttribute : Uint4B

+0x068 WindowFlags : Uint4B

+0x06c ShowWindowFlags : Uint4B

+0x070 WindowTitle : _UNICODE_STRING

+0x078 DesktopInfo : _UNICODE_STRING

+0x080 ShellInfo : _UNICODE_STRING

+0x088 RuntimeData : _UNICODE_STRING

+0x090 CurrentDirectores : [32] _RTL_DRIVE_LETTER_CURDIR

Chúng ta thấy trong cấu trúc trên có thành phần:

+0x038 ImagePathName : _UNICODE_STRING

Như chúng ta biết

;+0x038 UNICODE_STRING struct

;+0x038 _Length dw ?

; MaximumLength dw ?

;+0x03c Buffer dd ?

; UNICODE_STRING ends

Vậy Buffer tại +0x03c của cấu trúc _RTL_USER_PROCESS_PARAMETERS chứa tên đường dẫn của Image chương trình.

Bây giờ chúng ta sẽ coding như sau:

.386

.model flat, stdcall ;32 bit memory model

option casemap :none ;case sensitive

include C:\masm32\include\windows.inc

include C:\masm32\include\kernel32.inc

include C:\masm32\include\user32.inc

include \masm32\macros\macros.asm

includelib C:\masm32\lib\kernel32.lib

includelib C:\masm32\lib\user32.lib

.const

uniString dw "P","a","t","h"," ","o","f"," ","P","r","o","c",0

.data

dwPEB dd 0

dwImagePathName dd 0

lpBuffer dd 0

.data?

.code

start:

;-------------------------

;Get PEB of this proc

;-------------------------

assume fs: nothing

mov eax,fs:[18h]

mov edx,dword ptr [eax+30h]

;--------------------------------------------------------------

;Go to 0x010 _RTL_USER_PROCESS_PARAMETERS* ProcessParameters;

;--------------------------------------------------------------

mov ebx,dword ptr[edx+10h]

;----------------------------------------------------------

;Goto +0x038 ImagePathName : _UNICODE_STRING

;

;+0x038 UNICODE_STRING struct

;+0x038 _Length dw ?

; MaximumLength dw ?

;+0x03c Buffer dd ?

; UNICODE_STRING ends

;----------------------------------------------------------

mov ebx,dword ptr[ebx+3ch]

;Save PEB and addr ImagePathName

push edx

pop dwPEB

push ebx

pop dwImagePathName

invoke MessageBoxW,0,ebx,addr uniString,MB_OK

invoke wsprintf,addr lpBuffer,CTXT("Addr ImagePathName :%lx"),[dwImagePathName]

invoke MessageBox,0,addr lpBuffer,chr$("Addr ImagePathName"),MB_OK

invoke wsprintf,addr lpBuffer,CTXT("Base address PEB:%lx"),[dwPEB]

invoke MessageBox,0,addr lpBuffer,chr$("Base address PEB"),MB_OK

invoke ExitProcess,0

end start

Ghi chú:

Ở đây tôi dùng hàm MessageBoxW để hiển thị chuổi unicode

Khai báo uniString như sau để hiển thị trong MessageBoxW:

uniString dw "P","a","t","h"," ","o","f"," ","P","r","o","c",0

Benina