首页
课程
问答
CTF
社区
招聘
峰会
发现
排行榜
知识库
工具下载
看雪20年
看雪商城
证书查询
登录
注册
首页
社区
课程
招聘
发现
问答
CTF
排行榜
知识库
工具下载
峰会
看雪商城
证书查询
社区
Android安全
发新帖
25
19
[原创] 淺談Frida無痕Hook
发表于: 2026-5-19 12:05
4716
[原创] 淺談Frida無痕Hook
ngiokweng
5
2026-5-19 12:05
4716
## 0x0 前言 前段時間有大佬開源了一套名為wxshadow的無痕hook方案,它主要通過頁表的一些機制來實現,詳細實現推薦去看源碼,非常厲害的思路!!( 原文:「[**[原创]linux/android 利用shadow内存无痕hook方法**](https://bbs.kanxue.com/thread-290304.htm)」 ) wxshadow是一個提供了無痕patch接口的KPM模塊,而非一個可以開箱即用的hook框架,因此我就在想,能否把它集成到Frida中,給Frida裝上無痕Hook功能?本文簡單聊聊它的可行性。 ## 0x1 一些內核知識 一些個人認為要先了解的內核知識,來自「《linux内核深度解析》余华兵」第三章。 ### 1.1 統一的頁表框架 頁表用來把虛擬頁映射到物理頁,並且存放頁的保護位。 在Linux4.11版本之前,Linux內核把頁表分為四級: 1. 頁全局目錄 ( Page Global Directory,PGD ) 2. 頁上層目錄 ( Page Upper Directory,PUD ) 3. 頁中間目錄 ( Page Middle Directory,PMD ) 4. 直接頁表 ( Page Table,PT ,表中的元素稱為Page Table Entry,簡稱PTE ) 4.11版本把頁表擴展到五級,在PGD和PUD之間增加了頁四級目錄( Page 4th Directory,P4D )。 可以通過`CONFIG_PGTABLE_LEVELS`宏來配置頁表的級數,以我的P6為例,是3級頁表。 ```bash oriole:/ # zcat /proc/config.gz | grep CONFIG_PGTABLE_LEVELS CONFIG_PGTABLE_LEVELS=3 ``` 每個進程有獨立的頁表,進程的`mm_struct`實例成員`pgd`指向全局目錄,前面四級頁表的表項存放下一級頁表的起始地址,直接頁表的表項存放頁幀號( Page Frame Number,PFN )。 頁幀號 + 頁內編移 = 物理地址  ### 1.2 ARM64處理器頁表 ARM64把頁表稱為轉換表( translation table ),最多4級。 1. 頁長度是4KB:使用`4`級轉換表,`0`級轉換表對應頁全局目錄,`1`級轉換表對應頁上層目錄,如此類推( 沒有`P4D` )。 48位虛擬地址被分解為如下所示:  2. 頁長度是64KB:使用`3`級頁表,`1`級轉換表對應頁全局目錄,`2`級對應頁中間目錄,`3`級對應直接頁表。  ARM64把表項稱為描述符( descriptor ),長度為`64`位。描述符的第`0`位代表當前描述符是否有效,`0`表示無效,`1`表示有效。第`1`位指定描述符的類型,具體如下: - 在`0 ~ 2`級轉換表中,`0`表示塊( block )描述符,存放一個內存塊( 即巨型頁 )的起始地址,`1`表示表( table )描述符,存放下一級轉換表的地址。 - 在第`3`級轉換表中,`0`表示保留,`1`表示頁描述符。 `3`級轉換表的頁描述符如下圖所示:  在塊描述符和頁描述符中,內存屬性被拆分成一個高屬性塊和一個低屬性塊,如下圖所示:  wxshadow利用了其中幾個關鍵屬性來實現: - 第`54`位:在EL0中表示UXN( Unprivileged execute-Never ),即不允許EL0執行內核代碼;在其他異常級別,表示XN( execute-Never ),不允許執行。 - 第`6 ~ 7`位:`AP[2:1]`( Data Access Permissions,數據訪問權限 )。在階段1轉換中,`AP[2]`用來選擇只讀或讀寫,`1`表示只讀,`0`表示讀寫;`AP[1]`用來選擇是否允許EL0訪問,`1`表示允許,`0`表示不允許。在非異常級別`1`和`0`轉換機制的階段2轉換中,`AP[2:1]`為`00`表示不允許訪問,`01`表示只讀,`10`表示只寫,`11`表示讀寫。 ### 1.3 巨型頁 當運行內存需求量較大的應用程序時,如果使用長度為4KB的頁,將會產生較多的TLB未命中和缺頁異常,大大影響應用程序的性能。而如果使用長度為2MB,什至更大的巨型頁,可以大幅改善此問題,這正是內核引入巨型頁( Huge Page )的直接原因。 ARM64支持巨型頁的方式有兩種: 1. 通過塊描述符來支持  2. 通過頁/塊描述符的連續位來支持  ## 0x2 Frida集成wxshadow的可行性 wxshadow提供了`PR_WXSHADOW_PATCH`和`PR_WXSHADOW_RELEASE`,前者可以用於替代frida的patch行為,後者用於清理現場。 ```cpp // wxshadow_bp.c case PR_WXSHADOW_PATCH: pid = (pid_t)arg2; mm = resolve_pid_to_mm(pid); if (!mm) { args->ret = -3; args->skip_origin = 1; break; } ret = wxshadow_do_patch(mm, arg3, (void __user *)arg4, arg5); kfunc_mmput(mm); args->ret = ret; args->skip_origin = 1; break; case PR_WXSHADOW_RELEASE: pid = (pid_t)arg2; mm = resolve_pid_to_mm(pid); if (!mm) { args->ret = -3; args->skip_origin = 1; break; } if (arg3 == 0) { ret = wxshadow_release_pages_for_mm(mm, "release_all"); } else { ret = wxshadow_do_release(mm, arg3); } kfunc_mmput(mm); args->ret = ret; args->skip_origin = 1; break; ``` 實際嘗試時,遇到了兩個問題。 **問題一:會發生livelock的情況。** 原因是Frida hook會把目標地址patch成如下形式,用到了arm64的ldr literal技術( 代碼 / 數據在相鄰位置 )。 ```cpp ldr x16, [pc, #8] br x16 .dword on_enter_trampoline ``` 若`PR_WXSHADOW_PATCH`時仍然是按這種形式來patch,會導致livelock ( APP卡死 ) 因為wxshadow本質上維護了`original(r--)`( 讀 )和`wxshadow(--x)`( 執行 )兩種視圖,當wxshadow直接套用到上述patch中,就會發生以下情況: ```cpp ; 當前視圖: wxshadow(--x) exec: ldr x16, [pc, #8] ; 觸發read fault, 切換到original(r--) read: on_enter_trampoline ; 讀完後, 回到ldr指令, 觸發exec fault, 切換到wxshadow(--x) exec: ldr x16, [pc, #8] ; 死循環... ``` 而wxshadow的作用範圍是一整頁,因此對同頁下的ldr literal也要做處理。 **問題二:wxshadow無法對`libart.so`大部份函數進行hook。** 這與`libart.so`在某次更新時改用巨型頁( Huge PMD )有關,而wxshadow是以PTE為單位進行管理,雖然其中有對巨型頁做處理,但測試下來發現是不夠的。 ```cpp // https://android.googlesource.com/platform/art/+/07ff2833c7 Compile libart.so and libart-compiler.so with 2MB section alignment. Adds the appropriate linker flags for libart and libart-compiler to have 2MB section alignment. This allows the executable segment of these libraries to be backed by transparent hugepages on supporting systems. ``` 解決思路是手動把2MB的PMD分割成512個4KB的PTE,實測可行。 基於wxshadow提供能力,能很好地隱藏Frida本身的一些特徵: 1. 默認hook行為:以Frida16.5.9為例,默認會hook `libc.so`、`libselinux.so`和`libandroid_runtime.so`,用到Java相關API時,會hook `libart.so`。 注:之後的某個版本開始還會默認hook `linker` 2. maps特徵:啟動一次frida-server後,maps特徵( rwxp段、N段的`libc.so`等 )會永久留下,即使關掉frida-server也無用,必須要重開機才行。 原因是frida-server的那些默認hook行為是對zygote進程做的,而zygote進程是所有APP進程的父進程。 除此之外,Frida還有memfd、注入線程等特徵,可以在內核層做繞過。 總結:Frida集成wxshadow是完全可行的,遇到的各種問題基本都有解法。 ## 0x3 測試 兼容性和穩定性如何?用一些樣本來測測看。 ### 3.1 CrackProof 以前分析過這個保護,那時候還不知道它的名字叫`CrackProof`,個人認為是個很強的保護 ( 分析文章:[https://bbs.kanxue.com/thread-286746.htm](https://bbs.kanxue.com/thread-286746.htm) ) 遊戲邏輯在`libpad.so`裡,之前分析的時候這個so似乎還沒有加密,現在終於加密了,但也是直接dump就行的整體加密。 嘗試實現秒殺功能,對於這種非常規遊戲引擎開發的遊戲,讓AI來找簡直再合適不過: ```cpp 使用ida-pro-mcp, 分析"玩家攻擊" 相關的邏輯在哪? ``` 然後用魔改的Frida對AI給出的地址進行hook,成功實現秒殺。  運行得也挺穩定,未曾出現過閃退的問題。 ### 3.2 nProtect 之前也分析過,這次用另一個樣本來測 ( [https://bbs.kanxue.com/thread-288477.htm](https://bbs.kanxue.com/thread-288477.htm) ) 記得NP裡是有自定義linker保護的,沒想到直接dump `libil2cpp.so`也行。把gm文件也dump出來後,直接用Il2cppDumper就能把SDK給dump出來。 同樣嘗試實現秒殺功能,同樣交給AI去分析,結合ida和dump.cs,也是很簡單就找到對應的邏輯。  魔改Frida spawn這個APP時,有機會spawn失敗( Frida閃退 / APP卡住,並非被檢測到 ),但機率比較低,屬於可接受範圍之內。 小結:除此之外還測試了幾個Appdome保護的樣本,雖然都有機會發生上述spawn失敗的情況,但基本不影響使用,說明wxshadow已經是個非常成熟的方案。 ( 如果有其他檢測強的樣本,歡迎分享給我看看^^ ) ## 0x4 結語 一開始選用了`17.9.3`這個版本來進行魔改,改到後面發現會莫名其妙地崩潰,一度讓我以為是改崩了,但後來用原版的`17.9.3`去測試也一樣崩,說明是這個版本有問題???最後還是用回了`16.5.9`這個版本,以前一直用的這個版本,個人認為是比較穩定的一個版本。 對Frida魔改集成wxshadow的所有工作,可以完全交給AI來完成。在AI的幫助下,試錯成本低了很多,只要有思路,AI總能給你一個滿意的答覆,或許時代真的變了吧。
传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!
最后于
2026-6-5 10:02 被ngiokweng编辑 ,原因:
#基础理论
#程序开发
收藏
・
25
点赞
・
19
打赏
分享
分享到微信
分享到QQ
分享到微博
赞赏记录
参与人
雪币
留言
时间
wx_funcrever
非常支持你的观点!
2026-5-27 10:36
Dy1an
为你点赞!
2026-5-26 18:34
零_721409
你的分享对大家帮助很大,非常感谢!
2026-5-26 10:58
mb_iesvmzqc
为你点赞!
2026-5-25 11:23
sk97
感谢你分享这么好的资源!
2026-5-22 14:04
孤独的街
这个讨论对我很有帮助,谢谢!
2026-5-22 13:54
x1a0f3n9
这个讨论对我很有帮助,谢谢!
2026-5-22 01:23
jpacg
这个讨论对我很有帮助,谢谢!
2026-5-22 01:05
mb_rrvlrvbk
谢谢你的细致分析,受益匪浅!
2026-5-21 11:07
x_req
感谢你的贡献,论坛因你而更加精彩!
2026-5-21 00:50
andy张刘
为你点赞!
2026-5-20 19:05
X66iaM
谢谢你的细致分析,受益匪浅!
2026-5-20 15:40
taeyeon_ss
感谢你分享这么好的资源!
2026-5-20 11:44
n_1ng
为你点赞!
2026-5-20 11:32
fei3ei
谢谢你的细致分析,受益匪浅!
2026-5-20 09:44
我的小拇指啊
这个讨论对我很有帮助,谢谢!
2026-5-19 22:55
New对象处
感谢你的贡献,论坛因你而更加精彩!
2026-5-19 17:56
nonovo
感谢你分享这么好的资源!
2026-5-19 17:53
东方玻璃
期待更多优质内容的分享,论坛有你更精彩!
2026-5-19 15:40
查看更多
赞赏
×
1 雪花
5 雪花
10 雪花
20 雪花
50 雪花
80 雪花
100 雪花
150 雪花
200 雪花
支付方式:
微信支付
赞赏留言:
快捷留言
感谢分享~
精品文章~
原创内容~
精彩转帖~
助人为乐~
感谢分享~
最新回复
(
8
)
Imxz
雪 币:
112
活跃值:
(9405)
能力值:
( LV2,RANK:10 )
在线值:
发帖
6
回帖
750
粉丝
9
关注
私信
Imxz
2
楼
kkb
2026-5-19 15:31
0
wx_范迪塞尔
雪 币:
5
活跃值:
(4470)
能力值:
( LV2,RANK:10 )
在线值:
发帖
21
回帖
127
粉丝
6
关注
私信
wx_范迪塞尔
3
楼
意义不大,但是还是支持一下
2026-5-19 16:27
0
ngiokweng
雪 币:
4000
活跃值:
(7846)
能力值:
( LV12,RANK:280 )
在线值:
发帖
19
回帖
172
粉丝
297
关注
私信
ngiokweng
5
4
楼
wx_范迪塞尔
意义不大,但是还是支持一下
「淺談」
2026-5-19 17:24
0
流霜瞳
雪 币:
882
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
3
粉丝
0
关注
私信
流霜瞳
5
楼
学习一下
2026-5-20 10:17
0
墨穹呢
雪 币:
4704
活跃值:
(8122)
能力值:
( LV3,RANK:20 )
在线值:
发帖
2
回帖
224
粉丝
18
关注
私信
墨穹呢
6
楼
感谢分享
2026-5-20 19:58
0
MsScotch
雪 币:
4174
活跃值:
(4911)
能力值:
( LV2,RANK:10 )
在线值:
发帖
3
回帖
394
粉丝
5
关注
私信
MsScotch
7
楼
tql
2026-5-20 22:06
0
啊你好哇123
雪 币:
722
能力值:
( LV1,RANK:0 )
在线值:
发帖
0
回帖
361
粉丝
0
关注
私信
啊你好哇123
8
楼
手机没root可以用吗
2026-5-23 13:20
0
ngiokweng
雪 币:
4000
活跃值:
(7846)
能力值:
( LV12,RANK:280 )
在线值:
发帖
19
回帖
172
粉丝
297
关注
私信
ngiokweng
5
9
楼
啊你好哇123
手机没root可以用吗
不行
2026-5-23 15:13
0
游客
登录
|
注册
方可回帖
回帖
表情
雪币赚取及消费
高级回复
返回
ngiokweng
5
19
发帖
172
回帖
280
RANK
关注
私信
他的文章
[原创] 淺談Frida無痕Hook
4716
[原创] Appdome分析
4212
[原创] 記某手遊有趣的Frida檢測
5752
[原创] xVMP項目分析(基於LLVM的VMP實現)
17494
[原创] 初窺NP手遊保護
16020
关于我们
联系我们
企业服务
看雪公众号
专注于PC、移动、智能设备安全研究及逆向工程的开发者社区
看原图
赞赏
×
雪币:
+
留言:
快捷留言
为你点赞!
返回
顶部