- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以我在引用这篇论文:
二进制搅拌:的自随机指令地址
旧版x86二进制代码
https://www.utdallas.edu/~hamlen/wartell12ccs.pdf
代码与数据交织:现代编译器积极地交织
PE和ELF二进制文件中的代码段中的静态数据
性能原因。在编译的二进制文件中,通常没有
从代码中区分数据字节的方法。无意间
将数据与代码随机化会破坏二进制文件,
给指令级随机化器带来了困难。可行的
解决方案必须以某种方式保留数据,同时将所有
可达代码。
但是我有一些问题:
如何提高程序速度?我只能想象这只会使cpu的执行更加复杂吗?
CPU如何区分代码和数据?因为据我所知,除非存在跳转类型的指令,否则cpu将以线性方式依次执行每个指令,那么cpu怎么知道代码中的哪些指令是代码,哪些指令是数据?
考虑到代码段是可执行的,并且CPU可能会错误地将恶意数据作为代码执行,因此这对安全性是否非常不利? (也许攻击者将程序重定向到该指令?)
最佳答案
是的,他们提出的二进制随机化器需要处理这种情况,因为可能存在混淆的二进制文件,或者手写代码可能会执行任意操作,因为作者并不了解或出于某种奇怪的原因。
但是,不,普通编译器不会针对x86执行此操作。该答案针对书面提出的SO问题,而不是包含这些主张的论文:
出于性能原因,现代编译器在PE和ELF二进制文件的代码段中积极插入静态数据
需要引用!在我使用GCC和clang之类的编译器的经验中,对于x86来说,这完全是错误的,并且有些经验是从MSVC和ICC看asm输出的。
普通的编译器将静态只读数据放入section .rodata
(ELF平台)或section .rdata
(Windows)。 .rodata
节(和.text
节)被链接为文本段的一部分,但是整个可执行文件或库的所有只读数据都被分组在一起,而所有代码则被分别分组在一起。 What's the difference of section and segment in ELF file format(或者最近,即使在单独的ELF段中,也可以将.rodata
映射为noexec。)
Intel's optimization guide表示不要混合代码/数据,尤其是读写数据:
汇编/编译器编码规则50。(M影响,L通用性)如果(希望是只读的)数据必须
与代码出现在同一页面上,请避免在间接跳转之后立即将其放置。例如,
跟随间接跳转及其最可能的目标,然后将数据放在无条件分支之后。
汇编/编译器编码规则51。(对H的影响,对L的一般性)始终将代码和数据放在
单独的页面。尽可能避免自我修改代码。如果要修改代码,请尝试在以下位置进行所有操作
一次并确保执行修改的代码和正在修改的代码处于打开状态
单独的4 KB页面或单独的对齐的1 KB子页面。
(有趣的事实:Skylake实际上具有用于自修改代码管道核的高速缓存行粒度;在最近的高端用户中,将读/写数据放在64字节的代码内是安全的。)
在同一页面中混合使用代码和数据在x86上具有接近零的优势,并且浪费了代码字节的data-TLB覆盖范围,浪费了数据字节的指令-TLB覆盖范围。在64字节高速缓存行中也是如此,以浪费L1i / L1d中的空间。唯一的优势是统一缓存(L2和L3)的代码+数据局部性,但是通常不会这样做。 (例如,在代码提取将一行插入L2之后,从同一行中提取数据可能会进入L2,而不得不从另一缓存行进入RAM来获取数据。)
但是,使用分离的L1iTLB和L1dTLB,以及将L2 TLB作为统一的受害者缓存(maybe I think?),x86 CPU并未为此进行优化。从现代Intel CPU上的同一高速缓存行读取字节时,在获取“冷”功能时出现iTLB丢失并不能防止dTLB丢失。
x86上的代码大小优势为零。 x86-64的PC相对寻址模式为[RIP + rel32]
,因此它可以寻址当前位置+ -2GiB之内的任何内容。 32位x86甚至没有PC相关的寻址模式。
也许作者想到的是ARM,ARM附近的静态数据允许相对PC的负载(具有较小的偏移量)将32位常量存储到寄存器中? (在ARM上,这称为“文字池”,您将在函数之间找到它们。)
我认为它们并不意味着立即数据,例如mov eax, 12345
,其中32位12345
是指令编码的一部分。这不是要通过加载指令加载的静态数据。立即数据是另一回事。
显然,它仅用于只读数据;在指令指针附近进行写操作将触发清除管道以处理自修改代码的可能性。而且,您通常希望W ^ X(写或exec,而不是两者)用于内存页面。
CPU如何区分代码和数据?
逐渐增加。 CPU在RIP上提取字节,并将其解码为指令。从程序入口点开始之后,执行将在已执行的分支之后进行,并落入未执行的分支等。
从体系结构上讲,它不关心当前正在执行的字节或指令正在将其作为数据加载/存储的字节。如果再次需要,最近执行的字节将保留在L1-I高速缓存中,并且与L1-D高速缓存中的数据相同。
在无条件分支或ret
之后立即拥有数据而不是其他代码并不重要。函数之间的填充可以是任何东西。在极少数情况下,如果数据具有某种模式,则数据可能会暂停预解码或解码阶段(例如,由于现代CPU以16或32字节的宽块为单位进行取/解码),但随后的CPU阶段都是仅查看来自正确路径的实际解码指令。 (或者由于分支的错误推测...)
因此,如果执行到达一个字节,则该字节是指令的一部分。这对于CPU完全没问题,但对于想要查看可执行文件并将每个字节分类为“或”的程序无济于事。
代码提取总是检查TLB中的权限,因此,如果RIP指向不可执行的页面,它将导致错误。 (页表条目中的NX位)。
但是实际上就CPU而言,并没有真正的区别。 x86是冯·诺依曼架构。如果需要,一条指令可以加载自己的代码字节。
例如movzx eax, byte ptr [rip - 1]
将EAX设置为0x000000FF,加载rel32 = -1 = 0xffffffff位移的最后一个字节。
考虑到代码段是可执行的,并且CPU可能会错误地将恶意数据作为代码执行,因此这对安全性是否非常不利? (也许攻击者将程序重定向到该指令?)
可执行页面中的只读数据可以用作Spectre小工具,也可以用作面向返回编程(ROP)攻击的小工具。但是我认为通常在真实代码中已经有足够多的小工具了,这没什么大不了的。
但是,是的,与您的其他观点不同,这实际上是一个次要的反对。
最近(2019年或2018年末),GNU Binutils ld
已开始将.rodata
部分与.text
部分放在单独的页面中,因此无需执行权限即可将其只读。这使得静态只读数据在x86-64之类的ISA上不可执行,而exec权限与读取权限是分开的。即在单独的ELF细分中。
您可以使不可执行的事情越多越好,并且将代码+常量混合在一起将要求它们是可执行的。
关于x86 - 为什么编译器将数据放在PE和ELF文件的.text(code)部分中,并且CPU如何区分数据和代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55607052/
我目前正在创建一个正则表达式来拆分所有匹配以下格式的字符串:&[text(text - text text) !text]。这里的文本实际上可以是任何字符。并且间距很重要。文本将如图所示列出。 我已经
这个问题在这里已经有了答案: Remove duplicate commas and extra commas at start/end with RegExp in Javascript, and
我有以下代码。 from xml.dom.minidom import Document doc = Document() root = doc.createElement('root') doc.a
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: Find text string in jQuery and make it bold 如何使用 jQuer
我使用 libmagic 在我的元素的 Web 界面中获取文件的 MIME 类型。我在 css 和 js 文件上得到文本/纯 mime 类型。 例如 chromium 显示以下警告: Resource
起初我必须阅读很多教程,但我仍然不知道我做错了什么...... 我想内联使用 4 个 div。在我想放置的那些 div 中:文本、图像、文本、文本。我希望中间文本自动设置为最大宽度。 我写了一个简单的
我想替换所有出现的 [b: "text"]至text使用 JavaScript 和 RegEx。目前我知道如何替换 [b: ""]至使用'/\[b: ""\]/g'但我不知道如果 " 之间有文本该怎么
这可能是一个幼稚的问题,但我想知道是否有比使用 text() 更好的方法将文本添加到绘图中。注意,我也在使用 layout()以及。具体来说,我有一个情节的一部分,我想在其中添加一些带有标题的文本,然
我必须反复从 latex 源粘贴代码,因此每次都必须做很多查找和替换操作('“a'=>'ä','” o'=>'ö',...) 。 有没有一种方法可以存储这些搜索和替换规则,例如,我可以通过一次按键执行
当我在Sublime Text 3代码屏幕中编写代码时,它连续地向右滑动,如图所示。我该怎么办? 请注意第10行。 最佳答案 如果您只想为当前 View (正在编辑的当前文件)激活自动换行,只需vie
是否有可能更改 sublime text 中的默认字体目录?我只想使用可移植 sublime 文本存储在我的 pendrive 上的字体,这样我就不必在我使用可移植 sublime 文本的每台机器上安
我是 Android 开发的新手,我有一个愚蠢的问题。如何将“文本字段”框放在一行中的文本旁边。 例子: Please Enter the number: [ ] 关于 "t
我想自动将“我的文本”更改为“我的文本”,因为这是用德语写的正确方式。引号可以在文本中的任何位置。 有没有一种简单的方法可以实现这一点? 解决方案应该检查第一个字符,最后一个字符,比如“this”,或
我想知道是否有特殊的语法来绑定(bind)与现有文本连接的文本。 像这样。 显然,这行不通。 什么是最佳实践? 使用 SL4。 最佳答案 使用StringFormat在 Binding 上。 WPF
我认为它应该打印“真实文本”,因为它相当于 true console.log('true text' || true ? 'text' : 'text1'); 但是,输出是“文本”;抱歉,如果是愚蠢的
有没有办法通过 css 打破文本,以便中间有一个“空白”?目前我正在通过手工打破文本来解决这个问题 -但这是愚蠢的。我知道有一个函数可以让文本在另一个 div 中结束和开始,但 IE 不支持它。 文本
我想为我的Tcl/Tk工具实现一个效果:在text控件中,根据具体情况,希望高亮一些线条的背景色,其他线条正常透明.有可能吗? 我尝试了一些选项,例如:-highlightbackground 、-i
我正在尝试解析原始维基百科文章内容,例如the article on Sweden ,使用re.sub()。但是,我在尝试替换 {{some text}} block 时遇到了问题,因为它们可以包含更
我试图先删除 ComboBox 中的所有内容。然后在其前面添加文本,但保留了一些旧文本。有没有办法重置或清除 ComboBox?或者我怎样才能最好地实现这一目标? public void GetBad
我知道我们应该创建 Example对象并将其传递给 nlp.update() 方法。根据 docs 中的示例, 我们有 for raw_text, entity_offsets in train_da
我是一名优秀的程序员,十分优秀!