<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
有一天,老闆突然找到小B說,隱私合規需要我們獲取許可權前,需要明確授權來意,這個你來跟一下吧!小B此時就可愁了,因為專案許可權那麼多,每個自己手動加上授權來意提示的話,可能會漏掉很多,工作量也大,這可咋辦呀!老B看到小B這麼愁眉苦臉,連忙說:“可以用ASM進行插樁呀!hook想要的方法”,小B聽了,興奮的去百度了一下,但是發現asm學習成本又高,短期又不可能搞完,這可咋辦呀!明明我只想搞hook一個方法交差來著!!老B:”沒事,所以本文就來了!”
這裡只是提供一個設計思路,不會涉及到太多細節,需要讀者瞭解相關的知識,如果不清楚只想使用的話,也是有的 github.com/TestPlanB/S… 歡迎點星星或者pr噢!
目前可以利用位元組碼進行hook的框架有很多,比如ASM,AspectJ,javassit等等,都是可以在編譯時插入相關的位元組碼,進行方法的插樁,從而達到一個hook的目的,但是這些工具好歸好,但是都有一個小問題,就是需要上手,部分hook框架上手門檻高,也有自己獨特的用法,短時間內可能很難使得開發人員上手。所以對hook庫進行一個二次封裝,也是很多公司在做的一個事情。方法有很多種,作者基於自己的理解,認為設定式的hook才是最簡單的,畢竟,Android就有gradle進行各種的專案工程設定,那麼我們為什麼就不能通過gradle進行設定的Hook呢?基於上面的猜想,就有了本文!友情提示:閱讀本文最好對asm跟transform機制有所瞭解
為了更加通用和高效,本次採用asm作為底層,進行二次封裝,畢竟android官方的link還有比較出色的aspectj都是基於asm進行底層修改的,那我們這次也同樣使用,好了就開幹!
為了讓不太瞭解的ASM的也能夠閱讀本文,所以也會介紹部分ASM相關的資訊,詳細瞭解還需要大家去官網閱讀噢!這裡先介紹Transform機制。 Transform是android 進行編譯時,在class 檔案生成 dex檔案時,給我們開發者預留的一個小口,可以理解在這個階段,我們可以修改已生成的class等檔案,編織入自己額外的位元組碼,從而達到無需修改專案本身的原始碼就可以行為修改的機制!如果大家有留意的話,這個機制就是gradle 在build階段中,會存在一個transformClassesWithXXForXX的task,舉例子:
transformClassesWithSpiderPluginForDebug,就是在這裡進行的transform修改。 當然,一個專案會存在多個transform,如圖所示
就像流水線一樣,我們的transform處理完就會交給下一個transform,共同修改生成的位元組碼的行為。大家可以先簡單理解為這是一個任務,提供了介面給外部修改生成位元組碼的機會,具體我們可以google相關的資料,也可以看下最後例子專案的處理
ASM是一個位元組碼修改框架,他就在我們上文提到的Transform裡面做了文章。關於ASM的介紹我們簡單來幾下,有個大概的認知就好,就像我們存取一個方法/屬性一樣,jvm肯定是先載入類,然後在執行方法或者屬性的方法,ASM的執行機制就如圖一樣
我們的目標是建立一個基於gradle設定即可執行的hook庫,先從使用角度考慮,如果我想hook一個類是LogUtils,中的test方法的話,需要哪些引數呢?快動一下你聰明的小腦袋,emmm,比如類的名稱需要吧!方法名稱!還有捏!只靠這兩個明顯還不夠,因為我們還存在著各種過載不是嘛,那怎麼表示一個特定方法呢!沒錯,還有函數簽名對吧!畢竟編譯器底層就是靠著函數簽名去識別某個方法的呀,還有嘛?找到這個方法後,我們是在方法前/方法本身/方法後 進行自定義修改呢?所以就還需要一個類似於模式一樣的東西吧!這裡就稱為hook模式好了,還有嘛?找到這個方法,我們還需要自己自定義的操作吧!就定義為hook操作吧。 總結起來,我們需要hook模式,類的名稱,方法名稱,函數簽名,hook操作就可以完成一次hook某個方法的需求了對吧,就比如以下程式碼所示
比如hook LogUtils類的test方法,簽名是()V,
替換為呼叫LogTest類的一個靜態方法test
hookMethod hookMode.Default(hook模式),
"com/example/spider/LogUtils"(類的名稱),
"test"(方法名稱), "()V"(函數簽名), { MethodVisitor mv ->
mv.visitMethodInsn(Opcodes.INVOKESTATIC,
"com/example/spider/LogTest", "test", "()V", false)
}(hook操作)
為了使只要通過上面的程式碼就能實現hook操作,我們需要定義: asm相關的:自定義的classvisitor,methodvisitor gradle:extension引數,比如上面的“hookMethod”,用來標記我們需要哪部分進行hook操作 transform:標準transform寫法。
我們按照上面思路,是不是需要定義一個類,包含hook模式,類的名稱,方法名稱,函數簽名,hook操作,才能將引數傳給transform,從而執行自己的ASM操作。 所以就需要定義extension引數: 我們可以在定義plugin的時候,在apply階段通過project.extensions.create,建立一個自己的設定格式引數,比如Hook.class裡面就有我們的引數
project.extensions.create("hook"(標識名稱), Hook.class)
使用的話就可以在任意gradle檔案使用
hook{
引數1 物件值
引數2 物件值
}
這樣的話,我們只需要在Transform階段收集到設定資訊傳給ASM即可!。
gradle宣告的資訊我們都可以通過project.xx(標識名稱)獲取
比如
hook.methodHooker = project.hook,就拿到了一個屬於Hook類的hook物件
後續通過hook.hook模式就可以拿到屬性是hook模式的引數了
我們transform階段會遍歷所有的類,但是我們只需要對特定的類進行修改對不對,所以在這裡,我們需要針對只需對gradle設定的類,比如例子中的LogUtils進行處理即可,而不需要動刀其他的類! transform進行時,呼叫classvisitor就會呼叫其visit方法,我們在這裡識別出我們需要hook的類即可對不對,加入我們需要hook的東西都在 hook.hookMethodList裡面,我們只需要遍歷一遍,找到需要的類,然後打上一個標記
@Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { super.visit(version, access, name, signature, superName, interfaces); for(遍歷hookMethodList裡面){ if 如果設定的類 == name{ 標記就為true } } }
呼叫visit方法後,就代表了這個類被存取過了,就會呼叫其visitmethod方法,如果標記有效,我們就採用自定義的method visitor進行方法的修改,否則就還是原本的method visitor
@Override public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) { MethodVisitor mv = cv.visitMethod(access, name, descriptor, signature, exceptions); if (標記不為true) { return mv; } 進行我們自定義的method visitor操作 } return mv; }
如果class是我們需要hook的class,就會走到了自定義的method visitor,這裡是ASM的定義
@Override public void visitCode() { if hook模式是方法前{ hook 行為執行 } super.visitCode(); } @Override public void visitMethodInsn(int opcode, String owner, String methodName, String descriptor, boolean isInterface) { if hook模式是方法本身{ hook 行為執行 } super.visitMethodInsn(opcode, owner, methodName, descriptor, isInterface); } @Override public void visitInsn(int opcode) { if (opcode == Opcodes.ATHROW || (opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)) { if hook模式是方法後{ hook 行為執行 } } super.visitInsn(opcode); }
在設定階段,一個hook操作就可以抽象為Closure,如果用groovy語法就是Closure,如果是Kotlin就是一個函數,代表要進行的操作。 在Transform階段我們就可以織入自定義的closure,等滿足條件就觸發。幸運的是,ASM本身就提供了一個為AndroidStudio,準備的外掛,叫“ASM Bytecode viewer”,通過這個外掛,我們可以直接生成想要的插入程式碼所對應的ASM編碼,如圖:
通過closure所傳遞的methodvisitor,我們就可以執行設定的hook操作了。值得注意一點是,Spider不重新定義hook規則,而是在ASM基礎上,封裝比較容易編譯錯誤的點,比如Transform編寫,visitor類的編寫等等,便於實現我們自己的hook規格,而脫離框架本身,這點是需要運用Spider的開發者需要注意的點!
因為ASM體系有很多細節,文章是沒辦法列舉出所有細節,所以只能表露一個設計思路,具體的用法大家可以移步github.com/TestPlanB/S… 上面也是Spider的設計思路,具體用法也可以看Readme噢!
以上就是從零開始使用gradle設定即可執行的Hook庫詳解的詳細內容,更多關於gradle設定可執行Hook庫的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45