![]() |
|
||||||||||||||
| | 首页 | 新闻 | 文库 | 方案 | 技术 | 独家 | 座谈 | 下载 | 图库 | 开发板 | 仿真器 | 邮购 | VIP | 芯片 | 客户评价 | 论坛 | | ||
|
||
|
|||||
| objdump代码分析 | |||||
作者:快乐虾 文章来源:http://blog.csdn.net/lights_joy 点击数: 更新时间:2008-11-12 ![]() |
|||||
|
Objdump可以用于实现二进制文件的信息读取,其对二进制文件的读取依赖于bfd库,显示的代码实际并不长。 1.1 主程序:mainstatic char *default_target = NULL; /* Default at runtime. */ int main (int argc, char **argv) { int c; char *target = default_target; bfd_boolean seenflag = FALSE; ……………………… // bfd库初始化 bfd_init (); set_default_bfd_target (); …………………….. // 参数提取 while ((c = getopt_long (argc, argv, "pib:m:M:VvCdDlfFaHhrRtTxsSI:j:wE:zgeGW", long_options, (int *) 0)) != EOF) { ……………………………………… } // 判断参数是否合法 ………………………………. // 显示 if (formats_info) exit_status = display_info (); else { if (optind == argc) display_file ("a.out", target); else for (; optind < argc;) display_file (argv[optind++], target); } // 结束工作 END_PROGRESS (program_name); return exit_status; } 整个过程并不复杂,实际工作交由display_file这个函数来完成。 唯一需要注意的是这里将default_target设置为NULL,这样bfd库将读取二进制文件的头信息,查找最适合处理此类文件的target。如果不设置为NULL,bfd库将只使用指定的target进行处理,如果指定了与文件实际类型不符合的名称,bfd将无法进行下一步的工作。 1.2 显示所有文件:display_filestatic void display_file (char *filename, char *target) { bfd *file; bfd *arfile = NULL; if (get_file_size (filename) < 1) { exit_status = 1; return; } // 打开指定文件,由于target为NULL,BFD将指定一个默认的target,并标记为使用默认的target处理。 // 返回一个bfd指针,所有文件操作都由它完成。 file = bfd_openr (filename, target); if (file == NULL) { nonfatal (filename); return; } /* If the file is an archive, process all of its elements. */ if (bfd_check_format (file, bfd_archive)) { bfd *last_arfile = NULL; printf (_("In archive %s:\n"), bfd_get_filename (file)); for (;;) { bfd_set_error (bfd_error_no_error); arfile = bfd_openr_next_archived_file (file, arfile); if (arfile == NULL) { if (bfd_get_error () != bfd_error_no_more_archived_files) nonfatal (bfd_get_filename (file)); break; } display_bfd (arfile); if (last_arfile != NULL) bfd_close (last_arfile); last_arfile = arfile; } if (last_arfile != NULL) bfd_close (last_arfile); } else display_bfd (file); bfd_close (file); } 这段代码先判断是否是静态库文件,如果是则将此静态库文件中的每一个子文件显示出来。由于静态库文件仅仅是将一些单个的目标文件集合在一起(如.o,.obj之类的),它并没有改变这些.o或者.obj文件的格式,因此最后使用同一个函数display_bfd进行单个文件的显示。 1.3 单个文件显示:display_bfdstatic void display_bfd (bfd *abfd) { char **matching; if (bfd_check_format_matches (abfd, bfd_object, &matching)) { dump_bfd (abfd); return; } // 以下进行错误分析与处理 ……………………………. } 转向dump_bfd函数执行。 /* Dump selected contents of ABFD. */ static void dump_bfd (bfd *abfd) { /* If we are adjusting section VMA's, change them all now. Changing the BFD information is a hack. However, we must do it, or bfd_find_nearest_line will not do the right thing. */ if (adjust_section_vma != 0) { bfd_boolean has_reloc = (abfd->flags & HAS_RELOC); bfd_map_over_sections (abfd, adjust_addresses, &has_reloc); } if (! dump_debugging_tags) printf (_("\n%s: file format %s\n"), bfd_get_filename (abfd), abfd->xvec->name); if (dump_ar_hdrs) print_arelt_descr (stdout, abfd, TRUE); if (dump_file_header) dump_bfd_header (abfd); …………………………………. } 根据指定的参数一项项地显示内容,比如dump_bfd_header就是这样的: 纏ar static void dump_bfd_header (bfd *abfd) { char *comma = ""; printf (_("architecture: %s, "), bfd_printable_arch_mach (bfd_get_arch (abfd), bfd_get_mach (abfd))); printf (_("flags 0x%08x:\n"), abfd->flags); #define PF(x, y) if (abfd->flags & x) {printf("%s%s", comma, y); comma=", ";} PF (HAS_RELOC, "HAS_RELOC"); PF (EXEC_P, "EXEC_P"); PF (HAS_LINENO, "HAS_LINENO"); PF (HAS_DEBUG, "HAS_DEBUG"); PF (HAS_SYMS, "HAS_SYMS"); PF (HAS_LOCALS, "HAS_LOCALS"); PF (DYNAMIC, "DYNAMIC"); PF (WP_TEXT, "WP_TEXT"); PF (D_PAGED, "D_PAGED"); PF (BFD_IS_RELAXABLE, "BFD_IS_RELAXABLE"); PF (HAS_LOAD_PAGE, "HAS_LOAD_PAGE"); printf (_("\nstart address 0x")); bfd_printf_vma (abfd, abfd->start_address); printf ("\n"); } 整个主程序的逻辑挺简单的,除了判断是否为静态库文件之外都是顺序执行。 |
|||||
| 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 本站介绍 | 合作联络 | 欢迎投稿 | 广告业务 | 网站地图 | 设为首页 | 加入收藏 | 友情链接 | 网站公告 | 联系我们 | | |||
|