zoukankan      html  css  js  c++  java
  • pwnable.kr leg之write up

    看代码:

     1 #include <stdio.h>
     2 #include <fcntl.h>
     3 int key1(){
     4     asm("mov r3, pc
    ");
     5 }
     6 int key2(){
     7     asm(
     8     "push    {r6}
    "
     9     "add    r6, pc, $1
    "
    10     "bx    r6
    "
    11     ".code   16
    "
    12     "mov    r3, pc
    "
    13     "add    r3, $0x4
    "
    14     "push    {r3}
    "
    15     "pop    {pc}
    "
    16     ".code    32
    "
    17     "pop    {r6}
    "
    18     );
    19 }
    20 int key3(){
    21     asm("mov r3, lr
    ");
    22 }
    23 int main(){
    24     int key=0;
    25     printf("Daddy has very strong arm! : ");
    26     scanf("%d", &key);
    27     if( (key1()+key2()+key3()) == key ){
    28         printf("Congratz!
    ");
    29         int fd = open("flag", O_RDONLY);
    30         char buf[100];
    31         int r = read(fd, buf, 100);
    32         write(0, buf, r);
    33     }
    34     else{
    35         printf("I have strong leg :P
    ");
    36     }
    37     return 0;
    38 }
    C Code
     1 #include <stdio.h>
     2 #include <fcntl.h>
     3 int key1(){
     4     asm("mov r3, pc
    ");
     5 }
     6 int key2(){
     7     asm(
     8     "push    {r6}
    "
     9     "add    r6, pc, $1
    "
    10     "bx    r6
    "
    11     ".code   16
    "
    12     "mov    r3, pc
    "
    13     "add    r3, $0x4
    "
    14     "push    {r3}
    "
    15     "pop    {pc}
    "
    16     ".code    32
    "
    17     "pop    {r6}
    "
    18     );
    19 }
    20 int key3(){
    21     asm("mov r3, lr
    ");
    22 }
    23 int main(){
    24     int key=0;
    25     printf("Daddy has very strong arm! : ");
    26     scanf("%d", &key);
    27     if( (key1()+key2()+key3()) == key ){
    28         printf("Congratz!
    ");
    29         int fd = open("flag", O_RDONLY);
    30         char buf[100];
    31         int r = read(fd, buf, 100);
    32         write(0, buf, r);
    33     }
    34     else{
    35         printf("I have strong leg :P
    ");
    36     }
    37     return 0;
    38 }

    分析代码,key1()+key2()+key3()==key时,得到flag

    那么来分析给定的汇编代码:

     1 (gdb) disass key1
     2 Dump of assembler code for function key1:
     3    0x00008cd4 <+0>:    push    {r11}        ; (str r11, [sp, #-4]!)
     4    0x00008cd8 <+4>:    add    r11, sp, #0
     5    0x00008cdc <+8>:    mov    r3, pc
     6    0x00008ce0 <+12>:    mov    r0, r3
     7    0x00008ce4 <+16>:    sub    sp, r11, #0
     8    0x00008ce8 <+20>:    pop    {r11}        ; (ldr r11, [sp], #4)
     9    0x00008cec <+24>:    bx    lr
    10 End of assembler dump.

    返回地址是r0而r0等于pc,且为arm指令

    补充知识:

    PC代表程序计数器,流水线使用三个阶段,因此指令分为三个阶段执行:1.取指(从存储器装载一条指令);2.译码(识别将要被执行的指令);3.执行(处理指令并将结果写回寄存器)。而R15
    (PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指令。一般来说,人们习惯性约定将“正在执行的指令作为参考点”,称之为当前第一条指令,因此PC总是指向第三
    条指令。当ARM状态时,每条指令为4字节长,所以PC始终指向该指令地址加8字节的地址,即:PC值=当前程序执行位置+8; ARM指令是三级流水线,取指,译指,执行时同时执行的,现在PC指向的是正在取指的地址,那么cpu正在译指的指令地址是PC-4(假设在ARM状态下,一个指令占4个字节),cpu正在执行的指令地
    址是PC-8,也就是说PC所指向的地址和现在所执行的指令地址相差8。

    所以

    r0的地址等于0x8cdc+0x8

    再看key2:

    (gdb) disass key2
    Dump of assembler code for function key2:
       0x00008cf0 <+0>:    push    {r11}        ; (str r11, [sp, #-4]!)
       0x00008cf4 <+4>:    add    r11, sp, #0
       0x00008cf8 <+8>:    push    {r6}        ; (str r6, [sp, #-4]!)
       0x00008cfc <+12>:    add    r6, pc, #1
       0x00008d00 <+16>:    bx    r6
       0x00008d04 <+20>:    mov    r3, pc
       0x00008d06 <+22>:    adds    r3, #4
       0x00008d08 <+24>:    push    {r3}
       0x00008d0a <+26>:    pop    {pc}
       0x00008d0c <+28>:    pop    {r6}        ; (ldr r6, [sp], #4)
       0x00008d10 <+32>:    mov    r0, r3
       0x00008d14 <+36>:    sub    sp, r11, #0
       0x00008d18 <+40>:    pop    {r11}        ; (ldr r11, [sp], #4)
       0x00008d1c <+44>:    bx    lr
    End of assembler dump.

    返回地址为r3,bx r6跳转为thumb指令,所以r3=0x8d04+0x4+0x4;

    附:arm与thumb跳转:

    http://blog.csdn.net/itismine/article/details/4753701

    再看key3:

     1 (gdb) disass key3
     2 Dump of assembler code for function key3:
     3    0x00008d20 <+0>:    push    {r11}        ; (str r11, [sp, #-4]!)
     4    0x00008d24 <+4>:    add    r11, sp, #0
     5    0x00008d28 <+8>:    mov    r3, lr
     6    0x00008d2c <+12>:    mov    r0, r3
     7    0x00008d30 <+16>:    sub    sp, r11, #0
     8    0x00008d34 <+20>:    pop    {r11}        ; (ldr r11, [sp], #4)
     9    0x00008d38 <+24>:    bx    lr
    10 End of assembler dump.
    11 (gdb) 

    返回地址为r0,r0=lr,而lr保存返回地址

    返回到main函数:

     1 (gdb) disass main
     2 Dump of assembler code for function main:
     3    0x00008d3c <+0>:    push    {r4, r11, lr}
     4    0x00008d40 <+4>:    add    r11, sp, #8
     5    0x00008d44 <+8>:    sub    sp, sp, #12
     6    0x00008d48 <+12>:    mov    r3, #0
     7    0x00008d4c <+16>:    str    r3, [r11, #-16]
     8    0x00008d50 <+20>:    ldr    r0, [pc, #104]    ; 0x8dc0 <main+132>
     9    0x00008d54 <+24>:    bl    0xfb6c <printf>
    10    0x00008d58 <+28>:    sub    r3, r11, #16
    11    0x00008d5c <+32>:    ldr    r0, [pc, #96]    ; 0x8dc4 <main+136>
    12    0x00008d60 <+36>:    mov    r1, r3
    13    0x00008d64 <+40>:    bl    0xfbd8 <__isoc99_scanf>
    14    0x00008d68 <+44>:    bl    0x8cd4 <key1>
    15    0x00008d6c <+48>:    mov    r4, r0
    16    0x00008d70 <+52>:    bl    0x8cf0 <key2>
    17    0x00008d74 <+56>:    mov    r3, r0
    18    0x00008d78 <+60>:    add    r4, r4, r3
    19    0x00008d7c <+64>:    bl    0x8d20 <key3>
    20    0x00008d80 <+68>:    mov    r3, r0
    21    0x00008d84 <+72>:    add    r2, r4, r3
    22    0x00008d88 <+76>:    ldr    r3, [r11, #-16]
    23    0x00008d8c <+80>:    cmp    r2, r3
    24    0x00008d90 <+84>:    bne    0x8da8 <main+108>
    25    0x00008d94 <+88>:    ldr    r0, [pc, #44]    ; 0x8dc8 <main+140>
    26    0x00008d98 <+92>:    bl    0x1050c <puts>
    27    0x00008d9c <+96>:    ldr    r0, [pc, #40]    ; 0x8dcc <main+144>
    28    0x00008da0 <+100>:    bl    0xf89c <system>
    29    0x00008da4 <+104>:    b    0x8db0 <main+116>
    30    0x00008da8 <+108>:    ldr    r0, [pc, #32]    ; 0x8dd0 <main+148>
    31    0x00008dac <+112>:    bl    0x1050c <puts>
    32    0x00008db0 <+116>:    mov    r3, #0
    33    0x00008db4 <+120>:    mov    r0, r3
    34    0x00008db8 <+124>:    sub    sp, r11, #8
    35    0x00008dbc <+128>:    pop    {r4, r11, pc}
    36    0x00008dc0 <+132>:    andeq    r10, r6, r12, lsl #9
    37    0x00008dc4 <+136>:    andeq    r10, r6, r12, lsr #9
    38    0x00008dc8 <+140>:            ; <UNDEFINED> instruction: 0x0006a4b0
    39    0x00008dcc <+144>:            ; <UNDEFINED> instruction: 0x0006a4bc
    40    0x00008dd0 <+148>:    andeq    r10, r6, r4, asr #9
    41 End of assembler dump.

    第20行,key3的地址为0x8d80,

    python得到key的值:

    1 #/usr/bin/python
    2 
    3 key1=0x8cdc+0x8
    4 key2=0x8d04+0x4+0x4
    5 key3=0x8d80
    6 
    7 key=key1+key2+key3
    8 
    9 print key

    得到结果:

  • 相关阅读:
    PHPCMS V9生成静态地址绝对路径改为相对路径的方法
    python常识系列21-->一个不能不用的python日志模块**nb_log**
    python常识系列20-->python利用xlutils修改表格内容
    单元测试框架杂记02-->unittest结合requests时报一个警告
    修改element的NavMenu 导航菜单组件样式
    算法-04 | 贪心算法
    算法-05 | 二分查找
    数据结构-07| 堆
    数据结构-06| 字典树| 并查集
    数据结构-05| 布隆过滤器| 缓存机制
  • 原文地址:https://www.cnblogs.com/liuyimin/p/7278817.html
Copyright © 2011-2022 走看看