繁体   English   中英

x86 程序集:文本部分中的数据

[英]x86 Assembly: Data in the Text Section

我不太明白如何将变量存储在文本部分以及如何操作它们。 不应该所有变量都在 .data 部分中,并且 .text 部分不都是只读的吗? 那么这段代码是如何工作的呢?

[代码取自Shellcoder's Handbook ]

Section .text
global _start

_start:
    jmp short GotoCall

shellcode:
    pop esi
    xor eax, eax
    mov byte [esi + 7], al
    lea ebx, [esi]
    mov long [esi + 8], ebx
    mov long [esi + 12], eax
    mov byte al, 0x0b
    mov ebx, esi
    lea ecx, [esi + 8]
    lea edx, [esi + 12]
    int 0x80

GotoCall:
    call shellcode
    db '/bin/shJAAAAKKKK'

好吧,数据和代码只是字节。 只有你如何解释它们,它们才会成为它们的样子。 代码可以解释为数据,反之亦然。 在大多数情况下,它会产生无效的东西,但无论如何这是可能的。

该部分的属性取决于链接器,默认情况下,大多数属性使.text部分成为 RO,但这并不意味着它不能更改。

整个示例是一种巧妙的方法,只需使用call即可获取/bin/sh的地址。 基本上, call将下一条指令(下一个字节)的地址放在堆栈上,在这种情况下,它将是该字符串的地址,因此pop esi将从堆栈中获取该地址并使用它。

顶级答案是,x86 机器不知道“.text”和“.data”部分。 现代 x86 CPU 为操作系统提供了创建具有特定权限(如只读、无执行和读写)的虚拟地址空间的工具。

但是内存的内容只是字节,可以读、可以写、可以执行,CPU没有办法猜测内存的哪一部分是数据、什么是代码,只要你指向它,它就会愉快地执行。

那些.text/.data/...部分是编译器、链接器和操作系统(可执行加载器)支持的逻辑结构,它们共同协作为代码准备运行时环境,现在.text是只读的,并且您需要将可写变量放入.data.bss或类似文件中。 此外,某些操作系统和配置可能会提供不可执行的堆栈。

操作系统通常也有 API,所以应用程序可以改变权限或内存映射,或者用它需要的属性分配更多的内存(例如,JIT 编译器将无处可去,如果它们无法先将编译后的代码写入内存,然后执行)。

因此,如果您将在默认配置中的常见 linux 上使用您的代码示例,则很可能会出现段错误,因为.text将是只读的。 许多“漏洞利用”书籍都有完整的专门章节,如何以这种方式编译 + 设置示例的运行时环境,即关闭多个保护(ASLR、 NX等),从而允许其示例工作。

然后,真正的漏洞利用通常会使用应用程序中的一些错误/弱点将其有效负载注入某处。 根据“某处”的敌意,真正的漏洞可能必须首先提升其获得可写+可执行内存的权限(或者必须以不写入代码部分并使用其他内存作为变量的方式编写),除非应用程序由于其内部需求,它本身已经有一些友好的开发环境。

请记住,操作系统和应用程序的编写方式并不是为了确保漏洞利用能够正常工作,恰恰相反。 每个漏洞利用通常针对特定版本操作系统上的特定应用程序版本,这是易受攻击的,预计它会在稍后的安全更新中中断。 所以如果你知道你有可写和可执行的内存,你只需按原样利用它,而不必担心下一个版本会发生什么,当他们修复应用程序以保持他们的代码内存 RO 时。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM