Acerca de cómo puede incrustar código sin jmp en la sección de código y permanecer invisible si no estudia a fondo el código desensamblado. A quién le importa, por favor, debajo del gato.
Estoy desarrollando un desensamblador C para Linux. Sobre mí, no diría que soy un programador profesional. No trabajo como programador, pero lo que aprendí es leer libros o inventarlo yo mismo o estudiar el código fuente de otros programas. Por lo tanto, si el código te parece infantil, no lo jures.
Para empezar, hice un desensamblador y mi código ahora se ve así, es decir, se lee un byte y se pasa a la función deseada.
void disasm_intel ( unsigned char *ptr, int size, int byte_order, int show ) { show_asm = show; virt = global_virt_text; unsigned char *start = ptr; start_op = ptr; for ( int index = 0; index < size; index++ ) { if ( show_asm == TRUE ) printf ( "%lx: ", virt ); switch ( *ptr ) { case 0x30: intel_opcode_1_0x30 ( &ptr, &index, byte_order ); break; case 0x31: intel_opcode_1_0x31 ( &ptr, &index, byte_order ); break; case 0x66: intel_opcode_1_0x66 ( &ptr, &index, byte_order ); break; case 0x67: intel_opcode_1_0x67 ( &ptr, &index, byte_order ); break; case 0x83: intel_opcode_1_0x83 ( &ptr, &index, byte_order ); break; case 0x88: intel_opcode_1_0x88 ( &ptr, &index, byte_order ); break;
Y tales funciones ya son un montón. En algunos lugares hice comentarios para captar la interconexión de las instrucciones de la máquina, y tal vez más tarde para hacer un desensamblador más competente. Pero de esta forma, en la que tengo el código ahora, puedo establecer fácilmente cualquier condición para cada operador.
Entonces, mientras hacía esto, tuve una idea, ¿es posible agregar código en el medio de la sección de códigos? Resulta que puedes, pero en todos los casos? Hasta ahora, para agregar código, uso códigos de máquina ya preparados. Si puedo más tarde, haré que el traductor del ensamblador en el código de la máquina para agregar el código sea más conveniente. En mi caso, debe especificar el desplazamiento en la sección de código y los bytes se copian en el lugar correcto. También había un cierto problema: direccionamiento en memoria. Agregué un código al comando lea que guarda los datos necesarios en la estructura, y si inserta nuevos operadores en la sección de código, todos los desplazamientos se alinean para que indiquen datos en los nuevos desplazamientos. Bueno, no es muy difícil, si inserta el código, la sección de código aumentará en la misma cantidad de bytes y todas las demás secciones después de que la sección de código ya contenga nuevas compensaciones. Lo hice para que haya diferencias en el lugar donde pega el código, todos los desplazamientos funcionan correctamente. Entonces surgió el problema de que al abordar tales
mov eax, [eax + eax + 0x100]
El hecho es que en dicho direccionamiento puede haber ebp y apuntar a la pila, y no a otra sección. Decidí hacerlo de modo que si la dirección apunta a la sección de datos, considere los desplazamientos al insertar el código, si apunta a la pila, es decir, no la dirección en la sección de datos, entonces no tenga en cuenta los desplazamientos.
Y de esta manera los atacantes pueden aprovechar. Después de todo, se puede insertar código malicioso al comienzo de alguna función en el programa, por ejemplo, para que se cree un niño fork y se descargue un archivo especial. En Linux, esto se puede hacer sin ningún problema. De hecho, en / usr / include hay un archivo con todas las funciones del sistema operativo. Es decir, puede usar la parte de red, incluso si el programa no tiene funciones de red. No sé cómo en Windows, pero más adelante intentaré agregar trabajo con formato PE. Puede llegar a hacer lo mismo que en Linux. Hasta ahora tengo una versión de consola. Pero luego planeo hacerlo en GTK.
Gracias por dedicar tu tiempo a mi artículo.