通过下面的.sh脚本一键安装
预编译的c程序:
MIPS跟x86架构一样,MIPS程序也有32位、64位、大端序和小端序的区分,编译不同文件所需的命令如下
用file和readelf验证编译的MIPS程序

使用qemu-xxxx-static
模拟运行对应的文件即可

去掉-static
参数就可以了
同样可以用file和readelf命令查看文件详情,这里就看一下32位小端的

动态编译的程序需要指定动态链接库。在ubuntu中,mips的动态依赖库安装在了/usr/
目录中

如果不在,用find命令找一个这个文件夹,比如

找到动态链接库后,加上参数-L /usr/mipsel-linux-gnu
就可以了
以动态链接的32位小端为例

以demo_32_little为例,首先命令行输入qemu-mipsel -g 2234 ./demo_32_little
在2234端口运行。

再打开另一个命令行,打开gdb-multiarch
调试工具,依次输入

成功进入调试界面。

在调试界面输入info registers
查看该程序中的寄存器

比x86多很多,我们分为两类,一类是通用寄存器(黄色部分),一类是特殊寄存器。
通用寄存器
特殊寄存器
这里先介绍三个:lo、hi和$pc:
在讲MIPS程序的函数调用约定前,先要明确:
函数A调用函数B,如果函数B是叶子函数,那么在跳转到B函数的时候,$ra
寄存器中会存入函数B的返回地址;
如果函数B是非叶子函数,在跳转到B函数的时候,先在$ra
寄存器中存入函数B的返回地址,并且在栈中记录$ra
寄存器的值。
因为函数B在内部还要调用其他函数,$ra
寄存器会变,程序在从函数B返回到函数A的时候,就可以从栈中将之前记录的值读到$ra
寄存器,就可以返回到函数A了。
参数的传递
· 前四个参数:如果函数的参数数量小于或等于四个,这些参数会依次存放在$a0、$a1、$a2、$a3
寄存器中。
· 多于四个的参数:多出的参数会被存放到栈中。即调用者(函数 A)会在自己的栈顶为被调用者(函数 B)的参数预留空间,并将多出的参数存入该空间。
· 即使参数数量少于或等于四个,调用者(函数 A)仍然需要在栈中为被调用者(函数 B)的前四个参数预留空间。
· 被调用者(函数 B)会将前四个参数从$a0 ~ $a3
寄存器复制到栈中预留的空间——这个空间被称为调用参数空间
。
有了上面的基础之后,我们就可以调试demo_32_little
对MIPS架构的寄存器、汇编指令和函数调用约定做一个实例分析,加深印象。
首先在IDA里面打开demo_32_little
,找到main函数的起始地址0x4007DC

为了调试方便,使用symbol-file ./demo_32_little
加载符号表

进入调试后,下断点到main函数处,c
跳到断点处

main函数开头如下,从main函数栈帧的布置和跳转到调用的mySum函数
下面的表格是每行汇编执行前后相应寄存器或内存地址的变化,从中我们关注一下mips开辟栈帧的方式,以及调用函数时的变化
[
、]
代表该内存中的值(即C语言中的解引用)
$fp
和$s8
是有区分的,IDA会混淆这两个寄存器,gdb-multiarch会将所有的$fp
和$s8
都辨别为$fp
,在调试分析时要注意
注意:
si
进入mySum函数
X86架构和MIPS架构的栈帧布局对比:

我们知道,main函数其实是被__libc_start_main
函数调用的,在这个demo中,其实main函数是非叶子函数,我们刚才说过,调用叶子函数和调用非叶子函数的栈帧布局是不一样的:调用非叶子函数时在$fp-0x4
的位置记录当前$ra
的值,也就是上面图片中的0x400930(main_ret_addr)
。
回过头再看一下对main函数的分析中的第二行,正是做了这件事情:

那么在main函数返回的时候,想当然也是先要从$fp-0x4
的位置读值到$ra
,然后jr ra;nop
即可。
验证一下,一路ni来到return 0;
处

这一段的汇编如下:
其中这条语句lw ra,36(sp)
,就是把先前记录在栈上的0x400930
读到了寄存器中

继而jr ra;nop
,跳转到main的返回地址处。
02cK9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6*7K9h3E0Z5x3U0k6Q4x3X3g2Y4K9i4c8Z5N6h3u0Q4x3X3g2A6L8#2)9J5c8Y4m8G2M7%4c8K6i4K6u0r3z5e0p5&6j5K6t1&6j5K6c8Q4x3X3g2Z5N6r3#2D9
171K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6%4N6%4N6Q4x3X3g2&6N6i4q4#2k6g2)9J5k6h3y4G2L8g2)9J5c8X3y4&6j5X3g2J5j5h3&6Y4k6h3I4Q4x3V1k6J5k6K6W2Y4k6r3#2Q4x3V1k6&6P5r3t1H3y4U0M7`.
sudo apt install qemu
-
user
-
static
sudo apt install qemu
-
system
-
mips
sudo apt install binfmt
-
support
sudo apt install gdb
-
multiarch
sudo apt
-
get install gcc
-
mips
-
linux
-
gnu
sudo apt
-
get install gcc
-
mipsel
-
linux
-
gnu
sudo apt
-
get install gcc
-
mips64
-
linux
-
gnuabi64
sudo apt
-
get install gcc
-
mips64el
-
linux
-
gnuabi64
sudo apt install qemu
-
user
-
static
sudo apt install qemu
-
system
-
mips
sudo apt install binfmt
-
support
sudo apt install gdb
-
multiarch
sudo apt
-
get install gcc
-
mips
-
linux
-
gnu
sudo apt
-
get install gcc
-
mipsel
-
linux
-
gnu
sudo apt
-
get install gcc
-
mips64
-
linux
-
gnuabi64
sudo apt
-
get install gcc
-
mips64el
-
linux
-
gnuabi64
int
mySum(
int
a,
int
b)
{
int
value
=
a
+
b;
return
value;
}
int
main()
{
int
result
=
mySum(
1
,
2
);
printf(
"%d\n"
,result);
return
0
;
}
int
mySum(
int
a,
int
b)
{
int
value
=
a
+
b;
return
value;
}
int
main()
{
int
result
=
mySum(
1
,
2
);
printf(
"%d\n"
,result);
return
0
;
}
mipsel
-
linux
-
gnu
-
gcc demo.c
-
o demo_32_little
-
static
-
g
mips64el
-
linux
-
gnuabi64
-
gcc demo.c
-
o demo_64_little
-
static
-
g
mips
-
linux
-
gnu
-
gcc demo.c
-
o demo_32_big
-
static
-
g
mips64
-
linux
-
gnuabi64
-
gcc demo.c
-
o demo_64_big
-
static
-
g
mipsel
-
linux
-
gnu
-
gcc demo.c
-
o demo_32_little
-
static
-
g
mips64el
-
linux
-
gnuabi64
-
gcc demo.c
-
o demo_64_little
-
static
-
g
mips
-
linux
-
gnu
-
gcc demo.c
-
o demo_32_big
-
static
-
g
mips64
-
linux
-
gnuabi64
-
gcc demo.c
-
o demo_64_big
-
static
-
g
qemu
-
mipsel
-
static .
/
demo_32_little
qemu
-
mips
-
static .
/
demo_32_big
qemu
-
mips64el
-
static .
/
demo_64_little
qemu
-
mips64
-
static .
/
demo_64_big
qemu
-
mipsel
-
static .
/
demo_32_little
qemu
-
mips
-
static .
/
demo_32_big
qemu
-
mips64el
-
static .
/
demo_64_little
qemu
-
mips64
-
static .
/
demo_64_big
mipsel
-
linux
-
gnu
-
gcc demo.c
-
o demo_32_little_dy
-
g
mips64el
-
linux
-
gnuabi64
-
gcc demo.c
-
o demo_64_little_dy
-
g
mips
-
linux
-
gnu
-
gcc demo.c
-
o demo_32_big_dy
-
g
mips64
-
linux
-
gnuabi64
-
gcc demo.c
-
o demo_64_big_dy
-
g
mipsel
-
linux
-
gnu
-
gcc demo.c
-
o demo_32_little_dy
-
g
mips64el
-
linux
-
gnuabi64
-
gcc demo.c
-
o demo_64_little_dy
-
g
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课
最后于 2025-3-20 11:24
被kuban编辑
,原因: 重新上传图片