Friday, December 26, 2014

Architecture Detection (x86 or x64) Assembly Stub

This stub is useful for combining both a 32-bit and 64-bit shellcode payload into a single shot. Knowing the distinction in architecture is important for many types of payloads. For instance, on Windows the Thread Information Block is in the FS segment register on x86, and is in GS on x64.

Here are 5 bytes you you can use to detect the architecture you're on:

_shellcode:

    xor ecx, ecx        ; set ecx to 0
    db 0x41             ; x86 opcode for: inc ecx

    loop x64_code       ; ecx now -1 in x64, we jmp

x86_code:
    ; use fs segment

    ; ret

x64_code:
    ; use gs segment

Those familiar with x64 assembly should recognize that the 0x40-0x50 range is often used as a prefix for an instruction.  We can use this subtle difference to confuse the processor. In this case, if running in x64, the inc ecx opcode becomes a prefix for the loop. The loop instruction decrements ecx by one, and if ecx is not equal to 0 it will jump to the given label.

I used db 0x41 instead of inc ecx in the source code, since nasm uses a modern 2-byte instruction to prevent this ambiguity when we actually want the 1-byte increment. Here are the different outputs, which clearly show what is going on:

x86

 
 "\x31\xc9"              /* xor    %ecx,%ecx */
 "\x41"                  /* inc    %ecx */
 "\xe2\x01"              /* loop   x64_code  */     <-- ecx = 0, no jmp

x64

 
 "\x31\xc9"              /* xor    %ecx,%ecx */
 "\x41\xe2\x01"          /* rex.B loop x64_code  */ <-- ecx = -1, jmp

No comments :

Post a Comment