Determening datatypes
Benjamin Larsson <[email protected]> Sat, 14 Aug 2004 12:53:34 +0200
| Newsgroups | gmane.comp.video.xine.codec.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi, I've written a perl program that can extract tables out of binarys. Try theise examples to get hold of what it can do: ./tableextractor.pl -f ~/RealPlayer7/Codecs/dspr.so.6.0 test uchar 10 ./tableextractor.pl -f ~/RealPlayer7/Codecs/dspr.so.6.0 dico1_isf test 10 ./tableextractor.pl -f ~/RealPlayer7/Codecs/dspr.so.6.0 dico1_isf uchar 10 Now to the question, how do you get the correct datatype for a table ? Is there some smart way to get that information or do you check the assembly how it accesses and manipulates the data ? MvH Benjamin Larsson
tableextractor.pl
(application/x-perl, 3.1 KB)
#!/usr/bin/perl
# Init av variabler
sub callsource;
sub padding;
#Argument parser
if (@ARGV){
# print "@ARGV\n";
if ($ARGV[0] eq "-f"){
$FILE1 = $ARGV[1];
$tablename = $ARGV[2];
$vartype = $ARGV[3];
chomp($vartype);
$cols = $ARGV[4];
}
}
else{
print "Usage:\n";
print "./tableextractor.pl [command] binary function vartype cols\n";
print "-f input datafile\n";
exit;
}
#Check what type the table is supposed to be
@vartypelist = ("ascii","char","uchar","short","ushort","int","uint","long","ulong","netshort","netlong","float","dfloat","hex","nethex");
@unpacklist = ("A","c","C","s","S","i","I","l","L","n","N","f","d","h","H");
$typenr = 100;
for ($nptr=0;$nptr < $#vartypelist +1;$nptr++){
if ($vartype eq $vartypelist[$nptr]) {
$typenr = $nptr;
}
}
if ($typenr == 100) {
print "Vartype is not of correct type. Try one of theise:\n";
foreach $rad (@vartypelist) {
print "$rad\n";
}
exit;
}
# File IO
# get DYNAMIC SYMBOL TABLE
@fresource = `objdump -T $FILE1`;
$dsym = 0;
@tabaddress = 0;
@tabname = 0;
@tablength = 0;
$tabindex = 1;
#parse out the tables
foreach $rad (@fresource) {
if ($dsym){
$type = (substr $rad,17,5);
if ($type eq ".data") {
$address = (substr $rad,0,8);
$address =~ m/0*/; #get rid of starting 0's
$address = $';
$tablelength = (substr $rad,23,8);
$tablelength =~ m/0*/;
$tablelength = $';
$tablen = (substr $rad,32);
chomp($tablen);
#save the list
$tabaddress[$tabindex] = hex($address);
$tabname[$tabindex] = $tablen;
$tablength[$tabindex] = hex($tablelength);
$tabindex++;
#print "$address $type $tablelength $tablename\n";
}
}
if ($rad =~ m/DYNAMIC/) {
$dsym = 1;
}
}
$nameptr = 0;
$nptr = 0;
for ($nptr=1;$nptr < $#tabname +1;$nptr++){
if ($tabname[$nptr] eq $tablename) {
$nameptr = $nptr;
}
}
if ($nameptr == 0) {
print "Table does not exist or is misspelled. Try one of theise:\n";
for ($nptr=1;$nptr < $#tabname +1;$nptr++){
print "$tabname[$nptr]\n";
}
exit;
}
#Get .data offset
$doffset = 0;
@offsets = `readelf -S $FILE1`;
foreach $rad (@offsets) {
if ($rad=~ m/ \.data/) {
$dataaddress = (substr $rad,41,8);
$dataaddress =~ m/0*/;
$dataaddress = $';
$dataoffset = (substr $rad,50,6);
$dataoffset =~ m/0*/;
$dataoffset = $';
#print "$dataaddress $dataoffset|\n";
$doffset = hex($dataaddress) - hex($dataoffset);
}
}
#Calculate real address for table
$seekaddress = $tabaddress[$nameptr] - $doffset;
#Time to access the file for data
open(BINFILE, $FILE1) or die "can't open $FILE1: $!";
seek(BINFILE, $seekaddress, 0) or die "seek:$!";
#seek(BINFILE,hex(c61),0) or die "seek:$!";
read(BINFILE, $BUFFER, $tablength[$nameptr]);
@fields = unpack("$unpacklist[$typenr]*",$BUFFER);
#Print out everything in a nice form
$colcounter = 0;
$tablesi = $#fields+1;
print "/**\n";
print " * Table $tablename taken from file $FILE1.\n";
print " */\n\n";
print "static const $vartypelist[$typenr] $tablename\[$tablesi\] = {\n";
foreach $rad (@fields) {
if ($colcounter == $cols) {
print "\n";
$colcounter = 0;
}
print "$rad,";
$colcounter ++;
}
print "\n};\n";
close(BINFILE);