androguard解析指令及字节码

androguard解析指令及字节码

解析字节码是常用到的一个需求,被解析出来的字节码可以用于多种用途,例如数值分析、机器学习等。

所谓的字节码:在 Java 语言中中引入了虚拟机的概念,即在机器和编译程序之间加入了一层抽象的虚拟的机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在 Java 中,这种供虚拟机理解的代码叫做字节码(即扩展名为 .class 的文件),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。Java 源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行。这也就是解释了 Java 的编译与解释并存的特点。

采用字节码的好处:Java 语言通过字节码的方式,在一定程度上解决了传统解释型语言执行效率低的问题,同时又保留了解释型语言可移植的特点。所以 Java 程序运行时比较高效,而且,由于字节码并不专对一种特定的机器,因此,Java程序无须重新编译便可在多种不同的计算机上运行。

每种方法的字节码都存储在 Dalvik 文件中。Androguard 可以提供三种不同形式获取字节码的方法。

字节码是以16位为单位构造的,但是Androguard将使用8位单位来显示字节码。 如果在字节码中给出了偏移量,则也以字节表示。同样的所有索引均以字节长度提供。

由于Dalvik与Java密切相关,因此所有整数值都表示为带符号的“ int”(32位值)或“ long”(64位)。
值以十进制或十六进制表示。如果值为十六进制,则该值后缀为“ h”,即“ f7a0h”或“ 63392”。

Getting the raw bytecode

要想获取方法的字节码的原始字节表示,第一步仍然是先要加载要测试的 APK 文件

ubuntu@ubuntu:~$ androguard analyze /home/ubuntu/Desktop/meeting.apk 
Please be patient, this might take a while.
Found the provided file is of type 'APK'
[INFO    ] androguard.apk: Starting analysis on AndroidManifest.xml
[INFO    ] androguard.apk: APK file was successfully validated!
[INFO    ] androguard.analysis: Adding DEX file version 35
[INFO    ] androguard.analysis: Reading bytecode took : 0min 00s
[INFO    ] androguard.analysis: Adding DEX file version 35
[INFO    ] androguard.analysis: Reading bytecode took : 0min 00s
[INFO    ] androguard.analysis: End of creating cross references (XREF) run time: 0min 00s
Added file to session: SHA256::689673bed0f4d6121a63f3c9fd88efb538ec316561d426120c440d8be89f6256
Loaded APK file...
>>> a
<androguard.core.bytecodes.apk.APK object at 0x7f3b27bb8390>
>>> d
[<androguard.core.bytecodes.dvm.DalvikVMFormat object at 0x7f3b1ae9d978>, <androguard.core.bytecodes.dvm.DalvikVMFormat object at 0x7f3b1ae36b00>]
>>> dx
<analysis.Analysis VMs: 2, Classes: 85, Methods: 340, Strings: 122>

Androguard version 3.4.0a1 started

然后通过 python 编程获取所有方法的字节表示:

In [1]: for method in dx.get_methods():
   ...:     if method.is_external():
   ...:         continue
   ...:     m = method.get_method()
   ...:     if m.get_code():
   ...:         print(m.get_code().get_bc().get_raw())

其输出结果中将包含很多的二进制数据,如下:

bytearray(b'p\x10\t\x00\x00\x00\x0e\x00')
bytearray(b'p\x10\t\x00\x00\x00\x0e\x00')
bytearray(b'p\x10\xf3\x00\x00\x00\x0e\x00')
bytearray(b'\x12\x01i\x01E\x00\x1a\x00C\x01i\x00C\x00\x1a\x00\xa1\x02i\x00F\x00i\x01D\x00\x0e\x00')
bytearray(b'p\x10\x00\x00\x00\x00\x0e\x00')
bytearray(b'\x1d\x02b\x00C\x00\x1a\x01\x08\x00n \x03\x01\x10\x00\n\x008\x00\x1e\x00"\x00G\x00o\x10\x03\x00\x02\x00\x0c\x01q\x10\x06\x01\x01\x00\x0c\x01p \t\x01\x10\x00b\x01C\x00n \x0f\x01\x10\x00\x0c\x00n\x10\x11\x01\x00\x00\x0c\x00i\x00C\x00\x12\x10\x1e\x02\x0f\x00b\x00C\x00\x1a\x01\x08\x00n \xfe\x00\x10\x00\n\x00;\x00\xf5\xff"\x00G\x00o\x10\x03\x00\x02\x00\x0c\x01q\x10\x06\x01\x01\x00\x0c\x01p \t\x01\x10\x00\x1a\x01\x08\x00n \x0f\x01\x10\x00\x0c\x00b\x01C\x00n \x0f\x01\x10\x00\x0c\x00n\x10\x11\x01\x00\x00\x0c\x00i\x00C\x00(\xd4\r\x00\x1e\x02\'\x00')

Getting disassembled instructions

编写代码获取反汇编形式

In [2]: for method in dx.get_methods():
   ...:      if method.is_external():
   ...:          continue
   ...:      m = method.get_method()
   ...:      for idx, ins in m.get_instructions_idx():
   ...:          print(idx, ins.get_op_value(), ins.get_name(), ins.get_output())
   ...: 

输出为

0 112 invoke-direct v0, Ljava/lang
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值