arm64 的 rop 实现C代码
时间: 2024-05-10 20:21:22 浏览: 101
由于 ARM64 架构的指令集比较复杂,实现 ROP 需要理解 ARM64 的寄存器和指令的用途和操作,因此比较困难。以下是一个简单的示例:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
void gadget1() {
asm("mov x0, 0x1\n"
"mov x1, 0x2\n"
"mov x2, 0x3\n"
"mov x3, 0x4\n"
"mov x4, 0x5\n"
"mov x5, 0x6\n"
"mov x6, 0x7\n"
"mov x7, 0x8\n"
"mov x8, 0x9\n"
"mov x9, 0xa\n"
"mov x10, 0xb\n"
"mov x11, 0xc\n"
"mov x12, 0xd\n"
"mov x13, 0xe\n"
"mov x14, 0xf\n"
"mov x15, 0x10\n"
"mov x16, 0x11\n"
"mov x17, 0x12\n"
"mov x18, 0x13\n"
"mov x19, 0x14\n"
"mov x20, 0x15\n"
"mov x21, 0x16\n"
"mov x22, 0x17\n"
"mov x23, 0x18\n"
"mov x24, 0x19\n"
"mov x25, 0x1a\n"
"mov x26, 0x1b\n"
"mov x27, 0x1c\n"
"mov x28, 0x1d\n"
"mov x29, 0x1e\n"
"mov x30, 0x1f\n"
"ret");
}
void gadget2() {
asm("mov x0, 0xdeadbeef\n"
"mov x1, 0xcafebabe\n"
"mov x2, 0xfeedface\n"
"mov x3, 0xabcdef01\n"
"mov x4, 0x12345678\n"
"mov x5, 0x87654321\n"
"mov x6, 0xabcdef01\n"
"mov x7, 0xdeadbeef\n"
"mov x8, 0xcafebabe\n"
"mov x9, 0xfeedface\n"
"mov x10, 0xabcdef01\n"
"mov x11, 0x12345678\n"
"mov x12, 0x87654321\n"
"mov x13, 0xabcdef01\n"
"mov x14, 0xdeadbeef\n"
"mov x15, 0xcafebabe\n"
"mov x16, 0xfeedface\n"
"mov x17, 0xabcdef01\n"
"mov x18, 0x12345678\n"
"mov x19, 0x87654321\n"
"mov x20, 0xabcdef01\n"
"mov x21, 0xdeadbeef\n"
"mov x22, 0xcafebabe\n"
"mov x23, 0xfeedface\n"
"mov x24, 0xabcdef01\n"
"mov x25, 0x12345678\n"
"mov x26, 0x87654321\n"
"mov x27, 0xabcdef01\n"
"mov x28, 0xdeadbeef\n"
"mov x29, 0xcafebabe\n"
"mov x30, 0xfeedface\n"
"ret");
}
void gadget3() {
asm("mov x0, 0x12345678\n"
"mov x1, 0x87654321\n"
"mov x2, 0xabcdef01\n"
"mov x3, 0xdeadbeef\n"
"mov x4, 0xcafebabe\n"
"mov x5, 0xfeedface\n"
"mov x6, 0x12345678\n"
"mov x7, 0x87654321\n"
"mov x8, 0xabcdef01\n"
"mov x9, 0xdeadbeef\n"
"mov x10, 0xcafebabe\n"
"mov x11, 0xfeedface\n"
"mov x12, 0x12345678\n"
"mov x13, 0x87654321\n"
"mov x14, 0xabcdef01\n"
"mov x15, 0xdeadbeef\n"
"mov x16, 0xcafebabe\n"
"mov x17, 0xfeedface\n"
"mov x18, 0x12345678\n"
"mov x19, 0x87654321\n"
"mov x20, 0xabcdef01\n"
"mov x21, 0xdeadbeef\n"
"mov x22, 0xcafebabe\n"
"mov x23, 0xfeedface\n"
"mov x24, 0x12345678\n"
"mov x25, 0x87654321\n"
"mov x26, 0xabcdef01\n"
"mov x27, 0xdeadbeef\n"
"mov x28, 0xcafebabe\n"
"mov x29, 0xfeedface\n"
"mov x30, 0x12345678\n"
"ret");
}
void gadget4() {
asm("mov x0, 0xdeadbeef\n"
"mov x1, 0xcafebabe\n"
"mov x2, 0xfeedface\n"
"mov x3, 0xabcdef01\n"
"mov x4, 0x12345678\n"
"mov x5, 0x87654321\n"
"mov x6, 0xabcdef01\n"
"mov x7, 0xdeadbeef\n"
"mov x8, 0xcafebabe\n"
"mov x9, 0xfeedface\n"
"mov x10, 0xabcdef01\n"
"mov x11, 0x12345678\n"
"mov x12, 0x87654321\n"
"mov x13, 0xabcdef01\n"
"mov x14, 0xdeadbeef\n"
"mov x15, 0xcafebabe\n"
"mov x16, 0xfeedface\n"
"mov x17, 0xabcdef01\n"
"mov x18, 0x12345678\n"
"mov x19, 0x87654321\n"
"mov x20, 0xabcdef01\n"
"mov x21, 0xdeadbeef\n"
"mov x22, 0xcafebabe\n"
"mov x23, 0xfeedface\n"
"mov x24, 0xabcdef01\n"
"mov x25, 0x12345678\n"
"mov x26, 0x87654321\n"
"mov x27, 0xabcdef01\n"
"mov x28, 0xdeadbeef\n"
"mov x29, 0xcafebabe\n"
"mov x30, 0xfeedface\n"
"ret");
}
void gadget5() {
asm("mov x0, 0xdeadbeef\n"
"mov x1, 0xcafebabe\n"
"mov x2, 0xfeedface\n"
"mov x3, 0xabcdef01\n"
"mov x4, 0x12345678\n"
"mov x5, 0x87654321\n"
"mov x6, 0xabcdef01\n"
"mov x7, 0xdeadbeef\n"
"mov x8, 0xcafebabe\n"
"mov x9, 0xfeedface\n"
"mov x10, 0xabcdef01\n"
"mov x11, 0x12345678\n"
"mov x12, 0x87654321\n"
"mov x13, 0xabcdef01\n"
"mov x14, 0xdeadbeef\n"
"mov x15, 0xcafebabe\n"
"mov x16, 0xfeedface\n"
"mov x17, 0xabcdef01\n"
"mov x18, 0x12345678\n"
"mov x19, 0x87654321\n"
"mov x20, 0xabcdef01\n"
"mov x21, 0xdeadbeef\n"
"mov x22, 0xcafebabe\n"
"mov x23, 0xfeedface\n"
"mov x24, 0xabcdef01\n"
"mov x25, 0x12345678\n"
"mov x26, 0x87654321\n"
"mov x27, 0xabcdef01\n"
"mov x28, 0xdeadbeef\n"
"mov x29, 0xcafebabe\n"
"mov x30, 0xfeedface\n"
"ret");
}
void vuln(char *str) {
char buf[128];
strcpy(buf, str);
printf("buf=%s\n", buf);
}
int main(int argc, char **argv) {
char buf[128];
memset(buf, 0, sizeof(buf));
fgets(buf, sizeof(buf), stdin);
if (argc > 1) {
if (strcmp(argv[1], "1") == 0) {
gadget1();
} else if (strcmp(argv[1], "2") == 0) {
gadget2();
} else if (strcmp(argv[1], "3") == 0) {
gadget3();
} else if (strcmp(argv[1], "4") == 0) {
gadget4();
} else if (strcmp(argv[1], "5") == 0) {
gadget5();
}
}
vuln(buf);
return 0;
}
```
该代码包含了 5 个 gadget 函数,每个函数都会将一些值存入寄存器中,然后返回。vuln 函数中使用了 strcpy 函数,可以用来实现栈溢出。在 main 函数中,根据命令行参数选择使用哪个 gadget 函数,在调用 vuln 函数前先调用相应的 gadget 函数,然后传入用户输入的字符串。
使用 ROP 实现的过程如下:
1. 找到一个能够跳转到某个 gadget 的地址,例如 main 函数中的 fgets 函数。
2. 找到一个能够将参数传递到寄存器中的地址,例如 main 函数中的 strcmp 函数。
3. 找到能够将控制流跳转到指定地址的 gadget,例如 gadget2 函数。
4. 将第 2 步中得到的地址和参数传递到第 3 步中得到的 gadget 中,使其执行返回操作时跳转到指定地址,例如跳转到 gadget2 函数。
5. 在第 4 步中的 gadget 中设置相应的寄存器,使得在返回到 vuln 函数时执行指定的代码,例如将 x0 寄存器设置为 system 函数的地址,x1 寄存器设置为 "/bin/sh" 字符串的地址。
6. 调用 vuln 函数,使其执行第 5 步中设置的代码,例如执行 system("/bin/sh")。
具体实现过程详见代码。