在合法代码中出现0x90(NOP)序列

时间:2011-10-17 00:19:42

标签: security x86 stack-overflow packets

背景: 我编写了一个python脚本来检查IP数据包,特别是数据包的有效负载/数据,以便检测它是否可以用于缓冲区(堆栈)溢出。现在据我所知,NOP雪橇用于填充堆栈,以便指令指针最终会进入您的漏洞利用代码,我可以通过查找重复出现的0x90轻松检测到。我已经看到有很多NOP命令的代码在SQL slammer的情况下只有8个,所以我或许可以使用8个。

现在我的问题是,NOP雪橇是否经常用于合法代码?如果答案是肯定的,是否有一些特定情况(这意味着我可以查找这些情况,然后排除数据包可能无害)或者这种方法对于识别恶意代码是不实际的?

3 个答案:

答案 0 :(得分:8)

编译器将生成NOP以对齐代码 - 例如,在x86的某些迭代中,如果跳转目标与4,8或甚至16对齐,则跳转执行得更快 - 边界。

有些编译器尝试在可能的情况下使用“长NOP” - 单个指令占用超过一个字节的空间,并且可能正式执行某些操作,但对处理器状态没有影响 - 如 some < / em> x86架构的迭代这个更快。例如,66 90是一个双字节NOP,8d 74 26 00是一个四字节NOP(技术上lea 0(%esi,%eiz,1),%esi,但正如您所看到的那样只是复制%esi中的值对自己,所以没有效果)。但是,这些并不是在所有情况下都可以使用,并且在某些x86es上速度最快的序列通常在其他情况下非常慢。我还没有阅读当前的微优化指南,但如果英特尔和AMD正在努力制作90字符串来做长NOP的最快方法,并让他们的编译器匹配,我也不会感到惊讶。

答案 1 :(得分:3)

来自wikipedia

  

NOP最常用于计时目的,以强制记忆   对齐,防止危险,占用分支延迟槽,或作为   占位符将在稍后的程序中被活动指令替换   开发(或在重构时替换已删除的指令)   有问题或耗时)。在某些情况下,NOP可能会有轻微的   副作用;例如,在Motorola 68000系列处理器上,   NOP操作码将导致管道同步。

此外,编译器可能会将0x90用作未初始化数组的填充符,以防数组中的数据被解释为操作码,它什么都不做。您会看到Visual Studio使用0xCC填充未初始化数组的类似效果,int 3导致断点停止。

此外,可执行文件中的任何数据都可能包含任意数量的0x90,区分它和代码可能并不容易。

答案 2 :(得分:2)

我只是查看了我编译的最后一个二进制文件(Linux上的非恶意x86代码),并发现:

016b5e0 458b c9ec 90c3 9090 9090 9090 9090 9090

我认为你可以得出结论,找到重复的0x90序列并不一定表示恶意。