通过下面的.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的返回地址处。
813K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6*7K9h3E0Z5x3U0k6Q4x3X3g2Y4K9i4c8Z5N6h3u0Q4x3X3g2A6L8#2)9J5c8Y4m8G2M7%4c8K6i4K6u0r3z5e0p5&6j5K6t1&6j5K6c8Q4x3X3g2Z5N6r3#2D9
ea1K9s2c8@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
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!
最后于 2025-3-20 11:24
被kuban编辑
,原因: 重新上传图片