smali入门之迭代器循环:列出进程名字

首先在Eclipse中新建一个工程,默认是HelloWorld。将bin目录下的helloworld.apk拷贝出来,然后使用命令解包:

apktool d hello.apk

参考《Android软件安全与逆向分析》,其中的代码是写在一个函数中的,这里我边写边重构了一下,拆分成两个函数:

.class public Lcom/alipay/helloworld/MainActivity;
.super Landroid/app/Activity;
.source "MainActivity.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 protected onCreate(Landroid/os/Bundle;)V
    .locals 3
    .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/alipay/helloworld/MainActivity;->setContentView(I)V
    

    #invoke-virtual {p0}, Lcom/alipay/helloworld/MainActivity;->getRunningListString()Ljava/lang/String;  
    #move-result-object v1

    new-instance v1, Ljava/lang/StringBuilder;
    invoke-direct {v1}, Ljava/lang/StringBuilder;-><init>()V

    const-string v2, "hello,android reverse!"
    .local v2, msg:Ljava/lang/String;

    invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    invoke-virtual {v1} , Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    move-result-object v1
    invoke-virtual {p0, v1}, Lcom/alipay/helloworld/MainActivity;->showToastMessage(Ljava/lang/String;)V

    invoke-virtual {p0}, Lcom/alipay/helloworld/MainActivity;->getRunningListString()Ljava/lang/String;
    move-result-object v1
    invoke-virtual {p0, v1}, Lcom/alipay/helloworld/MainActivity;->showToastMessage(Ljava/lang/String;)V

    .line 12
    return-void
.end method


.method public showToastMessage(Ljava/lang/String;)V
    .locals 1
    const/4 v0, 0x01
    invoke-static {p0, p1, v0}, Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
    move-result-object v0
    invoke-virtual {v0}, Landroid/widget/Toast;->show()V
    return-void
.end method



.method public getRunningListString()Ljava/lang/String;  
    .locals 6

    # get the object of ActivityManager
    const-string v0, "activity"
    invoke-virtual {p0, v0}, Landroid/app/Activity;->getSystemService(Ljava/lang/String;)Ljava/lang/Object;
    move-result-object v1
    check-cast v1, Landroid/app/ActivityManager;
    .local v1, activityManager:Landroid/app/ActivityManager;

    # inistantiate a string buffer to save string
    new-instance v0, Ljava/lang/StringBuilder;
    invoke-direct {v0}, Ljava/lang/StringBuilder;-><init>()V
    .local v0, results:Ljava/lang/StringBuilder;

    # retrive the running app list
    invoke-virtual {v1}, Landroid/app/ActivityManager;->getRunningAppProcesses()Ljava/util/List;
    move-result-object v5
    .local v5, psInfos:Ljava/util/List;, "Ljava/util/List<Landroid/app/ActivityManager$RunningAppProcessInfo;>;"

    # travel the process list to get all the name of the running process
    invoke-interface {v5}, Ljava/util/List;->iterator()Ljava/util/Iterator;
    move-result-object v2

    :goto_list_not_empty
    invoke-interface {v2}, Ljava/util/Iterator;->hasNext()Z
    move-result v3
    if-eqz v3, :goto_end
    
    invoke-interface {v2}, Ljava/util/Iterator;->next()Ljava/lang/Object;
    move-result-object v3 
    check-cast v3, Landroid/app/ActivityManager$RunningAppProcessInfo;
    .local v3,  info:Landroid/app/ActivityManager$RunningAppProcessInfo;

    iget-object v4, v3, Landroid/app/ActivityManager$RunningAppProcessInfo;->processName:Ljava/lang/String;
    invoke-static {v4}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String;
    move-result-object v4
    
    invoke-virtual {v0, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

    const-string v4, "\n"
    invoke-virtual {v0, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
    goto : goto_list_not_empty
    
    :goto_end
    invoke-virtual {v0}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
    move-result-object v0
    return-object v0
.end method

重新打包并签名:

apktool b HelloWorld.apk hello.apk

在编写程序的时候两处地方出现了错误:

1. .locals指令用来设置当前函数使用的非参数寄存器个数,当时代码中使用了3个寄存器,结果我设置了.locals 2,于是程序在运行的时候抛出了java.lang.VerifyError异常。

2. 要区分invoke-interface、invoke-virtual、invoke-direct之间的区别。在使用的时候,好像invoke-direct就用来调用一下构造函数就可以,其余成员函数用invoke-virtual来调用,而对于一个接口类型,才使用invoke-interface.

下面是运行效果:








评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值