so加載流程分析
前言同樣是在研究360加固,對so加載的理解不夠深刻,特此分析記錄完整的so加載流程。
注:分析的AOSP版本是Oreo8.1.0_r33。
So加載流程System.loadLibrary與System.loadloadLibrary:傳入的是一個so的名稱,如libtest.so,這個so通常位於/data/app/<pkg>/lib/<arch>下。
load:傳入的是so的絕對地址。
兩者的執行流程其實沒有太大差異,最終都會調用Runtime_nativeLoad,本文以System.load作為起始點,一步一步分析下去。
1234567891011// libcore/ojluni/src/main/java/java/lang/System.java@CallerSensitivepublic static void loadLibrary(String libname) { Runtime.getRuntime().loadLibrary0(Reflection.getCallerClass(), libname);}@C ...
elf文件結構
前言在研究360加固時,發現自己對elf文件完全不理解,於是決定先好好學下elf文件結構。
本文以AOSP版本Oreo8.1.0_r33作為研究對象,由上到下逐漸解析一個so文件。
Elf Header32位elf文件的Elf Header的結構體是Elf32_Ehdr,64位基本一致,除了e_ident[4]。
同時也列出一些會用到的常量( 宏定義/枚舉值 )如下:
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556/*=================== art/runtime/elf.h ===================*/struct Elf32_Ehdr { unsigned char e_ident[EI_NIDENT]; // ELF Identification bytes Elf32_Half e_type; // Type of file (see ET_* below) ...
ollvm_bcf_anti
一、通過IDA Python Patch思路1:直接patch用到不透明謂詞的地方原理說明:
所謂不透明謂詞是指在跳轉前就已經確定的表達式,但IDA無法分析。
通過對不透明謂詞進行交叉引用會發現,沒有任何一處是賦值,全都是LDR,而且這些不透明謂詞通常會定義在.bss段,默認值為0。
下圖的x_70是一個不透名謂詞,通過上述分析可以知道它其實永遠都為0,但可惜IDA不知道。
因此patch的目標就是直接將其賦為0,讓IDA可以分析出來。
觀察匯編代碼可以發現,x_70最終通過LDR W9, [X9]賦給W9寄存器。
因此只需要將其修改成mov w9, 0即可
最後的問題就是如何從LDR W9, [X9] → mov w9, 0?
通過IDA的Keypatch插件不斷修改來發現機械碼的變化規律,如下所示:
12345678910111213# 40 B9 代表 ldr reg1, [reg2]# 第1、2字節要合起來用小端來看(記作num)# reg2 + 1 -> num += 0x20# reg1 + 1 -> num += 1LDR W0, [X0] -> ...
B站sign算法分析
Target目標是如下的sign參數,很多接口都需要這個參數,隨即找一個來分析就可以
關鍵點定位方法一:字符串搜索不能直接搜sign,因為會出現很多結果,難以肉眼看出。
要嘗試這樣搜索:"sign、sign"、sign=、&sign
最終可以定位到com.bilibili.nativelibrary.LibBili類的s函數,是一個native方法,在libbili.so中。
參數是自定義的類型SortedMap,其實傳入TreeMap就可以
方法二:hook HashMap這個方法是從這篇文章學來的 → https://blog.csdn.net/xmx_000/article/details/134123902
原理:
猜測sign值大機率是其餘參數的簽名,而且請求參數的鍵值對通常都會以HashMap( 其他Map都有可能? )來保存,因此hook HashMap再打印調用棧就能快速定位到指定位置。
這裡選擇用於判斷的鍵值是ad_extra而不是sign( ad_extra是接口其中一個請求參數 ),因為sign這個詞太常見,選擇一個較為少見的參數 ...
【Unity+lua手遊逆向】道友掛機嗎
分析查看lib目錄,發現libil2cpp.so、libunity.so、libtolua.so,由此可以判斷是Unity + lua的組合。
第一步必然是要將dump.cs搞下來,以下兩種方式都可以:
常規操作 ( 這樣方式可以獲得更多信息 )
frida-il2cpp-bridge ( 只能dump下來dump.cs )
配合dump.cs的信息嘗試trace libil2cpp.so的一些類和方法,但發現具體邏輯應該是調用lua腳本實現的。
嘗試尋找APK目錄下是否存在lua腳本,發現/assests/lua。
在assets目錄下有一些.assetbundle文件,這些是Unity的一些資源打包成assetbundle ( 簡稱ab包 )的形式。
.assetbundle文件開頭是"UnityFS"標誌。 ( 後面會用到這點 )
進入lua目錄,也有一堆.assetbundle文件,但是用010Editor來查看會發現與上述正常的.assetbundle文件完全不一致。
因此合理懷疑這些就是被加密打包後的lua腳本。
解密lua腳本思路一:ho ...
bilibili(Frida檢測)
注:本文使用了自編譯魔改的Frida!!!
分析通過hook dlopen,打印加載的so,發現到libmsaoaidsec.so後frida就閃退,由此可知libmsaoaidsec.so中有檢測frida的邏輯。
通常很多檢測frida的邏輯都會使用fopen函數打開/proc/self/中的文件( 如/proc/self/maps ),以此來尋找是否存在frida的特徵。
而fopen底層的系統調用號是__NR_openat,嘗試使用https://github.com/ngiokweng/Frida-Seccomp來監控該系統調用。
Hook驗證猜想在保存的log裡搜索libmsaoaidsec.so,目標是調用棧中出現libmsaoaidsec.so的那些。
第一個打開了:/proc/15547/cmdline
第二個打開了:/proc/self/maps
第一個大機率不是檢測點,而是其他某些操作?因為不論是在注入frida前後,它的內容都不會變。
而第二個則大機率是檢測點,通過hook來驗證下。
由於0x18a34是由.init_proc裡的函數調用的,因此不能直 ...
【腳本】Notion筆記半自動轉成hexo博客文章
Notion自帶導出功能:
導出的壓縮包裡,一個是md格式的notion筆記,一個是保存圖片的資料夾,如下所示:
在腳本同級目錄下創建一個target目錄,將壓縮包裡的東西放進去。
手動配置blogInfo,然後執行腳本即可
腳本如下:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106import osimport refrom datetime import datetimedef removeSpaces(directory): for filename in os.listdir(directory): newFilename = filename.replace(" " ...
殼實現的基本原理
殼實現原理 & 方案概述
殼本身也是一個APP程序,只不過它的作用只是用來解密原APP程序,然後加載。
殼程序在完成dex的解密後,都需要通過ClassLoader來加載( APP本身的Dex文件 ),一般是通過DexClassLoader來加載,安卓8.0以後引入了InMemoryDexClassLoader從內存加載Dex文件
最終還需要修復ClassLoader和Application( 具體原因在下方給出 ),才能順利運行原APP的Activity。
修復ClassLoader為什麼需要修復ClassLoader?Android的系統組件如Activity、Service等都是由系統組件加載器( PathClassLoader )加載的,以這方式加載的系統組件會有一個所謂的組件生命周期,而我們直接用DexClassLoader加載的類是沒有組件生命周期的,即使能通過對APK的動態加載完成對組件類的加載,但當系統啟動該組件時( 如startActivity )時,依然會出現找不到該類的情況。
以如下代碼為例,通過loadClass加載test.dex裡的MainActi ...
記一次Android手遊逆向
前言這是一款挺老的遊戲了,以前身邊很多人在玩所以我也玩了一會,在遇然得知網上有這遊戲的免費外掛後去嘗試了一下,感覺很爽,畢竟是一款半單機的遊戲,就算開掛也不太會影響別人。
在那之後有試過研究一下這外掛的原理,但當時可謂是0基礎,只能按別人影片裡的教學一步一操作地嘗試自己寫外掛,最後不出意外地失敗了。再之後又嘗試了幾次,同樣以失敗告終…
雖說一直失敗,但不得不說我對寫外掛一直都很感興趣,大學選了計算機專業很大部份原因也是因為對外掛感興趣吧。
今天總算是圓了這以前的遺憾了^^
前置操作利用MT管理器的APK共存功能複製一個APK出來:安裝包提取→選擇APK→APK共存
修改就只對新複製出來的那個APK進行修改,原APK不作任何修改,方便之後hook兩者來對比差異
閃退分析以前在修改這遊戲後發現會閃退,一直以為它有簽名校驗,但其實並沒有。
它真的會校驗的是libmonsterstrike.so這個so,如何發現的?當不進行任何修改直接重打包APK後,它不會閃退;而只要修改了libmonsterstrike.so任一地方後,APP會閃退,由此可知該APP會校驗libmonsterstrike ...
淺逆某里227滑塊
Target:aHR0cHM6Ly9qb2JzLjUxam9iLmNvbS9zdXpob3UtZ3l5cS8xNTMzMDczMjEuaHRtbA== ( 多刷新幾次就會觸發滑塊 )
在調試前可先用fiddler等工具固定滑塊頁面,這樣會方便很多
跟n值生成位置第一種方法在滑動滑塊前先下個script斷點,然後會斷在這裡
這時去看網路面板,可以發現滑塊的驗證是通過nocaptcha/analyze.jsonp這個接口,其中最關鍵的參數就是n
簡單跟下棧就能找到n的生成位置,o.__fy_options固定就可以
第二種方法這種方法是在別的大佬的文章看到的,一開始我是用第一種方法找到的,但第二種方法感覺也挺好的,特此記錄一下
下個全局的的mousedown斷點
斷下後走幾步會到這裡,看到它添加了一個mousemove事件,跟入s看看
經過一些運算後,判斷是否進入i,繼續深入i看看
前面先移除了各種事件,最後進入了m函數
然後m函數就是n值生成的位置
本地&瀏覽器調試通常我找到密文生成位置後,會先嘗試導出相關函數,然後在本地運行,直到能利用出值為止( 雖然這 ...