构建栈溢出ROP payload时4字节填充与\r字符作用相关疑问
问题1:'A'*4的作用与覆盖的栈区域
这是32位x86架构下C语言默认cdecl调用约定的硬性要求:
正常调用函数时,call 目标函数地址指令会自动执行两个操作:
- 把当前
call指令的下一条指令地址(即目标函数执行完毕后的返回地址)压入栈顶 - 跳转到目标函数地址开始执行
你通过栈溢出直接覆盖EIP寄存器为flag函数地址的操作,跳过了call指令压入返回地址的步骤,因此跳转到flag函数执行时,栈顶缺少了本该存在的4字节返回地址位。按照cdecl约定,flag函数会默认ebp+4位置存储返回地址,ebp+8存储第一个参数、ebp+12存储第二个参数,你填充的'A'*4就是用来占住返回地址的位置,确保后续写入的两个参数刚好落在正确的偏移位置,让flag可以正常读取参数。这4字节只要是不会触发输入截断的任意值都可以,这里用A只是构造方便。
问题2:参数间'\r'的作用
'\r'对应的ASCII码值为0x0D,你遇到的必须加它才能生效的情况,本质是两种常见场景:
- 它是第二个参数的合法组成部分:你给出的
flag函数是简化后的声明,实际可执行文件内的flag函数存在参数校验逻辑,要求第二个参数的对应字节为0x0D,你误以为它是参数之间的分隔符,实际上它是参数值的一部分,缺少的话参数校验不通过,自然无法正常执行。 - 输入流适配要求:如果你是通过终端、远程套接字等通道传输payload,部分运行环境会对输入的换行符做自动转义(比如把单独的
\n替换为\r\n),缺少这个0x0D会触发额外的字符插入,导致payload整体偏移错乱,后续参数被识别错误。
内容的提问来源于stack exchange,提问作者Serve Laurijssen
相关产品推荐
相关产品推荐

