【pwnable.kr】 leg
阿新 • • 發佈:2018-12-13
本關主要涉及了一些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