Mislead the Disassembler with Rogue Bytes
2022-05-23 Dawid Farbaniec

Disassemblers are one of the basic programs that are used in Reverse Code Engineering. They allow to obtain the code in Assembly language from the analyzed * .exe file. With these types of tools, there is no need to work with the machine code that is practically unreadable for humans. This text presents a simple method that allows you to cheat disassemblers, and in combination with additional techniques, it can make the work of crackers breaking software security or blue team analysts more difficult. Even if you do not protect the software, I invite you to read this text, because who knows maybe you will find a file containing this method.
The job of a disassembler is the reverse of compiling (building a program). Tools of this type try to recreate the code in the Assembly language from the given executable file (containing the machine code). One can also met with decompilers that recreated a C-like pseudo-code from machine code (for example: http://www.backerstreet.com/rec/rec.htm). The term decompiler is intentionally used here, as it produces code with a higher level of abstraction than disassembler.
The rogue byte technique takes advantage of the possibility of placing bytes of a certain value in the program code. The example will be in MASM x64 Assembly (ML64.EXE), which is included with the Microsoft Visual Studio environment. To understand how this method works, you need to think about how a disassembler works. In simple terms, it takes the next bytes of the machine code and according to the rules converts them into specific instructions in text representation (mnemonics). If you insert a byte with a certain value inside a program's instructions, many disassemblers will treat it as part of the machine code and misinterpret instructions near that byte.
When a disassembler (often built into debugger) encounters a byte
The byte inserted in the second place has the operational code
For the sake of clarity, let me mention that the code with the rogue byte method executes correctly. This is because the rogue byte is skipped over with a jump instruction
This method is only effective in combination with other types of security methods.
The job of a disassembler is the reverse of compiling (building a program). Tools of this type try to recreate the code in the Assembly language from the given executable file (containing the machine code). One can also met with decompilers that recreated a C-like pseudo-code from machine code (for example: http://www.backerstreet.com/rec/rec.htm). The term decompiler is intentionally used here, as it produces code with a higher level of abstraction than disassembler.
The rogue byte technique takes advantage of the possibility of placing bytes of a certain value in the program code. The example will be in MASM x64 Assembly (ML64.EXE), which is included with the Microsoft Visual Studio environment. To understand how this method works, you need to think about how a disassembler works. In simple terms, it takes the next bytes of the machine code and according to the rules converts them into specific instructions in text representation (mnemonics). If you insert a byte with a certain value inside a program's instructions, many disassemblers will treat it as part of the machine code and misinterpret instructions near that byte.
extrn ExitProcess : proc
extrn MessageBoxA : proc
.data
szText db "https://ethical.blue/", 0
.code
Main proc
jmp @f
db 0E8h ;rogue byte
@@:
sub rsp, 28h
xor r9, r9
lea r8, szText
lea rdx, szText
xor rcx, rcx
jmp @f
db 0E9h ;rogue byte
@@:
call MessageBoxA
add rsp, 28h
sub rsp, 28h
xor rcx, rcx
call ExitProcess
Main endp
end
When a disassembler (often built into debugger) encounters a byte
0E8h
, it will assume that this is the beginning of an instruction in machine code. Exactly the CALL
(procedure call) instruction. From now the code will be misinterpreted, which will result in its obfuscation.
The byte inserted in the second place has the operational code
0E9h
, that is the instruction JMP
(unconditional jump). After that, the instructions will be also decoded incorrectly.

For the sake of clarity, let me mention that the code with the rogue byte method executes correctly. This is because the rogue byte is skipped over with a jump instruction
JMP
.
This method is only effective in combination with other types of security methods.
Bibliography
https://x64dbg.com/ [access: 2019-07-30]http://www.backerstreet.com/rec/rec.htm [access: 2019-07-30]
https://docs.microsoft.com/en-us/cpp/assembler/masm/masm-for-x64-ml64-exe [access: 2019-07-30]