1. 程式人生 > >【pwnable.kr】 leg

【pwnable.kr】 leg

 

本關主要涉及了一些arm彙編的知識。

閱讀leg.c原始碼發現,本關呼叫scanf從標準輸入讀取key後,判斷是否和key1 key2 key3 三個函式的返回值的和相等。如果相等,則輸出flag。但是ARM彙編的函式返回值和暫存器R0有關,並且key函式中涉及到了PC LR 暫存器的操作。因此需要閱讀彙編。

int main(){
int key=0;
printf("Daddy has very strong arm! : ");
scanf("%d", &key);
if( (key1()+key2()+key3()) == key ){
printf("Congratz!\n");
int fd = open("flag", O_RDONLY);
char buf[100];
int r = read(fd, buf, 100);
write(0, buf, r);
}
else{
printf("I have strong leg :P\n");
}
return 0;
}

 閱讀leg.asm的彙編。

key1函式中,r0的值是由0x8cdc處PC暫存器的值。由於ARM處理器的三級流水線機制,執行到0x8cdc時,CPU已經完成了0x8cdc處指令的翻譯操作和0x8ce4處的解釋操作。因此PC暫存器的值是0x8cdc+4+4。r0 = 0x8cdc+8。  

key2函式同理,但是由於bx r6,r6最後一位為1,cpu切換到thumb模式,每條指令2byte。因此PC=0x8d04+2+2。r0 = 0x8d04+2+2+4。

key3函式中,r0是暫存器LR的值,LR是當前函式的返回值,通過檢視main函式中key3的返回值可知LR=0x8d80。因此r0 = 0x8d80。

最終key1()+key2()+key3() = 0x8cdc+4+4 + 0x8dc4+2+2+4 + 0x8d80 = 108400。

flag