android安全静态分析,[分享]发几个Android静态和动态分析的小技巧

没有好的调试工具下

对dex后的smali的技巧

f62cf84a0211c50e5ca23fc87c3f0403.gif

一、常用插代码(如果怕影响寄存器值,可以将.locals xxx改多几个或者合适的地方,如返回前添加)

1、

const-string v7, "log.v(xx, yy);"

invoke-static {v7, v7}, Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I

2、

const-string v0, "Must ensure vx is Context class, then Toast.makeText(vx, xxx, 1).show();" # CharSequence对象类型

const/4 v1, 0x1 # I int类型

invoke-static {p0, v0, v1}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast; # p0 是一个Context

move-result-object v0

invoke-virtual {v0}, Landroid/widget/Toast;->show()V

二.调用回溯

1、静态方法搜索需要扩展到父类的方法搜索,如Sublime Text 3下结果

.class public Lcom/dataviz/dxtg/common/android/launcher/TabbedLauncherActivity;

.super Lcom/dataviz/dxtg/common/android/ApplicationActivity;

# interfaces

.implements Landroid/view/GestureDetector$OnGestureListener;

.implements Lcom/dataviz/dxtg/common/android/ar;

.implements Lcom/dataviz/dxtg/common/android/bt;

.implements Lcom/dataviz/dxtg/common/android/cs;

.implements Lcom/dataviz/dxtg/common/android/dv;

.implements Lcom/dataviz/dxtg/common/android/iap/d;

.implements Lcom/dataviz/dxtg/common/android/iap/z;

.method public c()V

.end method

搜索方法

Lcom/dataviz/dxtg/common/android/launcher/TabbedLauncherActivity;->c()V

也许搜索没有结果,就有可能是父类或 接口。

这里是Lcom/dataviz/dxtg/common/android/dv;->c()V

.class public interface abstract Lcom/dataviz/dxtg/common/android/dv;

.super Ljava/lang/Object;

# virtual methods

.method public abstract a(Ljava/lang/String;)V

.end method

.method public abstract a(Z)V

.end method

.method public abstract c()V

.end method

结果

Searching 7287 files for "Lcom/dataviz/dxtg/common/android/dv;->c()V"

D:\com.dataviz.docstogo\smali\com\dataviz\dxtg\common\android\do.smali:

91:     invoke-interface {v0}, Lcom/dataviz/dxtg/common/android/dv;->c()V

289:     invoke-interface {v0}, Lcom/dataviz/dxtg/common/android/dv;->c()V

2 matches in 1 file

然后看看调用这个方法的所在方法有没有判断跳转语句,如果没有可能还要继续查看谁调用。

2. 动态/运行时查看

制造异常查看函数调用堆栈

在查看方法调用时,制造空指针异常。回溯方法调用堆栈

.method public c()V

.locals 1 ## .locals 1 romove desktop tab

const/4 v0, 0x0

#new-instance v0, Lcom/dataviz/dxtg/common/android/bl;

#invoke-direct {v0}, Lcom/dataviz/dxtg/common/android/bl;->()V

invoke-direct {p0, v0}, Lcom/dataviz/dxtg/common/android/launcher/TabbedLauncherActivity;->a(Landroid/support/v4/app/Fragment;)Z

return-void

.end method

堆栈截图

attachment.php?attachmentid=89928

三、smali修改代码出错举例1

1. 入参类型

当smali修改代码出错举例1,log如下:

虚拟机层次:

1.本身做出了预测,寄存器v2是符合要求入参,暗示你这个也许是你想要的。VFY: register1 v2 type 17, wanted ref

2.下一句:报参数1不对,应该是String类型。 VFY: bad arg 1 (into Ljava/lang/String;)

3.第三行,拒绝调用初始化。VFY:  rejecting call to Ljava/lang/StringBuilder;. (Ljava/lang/String;)V

4. 拒绝调用代码和偏移量。VFY:  rejecting opcode 0x70 at 0x031f

5. 函数调用堆栈。VFY:  rejected Lcom/dataviz/dxtg/common/android/AboutScreenActivity;.onCreate (Landroid/os/Bundle;)V

6.出错类,全路径。Verifier rejected class Lcom/dataviz/dxtg/common/android/AboutScreenActivity;

7.出错详细描述。Class init failed in newInstance call (Lcom/dataviz/dxtg/common/android/AboutScreenActivity;)

Android运行时日志:

略。

attachment.php?attachmentid=89927

2. 字段赋值const-string/jumbo v0, "4.001"

const v1, 666666

# # VFY: invalid reg type 1073801336 on iput instr (need 12)

# # VFY: rejecting opcode 0x59 at 0x001d

# # 0x59 表示 iput vx,vy, field_id, 0x001d应该是 方法里偏移量,两字节一个偏移量

iput v0, v4, Lxx/yy/clazz;->field:I

偏移量可正可负,它从指令开始字节计算的。偏移量按字(2字节1个偏移),从中可以看出偏移量大小。

原文:

The offset can be positive or negative and it is calculated from the offset of the starting byte of the instruction. The offset is always interpreted in words (2 bytes per 1 offset value increment/decrement). Negative offset is stored in two's complement format. The current position is the offset of the starting byte of the instruction.

四、代码混乱的替换

举例:

Lcom/dataviz/dxtg/common/d/j;单个类域替换,包括成员;

Lcom/dataviz/dxtg/common/d/j/此对应文件夹及其子文件夹下所有类都替换,最后斜杠。

可以保存脚本,替换回来。

用于向处理http的线程,比如,假设Lcom/dataviz/dxtg/common/d/j是线程Thread或Runnable的儿子、孙子或重孙子...类,可以替换为Lcom/dataviz/dxtg/common/d/HttpThread_j等有意义的类名。

b4bbc3bd7e6229e69e24e6a27755afd8.png

保存脚本内容可能这样:

Lcom/dataviz/dxtg/common/d/j/

Lcom/dataviz/dxtg/common/d/HttpThread_j

*

D:\d

貌似这里已经有了:

https://code.google.com/p/dex2jar/wiki/DeObfuscateJarWithDexTool

主要就是:

要点

混淆代码处理有现成的东西:DeObfuscateJarWithDexTool

1、自动收集建议的配置文件,也许像这样

#generate a 'suggest' config for rename

d2j-init-deobf -f -o init.txt a.jar

-o 输出配置文件,这里为init.txt

-f 如果存在重写文件

a.jar 待修改的文件

2、替换的命令也许这样:

d2j-jar-remap -f -c init.txt -o a-deobf.jar a.jar

-c 替换的配置文件

-o 输出文件

-f 如果存在重写文件

a.jar 待修改的文件

3、配置文件格式:

## file UTF-8

# format : ? x=y

#?为大写貌似是静态吗,因为在public class InitOut里方法private void doMethod(String owner, ClassInfo.MemberInfo member, int x)有句sb.append(AccUtils.isStatic(member.access) ? "M" : "m");

#重命名包a为pa

p a=pa

#重命名类a为C000_a

c a/a=C000_a

#重命名方法名a为Ma

m a/a.a()=Ma

#重命名字段名a为Fa

f a/a.a=Fa

## file UTF-8

## format : pqx=y

##

## p is as follow:

## a comment line config starts with '#';

## a field or method line config starts with 'F', 'M', 'f',or 'm';

## a class line config starts with 'C',or 'c';

## a package line config starts with 'P',or 'p';

## a @ line config starts with '@';

##

## q ?, but a space is ok

如果打不开,下面是拷贝过来的。

Introduction

dex-tool-0.0.9.8 add support to DeObfuscate a jar

Details

The Problem

for a Obfuscated jar like this

package a;

public class a

{

static String a = "Hello";

static void a() {

System.out.println(a);

}

public static void main(String[] args) {

a();

}

}

all package,class,field,method names are 'a', which is difficult to read.

DeObfuscate It

run the following command

#generate a 'suggest' config for rename

d2j-init-deobf -f -o init.txt a.jar

we got a init.txt

p a=pa

c a/a=C000_a

m a/a.a()=Ma

m a/a.a=Fa

which means

#rename package a to pa

p a=pa

#rename class a to C000_a

c a/a=C000_a

#rename method a to Ma

m a/a.a()=Ma

#rename field a to Fa

m a/a.a=Fa

modify init.txt to

#rename package a to hello

p a=hello

#rename class a to World

c a/a=World

#rename method a to say

m a/a.a()=say

#rename field a to message

m a/a.a=message

and run

d2j-jar-remap -f -c init.txt -o a-deobf.jar a.jar

now we get the comfortable source

package hello;

import java.io.PrintStream;

public class World

{

static String message = "Hello";

static void say() {

System.out.println(message);

}

public static void main(String[] args) {

say();

}

}

or run the program with

java -cp a-deobf.jar hello.World

1bcdffa0c60416e48695c13261c177f1.png

529d35bf4ca98f6ada164e0df09d5d9a.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值