[Taller en construcción]Secciones en archivos PE.

Iniciado por The Swash, 23 Mayo 2012, 18:44 PM

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

Belial & Grimoire

#20
hola

bueno, pues ya voy entendiendo mas, por lo menos el ejemplo del taller lo logre hacer bien, pero sigo teniendo problemas con el block

a ver, primero sigo los pasos de la primer parte

en el caso de mi sistema es
Citar
   Name: .EHN -> Valor a plasmar: 2E 45 48 4E 00 00 00 00
   VirtualSize: 0x17 -> Valor a plasmar: 17 00 00 00
   VirtualAddress: 0x3000 -> Valor a plasmar: 00 30 00 00
   SizeOfRawData: 0x200 -> Valor a plasmar: 00 02 00 00

me imagino que si son 0x200, porque reloc es

00100000 + los 17, quedaria alineado con FileAlignment (11C)

FileAlignment lo encuentro asi 00020000

Aqui tengo una duda, como mencionas una de las 2 formas de encontrar esto es colocando la
cantidad exacta de la aplicaion

CitarCorresponderá a la ubicación o posición en el archivo físicamente de los datos de nuestra nueva sección. Tenemos 2 formas de conseguir dicho valor, una es con el tamaño exácto del archivo y ya

en mi caso es "0002BE00", hacer esto y dejarlo asi esta bien? o se tiene que alinear?

lo menciono porque tambien mencionaste

CitarDe ambas formas llegamos a que es: 0x600, si se dan cuenta es múltiplo del FileAlignment por lo cúal constatamos que la sección anterior a nosotros está alineada.


PointerToRawData: 0002BE00 esto es la cantidad exacta del archivo -> entonces quedaria 0x00BE0200

porque la sección .reloc de PointerToRawData y SizeOfRawData seria

00100000 --> PoniterToRawData
00AE0200 --> SizeOfRawData


CitarPointerToRelocations: 00 00 00 00
   PointerToLineNumbers: 00 00 00 00
   NumberOfRelocations: 00 00
   NumberOfLineNumbers: 00 00
   Characteristics: C0 00 00 00 -> Valor a plasmar: 00 00 00 C0

de la ultima sección que es .reloc recorro 0x20h o 40 bytes, alli escribo mi sección

despues busco la sección BOUND_IMPORT_TABLE

CitarYa les había mencionado que el directorio correspondiente al BOUND_IMPORT_TABLE es el número 12, si aplicamos un poco de matemáticas y nos paramos justo al inicio de IMAGE_SECTION_HEADER y restamos (5*8) estaremos justo en la declaración del directorio. 0x1B0 - 0x28 = 0x188 -> BOUND_IMPORT_DIRECTORY

bueno, en mi caso IMAGE_SECTION_HEADER se encuentra en

1D8 - 0x28 = 1B0

otra forma de llegar es con PE + 0xD0

0xE0 + 0xD0 = 0x1B0

bueno la cuestion es... que me encuentro con BOUND_IMPORT_TABLE


000001A9 6D 00 00 40 00 00 00 78 02 00 00 28 01 00 00 00 10 m..@...x...(.....

me imagino que quedaria asi si borro RVA y Size

000001A9 6D 00 00 40 00 00 00 00 00 00 00 00 00 00 00 00 10 m..@.............

despues al final, agrego los 200 bytes para escribir la frase

y lo guardo

pero cuando lo ejecuto me menciona que no es una aplicacion win32

dejo el notepad con toda la modificacion que hice

http://www.mediafire.com/?1azivv26r9a9jce

bueno, ya descansare porque creo ya me bloque y cosas que ya hice se me estan dificultando de nuevo, mejor continuare despues, gracias por la ayuda de hoy

salu2
.                                 

m0rf

Muchas gracias, me va a ser útil.

Saludos.
Si todos fuéramos igual de inteligentes no existiría la mediocridad porque no podríamos apreciarla. Aprecias la mediocridad?

The Swash

En cuanto al SizeOfRawData:
Es la cantidad de bytes que añadirás en tu sección, Si este valor no es múltiplo del FileAlignment debes alinearlo y por tanto agregar la cantidad de bytes alineada, si alineas 0x17 con 0x200 te dará 0x200, equivalente al total de bytes a agregar, pero de esos 0x200 0x17 bytes serán los que contienen tus datos así que serán los primeros 0x17 bytes de los 0x200 en total.

En cuanto al PointerToRawData:
Tienes 4 secciones, la última con los siguientes datos:

  • VirtualAddress: 0x2F000
  • VirtualSize: 0xE34
  • PointerToRawData: 0x2AE000
  • SizeOfRawData: 0x1000

Si calculamos, el VirtualAddress de nuestra sección será: 0x2F000 + 0xE34 = 0x2FE34 Alineado a SectionAlignment (Se alinea al SectionAlignment porque ambos valores hacen referencia a memoria) = 0x30000 -> Nuevo VirtualAddress.

VirtualSize: La cantidad de datos que agregarás (0x17, esto se alinea solo en memoria).

PointerToRawData: (0x2AE00 + 0x1000 = 0x2BE00) Podemos comprobar que dicho valor está alineado ya que al hacer 0x2BE00 mod 0x200 será 0.

SizeOfRawData: Ya lo mencioné arriba.

Ahora, como te pudiste dar cuenta, hay datos justo al final de la última sección y estos corresponden a BOUND_IMPORT_TABLE. Comienza justo en: 0x278 y tiene un tamaño de 0x128. Esto lo podemos ver al ubicarnos primero al inicio del IMAGE_DATA_DIRECTORY, para esto nos basamos el donde inicia la primera sección y restamos la cantidad de directorios por el tamaño de cada uno (0x10* 0x8 =  0x80). Entonces sería 0x1D8 (inicio de primera sección) - 0x80 = 0x158 (inicio de IMAGE_DATA_DIRECTORY) + 0x58(posición del BOUND_IMPORT_TABLE). = 0x1B0 -> Aquí estarán los datos del BOUND_IMPORT_TABLE, en tu caso quedará más fácil "pisarla", entonces establece el RVA correspondiente a los primeros 4 bytes del BOUND_IMPORT_TABLE a 0, y los siguientes 4 correspondientes su tamaño también a 0.

Ahora puedes tranquilamente sobrescribir 0x28 bytes y todo andará bien.
No olvides actualizar NumberOfSectiosn y SizeOfImage.

Si quieres guiarte aquí te subo el notepad con la sección agregada.
https://dl.dropbox.com/u/26610132/notepad%20-%20copia.exe

Sigue prácticando.

Un saludo,
Iván Portilla.

Hendrix

Como te dije por MP, felicidades por el taller y ánimo en lo que te queda! Es realmente interesante :D Espero que la gente se anime a publicar documentos como este, sería un buen empujón para este subforo :)

Un Saludo :)
"Todos los días perdemos una docena de genios en el anonimato. Y se van. Y nadie sabe de ellos, de su historia, de su peripecia, de lo que han hecho, de sus angustias, de sus alegrías. Pero al menos una docena de genios se van todos los días sin que sepamos de ellos". - Juan Antonio Cebrián

Belial & Grimoire

#24
hola

ya vi mis errores, me sobraban 40 bytes, quitandoselos se volvio a colocar el icono

el segundo error que note es que no coloque bien los hexa

asi lo pusiste tu

00000300

asi lo puse yo

00030000

la siguente sección hice lo mismo

00020000
00000200

solo que note que en SizeOfImage tu pusiste

Citar00100300

y no recordaba que era la suma de SizeofImage y SizeOfRawData

00030000
00001000
00031000

00100300


y yo lo deje como

00000400

y olvide que NO son 200 decimales, son 200 en hexa y no aumente la cantidad exacta

continuare con la ultima sección a ver que tal

gracias por la ayuda
.                                 

The Swash

Hola,

Cosas que pasan mi amigo, practicad y seguro corregiréis esos pequeños pero importantes detalles. Ánimo.

Un saludo,
Iván Portilla.

Belial & Grimoire

hola

si creiste que ya te habias librado de mi, jeje te equivocas... solo que era fastidioso cambiar de particiones de linux a windows y viceversa y tuve que reacomodar todo para instalar vitualbox jeje

bueno, tengo 2 preguntas... una pregunta que ya me explicaste como 20 veces y no logro entender y otra sobre el cambio de secciones

logre cambiar la sección .text con .idata del primer programa de ejemplo que pusiste, pero el programa con VB6 tuve un problema...

en la primera aplicacion, PointerToRawData era de 00000200 y 00000400

lo cambie y quedo bien, no tuve problema de ejecutarlo y con ollydbg verfique el mapeo y esta bien

pero en el de VB6, me encontre con esto

00200000
00100000

al cambiarlo 00001000 y el otro es 00002000, tambien SizeOfRawData era de 0x1000.... y al cambiarlo me volvio a funcionar bien, pero el icono desaparecio, solo al executar el programa me aparece MessageBox, con el mensaje "hola mundo", pero como podria reaparecer el icono?

y la segunda y perdon por se tan insistente,es que no logro comprender SizeOfRawData, ya todo lo comprendi bien, agregue mi sección, pero solo en esa sección me volvi a equivocar

algo que me tiene confundido, es que yo pensaba que solo era la cantidad de sección a agregar, por ejemplo

si eran 0x17 ->0x00000017, si era 0x50 -> 0x00000050

ahora, la primera explicacion que me diste era que se alineara con FileAligment, si esa sección era 0x200, de 0x17 seria 0x200

pero en la otra explicacion me mencionas que para alinear 0x17 a FileAligment, es 0x100

y efectivamente, son 0x100 pero ya me confundi, creia que era 0x200

la verdad no entiendo como alinear

acaso, de 0x17, deberia alinarlo a 0x100? para que sea multiplo de 0x200?

y si fuera 0x50, tambien se aliena con 0x100?

y si fuera 0x201, entonces deberia agregar 0x300? o 0x400?

perdon, pero ya solo es esa sección que no entiendo como alinear, espero me puedas explicar con manzanas XD

salu2, que estes bien
.                                 

The Swash

Hola,

Mira te respondo lo primero. Acabo de hacer la prueba y en realidad con el ejecutable de Visual Basic sigue funcionando correctamente y mostrando el icono. Debes tratar de cambiar bien los valores y nada más. Además si quieres darme valores por aquí hazlo especificando a que campos se refiere y de que sección.
Te doy enlace del el ejecutable en Visual Basic al que intercambié la sección .text -> .rsrc:
https://dl.dropbox.com/u/26610132/Change.exe

En cuanto a lo segundo. He verificado y en ningún momento te he siquiera mencionado el valor 0x100, quizá si 0x1000 porque es un múltiplo de los FileAlignment con que hemos trabajado en el taller. Te vuelvo a explicar con 2 ejemplos distintos, pero la teoría es la misma, si tienes un valor, debes hacer que ese valor cumpla que (valor módulo FileAlignment) == 0. Y dicho valor no puede ser menor que el original, por lo tanto decimos que deberás alinearlo o redondearlo a su múltiplo mayor inmediato.

Ejemplo:
FileAlignment: 0x200
Valor 0x17
Si miras 0x17 módulo 0x200 = 0x17. Ya que es un valor menor, el más próximo que vas a encontrar múltiplo de 0x200 es el mismo 0x200. ya que 0x200 módulo 0x200 = 0.

Valor: 0x405
0x405 módulo 0x200 = 0x05. Es un valor mayor, pero ahora igual que en el anterior debes buscar el múltiplo mayor inmediato a 0x405 que haga que el módulo sea 0. En este caso, 0x600.

Si no lo entiendes aún te doy la siguiente fórmula, pero se trata de que tú seas capaz de entenderlo.

Aligned = (Valor + FileAlignment)-(Valor módulo FileAlignment).

Prueba:
Aligned = (0x405 + 0x200) - (0x405 módulo 0x200) => 0x605 - 0x05 = 0x600.
Aligned = (0x17 + 0x200) - (0x17 módulo 0x200) =>  0x217 - 0x17 = 0x200.
Aligned = (0x340 + 0x200) - (0x340 módulo 0x200) => 0x540 - 0x140 = 0x400.

Un saludo,
Iván Portilla.

Belial & Grimoire

creo ya comprendi

entonces si a mi me aparece FileAligment como

00 20 00 00 -> 00 00 20 00

seria

00 00 20 17 -> 0x2017 - 0x17 = 0x2000

y si me apareciera

00 00 10 17 -> 0x1017 - 0x17 = 0x1000

acaso es asi?

pero, en el block de notas me aparece como 0x2000, entonces porque no funciona con 0x2000 y si funciona con 0x1000

porque bueno, al revisarlo, lo tengo en la posicion 11C

00 20 00 00, al agregar 0x17, entonces seria 17 20 00 00 - 0x17 = 00 20 00 00, pero de esa manera no funciona, tengo que dejarlo como 0x1000

00 10 00 00, pero porque?

y de lo de VB6, ya lo logre, movi ".Text" y ".rsrc" y si quedo bien y el icono tambien quedo bien

solo que intente mover ".Text" y ".data", e igual desaparece el mensaje, incluso ahora me aparece Messagebox, pero vacio, jeje, quien sabe porque con ese me sale raro

salu2
.                                 

Belial & Grimoire

hola

estaba haciendo lo mismo de cambiar secciones en el block de notas, pero una pregunta

si SizeOfRawData, no esta lineado como en tu ejemplo

CitarSección .text: PointerToRawData: 0x200 SizeOfRawData: 0x200
    Sección .idata: PointerToRawData: 0x400 SizeOfRawData: 0x200
    Sección .data: PointerToRawData: 0x600 SizeOfRawData: 0x200

tendria que modficar eso tambien, por ejemplo en FileAligment me aprece 0x200

pero en .text es

.text: PointerToRawData: 00A80000 y SizeOfRawData: 00040000

y el de .reloc es

.reloc: PointerToRawData: 00100000 y SizeOfRawData: 00AE0200

en el caso de que fuece diferente, trendria que alinerlo, o que tendria que hacer?

salu2
.