#!/usr/bin/perl # # Copyright (c) 2009, 2011 Slade Maurer, Alexander Sviridenko. All rights reserved. # (see the pod text in Binutils::Objdump module for use and distribution rights) # our $VERSION = '0.1.2'; use Getopt::Long; use Binutils::Objdump qw(:ALL); GetOptions( 'h|help' => \&print_usage, 'V|version' => \&print_version, ); $input = shift @ARGV || 'a.out'; if (!-e $input || !-f $input) { die "$input cannot be found. Exit.\n"; } objdumpopt("-dTx --prefix-addresses"); objdump($input); # Reading strings ... foreach (objdump_section_headers()) { if (/.rodata/) { ($rubbish, $rest) = split /.rodata/, $_, 2; ($rubbish, $rest) = split /0/, $rest, 2; @numbers = split / /, $rest, 5; $size = hex($numbers[0]); $starting_address = hex($numbers[1]); $end_address = $starting_address + $size; $offset = hex($numbers[3]); open INPUT, '<', $input; seek INPUT, $offset, 0; read INPUT, $cadena, $size; close INPUT; } } # Processing symbol table ... foreach (objdump_symtab()) { last if /^\n/; @st_element = split(/ /, $_); $_ = $st_element[$#st_element]; # chop; $st_element[0] =~ s/^[0]+([1-9])/$1/; $symbol_table{$st_element[0]} = $_; } # Analysis ... foreach (objdump_sec_disasm('.text')) { s/0x//g; s/<.*?>//g; s/ / /g; if (/j/) { ($direccion,$inst,$destino) = split / /, $_, 3; $destino = ~s/ //g; chomp $destino; $salto{$destino} .= ($direccion." \; "); } elsif (/call/) { ($direccion, $inst, $destino) = split / /, $_, 3; $destino =~ s/ //g; chomp $destino; $call{$destino} .= ($direccion." \; "); } } # Writting references ... $char="."; $counter=0; $i=0; foreach (objdump_sec_disasm('.text')) { $counter++; $copia = $_; s/0x//g; s/\<.*?\>//ge; s/ / /g; ($direccion, $inst, $destino) = split / /, $_, 3; $destino =~ s/^[0]+([1-9])/$1/; $direccion =~ s/^[0]+([1-9])/$1/; if (defined $symbol_table{$direccion}) { print "\nFunction : ".$symbol_table{$direccion}; print "\n\n"; } if (/call/) { $destino =~ s/ //g; chomp $destino; if (defined $symbol_table{$destino}) { print "\n Reference to function : ".$symbol_table{$destino}."\n\n"; } } if (defined $salto{$direccion}) { print "\n Referenced from jump at ".$salto{$direccion}."\n\n"; } if (defined($call{$direccion})) { print "\n Referenced from call at ".$call{$direccion}."\n\n"; } if (/\$/){ ($instruccion, $operand) = split /\$/, $_, 2; if (!/push/) { ($operand, undef) = split /\,/, $operand, 2; } chomp $operand; $offset = hex $operand; if (($offset <= $end_address) && ($offset >= $starting_address)) { $auxiliar = substr($cadena, $offset-$starting_address); $length = index($auxiliar, pack("x")); $auxiliar=substr($auxiliar, 0, $length); $auxiliar =~ s/\n//g; print "\n Possible reference to string :\n"; print "\"$auxiliar\"\n\n" } if ($symbol_table{$operand}) { print "\n Appeared : ". $symbol_table{$operand} ."\n\n"; } } print "$copia\n"; } exit(0); sub print_usage { print "odasm $VERSION\n"; print "Usage: odasm [OPTION]... exe_file\n\n"; print " -V, --version display the version of odasm and exit.\n"; print " -h, --help print this help.\n"; exit(0); } sub print_version { print "odasm $VERSION\n"; print "Binutils::Objdump $Binutils::Objdump::VERSION\n\n"; print "Copyright (c) 2009, 2011 Slade Maurer, Alexander Sviridenko. All rights reserved.\n"; print "(see the pod text in Binutils::Objdump module for use and distribution rights)\n"; exit(0); } __END__ =head1 NAME odasm - A disassembler written on Perl and based on Bintuils::Objdump module =head1 SYNOPSIS odasm [OPTIONS] exe_file odasm -V odasm -h =head1 DESCRIPTION This disassembler based on linux disassembler 2.0799 by SiuL+Hacky, and written with help of L module. This script allows to show you: appeared functions and symbols, possible references to strings, references from Cs and Cs. =head1 AUTHORS Alexander Sviridenko Slade Maurer =head1 COPYRIGHT Copyright (c) 2009, 2011 Slade Maurer, Alexander Sviridenko. All rights reserved. (see the pod text in L module for use and distribution rights) =head1 SEE ALSO Binutils::Objdump(1) =cut