A forum for reverse engineering, OS internals and malware analysis 

Discussion on reverse-engineering and debugging.
 #18144  by myid
 Mon Feb 11, 2013 8:19 am
Hello, everyone. Who can tell me the definition of WOW64_PROCESS and LDR32?
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
......
+0x318 SecurityPort : Ptr64 Void
+0x320 Wow64Process : Ptr64 Void
+0x328 ActiveThreads : Uint4B
......
+0x4c8 TimerResolutionStackRecord : Ptr64 _PO_DIAG_STACK_RECORD
nt!_PEB32
+0x000 InheritedAddressSpace : UChar
......
+0x008 ImageBaseAddress : Uint4B
+0x00c Ldr : Uint4B
+0x010 ProcessParameters : Uint4B
......
+0x240 SpareTracingBits : Pos 2, 30 Bits
 #18146  by EP_X0FF
 Mon Feb 11, 2013 11:56 am
Code: Select all
typedef struct _WOW64_PROCESS {
   PVOID Wow64;
} WOW64_PROCESS, *PWOW64_PROCESS;
Code: Select all
#define WOW64_POINTER(Type) ULONG
typedef struct _PEB_LDR_DATA32
{
	ULONG Length;
	BOOLEAN Initialized;
	WOW64_POINTER(HANDLE) SsHandle;
	LIST_ENTRY32 InLoadOrderModuleList;
	LIST_ENTRY32 InMemoryOrderModuleList;
	LIST_ENTRY32 InInitializationOrderModuleList;
	WOW64_POINTER(PVOID) EntryInProgress;
	BOOLEAN ShutdownInProgress;
	WOW64_POINTER(HANDLE) ShutdownThreadId;
} PEB_LDR_DATA32, *PPEB_LDR_DATA32;
 #18152  by myid
 Mon Feb 11, 2013 2:32 pm
EP_X0FF wrote:
Code: Select all
typedef struct _WOW64_PROCESS {
   PVOID Wow64;
} WOW64_PROCESS, *PWOW64_PROCESS;
Code: Select all
#define WOW64_POINTER(Type) ULONG
typedef struct _PEB_LDR_DATA32
{
	ULONG Length;
	BOOLEAN Initialized;
	WOW64_POINTER(HANDLE) SsHandle;
	LIST_ENTRY32 InLoadOrderModuleList;
	LIST_ENTRY32 InMemoryOrderModuleList;
	LIST_ENTRY32 InInitializationOrderModuleList;
	WOW64_POINTER(PVOID) EntryInProgress;
	BOOLEAN ShutdownInProgress;
	WOW64_POINTER(HANDLE) ShutdownThreadId;
} PEB_LDR_DATA32, *PPEB_LDR_DATA32;
I mean, how to get PEB32 from EPROCESS?
There is a function called "PsGetProcessPeb" but no function called "PsGetWow64ProcessPeb".
I use PsGetWow64Process to get the value of EPROCESS.Wow64Process, but this value is a void pointer without any type.
So I don't know how to get PEB32 by EPROCESS.Wow64Process.

My code:
PLIST_ENTRY32 ModListHead32 = 0;
PLIST_ENTRY32 Module32 = 0;
Peb = (ULONG64)PsGetProcessWow64Process(Process);
if(!Peb)
return;
KeStackAttachProcess(Process, &ks);
__try
{
Ldr = Peb + 0xC;
ProbeForRead((CONST PVOID)Ldr, 4, 4);
ModListHead32 = (PLIST_ENTRY32)(*(PULONG32)Ldr + FIELD_OFFSET(PEB_LDR_DATA32, InLoadOrderModuleList));
ProbeForRead((CONST PVOID)ModListHead32, 4, 4); DbgPrint("ModListHead32: %x",(ULONG)ModListHead32);
Module32 = (PLIST_ENTRY32)(ModListHead32->Flink);
ProbeForRead((CONST PVOID)Module32, 4, 4); DbgPrint("Module32: %x",(ULONG)Module32);
while (ModListHead32 != Module32)
{
DbgPrint("%x\n",(ULONG64)(((PLDR_DATA_TABLE_ENTRY32)Module32)->DllBase));
Module32 = (PLIST_ENTRY32)(Module32->Flink);
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
////DbgPrint("[EnumModule32]__except (EXCEPTION_EXECUTE_HANDLER)");
}
KeUnstackDetachProcess(&ks);
Last edited by myid on Mon Feb 11, 2013 3:20 pm, edited 2 times in total.
 #18155  by myid
 Mon Feb 11, 2013 3:10 pm
EP_X0FF wrote:
Code: Select all
PEPROCESS Process;
PPEB32 Peb32;

....


if (Process->Wow64Process != NULL) {
      Peb32 = (PPEB32)Process->Wow64Process->Wow64;
}

....

Hey, EP_X0FF, that is a strange problem.
Value of PEPROCESS->Wow64Process is 7efde000, value of PEPROCESS->Wow64Process->Wow64 is ffffffff00010000.
+0x2e0 ImageFileName : [15] "Dbgview.exe"
+0x2ef PriorityClass : 0x2 ''
+0x2f0 JobLinks : _LIST_ENTRY [ 0xfffffa80`0465c3a8 - 0xfffffa80`0465c3a8 ]
+0x300 LockedPagesList : (null)
+0x308 ThreadListHead : _LIST_ENTRY [ 0xfffffa80`04fa3e30 - 0xfffffa80`038c0580 ]
+0x318 SecurityPort : (null)
+0x320 Wow64Process : 0x00000000`7efde000
+0x328 ActiveThreads : 6
+0x32c ImagePathHash : 0x777efb56
+0x330 DefaultHardErrorProcessing : 1
+0x334 LastThreadExitStatus : 0
+0x338 Peb : 0x00000000`7efdf000 _PEB
ntdll!DbgBreakPoint:
00000000`777af190 cc int 3

0:003> dq 7efde000
00000000`7efde000 ffffffff`00010000 77a40200`00400000
00000000`7efde010 00000000`005f1258 77a42100`005f0000
00000000`7efde020 00000000`00000000 75d8acf0`00000001
00000000`7efde030 00000000`00000000 00000000`00040000
00000000`7efde040 1fffffff`77a44248 7efe0000`00000000
00000000`7efde050 7efe0a90`00000000 7efa0000`7efa0000
00000000`7efde060 00000002`7efd0028 00000000`00000000
00000000`7efde070 ffffe86d`079b8000 00002000`00100000
0:003> g
What the hell is going on?

No matter how, I want to enumerate 32-bit process modules.
Last edited by myid on Mon Feb 11, 2013 3:22 pm, edited 4 times in total.
 #18158  by EP_X0FF
 Mon Feb 11, 2013 3:45 pm
Well I don't see any problem. As you see it is now simple pointer to PEB32, not on struct. The code above valid for old Windows versions. You can check this with disasm, dasm NtQueryInformationProcess, see case 26.
 #18159  by myid
 Mon Feb 11, 2013 3:46 pm
EP_X0FF wrote:Well I don't see any problem. As you see it is now simple pointer to PEB32, not on struct. The code above valid for old Windows versions. You can check this with disasm, dasm NtQueryInformationProcess, see case 26.
OK, thank you.
 #18166  by rinn
 Tue Feb 12, 2013 12:46 pm
Hello,
myid wrote:But I just want to know how it works.
Yes indeed, starting from Windows Vista x64 EPROCESS->Wow64Process is no longer pointer on WOW64_PROCESS structure but simply a pointer to the PEB32.

Windows 2003 SP2
Code: Select all
PAGE:00000000006DD555                 mov     rax, [rsp+2E8h+var_2A0]
PAGE:00000000006DD55A                 mov     rcx, [rax+2A8h]
PAGE:00000000006DD561                 test    rcx, rcx
PAGE:00000000006DD564                 jz      short loc_6DD569
PAGE:00000000006DD566                 mov     r12, [rcx]
Code: Select all
  +0x2a8 Wow64Process     : Ptr64 _WOW64_PROCESS
Windows 7
Code: Select all
PAGE:000000014038E504                 mov     rcx, [rsp+468h+var_280] ; Object
PAGE:000000014038E50C                 mov     rbx, [rcx+320h]
Code: Select all
   +0x320 Wow64Process     : Ptr64 Void
Windows 8
Code: Select all
PAGE:000000014042EC7F                 mov     rcx, [rsp+4E8h+var_4A8] ; Object
PAGE:000000014042EC84                 mov     rbx, [rcx+418h]
Code: Select all
 +0x418 Wow64Process     : Ptr64 Void
Less code, less memory, faster.

Best Regards,
-rin