更多精彩內容 :http://www.chenchuangfeng.comphp
QQ:375061590html
---------------------------------------------------------------------------------java
好久有寫過一個廣工圖書館主頁一個類爬蟲的demo(由於沒接口,只能扒取靜態網頁),實現一些圖書館系統的一些功能。但最近發現圖書館系統在html頁面上作了手腳,一頁html頁面中嵌入了幾千行的註釋,並有了本身的App,應該是爲了增長扒取的流量成原本防止別人去扒取網頁,不過加註釋這手段就不敢恭維了,內網訪問速度還行,但外網訪問的話體驗不好的。 android
主頁上的APP,必然是用了圖書館的後臺接口和服務器交互的,從而想試試用反編譯的手段來看看APP使用了什麼接口。(另外更簡單能夠經過tcpdump來給Android手機抓包分析其接口,再用Wireshark來分析tcp包,不過你想要知道所有接口的話,可能須要一個個接口去調用,會比較麻煩,採用反編譯,可能集中在一個類中找到這些接口)。服務器
首先要準備的工具:(瞭解更多反編譯工具能夠去看雪論壇下載或者學習-Link)
app
APKTool是GOOGLE提供的APK編譯工具,須要JAVA運行環境。能夠對APK進行反編譯,使用它能夠將其反編譯成很是接近打包前的原始格式。逆向AndroidManifest.xml、資源文件 resources.arsc以及將dex文件反編譯成能夠調試的smali文件。修改後,能夠將其編譯回apk文件。APKTool也能夠用來漢化Android軟件而後從新打包發佈。
官方:http://code.google.com/p/android-apktool/
tcp
解壓縮APKTool,並把要反編譯的APK放入目錄中
反編譯:
經過CMD進入上面的目錄,執行命令: apktool decode ZhaoBenShu.apk outdir
稍等片刻完成反編譯,反編譯後的文件會在outdir目錄下。
---outdir目錄結構
res :資源文件,跟adnroid工程目錄下的res基本同樣,各類UI圖片 XML佈局文件 values xml文件(多了一個public.xml,有各個資源的id號(R.java中的id))
smail:這個是重點文件夾,裏面都是smail格式文件,是Dalvik虛擬機執行的操做碼(Dalvik opcodes),這些操做嗎有本身的語法,若是有學過JNI的話, 這些語法仍是比較容易看懂和理解的。
AndroidManifest.xml:Android工程下的AndroidManifest.xml
apktool.yml:用於重打包。
smail語法:(所有語法請link)
smail中的數據類型簽名跟java中的是同樣的,以下。
smail代碼例子:
初看smail文件,可能會以爲有一些凌亂。不過只要把幾種語法弄懂了,就能夠很好地閱讀smail文件。
smail比較經常使用語法 ( 非所有)分爲: 賦值,取值,函數調用,if語句,返回值等。
賦值取值:
例子: iget-object v6, p0, Lcom/zbsh/code/clas/ClassSystem$9;->val$vBarCodes:Ljava/util/ArrayList;
分析:
iget個取值操做,i=instance,是用來instance filed(實例變量),object是類的意思。 v6是本地寄存器,p0在這裏是表明this(在非static函數正表明this,在static函數中
表明第一個參數)。Lcom/zbsh/code/clas/ClassSystem是表示包路徑爲 Lcom/zbsh/code/clas下的ClassSystem類,->至關於C/C++的箭頭操做符,後面是類中的變量或者方
法vBarCodes是ClassSystem中的一個變量,Ljava/util/ArrayList是vBarCodes這個變量的類型 (是java中類的簽名)
做用:
把ClassSystem中vBarCodes的值存放在寄存器v6中,vBarCodes的類型必須是對象,且是實例變量非靜態變量。
其中object能夠是替換成基本數據類型:iget-boolean iget-byte iget-char iget-short等等。
一樣的:
sget- [type]用來獲取static變量。(少了一個p0,由於靜態變量是沒有this的)
aget-[type]用來獲取array類型。
[x]get vx, vy,把寄存器vy中的值賦給vx。
賦值:
一樣都有如下幾種:
iput-[type]
sput-[type]
aput-[type]
也支持寄存器和寄存器之間的賦值,寄存器和變量之間的賦值。
函數調用:
invoke-direct 調用private函數
invoke-super 調用父類函數
invoke-static 調用靜態函數
invoke-virtual 用於調用protected或public函數(至關於C++的虛函數,java的重載函數,只有protect和public可以重載)
還有一種比較特殊的:invoke-xxxxx/range:參數多於5個的時候,要加/rang
例子:
invoke-virtual {v4, v1}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z
v4是this,表明 Ljava/lang/String的一個實例,v1是函數的第一個參數,在這裏是調用放在V4寄存器中類型爲Ljava/lang/String的實例的equal ()方法,並傳入參數v1,返回的結果是Z類型,也就是boolean類型。
若是是invoke-static{v4, v1}, 不一樣遇在於invoke-virtual {v4, v1}的是v4不是this,而是第一個參數。v1是第二個參數,所調用的方法須要兩個參數。
返回值:
獲取返回值:
move-result vx :把上一個方法返回的值,存在寄存器 vx中。
返回返回值:
return-void 沒返回。
return vx 返回寄存器中vx的值 。
if語句:
if-eq vx,vy,target:eq:equal 若是vx==xy 跳轉到target目標代碼,不然執行順序執行下一句代碼
if-ne vx,vy,target:nq :not equal 若是vx!=xy 跳轉到target目標代碼,不然執行順序執行下一句代碼
if-eqz vx,target:eqz : equal zero 若是vx==0 跳轉到target目標代碼,不然執行順序執行下一句代碼
if-nez vx,target:nez :not equal zero 若是vx!=0 跳轉到target目標代碼,不然執行順序執行下一句代碼
讀smail,找接口:
以搜索接口爲例子:
根據文件命名找到GropZbshFind.smali這個文件,應該就是搜索Activity。
在其中有一段代碼:
# virtual methods .method public onCreate(Landroid/os/Bundle;)V .locals 3 .parameter "savedInstanceState" .prologue .line 13 invoke-super {p0, p1}, Lcom/zbsh/code/thrd/GroupActivity;->onCreate(Landroid/os/Bundle;)V .line 14 const-class v0, Lcom/zbsh/code/ZbshFindMain; invoke-virtual {v0}, Ljava/lang/Class;->getName()Ljava/lang/String; move-result-object v0 new-instance v1, Landroid/content/Intent; const-class v2, Lcom/zbsh/code/ZbshFindMain; invoke-direct {v1, p0, v2}, Landroid/content/Intent;->(Landroid/content/Context;Ljava/lang/Class;)V invoke-virtual {p0, v0, v1}, Lcom/zbsh/code/GropZbshFind;->startChildActivity(Ljava/lang/String;Landroid/content/Intent;)V .line 15 return-void .end method
很明顯是經過startActivity來啓動ZbshFindMain這個Activity,
在ZbshFindMain中找到Onclick方法。
# virtual methods .method public onClick(Landroid/view/View;)V .........省略一坨代碼........... iget-object v0, v5, Lcom/zbsh/code/clas/ClassSystem;->ipAddress:Ljava/lang/String; .line 199 .local v0, ipAddress:Ljava/lang/String; new-instance v5, Ljava/lang/StringBuilder; invoke-static {v0}, Ljava/lang/String;->valueOf(Ljava/lang/Object;)Ljava/lang/String; move-result-object v6 invoke-direct {v5, v6}, Ljava/lang/StringBuilder;->(Ljava/lang/String;)V const-string v6, "Find/GetBookList.aspx?a=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "gdut" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "&b=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v6 iget-object v5, p0, Lcom/zbsh/code/ZbshFindMain$4;->this$0:Lcom/zbsh/code/ZbshFindMain; invoke-virtual {v5}, Lcom/zbsh/code/ZbshFindMain;->getApplication()Landroid/app/Application; move-result-object v5 check-cast v5, Lcom/zbsh/code/clas/ApplZbsh; iget-object v5, v5, Lcom/zbsh/code/clas/ApplZbsh;->iSystem:Lcom/zbsh/code/clas/ClassSystem; iget-object v5, v5, Lcom/zbsh/code/clas/ClassSystem;->searchType:Ljava/lang/String; invoke-virtual {v6, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "&c=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v6 iget-object v5, p0, Lcom/zbsh/code/ZbshFindMain$4;->this$0:Lcom/zbsh/code/ZbshFindMain; invoke-virtual {v5}, Lcom/zbsh/code/ZbshFindMain;->getApplication()Landroid/app/Application; move-result-object v5 check-cast v5, Lcom/zbsh/code/clas/ApplZbsh; iget-object v5, v5, Lcom/zbsh/code/clas/ApplZbsh;->iSystem:Lcom/zbsh/code/clas/ClassSystem; iget-object v5, v5, Lcom/zbsh/code/clas/ClassSystem;->inputKeywords:Ljava/lang/String; invoke-virtual {v6, v5}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "&d=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 sget v6, Lcom/zbsh/code/clas/ClassDataParameter;->count:I invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; move-result-object v5 const-string v6, "&e=" invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder; move-result-object v5 sget v6, Lcom/zbsh/code/clas/ClassDataParameter;->page:I invoke-virtual {v5, v6}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder; move-result-object v5 invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String; move-result-object v3 .line 201 .local v3, urlPath:Ljava/lang/String; iget-object v5, p0, Lcom/zbsh/code/ZbshFindMain$4;->this$0:Lcom/zbsh/code/ZbshFindMain; invoke-virtual {v5}, Lcom/zbsh/code/ZbshFindMain;->getApplication()Landroid/app/Application; move-result-object v5 check-cast v5, Lcom/zbsh/code/clas/ApplZbsh; iget-object v5, v5, Lcom/zbsh/code/clas/ApplZbsh;->iSystem:Lcom/zbsh/code/clas/ClassSystem; iget-object v6, p0, Lcom/zbsh/code/ZbshFindMain$4;->this$0:Lcom/zbsh/code/ZbshFindMain; iget-object v6, v6, Lcom/zbsh/code/ZbshFindMain;->mUIHandler:Landroid/os/Handler; invoke-virtual {v5, v0, v3, v6}, Lcom/zbsh/code/clas/ClassSystem;->GetFindOnThread(Ljava/lang/String;Ljava/lang/String;Landroid/os/Handler;)V
上面這段代碼,實現的是經過StringBuilder,經過append方法,拼成一個地址出來,再調用ClassSystem;->GetFindOnThread這個方法,傳入參數,進行一個異步圖書搜索的任務。
再從ClassDataParameter.smali中找到一些定義host地址常量。
.line 20 const-string v0, "http://59.41.253.11:7778/" sput-object v0, Lcom/zbsh/code/clas/ClassDataParameter;->IPADDRESS_TEL:Ljava/lang/String; .line 21 const-string v0, "http://222.200.98.173:7778/" sput-object v0, Lcom/zbsh/code/clas/ClassDataParameter;->IPADDRESS_EDU:Ljava/lang/String
咱們能夠拼出圖書搜索的接口是:http://222.200.98.173:7778/Find/GetBookList.aspx?a=&b=1&c=java&d=40&e=100
返回的是Json數據格式化下:
{ "error": "0", "findtotal": "1612", "findcache": "20131124024041.htm", "find_list": [ { "CtrlNo": "70658", "Isbn": "7-301-03477-6 ", "Title": "Java教程(Internet面向對象程序設計)", "Author": "Mary Campione", "Edition": " ", "Publisher": "北大版", "PubDate": "97.12" }, { "CtrlNo": "70657", "Isbn": "7-301-03476-8 ", "Title": "Java類手冊", "Author": "Patrick Chan", "Edition": " ", "Publisher": "北大版", "PubDate": "97.12" }, { "CtrlNo": "605337", "Isbn": "978-7-115-30271-7 ", "Title": "Java 7基礎教程= Java 7 for absolute beginners", "Author": "(美) Jay Bryant著;李鵬, 韓智譯", "Edition": " ", "Publisher": "人民郵電出版社", "PubDate": "2013.01" }, { "CtrlNo": "604835", "Isbn": "978-7-302-30346-6 ", "Title": "Java改錯學習法 [專著]", "Author": "朱福喜編著", "Edition": " ", "Publisher": "清華大學出版社", "PubDate": "2013" } ] }
其次:
還能夠經過反編譯更強大的用處是用來修改smali代碼,再重打包apk,來破解一些收費軟件,去除廣告之類,或者瞭解一些優秀軟件的實現邏輯。
--------------------------------------------------------------------------------
更多精彩內容 :http://www.chenchuangfeng.com
QQ:375061590
---------------------------------------------------------------------------------