第一节 简单的一个扫盲
玩过win PE破解的,都知道一个逆向破解,去查看汇编语言,然后插入自己的代码,保持堆栈平衡,修改逻辑代码,然后保存,完成破解过程。安卓里面的这个汇编语言就是smali,修改它来改变原本程序逻辑的过程,称之为插桩。比起win PE 的难度,smali的插桩比较简单,因为我们修改的是系统架构的jar apk文件,这些文件是不能混淆的,因为三方的是需要这些,因此相对于混淆的apk来说,明文太多,对
·
玩过win PE破解的,都知道一个逆向破解,去查看汇编语言,然后插入自己的代码,保持堆栈平衡,修改逻辑代码,然后保存,完成破解过程。安卓里面的这个汇编语言就是smali,修改它来改变原本程序逻辑的过程,称之为
插桩。比起win PE 的难度,smali的插桩比较简单,因为我们修改的是系统架构的jar apk文件,这些文件是不能混淆的,因为三方的是需要这些,因此相对于混淆的apk来说,明文太多,对于修改帮助意义比较大。
首先我们eclipse 创建一个demo apk,运行看下效果。我这里用的是我写的一个程序,这段代码为:package com.example.test;
import com.lxm.tools.myToast;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// myToast.makeText(this, "我们的\n世界患有传奇东西,什么鬼灯火辉煌火候不到誰說你好呢 ", Toast.LENGTH_LONG).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
我们的目标就是要在这个代码里面,新增一个注释的那行代码。
注释的那段代码反编译为:
.line 16
const-string v0, "\u6211\u4eec\u7684\n\u4e16\u754c\u60a3\u6709\u4f20\u5947\u4e1c\u897f\uff0c\u4ec0\u4e48\u9b3c\u706f\u706b\u8f89\u714c\u706b\u5019\u4e0d\u5230\u8ab0\u8aaa\u4f60\u597d\u5462 "
const/4 v1, 0x1
invoke-static {p0, v0, v1}, Lcom/lxm/tools/myToast;->makeText(Landroid/content/Context;Ljava/lang/String;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
我们原本代码为:
只放了关键代码
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 1
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
.line 14
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 15
const/high16 v0, 0x7f030000
invoke-virtual {p0, v0}, Lcom/example/test/MainActivity;->setContentView(I)V
.line 17
return-void
.end method
我们的目的便是在invoke-virtual {p0, v0}, Lcom/example/test/MainActivity;->setContentView(I)V后面增加一个TOast语句。
按照我们之前想的,应该直接追加即可。
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 1
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
.line 14
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 15
const/high16 v0, 0x7f030000
invoke-virtual {p0, v0}, Lcom/example/test/MainActivity;->setContentView(I)V
const-string v0, "\u6211\u4eec\u7684\n\u4e16\u754c\u60a3\u6709\u4f20\u5947\u4e1c\u897f\uff0c\u4ec0\u4e48\u9b3c\u706f\u706b\u8f89\u714c\u706b\u5019\u4e0d\u5230\u8ab0\u8aaa\u4f60\u597d\u5462 "
const/4 v1, 0x1
invoke-static {p0, v0, v1}, Lcom/lxm/tools/myToast;->makeText(Landroid/content/Context;Ljava/lang/String;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
.line 17
return-void
.end method
行数我们去掉,不需要这个代码。
我们反编译回去,发现启动不起来,这里就是我们要讲的一个关键点,局部变量问题。
我们看下.locals 1 说明只有一个局部变量,但是我们新增代码里面,有一个v0, v1,说明我们新增了一个局部变量,但是我们在方法前面只说了一个,所以出错,这里我们再将.locals 1
改为.locals 2 即可。
简单的一个教程。
我们再来看一个条件代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int a=30;
if(a>1)
{
myToast.makeText(this, "我们的\n世界患有传奇东西,什么鬼灯火辉煌火候不到誰說你好呢 ", Toast.LENGTH_LONG).show();
}
else
{
}
// myToast.makeText(this, "我们的\n世界患有传奇东西,什么鬼灯火辉煌火候不到誰說你好呢 ", Toast.LENGTH_LONG).show();
}
反编译为:
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 3
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
const/4 v2, 0x1
.line 14
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 15
const/high16 v1, 0x7f030000
invoke-virtual {p0, v1}, Lcom/example/test/MainActivity;->setContentView(I)V
.line 16
const/16 v0, 0x1e
.line 17
.local v0, "a":I
if-le v0, v2, :cond_0
.line 19
const-string v1, "\u6211\u4eec\u7684\n\u4e16\u754c\u60a3\u6709\u4f20\u5947\u4e1c\u897f\uff0c\u4ec0\u4e48\u9b3c\u706f\u706b\u8f89\u714c\u706b\u5019\u4e0d\u5230\u8ab0\u8aaa\u4f60\u597d\u5462 "
invoke-static {p0, v1, v2}, Lcom/lxm/tools/myToast;->makeText(Landroid/content/Context;Ljava/lang/String;I)Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V
.line 26
:cond_0
return-void
.end method
我们这里把条件语句换到else里面去。
.local v0, "a":I
if-le v0, v2, :cond_0
.line 19
const-string v1, "\u6211\u4eec\u7684\n\u4e16\u754c\u60a3\u6709\u4f20\u5947\u4e1c\u897f\uff0c\u4ec0\u4e48\u9b3c\u706f\u706b\u8f89\u714c\u706b\u5019\u4e0d\u5230\u8ab0\u8aaa\u4f60\u597d\u5462 "
invoke-static {p0, v1, v2}, Lcom/lxm/tools/myToast;->makeText(Landroid/content/Context;Ljava/lang/String;I)Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V
.line 26
:cond_0
逻辑代码如此。
我们看到一个条件语句:
if-le v0, v2, :cond_0
如果vx <= vy注2,跳转到目标。vx和vy是int型值
所以这句话意思为
如果v0<v2 跳到标记cond_0处。
我们发现这里逻辑跟我们的写法不同,但是执行效果一样,这就是源码到最终代码的一个转换。我们修改,则只需要将这里的条件转换
if-le v0, v2, :cond_0
换为
if-gt v0, v2, :cond_0 这样子就完成了我们的逻辑处理。
插桩。比起win PE 的难度,smali的插桩比较简单,因为我们修改的是系统架构的jar apk文件,这些文件是不能混淆的,因为三方的是需要这些,因此相对于混淆的apk来说,明文太多,对于修改帮助意义比较大。
首先我们eclipse 创建一个demo apk,运行看下效果。我这里用的是我写的一个程序,这段代码为:package com.example.test;
import com.lxm.tools.myToast;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.Toast;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// myToast.makeText(this, "我们的\n世界患有传奇东西,什么鬼灯火辉煌火候不到誰說你好呢 ", Toast.LENGTH_LONG).show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
我们的目标就是要在这个代码里面,新增一个注释的那行代码。
注释的那段代码反编译为:
.line 16
const-string v0, "\u6211\u4eec\u7684\n\u4e16\u754c\u60a3\u6709\u4f20\u5947\u4e1c\u897f\uff0c\u4ec0\u4e48\u9b3c\u706f\u706b\u8f89\u714c\u706b\u5019\u4e0d\u5230\u8ab0\u8aaa\u4f60\u597d\u5462 "
const/4 v1, 0x1
invoke-static {p0, v0, v1}, Lcom/lxm/tools/myToast;->makeText(Landroid/content/Context;Ljava/lang/String;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
我们原本代码为:
只放了关键代码
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 1
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
.line 14
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 15
const/high16 v0, 0x7f030000
invoke-virtual {p0, v0}, Lcom/example/test/MainActivity;->setContentView(I)V
.line 17
return-void
.end method
我们的目的便是在invoke-virtual {p0, v0}, Lcom/example/test/MainActivity;->setContentView(I)V后面增加一个TOast语句。
按照我们之前想的,应该直接追加即可。
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 1
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
.line 14
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 15
const/high16 v0, 0x7f030000
invoke-virtual {p0, v0}, Lcom/example/test/MainActivity;->setContentView(I)V
const-string v0, "\u6211\u4eec\u7684\n\u4e16\u754c\u60a3\u6709\u4f20\u5947\u4e1c\u897f\uff0c\u4ec0\u4e48\u9b3c\u706f\u706b\u8f89\u714c\u706b\u5019\u4e0d\u5230\u8ab0\u8aaa\u4f60\u597d\u5462 "
const/4 v1, 0x1
invoke-static {p0, v0, v1}, Lcom/lxm/tools/myToast;->makeText(Landroid/content/Context;Ljava/lang/String;I)Landroid/widget/Toast;
move-result-object v0
invoke-virtual {v0}, Landroid/widget/Toast;->show()V
.line 17
return-void
.end method
行数我们去掉,不需要这个代码。
我们反编译回去,发现启动不起来,这里就是我们要讲的一个关键点,局部变量问题。
我们看下.locals 1 说明只有一个局部变量,但是我们新增代码里面,有一个v0, v1,说明我们新增了一个局部变量,但是我们在方法前面只说了一个,所以出错,这里我们再将.locals 1
改为.locals 2 即可。
简单的一个教程。
我们再来看一个条件代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
int a=30;
if(a>1)
{
myToast.makeText(this, "我们的\n世界患有传奇东西,什么鬼灯火辉煌火候不到誰說你好呢 ", Toast.LENGTH_LONG).show();
}
else
{
}
// myToast.makeText(this, "我们的\n世界患有传奇东西,什么鬼灯火辉煌火候不到誰說你好呢 ", Toast.LENGTH_LONG).show();
}
反编译为:
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.locals 3
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.prologue
const/4 v2, 0x1
.line 14
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 15
const/high16 v1, 0x7f030000
invoke-virtual {p0, v1}, Lcom/example/test/MainActivity;->setContentView(I)V
.line 16
const/16 v0, 0x1e
.line 17
.local v0, "a":I
if-le v0, v2, :cond_0
.line 19
const-string v1, "\u6211\u4eec\u7684\n\u4e16\u754c\u60a3\u6709\u4f20\u5947\u4e1c\u897f\uff0c\u4ec0\u4e48\u9b3c\u706f\u706b\u8f89\u714c\u706b\u5019\u4e0d\u5230\u8ab0\u8aaa\u4f60\u597d\u5462 "
invoke-static {p0, v1, v2}, Lcom/lxm/tools/myToast;->makeText(Landroid/content/Context;Ljava/lang/String;I)Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V
.line 26
:cond_0
return-void
.end method
我们这里把条件语句换到else里面去。
.local v0, "a":I
if-le v0, v2, :cond_0
.line 19
const-string v1, "\u6211\u4eec\u7684\n\u4e16\u754c\u60a3\u6709\u4f20\u5947\u4e1c\u897f\uff0c\u4ec0\u4e48\u9b3c\u706f\u706b\u8f89\u714c\u706b\u5019\u4e0d\u5230\u8ab0\u8aaa\u4f60\u597d\u5462 "
invoke-static {p0, v1, v2}, Lcom/lxm/tools/myToast;->makeText(Landroid/content/Context;Ljava/lang/String;I)Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V
.line 26
:cond_0
逻辑代码如此。
我们看到一个条件语句:
if-le v0, v2, :cond_0
如果vx <= vy注2,跳转到目标。vx和vy是int型值
所以这句话意思为
如果v0<v2 跳到标记cond_0处。
我们发现这里逻辑跟我们的写法不同,但是执行效果一样,这就是源码到最终代码的一个转换。我们修改,则只需要将这里的条件转换
if-le v0, v2, :cond_0
换为
if-gt v0, v2, :cond_0 这样子就完成了我们的逻辑处理。
更多推荐
已为社区贡献2条内容
所有评论(0)