如何做无限循环
How to do Infinite Loop
我的目标是写一个无限循环。我必须无限地打印这个字符串 "Hello World %s" 并且我只能使用 ROP(面向 Return 的编程)。
gcc -fno-stack-protector loop.c -o loop
如图所示我可以编译。如何做 ROP?
#include<stdio.h>
#include<string.h>
main(char argc, char ** argv){
char buffer[80];
strcpy(buffer,argv[1]);
printf("Hello World %s",buffer);
return 1;
}
所以,粗略的做法:
buffer
位于栈上,main function
-callee的return地址所在。由于堆栈向后增长,您可以覆盖 return 地址,因为它之前已附加。堆栈应如下所示:
[buffer data][ebp save][callee return address]...anything
不太确定,但很可能,被调用方的 return 地址位于 ebp
保存值之后,该值位于缓冲区数据之后,因此您需要提供一个84 字节长的数据数组(不包含 0x00
,因为那样会终止字符串)后跟 return 地址。该地址需要指向某个地方,您的 "hack" 位于内存中。一个可能的位置是堆栈本身,因此您可能希望在 return 地址之后附加无限循环的机器代码。
请务必注意,您必须生成不包含空字节的机器代码。您可能会提供给程序的参数字符串的示例布局应如下所示:
[84 byte data][return address][machine code]
这应该适用于较旧的 linux 内核。此外,这假设您在 32 位系统上工作,因此指针的长度为 4 个字节。在 64 位系统上,它将是 8 个字节。
我不精通这个,但(理论上)你的最终目标是 return 到启动代码(_start
或例如 glibc 的 __libc_start_main
),这将反过来使用相同的参数再次调用您的 main()
。由于参数相同,代码进入死循环。
为了实现这一点,您可能需要找到一些 gadget(s) 来设置堆栈并在 before return转到上述启动代码(假设被调用者清理约定,可能只需要清理主要参数)。
请将您的结果更新给我们。
我的目标是写一个无限循环。我必须无限地打印这个字符串 "Hello World %s" 并且我只能使用 ROP(面向 Return 的编程)。
gcc -fno-stack-protector loop.c -o loop
如图所示我可以编译。如何做 ROP?
#include<stdio.h>
#include<string.h>
main(char argc, char ** argv){
char buffer[80];
strcpy(buffer,argv[1]);
printf("Hello World %s",buffer);
return 1;
}
所以,粗略的做法:
buffer
位于栈上,main function
-callee的return地址所在。由于堆栈向后增长,您可以覆盖 return 地址,因为它之前已附加。堆栈应如下所示:
[buffer data][ebp save][callee return address]...anything
不太确定,但很可能,被调用方的 return 地址位于 ebp
保存值之后,该值位于缓冲区数据之后,因此您需要提供一个84 字节长的数据数组(不包含 0x00
,因为那样会终止字符串)后跟 return 地址。该地址需要指向某个地方,您的 "hack" 位于内存中。一个可能的位置是堆栈本身,因此您可能希望在 return 地址之后附加无限循环的机器代码。
请务必注意,您必须生成不包含空字节的机器代码。您可能会提供给程序的参数字符串的示例布局应如下所示:
[84 byte data][return address][machine code]
这应该适用于较旧的 linux 内核。此外,这假设您在 32 位系统上工作,因此指针的长度为 4 个字节。在 64 位系统上,它将是 8 个字节。
我不精通这个,但(理论上)你的最终目标是 return 到启动代码(_start
或例如 glibc 的 __libc_start_main
),这将反过来使用相同的参数再次调用您的 main()
。由于参数相同,代码进入死循环。
为了实现这一点,您可能需要找到一些 gadget(s) 来设置堆栈并在 before return转到上述启动代码(假设被调用者清理约定,可能只需要清理主要参数)。
请将您的结果更新给我们。