本帖最后由 exixuezi 于 2016-7-20 21:48 编辑
因为要为smali做注释,要经常去查看java源代码和smali代码之间的差别,所以免不了要经常用dx、javac、dexdump、baksmali.jar等工具。所以写了一个批处理文件来做这些事情
[AppleScript] 纯文本查看 复制代码 javac -source 1.7 -target 1.7 %1
set aa=%1
set aa=%aa:java=class%
set bb=%aa:class=dex%
dx --dex --output=%bb% %aa%
java -jar baksmali.jar -o baksmaliout %bb%
cd baksmaliout
type %bb%
把这个bat文件放到.java文件同目录。可以自动生成smali文件然后type smali文件查看
[AppleScript] 纯文本查看 复制代码 .class public LHello; #定义类名Hello.super Ljava/lang/Object; #定义父类
.source "Hello.java" #源文件名,经过混淆的文件可能逆向得不到这一项
# direct methods
.method public constructor <init>()V #声明 这是不含参数的一个构造函数,构造器
.registers 1 #寄存器的个数
.prologue #单词是开场白的意思,是代码起始指令
.line 1 #行号
invoke-direct {p0}, Ljava/lang/Object;-><init>()V #构造函数的函数体
return-void
.end method
.method public static main([Ljava/lang/String;)V #这是main函数的声明,V表示返回值是void类型
.registers 5
.prologue
.line 7
new-instance v0, LHello; #新实例化Hello对象
invoke-direct {v0}, LHello;-><init>()V #调用实例的直接对象,我理解为Hello v1 = new Hello();中的new后面的部分
.line 8
sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream; #静态字段操作符,out是字段名,LJava/io/PrintStream是字段类型,这里应该是与System.out有关的
const/4 v2, 0x5 #赋值操作
const/4 v3, 0x3
invoke-virtual {v0, v2, v3}, LHello;->foo(II)I #调用虚拟函数foo(int ,int)
move-result v0 #将foo()函数返回的Int只赋给v0
invoke-virtual {v1, v0}, Ljava/io/PrintStream;->println(I)V #调用println()函数
.line 9
return-void #不返回
.end method #main方法结束
# virtual methods
.method public foo(II)I #foo()函数的声明
.registers 5
.prologue
.line 3
add-int v0, p1, p2 #p1+p2的值给v0
sub-int v1, p1, p2 #p1-p2的值给v1
mul-int/2addr v0, v1 #v0xv1的值给v0
return v0 #返回v0
.end method
通过对代码的注释,自己对字段的含义和smali的语法更加熟悉了,决定明天再来一篇,试着注释实际app反编译得到的smali文件。smali是dalvik虚拟机的语法,也是反编译的基础,需要多练习夯实对smali代码的阅读能力
注:
java "字段"的意思如下:如果说是类的话,就是类的成员变量(包括public,private,protected) 虚函数是多态性的体现 参考 https://pan.baidu.com/s/1jIwbvvw Android软件安全与逆向分析 http://pan.baidu.com/s/1c5Lj3o Android逆向手册
|