由于某些需求胚膊,我們需要對特定Apk進行修改。下面我們嘗試向某Apk的主Activity注入發(fā)送http請求的操作。鄭重申明:學會以后不可以做壞事哦~
-
需要的工具
- 反編譯/重打包/簽名 工具: 我使用的是mac下的Android Crack Tool集成工具朴肺, 包含了這三個功能窖剑。Windows下有類似的工具坚洽,讀者自行搜索下載即可。
- Android Studio: 由于直接編寫smali代碼難度很大西土!(牛批的大神可以略過~)我們這里使用IDEA的Java2Smali插件讶舰,可以直接將java文件轉換為smali文件。所以需了,Android Studio不是必須的跳昼,只要你能把java轉成smali就行。我這里徒省事肋乍,就直接用AS啦鹅颊。
- Jeb: 追蹤Apk代碼的強大工具!可以直接查看smali或decompile后的java代碼并自由切換墓造。當然堪伍,其他類似工具也可以~
-
反編譯Apk
可以看到,使用類似的集成化工具進行反編譯或其他操作是很簡單的觅闽。好吧好吧帝雇,我承認這不是簡單,簡直就是傻瓜式?(PД`q?)?゜ 不懂Android蛉拙,不會寫程序的也可以反編譯了好嗎尸闸!為了展現(xiàn)出我們Android逆向研究人員的專業(yè)性,為了b格孕锄,下面我們使用命令進行反編譯吮廉!(自己學吧~我才不教,費勁畸肆!ˋˊ )
回歸正題宦芦,執(zhí)行后,目錄下會生成test-O文件夾恼除,里面包含了反編譯后的文件踪旷。
-
重建Apk
選中我們剛才反編譯好的文件夾test-O再重建即可。目錄下會出現(xiàn)test-O-R.apk豁辉。
-
簽名Apk
重建好的apk是沒有簽名的令野,無法安裝到手機。所以我們用工具給apk簽個名就ok啦~
-
尋找Apk內的主Activity
這里先說明為什么我們要先走一遍 反編譯-重建-簽名 的流程徽级,因為某種神秘的因素气破,就算你沒有做任何修改,二次打包后的apk都無法安裝使用(′°????????ω°????????`) (其實這是別人告訴我的餐抢,如不正確請指正现使。為了不走彎路低匙,我就信了,反正事先試一下也不費事~)碳锈。下面開始正題顽冶。
在test-O文件夾里有AndroidManifest.xml,在里面看一下就知道售碳。我這里的主Activity為DeamonActivity,所在包為com.xxx.game.ui强重。對,包也要記住贸人,后面用得上间景!
-
編寫Java并轉Smali
還記得剛才找到的包名不?我的是com.xxx.game.ui∫罩牵現(xiàn)在我們新建一個Android工程倘要,并且新建com.xxx.game.ui包。我們的Activity和需要添加的類均在此包內創(chuàng)建(具體為什么我后面再解釋)十拣。這里看一下我寫好的幾個類:
LinkwebActivity內onCreate代碼:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
HttpRequester.sendGetHttp();
}
調用的方法必須靜態(tài)!靜態(tài)父晶!靜態(tài)哮缺!重要的事情說3遍!(原因我后面再解釋甲喝,我就不現(xiàn)在說~~不服你打我呀(?)?)
使用Java2Smali轉換java文件:
可以看到HttpRequester的smali有兩個尝苇,HttpReponser和LinkwebActivity的smali只有一個。這并不是轉換錯誤埠胖,而是因為HttpRequester的java文件中有對HttpResponser類的引用:
public HttpResponser sendPost(String urlString, Map<String, String> params)
throws IOException {
return this.send(urlString, "POST", params, null);
}
****$1.smali的代碼結構是比較復雜的糠溜,我們可以看一下:
.class final Lcom/xxx/game/ui/HttpRequester$1;
.super Ljava/lang/Object;
.source "HttpRequester.java"
# interfaces
.implements Ljava/lang/Runnable;
# annotations
.annotation system Ldalvik/annotation/EnclosingMethod;
value = Lcom/xxx/game/ui/HttpRequester;->sendGetHttp()V
.end annotation
.annotation system Ldalvik/annotation/InnerClass;
accessFlags = 0x8
name = null
.end annotation
# direct methods
.method constructor <init>()V
.registers 1
.prologue
.line 32
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
return-void
.end method
為了更容易修改apk內smali的代碼,我們應該避免LinkwebActivity的$1.smali文件的生成直撤,否則就需要修改Apk內DeamonActivity的$1.smali文件(代碼少還好改非竿,稍微多一點改起來就很恐怖了!)谋竖。這里就解釋了我為什么要把三個方法都放在com.xxx.game.ui包下,并且使用了靜態(tài)方法來調用红柱。
-
修改Apk內的smali文件
這里我們用Jeb打開apk,定位DeamonActivity的oncreate的smali具體在哪一行蓖乘,好做修改锤悄。
//java代碼
protected void onCreate(Bundle arg5) {
BroadcastReceiver v1 = null;
super.onCreate(arg5);
if(GameAssist.getInstance() == null) {
n.c("[onCreate] >>> instance==null");
this.c = v1;
this.a();
}
else if(GameAssist.getReady()) {
n.c("[onCreate] >>> instance get ready");
this.c = v1;
this.a();
}
}
//smali代碼
.method protected onCreate(Bundle)V
.registers 6
const/4 v1, 0x0
invoke-super Activity->onCreate(Bundle)V, p0, p1
invoke-static GameAssist->getInstance()GameAssist
move-result-object v0
if-nez v0, :2A
:14
const-string v0, "[onCreate] >>> instance==null"
invoke-static n->c(String)V, v0
iput-object v1, p0, DeamonActivity->c:BroadcastReceiver
invoke-direct DeamonActivity->a()V, p0
定位到需要修改的代碼位置后,我們在test-O/smali/com/xxx/game/ui/下打開DeamonActivity.smali文件添加代碼:
//LinkwebActivity中oncreate的smali代碼:
# virtual methods
.method protected onCreate(Landroid/os/Bundle;)V
.registers 2
.param p1, "savedInstanceState" # Landroid/os/Bundle;
.annotation build Landroid/support/annotation/Nullable;
.end annotation
.end param
.prologue
.line 16
invoke-super {p0, p1}, Landroid/app/Activity;->onCreate(Landroid/os/Bundle;)V
.line 17
invoke-static {}, Lcom/xxx/game/ui/HttpRequester;->sendGetHttp()V
.line 18
return-void
.end method
//DeamonActivity修改后的smali代碼
.method protected onCreate(Bundle)V
.registers 6
const/4 v1, 0x0
invoke-super Activity->onCreate(Bundle)V, p0, p1
invoke-static {}, Lcom/xxx/game/ui/HttpRequester;->sendGetHttp()V
invoke-static GameAssist->getInstance()GameAssist
move-result-object v0
if-nez v0, :2A
:14
const-string v0, "[onCreate] >>> instance==null"
invoke-static n->c(String)V, v0
iput-object v1, p0, DeamonActivity->c:BroadcastReceiver invoke-direct DeamonActivity->a()V, p0
只需要在Activity->onCreate后添加 invoke-static {}, Lcom/xxx/game/ui/HttpRequester;->sendGetHttp()V,然后直接保存嘉抒。接著把HttpRequest.smali零聚,HttpRequester$1.smali 和HttpResponser.smali都拷貝到目錄下即可。
-
finally
利用修改后的文件夾重建Apk-簽名-安裝到手機運行,抓包抓到我們寫入的httppost請求隶症,大功告成~~