Leg*_*end 5 java android reverse-engineering dalvik disassembly
我在我写的一个小的Hello World Android应用程序上玩了smali和baksmali.我的源代码是:
package com.hello;
import android.app.Activity;
import android.os.Bundle;
public class Main extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
}
Run Code Online (Sandbox Code Playgroud)
然后被拆解为:
.class public Lcom/hello/Main;
.super Landroid/app/Activity;
.source "Main.java"
# direct methods
.method public constructor <init>()V
.locals 0
.prologue
.line 6
invoke-direct {p0}, Landroid/app/Activity;-><init>()V
return-void
.end method
# virtual methods
.method public onCreate(Landroid/os/Bundle;)V
.locals 1
.parameter "savedInstanceState"
.prologue
.line 10
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 11
const/high16 v0, 0x7f03
invoke-virtual {p0, v0}, Lcom/hello/Main;->setContentView(I)V
.line 12
return-void
.end method
Run Code Online (Sandbox Code Playgroud)
我知道这是某种中级代表,但我不确定它是什么.据我所知,必须有一些关于如何理解这种表示的规范,但我无法弄清楚如何搜索它.所以给定一个apk文件,有人可以用外行语来解释如何使用Dalvik操作码规范来达到这种表示吗?我目前的理解是这样的:
上述两个步骤中的任何信息(可能都有一些简单的例子)可以帮助我很好地理解这些概念.
更新1(Chris回复后发布):
基本上,我会做以下事情来达到Dalvik字节码:
然后反汇编程序读取classes.dex文件并确定apk中存在的所有类.你能告诉我一些如何做到的信息吗?它是以十六进制模式解析文件并查找Dalvik规范然后适当解析吗?或者是其他事情发生了?例如,当我在classes.dex上使用hexdump时,它给了我这样的东西:
64 65 78 0a 30 33 ...
这些现在用于操作码查找吗?
实际上,简而言之,我有兴趣知道所有这些"神奇"是如何完成的.例如,如果我要学习编写这个工具,那么我应该遵循的高级路线图是什么?
Chr*_*son 14
您正在查看的是davlik字节码.Java代码由dx工具转换为Dalvik字节码.清单是一个单独的问题,我将在一分钟内完成.实际上,在编译Android应用程序时,dx工具使用256 dalvik操作码将Java代码转换为字节码(与javac将Java转换为标准JVM应用程序的Java字节码的方式相同).
例如,invoke-super是一个操作码,它指示dvm(dalvik虚拟机)调用超类上的方法.同样,invoke-interface指示dvm调用接口方法.
所以你可以看到
super.onCreate(savedInstanceState);
Run Code Online (Sandbox Code Playgroud)
翻译成
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)
Run Code Online (Sandbox Code Playgroud)
在这种情况下,invoke-super需要两个参数,即{p0,p1组和Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)参数,它是用于查找的方法规范,并在必要时解析方法.
然后invoke-direct是构造函数区域中的调用.
invoke-direct {p0}, Landroid/app/Activity;-><init>()V
Run Code Online (Sandbox Code Playgroud)
每个类都有一个init方法,用于初始化类的数据成员,也称为构造函数.构造类时,虚拟机还必须调用超类的构造函数.这解释了为什么类的Activity构造函数调用构造函数.
关于清单,发生的事情(如果您查看源代码,这在Dalvik规范中都是)编译器(生成apk文件)将清单转换为更加压缩的格式(二进制xml)用于此目的节省空间.该清单没有任何与您发布的代码,它更多的指示如何处理应用程序的DVM是一个整体与问候Activities,Services等什么你张贴实际上是被执行什么.
这是对你的问题的高级答案.如果您需要更多,请告诉我,我会尽力而为.
编辑你基本上是正确的.反编译器将二进制数据作为来自dex文件的字节流读取.它了解格式应该是什么,并能够提取诸如常量,类等信息.关于操作码,这正是它的作用.它理解每个操作码的字节值(或它在dex文件中的表示方式),并能够将其转换为人类可读的字符串.如果你要实现这个,除了理解编译器的一般基础知识之外,我将首先深入理解dex文件的结构.从那里,您需要构建一个将操作码值与人类可读字符串匹配的表.有了这些信息和一些关于字符串常量等的附加信息,您可以构造编译类的文本文件表示.那有意义吗?
| 归档时间: |
|
| 查看次数: |
8901 次 |
| 最近记录: |