(C) MITOSIS #2 E-Zine/GEDZAC 2004 Tema : Una forma de obtener el offset de un icono dentro de un PE Autor : Pr0t0z00 Válido para : Windows (Archivos Portables ejecutables) --------------------------------------------------------------------------------- Muy bien, en este articulo tratare de explicar como obtener el icono un PE a código limpio. Pues bueno, primero que todo necesitaremos el TASM 5.0 pero antes de empezar con el código veremos los pasos para lograr nuestra meta: 1- Obtener la .rsrc 2- Obtener el campo PointerToRawData que indica el desplazamiento dentro del archivo donde comienza la sección de recursos, este campo esta en ".rsrc + 14h" 3- Ir al offset que indica PointerToRawData y sumarle 14h 4- en el offset resultante en el paso 3 hay un valor el cual ahora debemos sumarlo al offset que indica PointerToRawData 5- Ir al offset resultante en el paso 4 y sumarle 14h 6- en el offset resultante en el paso 5 hay un valor el cual ahora debemos sumarlo al offset que indica PointerToRawData 7- Ir al offset resultante en el paso 6 y sumarle 14h 8- en el offset resultante en el paso 7 hay un valor el cual ahora debemos sumarlo al offset que indica PointerToRawData 9- Ir al offset resultante en el paso 8 y con esto ya estamos muy cerca del código del icono 10-Por ultimo Hacer un bucle que busque la cabecera del icono. (Todos estos pasos los podemos ir comprobando a mano abriendo algún PE con algún editor hexadecimal y efectuando los cálculos que indican los pasos anteriores) Ahora vamos con el código: -------------------------------------------------------------------------------- PARA EL PASO nº 1: Hay formas y formas de localizar la .rsrc dentro de un PE, una de estas formas consiste en utilizar la api LoadLibraryEx la cual retorna en EDX la .rsrc, pero esta forma no es fiable pues por razones que aun desconozco no funciona con algunos ficheros PE xD. Para este caso utilizaremos un método bruto jejeje. Para este método tomaremos en cuenta que todos los FICHEROS PE poseen la sección .reloc pero no todos poseen la .rsrc, afortunadamente sabemos que la .rsrc siempre esta antes que la .reloc entonces ya podemos hacer un bucle como el siguiente: Cargamos el fichero a ser tratado con la api LoadLibraryEx pero no tomaremos en cuenta el valor que esta api retorna en EDX por razones ya mencionadas, solo utilizaremos esta api con motivo de obtener la dirección base del fichero que utilizaremos como conejo de indias. push 2 ; LOAD_LIBRARY_AS_DATAFILE push 0 ; Null push offset File ; Apuntamos a la cadena que contiene la ruta del PE a tratar call LoadLibraryExA dec eax ; EAX = Base del fichero cargado (MZ) PUSH EAX Pos lo que viene a continuación esta demás explicarlo =P, de todos modos si todo sale bien obtendremos al final del bucle la .rsrc en EDX BuscarReloc: inc eax cmp dword ptr [eax],'rsr.' ; buscamos la .rsrc je TieneRsrc ; si la encontramos saltamos cmp dword ptr [eax],'ler.' ; buscamos la .reloc jne BuscarReloc ; si aun no se encuentra la .reloc seguimos buscandola jmp FIN ; si la encontramos adios lucas xD (si llegamos a este ; punto significa que el fichero no tenia .rsrc) TieneRsrc: mov edx,eax ; EDX = .rsrc ---------------------------------------------------------------------------------- PARA EL PASO nº 2: Obtener el campo PointerToRawData POP EAX add edx,14h ; EDX = .rsrc + 14h ( PointerToRawData ) ---------------------------------------------------------------------------------- PARA EL PASO nº 3: mov esi, dword ptr ds:[edx] ; ESI = Offset que indica PointerToRawData add eax,esi ; vamos al offset que indica ESI y con esto ya ; estamos en la sección de recursos PUSH EAX ; Salvo la sección de recursos del exe pues la necesitaremos add eax,14h ; Sumo 14h a eax pues en el offset resultante esta ; el primer "valor" que necesitamos ---------------------------------------------------------------------------------- PARA EL PASO nº 4: xor edx,edx ; Limpiamos EDX para pasarle el "valor" obtenido anteriormente mov dx,word ptr ds:[eax] ; Movemos a EDX el "valor" POP EAX ; Recupero en eax la sección de recursos PUSH EAX ; Salvo la sección de recursos del exe pues la necesitaremos ---------------------------------------------------------------------------------- PARA EL PASO nº 5: add eax,edx ; vamos al offset que indica EDX add eax,14h ; Sumo 14h a eax pues en el offset resultante esta el ; segundo "valor" que necesitamos ---------------------------------------------------------------------------------- PARA EL PASO nº 6: xor edx,edx ; Limpiamos EDX para pasarle el "valor" obtenido anteriormente mov dx,word ptr ds:[eax] ; Movemos a EDX el "valor " POP EAX ; Recupero en eax la sección de recursos PUSH EAX ; Salvo la sección de recursos del exe pues la necesitaremos ---------------------------------------------------------------------------------- PARA EL PASO nº 7: add eax,edx ; vamos al offset que indica EDX add eax,14h ; Sumo 14h a eax pues en el offset resultante esta el ; tercer "valor" que necesitamos ---------------------------------------------------------------------------------- PARA EL PASO nº 8: xor edx,edx ; Limpiamos EDX para pasarle el "valor" obtenido anteriormente mov dx,word ptr ds:[eax] ; Movemos a EDX el "valor" POP EAX ; Recupero en eax la sección de recursos ---------------------------------------------------------------------------------- PARA EL PASO nº 9: add eax,edx ; vamos al offset que indica EDX y con esto ya estamos cerca ; del código del icono ---------------------------------------------------------------------------------- PARA EL PASO nº 10: Ahora debemos construir un bucle que se encargue de buscar el código del icono, por lo que me he dado cuenta en la mayor parte de los PE (NO EN TODOS) el icono de aplicación comienza con el código hexa '28 00 00 00 20 00 00 00 40 00 00 00 01 00 04' entonces ya podemos hacer un bucle como este: bucleIcono: inc eax ; Ahora buscamos la cabecera del icono ; que es '28 00 00 00 20 00 00 00 40 00 00 00 01 00 04' cmp byte ptr [eax],28h jne bucleIcono add eax,4h ; sumamos 4 cmp byte ptr [eax],20h jne bucleIcono add eax,4h ; sumamos 4 cmp byte ptr [eax],40h jne bucleIcono add eax,4h ; sumamos 4 cmp byte ptr [eax],01h jne bucleIcono add eax,2h ; sumamos 2 cmp byte ptr [eax],04h jne bucleIcono sub eax,0000000Eh ; restamos todas las sumas que hicimos anteriormente ---------------------------------------------------------------------------------- Pos bueno, este articulo llego a su fin y espero que le encuentren una buena utilidad a esto porque si que las tiene. COLORÍN COLORIDO ESTE ARTICULO HA SUCUMBIDO. (C) MITOSIS #2 E-Zine/GEDZAC 2004