#include #include #include #include #include #define BASE 0xe1ba3d static char size[] = { 'b', 'w', 'd' }; #define make_w(ptr) (((ptr)[1] << 8) + (ptr)[0]) #define make_dw(ptr) (((unsigned long) (ptr)[3] << 0x18) + ((unsigned long) (ptr)[2] << 0x10) + ((ptr)[1] << 8) + (ptr)[0]) void main(int argc, char *argv[]) { int f, l; unsigned char *b1, *b2; printf("Bruit - Disassembler for the Brulez VCPU, by Peter Ferrie 2004\n\n"); if ((argc != 2) || ((f = open(argv[1], O_RDONLY | O_BINARY)) == -1) ) { printf("usage: bruit \n"); return; } read(f, b1 = b2 = (unsigned char *) malloc(l = filelength(f)), filelength(f)); close(f); do { unsigned char c; printf("%08lx\t", (long) (b1 - b2) + BASE); switch (c = *b1++) { case 0: { switch (*b1++) { case 0: { printf("PUSH\t%08lx\n", make_dw(b1) ^ 0x37195411); b1 += 4; break; } case 1: { printf("PUSH\t%08lx\n", make_dw(b1) + 0xADD01337); b1 += 4; break; } case 2: { printf("PUSH\tR%d\n", *b1++ ^ 0x47); break; } case 3: { printf("POP\tR%d\n", *b1++ ^ 0x66); break; } case 4: { printf("POP\t%d\n", *b1++ ^ 0x45); break; } default: { goto bad_op; } } break; } case 1: { switch (c = *b1++) { case 0: case 2: { printf("JMP\tSPECIAL\n"); break; } case 1: { printf("EXCPT\n"); break; } case 3: { if (b1[1] > 2) { goto bad_op; } printf("XOR\t%c[R%d], R%d\n", size[b1[1]], b1[2], b1[0]); b1 += 3; break; } case 4: { printf("ADD\tR%d, %08lx\n", b1[0] - 3, make_dw(b1 + 1)); b1 += 5; break; } case 5: { printf("SUB\tR%d, %08lx\n", b1[0] - 2, make_dw(b1 + 1)); b1 += 5; break; } case 6: { printf("AND\tR%d, %08lx\n", b1[0] - 5, make_dw(b1 + 1)); b1 += 5; break; } case 7: { printf("OR\tR%d, %08lx\n", b1[0] - 4, make_dw(b1 + 1)); b1 += 5; break; } case 8: { printf("XOR\tR%d, %08lx\n", b1[0], make_dw(b1 + 1)); b1 += 5; break; } case 9: { printf("ADD\tR%d, R%d\n", b1[1] - 3, b1[2] - 1); b1 += 2; break; } case 0x0a: { printf("CMP\tR%d, R%d\n", b1[1] - 1, b1[2] - 2); b1 += 2; break; } default: { goto bad_op; } } break; } case 2: { switch (c = *b1++) { case 0: { printf("EXIT\n"); break; } case 1: { printf("CALL\t[%08lx]\n", make_dw(b1) + 0xFEA731DE); b1 += 4; break; } case 2: { printf("MOV\tR%d, %08lx\n", b1[4], make_dw(b1) + 0xAEFDED04); b1 += 5; break; } case 3: { printf("DEC\tR%d\n", *b1++); break; } case 4: { printf("INC\tR%d\n", *b1++); break; } case 5: { printf("AND\tR%d, 0\n", *b1++); break; } case 6: { printf("SCAN\t[R0], %02hx, %04hx\n", b1[0], make_w(b1 + 1)); b1 += 3; break; } case 7: { printf("BREAK"); break; } case 8: case 0x0a: case 0x0b: { printf("MOV\tR%d, %c[R%d]\n", b1[1], size[((c - 9) & 3) - 1], b1[0]); b1 += 2; break; } case 9: { printf("BSWAP\tR%d\n", *b1++); break; } default: { goto bad_op; } } break; } case 3: { switch (*b1++) { case 0: { printf("CMP\tSTK[0], STK[1]\n" "%08lx\t" "JE\t%08lx\n", (long) (b1 - b2) + BASE, make_dw(b1) - 0x31337 ); b1 += 4; break; } default: { goto bad_op; } } break; } case 4: { switch (*b1++) { case 0: { printf("JMP\t%08lx\n", make_dw(b1) + 0x0DEADEAD); b1 += 4; break; } case 1: { printf("JNE\t%08lx\n", make_dw(b1) + 1 + BASE); b1 += 4; break; } case 2: { printf("JE\t%08lx\n", make_dw(b1) + 4 + BASE); b1 += 4; break; } default: { goto bad_op; } } break; } case 5: { switch (*b1++) { case 0: { printf("CALL\t%08lx\n", make_dw(b1)); b1 += 4; break; } case 1: { printf("RET\n"); break; } default: { goto bad_op; } } break; } default: { if ((c >= 0x41) && (c <= 0x5a) ) { printf("db\t%s\n", b1 - 1); b1 += strlen(b1) + 1; } else { bad_op:; printf("unsupported opcode (%x)\n", *(b1 - 1)); } } } } while ((long) (b1 - b2) < l); printf("%08lx\tEND\n", (long) (b1 - b2) + BASE); free(b2); }