Alternatives to NOP for shellcode nop sleds
Asked Answered
D

6

6

Does anyone know of any online source that provides instruction alternatives to a NOP opcode ?

Like 'xchg ax, ax' and the likes. I'm pretty sure that there is also a tool for it, can someone point me to that direction please ?

Deerdre answered 29/9, 2011 at 16:13 Comment(2)
Is it able to produce nop alternatives ?Deerdre
Out of curiosity, what is your purpose in looking for nop alternatives?Easing
H
5

Some shellcode engines contain nop sled generators, if that is what you're looking for.

Though there are an infinite variety of nop-equivalents of various lengths, so an exhaustive listing is impractical.

For instance, push eax; pop eax is effectively a nop. (assuming a valid esp, etc, etc)

Or inc eax; dec eax (assuming no overflow or you test then reset the overflow flag).

Hereditary answered 29/9, 2011 at 18:52 Comment(2)
Yeah, i was thinking about them, or something like 'xor eax, 0'. I would hope there is a list or something. As i said, i am pretty sure i have seen a tool that does this in the past.Deerdre
If you want to write a generator: A really really lazy way to do things is save the machine state to the stack, then generate random instructions (those that don't touch memory or cause interrupts to be raised), then reload the machine state. (Polymorphic shellcode normally does something similar, though there might be more restrictions like using only single-byte instructions, for instance.)Hereditary
H
4

This page has a nice list of NOP alternatives with increasing encoding lengths: http://www.asmpedia.org/index.php?title=NOP

Heaviside answered 29/9, 2011 at 16:24 Comment(4)
the problem is that this is mainly about nop itself. I would want instructions like 'mov ax, ax' as well.Deerdre
deadline, any alternative or achieves?Parlin
Hmm - too bad. Doesn't look like the wayback machine has it either. If I can't find a reliable source soon I will delete my answer.Heaviside
Oh, OmnipotentEntity actually posted an excerpt below.Heaviside
L
3

An alternative to NOP that's useless for nop sleds, but useful for performance: What methods can be used to efficiently extend instruction length on modern x86? (e.g. add extra prefixes to make instructions longer).


Normally your exploit payload doesn't care about register values (other than the stack pointer), so you can freely destroy them with things like inc eax (single-byte in 32-bit code). There are lots of single-byte instructions that only modify registers and won't fault. e.g. cld/std, stc/clc/cmc, cwde, cdq are all single-byte. Again in 32-bit code, even BCD instructions like AAA or DAA are usable, but those will stick out like a sore thumb because compilers never use them. (Compilers do in practice use cdq and maybe cwde, but typically not cld or std.)

Also the other xchg-with-eax one-byte 0x91..7 instructions, other than 0x90 nop which uses the same encoding that xchg eax,eax would have, and could in 32-bit mode. (But note that xchg eax,eax in 64-bit mode isn't a NOP; it has to use the other encoding so it can truncate RAX to EAX.)

With any multi-byte instruction like mov eax,eax, make sure to check how it decodes if execution starts at something other than the first byte. The whole point of a sled is that execution has to land somewhere inside the buffer but you don't know where.

You can use optional prefixes to make multi-byte instructions that still decode ok if execution starts after the prefix. cbw is 0x66 cwde (operand-size prefix). Or REX prefixes (0x40..4f), so xchg rax,rcx for example.

rep prefixes are typically ignored safely on instructions they don't apply to, but may run differently on future CPUs. (e.g. rep nop used to just be NOP, but now it's pause. rep bsr is now lzcnt, which produces a different result.) This is fine for shellcode, you're trying to exploit one system now, not be future-proof for future CPUs.


If you know the target buffer alignment, then you control (via the low bits of the instruction pointer) which possible offsets you can jump to. If the buffer is 4-byte aligned (or more specifically that your payload will end up a 4-byte aligned location), then only every 4th byte needs to be a valid starting point for decoding, so you can use pairs of 2-byte instructions like xor eax, ebx / add ecx, edx.

4-byte instructions include addss xmm0, xmm1 and other SSE1/SSE2 instructions. Unless the code you're exploiting is running in kernel mode with SSE disabled, you can normally assume that whatever machine you're exploiting has SSE1.

You could even use a 5-byte instruction like mov eax, 0x90345612 starting at a 4-byte aligned address. Note that the last byte of the little-endian immediate is 0x90 nop, so it's ok if decoding starts there.


My understanding is that techniques like this are widely used to work around intrusion-detection systems / virus scanners that find long strings of 0x90 suspicious. (And/or because 0x90 is not printable ASCII, and not valid UTF-8).

Lampert answered 25/8, 2018 at 20:35 Comment(0)
S
2

The intel optimization manual and the instruction manuals for intel and AMD should have listing of all the no op equivalent functions. It should be noted that most of them are multi byte no ops, to be used for aligning branch and code cache targets etc.

Scarron answered 29/9, 2011 at 18:39 Comment(1)
Vol. 2B 4-13Bausch
C
1

From the internet archive of the dead link in the top answer.

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]
Carchemish answered 25/8, 2018 at 19:56 Comment(2)
This doesn't work as a NOP sled. If execution lands in the middle of one of these long instructions, it can fault. e.g. 00 00 is add [rax], alLampert
It does if you can guarantee alignment of the landing. But yes, I agree.Carchemish
S
0

just think through the different operations that dont change anything (other than flags). add zero to a register, or the register with itself and the register with itself, move the register to itself. subtract 0, or with zero, and with ~0. A bit test type instruction, usually an and but the destination is not modified.

Sinhalese answered 29/9, 2011 at 18:50 Comment(2)
If it changes the flags, it's not really a NOP.Labor
I agree, depends on what operation the poster is actually looking for, do nothing to registers or do nothing to registers and flags.Sinhalese

© 2022 - 2024 — McMap. All rights reserved.