Purpose of NOP Instruction and Align Statement in x86 Assembly

assemblyx86

It has been a year or so since I last took an assembly class. In that class, we were using MASM with the Irvine libraries to make it easier to program in.

After we'd gone through most of the instructions, he said that the NOP instruction essentially did nothing and not to worry about using it. Anyway, it was about midterm and he has some example code that wouldn't run properly, so he told us to add a NOP instruction and it worked fine. I asked I'm after class why and what it actually did, and he said he didn't know.

Anybody know?

Best Answer

Often times NOP is used to align instruction addresses. This is usually encountered for example when writing Shellcode to exploit buffer overflow or format string vulnerability.

Say you have a relative jump to 100 bytes forwards, and make some modifications to the code. The chances are that your modifications mess up the jump target's address and as such you'd have to also change the aforementioned relative jump. Here, you can add NOPs to push the target address forward. If you have multiple NOPs between the target address and the jump instruction, you can remove the NOPs to pull the target address backward.

This would not be a problem if you are working with an assembler which supports labels. You can simply do JXX someLabel(where JXX is some conditional jump) and the assembler will replace the someLabel with the address of that label. However, if you simply modify the assembled machine code(the actual opcodes) by hand(as it sometimes happens with writing shellcode), you also have to change the jump instruction manually. Either you modify it, or then move the target code address by using NOPs.

Another use-case for NOP instruction would be something called a NOP sled. In essence the idea is to create a large enough array of instructions which cause no side-effects(such as NOP or incrementing and then decrementing a register) but increase the instruction pointer. This is useful for example when one wants to jump to a certain piece of code which address isn't known. The trick is to place the said NOP sled in front of the target code and then jumping somewhere to the said sled. What happens is that the execution continues hopefully from the array which has no side-effects and it traverses forwards instruction-per-instruction until it hits the desired piece of code. This technique is commonly used in aforementioned buffer overflow exploits and especially to counter security measures such as ASLR.

Yet another particular use for the NOP instruction is when one is modifying code of some program. For example, you can replace parts of conditional jumps with NOPs and as such circumvent the condition. This is a often used method when "cracking" copy protection of software. At simplest it's just about removing the assembly code construct for if(genuineCopy) ... line of code and replacing the instructions with NOPs and.. Voilà! No checks are made and non-genuine copy works!

Note that in essence both examples of shellcode and cracking do the same; modify existing code without updating the relative addresses of operations which rely on relative addressing.

Related Topic