標籤:源檔案 set xml檔案 代碼實現 source 結束 2016年 固定 工具
[toc]
#0x00 前言
##不知所以然,請看
Android逆向-Android基礎逆向(1)
Android逆向-Android基礎逆向(2)
##以及java系列:
Android逆向-java代碼基礎(1)
Android逆向-java代碼基礎(2)
Android逆向-java代碼基礎(3)
Android逆向-java代碼基礎(4)
Android逆向-java代碼基礎(5)
Android逆向-java代碼基礎(6)
Android逆向-java代碼基礎(7)
Android逆向-java代碼基礎(8)
由於之前的Android逆向-Android基礎逆向(2)的偽加密部分篇幅太長,導致其他內容沒有完成,所以才有了這裡的Android逆向-Android基礎逆向(2-2)。希望可以完成計劃中的內容。
##學習內容
(1)APK檔案偽加密√
(2)資源檔防反編譯
(3)apk打包流程
(4)apk反編譯流程
(5)apk回編譯流程、
#0x01 資源檔防反編譯
之前說過可以通過更改第四個欄位來進行防止一定程度的反編譯。那麼除了這種偽加密的方式,還有什麼方式可以防止這種偽加密的出現呢。
來看看資源檔是如何防止反編譯的。
自然我們需要研究一下xml檔案的格式。四哥在2016年已經分析過了,不過那是人家分析的,只看別人分析的不能進行更深入的學習。紙上得來終覺淺,絕知此事要躬行。so,就有了這篇。
##1.第一個模組
這裡對應使用一個執行個體分析,就用Android逆向-Android基礎逆向(1)中的簡單的apk來分析吧。
###1.1 Magic Number
這裡魔數是00 08 00 03,這個是一個固定的值。
###1.2File Size
這個就是用來確認檔案大小的。
這裡是00 00 07 90 ,也就是1970個bytes。
###1.3用python實現分析
四哥用java寫的,我就獻醜寫個python的,還在學習python的過程中,有什麼錯誤或者做的不好的地方,還請見諒。
這個是實現這個模組的代碼。但是感覺自己寫的好繁瑣,等一會兒適當修改一下。
2018年1月27日11:57:35,忙別的事情去了。
def fenxi(filename): try: f=open(filename,‘rb‘) print ‘start--------‘ i=0 p1="" p2="" p3="" p4="" p="" while True: t=f.read(1) t1=t.encode(‘hex‘) if i==0: p1=t1 if i==1: p2=t1 if i==2: p3=t1 if i==3: p4=t1 i=i+1 if i<4: p=p+" " if i==4: break pass p=p4+" "+p3+" "+p2+" "+p1 print "Magic Number:",p i=0 p1="" p2="" p3="" p4="" p="" while True: t=f.read(1) t1=t.encode(‘hex‘) if i==0: p1=t1 if i==1: p2=t1 if i==2: p3=t1 if i==3: p4=t1 i=i+1 if i<4: p=p+" " if i==4: break pass p=p4+" "+p3+" "+p2+" "+p1 print "FileSize:",p except IOError: print "This is bad for input ‘",name,"‘." print "You can enter -h for help."
2.第二個模組
###1.Chunk Type
String Chunk 的標識符,預設是00 08 00 03
2.Chunk Size
String Chunk的大小。
3.String Count
字串的個數。
4.Style Count
樣式的個數
5.Unknow
6.String Pool Offset
首部位移量,也就是String Chunk的位置。
7.Style Pool Offset
樣式位移,但是因為樣式沒有。所以這裡全部為0
8.String Offsets
這個是字串位移,大小就是String count*4個bytes
9.常量池
這個就是最主要的地方了。不過中間有一個0的Null 字元串。需要注意,然後使用一個迴圈就可以簡單的分析出來了。
這裡帖出代碼部分。
while True: t1=f.read(1) t2=f.read(1) tf1=t1.encode(‘hex‘) tf2=t2.encode(‘hex‘) p1=tf2+tf1 ph=int(p1, 16) p3="" i=0 while True: t=f.read(1) t1=t.encode(‘hex‘) p=int(t1, 16) p3=p3+chr(p) t=f.read(1) i=i+1 if i==ph: break pass print "first string:",p3 t=f.read(2) if l==12: t=f.read(4) l=l+1 if l==x-1: break
運行結果展示:
3.第三個模組 Resourceld Chunk
這個Chunk主要是存放的是AndroidManifest中用到的系統屬性值對應的資源Id
3.1 Chunk Type
和其他Chunk一樣,都有特徵值,Resourceld Chunk的特徵值是:0x00080108
3.2 Chunk Size
Size大小沒有什麼好解釋的。
3.3Resourcelds
這裡可以根據id在frameworks\base\core\res\res\values\public.xml中尋找到相對應的string。
一下是簡單的代碼模組:
a=p/4-2 i1=0 while True: i=0 p1="" p2="" p3="" p4="" p="" while True: t=f.read(1) t1=t.encode(‘hex‘) if i==0: p1=t1 if i==1: p2=t1 if i==2: p3=t1 if i==3: p4=t1 i=i+1 if i==4: break pass p=p4+p3+p2+p1 p5=p4+" "+p3+" "+p2+" "+p1 p=int(p, 16) print "123id:",p,"bytes","hex:",p5 i1=i1+1 if i1==a: break
4.第四個模組
這個Chunk主要包含一個AndroidManifest檔案中的命令空間的內容
4.1 Chunk Type
特徵碼,這裡不強調了。 特徵碼是00 10 01 00。
4.2 Chunk Size
Chunk的大小。
4.3 Line Number
在AndroidManifest檔案中的行號
4.4Unknown
未知地區,一般是ffff
4.5 Prefix
命名空間的首碼
4.6Uri
命名空間的Urk
5.第五個模組
這個模組主要是為了存放標籤資訊
這裡要囉嗦了。第五個模組要寫完的時候,突然滑鼠的返回鍵被按到了。我都在想是不是應該在本地寫了,而不是在雲端寫,太感人了這個。傷心。準備偷懶了。
5.1 Chunk Type
標誌欄位,固定字元。
00 10 01 02
5.2 Chunk Size
Chunk 大小
5.3 Line Number
行數,和上一個段一樣
5.4 Unknown
位置地區
5.5Namespace Uri
標籤用的uri,但是也有可能是返回 ff ff ff ff。
代碼實現:
i=0 p1="" p2="" p3="" p4="" p="" while True: t=f.read(1) t1=t.encode(‘hex‘) if i==0: p1=t1 if i==1: p2=t1 if i==2: p3=t1 if i==3: p4=t1 i=i+1 if i==4: break pass p=p4+p3+p2+p1 p=int(p, 16) try : print "Namespace Uri:",list[p] except IndexError: print "Namespace Uri is nothing"
5.6 name
標籤名稱欄位
5.7 flags欄位
標識是開始flags還是結束flags
5.8 Attribute Count
包含屬性的個數
5.9 Class Attribute
標籤包含的類屬性
5.10Attributes Attribute
屬性內容。包括NamespaceUri,Name,ValueString,type,Data,這五個欄位。
6.第六個模組
這個和第五個塊一樣。
7.第七個模組
因為是和之前的模組一樣這裡就不做解釋了
收穫
##python
1.python右移的方式
2.python格式轉換
3.對二進位模組分析
4.這個是最大的收貨,得到了一個xml檔案分析工具。
5.github地址:xml.py檔案分析
結束語
感覺這裡需要的內容很多,就得要分成很多小塊來說。為什麼這裡要寫關於xml的分析呢,因為加固的目的就是為了防止反編譯。那麼我們可以針對反編譯軟體進行針對化加固,在下一個小塊將會詳細講解。
Android逆向-Android基礎逆向(2-2)