├── .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 |
--------------------------------------------------------------------------------