Skip to content

Commit cd27434

Browse files
committed
'disassemble' cmd : we can now disassemble a symbol (--sym option)
1 parent d2874e4 commit cd27434

File tree

4 files changed

+50
-9
lines changed

4 files changed

+50
-9
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ OPTIONS:
127127
--no-color, -N Do not colorize output
128128
--address, -a <a> Start disassembling at address <a>
129129
--offset, -o <o> Start disassembling at offset <o>
130+
--sym, -s <s> Disassemble symbol
130131
--len, -l <l> Disassemble only <l> bytes
131132
--arch, -A <a> Select architecture (x86, x86-64, arm, arm64)
132133
--flavor, -f <f> Change flavor (intel, att)

api/binfmt/syms.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,21 @@ static int r_binfmt_syms_cmp(const void* s1, const void* s2) {
4747
return 0;
4848
}
4949

50+
addr_t r_binfmt_get_sym_by_name(r_binfmt_s *bin, const char *name) {
51+
int i;
52+
r_binfmt_sym_s *sym;
53+
54+
i = 0;
55+
56+
while((sym = r_utils_list_access(&bin->syms, i))) {
57+
if(!strcmp(name, sym->name))
58+
return sym->addr;
59+
i++;
60+
}
61+
62+
return R_BINFMT_BAD_ADDR;
63+
}
64+
5065
/* Dichotomy research - symbols must be sorted in ascending order */
5166
const char* r_binfmt_get_sym_by_addr(r_binfmt_s *bin, addr_t addr) {
5267
size_t start, end, cur;

include/api/binfmt.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,7 +186,7 @@ r_binfmt_sym_s* r_binfmt_sym_new(void);
186186
void r_binfmt_syms_free(r_binfmt_s *bin);
187187
void r_binfmt_syms_sort(r_binfmt_s *bin);
188188
const char* r_binfmt_get_sym_by_addr(r_binfmt_s *bin, addr_t addr);
189-
189+
addr_t r_binfmt_get_sym_by_name(r_binfmt_s *bin, const char *name);
190190

191191
/* ==============================================
192192
sections.c

src/disassemble/dis.c

Lines changed: 33 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ addr_t dis_options_offset = R_BINFMT_BAD_OFFSET;
3030
u64 dis_options_len = 0;
3131
r_binfmt_arch_e dis_options_arch = R_BINFMT_TYPE_UNDEF;
3232
r_disa_flavor_e dis_options_flavor = R_DISA_FLAVOR_INTEL;
33+
const char *dis_options_sym = NULL;
3334

3435
/* Print disassemble help */
3536
void dis_help(void) {
@@ -39,6 +40,7 @@ void dis_help(void) {
3940
printf(" --no-color, -N Do not colorize output\n");
4041
printf(" --address, -a <a> Start disassembling at address <a>\n");
4142
printf(" --offset, -o <o> Start disassembling at offset <o>\n");
43+
printf(" --sym, -s <s> Disassemble symbol\n");
4244
printf(" --len, -l <l> Disassemble only <l> bytes\n");
4345
printf(" --arch, -A <a> Select architecture (x86, x86-64, arm, arm64)\n");
4446
printf(" --flavor, -f <f> Change flavor (intel, att)\n");
@@ -53,6 +55,7 @@ void dis_options_parse(int argc, char **argv) {
5355
const struct option opts[] = {
5456
{"address", required_argument, NULL, 'a'},
5557
{"arch", required_argument, NULL, 'A'},
58+
{"sym", required_argument, NULL, 's'},
5659
{"flavor", required_argument, NULL, 'f'},
5760
{"help", no_argument, NULL, 'h'},
5861
{"len", required_argument, NULL, 'l'},
@@ -61,13 +64,17 @@ void dis_options_parse(int argc, char **argv) {
6164
{NULL, 0, NULL, 0 }
6265
};
6366

64-
while((opt = getopt_long(argc, argv, "a:A:f:hl:No:", opts, NULL)) != -1) {
67+
while((opt = getopt_long(argc, argv, "a:A:s:f:hl:No:", opts, NULL)) != -1) {
6568
switch(opt) {
6669

6770
case 'a':
6871
dis_options_address = strtoull(optarg, NULL, 0);
6972
break;
7073

74+
case 's':
75+
dis_options_sym = optarg;
76+
break;
77+
7178
case 'A':
7279
dis_options_arch = r_binfmt_string_to_arch(optarg);
7380
if(dis_options_arch == R_BINFMT_ARCH_UNDEF)
@@ -106,19 +113,16 @@ void dis_options_parse(int argc, char **argv) {
106113
if(optind < argc) {
107114
dis_options_filename = argv[optind];
108115
}
109-
110-
if(dis_options_offset != R_BINFMT_BAD_OFFSET &&
111-
dis_options_address != R_BINFMT_BAD_ADDR)
112-
R_UTILS_ERR("You must specify offset or address, not twice !");
113116
}
114117

115118
/* Disassemble binary at specified address */
116-
void dis_address(r_disa_s *dis, r_binfmt_s *bin, addr_t addr, u64 len) {
119+
void dis_address(r_disa_s *dis, r_binfmt_s *bin, addr_t addr, u64 len, int stop_next_sym) {
117120
r_binfmt_mem_s *m;
118121
r_disa_instr_t *instr;
119122
const char *sym;
120123
u64 length;
121124
u64 off;
125+
int sym_processed = 0;
122126

123127
/* Test every loadable segment */
124128
for(m = bin->mlist->head; m; m = m->next) {
@@ -142,6 +146,12 @@ void dis_address(r_disa_s *dis, r_binfmt_s *bin, addr_t addr, u64 len) {
142146

143147
/* Print symbol, if it exists */
144148
if((sym = r_binfmt_get_sym_by_addr(bin, instr->address)) != NULL) {
149+
if(stop_next_sym) {
150+
if(sym_processed > 0)
151+
return;
152+
else
153+
sym_processed++;
154+
}
145155
R_UTILS_PRINT_YELLOW_BG_BLACK(dis_options_color, "\n<%s>:\n", sym);
146156
}
147157

@@ -207,6 +217,8 @@ void dis_offset(r_disa_s *dis, r_binfmt_s *bin, u64 offset, u64 len) {
207217

208218
/* Main function of disassemble command */
209219
void dis_cmd(int argc, char **argv) {
220+
int stop_next_sym = 0;
221+
addr_t sym;
210222
r_binfmt_s bin;
211223
r_disa_s dis;
212224

@@ -221,16 +233,29 @@ void dis_cmd(int argc, char **argv) {
221233
if(!r_disa_set_flavor(&dis, dis_options_flavor))
222234
R_UTILS_ERR("Can't set flavor");
223235

236+
/* Try to find symbol, if option is set */
237+
if(dis_options_sym != NULL) {
238+
if((sym = r_binfmt_get_sym_by_name(&bin, dis_options_sym)) == R_BINFMT_BAD_ADDR)
239+
R_UTILS_ERR("Symbol <%s> not found", dis_options_sym);
240+
dis_options_address = sym;
241+
stop_next_sym = 1;
242+
}
243+
244+
/* Can't disassemble offset + address at the same time */
245+
if(dis_options_offset != R_BINFMT_BAD_OFFSET &&
246+
dis_options_address != R_BINFMT_BAD_ADDR)
247+
R_UTILS_ERR("You must specify offset or address, not twice !");
248+
224249
/* First, try disassemble at offset */
225250
if(dis_options_offset != R_BINFMT_BAD_OFFSET) {
226251
dis_offset(&dis, &bin, dis_options_offset, dis_options_len);
227252
} else {
228253
/* Now check if address if specified */
229254
if(dis_options_address != R_BINFMT_BAD_ADDR) {
230-
dis_address(&dis, &bin, dis_options_address, dis_options_len);
255+
dis_address(&dis, &bin, dis_options_address, dis_options_len, stop_next_sym);
231256
/* If not, try to disassemble starting at entry point */
232257
} else if(bin.entry != 0) {
233-
dis_address(&dis, &bin, bin.entry, dis_options_len);
258+
dis_address(&dis, &bin, bin.entry, dis_options_len, stop_next_sym);
234259
/* Entry point is bad...Start at beginning of the file */
235260
} else {
236261
dis_offset(&dis, &bin, 0, dis_options_len);

0 commit comments

Comments
 (0)