替代NOP的shellcode nop雪橇

时间:2011-09-29 16:13:17

标签: security assembly x86 shellcode

有没有人知道任何提供NOP操作码替代指令的在线资源?

喜欢'xchg ax,ax'等。我很确定它还有一个工具,有人可以指点我这个方向吗?

6 个答案:

答案 0 :(得分:3)

此页面有一个很好的NOP替代列表,编码长度不断增加:http://www.asmpedia.org/index.php?title=NOP

答案 1 :(得分:3)

一些shellcode引擎包含nop sled生成器,如果你正在寻找它。

虽然有nop种无穷多种 - 各种长度的等价物,但是详尽的列表是不切实际的。

例如,push eax; pop eax实际上是nop。 (假设有效的esp等等)

inc eax; dec eax(假设没有溢出或测试然后重置溢出标志)。

答案 2 :(得分:2)

英特尔优化手册和英特尔和AMD的使用说明书应该列出所有无操作等效功能。应该注意的是,它们中的大多数是多字节无操作,用于对齐分支和代码缓存目标等。

答案 3 :(得分:1)

摘自顶部答案中无效链接的互联网档案。

90              nop
6690            xchg    ax,ax ; 66: switch to 16-bit operand 90: opcode 
0f1f00          nop     dword ptr [eax] ; 0f1f: 2-byte opcode 00: mod=00 reg=000 rm=000 [EAX]
0f1f4000        nop     dword ptr [eax] ; 0f1f: 2-byte opcode 40: mod=01 reg=000 rm=000 [EAX+0x00]
0f1f440000      nop     dword ptr [eax+eax] ; 0f1f: 2-byte opcode 44: mod=01 reg=000 rm=100 SIB + 0x00
660f1f440000    nop     word ptr [eax+eax] ; 66: switch to 16-bit operand 0f1f: 2-byte opcode 44: mod=01 reg=000 rm=100 SIB + 0x00
0f1f8000000000  nop     dword ptr [eax] ; 0f1f: 2-byte opcode 80: mod=10 reg=000 rm=000 [EAX+0x00000000]

答案 4 :(得分:1)

NOP的替代品,对nop雪橇无用,但对性能有用:What methods can be used to efficiently extend instruction length on modern x86?(例如,添加额外的前缀以使指令更长)。


通常,您的漏洞利用有效负载并不关心寄存器值(堆栈指针除外),因此您可以使用inc eax(32位代码中的单字节)之类的东西随意销毁它们。 许多单字节指令只能修改寄存器,不会出错。例如 cld / stdstc / clc / cmccwdecdq都是单字节。 同样,在32位代码中,甚至可以使用AAADAA之类的BCD指令,但由于编译器从不使用它们,它们会像拇指一样伸出来。 (实际上,编译器确实使用cdq,也许使用cwde,但通常不使用cldstd。)

对于mov eax,eax之类的多字节指令,请确保检查是否从第一个字节以外的其他位置开始执行。雪橇的全部要点是执行必须降落到缓冲区内的某个位置,但是您不知道在哪里。

您可以使用可选的前缀来制作多字节指令,如果在前缀之后开始执行,这些指令仍会解码为OK。 cbw0x66 cwde(操作数大小的前缀)。

rep前缀通常在不适用的指令上被安全地忽略,但在将来的CPU上可能会以不同的方式运行。 (例如,rep nop以前只是NOP,但现在是pauserep bsr现在是lzcnt,它会产生不同的结果。)这对于shellcode很好,您重新尝试现在开发一个系统,而不是将来的CPU要适应未来。


如果知道目标缓冲区的对齐方式,则可以控制(通过指令指针的低位)可以跳转到哪些可能的偏移量。如果缓冲区是4字节对齐的(或者更确切地说,您的有效负载将以4字节对齐的位置结束),则只有每第4个字节才是解码的有效起点,因此您可以使用2字节对xor eax, ebx / add ecx, edx之类的说明。

4字节指令包括addss xmm0, xmm1和其他SSE1 / SSE2指令。除非所利用的代码在禁用SSE的内核模式下运行,否则通常可以假定所利用的任何计算机都具有SSE1。

您甚至可以使用从4字节对齐地址开始的5字节指令,例如mov eax, 0x90345612。请注意,little-endian立即数的最后一个字节是0x90 nop,因此从那里开始解码是可以的。


我的理解是,像这样的技术被广泛用于解决入侵检测系统/病毒扫描程序,这些系统发现长串0x90可疑。 (和/或因为0x90不是可打印的ASCII,并且不是有效的UTF-8)。

答案 5 :(得分:0)

只考虑不改变任何东西的不同操作(除了标志)。将0添加到寄存器,或将寄存器与其自身和寄存器自身相加,将寄存器移至自身。减去0,或减零,并用~0。一个位测试类型指令,通常是一个但不会修改目标。