┏━━┓
BACK
┗━━┛
╔══════════════════════════════════════════════════════════════════════════════════╗
║ 16-07-2026                                                                       ║
║ A Small Obfuscation Detour                                                       ║
║                                                                                  ║
╠══-----==[ Contents ]==---------------------------------------------------------══╣
║                                                                                  ║
║ 1: brief recap of lock instruction                                               ║
║ 2: some ret manipulation                                                         ║
║                                                                                  ║
╚══════════════════════════════════════════════════════════════════════════════════╝
╔══════════════════════════════════════════════════════════════════════════════════╗
╠══-----==[ 1 ]==----------------------------------------------------------------══╣
║                                                                                  ║
║ Once again, it has been a while. With a view to breaking the silence, a short    ║
║ exploration into messing with *insert disassembler of choice*.                   ║
║                                                                                  ║
║ The idea came from toying with illegal instructions, and the way it appears to   ║
║ mess with disassembler heuristics (as per this throwaway comment on a previous   ║
║ post)                                                                            ║
║                                                                                  ║
║ Again, we shall be working with assembly since that gives us the granular        ║
║ control I need, plus it's what I am comfortable with                             ║
║                                                                                  ║
║ If we have an instruction that triggers a SigIll (via the #UD xor exception):    ║
╠══------------------------------------------------------------------------------══╣
║     lock xor rax, rbx                                                            ║
╠══------------------------------------------------------------------------------══╣
║                                                                                  ║
║ and we force gcc to compile that instruction using:                              ║
║                                                                                  ║
╠══------------------------------------------------------------------------------══╣
║     .byte 0xF0, 0x48, 0x31, 0xD8        # bytecode for [lock xor rax, rbx]       ║
╠══------------------------------------------------------------------------------══╣
║                                                                                  ║
║ we can make a small program, and insert our instruction bytes some way through:  ║
║                                                                                  ║
╠══------------------------------------------------------------------------------══╣
║     _start:                                                                      ║
║                                                                                  ║
║         xor rax, rax                                                             ║
║         mov rax, 0x1                                                             ║
║         mov rax, 0x2                                                             ║
║                                                                                  ║
║         .byte 0xF0, 0x48, 0x31, 0xD8                                             ║
║                                                                                  ║
║         mov rax, 0x3                                                             ║
║         mov rax, 0x4                                                             ║
║         mov rax, 0x5                                                             ║
╠══------------------------------------------------------------------------------══╣
║                                                                                  ║
║ again, there are some hoops we have to jump through to compile this to a working ║
║ executable under the ever suspicious auspices of gcc, I'll put the commands here ║
║ as henceforth a script will be doing this for me - which means I'll forget them  ║
║ in short order                                                                   ║
║                                                                                  ║
║     gcc -c -g -o testprogram.o testprogram.s                                     ║
║     gcc -nostdlib -no-pie -o testprogram testprogram.o                           ║
║                                                                                  ║
║ syntax for buildfile: ./build.sh -filename- (minus extension, expects .s)        ║
║                                                                                  ║
║ once compiled, we can plug the resulting executable into binay ninja and see     ║
║ what the disassembler spits back out:                                            ║
║                                                                                  ║
╠══------------------------------------------------------------------------------══╣
║     _start:                                                                      ║
║                                                                                  ║
║         xor rax, rax                                                             ║
║         mov rax, 0x1                                                             ║
║         mov rax, 0x2                                                             ║
║         ??                                                                       ║
║         H1\xd8H\xc7\xc0\x03\x00\x00\x00H\xc7\xc0\x04                             ║
║         \x00\x00\x00H\xc7\xc0\x05\x00\x00\x00                                    ║
╠══------------------------------------------------------------------------------══╣
║                                                                                  ║
║ It seems that the moment the disassembler hits the illegal instruction, it no    ║
║ longer continues the code flow, since, it its opinion, execution would never     ║
║ reach those opcodes (which is true)                                              ║
║                                                                                  ║
║ both ghidra and IDA (the free version, I’m not a millionaire) do much the same.  ║
║ This is not particularly useful unless we can actually get the unreadable        ║
║ instructions to execute. The obvious way to do this is set a label after the     ║
║ bytes, and then jump over the bytes to that label. Unfortunately, this is far    ║
║ too obvious and the disassembler will just follow that jump and neatly display   ║
║ our "obfuscated" code                                                            ║
║                                                                                  ║
║ So we have a new objective, somehow redirect code flow past these bytes in a way ║
║ that can't be obviously detected                                                 ║
║                                                                                  ║
╠══════════════════════════════════════════════════════════════════════════════════╣
╠══-----==[ 2 ]==----------------------------------------------------------------══╣
║                                                                                  ║
║ A while ago, 0xnubb made a blog post about some malware he was disassembling,    ║
║ and, after I pinged him a message, we had some back-and-forth taking a deeper    ║ 
║ look at floxiv                                                                   ║
║                                                                                  ║
║ Putting aside the function of the malware for the moment, the primary way floxiv ║
║ obfuscates control flow is through ret manipulation. Adding x bytes to the       ║
║ return address such that when the function calls ret, we are dumped back into    ║
║ the control flow having skipped over x bytes of machine code. One such function, ║
║ in its most simple form, may look something like:                                ║
║                                                                                  ║
╠══------------------------------------------------------------------------------══╣
║     _skip_4:                                                                     ║
║         pop rax                                                                  ║
║         add rax, 4                                                               ║
║         push rax                                                                 ║
║         ret                                                                      ║
╠══------------------------------------------------------------------------------══╣
║                                                                                  ║
║ We can use this to obfuscate our path over the illegal instruction as such:      ║
║                                                                                  ║
╠══------------------------------------------------------------------------------══╣
║     _start:                                                                      ║
║         xor rax, rax                                                             ║
║       ┌──────────────────────────────┐                                           ║
║       | call _skip_4                 ├───[ our obfuscation package               ║
║       | .byte 0xF0, 0x48, 0x31, 0xD8 |                                           ║
║       └──────────────────────────────┘                                           ║
║         xor rax, 0xdead                                                          ║
╠══------------------------------------------------------------------------------══╣
║                                                                                  ║
║ The part after our obfuscation isn't disassembled by binja, as it is deemed      ║
║ "unreachable". I'm not sure what the application for this type of obfuscation    ║
║ could serve, considering it is focused at the reverse engineering step, though   ║
║ I'm sure it has some use. So the xor rax, 0xdead is "hidden" to a static         ║
║ reverse engineer                                                                 ║
║                                                                                  ║
║ Originally this blog post went into a multitude of different ways that I tried   ║
║ to execute the code after our obfuscation block, but it lost it's focus and      ║
║ there were several large assumptions I made about disassemblers and their        ║
║ process that rendered those investigations moot (at least for a reader). These   ║
║ snippets will eventually be masticated and regurgitated into a future blogpost   ║
║ on other obfuscation processes!                                                  ║
║                                                                                  ║
║ CWW out                                                                          ║
╚══════════════════════════════════════════════════════════════════════════════════╝
┏━━┓
BACK
┗━━┛