看代码:

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

C Code

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

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

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

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

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

补充知识:

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

所以

r0的地址等于0x8cdc+0x8

再看key2:

  1. (gdb) disass key2
  2. Dump of assembler code for function key2:
  3. 0x00008cf0 <+>: push {r11} ; (str r11, [sp, #-4]!)
  4. 0x00008cf4 <+>: add r11, sp, #
  5. 0x00008cf8 <+>: push {r6} ; (str r6, [sp, #-4]!)
  6. 0x00008cfc <+>: add r6, pc, #
  7. 0x00008d00 <+>: bx r6
  8. 0x00008d04 <+>: mov r3, pc
  9. 0x00008d06 <+>: adds r3, #
  10. 0x00008d08 <+>: push {r3}
  11. 0x00008d0a <+>: pop {pc}
  12. 0x00008d0c <+>: pop {r6} ; (ldr r6, [sp], #4)
  13. 0x00008d10 <+>: mov r0, r3
  14. 0x00008d14 <+>: sub sp, r11, #
  15. 0x00008d18 <+>: pop {r11} ; (ldr r11, [sp], #4)
  16. 0x00008d1c <+>: bx lr
  17. 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 <+>: push {r11} ; (str r11, [sp, #-4]!)
  4. 0x00008d24 <+>: add r11, sp, #
  5. 0x00008d28 <+>: mov r3, lr
  6. 0x00008d2c <+>: mov r0, r3
  7. 0x00008d30 <+>: sub sp, r11, #
  8. 0x00008d34 <+>: pop {r11} ; (ldr r11, [sp], #4)
  9. 0x00008d38 <+>: 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 <+>: push {r4, r11, lr}
  4. 0x00008d40 <+>: add r11, sp, #
  5. 0x00008d44 <+>: sub sp, sp, #
  6. 0x00008d48 <+>: mov r3, #
  7. 0x00008d4c <+>: str r3, [r11, #-16]
  8. 0x00008d50 <+>: ldr r0, [pc, #104] ; 0x8dc0 <main+132>
  9. 0x00008d54 <+>: bl 0xfb6c <printf>
  10. 0x00008d58 <+>: sub r3, r11, #
  11. 0x00008d5c <+>: ldr r0, [pc, #96] ; 0x8dc4 <main+136>
  12. 0x00008d60 <+>: mov r1, r3
  13. 0x00008d64 <+>: bl 0xfbd8 <__isoc99_scanf>
  14. 0x00008d68 <+>: bl 0x8cd4 <key1>
  15. 0x00008d6c <+>: mov r4, r0
  16. 0x00008d70 <+>: bl 0x8cf0 <key2>
  17. 0x00008d74 <+>: mov r3, r0
  18. 0x00008d78 <+>: add r4, r4, r3
  19. 0x00008d7c <+>: bl 0x8d20 <key3>
  20. 0x00008d80 <+>: mov r3, r0
  21. 0x00008d84 <+>: add r2, r4, r3
  22. 0x00008d88 <+>: ldr r3, [r11, #-16]
  23. 0x00008d8c <+>: cmp r2, r3
  24. 0x00008d90 <+>: bne 0x8da8 <main+>
  25. 0x00008d94 <+>: ldr r0, [pc, #44] ; 0x8dc8 <main+140>
  26. 0x00008d98 <+>: bl 0x1050c <puts>
  27. 0x00008d9c <+>: ldr r0, [pc, #40] ; 0x8dcc <main+144>
  28. 0x00008da0 <+>: bl 0xf89c <system>
  29. 0x00008da4 <+>: b 0x8db0 <main+>
  30. 0x00008da8 <+>: ldr r0, [pc, #32] ; 0x8dd0 <main+148>
  31. 0x00008dac <+>: bl 0x1050c <puts>
  32. 0x00008db0 <+>: mov r3, #
  33. 0x00008db4 <+>: mov r0, r3
  34. 0x00008db8 <+>: sub sp, r11, #
  35. 0x00008dbc <+>: pop {r4, r11, pc}
  36. 0x00008dc0 <+>: andeq r10, r6, r12, lsl #
  37. 0x00008dc4 <+>: andeq r10, r6, r12, lsr #
  38. 0x00008dc8 <+>: ; <UNDEFINED> instruction: 0x0006a4b0
  39. 0x00008dcc <+>: ; <UNDEFINED> instruction: 0x0006a4bc
  40. 0x00008dd0 <+>: andeq r10, r6, r4, asr #
  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

得到结果:

pwnable.kr leg之write up的更多相关文章

  1. 【pwnable.kr】leg

    pwnable从入门到放弃第八题. Download : http://pwnable.kr/bin/leg.cDownload : http://pwnable.kr/bin/leg.asm ssh ...

  2. pwnable.kr详细通关秘籍(二)

    i春秋作家:W1ngs 原文来自:pwnable.kr详细通关秘籍(二) 0x00 input 首先看一下代码: 可以看到程序总共有五步,全部都满足了才可以得到flag,那我们就一步一步来看 这道题考 ...

  3. pwnable.kr的passcode

    前段时间找到一个练习pwn的网站,pwnable.kr 这里记录其中的passcode的做题过程,给自己加深印象. 废话不多说了,看一下题目, 看到题目,就ssh连接进去,就看到三个文件如下 看了一下 ...

  4. pwnable.kr bof之write up

    这一题与前两题不同,用到了静态调试工具ida 首先题中给出了源码: #include <stdio.h> #include <string.h> #include <st ...

  5. pwnable.kr col之write up

    Daddy told me about cool MD5 hash collision today. I wanna do something like that too! ssh col@pwnab ...

  6. pwnable.kr brainfuck之write up

    I made a simple brain-fuck language emulation program written in C. The [ ] commands are not impleme ...

  7. pwnable.kr login之write up

    main函数如下: auth函数如下: 程序的流程如下: 输入Authenticate值,并base64解码,将解码的值代入md5_auth函数中 mad5_auth()生成其MD5值并与f87cd6 ...

  8. pwnable.kr simple login writeup

    这道题是pwnable.kr Rookiss部分的simple login,需要我们去覆盖程序的ebp,eip,esp去改变程序的执行流程   主要逻辑是输入一个字符串,base64解码后看是否与题目 ...

  9. pwnable.kr第二天

    3.bof 这题就是简单的数组越界覆盖,直接用gdb 调试出偏移就ok from pwn import * context.log_level='debug' payload='A'*52+p32(0 ...

随机推荐

  1. ThinkPHP 前台视图实现类似于Yii的自动验证

    ThinkPHP model类其实自带这个功能 可以写一个基础类继承Model 模型层代码: <?php namespace Manager\Model; use Think\Model; cl ...

  2. grid编辑后时间格式不对问题

    在column中应该定义xtype和format格式: xtype: 'datecolumn', format:'Y-m-d'   之后正常

  3. CC2530入门教程-02】CC2530的通用I/O端口输入和输出控制

    第2课  CC2530的通用I/O端口输入和输出控制 广东职业技术学院  欧浩源 一.CC2530的引脚概述 CC2530微控制器采用QFN40封装,有40 个引脚.其中,有21个数字I/O端口,其中 ...

  4. v9.5.2上传缩略图/附件提示“undefined”

    把phpcms\modules\attachment\attachments.php中将                        if(empty($this->userid)){改成  ...

  5. CSharpGL(42)借助帧缓存实现渲染到纹理(RenderToTexture)

    CSharpGL(42)借助帧缓存实现渲染到纹理(RenderToTexture) 渲染到纹理(Render To Texture)是实现很多OpenGL高级效果的一个基础.本文记录了如何用CShar ...

  6. Notepad++中过滤掉的正则方式

    2 => 'ashadv'3 => 'aogro'4 => 'aogs'5 => 'ashamw'6 => 'arc'8 => 'gtsatq'9 => 'b ...

  7. group by和count联合使用问题

    要根据用户发布的产品数量来排序做分页,使用group ) FROM( SELECT uid,COU 工作中要根据用户发布的产品数量来排序做分页,使用group by uid 用count(uid) 来 ...

  8. 【Android Developers Training】 19. 序言:通过Fragments构建动态UI

    注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...

  9. USACO hamming

    考试周终于过去了一半,可以继续写USACO了. 先来看一下题目吧. Hamming CodesRob Kolstad Given N, B, and D: Find a set of N codewo ...

  10. 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)

    本文分析了HashMap的实现原理,以及resize可能引起死循环和Fast-fail等线程不安全行为.同时结合源码从数据结构,寻址方式,同步方式,计算size等角度分析了JDK 1.7和JDK 1. ...