pwnable.kr leg之write up
看代码:
- #include <stdio.h>
- #include <fcntl.h>
- int key1(){
- asm("mov r3, pc\n");
- }
- int key2(){
- asm(
- "push {r6}\n"
- "add r6, pc, $1\n"
- "bx r6\n"
- ".code 16\n"
- "mov r3, pc\n"
- "add r3, $0x4\n"
- "push {r3}\n"
- "pop {pc}\n"
- ".code 32\n"
- "pop {r6}\n"
- );
- }
- int key3(){
- asm("mov r3, lr\n");
- }
- int main(){
- int key=;
- 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[];
- int r = read(fd, buf, );
- write(, buf, r);
- }
- else{
- printf("I have strong leg :P\n");
- }
- return ;
- }
C Code
- #include <stdio.h>
- #include <fcntl.h>
- int key1(){
- asm("mov r3, pc\n");
- }
- int key2(){
- asm(
- "push {r6}\n"
- "add r6, pc, $1\n"
- "bx r6\n"
- ".code 16\n"
- "mov r3, pc\n"
- "add r3, $0x4\n"
- "push {r3}\n"
- "pop {pc}\n"
- ".code 32\n"
- "pop {r6}\n"
- );
- }
- int key3(){
- asm("mov r3, lr\n");
- }
- int main(){
- int key=;
- 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[];
- int r = read(fd, buf, );
- write(, buf, r);
- }
- else{
- printf("I have strong leg :P\n");
- }
- return ;
- }
分析代码,key1()+key2()+key3()==key时,得到flag
那么来分析给定的汇编代码:
- (gdb) disass key1
- Dump of assembler code for function key1:
- 0x00008cd4 <+>: push {r11} ; (str r11, [sp, #-4]!)
- 0x00008cd8 <+>: add r11, sp, #
- 0x00008cdc <+>: mov r3, pc
- 0x00008ce0 <+>: mov r0, r3
- 0x00008ce4 <+>: sub sp, r11, #
- 0x00008ce8 <+>: pop {r11} ; (ldr r11, [sp], #4)
- 0x00008cec <+>: bx lr
- End of assembler dump.
返回地址是r0而r0等于pc,且为arm指令
补充知识:
- PC代表程序计数器,流水线使用三个阶段,因此指令分为三个阶段执行:.取指(从存储器装载一条指令);.译码(识别将要被执行的指令);.执行(处理指令并将结果写回寄存器)。而R15
(PC)总是指向“正在取指”的指令,而不是指向“正在执行”的指令或正在“译码”的指令。一般来说,人们习惯性约定将“正在执行的指令作为参考点”,称之为当前第一条指令,因此PC总是指向第三
条指令。当ARM状态时,每条指令为4字节长,所以PC始终指向该指令地址加8字节的地址,即:PC值=当前程序执行位置+;- ARM指令是三级流水线,取指,译指,执行时同时执行的,现在PC指向的是正在取指的地址,那么cpu正在译指的指令地址是PC-(假设在ARM状态下,一个指令占4个字节),cpu正在执行的指令地
址是PC-,也就是说PC所指向的地址和现在所执行的指令地址相差8。
所以
r0的地址等于0x8cdc+0x8
再看key2:
- (gdb) disass key2
- Dump of assembler code for function key2:
- 0x00008cf0 <+>: push {r11} ; (str r11, [sp, #-4]!)
- 0x00008cf4 <+>: add r11, sp, #
- 0x00008cf8 <+>: push {r6} ; (str r6, [sp, #-4]!)
- 0x00008cfc <+>: add r6, pc, #
- 0x00008d00 <+>: bx r6
- 0x00008d04 <+>: mov r3, pc
- 0x00008d06 <+>: adds r3, #
- 0x00008d08 <+>: push {r3}
- 0x00008d0a <+>: pop {pc}
- 0x00008d0c <+>: pop {r6} ; (ldr r6, [sp], #4)
- 0x00008d10 <+>: mov r0, r3
- 0x00008d14 <+>: sub sp, r11, #
- 0x00008d18 <+>: pop {r11} ; (ldr r11, [sp], #4)
- 0x00008d1c <+>: 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:
- (gdb) disass key3
- Dump of assembler code for function key3:
- 0x00008d20 <+>: push {r11} ; (str r11, [sp, #-4]!)
- 0x00008d24 <+>: add r11, sp, #
- 0x00008d28 <+>: mov r3, lr
- 0x00008d2c <+>: mov r0, r3
- 0x00008d30 <+>: sub sp, r11, #
- 0x00008d34 <+>: pop {r11} ; (ldr r11, [sp], #4)
- 0x00008d38 <+>: bx lr
- End of assembler dump.
- (gdb)
返回地址为r0,r0=lr,而lr保存返回地址
返回到main函数:
- (gdb) disass main
- Dump of assembler code for function main:
- 0x00008d3c <+>: push {r4, r11, lr}
- 0x00008d40 <+>: add r11, sp, #
- 0x00008d44 <+>: sub sp, sp, #
- 0x00008d48 <+>: mov r3, #
- 0x00008d4c <+>: str r3, [r11, #-16]
- 0x00008d50 <+>: ldr r0, [pc, #104] ; 0x8dc0 <main+132>
- 0x00008d54 <+>: bl 0xfb6c <printf>
- 0x00008d58 <+>: sub r3, r11, #
- 0x00008d5c <+>: ldr r0, [pc, #96] ; 0x8dc4 <main+136>
- 0x00008d60 <+>: mov r1, r3
- 0x00008d64 <+>: bl 0xfbd8 <__isoc99_scanf>
- 0x00008d68 <+>: bl 0x8cd4 <key1>
- 0x00008d6c <+>: mov r4, r0
- 0x00008d70 <+>: bl 0x8cf0 <key2>
- 0x00008d74 <+>: mov r3, r0
- 0x00008d78 <+>: add r4, r4, r3
- 0x00008d7c <+>: bl 0x8d20 <key3>
- 0x00008d80 <+>: mov r3, r0
- 0x00008d84 <+>: add r2, r4, r3
- 0x00008d88 <+>: ldr r3, [r11, #-16]
- 0x00008d8c <+>: cmp r2, r3
- 0x00008d90 <+>: bne 0x8da8 <main+>
- 0x00008d94 <+>: ldr r0, [pc, #44] ; 0x8dc8 <main+140>
- 0x00008d98 <+>: bl 0x1050c <puts>
- 0x00008d9c <+>: ldr r0, [pc, #40] ; 0x8dcc <main+144>
- 0x00008da0 <+>: bl 0xf89c <system>
- 0x00008da4 <+>: b 0x8db0 <main+>
- 0x00008da8 <+>: ldr r0, [pc, #32] ; 0x8dd0 <main+148>
- 0x00008dac <+>: bl 0x1050c <puts>
- 0x00008db0 <+>: mov r3, #
- 0x00008db4 <+>: mov r0, r3
- 0x00008db8 <+>: sub sp, r11, #
- 0x00008dbc <+>: pop {r4, r11, pc}
- 0x00008dc0 <+>: andeq r10, r6, r12, lsl #
- 0x00008dc4 <+>: andeq r10, r6, r12, lsr #
- 0x00008dc8 <+>: ; <UNDEFINED> instruction: 0x0006a4b0
- 0x00008dcc <+>: ; <UNDEFINED> instruction: 0x0006a4bc
- 0x00008dd0 <+>: andeq r10, r6, r4, asr #
- End of assembler dump.
第20行,key3的地址为0x8d80,
python得到key的值:
- #/usr/bin/python
- key1=0x8cdc+0x8
- key2=0x8d04+0x4+0x4
- key3=0x8d80
- key=key1+key2+key3
- print key
得到结果:
pwnable.kr leg之write up的更多相关文章
- 【pwnable.kr】leg
pwnable从入门到放弃第八题. Download : http://pwnable.kr/bin/leg.cDownload : http://pwnable.kr/bin/leg.asm ssh ...
- pwnable.kr详细通关秘籍(二)
i春秋作家:W1ngs 原文来自:pwnable.kr详细通关秘籍(二) 0x00 input 首先看一下代码: 可以看到程序总共有五步,全部都满足了才可以得到flag,那我们就一步一步来看 这道题考 ...
- pwnable.kr的passcode
前段时间找到一个练习pwn的网站,pwnable.kr 这里记录其中的passcode的做题过程,给自己加深印象. 废话不多说了,看一下题目, 看到题目,就ssh连接进去,就看到三个文件如下 看了一下 ...
- pwnable.kr bof之write up
这一题与前两题不同,用到了静态调试工具ida 首先题中给出了源码: #include <stdio.h> #include <string.h> #include <st ...
- pwnable.kr col之write up
Daddy told me about cool MD5 hash collision today. I wanna do something like that too! ssh col@pwnab ...
- pwnable.kr brainfuck之write up
I made a simple brain-fuck language emulation program written in C. The [ ] commands are not impleme ...
- pwnable.kr login之write up
main函数如下: auth函数如下: 程序的流程如下: 输入Authenticate值,并base64解码,将解码的值代入md5_auth函数中 mad5_auth()生成其MD5值并与f87cd6 ...
- pwnable.kr simple login writeup
这道题是pwnable.kr Rookiss部分的simple login,需要我们去覆盖程序的ebp,eip,esp去改变程序的执行流程 主要逻辑是输入一个字符串,base64解码后看是否与题目 ...
- pwnable.kr第二天
3.bof 这题就是简单的数组越界覆盖,直接用gdb 调试出偏移就ok from pwn import * context.log_level='debug' payload='A'*52+p32(0 ...
随机推荐
- ThinkPHP 前台视图实现类似于Yii的自动验证
ThinkPHP model类其实自带这个功能 可以写一个基础类继承Model 模型层代码: <?php namespace Manager\Model; use Think\Model; cl ...
- grid编辑后时间格式不对问题
在column中应该定义xtype和format格式: xtype: 'datecolumn', format:'Y-m-d' 之后正常
- CC2530入门教程-02】CC2530的通用I/O端口输入和输出控制
第2课 CC2530的通用I/O端口输入和输出控制 广东职业技术学院 欧浩源 一.CC2530的引脚概述 CC2530微控制器采用QFN40封装,有40 个引脚.其中,有21个数字I/O端口,其中 ...
- v9.5.2上传缩略图/附件提示“undefined”
把phpcms\modules\attachment\attachments.php中将 if(empty($this->userid)){改成 ...
- CSharpGL(42)借助帧缓存实现渲染到纹理(RenderToTexture)
CSharpGL(42)借助帧缓存实现渲染到纹理(RenderToTexture) 渲染到纹理(Render To Texture)是实现很多OpenGL高级效果的一个基础.本文记录了如何用CShar ...
- Notepad++中过滤掉的正则方式
2 => 'ashadv'3 => 'aogro'4 => 'aogs'5 => 'ashamw'6 => 'arc'8 => 'gtsatq'9 => 'b ...
- group by和count联合使用问题
要根据用户发布的产品数量来排序做分页,使用group ) FROM( SELECT uid,COU 工作中要根据用户发布的产品数量来排序做分页,使用group by uid 用count(uid) 来 ...
- 【Android Developers Training】 19. 序言:通过Fragments构建动态UI
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- USACO hamming
考试周终于过去了一半,可以继续写USACO了. 先来看一下题目吧. Hamming CodesRob Kolstad Given N, B, and D: Find a set of N codewo ...
- 从ConcurrentHashMap的演进看Java多线程核心技术 Java进阶(六)
本文分析了HashMap的实现原理,以及resize可能引起死循环和Fast-fail等线程不安全行为.同时结合源码从数据结构,寻址方式,同步方式,计算size等角度分析了JDK 1.7和JDK 1. ...