c - 无法执行位于 WSL 中程序数据段中的汇编代码
问题描述
此程序覆盖主函数的返回地址,以指向编码的 x86-64 汇编指令的字符数组。这些指令只是对 NOP 进行编码,然后是系统调用 exit(1)。
char shellcode[] = "\x90\x48\x31\xc0\x48\x89\xc7\x48\xff\xc7\x04\x3c\x0f\x05";
void main() {
long int *ret;
ret = (long int *)&ret + 2;
(*ret) = (long int)shellcode;
}
它是用
gcc program.c -o program.exe -fno-stack-protector -z execstack
在 WSL 上。(来自 Microsoft Store 的 Ubuntu 应用程序)
该-z execstack
标志应该使堆栈以及程序的所有其他可写部分成为可执行的。
由于全局字符数组位于汇编代码的 .data 中,因此它应该是可执行的。在 Linux VM 上运行程序时确实如此,但显然不是在 WSL 上?在 WSL 上,控制仍然正确地重定向到 NOP,但是如果您尝试执行该指令(可能是从不可执行的页面获取代码),它会出现段错误。从 main 返回后运行 gdb 会显示:
=> 0x8004010 <shellcode>: nop
0x8004011 <shellcode+1>: xor %rax,%rax
(gdb) si
Program received signal SIGSEGV, Segmentation fault.
是什么导致了 WSL 和真正的 Linux 之间的这种不一致?WSL 是否强制执行严格的W^X,甚至覆盖-z execstack
?
是否还有其他 Windows 安全功能在起作用?我不知道它是 WSL 1 还是 2,但 uname -a 输出是:
Linux LAPTOP-M91FQN9V 4.4.0-18362-Microsoft #836-Microsoft Mon May 05 16:04:00 PST 2020 x86_64 x86_64 x86_64 GNU/Linux
当 Linux VM 上没有发生同样的情况时,是什么阻止了指令运行?
解决方案
推荐阅读
- assembly - 为什么在 MIPS 中有两种方法可以将任意有符号数相乘?
- matlab - 有没有办法在matlab中计算分类时间?
- python - 定义这个函数绝对不会返回任何东西:
- c# - 我的 HTTP 触发 Azure 函数如何将请求的参数直接传递给 Run 方法?
- java - 我可以将自定义标准(来自数据库扩展)与 spring JPA 规范一起使用吗?
- c++ - 指针验证的最佳实践?
- oracle - BULK COLLECT 和 FORALL 带参数
- r - 在 ggplot2 中连接 coord_polar 图表上的点
- nlp - 在 Stanford Core NLP OpenIE 中无法使用 OLLIE 开放信息提取方法
- c++ - 将字符串放入字符串向量时遇到问题?