[solucionado] Problema con PEB

Iniciado por cuentanegra1990, 14 Julio 2015, 16:25 PM

0 Miembros y 1 Visitante están viendo este tema.

cuentanegra1990

Hola quería prestarme antes de nada, mi nombre es Ruben y soy fiel seguidor del foro desde hace ya unos cuantos años, y me veo obligado a registrarme ya que andar a solas en temas de estos es en algunas ocasiones un poco difícil.

Bueno dejo de marearos y voy al grano...



Analizando la imagen podemos ver que se obtiene el puntero al TEB, apartir de ahi nos desplazamos al PEB que es la estructura que contiene la informacion sobre los modulos cargados en memoria de ese proceso(entre ellos el que nos interesa kernel32)

luego nos desplazamos a la estructura LDR la cual tiene esta estructura:

typedef struct _PEB_LDR_DATA {
 BYTE       Reserved1[8];
 PVOID      Reserved2[3];
 LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;


Y aquí es donde me pierdo, se que tenemos que referencia a otra estructura llamada "LDR_DATA_TABLE_ENTRY" que muchas otras personas la denominan "LDR_MODULE" que es a la que finalmente tenemos que llegar para encontrar el nombre de la dll, pero tenemos que apuntar hacia ella por medio de los Flink y Blink.

Tengo que decir que hay muchísimos códigos por internet que lo único que hacen es ponerte las estructuras y ponerte como definición lo que pone en la MSDN o la wikipedia literalmente y se quedan tan panchos.

Si hay algún alma caritativa capaz de ayudarme lo agradecería.

MCKSys Argentina

Antes de ver el tema de la PEB, te recomiedo leer ésto: click (y mirar el pdf que indica ese blogpost)

Ahora, LIST_ENTRY es la struct que tiene los 2 punteros Flink y Blink. Uno apunta al siguiente elemento y el otro al anterior.

Eso es lo que no entendías o es otra cosa?

Saludos!
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


cuentanegra1990

#2
Hola MCKSys Argentina, gracias por el pdf, tras verlo esto es hasta donde yo llego a entender:

Inicio realizando un desplazamiento desde la estructura TEB hasta la estructura PEB que es la que contiene los módulos cargados:

Código (asm) [Seleccionar]
0:000> dt ntdll!_PEB
  +0x000 InheritedAddressSpace : UChar
  +0x001 ReadImageFileExecOptions : UChar
  +0x002 BeingDebugged    : UChar
  +0x003 BitField         : UChar
  +0x003 ImageUsesLargePages : Pos 0, 1 Bit
  +0x003 IsProtectedProcess : Pos 1, 1 Bit
  +0x003 IsLegacyProcess  : Pos 2, 1 Bit
  +0x003 IsImageDynamicallyRelocated : Pos 3, 1 Bit
  +0x003 SkipPatchingUser32Forwarders : Pos 4, 1 Bit
  +0x003 SpareBits        : Pos 5, 3 Bits
  +0x004 Mutant           : Ptr32 Void
  +0x008 ImageBaseAddress : Ptr32 Void
  +0x00c Ldr              : Ptr32 _PEB_LDR_DATA


El código es el siguiente:

Código (asm) [Seleccionar]
xor eax, eax
mov eax, dword ptr fs:[eax + 30h]


De este modo tengo en el registro eax un puntero hacia la estructura PEB.

El campo que nos interesa es "PPEB_LDR_DATA  Ldr" cuyo desplazamiento es 0x0C, su estructura es la siguiente:

Código (asm) [Seleccionar]
0:000> dt ntdll!_PEB_LDR_DATA
  +0x000 Length           : Uint4B
  +0x004 Initialized      : UChar
  +0x008 SsHandle         : Ptr32 Void
  +0x00c InLoadOrderModuleList : _LIST_ENTRY
  +0x014 InMemoryOrderModuleList : _LIST_ENTRY
  +0x01c InInitializationOrderModuleList : _LIST_ENTRY
  +0x024 EntryInProgress  : Ptr32 Void
  +0x028 ShutdownInProgress : UChar
  +0x02c ShutdownThreadId : Ptr32 Void


Esta estructura contiene los módulos cargados en memoria los cuales hace uso el hilo, entre ellos tendremos kernel32 que se carga con todos los procesos.

Código (asm) [Seleccionar]
mov eax, [eax + 0Ch]

Con este código tenemos en eax el puntero hacia esa estructura. A partir de aquí podemos hacer uso de tres tipo de listas diferentes para poder acceder a los módulos según la opción que mas nos interese:

1) En el orden en el que fueron cargados. (offset 0Ch)
2) En memoria. (offset 14h)
3) En modo en el que fueron inicializados. (offset 1Ch)

Dependiendo de la lista que utilicemos tendremos que hacérselo saber en el desplazacimento de este, y dependiendo de la lista que se utilice tendra unas variaciones a la hora de hacer uso de la estructura "LDR_DATA_TABLE_ENTRY" para obtener el nombre de la librería(modulo).

El código que tengo hasta aquí es el siguiente:

Código (asm) [Seleccionar]
xor eax, eax
mov eax, [fs:eax + 30h]
mov eax, [eax + 0Ch]
lea eax, [eax + 14h]


Hasta aquí tengo el registro eax apuntando hacia la lista "InMemoryOrderModuleList" a partir de aquí es donde me pierdo, según tengo entendido hay que hacer un bucle recorriendo cada una de las tablas "LDR_DATA_TABLE_ENTRY" en busca del modulo kernel32.(no se si hay una tabla para todos los módulos, o una tabla para cada modulo).

Por lo que veo en códigos que veo por Internet siguen de la siguiente manera(valido para windows 7):

Código (asm) [Seleccionar]
xor ebx, ebx               // clear ebx
mov ebx, fs:[ 0x30 ]       // get a pointer to the PEB
mov ebx, [ ebx + 0x0C ]    // get PEB->Ldr
mov ebx, [ ebx + 0x14 ]    // get PEB->Ldr.InMemoryOrderModuleList.Flink (1st entry)         -----Aquí-----
mov ebx, [ ebx ]           // get the next entry (2nd entry)
mov ebx, [ ebx ]           // get the next entry (3rd entry)
mov ebx, [ ebx + 0x10 ]    // get the 3rd entries base address (kernel32.dll)


La parte que pongo aquí por lo que leo en el comentario tiene lo mismo que yo pero dice que ya tiene el Flink? es decir la estructura es esta:

Código (asm) [Seleccionar]
typedef struct _LIST_ENTRY {
  struct _LIST_ENTRY *Flink;
  struct _LIST_ENTRY *Blink;
} LIST_ENTRY, *PLIST_ENTRY, *RESTRICTED_POINTER PRLIST_ENTRY;


Es que tras seleccionar "InMemoryOrderModuleList" ya tengo un puntero hacia la primera entrada de "LDR_DATA_TABLE_ENTRY" sin necesidad de tocar Flink?


MCKSys Argentina

Hola!

Vas a tener que hacer un código que haga eso y depurarlo. Crep que es la única manera en que lo entenderás.

Por tu duda del código, mira este link.

Revisa la parte donde explica qué es InMemoryOrderModuleList.

Saludos!
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


cuentanegra1990

#4
¿Por que la MSDN trata las LIST_ENTRY como una estructura aparte si es un miembro de la estructura PEB_LDR_DATA?

Por lo que leo la estructura LIST_ENTRY esta dentro de la estructura PEB_LDR_DATA.

InMemoryOrderModuleList es un array que contiene los punteros hacia las estructuras LDR_DATA_TABLE_ENTRY.

_LIST_ENTRY = Puntero a una estructura tipo DATA_TABLE_ENTRY



Código (asm) [Seleccionar]
lkd> _LIST_ENTRY dt nt!
+ 0x000 Flink: Ptr32 _LIST_ENTRY
+ 0x004 Blink: Ptr32 _LIST_ENTRY


Con esta imagen es la única manera que intento relacionarlo, al haber un desplazamiento de 0 en los Flink ya estaría en la siguiente estructura LDR_DATA_TABLE_ENTRY apuntando a su vez a la lista seleccionada. Por ejemplo:

Si selecciono la lista InMemoryOrderModuleList y nos desplazamos a la primera tabla DATA_TABLE_ENTRY estaríamos apuntando al miembro InMemoryOrderModuleList de esa nueva tabla.

Estoy en lo cierto? de no ser así me podrías decir en que fallo.
saludos.

cuentanegra1990

Por favor podéis ayudarme a entender el enlace entre las estructuras PEB_LDR_DATA y LDR_DATA_TABLE_ENTRY por medio de los Flink?

MCKSys Argentina

Cita de: cuentanegra1990 en 17 Julio 2015, 08:18 AM
Por favor podéis ayudarme a entender el enlace entre las estructuras PEB_LDR_DATA y LDR_DATA_TABLE_ENTRY por medio de los Flink?

Hola!

Después de todo lo que he escrito y de lo que haz escrito, creo que la mejor opción es que abras el debugger que mejor manejes, cargues un calc o un notepad y revises las zonas de memoria donde están las structs.

En mi experiencia, no hay mejor explicación que la deducción que hagas por tus propios medios, "in-situ";)

Saludos!
MCKSys Argentina

"Si piensas que algo está bien sólo porque todo el mundo lo cree, no estás pensando."


cuentanegra1990

#7
Pero si es lo que he hecho, y es a la conclusion que he llegado que al selecionar cualquiera de las listas ya estas apuntando directamente a la estructura LDR_DATA_TABLE_ENTRY ya que tiene un desplazamiento de 0 el Flink.

Como he dicho lo he probado ademas e visto imagenes x internet que tambien me hacen pensar que estoy en lo cierto. Es por eso que lo pregunto para que algun profesional del tema pueda confirmarmelo.

Digamos que soy un poco inseguro y necesito de una confirmacion de una persona especializadaen el tema.

cuentanegra1990

Alguien que me diga si estoy en lo cierto o no, solo pido eso  :-(

Eternal Idol

No crees hilos repetidos en otros subforos (tampoco me mandes mensajes privados, para eso esta el foro).

Esta todo bien hasta que decidis que ebx + 010h es donde esta la direccion base:

0:000> dt ntdll!_LDR_DATA_TABLE_ENTRY @ebx
   +0x000 InLoadOrderLinks : _LIST_ENTRY [ 0xcd4d98 - 0xcd46f0 ]
   +0x008 InMemoryOrderLinks : _LIST_ENTRY [ 0x7700f1fc - 0xcd4da0 ]
   +0x010 InInitializationOrderLinks : _LIST_ENTRY [ 0x75030000 - 0x75047c90 ]
   +0x010 InProgressLinks  : _LIST_ENTRY [ 0x75030000 - 0x75047c90 ]
   +0x018 DllBase          : 0x00140000 Void
   +0x01c EntryPoint       : 0x00420040 Void
   +0x020 SizeOfImage      : 0xcd4b08
   +0x024 FullDllName      : _UNICODE_STRING "KERNEL32.DLL"
...
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón