├── .gitignore ├── .gitmodules ├── Makefile ├── README.md ├── src ├── Makefile └── main.c ├── testfiles ├── helloworld_arm.asm ├── helloworld_arm_be.bin ├── helloworld_arm_le.bin ├── helloworld_mips.asm ├── helloworld_mips_be.bin ├── helloworld_mips_le.bin ├── helloworld_ppc.asm ├── helloworld_ppc_be.bin ├── helloworld_ppc_le.bin ├── helloworld_x86.asm ├── helloworld_x86.bin ├── helloworld_x86_64.asm └── helloworld_x86_64.bin └── xdisasm /.gitignore: -------------------------------------------------------------------------------- 1 | # C 2 | *.so 3 | *.o 4 | 5 | # Build 6 | build 7 | 8 | # Notes 9 | notes 10 | 11 | # gdb 12 | .gdb_history 13 | 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "src/libxdisasm"] 2 | path = src/libxdisasm 3 | url = https://github.com/acama/libxdisasm.git 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | default: xdis 2 | 3 | xdis: 4 | mkdir -p build/lib 5 | cd src && $(MAKE) 6 | 7 | clean: 8 | cd src && $(MAKE) clean 9 | rm -rf build 10 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | xdisasm 2 | ======= 3 | 4 | xdisasm is a simple binary file disassembler based on libopcodes and bfd from binutils. It uses the [libxdisasm](http://github.com/acama/libxdisasm) library which currently supports x86, x86_64, arm, ppc and mips. The idea is to try and mimic the output given by the [ndisasm](http://www.nasm.us/doc/nasmdoca.html) program which unfortunately only supports x86/x86_64. 5 | 6 | Build Instructions: 7 | ------------------- 8 | ``` 9 | git clone --recursive https://github.com/acama/xdisasm.git 10 | make 11 | ``` 12 | 13 | Examples: 14 | --------- 15 | ``` 16 | ./xdisasm -m arm testfiles/helloworld_arm_le.bin 17 | 18 | 00000000 E28F1014 add r1, pc, #20 19 | 00000004 E3A00001 mov r0, #1 20 | 00000008 E3A0200C mov r2, #12 21 | 0000000C E3A07004 mov r7, #4 22 | 00000010 EF000000 svc 0x00000000 23 | 00000014 E3A07001 mov r7, #1 24 | 00000018 EF000000 svc 0x00000000 25 | 0000001C 6C6C6548 cfstr64vs mvdx6, [ip], #-288 ; 0xfffffee0 26 | 00000020 6F57206F svcvs 0x0057206f 27 | 00000024 0A646C72 beq 0x191b1f4 28 | ``` 29 | ``` 30 | ./xdisasm -m arm testfiles/helloworld_arm_be.bin -lb 31 | 32 | 00000000 E28F1014 add r1, pc, #20 33 | 00000004 E3A00001 mov r0, #1 34 | 00000008 E3A0200C mov r2, #12 35 | 0000000C E3A07004 mov r7, #4 36 | 00000010 EF000000 svc 0x00000000 37 | 00000014 E3A07001 mov r7, #1 38 | 00000018 EF000000 svc 0x00000000 39 | 0000001C 48656C6C stmdami r5!, {r2, r3, r5, r6, sl, fp, sp, lr}^ 40 | 00000020 6F20576F svcvs 0x0020576f 41 | 00000024 726C640A rsbvc r6, ip, #167772160 ; 0xa000000 42 | ``` 43 | ``` 44 | ./xdisasm -m x86 -b64 testfiles/helloworld_x86_64.bin 45 | 46 | 00000000 488D3518000000 lea rsi,[rip+0x18] # 0x1f 47 | 00000007 B801000000 mov eax,0x1 48 | 0000000C BF01000000 mov edi,0x1 49 | 00000011 BA0C000000 mov edx,0xc 50 | 00000016 0F05 syscall 51 | 00000018 B83C000000 mov eax,0x3c 52 | 0000001D 0F05 syscall 53 | 0000001F 48 rex.W 54 | 00000020 65 gs 55 | 00000021 6C ins BYTE PTR es:[rdi],dx 56 | 00000022 6C ins BYTE PTR es:[rdi],dx 57 | 00000023 6F outs dx,DWORD PTR ds:[rsi] 58 | 00000024 20576F and BYTE PTR [rdi+0x6f],dl 59 | 00000027 726C jb 0x95 60 | 00000029 64 fs 61 | 0000002A 0A .byte 0xa 62 | ``` 63 | ``` 64 | ./xdisasm -m powerpc testfiles/helloworld_ppc_le.bin 65 | 66 | 00000000 48000020 b 0x20 67 | 00000004 38600001 li r3,1 68 | 00000008 38A0000C li r5,12 69 | 0000000C 7C8802A6 mflr r4 70 | 00000010 38000004 li r0,4 71 | 00000014 44000002 sc 72 | 00000018 38000001 li r0,1 73 | 0000001C 44000002 sc 74 | 00000020 4BFFFFE5 bl 0x4 75 | 00000024 6C6C6548 xoris r12,r3,25928 76 | 00000028 6F57206F xoris r23,r26,8303 77 | 0000002C 0A646C72 tdi 19,r4,27762 78 | ``` 79 | -------------------------------------------------------------------------------- /src/Makefile: -------------------------------------------------------------------------------- 1 | CC=gcc 2 | APP=../build/xdisasmbin 3 | CFLAGS= -Wall 4 | LDFLAGS= -lopcodes -Llibxdisasm/build/lib/ -lxdisasm -lbfd -liberty -lz -ldl 5 | 6 | 7 | default: all 8 | 9 | all: makelib xdisasm 10 | 11 | makelib: 12 | cd libxdisasm && $(MAKE) 13 | cp libxdisasm/build/lib/libxdisasm.so ../build/lib/libxdisasm.so 14 | 15 | xdisasm: main.o 16 | $(CC) $(CFLAGS) main.o -o ${APP} $(LDFLAGS) 17 | 18 | clean: 19 | rm -rf *.o ${APP} 20 | rm -rf libxdisasm 21 | -------------------------------------------------------------------------------- /src/main.c: -------------------------------------------------------------------------------- 1 | /* 2 | main.c -- Main file 3 | Copyright (C) 2014 Amat I. Cama 4 | 5 | This file is part of xdisasm. 6 | 7 | Xdisasm is free software: you can redistribute it and/or modify 8 | it under the terms of the GNU General Public License as published by 9 | the Free Software Foundation, either version 3 of the License, or 10 | (at your option) any later version. 11 | 12 | Xdisasm is distributed in the hope that it will be useful, 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | GNU General Public License for more details. 16 | 17 | You should have received a copy of the GNU General Public License 18 | along with this program. If not, see . 19 | 20 | */ 21 | 22 | 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include "libxdisasm/include/xdisasm.h" 30 | 31 | #define VERSION "1.0" 32 | #define XNAME "xdisasm" 33 | 34 | // Print version 35 | void print_version(){ 36 | printf("%s %s \n", XNAME, VERSION); 37 | exit(0); 38 | } 39 | 40 | // Print usage 41 | void print_usage(){ 42 | printf("Usage: xdisasm -m arch [-b bits] [-e bytes] [-l endian] [-a relocaddr] [-v] [-h] inputfile\n"); 43 | printf("\t -b (16 | 32 | 64) sets the processor mode\n"); 44 | printf("\t -m (arm | mips | powerpc | x86) sets the architecture\n"); 45 | printf("\t -v displays the version number\n"); 46 | printf("\t -l (b | e) big or little endian\n"); 47 | printf("\t -e skips of header\n"); 48 | printf("\t -a rellocate at given address\n"); 49 | printf("\t -h prints this menu\n"); 50 | exit(0); 51 | } 52 | 53 | int main(int argc, char **argv){ 54 | FILE * fp = NULL; 55 | int opt, endian = 0; 56 | int fb = 0, fv = 0, fh = 0, bits = 0, arch = 0, fl = 0; 57 | insn_list * ilist = NULL; 58 | char * bval = NULL; 59 | char * mval = NULL; 60 | char * eval = NULL; 61 | char * aval = NULL; 62 | char * infile = NULL; 63 | char * data = NULL; 64 | size_t datalen = 0; 65 | size_t hdrlen = 0; 66 | unsigned long long vma = 0; 67 | char endianchar = 0; 68 | 69 | while((opt = getopt(argc, argv, "b:m:e:a:vhl:")) != -1){ 70 | switch(opt){ 71 | case 'b': 72 | fb = 1; 73 | bval = optarg; 74 | break; 75 | case 'm': 76 | mval = optarg; 77 | break; 78 | case 'e': 79 | eval = optarg; 80 | break; 81 | case 'v': 82 | fv = 1; 83 | break; 84 | case 'h': 85 | fh = 1; 86 | break; 87 | case 'l': 88 | fl = 1; 89 | endianchar = optarg[0]; 90 | break; 91 | case 'a': 92 | aval = optarg; 93 | break; 94 | default: 95 | case '?': 96 | print_usage(); 97 | } 98 | } 99 | 100 | if(fv){ 101 | print_version(); 102 | } 103 | 104 | if(fh){ 105 | print_usage(); 106 | } 107 | 108 | if (argv[optind] == NULL) { 109 | print_usage(); 110 | } 111 | 112 | infile = argv[optind]; 113 | 114 | if(aval){ 115 | vma = strtoull(aval, NULL, 0); 116 | if(vma == LONG_MAX || vma == LONG_MIN || vma == 0){ 117 | perror("strtol"); 118 | exit(-1); 119 | } 120 | } 121 | 122 | if(fb){ 123 | bits = strtol(bval, NULL, 10); 124 | if(bits != 16 && bits != 32 && bits != 64){ 125 | print_usage(); 126 | } 127 | } 128 | 129 | if(fl){ 130 | if(endianchar == 'b') endian = 1; 131 | else if(endianchar == 'e') endian = 0; 132 | else print_usage(); 133 | } 134 | 135 | if(mval){ 136 | if(!strcmp(mval, "arm")){ 137 | arch = ARCH_arm; 138 | } 139 | else if(!strcmp(mval, "powerpc")){ 140 | arch = ARCH_powerpc; 141 | } 142 | else if(!strcmp(mval, "x86")){ 143 | arch = ARCH_x86; 144 | } 145 | else if(!strcmp(mval, "mips")){ 146 | arch = ARCH_mips; 147 | } 148 | else{ 149 | print_usage(); 150 | } 151 | }else{ 152 | print_usage(); 153 | } 154 | 155 | if(eval){ 156 | hdrlen = strtol(eval, NULL, 10); 157 | if(hdrlen == LONG_MAX || hdrlen == LONG_MIN || hdrlen == 0){ 158 | perror("strtol"); 159 | exit(-1); 160 | } 161 | } 162 | 163 | fp = fopen (infile, "rb"); 164 | 165 | if (fp){ 166 | fseek (fp, hdrlen, SEEK_END); 167 | datalen = ftell (fp); // TODO: maybe check if vma + datalen will overflow address range 168 | if(datalen < 0){ 169 | perror("ftell"); 170 | exit(-1); 171 | } 172 | if(datalen == 0){ 173 | printf("%s: file %s is empty", argv[0], infile); 174 | } 175 | fseek (fp, hdrlen, SEEK_SET); 176 | data = malloc (datalen); 177 | if (data) 178 | { 179 | fread (data, 1, datalen, fp); 180 | }else{ 181 | perror("malloc"); 182 | exit(-1); 183 | } 184 | fclose (fp); 185 | }else{ 186 | perror("fopen"); 187 | exit(-1); 188 | } 189 | 190 | ilist = disassemble(vma, data, datalen, arch, bits, endian); 191 | if(!ilist) return -1; 192 | print_all_instrs(&ilist); 193 | 194 | /* 195 | insn_t * i = disassemble_one(vma, data, datalen, arch, bits, endian); 196 | print_instr(i); 197 | free_instr(i); 198 | */ 199 | 200 | free_all_instrs(&ilist); 201 | free(data); 202 | return 0; 203 | } 204 | -------------------------------------------------------------------------------- /testfiles/helloworld_arm.asm: -------------------------------------------------------------------------------- 1 | .text 2 | .global _start 3 | 4 | _start: 5 | adr r1, hello 6 | mov r0, #1 7 | mov r2, #12 8 | mov r7, #4 9 | svc 0x0 10 | mov r7, #1 11 | svc 0x0 12 | hello: 13 | .ascii "Hello World\n" 14 | -------------------------------------------------------------------------------- /testfiles/helloworld_arm_be.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acama/xdisasm/ea9824313c686ae4c3f1ae23d9e8252aa7ef51d6/testfiles/helloworld_arm_be.bin -------------------------------------------------------------------------------- /testfiles/helloworld_arm_le.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acama/xdisasm/ea9824313c686ae4c3f1ae23d9e8252aa7ef51d6/testfiles/helloworld_arm_le.bin -------------------------------------------------------------------------------- /testfiles/helloworld_mips.asm: -------------------------------------------------------------------------------- 1 | .text 2 | .global __start 3 | 4 | __start: 5 | nop 6 | nop 7 | nop 8 | nop 9 | nop 10 | nop 11 | begin: 12 | j hello 13 | write: 14 | li $a1, 1 15 | move $a1, $ra 16 | li $a2, 12 17 | li $v0, 4004 18 | syscall 19 | li $v0, 4001 20 | syscall 21 | 22 | hello: 23 | jal write 24 | .ascii "Hello World\n" 25 | -------------------------------------------------------------------------------- /testfiles/helloworld_mips_be.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acama/xdisasm/ea9824313c686ae4c3f1ae23d9e8252aa7ef51d6/testfiles/helloworld_mips_be.bin -------------------------------------------------------------------------------- /testfiles/helloworld_mips_le.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acama/xdisasm/ea9824313c686ae4c3f1ae23d9e8252aa7ef51d6/testfiles/helloworld_mips_le.bin -------------------------------------------------------------------------------- /testfiles/helloworld_ppc.asm: -------------------------------------------------------------------------------- 1 | .text 2 | .global _start 3 | 4 | _start: 5 | b hello 6 | 7 | write: 8 | li r3, 1 9 | li r5, 12 10 | mflr r4 11 | li r0, 4 12 | sc 13 | li r0, 1 14 | sc 15 | hello: 16 | bl write 17 | .ascii "Hello World\n" 18 | -------------------------------------------------------------------------------- /testfiles/helloworld_ppc_be.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acama/xdisasm/ea9824313c686ae4c3f1ae23d9e8252aa7ef51d6/testfiles/helloworld_ppc_be.bin -------------------------------------------------------------------------------- /testfiles/helloworld_ppc_le.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acama/xdisasm/ea9824313c686ae4c3f1ae23d9e8252aa7ef51d6/testfiles/helloworld_ppc_le.bin -------------------------------------------------------------------------------- /testfiles/helloworld_x86.asm: -------------------------------------------------------------------------------- 1 | USE32 2 | section .text 3 | global _start 4 | 5 | _start: 6 | jmp hello 7 | write: 8 | pop ecx 9 | mov ebx, 1 10 | mov edx, 12 11 | mov eax, 4 12 | int 80h 13 | mov eax, 1 14 | int 80h 15 | 16 | hello: 17 | call write 18 | db "Hello World",0xa 19 | -------------------------------------------------------------------------------- /testfiles/helloworld_x86.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acama/xdisasm/ea9824313c686ae4c3f1ae23d9e8252aa7ef51d6/testfiles/helloworld_x86.bin -------------------------------------------------------------------------------- /testfiles/helloworld_x86_64.asm: -------------------------------------------------------------------------------- 1 | USE64 2 | DEFAULT REL 3 | 4 | section .text 5 | global _start 6 | 7 | _start: 8 | lea rsi, [hello] 9 | mov rax, 1 10 | mov rdi, 1 11 | mov rdx, 12 12 | syscall 13 | mov rax, 60 14 | syscall 15 | 16 | hello: 17 | db "Hello World",0xa 18 | -------------------------------------------------------------------------------- /testfiles/helloworld_x86_64.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/acama/xdisasm/ea9824313c686ae4c3f1ae23d9e8252aa7ef51d6/testfiles/helloworld_x86_64.bin -------------------------------------------------------------------------------- /xdisasm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | LD_LIBRARY_PATH=build/lib/ build/xdisasmbin "$@" 4 | --------------------------------------------------------------------------------