├── .gitignore ├── Makefile ├── README.md ├── add.c ├── call.c ├── cdqe.c ├── cmp.c ├── div.c ├── imul.c ├── ja.c ├── jae.c ├── jb.c ├── jbe.c ├── je.c ├── jg.c ├── jge.c ├── jl.c ├── jle.c ├── jmp.c ├── jne.c ├── jno.c ├── jns.c ├── jnz.c ├── jo.c ├── js.c ├── jz.c ├── lea.c ├── main.c ├── mov.c ├── movsx.c ├── movsxd.c ├── movzx.c ├── nop.c ├── parse.c ├── pop.c ├── push.c ├── shl.c ├── shr.c ├── sub.c ├── test.c ├── test ├── Makefile ├── cal.c ├── hash.c └── sort.c ├── vm.h ├── x64_trans.py └── xor.c /.gitignore: -------------------------------------------------------------------------------- 1 | *.swp 2 | *.pyc 3 | .DS_Store 4 | .gdb_history 5 | peda-session-main.txt 6 | util.py 7 | cal 8 | hash 9 | main 10 | sort 11 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -s -masm=intel -no-pie -fno-stack-protector 3 | TARGET = main 4 | OBJECTS = main.o parse.o nop.o push.o pop.o mov.o movsx.o movsxd.o movzx.o cdqe.o lea.o add.o sub.o xor.o jmp.o je.o jne.o jg.o jge.o ja.o jae.o jl.o jle.o jb.o jbe.o jo.o jno.o jz.o jnz.o js.o jns.o shl.o shr.o cmp.o test.o call.o div.o imul.o 5 | 6 | all : $(TARGET) 7 | 8 | $(TARGET) : $(OBJECTS) 9 | $(CC) $(CFLAGS) -o $@ $^ 10 | rm *.o 11 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Vobfus 2 | -------------------------------------------------------------------------------- /add.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_add(v_register *v_reg) 4 | { 5 | DEBUG("add\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | if (info[0].SIZE == 0) { 10 | *(char *)info[0].operand += *(char *)info[1].operand; 11 | } 12 | else if (info[0].SIZE == 1) { 13 | *(short *)info[0].operand += *(short *)info[1].operand; 14 | } 15 | else if (info[0].SIZE == 2) { 16 | *(int *)info[0].operand += *(int *)info[1].operand; 17 | } 18 | else if (info[0].SIZE == 3) { 19 | *(long long *)info[0].operand += *(long long *)info[1].operand; 20 | } 21 | 22 | free(info); 23 | } 24 | -------------------------------------------------------------------------------- /call.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_call(v_register *v_reg) 4 | { 5 | printf("call\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | free(info); 10 | } 11 | -------------------------------------------------------------------------------- /cdqe.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_cdqe(v_register *v_reg) 4 | { 5 | DEBUG("cdqe\n"); 6 | 7 | v_info *info = parse(v_reg, 0); 8 | 9 | long long tmp = (long long)*(int *)&(v_reg->v_rax); 10 | 11 | v_reg->v_rax = tmp; 12 | 13 | free(info); 14 | } 15 | -------------------------------------------------------------------------------- /cmp.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_cmp(v_register *v_reg) 4 | { 5 | DEBUG("cmp\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | int CF; 10 | int PF; 11 | int ZF; 12 | int SF; 13 | int OF; 14 | 15 | if (info[0].SIZE == 0) { 16 | char result = *(char *)info[0].operand - *(char *)info[1].operand; 17 | SF = (result & (1 << 7))? 1: 0; 18 | ZF = (result) ? 0 : 1; 19 | if (ZF) CF = 0; 20 | for (int i = 0; i < 8; i++) { 21 | PF ^= (result & (1 << i)) >> i; 22 | } 23 | if (*(char *)info[0].operand < *(char *)info[1].operand) { 24 | CF = 1; 25 | OF = SF ^ 1; 26 | } 27 | else if (*(char *)info[0].operand > *(char *)info[1].operand) { 28 | CF = 0; 29 | OF = SF; 30 | } 31 | } 32 | else if (info[0].SIZE == 1) { 33 | short result = *(short *)info[0].operand - *(short *)info[1].operand; 34 | SF = (result & (1 << 15))? 1: 0; 35 | ZF = (result) ? 0 : 1; 36 | if (ZF) CF = 0; 37 | for (int i = 0; i < 16; i++) { 38 | PF ^= (result & (1 << i)) >> i; 39 | } 40 | if (*(short *)info[0].operand < *(short *)info[1].operand) { 41 | CF = 1; 42 | OF = SF ^ 1; 43 | } 44 | else if (*(short *)info[0].operand > *(short *)info[1].operand) { 45 | CF = 0; 46 | OF = SF; 47 | } 48 | } 49 | else if (info[0].SIZE == 2) { 50 | int result = *(int *)info[0].operand - *(int *)info[1].operand; 51 | SF = (result & (1 << 31))? 1: 0; 52 | ZF = (result) ? 0 : 1; 53 | if (ZF) CF = 0; 54 | for (int i = 0; i < 32; i++) { 55 | PF ^= (result & (1 << i)) >> i; 56 | } 57 | if (*(int *)info[0].operand < *(int *)info[1].operand) { 58 | CF = 1; 59 | OF = SF ^ 1; 60 | } 61 | else if (*(int *)info[0].operand > *(int *)info[1].operand) { 62 | CF = 0; 63 | OF = SF; 64 | } 65 | } 66 | else if (info[0].SIZE == 3) { 67 | long long result = *(long long *)info[0].operand - *(long long *)info[1].operand; 68 | SF = (result & (1LL << 63))? 1: 0; 69 | ZF = (result) ? 0 : 1; 70 | if (ZF) CF = 0; 71 | for (int i = 0; i < 64; i++) { 72 | PF ^= (result & (1 << i)) >> i; 73 | } 74 | if (*(long long *)info[0].operand < *(long long *)info[1].operand) { 75 | CF = 1; 76 | OF = SF ^ 1; 77 | } 78 | else if (*(long long *)info[0].operand > *(long long *)info[1].operand) { 79 | CF = 0; 80 | OF = SF; 81 | } 82 | } 83 | 84 | // set CF 85 | if (CF) { 86 | v_reg->v_eflags |= 0x1; 87 | } 88 | else { 89 | v_reg->v_eflags &= ~0x1; 90 | } 91 | 92 | // set PF 93 | if (PF) { 94 | v_reg->v_eflags |= 0x4; 95 | } 96 | else { 97 | v_reg->v_eflags &= ~0x4; 98 | } 99 | 100 | // set ZF 101 | if (ZF) { 102 | v_reg->v_eflags |= 0x40; 103 | } 104 | else { 105 | v_reg->v_eflags &= ~0x40; 106 | } 107 | 108 | // set SF 109 | if (SF) { 110 | v_reg->v_eflags |= 0x80; 111 | } 112 | else { 113 | v_reg->v_eflags &= ~0x80; 114 | } 115 | 116 | // set OF 117 | if (OF) { 118 | v_reg->v_eflags |= 0x800; 119 | } 120 | else { 121 | v_reg->v_eflags &= ~0x800; 122 | } 123 | 124 | free(info); 125 | } 126 | -------------------------------------------------------------------------------- /div.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_div(v_register *v_reg) 4 | { 5 | printf("div\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | free(info); 10 | } 11 | -------------------------------------------------------------------------------- /imul.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_imul(v_register *v_reg) 4 | { 5 | printf("imul\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | free(info); 10 | } 11 | -------------------------------------------------------------------------------- /ja.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_ja(v_register *v_reg) 4 | { 5 | DEBUG("ja\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (!(v_reg->v_eflags & 0x1) && !(v_reg->v_eflags & 0x40)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jae.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jae(v_register *v_reg) 4 | { 5 | DEBUG("jae\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (!(v_reg->v_eflags & 0x1) || (v_reg->v_eflags & 0x40)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jb.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jb(v_register *v_reg) 4 | { 5 | DEBUG("jb\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (v_reg->v_eflags & 0x1) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jbe.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jbe(v_register *v_reg) 4 | { 5 | DEBUG("jbe\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if ((v_reg->v_eflags & 0x1) || (v_reg->v_eflags & 0x40)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /je.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_je(v_register *v_reg) 4 | { 5 | DEBUG("je\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (v_reg->v_eflags & 0x40) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jg.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jg(v_register *v_reg) 4 | { 5 | DEBUG("jg\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if ((v_reg->v_eflags & 0x80 == v_reg->v_eflags & 0x800) && !(v_reg->v_eflags & 0x40)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jge.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jge(v_register *v_reg) 4 | { 5 | DEBUG("jge\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if ((v_reg->v_eflags & 0x80 == v_reg->v_eflags & 0x800) || (v_reg->v_eflags & 0x40)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jl.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jl(v_register *v_reg) 4 | { 5 | DEBUG("jl\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (((v_reg->v_eflags & 0x80) >> 7) != (v_reg->v_eflags & 0x800) >> 11) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jle.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jle(v_register *v_reg) 4 | { 5 | DEBUG("jle\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if ((v_reg->v_eflags & 0x80 != v_reg->v_eflags & 0x800) || (v_reg->v_eflags & 0x40)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jmp.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jmp(v_register *v_reg) 4 | { 5 | DEBUG("jmp\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (info[0].SIGN == 2) { 10 | v_reg->v_rip -= *(long long *)info[0].operand; 11 | } 12 | else { 13 | v_reg->v_rip += *(long long *)info[0].operand; 14 | } 15 | 16 | free(info); 17 | } 18 | -------------------------------------------------------------------------------- /jne.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jne(v_register *v_reg) 4 | { 5 | DEBUG("jne\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (!(v_reg->v_eflags & 0x40)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jno.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jno(v_register *v_reg) 4 | { 5 | DEBUG("jno\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (!(v_reg->v_eflags & 0x800)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jns.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jns(v_register *v_reg) 4 | { 5 | DEBUG("jns\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (!(v_reg->v_eflags & 0x80)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jnz.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jnz(v_register *v_reg) 4 | { 5 | DEBUG("jnz\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (!(v_reg->v_eflags & 0x40)) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jo.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jo(v_register *v_reg) 4 | { 5 | DEBUG("jo\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (v_reg->v_eflags & 0x800) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /js.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_js(v_register *v_reg) 4 | { 5 | DEBUG("js\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (v_reg->v_eflags & 0x80) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /jz.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_jz(v_register *v_reg) 4 | { 5 | DEBUG("jz\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | if (v_reg->v_eflags & 0x40) { 10 | if (info[0].SIGN == 2) { 11 | v_reg->v_rip -= *(long long *)info[0].operand; 12 | } 13 | else { 14 | v_reg->v_rip += *(long long *)info[0].operand; 15 | } 16 | } 17 | 18 | free(info); 19 | } 20 | -------------------------------------------------------------------------------- /lea.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_lea(v_register *v_reg) 4 | { 5 | DEBUG("lea\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | if (info[0].SIZE == 2) { 10 | *(int *)info[0].operand = (int)info[1].operand; 11 | } 12 | else if (info[0].SIZE == 3) { 13 | *(long long *)info[0].operand = (long long)info[1].operand; 14 | } 15 | 16 | free(info); 17 | } 18 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | /* 4 | * 5 | * [ ] rbp - 0x200 <-- rsp 6 | * [ ] : 7 | * [ ] : 8 | * [ v_rax ] rbp - 0xa0 <-- v_rbp, v_rsp 9 | * [ v_rbx ] rbp - 0x98 10 | * [ v_rcx ] rbp - 0x90 11 | * [ v_rdx ] rbp - 0x88 12 | * [ v_rsi ] rbp - 0x80 13 | * [ v_rdi ] rbp - 0x78 14 | * [ v_rbp ] rbp - 0x70 15 | * [ v_rsp ] rbp - 0x68 16 | * [ v_rip ] rbp - 0x60 17 | * [ v_r8 ] rbp - 0x58 18 | * [ v_r9 ] rbp - 0x50 19 | * [ v_r10 ] rbp - 0x48 20 | * [ v_r11 ] rbp - 0x40 21 | * [ v_r12 ] rbp - 0x38 22 | * [ v_r13 ] rbp - 0x30 23 | * [ v_r14 ] rbp - 0x28 24 | * [ v_r15 ] rbp - 0x20 25 | * [ v_rsv ] rbp - 0x18 26 | * [ v_eflag ] rbp - 0x10 27 | * [ old_rbp ] rbp - 0x8 <-- rbp, old_rsp 28 | * [ ret ] 29 | * 30 | */ 31 | 32 | void (*v_table[])(v_register *v_reg) = { 33 | v_nop, 34 | v_push, 35 | v_pop, 36 | v_mov, 37 | v_movsx, 38 | v_movsxd, 39 | v_movzx, 40 | v_cdqe, 41 | v_lea, 42 | v_add, 43 | v_sub, 44 | v_xor, 45 | v_jmp, 46 | v_je, 47 | v_jne, 48 | v_jg, 49 | v_jge, 50 | v_ja, 51 | v_jae, 52 | v_jl, 53 | v_jle, 54 | v_jb, 55 | v_jbe, 56 | v_jo, 57 | v_jno, 58 | v_jz, 59 | v_jnz, 60 | v_js, 61 | v_jns, 62 | v_shl, 63 | v_shr, 64 | v_cmp, 65 | v_test, 66 | v_call, 67 | v_div, 68 | v_imul 69 | }; 70 | 71 | char v_code[] = {'\x83', '\xb7', '\x06', '\x18', '\x63', '\x05', '\x83', '\xb6', '\x06', '\x1c', '\x62', '\x04', '\x83', '\xb6', '\x06', '\x04', '\x00', '\x01', '\x8c', '\x20', '\xde', '\x00', '\x00', '\x83', '\x62', '\x00', '\xb6', '\x06', '\x04', '\x87', '\x88', '\x63', '\x03', '\x67', '\x80', '\x83', '\x63', '\x00', '\xb7', '\x06', '\x18', '\x89', '\x63', '\x00', '\x63', '\x03', '\x83', '\x62', '\x00', '\x66', '\x00', '\x83', '\xb6', '\x06', '\x0c', '\x62', '\x00', '\x83', '\x62', '\x00', '\xb6', '\x06', '\x04', '\x8a', '\x62', '\x00', '\x00', '\x01', '\x83', '\xb6', '\x06', '\x08', '\x62', '\x00', '\x8c', '\x20', '\x47', '\x00', '\x00', '\x83', '\x62', '\x00', '\xb6', '\x06', '\x08', '\x87', '\x88', '\x63', '\x03', '\x67', '\x80', '\x83', '\x63', '\x00', '\xb7', '\x06', '\x18', '\x89', '\x63', '\x00', '\x63', '\x03', '\x83', '\x62', '\x03', '\xb6', '\x06', '\x08', '\x85', '\x63', '\x03', '\x62', '\x03', '\x89', '\x63', '\x03', '\x00', '\x01', '\x88', '\x63', '\x02', '\x67', '\x83', '\x83', '\x63', '\x03', '\xb7', '\x06', '\x18', '\x89', '\x63', '\x03', '\x63', '\x02', '\x83', '\x62', '\x00', '\x66', '\x00', '\x83', '\x66', '\x03', '\x62', '\x00', '\x8a', '\xb6', '\x06', '\x08', '\x00', '\x01', '\x9f', '\xb6', '\x06', '\x08', '\x00', '\x00', '\x9b', '\x20', '\x27', '\x00', '\x00', '\x83', '\x62', '\x00', '\xb6', '\x06', '\x08', '\x87', '\x88', '\x63', '\x03', '\x67', '\x80', '\x83', '\x63', '\x00', '\xb7', '\x06', '\x18', '\x89', '\x63', '\x00', '\x63', '\x03', '\x83', '\x62', '\x00', '\x66', '\x00', '\x9f', '\xb6', '\x06', '\x0c', '\x62', '\x00', '\x93', '\x30', '\x79', '\x00', '\x00', '\x83', '\x62', '\x00', '\xb6', '\x06', '\x08', '\x87', '\x89', '\x63', '\x00', '\x00', '\x01', '\x88', '\x63', '\x03', '\x67', '\x80', '\x83', '\x63', '\x00', '\xb7', '\x06', '\x18', '\x89', '\x63', '\x03', '\x63', '\x00', '\x83', '\x62', '\x00', '\xb6', '\x06', '\x0c', '\x83', '\x66', '\x03', '\x62', '\x00', '\x89', '\xb6', '\x06', '\x04', '\x00', '\x01', '\x83', '\x62', '\x00', '\xb6', '\x06', '\x04', '\x9f', '\x62', '\x00', '\xb6', '\x06', '\x1c', '\x93', '\x30', '\xef', '\x00', '\x00', '\x80', '\x00'}; 72 | 73 | void volatile insertionSort(int arr[], int n) 74 | { 75 | __asm__ 76 | ( 77 | ".intel_syntax noprefix;" 78 | "construct:;" 79 | " sub rsp, 0x200;" // set rsp to lower place 80 | " lea rax, [rbp - 0xa0];" 81 | " mov qword ptr [rbp - 0x70], rax;" // set v_rbp 82 | " mov qword ptr [rbp - 0x68], rax;" // set v_rsp 83 | " lea rax, %0;" 84 | " mov qword ptr [rbp - 0x60], rax;" // set v_rip 85 | " mov qword ptr [rbp - 0x78], rdi;" // set v_rdi 86 | " mov qword ptr [rbp - 0x80], rsi;" // set v_rsi 87 | "fetch:;" 88 | " xor rax, rax;" 89 | " mov rbx, qword ptr [rbp - 0x60];" 90 | " mov al, byte ptr [rbx];" 91 | " test al, al;" // test if next opcode is \x00 92 | " je destruct;" 93 | "execute:;" 94 | " lea rdi, [rbp - 0xa0];" 95 | " sub rax, 0x80;" 96 | " shl rax, 3;" 97 | " lea rbx, %1;" 98 | " add rbx, rax;" // use rax as v_table offset 99 | " call qword ptr [rbx];" // call function accordingly 100 | " jmp fetch;" 101 | "destruct:;" 102 | " mov rax, qword ptr [rbp - 0xa0];" // return value 103 | " mov rsp, rbp;" // restore rsp 104 | : 105 | : "m" (v_code), "m" (v_table) 106 | : 107 | ); 108 | } 109 | 110 | void printArray(int arr[], int n) 111 | { 112 | int i; 113 | for (i = 0; i < n; i++) 114 | printf("%d ", arr[i]); 115 | printf("\n"); 116 | } 117 | 118 | int main() 119 | { 120 | int arr[] = {1524, 5772, 9906, 9432, 5306, 5762, 4371, 9723, 9262, 9163, 548, 3736, 3436, 7444, 9943, 811, 4215, 4729, 2628, 4105, 4037, 4083, 5397, 8664, 9460, 1784, 3785, 3067, 9358, 7312, 8307, 1937, 4282, 3470, 5392, 9720, 4800, 4886, 8412, 7641, 9326, 3347, 2090, 4488, 9799, 7541, 316, 9869, 2501, 4003, 9095, 784, 1351, 1507, 8407, 5526, 9557, 5974, 9651, 5200, 4325, 2102, 9228, 6673, 4274, 7979, 5030, 2421, 3103, 9062, 4841, 2096, 3501, 8380, 2422, 6122, 6033, 855, 6767, 4297, 8859, 7955, 176, 8883, 5556, 4988, 6100, 6091, 9274, 8378, 7696, 8531, 3927, 8836, 6839, 3592, 2739, 3150, 7955, 2887, 5002, 3536, 5918, 627, 5063, 6466, 7177, 5152, 5581, 4314, 1617, 8122, 4920, 3178, 7696, 4357, 6206, 2738, 529, 6669, 5035, 7676, 1470, 616, 1784, 2596, 6340, 1917, 7703, 7437, 9938, 7014, 8238, 5793, 758, 9369, 6611, 8693, 4445, 2894, 7870, 9801, 2581, 3915, 938, 184, 8947, 329, 9964, 2499, 8741, 3345, 8551, 7111, 3362, 1029, 3947}; 121 | int n = sizeof(arr) / sizeof(arr[0]); 122 | 123 | insertionSort(arr, n); 124 | printArray(arr, n); 125 | 126 | return 0; 127 | } 128 | -------------------------------------------------------------------------------- /mov.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_mov(v_register *v_reg) 4 | { 5 | DEBUG("mov\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | if (info[0].SIZE == 0) { 10 | *(char *)info[0].operand = *(char *)info[1].operand; 11 | } 12 | else if (info[0].SIZE == 1) { 13 | *(short *)info[0].operand = *(short *)info[1].operand; 14 | } 15 | else if (info[0].SIZE == 2) { 16 | *(int *)info[0].operand = *(int *)info[1].operand; 17 | } 18 | else if (info[0].SIZE == 3) { 19 | *(long long *)info[0].operand = *(long long *)info[1].operand; 20 | } 21 | 22 | free(info); 23 | } 24 | -------------------------------------------------------------------------------- /movsx.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_movsx(v_register *v_reg) 4 | { 5 | DEBUG("movsx\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | long long tmp = *(long long *)info[1].operand; 10 | 11 | if (info[1].SIZE == 0) { 12 | tmp = (long long)*(char *)&tmp; 13 | } 14 | else if (info[1].SIZE == 1) { 15 | tmp = (long long)*(short *)&tmp; 16 | } 17 | else if (info[1].SIZE == 2) { 18 | tmp = (long long)*(int *)&tmp; 19 | } 20 | 21 | if (info[0].SIZE == 0) { 22 | *(char *)info[0].operand = *(char *)&tmp; 23 | } 24 | else if (info[0].SIZE == 1) { 25 | *(short *)info[0].operand = *(short *)&tmp; 26 | } 27 | else if (info[0].SIZE == 2) { 28 | *(int *)info[0].operand = *(int *)&tmp; 29 | } 30 | else if (info[0].SIZE == 3) { 31 | *(long long *)info[0].operand = *(long long *)&tmp; 32 | } 33 | 34 | free(info); 35 | } 36 | -------------------------------------------------------------------------------- /movsxd.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_movsxd(v_register *v_reg) 4 | { 5 | DEBUG("movsxd\n"); 6 | 7 | v_movsx(v_reg); 8 | } 9 | -------------------------------------------------------------------------------- /movzx.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_movzx(v_register *v_reg) 4 | { 5 | DEBUG("movzx\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | long long tmp = *(long long *)info[1].operand; 10 | 11 | if (info[1].SIZE == 0) { 12 | tmp = (long long)*(char *)&tmp & 0xff; 13 | } 14 | else if (info[1].SIZE == 1) { 15 | tmp = (long long)*(short *)&tmp & 0xffff; 16 | } 17 | else if (info[1].SIZE == 2) { 18 | tmp = (long long)*(int *)&tmp & 0xffffffff; 19 | } 20 | 21 | if (info[0].SIZE == 0) { 22 | *(char *)info[0].operand = *(char *)&tmp; 23 | } 24 | else if (info[0].SIZE == 1) { 25 | *(short *)info[0].operand = *(short *)&tmp; 26 | } 27 | else if (info[0].SIZE == 2) { 28 | *(int *)info[0].operand = *(int *)&tmp; 29 | } 30 | else if (info[0].SIZE == 3) { 31 | *(long long *)info[0].operand = *(long long *)&tmp; 32 | } 33 | 34 | free(info); 35 | } 36 | -------------------------------------------------------------------------------- /nop.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_nop(v_register *v_reg) 4 | { 5 | DEBUG("nop\n"); 6 | 7 | v_info *info = parse(v_reg, 0); 8 | 9 | free(info); 10 | } 11 | -------------------------------------------------------------------------------- /parse.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | v_info *parse(v_register *v_reg, int size) 4 | { 5 | v_info *info; 6 | info = malloc(size * sizeof(v_info)); 7 | 8 | int idx = 0; 9 | char v_code[16]; 10 | 11 | //skip inst byte 12 | v_code[idx++] = *(char *)(v_reg->v_rip); 13 | v_reg->v_rip++; 14 | 15 | for (int i = 0; i < size; i++) { 16 | 17 | // skip opX_meta byte 18 | char meta = *(char *)(v_reg->v_rip); 19 | v_code[idx++] = meta; 20 | v_reg->v_rip++; 21 | 22 | info[i].TYPE = (meta & 0xe0) >> 5; 23 | info[i].SIGN = (meta & 0x18) >> 3; 24 | info[i].REF = (meta & 0x4) >> 2; 25 | info[i].SIZE = (meta & 0x3); 26 | 27 | DEBUG("op%d_TYPE: %d\n", i, info[i].TYPE); 28 | DEBUG("op%d_SIGN: %d\n", i, info[i].SIGN); 29 | DEBUG("op%d_REF: %d\n", i, info[i].REF); 30 | DEBUG("op%d_SIZE: %d\n", i, info[i].SIZE); 31 | DEBUG("\n"); 32 | 33 | // immediate only 34 | if (info[i].TYPE <= 2) { 35 | int avail_size[] = {1, 3, 8}; 36 | int imm_size = avail_size[info[i].TYPE]; 37 | char imm[8] = {0}; 38 | strncpy(&v_code[idx], (char *)(v_reg->v_rip), imm_size); 39 | strncpy(imm, (char *)(v_reg->v_rip), imm_size); 40 | v_reg->v_rip += imm_size; 41 | idx += imm_size; 42 | 43 | info[i].operand = (long long)imm; 44 | } 45 | // reference 46 | else if (info[i].REF) { 47 | // first register 48 | char reg = *(char *)(v_reg->v_rip); 49 | v_code[idx++] = reg; 50 | v_reg->v_rip++; 51 | 52 | info[i].operand = (long long)v_reg; 53 | int mul = 0; 54 | if ((reg & 0xff) > 0x11) { 55 | mul = (reg & 0xc0) >> 6; 56 | reg &= 0x3f; 57 | } 58 | info[i].operand += reg * 8; 59 | info[i].operand = *(long long *)(info[i].operand); 60 | info[i].operand <<= mul; 61 | 62 | // check second register 63 | if (info[i].TYPE == 4 || info[i].TYPE == 7) { 64 | long long tmp; 65 | char reg = *(char *)(v_reg->v_rip); 66 | v_code[idx++] = reg; 67 | v_reg->v_rip++; 68 | 69 | tmp = (long long)v_reg; 70 | int mul = 0; 71 | if ((reg & 0xff) > 0x11) { 72 | mul = (reg & 0xc0) >> 6; 73 | reg &= 0x3f; 74 | } 75 | tmp += reg * 8; 76 | tmp = *(long long *)tmp; 77 | tmp <<= mul; 78 | if (info[i].SIGN & 0x2) { 79 | info[i].operand -= tmp; 80 | } 81 | else { 82 | info[i].operand += tmp; 83 | } 84 | } 85 | 86 | // check immediate 87 | if (info[i].TYPE == 5 || info[i].TYPE == 6) { 88 | int avail_size[] = {1, 3}; 89 | int imm_size = avail_size[info[i].TYPE - 5]; 90 | char imm[8] = {0}; 91 | strncpy(&v_code[idx], (char *)(v_reg->v_rip), imm_size); 92 | strncpy(imm, (char *)(v_reg->v_rip), imm_size); 93 | v_reg->v_rip += imm_size; 94 | idx += imm_size; 95 | 96 | if (info[i].SIGN & 0x2) { 97 | info[i].operand -= *(long long *)imm; 98 | } 99 | else { 100 | info[i].operand += *(long long *)imm; 101 | } 102 | } 103 | 104 | else if (info[i].TYPE == 7){ 105 | char imm[8] = {0}; 106 | strncpy(&v_code[idx], (char *)(v_reg->v_rip), 1); 107 | strncpy(imm, (char *)(v_reg->v_rip), 1); 108 | v_reg->v_rip++; 109 | idx++; 110 | 111 | if (info[i].SIGN & 0x1) { 112 | info[i].operand -= *(long long *)imm; 113 | } 114 | else { 115 | info[i].operand += *(long long *)imm; 116 | } 117 | } 118 | } 119 | // register only 120 | else { 121 | char reg = *(char *)(v_reg->v_rip); 122 | v_code[idx++] = reg; 123 | v_reg->v_rip++; 124 | 125 | info[i].operand = (long long)v_reg; 126 | info[i].operand += reg * 8; 127 | } 128 | } 129 | 130 | // print v_code 131 | for (int i = 0; i < idx; i++) { 132 | DEBUG("0x%02x ", v_code[i] & 0xff); 133 | } 134 | DEBUG("\n"); 135 | 136 | return info; 137 | } 138 | -------------------------------------------------------------------------------- /pop.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_pop(v_register *v_reg) 4 | { 5 | printf("pop\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | free(info); 10 | } 11 | -------------------------------------------------------------------------------- /push.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_push(v_register *v_reg) 4 | { 5 | printf("push\n"); 6 | 7 | v_info *info = parse(v_reg, 1); 8 | 9 | free(info); 10 | } 11 | -------------------------------------------------------------------------------- /shl.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_shl(v_register *v_reg) 4 | { 5 | DEBUG("shl\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | if (info[0].SIZE == 0) { 10 | *(char *)info[0].operand <<= *(int *)info[1].operand; 11 | } 12 | else if (info[0].SIZE == 1) { 13 | *(short *)info[0].operand <<= *(int *)info[1].operand; 14 | } 15 | else if (info[0].SIZE == 2) { 16 | *(int *)info[0].operand <<= *(int *)info[1].operand; 17 | } 18 | else if (info[0].SIZE == 3) { 19 | *(long long *)info[0].operand <<= *(int *)info[1].operand; 20 | } 21 | 22 | free(info); 23 | } 24 | -------------------------------------------------------------------------------- /shr.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_shr(v_register *v_reg) 4 | { 5 | DEBUG("shr\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | if (info[0].SIZE == 0) { 10 | *(char *)info[0].operand >>= *(int *)info[1].operand; 11 | } 12 | else if (info[0].SIZE == 1) { 13 | *(short *)info[0].operand >>= *(int *)info[1].operand; 14 | } 15 | else if (info[0].SIZE == 2) { 16 | *(int *)info[0].operand >>= *(int *)info[1].operand; 17 | } 18 | else if (info[0].SIZE == 3) { 19 | *(long long *)info[0].operand >>= *(int *)info[1].operand; 20 | } 21 | 22 | free(info); 23 | } 24 | -------------------------------------------------------------------------------- /sub.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_sub(v_register *v_reg) 4 | { 5 | DEBUG("sub\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | if (info[0].SIZE == 0) { 10 | *(char *)info[0].operand -= *(char *)info[1].operand; 11 | } 12 | else if (info[0].SIZE == 1) { 13 | *(short *)info[0].operand -= *(short *)info[1].operand; 14 | } 15 | else if (info[0].SIZE == 2) { 16 | *(int *)info[0].operand -= *(int *)info[1].operand; 17 | } 18 | else if (info[0].SIZE == 3) { 19 | *(long long *)info[0].operand -= *(long long *)info[1].operand; 20 | } 21 | 22 | free(info); 23 | } 24 | -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_test(v_register *v_reg) 4 | { 5 | DEBUG("test\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | int PF; 10 | int ZF; 11 | int SF; 12 | 13 | if (info[0].SIZE == 0) { 14 | char result = *(char *)info[0].operand & *(char *)info[1].operand; 15 | SF = (result & (1 << 7)) >> 7; 16 | ZF = (result) ? 0 : 1; 17 | for (int i = 0; i < 8; i++) { 18 | PF ^= (result & (1 << i)) >> i; 19 | } 20 | } 21 | else if (info[0].SIZE == 1) { 22 | short result = *(short *)info[0].operand & *(short *)info[1].operand; 23 | SF = (result & (1 << 15)) >> 15; 24 | ZF = (result) ? 0 : 1; 25 | for (int i = 0; i < 16; i++) { 26 | PF ^= (result & (1 << i)) >> i; 27 | } 28 | } 29 | else if (info[0].SIZE == 2) { 30 | int result = *(int *)info[0].operand & *(int *)info[1].operand; 31 | SF = (result & (1 << 31)) >> 31; 32 | ZF = (result) ? 0 : 1; 33 | for (int i = 0; i < 32; i++) { 34 | PF ^= (result & (1 << i)) >> i; 35 | } 36 | } 37 | else if (info[0].SIZE == 3) { 38 | long long result = *(long long *)info[0].operand & *(long long *)info[1].operand; 39 | SF = (result & (1LL << 63)) >> 63; 40 | ZF = (result) ? 0 : 1; 41 | for (int i = 0; i < 64; i++) { 42 | PF ^= (result & (1 << i)) >> i; 43 | } 44 | } 45 | 46 | // set CF and OF to 0 47 | v_reg->v_eflags &= ~0x801; 48 | 49 | // set PF 50 | if (PF) { 51 | v_reg->v_eflags |= 0x4; 52 | } 53 | else { 54 | v_reg->v_eflags &= ~0x4; 55 | } 56 | 57 | // set ZF 58 | if (ZF) { 59 | v_reg->v_eflags |= 0x40; 60 | } 61 | else { 62 | v_reg->v_eflags &= ~0x40; 63 | } 64 | 65 | // set SF 66 | if (SF) { 67 | v_reg->v_eflags |= 0x80; 68 | } 69 | else { 70 | v_reg->v_eflags &= ~0x80; 71 | } 72 | 73 | free(info); 74 | } 75 | -------------------------------------------------------------------------------- /test/Makefile: -------------------------------------------------------------------------------- 1 | CC = gcc 2 | CFLAGS = -no-pie -fno-stack-protector 3 | 4 | all: cal hash sort 5 | 6 | cal: cal.c 7 | $(CC) $(CFLAGS) -o $@ $^ 8 | 9 | hash: hash.c 10 | $(CC) $(CFLAGS) -o $@ $^ 11 | 12 | sort: sort.c 13 | $(CC) $(CFLAGS) -o $@ $^ 14 | -------------------------------------------------------------------------------- /test/cal.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int func(int x, int y) 4 | { 5 | int a = x; 6 | int b = y; 7 | return a ^ b; 8 | } 9 | 10 | int main(void) 11 | { 12 | int x, y; 13 | printf("x: "); 14 | scanf("%d", &x); 15 | printf("y: "); 16 | scanf("%d", &y); 17 | printf("result: %d\n", func(x, y)); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /test/hash.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | long long sdbm(char *s) 4 | { 5 | long long hash = 0; 6 | int i = 0; 7 | while (s[i] != '\x00') 8 | { 9 | hash = s[i] + (hash << 6) + (hash << 16) - hash; 10 | i++; 11 | } 12 | return hash; 13 | } 14 | 15 | int main(void) 16 | { 17 | char s[64]; 18 | 19 | printf("input: "); 20 | scanf("%s", s); 21 | 22 | printf("sdbm: %s --> %lld\n", s, sdbm(s)); 23 | 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /test/sort.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void insertionSort(int arr[], int n) 4 | { 5 | int i, key, j; 6 | for (i = 1; i < n; i++) { 7 | key = arr[i]; 8 | j = i - 1; 9 | while (j >= 0 && arr[j] > key) { 10 | arr[j + 1] = arr[j]; 11 | j = j - 1; 12 | } 13 | arr[j + 1] = key; 14 | } 15 | } 16 | 17 | void printArray(int arr[], int n) 18 | { 19 | int i; 20 | for (i = 0; i < n; i++) 21 | printf("%d ", arr[i]); 22 | printf("\n"); 23 | } 24 | 25 | int main() 26 | { 27 | //int arr[] = {12, 11, 13, 5, 6}; 28 | int arr[] = {1524, 5772, 9906, 9432, 5306, 5762, 4371, 9723, 9262, 9163, 548, 3736, 3436, 7444, 9943, 811, 4215, 4729, 2628, 4105, 4037, 4083, 5397, 8664, 9460, 1784, 3785, 3067, 9358, 7312, 8307, 1937, 4282, 3470, 5392, 9720, 4800, 4886, 8412, 7641, 9326, 3347, 2090, 4488, 9799, 7541, 316, 9869, 2501, 4003, 9095, 784, 1351, 1507, 8407, 5526, 9557, 5974, 9651, 5200, 4325, 2102, 9228, 6673, 4274, 7979, 5030, 2421, 3103, 9062, 4841, 2096, 3501, 8380, 2422, 6122, 6033, 855, 6767, 4297, 8859, 7955, 176, 8883, 5556, 4988, 6100, 6091, 9274, 8378, 7696, 8531, 3927, 8836, 6839, 3592, 2739, 3150, 7955, 2887, 5002, 3536, 5918, 627, 5063, 6466, 7177, 5152, 5581, 4314, 1617, 8122, 4920, 3178, 7696, 4357, 6206, 2738, 529, 6669, 5035, 7676, 1470, 616, 1784, 2596, 6340, 1917, 7703, 7437, 9938, 7014, 8238, 5793, 758, 9369, 6611, 8693, 4445, 2894, 7870, 9801, 2581, 3915, 938, 184, 8947, 329, 9964, 2499, 8741, 3345, 8551, 7111, 3362, 1029, 3947}; 29 | int n = sizeof(arr) / sizeof(arr[0]); 30 | 31 | insertionSort(arr, n); 32 | printArray(arr, n); 33 | 34 | return 0; 35 | } 36 | -------------------------------------------------------------------------------- /vm.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #define DEBUG //printf 9 | 10 | typedef struct v_register 11 | { 12 | long long v_rax; 13 | long long v_rbx; 14 | long long v_rcx; 15 | long long v_rdx; 16 | long long v_rsi; 17 | long long v_rdi; 18 | long long v_rbp; 19 | long long v_rsp; 20 | long long v_rip; 21 | long long v_r8; 22 | long long v_r9; 23 | long long v_r10; 24 | long long v_r11; 25 | long long v_r12; 26 | long long v_r13; 27 | long long v_r14; 28 | long long v_r15; 29 | long long v_rsv; 30 | long long v_eflags; 31 | } v_register; 32 | 33 | typedef struct v_info 34 | { 35 | int TYPE; 36 | int SIGN; 37 | bool REF; 38 | int SIZE; 39 | long long operand; 40 | } v_info; 41 | 42 | v_info *parse(v_register *v_reg, int size); 43 | 44 | void v_nop(v_register *v_reg); 45 | 46 | void v_push(v_register *v_reg); 47 | 48 | void v_pop(v_register *v_reg); 49 | 50 | void v_mov(v_register *v_reg); 51 | 52 | void v_movsx(v_register *v_reg); 53 | 54 | void v_movsxd(v_register *v_reg); 55 | 56 | void v_movzx(v_register *v_reg); 57 | 58 | void v_cdqe(v_register *v_reg); 59 | 60 | void v_lea(v_register *v_reg); 61 | 62 | void v_add(v_register *v_reg); 63 | 64 | void v_sub(v_register *v_reg); 65 | 66 | void v_xor(v_register *v_reg); 67 | 68 | void v_jmp(v_register *v_reg); 69 | 70 | void v_je(v_register *v_reg); 71 | 72 | void v_jne(v_register *v_reg); 73 | 74 | void v_jg(v_register *v_reg); 75 | 76 | void v_jge(v_register *v_reg); 77 | 78 | void v_ja(v_register *v_reg); 79 | 80 | void v_jae(v_register *v_reg); 81 | 82 | void v_jl(v_register *v_reg); 83 | 84 | void v_jle(v_register *v_reg); 85 | 86 | void v_jb(v_register *v_reg); 87 | 88 | void v_jbe(v_register *v_reg); 89 | 90 | void v_jo(v_register *v_reg); 91 | 92 | void v_jno(v_register *v_reg); 93 | 94 | void v_jz(v_register *v_reg); 95 | 96 | void v_jnz(v_register *v_reg); 97 | 98 | void v_js(v_register *v_reg); 99 | 100 | void v_jns(v_register *v_reg); 101 | 102 | void v_shl(v_register *v_reg); 103 | 104 | void v_shr(v_register *v_reg); 105 | 106 | void v_cmp(v_register *v_reg); 107 | 108 | void v_test(v_register *v_reg); 109 | 110 | void v_call(v_register *v_reg); 111 | 112 | void v_div(v_register *v_reg); 113 | 114 | void v_imul(v_register *v_reg); 115 | -------------------------------------------------------------------------------- /x64_trans.py: -------------------------------------------------------------------------------- 1 | from capstone import * 2 | from pwn import * 3 | 4 | import re 5 | import string 6 | import subprocess 7 | import sys 8 | 9 | reg_table = { 10 | 'rax': '\x00', 11 | 'rbx': '\x01', 12 | 'rcx': '\x02', 13 | 'rdx': '\x03', 14 | 'rsi': '\x04', 15 | 'rdi': '\x05', 16 | 'rbp': '\x06', 17 | 'rsp': '\x07', 18 | 'rip': '\x08', 19 | 'r8' : '\x09', 20 | 'r9' : '\x0a', 21 | 'r10': '\x0b', 22 | 'r11': '\x0c', 23 | 'r12': '\x0d', 24 | 'r13': '\x0e', 25 | 'r14': '\x0f', 26 | 'r15': '\x10', 27 | 'rsv': '\x11', 28 | } 29 | 30 | inst_table = { 31 | 'nop' : '\x80', 32 | 'push' : '\x81',# 33 | 'pop' : '\x82',# 34 | 'mov' : '\x83', 35 | 'movsx' : '\x84', 36 | 'movsxd': '\x85', 37 | 'movzx' : '\x86', 38 | 'cdqe' : '\x87', 39 | 'lea' : '\x88', 40 | 'add' : '\x89', 41 | 'sub' : '\x8a', 42 | 'xor' : '\x8b', 43 | 'jmp' : '\x8c', 44 | 'je' : '\x8d', 45 | 'jne' : '\x8e', 46 | 'jg' : '\x8f', 47 | 'jge' : '\x90', 48 | 'ja' : '\x91', 49 | 'jae' : '\x92', 50 | 'jl' : '\x93', 51 | 'jle' : '\x94', 52 | 'jb' : '\x95', 53 | 'jbe' : '\x96', 54 | 'jo' : '\x97', 55 | 'jno' : '\x98', 56 | 'jz' : '\x99', 57 | 'jnz' : '\x9a', 58 | 'js' : '\x9b', 59 | 'jns' : '\x9c', 60 | 'shl' : '\x9d', 61 | 'shr' : '\x9e', 62 | 'cmp' : '\x9f', 63 | 'test' : '\xa0', 64 | 'call' : '\xa1',# 65 | 'div' : '\xa2',# 66 | 'imul' : '\xa3' # 67 | } 68 | 69 | vaddr = 0 70 | 71 | class Code: 72 | 73 | def __init__(self, addr, opcode, operand): 74 | 75 | self.addr = addr 76 | self.opcode = opcode 77 | self.operand = operand 78 | self.vcode = '' 79 | self.vaddr = 0 80 | 81 | self.TYPE = [] 82 | self.SIGN = [] 83 | self.REF = [] 84 | self.SIZE = [] 85 | self.reg = [] 86 | self.imm = [] 87 | 88 | def print_code(self): 89 | 90 | print '0x{:x}:\t{}\t{}'.format(self.addr, self.opcode, self.operand) 91 | print '' 92 | 93 | def virtualizatoin(self): 94 | 95 | ''' 96 | Vcode Format 97 | 98 | [inst] [opX_meta] [opX_data] 99 | 100 | [inst]: 1 byte 101 | [opX_meta]: 1 byte [type] [sign] [ref] [size] 102 | [type]: 3 bit 103 | 000 -> [imm(1)] 104 | 001 -> [imm(3)] 105 | 010 -> [imm(8)] 106 | 011 -> [reg] 107 | 100 -> [reg] [reg] 108 | 101 -> [reg] [imm(1)] 109 | 110 -> [reg] [imm(3)] 110 | 111 -> [reg] [reg] [imm(1)] 111 | [sign]: 2 bit 112 | [ref]: 1 bit 113 | [size]: 2 bit 114 | [opX_data]: 1~8 byte 115 | ''' 116 | 117 | # [inst] 118 | self.vcode += inst_table[self.opcode] 119 | 120 | # [opX_meta] 121 | ops = re.split(r', ', self.operand) 122 | for op in ops: 123 | 124 | if op == '': 125 | break 126 | 127 | print '< {} >'.format(op) 128 | 129 | TYPE = 0b000 130 | SIGN = 0b00 131 | REF = 0b0 132 | SIZE = 0b00 133 | 134 | reg = [] 135 | imm = 0 136 | 137 | # immediate only 138 | if op[0].isdigit(): 139 | 140 | # [imm] 141 | imm_str = op.replace('0x', '') 142 | imm = int(imm_str, 16) 143 | 144 | # [type] 145 | if len(imm_str) <= 2: 146 | TYPE = 0b000 147 | elif len(imm_str) <= 6: 148 | TYPE = 0b001 149 | elif len(imm_str) <= 16: 150 | TYPE = 0b010 151 | else: 152 | print 'imm error' 153 | sys.exit(1) 154 | 155 | # reference 156 | elif '[' in op: 157 | 158 | # [ref] 159 | REF = 0b1 160 | 161 | op = op.replace('[', '').replace(']', '') 162 | comps = re.split(r' ', op) 163 | 164 | # [size] 165 | if comps[0] == 'qword': 166 | SIZE = 0b11 167 | elif comps[0] == 'dword': 168 | SIZE = 0b10 169 | elif comps[0] == 'word': 170 | SIZE = 0b01 171 | elif comps[0] == 'byte': 172 | SIZE = 0b00 173 | else: 174 | print 'size error' 175 | sys.exit(1) 176 | 177 | comps = comps[2:] 178 | 179 | # differentiate by component length 180 | if len(comps) == 1: 181 | 182 | # [type] 183 | TYPE = 0b011 184 | 185 | # check if * in component 186 | if '*' in comps[0]: 187 | mul = comps[0][-1:] 188 | r = reg_table[comps[0][:-2]] 189 | if mul == '2': 190 | m = 0b01 191 | elif mul == '4': 192 | m = 0b10 193 | elif mul == '8': 194 | m = 0b11 195 | 196 | # [reg] 197 | reg.append(chr(ord(r) | (m << 6))) 198 | 199 | else: 200 | 201 | # [reg] 202 | reg.append(reg_table[comps[0]]) 203 | 204 | elif len(comps) == 3: 205 | 206 | # [sign] 207 | if comps[1] == '-': 208 | SIGN = 0b10 209 | 210 | # differentiate by third component 211 | if comps[2][0].isdigit(): 212 | 213 | # check if * in component 214 | if '*' in comps[0]: 215 | mul = comps[0][-1:] 216 | r = reg_table[comps[0][:-2]] 217 | if mul == '2': 218 | m = 0b01 219 | elif mul == '4': 220 | m = 0b10 221 | elif mul == '8': 222 | m = 0b11 223 | 224 | # [reg] 225 | reg.append(chr(ord(r) | (m << 6))) 226 | 227 | else: 228 | 229 | # [reg] 230 | reg.append(reg_table[comps[0]]) 231 | 232 | # [imm] 233 | imm_str = comps[2].replace('0x', '') 234 | imm = int(imm_str, 16) 235 | 236 | # [type] 237 | if len(imm_str) <= 2: 238 | TYPE = 0b101 239 | elif len(imm_str) <= 6: 240 | TYPE = 0b110 241 | else: 242 | print 'imm error' 243 | sys.exit(1) 244 | 245 | else: 246 | 247 | # [type] 248 | TYPE = 0b100 249 | 250 | for i in range(2): 251 | idx = i * 2 252 | 253 | # check if * in component 254 | if '*' in comps[idx]: 255 | mul = comps[idx][-1:] 256 | r = reg_table[comps[idx][:-2]] 257 | if mul == '2': 258 | m = 0b01 259 | elif mul == '4': 260 | m = 0b10 261 | elif mul == '8': 262 | m = 0b11 263 | 264 | # [reg] 265 | reg.append(chr(ord(r) | (m << 6))) 266 | 267 | else: 268 | 269 | # [reg] 270 | reg.append(reg_table[comps[idx]]) 271 | 272 | elif len(comps) == 5: 273 | 274 | # [type] 275 | TYPE = 0b111 276 | 277 | # [sign] 278 | if comps[1] == '-': 279 | SIGN |= 0b10 280 | if comps[3] == '-': 281 | SIGN |= 0b01 282 | 283 | for i in range(2): 284 | idx = i * 2 285 | 286 | # check if * in component 287 | if '*' in comps[idx]: 288 | mul = comps[idx][-1:] 289 | r = reg_table[comps[idx][:-2]] 290 | if mul == '2': 291 | m = 0b01 292 | elif mul == '4': 293 | m = 0b10 294 | elif mul == '8': 295 | m = 0b11 296 | 297 | # [reg] 298 | reg.append(chr(ord(r) | (m << 6))) 299 | 300 | else: 301 | 302 | # [reg] 303 | reg.append(reg_table[comps[idx]]) 304 | 305 | # [imm] 306 | imm_str = comps[4].replace('0x', '') 307 | imm = int(imm_str, 16) 308 | 309 | else: 310 | print 'type error' 311 | sys.exit(1) 312 | 313 | # register only 314 | else: 315 | 316 | # [type] 317 | TYPE = 0b011 318 | 319 | # [size] 320 | if op.startswith('r'): 321 | SIZE = 0b11 322 | elif op.startswith('e'): 323 | SIZE = 0b10 324 | op = op.replace('e', 'r') 325 | elif op.endswith('x'): 326 | SIZE = 0b01 327 | op = 'r' + op 328 | elif op.endswith('l'): 329 | SIZE = 0b00 330 | op = 'r' + op.replace('l', 'x') 331 | else: 332 | print 'size error' 333 | sys.exit(1) 334 | 335 | # [reg] 336 | reg.append(reg_table[op]) 337 | 338 | print 'TYPE: {0:03b}'.format(TYPE) 339 | print 'SIGN: {0:02b}'.format(SIGN) 340 | print 'REF: {:b}'.format(REF) 341 | print 'SIZE: {0:02b}'.format(SIZE) 342 | print 'reg: {}'.format(reg) 343 | print 'imm: 0x{:x}'.format(imm) 344 | print '' 345 | 346 | self.TYPE.append(TYPE) 347 | self.SIGN.append(SIGN) 348 | self.REF.append(REF) 349 | self.SIZE.append(SIZE) 350 | self.reg.append(reg) 351 | self.imm.append(imm) 352 | 353 | # append opX_meta to vcode 354 | meta = chr((TYPE << 5) + (SIGN << 3) + (REF << 2) + SIZE) 355 | self.vcode += meta 356 | 357 | # append opX_data to vcode 358 | if TYPE == 0b000: 359 | self.vcode += p64(imm)[:1] 360 | elif TYPE == 0b001: 361 | self.vcode += p64(imm)[:3] 362 | elif TYPE == 0b010: 363 | self.vcode += p64(imm) 364 | elif TYPE == 0b011: 365 | self.vcode += reg[0] 366 | elif TYPE == 0b100: 367 | self.vcode += reg[0] 368 | self.vcode += reg[1] 369 | elif TYPE == 0b101: 370 | self.vcode += reg[0] 371 | self.vcode += p64(imm)[:1] 372 | elif TYPE == 0b110: 373 | self.vcode += reg[0] 374 | self.vcode += p64(imm)[:3] 375 | elif TYPE == 0b111: 376 | self.vcode += reg[0] 377 | self.vcode += reg[1] 378 | self.vcode += p64(imm)[:1] 379 | else: 380 | print 'type error' 381 | sys.exit(1) 382 | 383 | # set virtual address 384 | global vaddr 385 | self.vaddr = vaddr 386 | vaddr += len(self.vcode) 387 | 388 | def print_vcode(self): 389 | 390 | print '0x{:x}:'.format(self.vaddr), 391 | for c in self.vcode: 392 | print '0x{:02x}'.format(ord(c)), 393 | 394 | print '' 395 | print '==================================================' 396 | 397 | 398 | def disassemble(exec_name, func_start, func_end): 399 | 400 | func_size = func_end - func_start + 1 401 | 402 | with open(exec_name, 'rb') as f: 403 | f.seek(func_start) 404 | binary = f.read(func_size) 405 | 406 | codes = [] 407 | md = Cs(CS_ARCH_X86, CS_MODE_64) 408 | for inst in md.disasm(binary, func_start): 409 | codes.append(Code(inst.address, inst.mnemonic, inst.op_str)) 410 | 411 | return codes 412 | 413 | def translate(exec_name, func_start, func_end): 414 | 415 | codes = disassemble(exec_name, func_start, func_end) 416 | for code in codes: 417 | code.print_code() 418 | code.virtualizatoin() 419 | code.print_vcode() 420 | 421 | # jump relocation 422 | for i in range(len(codes)): 423 | if codes[i].opcode.startswith('j') and codes[i].TYPE[0] <= 0b010: 424 | tar_addr = codes[i].imm[0] 425 | tar_vaddr = 0 426 | for j in range(len(codes)): 427 | if codes[j].addr == tar_addr: 428 | tar_vaddr = codes[j].vaddr 429 | 430 | # modify vcode 431 | curr_vaddr = codes[i].vaddr + len(codes[i].vcode) 432 | mod_vcode = '' 433 | if tar_vaddr > curr_vaddr: 434 | offset = tar_vaddr - curr_vaddr 435 | mod_vcode = codes[i].vcode[:2] + p64(offset)[:3] 436 | else: 437 | offset = curr_vaddr - tar_vaddr 438 | mod_vcode = codes[i].vcode[:1] + '\x30' + p64(offset)[:3] 439 | codes[i].vcode = mod_vcode 440 | 441 | # output 442 | vcode = '' 443 | for code in codes: 444 | vcode += code.vcode 445 | 446 | output = 'char v_code[] = {' 447 | for i in range(len(vcode)): 448 | output += "'\\x{:02x}', ".format(ord(vcode[i])) 449 | output += "'\\x00'};" 450 | 451 | print output 452 | 453 | def get_func_addr(exec_name, func_name): 454 | 455 | cmd = 'gdb -batch -ex "file {}" -ex "disassemble {}"'.format(exec_name, func_name) 456 | output = subprocess.check_output(cmd, shell=True).splitlines() 457 | 458 | func_start = int(output[1].split()[0], 16) - 0x400000 459 | func_end = int(output[-2].split()[0],16) - 0x400000 460 | 461 | return func_start, func_end 462 | 463 | if __name__ == '__main__': 464 | 465 | if len(sys.argv) != 3: 466 | print 'usage: python x64_trans.py [exec_name] [func_name]' 467 | exit() 468 | 469 | exec_name = sys.argv[1] 470 | func_name = sys.argv[2] 471 | 472 | # get function address range 473 | func_start, func_end = get_func_addr(exec_name, func_name) 474 | 475 | # skip function prologue & function epilogue 476 | func_start += 4 477 | func_end -= 2 478 | 479 | translate(exec_name, func_start, func_end) 480 | -------------------------------------------------------------------------------- /xor.c: -------------------------------------------------------------------------------- 1 | #include "vm.h" 2 | 3 | void v_xor(v_register *v_reg) 4 | { 5 | DEBUG("xor\n"); 6 | 7 | v_info *info = parse(v_reg, 2); 8 | 9 | if (info[0].SIZE == 0) { 10 | *(char *)info[0].operand ^= *(char *)info[1].operand; 11 | } 12 | else if (info[0].SIZE == 1) { 13 | *(short *)info[0].operand ^= *(short *)info[1].operand; 14 | } 15 | else if (info[0].SIZE == 2) { 16 | *(int *)info[0].operand ^= *(int *)info[1].operand; 17 | } 18 | else if (info[0].SIZE == 3) { 19 | *(long long *)info[0].operand = *(long long *)info[1].operand; 20 | } 21 | 22 | free(info); 23 | } 24 | --------------------------------------------------------------------------------