Android逆向:smali编码实践(一)—— 字符串拼接以及打印

 

目录

1.准备工作

2.编写smali文件

3.编译smail文件

4.检查并运行

5.遇到的问题


 

1.准备工作

1.1下载好smali的jar这里使用smali-2.4.0.jar  (PS: 执行命令为 java -jar assemble xxx.smali -o xxx.dex)

1.2 root的真机或者模拟器

1.3 安装好JaDex方便自己看看大概写出来的东西是个什么样子,用其它工具也行,不过这个很方便。

2.编写smali文件

首先编写一个简单的smali文件

.class public Lcom/test/smali/HelloWorld;
.super Ljava/lang/Object;
.source "HelloWorld.java"

#static field
.field public static final TAG:Ljava/lang/String;="MY_TAG"

.method public static main([Ljava/lang/String;)V
#局部变量数量
.locals 8
.param p0, "strs"
#开始
.prologue
#定义String变量
const-string v0, ":__TEST__"
const-string v1, "Hello World!"

#创建一个StringBuilder对象用来拼接字符串
new-instance v2, Ljava/lang/StringBuilder;

#调用StringBuilder的构造函数
invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V

#调用StringBuilder对象的append方法拼接字符串
invoke-virtual {v2,v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

#再次调用StringBuilder对象的append方法拼接字符串
invoke-virtual {v2,v1}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

#将静态域TAG的值赋值给寄存器v4
sget-object v4, Lcom/test/smali/HelloWorld;->TAG:Ljava/lang/String;

#调用StringBuilder的insert方法将TAG插入到前面
const v5,0 
invoke-virtual {v2,v5,v4}, Ljava/lang/StringBuilder;->insert(ILjava/lang/String;)Ljava/lang/StringBuilder;

#调用StringBuilder的toString方法获得拼接后的字符串
invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;

#将toString方法的结果赋值给寄存器v3
move-result-object v3

#调用安卓日志打印接口打印拼接后的字符串!(运行不了,换System.out.println)
#invoke-static{v4,v3}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

#获取System下的PrintStream类型的静态变量out并赋值给v6
sget-object v6, Ljava/lang/System;->out:Ljava/io/PrintStream;

#调用PrintStream的println方法打印字符串!
invoke-virtual {v6,v3}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V

return-void
.end method

3.编译smail文件

编译成功后smali文件同目录会出现一个同名的dex文件。

4.检查并运行

使用jadex查看dex

推送到模拟器上并运行

 

 

 

5.遇到的问题

1.

错误原因:指令错误,当时代码中调用StringBuilder的append方法时花括号后面掉了一个逗号

正确写法:invoke-virtual {v2,v0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;

2.

错误原因:指令错误,sget-object写成了sget-static

正确情况下应该是sget-object v4, Lcom/test/smali/HelloWorld;->TAG:Ljava/lang/String;

3.

错误原因:指令错误,invoke-static {v4,v3} , 逗号遗漏了

正确情况应该是invoke-static {v4,v3}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String)I

4.

错误原因:指令错误,move-result应该是接收上一个invoke返回的非字符串单字结果,StringBuilder -> toString 返回的是一个对象应该用move-result-object来接收

正确写法应该是 move-result-object v3

5.

不知道咋办,换打印的方法吧!System.out.println

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Smali 中,将字符串加密为数组的过程大概如下: 1. 将字符串转换为 char 数组。 2. 对 char 数组中的每个字符进行加密(如异或)。 3. 将加密后的 char 数组存入一个 int 数组中,每个 int 元素存储 4 个 char 元素的加密结果。 解密的过程则是相反的: 1. 读取加密后的 int 数组,并将其中的每个 int 元素还原为 4 个 char 元素的加密结果。 2. 对每个 char 元素进行解密(如异或)。 3. 将解密后的 char 数组转换为字符串。 下面是一个简单的示例代码,假设加密使用的是异或操作: ```smali # 加密字符串为数组 const-string v0, "hello world" const/4 v1, 0x2 new-array v2, v1, [C invoke-virtual {v0}, java/lang/String/toCharArray:()[C move-result-object v0 const/4 v1, 0x0 :goto_0 if-ge v1, v2.length, :cond_1 iget-object v3, v2, v1 new-array v4, v3, [I const/4 v5, 0x0 :goto_2 if-ge v5, v3, :cond_0 iget-object v6, v4, v5 iget-object v7, v0, v5 const/16 v8, 0x10 xor-int/2addr v7, v8 aput-char v7, v0, v5 int-to-char v7, v7 aput-char v7, v6, v5 add-int/lit8 v5, v5, 0x1 goto :goto_2 :cond_0 add-int/lit8 v1, v1, 0x1 goto :goto_0 :cond_1 ``` ```smali # 从数组解密字符串 iget-object v0, p0, Lcom/example/MyClass;->mIntArray:[I iget-object v1, p0, Lcom/example/MyClass;->mCharArray:[C const/4 v2, 0x0 :goto_0 if-ge v2, v0.length, :cond_1 iget-object v3, v0, v2 new-array v4, v3, [C const/4 v5, 0x0 :goto_2 if-ge v5, v3, :cond_0 iget-object v6, v4, v5 iget-object v7, v1, v5 int-to-char v7, v7 const/16 v8, 0x10 xor-int/2addr v7, v8 aput-char v7, v1, v5 aput-char v7, v6, v5 add-int/lit8 v5, v5, 0x1 goto :goto_2 :cond_0 invoke-virtual {v4}, [C/toString()Ljava/lang/String; move-result-object v4 const-string v5, "" invoke-virtual {v5, v4}, java/lang/String/concat:(Ljava/lang/String;)Ljava/lang/String; move-result-object v5 add-int/lit8 v2, v2, 0x1 goto :goto_0 :cond_1 ``` 需要注意的是,加密和解密的过程都需要通过相同的加密方法和密钥来进行。如果密钥泄露,加密就失去了意义。因此,在实际应用中,需要使用更加复杂和安全的加密方式来保护敏感信息。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值