This emulator is totally useless, but it 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/
git clone git@github.com:JonathanSalwan/VMNDH-2k12.git cd ./VMNDH-2k12 make
STACK [0000 - 7FFF] (default ASLR is disable. Possibility to set ASLR with -aslr) Program [8000 - FFFE] (default NX & PIE are disable. Possibility to set 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 executed, argv and argc are | | STACK ^^ | pushed on the stack. | | || | If an argument is set with (-arg), argc = 1 | | | and argv points to the string. | +-----------------+< SP & BP 6 | ARG | If you don't set an argument, argc and argv 4 | | are pushed with value 0x00. K 8000>+-----------------+< PC | | | | | || | Exemple1: ./vmndh -file ./binary | | CODE vv | | | | [SP] 0x00 0x00 0x00 0x00 0x00 0x00 | | | <--argc-> <-argv--> | | | v ffff>+-----------------+ Exemple2: ./vmndh -file ./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: instructions
All registers are on 16 bits.
[OPCODE] [OP_FLAGS | !] [OPERAND #1] [OPERAND #2] [ADD] <opcode> <FLAG> <REG> <REG | DIR8 | DIR16> (size = 4 or 5 bytes) - reg = add - 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 = mull [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 = push - 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
r0 = syscall number r1 = arg1 r2 = arg2 r3 = arg3 r4 = arg4 syscalls supported: open(), read(), write(), close(), exit(), setuid(), setgid(), dup2(), send() recv(), socket(), listen(), bind(), accept(), 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
The syscall's return value is set into r0.
ZF is set with following instructions:
AF & BF are set with following instructions:
AF & BF are used for JA and JB instructions.
Syntax: ./vmndh [OPTION] <binary> [FLAG] OPTION: -file Load binary -arg Binary argument (optional) FLAG: -aslr Enable ASLR -nx Enable NX bit -pie Enable PIE -debug Debug console -core Generates a core dump when segfault
You can use the debug console with '-debug' flag for debugging ndh binary.
[Console]#> help <enter> Execute next instruction run Run program bp <addr> Set breakpoint info bp Display info breakpoint info reg Display registers show sp Display SP memory show pc Display PC memory dis <addr>:<size> Disassembly X bytes from ADDR x/x <addr>:<size> Print X bytes from ADDR x/s <addr> Print string addr set reg=value Set value in register syscall Execute 'syscall' instruction help Display this help quit Quit console debugging [Console]#>
The compiler is written in python and support labels, comments and includes. You can see the following source code with the famous 'Hello World'.
; NDH Hello world sample .label main movl r0, :helloworld movl r1, #0 movl r2, #0 movl r5, #0 .label loop mov r2, [r0] test r2,r2 inc r5 inc r0 jnz :loop movb r0, #4 movb r1, #1 movl r2, :helloworld mov r3, r5 syscall end .label helloworld .db "Hello World !",0x0A,0
$ ./ndasm/ndasm.py -i ./src_asm_challenge/hello_world.asm -o hello_world.ndh [*] Parsing source file ... [+] Assembling ... [*] Linking ... [*] Creating outfile ... [*] Done. 71 bytes written. $ ./vmndh -file ./hello_world.ndh Hello World ! $