说说APK反编译(代码插入)的那点事
2012-02-26 22:33
417 查看
http://shazhuzhu1.iteye.com/blog/1415328
很多人热衷于逆向工程,其过程中既可以学习作者的思路,又可以锻炼自己的能力,可谓是一举多得! 今天我来给大家伙介绍介绍我所了解的apk反编译的相关技术,和大家一起来做一个逆向工程.
提醒:未经授权而逆向别人的程序是违法行为! 在此,我们只做学术研究,不搞破坏~
知识铺垫:
1.反编译的结果有两种,一种是smali (java机器码),还有一种是大家喜闻乐见的java代码形式.
2.apk文件其实是一个zip压缩包,里面的目录结构与android工程的结构很类似,其中我们的java源码(包括R.java)在classes.dex文件中.
3.期间的工具大部分是java写的,运行时需要具备java环境!
我先介绍大家喜闻乐见的形式吧,哈哈…
将apk反编译为源码.
需要的工具:
1.dex2jar.
dex2jar-0.0.7.10-SNAPSHOT.zip (590.31
KB, 下载次数: 44)
2.Jd-gui.
jd-gui-0.3.3.osx.i686.zip (689.59
KB, 下载次数: 39)
3.AXMLPrinter2.
AXMLPrinter2.zip (38.76
KB, 下载次数: 34)
逆向目标是前阵子悬赏区发过的一个demo,正好是我写的,我授权给所有cmd100用户,欢迎逆向,不追任何究法律责任..
源码:http://www.cmd100.com/bbs/forum- ... 052-pid-173308.html
Apk文件:
CMD100.demo.slipButton.rar (18.74
KB, 下载次数: 19)
方法:
既然是一个zip压缩包,那就先把apk包解压出来吧!
可以看到解压出来的文件如下:
先处理xml 文件.. 你可能想直接打开xml文件,但其实xml文件被加密过了,打开只会是一堆你读不懂的东西,这需要用工具解码一下, 用到AXMLPrinter2.
打开CMD切换到AXMLPrinter2目录.
命令: Java –jar axmlprinter2.jar [路径]\AndroidManifest.xml >输出文件名.xml
打开生成的这个文件,看看Manifest.xml是不是出来了?
反编译结果:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="CMD100.demo.slipButton"
>
<application
android:label="@7F040001"
android:icon="@7F020000"
android:debuggable="true"
>
<activity
android:label="@7F040001"
android:name=".Main"
>
<intent-filter
>
<action
android:name="android.intent.action.MAIN"
>
</action>
<category
android:name="android.intent.category.LAUNCHER"
>
</category>
</intent-filter>
</activity>
</application>
<uses-sdk
android:minSdkVersion="4"
>
</uses-sdk>
</manifest>
复制代码
源文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="CMD100.demo.slipButton"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="4" />
</manifest>
复制代码
使用同样的方法把res/layout/目录下的布局文件也解码一下~在此我就不再赘述了.
接下来是dex文件的处理,需要用dex2jar工具处理转换一下.
先把工具解压出来,然后CMD切换到指定目录,运行如下命令:
dex2jar.bat [目录]\classes.dex
执行完毕后,classes.dex所在目录下便生成了一个名为classes.dex.dex2jar.jar的文件!
用jd-gui打开这个生成的jar试试!代码就在里面了有没有?!
对比一下main.java吧.
反编译:
public class Main extends Activity
implements OnChangedListener
{
public void OnChanged(boolean paramBoolean)
{
if (paramBoolean)
{
Toast.makeText(this, "打开了...", 0).show();
return;
}
Toast.makeText(this, "关闭了...", 0).show();
}
public void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2130903040);
((SlipButton)findViewById(2131034112)).SetOnChangedListener(this);
}
}
复制代码
源文件:
public class Main extends Activity implements OnChangedListener {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SlipButton myBtn =(SlipButton) findViewById(R.id.slipBtn);//获得指定控件
myBtn.SetOnChangedListener(this);//为控件设置监听器
}
@Override
public void OnChanged(boolean CheckState) {//当按钮状态被改变时
// TODO Auto-generated method stub
if(CheckState)
Toast.makeText(this,"打开了..." , Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"关闭了..." , Toast.LENGTH_SHORT).show();
}
}
复制代码
P.S.其实这样获得的源码还是有一部分会出现错误啊~
=================分割线========================
将apk反编译为smali并插入自己的代码
用到的工具:
1.apktool.jar (或smali-1.2.6.jar & baksmali-1.2.6.jar)
Apktool.zip (2.01
MB, 下载次数: 27)
2.auto-sign.
APK-sign.rar (1.66
MB, 下载次数: 33)
这些工具都是google的开源项目…
主要流程:
1.反编译
2.插入代码
3.重新打包
方法:
有了前面的铺垫,我就不再啰嗦了.
命令:java -jar apktool.jar d 目标文件.apk
在apktool.jar所在目录下就生成了这个apk反编译后的文件夹,打开看看!
包括xml在内的文件都被解码了!
不过我们关注的是smali文件夹,打开看看,里面的目录结构和源码的目录结构是一致的!
找到要修改的地方.在这个例子里,就在Main.java(第一个载入的activity)的OnCreate方法里插入一段代码吧!
打开 Main.smali
.class public LCMD100/demo/slipButton/Main;
.super Landroid/app/Activity;
.source "Main.java"
# interfaces
.implements LCMD100/demo/slipButton/OnChangedListener;
# direct methods
.method public constructor <init>()V
.locals 0
.prologue
.line 14
invoke-direct {p0}, Landroid/app/Activity;-><init>()V
return-void
.end method
# virtual methods
.method public OnChanged(Z)V
.locals 2
.parameter "CheckState"
.prologue
const/4 v1, 0x0
.line 28
if-eqz p1, :cond_0
.line 29
const-string v0, "\u6253\u5f00\u4e86..."
invoke-static {p0, v0, v1}, 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
.line 32
:goto_0
return-void
.line 31
:cond_0
const-string v0, "\u5173\u95ed\u4e86..."
invoke-static {p0, v0, v1}, 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
goto :goto_0
.end method
.method public onCreate(Landroid/os/Bundle;)V
.locals 2
.parameter "savedInstanceState"
.prologue
.line 18
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 19
const/high16 v1, 0x7f03
invoke-virtual {p0, v1}, LCMD100/demo/slipButton/Main;->setContentView(I)V
.line 21
const/high16 v1, 0x7f05
invoke-virtual {p0, v1}, LCMD100/demo/slipButton/Main;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, LCMD100/demo/slipButton/SlipButton;
.line 22
.local v0, myBtn:LCMD100/demo/slipButton/SlipButton;
invoke-virtual {v0, p0}, LCMD100/demo/slipButton/SlipButton;->SetOnChangedListener(LCMD100/demo/slipButton/OnChangedListener;)V
.line 23
return-void
.end method
复制代码
你发现里头的代码是见都没见过的格式,这就是java的汇编代码了…
学过80x86汇编的同学看着这些代码是不是也觉得陌生?
没事,我们可以对照前面介绍的那种方法查看源码,然后寻找修改的位置!
找到这一行:
.method public onCreate(Landroid/os/Bundle;)V
这就是OnCreate方法的代码起始了,在
.line 23
return-void
之前插入如下代码: (效果是Toast弹出一句话.)
const-string v0, "Hey,dude.This program has been fucked!"
const/4 v1, 0x0
invoke-static {p0, v0, v1}, 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
复制代码
为什么是这个,其实我也不懂smali,但是可以把自己要的功能写出来,再反汇编…然后copy到这来…
好吧,我们来分析一下这段代码,前面是类似申明了两个变量,v0,v1,然后调用了Toast的makeText方法(列出了参数),再然后调用了其show方法…
看吧,其实我们是能大概看懂smali的内容,只是不懂语法而已!
好吧,废话不多说.
现在改好了,用apktool重新打包~
命令: java -jar apktool.jar b 目标文件夹
执行完后,就在这个目录里生成了两个目录,分别是build,dist
Build下是中间文件,dist下则是apk文件(但是这个apk文件未签名)
下面就是重新签名了.
先解压auto-sign
我们进入Build文件夹,复制apk文件夹到auto-sign文件夹下,然后执行命令:
sign_pack.bat apk
稍等片刻,你会发现文件夹下生成了对应的目录,进入这个目录,apk静静地躺在那…
赶紧,装到手机上看看,是不是改成了?
成功弹出,哈哈...
至此,apk的反编译和代码插入就结束了.
借此方法,我们可以轻松的对apk进行DIY...
欢迎转载,但,转载请注明出处!
很多人热衷于逆向工程,其过程中既可以学习作者的思路,又可以锻炼自己的能力,可谓是一举多得! 今天我来给大家伙介绍介绍我所了解的apk反编译的相关技术,和大家一起来做一个逆向工程.
提醒:未经授权而逆向别人的程序是违法行为! 在此,我们只做学术研究,不搞破坏~
知识铺垫:
1.反编译的结果有两种,一种是smali (java机器码),还有一种是大家喜闻乐见的java代码形式.
2.apk文件其实是一个zip压缩包,里面的目录结构与android工程的结构很类似,其中我们的java源码(包括R.java)在classes.dex文件中.
3.期间的工具大部分是java写的,运行时需要具备java环境!
我先介绍大家喜闻乐见的形式吧,哈哈…
将apk反编译为源码.
需要的工具:
1.dex2jar.
dex2jar-0.0.7.10-SNAPSHOT.zip (590.31
KB, 下载次数: 44)
2.Jd-gui.
jd-gui-0.3.3.osx.i686.zip (689.59
KB, 下载次数: 39)
3.AXMLPrinter2.
AXMLPrinter2.zip (38.76
KB, 下载次数: 34)
逆向目标是前阵子悬赏区发过的一个demo,正好是我写的,我授权给所有cmd100用户,欢迎逆向,不追任何究法律责任..
源码:http://www.cmd100.com/bbs/forum- ... 052-pid-173308.html
Apk文件:
CMD100.demo.slipButton.rar (18.74
KB, 下载次数: 19)
方法:
既然是一个zip压缩包,那就先把apk包解压出来吧!
可以看到解压出来的文件如下:
先处理xml 文件.. 你可能想直接打开xml文件,但其实xml文件被加密过了,打开只会是一堆你读不懂的东西,这需要用工具解码一下, 用到AXMLPrinter2.
打开CMD切换到AXMLPrinter2目录.
命令: Java –jar axmlprinter2.jar [路径]\AndroidManifest.xml >输出文件名.xml
打开生成的这个文件,看看Manifest.xml是不是出来了?
反编译结果:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="CMD100.demo.slipButton"
>
<application
android:label="@7F040001"
android:icon="@7F020000"
android:debuggable="true"
>
<activity
android:label="@7F040001"
android:name=".Main"
>
<intent-filter
>
<action
android:name="android.intent.action.MAIN"
>
</action>
<category
android:name="android.intent.category.LAUNCHER"
>
</category>
</intent-filter>
</activity>
</application>
<uses-sdk
android:minSdkVersion="4"
>
</uses-sdk>
</manifest>
复制代码
源文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="CMD100.demo.slipButton"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".Main"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-sdk android:minSdkVersion="4" />
</manifest>
复制代码
使用同样的方法把res/layout/目录下的布局文件也解码一下~在此我就不再赘述了.
接下来是dex文件的处理,需要用dex2jar工具处理转换一下.
先把工具解压出来,然后CMD切换到指定目录,运行如下命令:
dex2jar.bat [目录]\classes.dex
执行完毕后,classes.dex所在目录下便生成了一个名为classes.dex.dex2jar.jar的文件!
用jd-gui打开这个生成的jar试试!代码就在里面了有没有?!
对比一下main.java吧.
反编译:
public class Main extends Activity
implements OnChangedListener
{
public void OnChanged(boolean paramBoolean)
{
if (paramBoolean)
{
Toast.makeText(this, "打开了...", 0).show();
return;
}
Toast.makeText(this, "关闭了...", 0).show();
}
public void onCreate(Bundle paramBundle)
{
super.onCreate(paramBundle);
setContentView(2130903040);
((SlipButton)findViewById(2131034112)).SetOnChangedListener(this);
}
}
复制代码
源文件:
public class Main extends Activity implements OnChangedListener {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SlipButton myBtn =(SlipButton) findViewById(R.id.slipBtn);//获得指定控件
myBtn.SetOnChangedListener(this);//为控件设置监听器
}
@Override
public void OnChanged(boolean CheckState) {//当按钮状态被改变时
// TODO Auto-generated method stub
if(CheckState)
Toast.makeText(this,"打开了..." , Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"关闭了..." , Toast.LENGTH_SHORT).show();
}
}
复制代码
P.S.其实这样获得的源码还是有一部分会出现错误啊~
=================分割线========================
将apk反编译为smali并插入自己的代码
用到的工具:
1.apktool.jar (或smali-1.2.6.jar & baksmali-1.2.6.jar)
Apktool.zip (2.01
MB, 下载次数: 27)
2.auto-sign.
APK-sign.rar (1.66
MB, 下载次数: 33)
这些工具都是google的开源项目…
主要流程:
1.反编译
2.插入代码
3.重新打包
方法:
有了前面的铺垫,我就不再啰嗦了.
命令:java -jar apktool.jar d 目标文件.apk
在apktool.jar所在目录下就生成了这个apk反编译后的文件夹,打开看看!
包括xml在内的文件都被解码了!
不过我们关注的是smali文件夹,打开看看,里面的目录结构和源码的目录结构是一致的!
找到要修改的地方.在这个例子里,就在Main.java(第一个载入的activity)的OnCreate方法里插入一段代码吧!
打开 Main.smali
.class public LCMD100/demo/slipButton/Main;
.super Landroid/app/Activity;
.source "Main.java"
# interfaces
.implements LCMD100/demo/slipButton/OnChangedListener;
# direct methods
.method public constructor <init>()V
.locals 0
.prologue
.line 14
invoke-direct {p0}, Landroid/app/Activity;-><init>()V
return-void
.end method
# virtual methods
.method public OnChanged(Z)V
.locals 2
.parameter "CheckState"
.prologue
const/4 v1, 0x0
.line 28
if-eqz p1, :cond_0
.line 29
const-string v0, "\u6253\u5f00\u4e86..."
invoke-static {p0, v0, v1}, 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
.line 32
:goto_0
return-void
.line 31
:cond_0
const-string v0, "\u5173\u95ed\u4e86..."
invoke-static {p0, v0, v1}, 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
goto :goto_0
.end method
.method public onCreate(Landroid/os/Bundle;)V
.locals 2
.parameter "savedInstanceState"
.prologue
.line 18
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 19
const/high16 v1, 0x7f03
invoke-virtual {p0, v1}, LCMD100/demo/slipButton/Main;->setContentView(I)V
.line 21
const/high16 v1, 0x7f05
invoke-virtual {p0, v1}, LCMD100/demo/slipButton/Main;->findViewById(I)Landroid/view/View;
move-result-object v0
check-cast v0, LCMD100/demo/slipButton/SlipButton;
.line 22
.local v0, myBtn:LCMD100/demo/slipButton/SlipButton;
invoke-virtual {v0, p0}, LCMD100/demo/slipButton/SlipButton;->SetOnChangedListener(LCMD100/demo/slipButton/OnChangedListener;)V
.line 23
return-void
.end method
复制代码
你发现里头的代码是见都没见过的格式,这就是java的汇编代码了…
学过80x86汇编的同学看着这些代码是不是也觉得陌生?
没事,我们可以对照前面介绍的那种方法查看源码,然后寻找修改的位置!
找到这一行:
.method public onCreate(Landroid/os/Bundle;)V
这就是OnCreate方法的代码起始了,在
.line 23
return-void
之前插入如下代码: (效果是Toast弹出一句话.)
const-string v0, "Hey,dude.This program has been fucked!"
const/4 v1, 0x0
invoke-static {p0, v0, v1}, 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
复制代码
为什么是这个,其实我也不懂smali,但是可以把自己要的功能写出来,再反汇编…然后copy到这来…
好吧,我们来分析一下这段代码,前面是类似申明了两个变量,v0,v1,然后调用了Toast的makeText方法(列出了参数),再然后调用了其show方法…
看吧,其实我们是能大概看懂smali的内容,只是不懂语法而已!
好吧,废话不多说.
现在改好了,用apktool重新打包~
命令: java -jar apktool.jar b 目标文件夹
执行完后,就在这个目录里生成了两个目录,分别是build,dist
Build下是中间文件,dist下则是apk文件(但是这个apk文件未签名)
下面就是重新签名了.
先解压auto-sign
我们进入Build文件夹,复制apk文件夹到auto-sign文件夹下,然后执行命令:
sign_pack.bat apk
稍等片刻,你会发现文件夹下生成了对应的目录,进入这个目录,apk静静地躺在那…
赶紧,装到手机上看看,是不是改成了?
成功弹出,哈哈...
至此,apk的反编译和代码插入就结束了.
借此方法,我们可以轻松的对apk进行DIY...
欢迎转载,但,转载请注明出处!
相关文章推荐
- APK反编译后插入代码
- 反编译APK获取代码&资源
- 工欲善其事,必先利其器 软件工具开发关键词 protractor自动化测试工具 RegexBuddy正则 CodeSmith,LightSwitch:代码生成 CheatEngine:玩游戏修改内存值必备神器 ApkIDE:Android反编译工具 Reflector:反编译dll动态链接库
- Android APK反编译 得到 代码 图片
- 反编译APK获取java代码与图片,字符串资源,xml文件等资源
- 如何阻止APK反编译查看源代码?
- Android apk反编译及AS代码混淆方法
- Android APK反编译以及代码混淆
- 借助apktool.jar工具,使用python代码简化批量反编译apk安装包的简单实现
- Android APK反编译方法(可以获取APK xml和android Manifest,java代码等内容)
- 反编译APK获取java代码与图片,字符串资源,xml文件等资源
- 防止 apk反编译 jocky-- java混淆代码
- APK反编译后代码分析(一)
- 反编译APK获取java代码与图片,字符串资源,xml文件等资源
- 反编译apk插入日志重新打包流程
- 反编译APK获取代码&资源
- Android基础入门教程——1.10 反编译APK获取代码&资源
- APK反编译之一:smail代码的基础
- Android APK反编译和代码混淆
- apk的打包和反编译一、代码混淆ProGuard