關於pyc檔案的逆向
最近感覺遇到的pyc檔案逆向的越來越多了,所以就來總結下。//參考了大佬的blog:
0x1 pyc的檔案結構
在命令列輸入 python -m filename.py的時候,便會得到乙個對應的filename.pyc。
拖進hxd中看二進位制。其中,開頭的4個位元組是magic number,相對比較固定,是標識的此pyc的版本資訊,不同的版本的magic在python/import.c中定義。
而之後4個位元組是小端序的時間戳。
之後的位元組是個0x63,也就是pycodeobject的識別符號,隨後是小端序的co_argument(引數個數),co_nlocals(變數個數),co_stacksize(棧空間)和co_flags(特殊標誌)特殊標誌的flags:
#define co_optimized 0x0001之後是opcode,先是0x73,之後接4個位元組的小端序的數字,表示opcode所佔的總的位元組//在我的個人理解中,opcode跟我們用c之類的編寫的反編譯出來的彙編差不多。#define co_newlocals 0x0002
#define co_varargs 0x0004
#define co_varkeywords 0x0008
#define co_nested 0x0010
#define co_generator 0x0020
#define co_nofree 0x0040
#define co_future_division 0x2000
#define co_future_absolute_import 0x4000
#define co_future_with_statement 0x8000
#define co_future_print_function 0x10000
#define co_future_unicode_literals 0x20000
之後,乙個位元組表示儲存的型別,之後四個位元組表示該型別佔的空間(小端序表示)(例如如果是小端序的0x40,那之後的0x40個位元組就是他儲存的內容)以此類推。繼續從大佬blog中拖資料型別標識:
#define type_null 『0』0x2 pyc檔案反編譯的常用工具#define type_none 『n』
#define type_false 『f』
#define type_true 『t』
#define type_stopiter 『s』
#define type_ellipsis 『.』
#define type_int 『i』
#define type_int64 『i』
#define type_float 『f』
#define type_binary_float 『g』
#define type_complex 『x』
#define type_binary_complex 『y』
#define type_long 『l』
#define type_string 『s』
#define type_interned 『t』
#define type_stringref 『r』
#define type_tuple 『(』
#define type_list 『[』
#define type_dict 『{』
#define type_code 『c』
#define type_unicode 『u』
#define type_unknown 『?』
#define type_set 『<』
#define type_frozenset 『>』
最常用的就是uncompyle6,用uncompyle6 -o filename.py filename.pyc這個命令就可以了,當然,在網上也有一些把uncompyle6這種工具開出gui介面的,這個自行搜尋。
0x3 出現反編譯失敗的情況
以hgame的pro的python教室(三&四)為例子
先檢視發現magic number之類的沒有錯,這裡介紹乙個叫marshal的py庫,使用如下:
import dis,marshalf = open(「third.pyc」, 「rb」)
magic = f.read(4)
mtime = f.read(4)
dis.dis(marshal.load(f)),
在偏移13的位置出現了load_const 100,然後,py返回錯誤。
來看下這邊的opcode的表達:
0 jump_absolute 3
3 jump_absolute 9
6 load_const 15 ("you』re wrong! ")
9 jump_absolute 14
12 print_item
13 load_const 100
好的,有個load_const 100的操作,這個是溢位了範圍的,但是在這上面有個jump 14的操作,所以其實12,13根本就不會執行(其實這也是一種常見的防反編譯的方法,在程式中加入一段跳轉到不存在的地方的操作,但是這個操作正常執行根本不會執行,所以程式執行沒有一點毛病,但是反編譯工具卻無法進行下去了。也就是花指令了)那麼就可以直接把它刪了,外加改下其他的定義的長度,使得符合上述的規則就ok了。
此外,還有那些用py檔案編譯出的exe檔案,這些檔案一般是用py extractor這個工具來進行反編譯。
逆向 簡單的pyc
這個是i c的比賽逆向題目 比賽還沒結束qaq 題目內容很簡單 提示說要逆向乙個pyc 直接拉進去 執行 得到如下內容 import base64 def encode message s for i in message x ord i 32 x x 16 s chr x return base6...
180627 逆向 pyc還原指令碼
針對suctf的python 好一題,通過解析內容還原pyc的指令碼 對於不同的解析內容需要另加修改,但原理一致 將元素按照 格式識別符號 len 內容的形式遞迴填入即可 值得說明的一點是指令碼無法還原出原來一模一樣的pyc,但可以還原出相同的py檔案 這是因為python在編譯pyc的時候,會將一...
pyc逆向之opcode簡單置換
最近做了一道pyc的逆向題,主要難點在於python環境的opcode被置換,就簡單記錄一下相關知識。opcode其實是指python原始碼的操作碼,python源 py編譯後可以得到二進位制檔案 pyc,pyc檔案中就含有opcode序列。對於不同版本的python,其opcode是不完全相同的,...