越狱 发表于 2015-11-20 12:12:38

Android resources.arsc资源文件防护原理分析

主要防止apktool反编译resources.acrs资源文件,从而对资源文件进行保护
resources.acrs资源文件格式主要引用老罗的博客内容
Resources.arsc文件格式是由一系列的chunk构成,每一个chunk均包含如下结构的ResChunk_header,用来描述这个chunk的基本信息。
struct ResChunk_header
{
   enum
   {
         RES_NULL_TYPE               = 0x0000,
         RES_STRING_POOL_TYPE      = 0x0001,
         RES_TABLE_TYPE            = 0x0002,
         RES_XML_TYPE                = 0x0003,
         RES_XML_FIRST_CHUNK_TYPE    = 0x0100,
         RES_XML_START_NAMESPACE_TYPE= 0x0100,
         RES_XML_END_NAMESPACE_TYPE= 0x0101,
         RES_XML_START_ELEMENT_TYPE= 0x0102,
         RES_XML_END_ELEMENT_TYPE    = 0x0103,
         RES_XML_CDATA_TYPE          = 0x0104,
         RES_XML_LAST_CHUNK_TYPE   = 0x017f,
         RES_XML_RESOURCE_MAP_TYPE   = 0x0180,
         RES_TABLE_PACKAGE_TYPE      = 0x0200,
         RES_TABLE_TYPE_TYPE         = 0x0201,
         RES_TABLE_TYPE_SPEC_TYPE    = 0x0202
   };
   //当前这个chunk的类型
   uint16_t type;
   //当前这个chunk的头部大小
   uint16_t headerSize;
   //当前这个chunk的大小
   uint32_t size;
};

我们先看反编译错误信息,后面再说如何实现
apktool错误日志:
Exception in thread "main" brut.androlib.err.UndefinedResObject: resource spec: 0x7f000005
at brut.androlib.res.data.ResPackage.getResSpec(ResPackage.java:59)
at brut.androlib.res.data.ResTable.getResSpec(ResTable.java:65)
at brut.androlib.res.data.ResTable.getResSpec(ResTable.java:61)
at brut.androlib.res.data.value.ResReferenceValue.getReferent(ResReferenceValue.java:57)
at brut.androlib.res.data.value.ResReferenceValue.encodeAsResXml(ResReferenceValue.java:47)
at brut.androlib.res.data.value.ResScalarValue.encodeAsResXmlValue(ResScalarValue.java:58)
at brut.androlib.res.data.value.ResScalarValue.serializeToResValuesXml(ResScalarValue.java:75)
at brut.androlib.res.AndrolibResources.generateValuesFile(AndrolibResources.java:502)
at brut.androlib.res.AndrolibResources.decode(AndrolibResources.java:252)
at brut.androlib.Androlib.decodeResourcesFull(Androlib.java:136)
at brut.androlib.ApkDecoder.decode(ApkDecoder.java:102)
at brut.apktool.Main.cmdDecode(Main.java:165)
at brut.apktool.Main.main(Main.java:81)

错误提示是resource spec: 0x7f000005,下面就来看看使用aapt d resources test.apk 查看资源信息
appt d resources的基本格式如下:
resource <Resource ID> <Package Name>:<Type>/<Name>: t=<DataType> d=<Data> (s=<Size> r=<Res0>)
Resource ID R.java中的资源ID
Package Name 资源所在的的包
Type 资源的类型
Name 资源名称
DataType 数据类型,按照以下枚举类型取值
Data 资源的值,根据dataType进行解释
Size 一直为0x0008
Res0 固定为0x00

aapt d resources test.apk
Package Groups (1)
Package Group 0 id=0x7f packageCount=1 name=com.example.myapp
Package 0 id=0x7f name=com.example.myapp
    type 1 configCount=4 entryCount=1
      spec resource 0x7f020000 com.example.myapp:drawable/ic_launcher: flags=0x00000100
      config ldpi-v4:
      resource 0x7f020000 com.example.myapp:drawable/ic_launcher: t=0x03 d=0x00000001 (s=0x0008 r=0x00)
      config mdpi-v4:
      resource 0x7f020000 com.example.myapp:drawable/ic_launcher: t=0x03 d=0x00000002 (s=0x0008 r=0x00)
      config hdpi-v4:
      resource 0x7f020000 com.example.myapp:drawable/ic_launcher: t=0x03 d=0x00000003 (s=0x0008 r=0x00)
      config xhdpi-v4:
      resource 0x7f020000 com.example.myapp:drawable/ic_launcher: t=0x03 d=0x00000004 (s=0x0008 r=0x00)
    type 2 configCount=1 entryCount=1
      spec resource 0x7f030000 com.example.myapp:layout/main: flags=0x00000000
      config (default):
      resource 0x7f030000 com.example.myapp:layout/main: t=0x03 d=0x00000000 (s=0x0008 r=0x00)
    type 3 configCount=1 entryCount=1
      spec resource 0x7f040000 com.example.myapp:string/app_name: flags=0x00000000
      config (default):
      resource 0x7f040000 com.example.myapp:string/app_name: t=0x02 d=0x00000005 (s=0x0008 r=0x00)

我随便弄了一个com.example.myapp进行测试,通过上面信息可以看到app_name: t=0x02 已经改变,也就是DataType 数据类型。
直接使用010 Editor或其他HEX工具打开resources.arsc搜索对应的d=0x00000005(十六进制搜索需要反过来)
直接搜索HEX值:05000000然后将前面对应的08 00 00 02改成08 00 00 03然后保存打包,再反编译测试
经过测试drawable或string对应的DataType 数据类型值t=0x03修改为0x01或0x02都可以导致apktool反编译失败

听鬼哥说故事 发表于 2015-11-20 12:15:57

沙发,给力的越狱兄台,赞一个~

默小坑 发表于 2015-11-20 12:26:26

给力。。。

花墨 发表于 2015-11-20 19:05:08

似乎可以用上了,感谢一下{:4_87:}

strings 发表于 2015-11-20 21:19:27

膜拜大牛

sndncel 发表于 2015-11-21 05:27:12

支持一下呀。。。。。谢谢分享

mmzxc120 发表于 2015-11-24 20:27:08

楼主啊,我编译一个APK 出现这个情况,是不是跟你说的一样,他们修改了resources.arsc


>Exception in thread "main" java.lang.reflect.InvocationTargetException
>        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
>        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
>        at java.lang.reflect.Method.invoke(Method.java:483)
>        at b.a.d.b.a.a(Unknown Source)
>        at b.a.d.b.a.b(Unknown Source)
>        at b.a.d.b.a.a(Unknown Source)
>        at b.a.d.a.a(Unknown Source)
>        at b.a.d.a.a(Unknown Source)
>        at b.a.d.a.a(Unknown Source)
>        at b.a.a.a(Unknown Source)
>        at b.a.E.b(Unknown Source)
>        at b.a.E.a(Unknown Source)
>        at b.b.a.a(Unknown Source)
>        at b.b.a.a(Unknown Source)
>        at com.rover12421.shaka.cli.Main.main(Unknown Source)
>Caused by: b.a.D: Invalid chunk type: expected=0x00000002, got=0x00000000
>        at b.a.d.b.a.b(Unknown Source)
>        at b.a.d.b.a.nextChunkCheckType(Unknown Source)
>        ... 16 more
APK 反编译失败,无法继续下一步源码反编译!

andrewhzf 发表于 2015-11-30 08:14:50

越狱老大,怎样用010 editor修改16进制呢,我第一次用,发现不能改成自己想要的数值啊,比如08 00 00 03改成08 00 00 01

冰冻冷咖啡 发表于 2015-12-6 00:29:54

andrewhzf 发表于 2015-11-30 08:14
越狱老大,怎样用010 editor修改16进制呢,我第一次用,发现不能改成自己想要的数值啊,比如08 00 00 03改 ...

可以试下hex workshop http://tools.pediy.com/windows/editors.htm

jzbb99 发表于 2015-12-6 20:10:16

如果apktool可以反编译,但是关键算法部分的代码无法生成smali。怎么办?
页: [1] 2
查看完整版本: Android resources.arsc资源文件防护原理分析