Ayuda con este codigo

Iniciado por [Kayser], 14 Mayo 2012, 22:56 PM

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

[Kayser]

Hola gente llevo tiempo rompiendome la cabeza con el codigo de un RunPE...

For i = 0 To Pinh.FileHeader.NumberOfSections - 1
RtlMoveMemory Pish, bvBuff(Pidh.e_lfanew + 248 + 40 * i), Len(Pish)
WriteProcessMemory Pi.hProcess, ByVal Pinh.OptionalHeader.ImageBase + Pish.VirtualAddress, bvBuff(Pish.PointerToRawData), Pish.SizeOfRawData, 0
Next i


Se supone que escribe cada sección en su virtual adress pero acaso el virtualaddress no es el mismo cada vez? O a medida que se llena la estructura de image section header el valor del virtualadress va cambiando apuntando a cada sección cada vez?

A ver si pueden ayudarme por favor un saludo y gracias

Binary_Death

El VirtualAddress de cada sección es el RVA donde se cargará en memoria cada sección, y es siempre un múltiplo de SectionAlignment.

Vamos a ver, imagínate que tienes un ejecutable con un ImageBase de 04000000h, que suele ser así en la mayoría de casos en los que no tienen relocation table.
Si el SectionAlignment es 1000h, eso significará que el VirtualAddress de cada sección deberá de ser un múltiplo de 1000h.

Es posible que la sección de código tenga un VirtualAddress de 1000h, y la sección de datos de 2000h, y así sucesivamente.

Lo que tiene que hacer el RunPE es ver que VirtualAddress tiene cada sección, sumárselo al ImageBase y escribir tantos bytes como indique el VirtualSize de la sección en la dirección de memoria del proceso ImageBase+VirtualAddress.

Así pues, imagínate que tenemos que el VirtualSize de la anterior sección de código citada es 0B5h, por decir algo. Entonces escribirá 181 bytes (en decimal lo digo) a partir de la dirección 04001000h.

Por lo que veo ahí (y no entendiendo de VB) veo que se usa SizeOfRawData en vez de VirtualSize. SizeOfRawData es lo mismo que VirtualSize pero alineado a FileAlignment (que suele ser 512h, tamaño de un sector).


The Swash

El código que mencionas en teoría es un ciclo que recorre todas las secciones.
Seguro esta parte no te gusta mucho:

RtlMoveMemory Pish, bvBuff(Pidh.e_lfanew + 248 + 40 * i), Len(Pish)

Bueno el ciclo va desde 0 hasta el número de secciones:

    (Rpidh.e_lfanew + 248 + 40* i) -> Corresponde a lo siguiente:
    • l_fanew apunta al inicio de NT_HEADERS, lo reconoces por la firma PEx0x0
    • +248 -> te ubica justo al inicio de la tabla de secciones.
    • +40*i -> como sabes por jerarquía de operadores se hace primero la multiplicación, la i corresponde a la sección y el 40 al tamaño (40*(i=0)) = 0, l_fanew + 248 + 0 será de donde se lea la primera sección.

    RtlMoveMemory constantemente cambiará el valor de la estructura
Pish, esta estructura tendrá valores distintos a cada vuelta del ciclo ya que como mencionamos estamos recorriendo la declaración de las secciones.

WriteProcessMemory toma en varios de sus parámetros datos de la estructura y posteriormente copia en memoria, las secciones inician en ImageBase + VirtualAddress y tienen tamaño VirtualSize.

Así que eso, es copiar en memoria las secciones del buffer pero se hace como corresponde en memoria usando los datos del IMAGE_SECTION_HEADER. Si quieres aclarar tus dudas sobre secciones te invito a participar de este taller:
http://foro.elhacker.net/analisis_y_diseno_de_malware/taller_en_construccionsecciones_en_archivos_pe-t362515.0.html

Un saludo,
Iván Portilla.