ROP, Prolog suchen
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");
}