Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Help parsing resources.arsc?

I'm trying to parse the resources contained in a resources.arsc file as discussed in this question. I know the androidmanifest.xml file identifies resources located in the .arsc file. I have successfully managed to parse the header of the .arsc file, I can't figure out how to parse the resources themselves.

Can somebody please help me figure out how to parse the resources contained in an .arsc file?

My parsing code so far:

<?php

$doc = fopen('resources.arsc', 'r+');


for($i=1;$i<10;$i++){
    $res[$i] = _unpack('V', fread($doc, 4));
}


for ($i = 0, $j = $res[6]; $i <= $j; $i++)  {
    $word = fread($doc, 4);
    $stroffs[] = _unpack('V', $word);
}


$strings = array();

$curroffs = 0;
foreach($stroffs as $offs){
    //read length
    $len = _unpack('v', fread($doc, 2));

    //read string
    if($len>0){
        $str = fread($doc, $len*2);
    }else{
        $str = '';
    }
    //null
    $wd = fread($doc, 2);
    //utf-16le
    $strings[] =  mb_convert_encoding($str, 'gbk', 'UTF-16LE');

    //curr offset
    $curroffs += ($len+1)*2 + 2;
}


$tpos = ftell($doc);

read_doc_past_sentinel($doc);

//fseek($doc, $tpos + $tpos % 4);

$i = 0;

$xmls = $strings;

print_r($xmls);

//------------------------------------
//and then...somebody konw format or continue parse?
//------------------------------------


function read_doc_past_sentinel(&$doc){
    $pos = ftell($doc);
    $count= 0;
    while($word = fread($doc, 4)){
        if(_unpack('V', $word)==-1)break;
    }

    $n = 1;
    if ($count < $n){
        while($word = peek_doc($doc, 4)){
            if(_unpack('V', $word) != -1)break;
            fread($doc, 4);
            $n++;
            if(isset($count) && $count >= $n)break;
        }
        echo 'skip '.$n.' chars<br />';
    }

}

function peek_doc(&$doc, $size){
    $data = fread($doc, $size);
    fseek($doc, ftell($doc)-$size);
    return $data;
}



function _unpack($m, $b){
    //if(!$b)return '';
     $res = unpack($m, $b);
    return $res[1];
}
?>
like image 622
djunny Avatar asked Jun 16 '11 09:06

djunny


1 Answers

This is a fairly complicated binary file. You will need way more code than that to parse it. :)

My suggestion would be to use the same code that the platform does -- that is the ResTable and related classes found here:

frameworks/base/include/utils/ResourceTypes.h frameworks/base/libs/utils/ResourceTypes.cpp

Note that ResourceTypes.h also has definitions for the complete structure of the resource table (which the classes there use to parse it).

You may also just be able to use the aapt tool. This has a number of options for parsing resource-related data out of an .apk:

aapt d[ump] [--values] WHAT file.{apk} [asset [asset ...]]
  badging          Print the label and icon for the app declared in APK.
  permissions      Print the permissions from the APK.
  resources        Print the resource table from the APK.
  configurations   Print the configurations in the APK.
  xmltree          Print the compiled xmls in the given assets.
  xmlstrings       Print the strings of the given compiled xml assets.

If there is some other data you want not available with those commands, consider modifying the tool code in frameworks/base/tools/aapt to add stuff to parse out what you want. This tool is using ResTable to parse the resources.

like image 53
hackbod Avatar answered Oct 12 '22 08:10

hackbod