摘要:閑來無事,學習了下安卓的逆向工程,有助于觀摩學習他人的優秀代碼,查詢了解后發現大體包括兩部分反編譯,即語法學習層,匯編學習。不多說,做過安卓開發都可以改,重點是的閱讀修改。想要深入了解相關知識,可以百度關鍵字安卓,安卓,安卓,安卓。
閑來無事,學習了下安卓的逆向工程,有助于觀摩學習他人的優秀代碼,查詢了解后發現大體包括兩部分:
1.dex反編譯,即smali語法學習;
2.Native層,arm匯編學習。
java環境不多說
1.apktool.jar;
2.jd-gui.jar;
3.dex2jar.zip;
這里就不提供了,畢竟自己動手,豐衣足食,建議百度下載最新的版本,舊版本可能會有bug。
假設現在有一個test.apk,如果我們想要查看一個apk里的java源碼,就可以通過解壓apk文件得到dex文件,然后使用dex2jar.zip工具包中的d2j-dex2jar.bat將dex轉為jar文件:
將classes.dex拖動到d2j-dex2jar.bat上,得到classes-dex2jar.jar,使用jd-gui.jar打開就可以查看源碼了:
反編譯但是jar文件只能輔助我們查看java代碼,無法修改。想要修改的話,還是要反編譯出smali文件,然后對smali文件進行修改操作,使用下邊的命令反編譯apk:
apktool.jar d test.apk
然后會在當前目錄生成test目錄,目錄內容大體如下:
assets資源目錄,包含了圖片和字體等資源;
build和dist為重新編譯生成的,新apk在dist目錄;
lib為so文件目錄;
original保存了原簽名和反編譯前的清單文件;
res主要為layout,strings等xml文件;
unknown不用管;
下邊是AndroidManifest.xml,清單文件,已經可以打開查看了;
然后最重要的來了smali和smali_classes2,apk中的每個dex文件會反編譯出一個smali文件夾,classes.dex對應smali,classes2.dex對應smali_classes2,以此類推。
知道了這些后,就可以查看修改我們想要的內容了。AndroidManifest.xml不多說,做過安卓開發都可以改,重點是smali的閱讀修改。首先打開smali文件夾內容如下:
由于現在apk編譯時普遍會進行混肴,以防他人修改二次發布,所以目錄結構有些亂,但并無大礙。
隨手打開一個smali文件(sublime,已安裝smali插件):
嗯,看不懂,沒事現在學還來得及,你需要了解下smali語法,傳送門:APK反編譯之一:基礎知識--smali文件閱讀。
smali修改簡單示例:
上圖為原java代碼,下圖是反編譯出的smali代碼,此方法用來判斷外置儲存是否可讀。
現在無論外置存儲是否可讀,我們都想讓此方法返回true,則可以在smali代碼中的return v1前加上一行const/4 v1, 0x1,如下圖:
是不是非常簡單?當然,這只是最簡單的修改,一切都建立在深入地學習和了解過smali語法的基礎上。
Native層,arm匯編安卓native層,通俗來說就是對lib目錄下的so文件學習和了解,so文件是Android NDK動態鏈接庫,是二進制文件,作用相當于windows下的.dll文件。想要深入了解相關知識,可以百度關鍵字:‘安卓 native’,‘安卓 JNI’,‘安卓 ELF’,‘安卓 NDK’。
不同的cpu構架so通常是針對不同的cpu構建編譯而成的,如下圖:
arm64-v8a:arm最新的64cpu構架,如驍龍810,820,835等都是基于此構架的,同時兼容A32,T32指令集;
armeabi-v7a:32位cpu構架,如驍龍800,801等,兼容armv5,armv6;
armeabi:armv5,armv6構架,基本已經淘汰了;
x86:intel的32位cpu構架,即windows平臺的32位cpu構架;
x86_64:其實是amd出的兼容64位的32位cpu構架;
arm構架都是向下兼容的,例如如果CPU是armv8,沒有對應arm64-v8a文件夾,則會執行armeabi-v7a中的so文件。
話不多說,開始研究修改so文件吧,首先使用010 editor或ida打開armeabi下的so(elf)文件(這里使用ida),彈出界面直接點擊ok,進入如下頁面:
要了解elf文件的詳細信息可以查看:ARM平臺下elf文件超詳細的分析與解讀,elf文件的解析這里不做更多說明。如果你跟我一樣,別的什么也不想看,就想知道怎么修改so,那么下面我們就來看看怎么修改arm匯編的機器碼,來達到修改so文件的目的。
修改前的準備工作1.了解二進制文件的大小端模式,傳送門:詳解大端模式和小端模式;
2.了解寄存器相關知識,了解arm32位和64位寄存器的區別,特別是lr,sp,pc等關鍵寄存器的作用;
3.arm指令集學習,包括32位指令(A32,T32)和64位指令(A64),這里不上鏈接了,因為太多了,具體建議百度自查;
4.下載arm官網cpu構架手冊,修改時需要對應查看,鏈接:A-Profile Architecture,我們主要查看a系列的構架手冊,主要下載的文件:
Arm? Architecture Reference Manual Armv8, for Armv8-A architecture profile Arm? Architecture Reference Manual Armv7-A and Armv7-R edition The A64 instruction set
第一本是關于A64指令集的手冊,其實也包含了A32和T32指令集,第二本是armv7構架,包含了ARM指令和Thumb指令,第三本介紹了A64指令。
5.熟練進行進制轉換,可以使用win10自帶的計算器的程序員模式。
- 32位
以下內容建立在以上知識的基礎上,開始修改,接著我們打開的so頁面(armeabi-v7a),滾動到匯編代碼區域,如下圖:
例如想要修改Ox00005EE8處的關鍵跳轉BEQ loc_5EFA為BNE loc_5EFA,通過匯編代碼知道,此處用R0寄存器中的值和2比較大小,如果R0中的值等于2,跳轉到下邊的loc_5EFA處:
雙擊此行,然后點擊Hex View-1標簽可以看到對應的機器碼:
由于elf的存儲模式是小端模式(Little-endian),故實際的機器碼是D0 07,轉換為二進制:?1101 0000 0000 0111?,可以看出是16位的Thumb指令,打開armv7構架手冊(armv8也可以),找到指令集部分:
如上圖,此機器碼對應紅框中的編碼方式,要修改BEQ為BNE,則需要修改8-11位的條件位,立即數保持不變:
上圖可以查出EQ的機器碼為0000,NE機器碼則是0001,因此修改后的機器碼為?1101 0001 0000 0111,再轉換回16進制為?D1 07?,小端存儲07 D1,按如下步驟,右鍵點擊修改:
修改完后右鍵點擊應用修改:
然后返回IDA View-A視圖,可以看到BEQ loc_5EFA已經改為了BNE loc_5EFA:
- 64位
下邊嘗試下修改64位構架下的so文件,64位的so必須用64位的ida打開:
如上圖,我們修改紅框中的代碼,改為:
CMP W1, #1 B.LT loc_1B5C
CMP W0, #0的機器碼為?0111 0001 0000 0000 0000 0000 0001 1111?,查看armv8a手冊:
寄存器w0改成w1,只需將5-9位改為00001。立即數#0改為#1,需要將10-21位改為00 0000 0000 01,改完后機器碼變為?0111 0001 0000 0000 0000 0100 0011 1111?,轉換為16進制后:?71 00 04 3F,小端模式3F 04 00 71?;
B.GT loc_1B10的機器碼?0101 0100 1111 1111 1111 1110 0000 1100?,編碼方式如下:
B.GT改為B.LT,即修改0-3位為1011。
原立即數1111 1111 1111 1110 000,補碼轉為原碼為1001 0000,即-16。
偏移量計算方法為:offset = SignExtend(imm19:"00", 64),也就是19位的立即數后邊拼接00(左移2位),變為1111 1111 1111 1110 000 00,然后有符號擴展為64位(對于負數,前邊補1,補足64位),變為?1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1100 0000?,此為補碼,轉為原碼1100 0000,即-64。正如紅框中的所述,是立即數的4倍。
此處要改為loc_1B5C,即偏移量為+12,則立即數為+12/4 = +3,5-23位的立即數變為0000 0000 0000 0000 011。
最終機器碼為?0101 0100 0000 0000 0000 0000 0110 1011,轉換16進制?54 00 00 6B?,小端模式6B 00 00 54。
然后,修改應用后查看結果:
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/68115.html
閱讀 1737·2021-10-18 13:30
閱讀 2613·2021-10-09 10:02
閱讀 2968·2021-09-28 09:35
閱讀 2093·2019-08-26 13:39
閱讀 3525·2019-08-26 13:36
閱讀 1954·2019-08-26 11:46
閱讀 1138·2019-08-23 14:56
閱讀 1699·2019-08-23 10:38