Useless emulator for fun (vmndh-2k12)
by @Jonathan Salwan - 2012-03-26Emulator NDH 2K12
This emulator was created for the CTF NDH 2012. Some challenges were on the NDH architecture. The NDH architecture is a new architecture which looks like a mix between ARM and x86.
GitHub (Stable v0.1) https://github.com/JonathanSalwan/VMNDH-2k12/
Authors
- Jonathan Salwan (Emulator & Architecture)
- Damien Cauquil (Compiler)
取り付け・設備
$ git clone git@github.com:JonathanSalwan/VMNDH-2k12.git
$ cd ./VMNDH-2k12
$ make
NDH Architecture
STACK [0000 - 7FFF] (default ASLR is 無能にする. 可能性 to 始める,決める ASLR with -aslr)
Program [8000 - FFFE] (default NX & PIE are 無能にする. 可能性 to 始める,決める NX & PIE with -nx -pie)
ASLR genered with:
__asm__("mov %gs:0x14, %eax");
__asm__("shr $0x08, %eax");
__asm__("mov %%eax, %0" : "=m"(aslr));
aslr = aslr % 0x3000 + 0x4ffe;
PIE genered with:
__asm__("mov %gs:0x14, %eax");
__asm__("shr $0x08, %eax");
__asm__("mov %%eax, %0" : "=m"(pie));
pie = pie % 0x3000 + 0x8000;
^ 0000>+-----------------+
| | | The max size of binary is 0x7ffe.
| | |
| | | Before the program is 遂行する/発効させるd, argv and argc are
| | STACK ^^ | 押し進めるd on the stack.
| | || | If an argument is 始める,決める with (-arg), argc = 1
| | | and argv points to the string.
| +-----------------+< SP & BP
6 | ARG | If you don't 始める,決める an argument, argc and argv
4 | | are 押し進めるd with value 0x00.
K 8000>+-----------------+< PC
| | |
| | || | Exemple1: ./vmndh -とじ込み/提出する ./binary
| | CODE vv |
| | | [SP] 0x00 0x00 0x00 0x00 0x00 0x00
| | | <--argc-> <-argv-->
| | |
v ffff>+-----------------+ Exemple2: ./vmndh -とじ込み/提出する ./binary -arg "abcd"
[SP] 0x01 0x00 0xac 0x7f 0x00 0x00
<--argc-> <-argv-->
とじ込み/提出する 判型
[MAGIC][size .text][.text content]
MAGIC: ".NDH"
SIZE: size of section TEXT
CODE: 指示/教授/教育s
指示/教授/教育s Encoding
[OPCODE] [OP_FLAGS | !] [OPERAND #1] [OPERAND #2]
[ADD] <opcode> <FLAG> <REG> <REG | DIR8 | DIR16> (size = 4 or 5 bytes)
- reg = 追加する
- dir8 = addb
- dir16 = addl
[AND] <opcode> <FLAG> <REG> <REG | DIR8 | DIR16> (size = 4 or 5 bytes)
- reg = and
- dir8 = andb
- dir16 = andl
[CALL] <opcode> <FLAG> <REG | DIR16> (size = 3 or 4 bytes)
[CMP] <opcode> <FLAG> <REG> <REG | DIR8 | DIR16> (size = 4 or 5 bytes)
- reg = cmp
- dir8 = cmpb
- dir16 = cmpl
[DEC] <opcode> <REG> (size = 2)
[DIV] <opcode> <FLAG> <REG> <REG | DIR8 | DIR16> (size = 4 or 5 bytes)
- reg = div
- dir8 = divb
- dir16 = divl
[END] <opcode> (size = 1 byte)
[INC] <opcode> <REG> (size = 2 bytes)
[JMPL] <opcode> <DIR16> (size = 3 bytes)
[JMPS] <opcode> <DIR8> (size = 2 bytes)
[JNZ] <opcode> <DIR16> (size = 3 bytes)
[JZ] <opcode> <DIR16> (size = 3 bytes)
[JA] <opcode> <DIR16> (size = 3 bytes)
[JB] <opcode> <DIR16> (size = 3 bytes)
[MOV] <opcode> <FLAG> <REG | REG_INDIRECT> <REG | REG_INDIRECT | DIR8 | DIR16> (size = 4 or 5 bytes)
- reg = mov
- dir8 = movb
- dir16 = movl
- indir = mov [rX]
[MUL] <opcode> <FLAG> <REG> <REG | DIR8 | DIR16> (size = 4 or 5 bytes)
- reg = mul
- dir8 = mulb
- dir16 = 検討する,考慮する
[NOP] <opcode> (size = 1 byte)
[NOT] <opcode> <REG> (size = 2 bytes)
[OR] <opcode> <FLAG> <REG> <REG | DIR8 | DIR16> (size = 4 or 5 bytes)
- reg = or
- dir8 = orb
- dir16 = orl
[POP] <opcode> <REG> (size = 2 bytes)
[PUSH] <opcode> <FLAG> <REG | DIR08 | DIR16> (size = 3 or 4 bytes)
- reg = 押し進める
- dir8 = pushb
- dir16 = pushl
[RET] <opcode> (size = 1 byte)
[SUB] <opcode> <FLAG> <REG> <REG | DIR8 | DIR16> (size = 4 or 5 bytes)
- reg = sub
- dir8 = subb
- dir16 = subl
[SYSCALL] <opcode> (size = 1 byte)
[TEST] <opcode> <REG> <REG> (size = 3 bytes)
[XCHG] <opcode> <REG> <REG> (size = 3 bytes
[XOR] <opcode> <FLAG> <REG> <REG | DIR8 | DIR16> (size = 4 or 5 bytes)
- reg = xor
- dir8 = xorb
- dir16 = xorl
Syscalls
r0 = syscall number
r1 = arg1
r2 = arg2
r3 = arg3
r4 = arg4
syscalls supported: open(), read(), 令状(), の近くに(), 出口(), setuid(), setgid(), dup2(),
send() recv(), socket(), listen(), 貯蔵所d(), 受託する(), chdir(), chmod(),
lseek(), getpid(), getuid(), pause()
[sys_open] r1 = uint16_t *
r2 = uint16_t
r3 = uint16_t
[sys_exit] r1 = uint16_t
[sys_read] r1 = uint16_t
r2 = uint16_t *
r3 = uint16_t
[sys_write] r1 = uint16_t
r2 = uint16_t *
r3 = uint16_t
[sys_close] r1 = uint16_t
[sys_exit] r1 = uint16_t
[sys_setuid] r1 = uint16_t
[sys_setgid] r1 = uint16_t
[sys_dup2] r1 = uint16_t
r2 = uint16_t
[sys_send] r1 = uint16_t
r2 = uint16_t *
r3 = uint16_t
r4 = uint16_t
[sys_recv] r1 = uint16_t
r2 = uint16_t *
r3 = uint16_t
r4 = uint16_t
[sys_socket] r1 = uint16_t
r2 = uint16_t
r3 = uint16_t
[sys_listen] r1 = uint16_t
r2 = uint16_t
[sys_bind] r1 = uint16_t (socket)
r2 = uint16_t (port)
[sys_accept] r1 = uint16_t (socket)
[SYS_CHDIR] r1 = uint16_t *
[SYS_CHMOD] r1 = uint16_t *
r2 = uint16_t
[SYS_LSEEK] r1 = uint16_t
r2 = uint16_t
r3 = uint16_t
[SYS_GETPID] n/a
[SYS_GETUID] n/a
[SYS_PAUSE] n/a
旗s
ZF
is 始める,決める with に引き続いて 指示/教授/教育s:
- ADD
- SUB
- MUL
- DIC
- INC
- DEC
- OR
- XOR
- AND
- NOT
- TEST
- CMP
AF
& BF
are 始める,決める with に引き続いて 指示/教授/教育s:
- CMP
AF
& BF
are used for JA
and JB
指示/教授/教育s.
Usage
Syntax: ./vmndh [OPTION] [FLAG]
OPTION:
-とじ込み/提出する 負担 binary
-arg Binary argument (optional)
FLAG:
-aslr Enable ASLR
-nx Enable NX bit
-pie Enable PIE
-debug Debug console
-核心 生成するs a 核心 捨てる when segfault
Compiler
The compiler is written in python and support labels, comments and 含むs. You can see the に引き続いて source code with the famous 'Hello World'.
; NDH Hello world 見本
.label main
movl r0, :helloworld
movl r1, #0
movl r2, #0
movl r5, #0
.label 宙返り飛行
mov r2, [r0]
実験(する) r2,r2
inc r5
inc r0
jnz :宙返り飛行
movb r0, #4
movb r1, #1
movl r2, :helloworld
mov r3, r5
syscall
end
.label helloworld
.db "Hello World !",0x0A,0
収集する example
$ ./ndasm/ndasm.py -i ./src_asm_challenge/hello_world.asm -o hello_world.ndh
[*] Parsing source とじ込み/提出する ...
[+] 組み立てる/集結するing ...
[*] Linking ...
[*] Creating outfile ...
[*] Done. 71 bytes written.
$ ./vmndh -とじ込み/提出する ./hello_world.ndh
Hello World !
$