Qemu搭建arm解题小练习

qemu 是一个在 linux 上广泛使用的可以模拟 ARM 的模拟器。通过交叉编译工具,我们就可以在 CPU 能力很强、存储空间足够的主机平台上(比如 PC 上)编译出针对其他平台的可执行程序。在安装 qemu 模拟器之前安装了交叉编译工具链,满足交叉编译的要求,然后安装了相应的依赖库以满足 qemu 的正常运行。

qemu-arm和qemu-system-arm的区别:

qemu-arm是用户模式的模拟器(更精确的表述应该是系统调用模拟器),而qemu-system-arm则是系统模拟器,它可以模拟出整个机器并运行操作系统
qemu-arm仅可用来运行二进制文件,因此你可以交叉编译完例如hello world之类的程序然后交给qemu-arm来运行,简单而高效。而qemu-system-arm则需要你把hello world程序下载到客户机操作系统能访问到的硬盘里才能运行。

运行环境具体搭建可见博文:https://blog.csdn.net/tycoon1988/article/details/46530063

实战演练:
1.file guest //查看文件格式 checksec guest //查看保护机制
在这里插入图片描述
可以看见是32位可执行文件,正常查看安全防护,开启了 DEP 保护后栈上就没有执行的权限也就无法控制程序流程。
此处要加深一下印象,之前学的模模糊糊的。一存在溢出漏洞的程序,当处理某些文件时未能检查文件长度的限制,导致栈区溢出,若不开启DEP保护,则溢出后EIP可以跳转至栈区执行指令,而当添加了DEP保护后,由于栈区被标记为不可执行。

一般题目中有目标函数,直接覆盖返回地址到函数入口就可以getshell,
其他题,需要执行指令拿shell,即编写shellcode。当获取任意地址读写能力时,即可写入shellcode,再执行此处的代码即可。了解到开启PIE(内存空间随机化)的话可以防范基于return2libc方式的针对DEP的攻击,这里没开启哈哈哈哈。

2.既然是32位的,当然要拉进ida里康康咯
不看不知道,一看吓一跳(第一反应确实如此)
在这里插入图片描述
第一疑惑,没有main函数,所有东西都去符号了,挨个F5反编译一下中间白色地带的函数。
#IDA里的一些表示:
sub_XXXXX 地址XXXX的子例程
loc_XXXXX 地址XXXX的一个指令
byte/word/dword_XXXXX 地址XXXX的8/16/32位数据
unk_XXXXX 地址XXXX的未知数据

反编译结果如下:

__int64 sub_10500()
{
return sub_104A0();
}

sub_10500函数的功能是return sub_104A0();

   __int64 sub_104A0()
   {
   __int64 result; // r0
   LODWORD(result) = &unk_21034;
   HIDWORD(result) = 0;
   return result;
   }

这是在32位系统上为变量分配64位值的典型模式——分别计算每个32位值,然后将它们推入64位值的高32位和低32位。

“LODWORD()”从“result”和“HIDWORD()”中提取了低DWORD,而“HIDWORD()”从高DWORD中提取了高DWORD。
(DWORD 就是 Double Word, 每个word为2个字节的长度,DWORD 双字即为4个字节,每个字节是8位,共32位。DWORD在Windows下经常用来保存地址(或者存放指针))

sub_104A0函数的功能是返回result—低32位是未知地址unk_21034的数据,高32位为0.

点进unk_21034未知地址,

  LOAD:00021034                 ; ORG 0x21034
  LOAD:00021034 unk_21034       % 1                     ; DATA XREF: sub_10470+4↑o
  LOAD:00021034                                         ; .text:off_10498↑o ...     

LOAD是取后面地址单元的内容,放到前面地址单元里面去。SORE是把前面地址的内容存储到后面地址单元里面去。也就是说未知地址unk_21034里存放的就是1?一会在gdb里确认一下就好。

 void *sub_10470()
 {
 return &unk_21034;
 }

sub_10470函数也是返回这个地址;啥情况

   void sub_10538()
   {
   setbuf((FILE *)stdin, 0);
   setbuf((FILE *)stdout, 0);
   setbuf((FILE *)stderr, 0);
   }

sub_10538 ,就是调用一些标准输入输出的函数
C 库函数 void setbuf(FILE *stream, char *buffer) 定义流 stream 应如何缓冲。该函数应在与流 stream 相关的文件被打开时,且还未发生任何输入或输出操作之前被调用一次

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值