This script not only disassemble u-boot.bin, but also regenerate a elf that could be used for GDB.
./disassemble.pl <offset> <binary_file>
./disassemble.pl 0xc0000000 u-boot.bin
GPL:disassemble.pl - CHDK Wiki
http://chdk.wikia.com/wiki/GPL:disassemble.pl#
#!/usr/bin/perl # disassemble alien binary blobs # look for "ldr .., [pc + #nn]" etc. # and add strings and values it refers to # # (c) 2008 chr # GPL V3+ # # v0.2.1: # * create labels for branch targets # v0.2: # * catch unaligned strings # * note on strings # * check for integer overflow # use Data::Dumper; # $Data::Dumper::Sortkeys = 1; # Added to support execution of disassembler.pl # when not in the same folder as binary file to # be disassembled. use Cwd; $firmware_basepath = getcwd; # adjust these for your needs (note final slash): #$path = "$ENV{'HOME'}/gcc-4.1-arm/bin/"; $path = ""; # note on "strings": default is a minimum length of 4 chars. # So if u are hunting for e.g. "FI2" add -n3 # However, it gives a lot of false positive. $strdump = "strings -t x"; $objdump = "${path}arm-elf-objdump"; $objcopy = "${path}arm-elf-objcopy"; if (@ARGV != 2) { die("Usage: $0 0x); } $offset = $ARGV[0]; $binfile = $ARGV[1]; $firmware_file_path = "$firmware_basepath/$ARGV[1]"; # check if we wrap over die "error stat($firmware_file_path): $!" unless ($flen = (stat($firmware_file_path))[7]); if ( hex($offset) + $flen - 1 > 0xffffffff) { die "offset + filesize - 1 > 0xffffffff. We can't wrap around!\n\ngame over" } ##### print "string dump\n"; my %strings; open(IN, "$strdump \"$firmware_file_path\" |") or die "cannot start $strdump \"$firmware_file_path\": $!"; open(OUT,">$firmware_file_path.strings") or die "cannot write to $firmware_file_path.strings: $!"; while ( " ) { /^ *([[:xdigit:]]*) (.*)/; my $addr = hex($1) + hex($offset); my $addr_str = sprintf("%08x", $addr); $strings{$addr_str} = $2; print OUT "$addr_str $2\n"; # align string address so unaligned strings appears in disassemble $addr_str = sprintf("%08x", $addr & ~0x3); my $offs = $addr & 0x3; $strings{$addr_str} = '.' x $offs . $2; } close IN; close OUT; #$strings{'ff810164'} = "TEST test"; #$strings{'ff810420'} = "add test"; #print Dumper(\%strings); #exit; ##### print "create elf file\n"; `$objcopy --change-addresses=$offset -I binary -O elf32-littlearm -B arm \"$firmware_file_path\" \"$firmware_file_path.elf\"`; `$objcopy --set-section-flags .data=code,load,alloc,content \"$firmware_file_path.elf\"`; ##### print "label scan\n"; my %labels; open(IN, "$objdump -d \"$firmware_file_path.elf\" |") or die "cannot start $objdump \"$firmware_file_path\": $!"; open(OUT,">$firmware_file_path.labels") or die "cannot write to $firmware_file_path.labels: $!"; while ( ) { if (my ($addr, $dest) = $_ =~ /^ *([[:xdigit:]]+):[ \t]+[[:xdigit:]]+[ \t]+[Bb][[:alpha:]]*[ \t]+([[:xdigit:]]+)/) { if ($labels{$dest} lt 1) { print OUT "$dest ($addr)\n"; } $labels{$dest} += 1; print "\r0x$addr "; } } close IN; close OUT; ##### print "\ndisassemble and string lookup\n"; open(IN, "$objdump -d \"$firmware_file_path.elf\" |") or die "cannot start $objdump \"$firmware_file_path\": $!"; open(OUT,">$firmware_file_path.dis") or die "cannot write to $firmware_file_path.dis: $!"; open(BIN, "<$firmware_file_path") or die "cannot read $firmware_file_path"; binmode BIN; while ( ) { if ($_ eq " ...\n") { print OUT $_; next;} my ($addr, $line) = $_ =~ /^ *([[:xdigit:]]*):(.*)/ or next; # ff810b98: e51f2060 ldr r2, [pc, #-96] ; ff810b40 <_binary_dump_bin_start xb40=""> # ff815dd4: e28f10dc add r1, pc, #220 ; 0xdc if ( ($line =~ /^(.*\tldr.*\[pc, #([-\d]+).*; )/) || ($line =~ /^(.*\tadd.*pc, #([-\d]+).*; )/) ) { $line = $1; my $off = hex($addr) - hex($offset) + $2 + 8; my $point = sprintf("%08x", hex($addr) + $2 + 8); my $value = &get_word($off); $line .= "$point: ($value) "; if (my $str = $strings{$point}) { # add pointed string $line .= qq| *"$str"|; } elsif (my $str = $strings{$value}) { # pointer to pointer ... $line .= qq| **"$str"|; } } # ff815e1c: e24f0090 sub r0, pc, #144 ; 0x90 elsif ($line =~ /^(.*\tsub.*pc, #([-\d]+).*; )/) { $line = $1; my $off = hex($addr) - hex($offset) - $2 + 8; my $point = sprintf("%08x", hex($addr) - $2 + 8); my $value = &get_word($off); $line .= "$point: ($value) "; if (my $str = $strings{$point}) { $line .= qq| *"$str"|; } elsif (my $str = $strings{$value}) { $line .= qq| **"$str"|; } } # ff81015c: 3afffffc bcc ff810154 <_binary__blah ...=""> elsif ($line =~ /^([ \t]*[[:xdigit:]]+[ \t]+[Bb][[:alpha:]]*[ \t]+)([[:xdigit:]]+)/) { $line = "$1loc_$2" } # insert label if ($labels{$addr} gt 1) { print OUT "loc_$addr: ; $labels{$addr} refs\n"; } elsif ($labels{$addr} gt 0) { print OUT "loc_$addr:\n"; } # add string comment if (my $str = $strings{$addr}) { print OUT qq|"$str":\n|; } print OUT "$addr: $line\n"; print "\r0x$addr "; } close IN; close OUT; ##### print "\njob complete!\n"; sub get_word { my $off = shift; my $ret; seek(BIN, $off, 0); my $c = read(BIN, $ret, 4);# or die "off: $off $! ($ret)"; return ($c > 0 ? sprintf("%08x", unpack("I", $ret)) : '???'); }
With the following changes:
diff --git a/disassemble.pl b/disassemble.pl index fea0761..1a85518 100644 --- a/disassemble.pl +++ b/disassemble.pl @@ -27,12 +27,16 @@ $firmware_basepath = getcwd; #$path = "$ENV{'HOME'}/gcc-4.1-arm/bin/"; $path = ""; +#$cross = "arm-elf-"; +$cross = "mips64-octeon-linux-gnu-"; # note on "strings": default is a minimum length of 4 chars. # So if u are hunting for e.g. "FI2" add -n3 # However, it gives a lot of false positive. $strdump = "strings -t x"; -$objdump = "${path}arm-elf-objdump"; -$objcopy = "${path}arm-elf-objcopy"; +$objdump = "${path}${cross}objdump"; +$objcopy = "${path}${cross}objcopy"; +#$objcopy_param = " -I binary -O elf32-littlearm -B arm "; +$objcopy_param = "-I binary -O elf32-ntradbigmips -B mips:octeon2 "; if (@ARGV != 2) { die("Usage: $0 0x"); @@ -79,7 +83,7 @@ close OUT; ##### print "create elf file\n"; -`$objcopy --change-addresses=$offset -I binary -O elf32-littlearm -B arm \"$firmware_file_path\" \"$firmware_file_path.elf\"`; +`$objcopy --change-addresses=$offset ${objcopy_param} \"$firmware_file_path\" \"$firmware_file_path.elf\"`; `$objcopy --set-section-flags .data=code,load,alloc,content \"$firmware_file_path.elf\"`; #####
Linux下如何反汇编arm raw binary文件 - ZhengKarl的专栏 - 博客频道 - CSDN.NET
http://blog.csdn.net/zhengkarl/article/details/5663042
GPL Disassembling - CHDK Wiki
http://chdk.wikia.com/wiki/GPL_Disassembling
linux下的arm反汇编-CPU与编译器-ChinaUnix.net
http://bbs.chinaunix.net/thread-1948607-1-1.html
The following works:
mips64-octeon-linux-gnu-objdump u-boot.bin -b binary -D -m mips:octeon2 -M reg-names=n32,reg-names=octeon2 -EB | head
u-boot.bin: file format binary
Disassembly of section .data:
0000000000000000 <.data>:
0: 1000013f b 0x500
4: 00000000 nop
8: 424f4f54 c0 0x4f4f54
Emulating Digicam with QEMU - page 4 - General Discussion and Assistance - CHDK Forum
http://chdk.setepontos.com/index.php/topic,1918.msg20065.html#msg20065
Emulating Digicam with QEMU - page 5 - General Discussion and Assistance - CHDK Forum
http://chdk.setepontos.com/index.php?topic=1918.msg28546#msg28546
disassemble_with_stubs_funcs-v1.0.zip
http://chdk.setepontos.com/index.php?action=dlattach;topic=1918.0;attach=2786
沒有留言:
張貼留言