Android反編譯基礎(apktoos)--廣工圖書館APK

更多精彩內容 :http://www.chenchuangfeng.comphp

QQ:375061590html

---------------------------------------------------------------------------------java

好久有寫過一個廣工圖書館主頁一個類爬蟲的demo(由於沒接口,只能扒取靜態網頁),實現一些圖書館系統的一些功能。但最近發現圖書館系統在html頁面上作了手腳,一頁html頁面中嵌入了幾千行的註釋,並有了本身的App,應該是爲了增長扒取的流量成原本防止別人去扒取網頁,不過加註釋這手段就不敢恭維了,內網訪問速度還行,但外網訪問的話體驗不好的。 android

 

以下圖:一堆註釋,致使一個網頁要2MB windows

dfe4342t5h5e6uw23t

 

       主頁上的APP,必然是用了圖書館的後臺接口和服務器交互的,從而想試試用反編譯的手段來看看APP使用了什麼接口。(另外更簡單能夠經過tcpdump來給Android手機抓包分析其接口,再用Wireshark來分析tcp包,不過你想要知道所有接口的話,可能須要一個個接口去調用,會比較麻煩,採用反編譯,可能集中在一個類中找到這些接口)。服務器

 

首先要準備的工具:(瞭解更多反編譯工具能夠去看雪論壇下載或者學習-Link)
app

    APKTool    點擊下載
異步

            APKTool是GOOGLE提供的APK編譯工具,須要JAVA運行環境。能夠對APK進行反編譯,使用它能夠將其反編譯成很是接近打包前的原始格式。逆向AndroidManifest.xml、資源文件 resources.arsc以及將dex文件反編譯成能夠調試的smali文件。修改後,能夠將其編譯回apk文件。APKTool也能夠用來漢化Android軟件而後從新打包發佈。 
官方:http://code.google.com/p/android-apktool/
tcp

 

    找本書APP  點擊下載
函數

 

    

 

    解壓縮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中的是同樣的,以下。

 

  • B---byte
  • C---char
  • D---double
  • F---float
  • I---int
  • J---long
  • S---short
  • V---void
  • Z---boolean
  • [XXX---array
  • Lxxx/yyy---object

 

    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++的箭頭操做符,後面是類中的變量或者方

        法vBarCodesClassSystem中的一個變量,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,targeteq: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,targetnez :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

---------------------------------------------------------------------------------

相關文章
相關標籤/搜索