1. 程式人生 > 實用技巧 >對流氓APP——一份禮物.apk的逆向分析

對流氓APP——一份禮物.apk的逆向分析

  1. 拿到apk ,第一步肯定先放到虛擬機器裡跑一下看下效果,emmm這似曾相識的頁面,這熟悉的音量,唯一變化的就是音樂變成了O泡果奶的魔性洗腦廣告,懂了,不就是 "送給最好的ta.apk" 嗎?

  2. 使用Android killer或apk改之理分析一下,這裡使用Android Killer:

  3. 通過對比送給最好的ta.apk發現:多了一個layout.lua檔案 不過從名字上看這就是個佈局檔案,影響不大,再就是mp3檔名字從原來的0.mp3改為了mc.mp3,其他的都沒變 甚至軟體圖示都沒變.

  4. 剩下的就簡單了,雖然lua檔案是加密過的,但是盲猜加密方式也沒變,因此白嫖pcat大佬的解密指令碼:

    from ctypes import *
    import sys
    
    def decrypt(filename):
        s = open(filename, 'rb').read()
        outfile = 'out.lua'
        if s[0] == chr(0x1b) and s[1] != chr(0x4c):
            rst = chr(0x1b)
            size = len(s)
            v10 = 0
            for i in range(1, size):
                v10 += size
                v = (c_ulonglong(-2139062143 * v10).value >> 32) + v10
                v1 = c_uint(v).value >> 7
                v2 = c_int(v).value < 0
                rst += chr(ord(s[i]) ^ (v10 + v1 + v2) & 0xff)
            with open(outfile, 'wb') as f:
                f.write(rst)
        else:
            pass
    
    def foo():
        print len(sys.argv)
        if len(sys.argv) == 2:
            filename = sys.argv[1]
        else:
            filename = 'main.lua'
        decrypt(filename)
    
    if __name__ == '__main__':
        foo()
    
    
  5. 將得到的檔案使用unluac.jar進行還原,最終得到三個lua檔案分別為:

    init.lua:

    local L0, L1
    appname = "\230\143\146\228\187\1829.0"
    appver = "9.0"
    packagename = "com.ta.cnm"
    appcode = "9"
    appsdk = "15"
    theme = "Theme_DeviceDefault_Light_NoActionBar"
    L0 = {}
    L1 = "WRITE_EXTERNAL_STORAGE"
    L0[1] = L1
    user_permission = L0
    

    main.lua:

    local L0, L1, L2, L3
    L0 = require
    L1 = "import"
    L0(L1)
    L0 = import
    L1 = "android.app.*"
    L0(L1)
    L0 = import
    L1 = "android.os.*"
    L0(L1)
    L0 = import
    L1 = "android.widget.*"
    L0(L1)
    L0 = import
    L1 = "android.view.*"
    L0(L1)
    L0 = import
    L1 = "android.view.View"
    L0(L1)
    L0 = import
    L1 = "android.content.Context"
    L0(L1)
    L0 = import
    L1 = "android.media.MediaPlayer"
    L0(L1)
    L0 = import
    L1 = "android.media.AudioManager"
    L0(L1)
    L0 = import
    L1 = "com.androlua.Ticker"
    L0(L1)
    L0 = activity
    L0 = L0.getSystemService
    L1 = Context
    L1 = L1.AUDIO_SERVICE
    L0 = L0(L1)
    L0 = L0.setStreamVolume
    L1 = AudioManager
    L1 = L1.STREAM_MUSIC
    L2 = 15
    L3 = AudioManager
    L3 = L3.FLAG_SHOW_UI
    L0(L1, L2, L3)
    L0 = activity
    L0 = L0.getDecorView
    L0 = L0()
    L0 = L0.setSystemUiVisibility
    L1 = View
    L1 = L1.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    L2 = View
    L2 = L2.SYSTEM_UI_FLAG_IMMERSIVE
    L1 = L1 | L2
    L0(L1)
    L0 = MediaPlayer
    L0 = L0()
    m = L0
    L0 = m
    L0 = L0.reset
    L0()
    L0 = m
    L0 = L0.setDataSource
    L1 = activity
    L1 = L1.getLuaDir
    L1 = L1()
    L2 = "/mc.mp3"
    L1 = L1 .. L2
    L0(L1)
    L0 = m
    L0 = L0.prepare
    L0()
    L0 = m
    L0 = L0.start
    L0()
    L0 = m
    L0 = L0.setLooping
    L1 = true
    L0(L1)
    L0 = Ticker
    L0 = L0()
    ti = L0
    L0 = ti
    L0.Period = 10
    L0 = ti
    function L1()
      local L0, L1, L2, L3
      L0 = activity
      L0 = L0.getSystemService
      L1 = Context
      L1 = L1.AUDIO_SERVICE
      L0 = L0(L1)
      L0 = L0.setStreamVolume
      L1 = AudioManager
      L1 = L1.STREAM_MUSIC
      L2 = 15
      L3 = AudioManager
      L3 = L3.FLAG_SHOW_UI
      L0(L1, L2, L3)
      L0 = activity
      L0 = L0.getDecorView
      L0 = L0()
      L0 = L0.setSystemUiVisibility
      L1 = View
      L1 = L1.SYSTEM_UI_FLAG_HIDE_NAVIGATION
      L2 = View
      L2 = L2.SYSTEM_UI_FLAG_IMMERSIVE
      L1 = L1 | L2
      L0(L1)
    end
    L0.onTick = L1
    L0 = ti
    L0 = L0.start
    L0()
    function L0(A0, A1)
      local L2, L3, L4, L5
      L2 = string
      L2 = L2.find
      L3 = tostring
      L4 = A1
      L3 = L3(L4)
      L4 = "KEYCODE_BACK"
      L2 = L2(L3, L4)
      if L2 ~= nil then
        L2 = activity
        L2 = L2.getSystemService
        L3 = Context
        L3 = L3.AUDIO_SERVICE
        L2 = L2(L3)
        L2 = L2.setStreamVolume
        L3 = AudioManager
        L3 = L3.STREAM_MUSIC
        L4 = 15
        L5 = AudioManager
        L5 = L5.FLAG_SHOW_UI
        L2(L3, L4, L5)
      end
      L2 = true
      return L2
    end
    onKeyDown = L0
    

    layout.lua:

    local L0, L1, L2, L3
    L0 = {}
    L1 = LinearLayout
    L0.layout_width = "fill"
    L0.layout_height = "fill"
    L2 = {}
    L3 = Button
    L2.textColor = "#D50000"
    L2.text = "\230\131\138\228\184\141\230\131\138\229\150\156 \230\132\143\228\184\141\230\132\143\229\164\150"
    L2.layout_height = "match_parent"
    L2.layout_width = "match_parent"
    L2.background = "#88888888"
    L2[1] = L3
    L0[1] = L1
    L0[2] = L2
    return L0
    
    
  6. 分析這三個檔案:

    init.lua: 定義了app的名字,版本(已經是9.0了嗎),包名(有點暴躁啊這位老哥),sdk版本,使用的主題,需要的許可權等資料

    main.lua:具體邏輯都在這裡面:讀取mc.mp3 播放 並一直把音量調整到15(最大),監聽禁用返回按鈕.

    layout.lua:設定頁面佈局

  7. 分析完畢.解決