- 浏览: 335006 次
- 性别:
- 来自: 安徽
文章分类
最新评论
-
secally:
楼主可以上传个例子吗,谢谢,我咋跑不起来,,eclipse不是 ...
Android自动打包、签名、优化、上传ANT脚本 -
secally:
请问下执行命令是啥,ant release 还是?麻烦指教谢谢 ...
Android自动打包、签名、优化、上传ANT脚本 -
trp1022:
好牛啊
程序员不能不通文史 -
sunny78117:
谢谢,写得好
Android bitmap优化 -
futurebp:
这是什么类型的脚本啊?
Android自动打包、签名、优化、上传ANT脚本
為了某個實驗的動機,我們評估反編譯 Android 應用程式的可行性,本文即是筆者的心得與實際的範例,僅供參考。就筆者的認知,目前還沒有針對 Android 的 DEX to Java source 反編譯工具,可實際處理一般的 Android 應用程式,多半要繞幾圈,還會得到不甚理想的結果,不過,smali 這個反組譯工具,已是可用了,只是得對付類似 Jasmin 語法的 Dalvik 組合語言。筆者打包了 smali 與 Frozen Bubble for Android,作為示範:
在
GNU/Linux 環境中,首先取得 Android SDK,這裡採用 Eclair/2.1,工具執行檔的路徑是
android-sdk-linux_86/tools,將此路徑放入 $PATH 環境變數,如此一來,就可以操作 adb, aapt,
apkbuilder 一類的工具程式。筆者提供的套件已包含 Frozen Bubble 執行檔,檔名為
"FrozenBubble-orig.apk"。一旦 Android emulator 啟動後,即可安裝進去執行:(後續的操作也需要
Emulator 持續開啟)
$ adb install -r FrozenBubble-orig.apk
以下是執行畫面:
當然,沒必要讓筆者置喙談如何玩這個經典遊戲,不過我們倒是想更改原本的行為。在進行之前,我們先來複習 Android APK 的建立,參考 "How
to build Android application package (.apk) from the command line using
the SDK tools + continuously integrated using CruiseControl." 一文,我們可從以下圖表知悉細部的流程:
假設我們完全無法取得原始程式碼,該如何進行呢?沒錯,就透過 smali,簡化繁瑣的流程,筆者包裝為 Makefile,所以只要先解開並反組譯:
回 到筆者剛剛設定的目標,我們既然知道 class org.jfedor.frozenbubble.GameView$GameThread 掌控了程式處理邏輯,自然一堆變數的傳遞、method 呼叫,都在此進行,那我們先試著用 "level" 字串去搜尋,想辦法找出常數定義,後者在 Dalvik 中,會集中保存於 constant pool 中,而 smali 的組合語言寫法大致是 "const" 開頭的宣告,端看其類型而定。以程式追蹤的目的來說,我們專注於以下兩種:
前 面談過「倘若需要在 method invocation 時,帶入參數,一般會被替換為 "{v0, v1, v2, ...} 的 register 列表」這樣的概念,我們可推知,Register v1 與 v2 就是實際上 class org.jfedor.frozenbubble.LevelManager 的 constructor 參數。就程式設計的邏輯來看,class GameView 就是依據某個流程,要求 LevelManager 去改變狀態,所以這裡的兩個參數,其實就是初始值,非常的重要。
與 Register v1 相關的組合語言指令有這幾行:(用粗體字標示)
那麼,看看 Register v2 吧,同樣用粗體字標示相關的指令:
不過,回顧稍早 Register v2 的相關程式碼輸出,其中有兩行需要留意 (以粗體字為主):
注意到左下角,這表示我們成功了,完全不用取得 Java 原始程式碼,就可以作反組譯並且修改的動作。
$ make extract這時候會看到兩個目錄:
- smali-src : 存放反組譯的程式檔輸出
- workspace : 原本 Frozen Bubble 的 Android resource files
smali-src$ find就 忠實地依據 Java package 的方式呈現,檔名結尾是 ".smali"。筆者的修改目標是,讓一開始的關卡 (Level) 從第一關直接跳躍到第五關。在 smali 原始程式碼 (注意:這完全不同於 Java 原始程式碼,而是極為貼近 Dalvik VM 所接受的 DEX 檔案的組合語言形式) 搜尋 "Level" 字眼,可發現主要的分佈就落於兩個檔案:
./org/jfedor/frozenbubble/FrozenBubble.smali
./org/jfedor/frozenbubble/R$id.smali
./org/jfedor/frozenbubble/GameView.smali
./org/jfedor/frozenbubble/SoundManager.smali
./org/jfedor/frozenbubble/LaunchBubbleSprite.smali
./org/jfedor/frozenbubble/Compressor.smali
./org/jfedor/frozenbubble/R$attr.smali
./org/jfedor/frozenbubble/BubbleFont.smali
./org/jfedor/frozenbubble/PenguinSprite.smali
./org/jfedor/frozenbubble/GameView$GameThread.smali
./org/jfedor/frozenbubble/BubbleSprite.smali./org/jfedor/frozenbubble/R$string.smali
./org/jfedor/frozenbubble/R$drawable.smali
./org/jfedor/frozenbubble/ImageSprite.smali
./org/jfedor/frozenbubble/BubbleManager.smali
./org/jfedor/frozenbubble/GameScreen.smali
./org/jfedor/frozenbubble/R.smali
./org/jfedor/frozenbubble/R$layout.smali
./org/jfedor/frozenbubble/BmpWrap.smali./org/jfedor/frozenbubble/FrozenGame.smali
./org/jfedor/frozenbubble/Sprite.smali
./org/jfedor/frozenbubble/LevelManager.smali
./org/jfedor/frozenbubble/R$raw.smali
- ./org/jfedor/frozenbubble/GameView$GameThread.smali
- ./org/jfedor/frozenbubble/LevelManager.smali
smali-src$ grep "\.method" org/jfedor/frozenbubble/LevelManager.smali倘若我們以 "goToFirstLevel" 一類的關鍵字,在 org/jfedor/frozenbubble/GameView$GameThread.smali 檔案中搜尋,可找出有具體的呼叫行為:
.method public constructor <init>([BI)V
.method private getLevel(Ljava/lang/String;)[[B
.method public getCurrentLevel()[[B
.method public getLevelIndex()I
.method public goToFirstLevel()V
.method public goToNextLevel()V.method public restoreState(Landroid/os/Bundle;)V
.method public saveState(Landroid/os/Bundle;)V
smali-src$ grep -r goToFirstLevel *由此更確定我們之前的猜想。其中組合語言寫為以下:
org/jfedor/frozenbubble/GameView$GameThread.smali: invoke-virtual {v2}, Lorg/jfedor/frozenbubble/LevelManager;->goToFirstLevel()V
org/jfedor/frozenbubble/LevelManager.smali:.method public goToFirstLevel()V
move-object/from16 v0, p0不 要被貌似複雜的語法嚇到了,基本上掌握 Java 程式語言的原則 "Everything is Object" (不過仍有提供 primitive type),組合語言仍會作 Java Object 的實體化 (instantialization),Dalvik 本身是 Register-based Virtual Machine,而扣除 static/class method 外,Java 中所有的 method invocation 多為 virtual function (對應於 C++ 的觀點,才能更具體用機械方式思考),所以組合語言的指令為 "invoke-virtual" (注意有連字號,此與 Java bytecode 不同),"{v2}" 表示第一受者的 Register,此為 Object 本體。接著,與 Java bytecode 一樣,"Lorg/jfedor/frozenbubble/LevelManager;" 就表示 Java 層面的 class "org.jfedor.frozenbubble.LevelManager",字母 "L" 即為 class 的識別,而 "->" 就很直觀了,自然是 method invocation,所以連貫來看,這一段組合語言的 Java 意思為:
iget-object v0, v0, Lorg/jfedor/frozenbubble/GameView$GameThread;->mLevelManager:Lorg/jfedor/frozenbubble/LevelManager;
move-object v2, v0
invoke-virtual {v2}, Lorg/jfedor/frozenbubble/LevelManager;->goToFirstLevel()V
objectLevelManager.goToFirstLevel();其 中 objectLevelManager 是一個 class LevelManager 的實例/實體 (instance)。倘若需要在 method invocation 時,帶入參數,那麼前述的 "{v2}" 一般會被替換為 "{v0, v1, v2, ...} 的 register 列表。關於詳細的狀況,可參考 Dalvik 非官方說明,另外 smali 的 wiki 也提供一些範例,可多加利用。
回 到筆者剛剛設定的目標,我們既然知道 class org.jfedor.frozenbubble.GameView$GameThread 掌控了程式處理邏輯,自然一堆變數的傳遞、method 呼叫,都在此進行,那我們先試著用 "level" 字串去搜尋,想辦法找出常數定義,後者在 Dalvik 中,會集中保存於 constant pool 中,而 smali 的組合語言寫法大致是 "const" 開頭的宣告,端看其類型而定。以程式追蹤的目的來說,我們專注於以下兩種:
- const-string : primitive string (不同於 java.lang.String) 表示
- const/4 : 長度為 4 bytes (32 bit) 的整數表示
const-string v3, "level"在 上述程式碼列表中,"Lorg/jfedor/frozenbubble/LevelManager;-><init>" 表示呼叫 class LevelManager 的 constructor,也就是 "<init>"。注意到 method invocation 方式就不同了,是 "invoke-direct",表示 class constructor,而這之前要有 "new-instance v3, Lorg/jfedor/frozenbubble/LevelManager;" 的組合語言指令宣告。
const/4 v4, 0x0
move-object/from16 v0, v25 move-object v1, v3
move v2, v4
invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences;->getInt(Ljava/lang/String;I)I
move-result p4
new-instance v3, Lorg/jfedor/frozenbubble/LevelManager;
move-object v0, v3
move-object/from16 v1, v22
move/from16 v2, p4 invoke-direct {v0, v1, v2}, Lorg/jfedor/frozenbubble/LevelManager;-><init>([BI)V
前 面談過「倘若需要在 method invocation 時,帶入參數,一般會被替換為 "{v0, v1, v2, ...} 的 register 列表」這樣的概念,我們可推知,Register v1 與 v2 就是實際上 class org.jfedor.frozenbubble.LevelManager 的 constructor 參數。就程式設計的邏輯來看,class GameView 就是依據某個流程,要求 LevelManager 去改變狀態,所以這裡的兩個參數,其實就是初始值,非常的重要。
與 Register v1 相關的組合語言指令有這幾行:(用粗體字標示)
const-string v3, "level"顯 然,Register v1 還被帶入到 android.content.Shared.Preference.getInt() method,而更早以前,其內含值被設定為 Register v3 的值,也就是常數字串 (const-string) "level",這好像與我們的焦點不同。另外,像是 Register v22 這個編號較大的 register,表示 local variable,這點需要多留意,因為 Java 程式設計的規範來說,往往會將程式切割為若干 method,而 method 實做體中,又有極多的 local variable,於是往往可從組合語言反推 Java 原始碼的型態。
const/4 v4, 0x0
move-object/from16 v0, v25
move-object v1, v3
move v2, v4
invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences;->getInt(Ljava/lang/String;I)I
move-result p4
new-instance v3, Lorg/jfedor/frozenbubble/LevelManager;
move-object v0, v3
move-object/from16 v1, v22
move/from16 v2, p4
invoke-direct {v0, v1, v2}, Lorg/jfedor/frozenbubble/LevelManager;-><init>([BI)V
那麼,看看 Register v2 吧,同樣用粗體字標示相關的指令:
const-string v3, "level"這 個 Register v4 的內含值 "0x0" 會指派到 Register v2 中,而讓我們似乎找到方向了,回頭看看 class org.jfedor.frozenbubble.LevelManager 的 constructor 宣告方式: (之前 grep 結果的第一行)
const/4 v4, 0x0
move-object/from16 v0, v25
move-object v1, v3
move v2, v4
invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences;->getInt(Ljava/lang/String;I)I
move-result p4
new-instance v3, Lorg/jfedor/frozenbubble/LevelManager;
move-object v0, v3
move-object/from16 v1, v22
move/from16 v2, p4
invoke-direct {v0, v1, v2}, Lorg/jfedor/frozenbubble/LevelManager;-><init>([BI)V
smali-src$ grep "\.method" org/jfedor/frozenbubble/LevelManager.smali其中 "public" 是 ACL (存取權限) 的宣告,而 constructor 的符號規範為 "<init>",注意到括號 "(" 與 ")" 裡面的兩個大寫字母,表示接受兩個參數,對應的型態為:
.method public constructor <init>([BI)V
- B : byte
- I : int
不過,回顧稍早 Register v2 的相關程式碼輸出,其中有兩行需要留意 (以粗體字為主):
invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences;->getInt(Ljava/lang/String;I)I"p4" 用以保存 method invocation 之後的回傳值,顯然,Register v2 受到 p4 的指派,也就是被更動為 android.content.Shared.Preference.getInt() method 的回傳值,這存在不確定性,於是,我們乾脆一口氣改掉: (修改的部份會用井字號 "#" 作註解)
move-result p4
new-instance v3, Lorg/jfedor/frozenbubble/LevelManager;
move-object v0, v3
move-object/from16 v1, v22
move/from16 v2, p4
# Modified from 0x0 to 0x4"改好程式,當然要驗證,回到上一層目錄,透過 smali 提供的組譯器,重新產生 Dalvik DEX 輸出,為了簡化流程,筆者把 smali, apkbuilder, aapt, adb install 都一次整合進去,所以會直接讓 Android Emulator 生效,來看看我們的戰果吧:
const/4 v4, 0x4
move-object/from16 v0, v25
move-object v1, v3
move v2, v4
# Modified: removed the following 2 lines
# invoke-interface {v0, v1, v2}, Landroid/content/SharedPreferences;->getInt(Ljava/lang/String;I)I
# move-result p4
new-instance v3, Lorg/jfedor/frozenbubble/LevelManager;
move-object v0, v3
move-object/from16 v1, v22
# Modified: removed the following 1 line
# move/from16 v2, p4
invoke-direct {v0, v1, v2}, Lorg/jfedor/frozenbubble/LevelManager;-><init>([BI)V
发表评论
-
抓取Android WebView截屏
2011-08-19 21:33 7597一般使用setDrawingCacheEnabled(true ... -
Android bitmap优化
2011-08-11 17:02 5889直接使用ImageView显示 ... -
Android模拟器更改分辨率后 无法取得分辨率问题
2011-05-11 21:06 2792在PC上更改模拟器分辨率为480*800 (如果你的PC界面 ... -
获取屏幕硬件分辨率方法 收藏
2011-05-11 16:28 1881TextView tv=(TextVie ... -
Bytecode for the Dalvik VM
2011-05-10 22:35 1318http://www.netmite.com/android/ ... -
Android DEX反编译后部分代码解析
2011-05-10 22:07 3865一个private 方法 private Stri ... -
Android Ant编译时候进行混淆
2010-10-18 13:49 3805版权所有,欢迎转载,转载请注明 : SinFrancis h ... -
自定义Ant Task
2010-09-13 17:58 2962版权所有,欢迎转载,转载请注明 : SinFrancis h ... -
Android自动打包、签名、优化、上传ANT脚本
2010-07-26 16:51 13932版权所有,欢迎转载,转载请注明 : SinFrancis h ... -
Android自定义含有CheckBox的Adapter遇到的问题
2010-06-23 13:48 4084版权所有,欢迎转载,转载请注明 : SinFrancis h ... -
QR code类库
2010-06-03 23:11 2291Google code发现的好东西。 QR code 类库 ... -
Android QQ,一个WEBOS APP诞生!!(两个QQ对比!)
2010-04-10 12:05 1844请看这个大哥的言论 http://linuxtoy.or ... -
Android 、BlackBerry 文本对齐方式对比
2010-02-22 13:11 1776版权所有,欢迎转载,转载请注明 : SinFrancis h ... -
教你如何开关Android的APN网络
2010-01-08 11:36 5971版权所有,转载请注明来自Mobile Developer (h ... -
史上最强NDK入门项目实战
2009-10-10 13:29 2661以下内容Sinfrancis版权所有,专注请注明来自 htt ... -
使用TimerTask控制ProgressBar
2009-10-10 13:21 1044以下内容Sinfrancis版权所有,专注请注明来自 htt ... -
自定义List布局
2009-10-10 13:19 1856以下内容Sinfrancis版权所有,专注请注明来自 htt ... -
重画Progressbar的进度
2009-10-10 13:15 1908以下内容Sinfrancis版权所有,专注请注明来自 htt ... -
谈谈Android中文短信的实现
2009-10-10 13:13 2143似 乎Google在推出G1时 ... -
模拟器互发短信
2009-10-10 13:11 1256以下内容Sinfrancis版权所有,专注请注明来自 htt ...
相关推荐
androidapk反编译or打包工具,反编译apk包进行修改并重新打包
反编译工具包 下载后的操作步骤 Android APK反编译 未做测试全是最新工具包,另附已经做过测试的工具包,...首先,下载上述反编译工具包,打开Androidfby目录,双击Android反编译工具.exe,就可以浏览打开要反编译的apk
Android的apk文件反编译后,甚多的资源和java文件无法对应,java文件中引用的资源id变成十进制数字。本文将反编译apk的java文件和资源文件重新关联引用对应,使得java文件能准确无误地重新引用资源文件。 (1)将反...
android的apk反编译,适用于对软件广告的去除和手机游戏的经验金币的修改等
APK改之理(Apk IDE)是一款可视化的用于修改安卓Apk程序文件的工具,集成了ApkTool、Dex2jar、JD-GUI等Apk修改工具,集Apk反编译、Apk打包、Apk签名,支持语法高亮的代码编辑器,基于文件内容的关键字(支持单行...
4、包含了dex2jar,可将apk文件解压时的classes.dex反编译为jar包文件; 5、包含了jd-jui,可将jar包文件反编译为java源代码; 6、包含了APKSign签名工具,可对修改后的apk文件进行签名,确保apk可以安装运行; 7、...
ANDROID apk 反编译工具包 包含 Gapktool,DoAPK_Beta1.0和Dodo_APKToolsAPK安装包自由修改工具 推荐使用 Gapktool进行反编译,反编译出来的源码相对完整,方便初学者对某些程序的功能实现过程学习参考
NULL 博文链接:https://chenzheng8975.iteye.com/blog/2113392
本文首先介绍几种Android反编译工具的使用,然后实现在不需要知道源代码的情况下,仅通过修改反编译得到的smali文件实现修改apk逻辑功能的目的。 Android中常用的反编译工具有三个:dex2jar、jd-gui和apk
本人博客:Android对apk源码的修改--反编译+源码修改+重新打包+签名【附HelloWorld的修改实例】中用到的资源,博客以helloworld为例讲述了对apk源码进行修改的方法,感兴趣的可以看看
强力推荐,Android Kill(最好用的Android apk反编译软件) Android Killer是一款可以对APK进行反编译的工具,它能够对反编译后的Smali文件进行修改,并将修改后的文件进行打包
Android Killer是一款可视化的安卓应用逆向工具,集Apk反编译、Apk打包、Apk签名,编码互转,ADB通信(应用安装-卸载-运行-设备文件管理)等特色功能于一 身,支持logcat日志输出,语法高亮,基于关键字(支持单行...
是一款,针对Android OS系统的APK程序,直接反编译修改的工具。 APKDB集合了当今最强悍,最犀利的APK及Dex文件编译工具; 正常安装后,它直接在【鼠标右键】创建快捷菜单; 非常方便汉化工作者,对APK或Dex文件...
Android APK+Dex(APKDB)安卓反编译利器包是一款针对Android OS系统的APK程序直接反编译修改的工具,集合了当今最强悍,最犀利的APK及Dex文件编译工具,这款软件比上版调整幅度比较大,而这轮主要是先进行稳定性方面...
安卓包名修改工具,可修改包名反编译
是一款,针对Android OS系统的APK程序,直接反编译修改的工具。 APKDB集合了当今最强悍,最犀利的APK及Dex文件编译工具; 正常安装后,它直接在【鼠标右键】创建快捷菜单; 非常方便汉化工作者,对APK或Dex文件...
Android Killer 中文版是一款可视化的安卓反编译软件,集Apk反编译、Apk打包、Apk签名,编码互转,ADB通信(应用安装-卸载-运行-设备文件管理)等特色功能于一身,支持logcat日志输出,语法高亮,基于关键字(支持...
可以将apk反编译成java源代码的工具,具体使用方法可参考 http://blog.csdn.net/kjianjun/article/details/7742989
有了这些反编译出来的smali代码之后,我们就可以轻松地了解别人的APK使用的一些技术或者直接修改别人的APK。由于这些APK反编译工具的存在,我们迫切地希望能有方法去防止别人来反编译我们的APK,从而保护自己的商业...
本工具箱集合了,当今最强悍,最犀利的APK\Dex反编译工具; 【注意:反编译文件名称 不能用中文,否则无法回编译。】 _____________________________________________________________________________________...