I've noticed that if I disassemble some code, then reassemble it, I get back different code from where I started! This isn't particularly worrying, but I was wondering if this was intentional?
Here's a harmless example:
$ printf '\x3b\xc8' | ndisasm -u /dev/stdin
00000000 3BC8 cmp ecx,eax
$ printf 'BITS 32\ncmp ecx,eax' > tmp; nasm tmp -f bin -o /dev/stdout | ndisasm -u /dev/stdin
00000000 39C1 cmp ecx,eax
Here's a more worrying example, where the size of the instruction changes, which means later jump offset will be wrong (ie disassembling then reassembling breaks the code):
$ printf '\x75\x03' | ndisasm -u /dev/stdin
00000000 7503 jnz 0x5
$ printf 'BITS 32\njnz 0x5' > tmp; nasm tmp -f bin -o /dev/stdout | ndisasm -u /dev/stdin
00000000 0F85FFFFFFFF jnz dword 0x5
Yikes! On the other hand, watch what happens for straight jmp instructions:
$ printf '\xeb\x18' | ndisasm -u /dev/stdin
00000000 EB18 jmp short 0x1a
$ printf 'BITS 32\njmp short 0x1a' > tmp; nasm tmp -f bin -o /dev/stdout | ndisasm -u /dev/stdin
00000000 EB18 jmp short 0x1a
So, why is it that ndisasm generates "jmp short ...", but just "jnz ..."? If ndisasm were to output instead "jnz short ..." for my example, as it does for jmp, then it might generate less surprise! I'm not experienced with assembler, so maybe there's some difference between the instructions I'm unaware of that explains the behaviour.