Cómo modificar la ruta de lectura por defecto de una dll mediante tecnología de desmontaje

Recientemente, recibí una solicitud para modificar la función de cierta dll para que pueda leer los archivos en el directorio especificado por el cliente en lugar de la ruta original de la dll

La ruta para leer el archivo está ubicada por ida y ensamblada por sprintf. El uso de ida para desensamblar el código de la máquina es el siguiente:

.text:00000001800042AD 4C 8B 05 5C 5B 5F 00          mov     r8, cs:qword_1805F9E10
.text:00000001800042B4 8B F5                         mov     esi, ebp
.text:00000001800042B6 48 69 F6 08 EA 2B 00          imul    rsi, 2BEA08h
.text:00000001800042BD 48 8D 15 4C C6 0F 00          lea     rdx, aSSIni                     ; "%s\\%s.ini"
.text:00000001800042C4 48 8D 8C 24 30 01 00 00       lea     rcx, [rsp+918h+Source]          ; Buffer
.text:00000001800042CC 4C 8D 8C 3E 80 E8 23 00       lea     r9, [rsi+rdi+23E880h]
.text:00000001800042D4 E8 D7 9F 0B 00                call    sprintf

El código C desmontado es el siguiente:


      sprintf(Source, "%s\\%s.ini", (const char *)qword_1805F9E10, (const char *)qword_1805F96D8 + v7 + 2353280);
     

Nuestro objetivo es reemplazar el nombre del directorio. Mirando el código anterior, podemos saber que el nombre del directorio es el puntero qword_1805f9e10. Necesitamos reemplazarlo con otro nombre. Saltando, podemos encontrar la cadena %s\\%s .ini en Bajo .rdata:

.rdata:000000018010090E 00 00                         align 10h
.rdata:0000000180100910                               ; const char aSSIni[]
.rdata:0000000180100910 25 73 5C 25 73 2E 69 6E 69 00 aSSIni db '%s\%s.ini',0                 ; DATA XREF: sub_180004150+16D↑o
.rdata:000000018010091A 00 00                         align 4
.rdata:000000018010091C 00 00 7F 43                   dword_18010091C dd 437F0000h            ; DATA XREF: sub_180004150+F7↑r
.rdata:000000018010091C

Puedes ver que 25 73 5c 25 73 2e 69 63 69 representa el código ascii de %s\%s.ini

Acabamos de ver que todavía hay 4 bytes de espacio detrás de la cadena para reproducir

Lo cambiamos a ice\%s.ini, el código ascii es 69 63 65 25 73 2e 69 63 69

Al modificar, tenga cuidado de no cambiar la longitud de estos caracteres a voluntad, solo para reemplazar bytes diferentes

Como el original es 25 73 5C 25 73 2E 69 6E 69 00

Después de la modificación, es 69 63 65 5C 25 73 2e 69 63 69

Puede acortarlo y reemplazar todos los extras con 00. Si hay 0 adicionales detrás y es un espacio reservado, puede alargar la cadena original, al igual que las dos líneas anteriores. Tenga en cuenta que debe dejarse al menos un 0 en el end, como el final de la cadena, como el nuestro, solo hay más bytes, uso uno más

Desde 18010910-1801091a, es el área que operamos a voluntad, un total de 10 bytes

Después de modificar esta cadena, la configuración en el directorio ice no se puede leer y los parámetros de sprintf deben modificarse

Del código anterior, sabemos que %s\%s se usó para hacer coincidir dos parámetros. Ahora que lo hemos cambiado a ice\%s, necesitamos ajustar el último parámetro del código original al frente.

Al aprender el conocimiento de ensamblaje de x64, podemos saber que el orden de pasar parámetros de una función es transferir datos a los cuatro registros rcx rdx r8 r9

En comparación con el código anterior, puede saber fácilmente qué parámetro está almacenado en qué dirección. Solo necesitamos modificar el registro de almacenamiento de datos para modificar el orden de paso de los parámetros.

Necesitamos ajustar el orden de r8 y r9, 4C 8B 05 5C 5B 5F 00 significa transferir la cadena al registro r8, entre ellos,

4C 8B es el movimiento de datos a r8, seguido de 05 5c 5B 5F es el puntero del directorio original

4C 8D 8C 3E 80 E8 23 00 es mover datos a r9, reemplazaremos este 4C 8D con el 4C 8B en la oración anterior,

Es decir, el cuarto parámetro es r9, lo guardamos en r8, y el tercer parámetro lo guardamos en r9, ya que cambiamos la cadena a ice\%s.ini, luego el programa usa r8, y r9 se le da a Discarded, realizando así la sustitución del directorio

Después de la modificación anterior, el programa leerá el archivo ini en el directorio ice en lugar de la ruta empalmada anteriormente

Alguien preguntó, ¿cómo modificarlo? Mi método es usar vim -b xxx, y luego usar el comando:%!xxd para obtener binario, y luego buscar el número hexadecimal correspondiente para modificar. De nuevo: guarde con wq, como para como se hace funcionar en windows, no se...

El contenido anterior se basa en mi propia exploración y resumen, después de la operación práctica, pero la interpretación del código de la máquina aún es algo inexacta.

El siguiente paso es analizar completamente el significado representado por el código de la máquina. Cuando pueda analizar completamente el significado del código de la máquina, podré reescribir fácilmente la lógica del programa, jajajaja

En cuanto a cómo analizar el código de la máquina, no he encontrado la información correspondiente... No sé si tiene alguna buena recomendación.

Supongo que te gusta

Origin blog.csdn.net/kof98765/article/details/128653465
Recomendado
Clasificación