f.zz.de
posts /

ROP, Prolog suchen

Posted Tue 26 Apr 2016 12:21:29 PM CEST Florian Lohoff
in

ROPs (Return Oriented Programming) ist ja gerade ganz hip. Wir suchen uns minifunktionen die nur einen opcode oder 2 haben und dann ein return. Damit bauen wir uns dann das ganze programm zusammen. Bei der Diskussion mit den Kollegen darüber fiel mir wieder ein das ich mal für einen Bootloader ähnlichen kram gemacht habe. Wir suchen im PROM der Siemens Nixdorf RM200 den einsprung für seek. Den hatten die PROM Leute leider vergessen so das ein Bootloader jetzt eher witzlos war.

Disassembliert fängt jede MIPS function mit demselben Prolog an. Aufsetzen des Stack Frames damit ich die callee saved registers loswerde auf dem Stack. Das ist dann ein addiu $sp, -X. Den kann man natürlich suchen. Ich habe sogar den alten code von 2007 wiedergergefunden - Da hatte ich arcboot - den SGI Bootloader so modifiziert das der auch auf der SNI RM Serie läuft:

/*
 * The SNI Prom does not contain an official entry point for "prom_seek" which is
 * a pain and basically is a showstopper for bootloaders. There is a seek function
 * though which seems to be inbetween prom_open and prom_read. We try to find
 * it by looking for the function prolog e.g. the $sp setup. We then know the
 * address of the seek.
 */

void prom_init(void ) {
        unsigned int    jump;
        unsigned int    *readaddr,
                        *openaddr,
                        *saddr;

        jump = *((unsigned int *)PROM_ENTRY(PROM_READ));
        readaddr=(unsigned int *) (((jump & 0x03ffffff)<<2)|0xb0000000);
        jump = *((unsigned int *)PROM_ENTRY(PROM_OPEN));
        openaddr= (unsigned int *) (((jump & 0x03ffffff)<<2)|0xb0000000);

        for(saddr=readaddr-1;saddr>openaddr;saddr--) {
                /* Search for addiu $sp, negative */
                if ((*saddr & 0xffff8000) == 0x27bd8000) {
                        __prom_lseek=(void *) saddr;
                        break;
                }
        }

        if (__prom_lseek == NULL)
                prom_fatal("Didnt find prom_seek prolog between open and read\n\r");
}