最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

從零開(kāi)始使用gradle配置即可執(zhí)行的Hook庫(kù)詳解

 更新時(shí)間:2022年09月21日 12:07:42   作者:Pika  
這篇文章主要為大家介紹了從零開(kāi)始使用gradle配置即可執(zhí)行的Hook庫(kù)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

背景

有一天,老板突然找到小B說(shuō),隱私合規(guī)需要我們獲取權(quán)限前,需要明確授權(quán)來(lái)意,這個(gè)你來(lái)跟一下吧!小B此時(shí)就可愁了,因?yàn)轫?xiàng)目權(quán)限那么多,每個(gè)自己手動(dòng)加上授權(quán)來(lái)意提示的話(huà),可能會(huì)漏掉很多,工作量也大,這可咋辦呀!老B看到小B這么愁眉苦臉,連忙說(shuō):“可以用ASM進(jìn)行插樁呀!hook想要的方法”,小B聽(tīng)了,興奮的去百度了一下,但是發(fā)現(xiàn)asm學(xué)習(xí)成本又高,短期又不可能搞完,這可咋辦呀!明明我只想搞hook一個(gè)方法交差來(lái)著??!老B:”沒(méi)事,所以本文就來(lái)了!”

本文須知

這里只是提供一個(gè)設(shè)計(jì)思路,不會(huì)涉及到太多細(xì)節(jié),需要讀者了解相關(guān)的知識(shí),如果不清楚只想使用的話(huà),也是有的 github.com/TestPlanB/S… 歡迎點(diǎn)星星或者pr噢!

當(dāng)前技術(shù)背景

目前可以利用字節(jié)碼進(jìn)行hook的框架有很多,比如ASM,AspectJ,javassit等等,都是可以在編譯時(shí)插入相關(guān)的字節(jié)碼,進(jìn)行方法的插樁,從而達(dá)到一個(gè)hook的目的,但是這些工具好歸好,但是都有一個(gè)小問(wèn)題,就是需要上手,部分hook框架上手門(mén)檻高,也有自己獨(dú)特的用法,短時(shí)間內(nèi)可能很難使得開(kāi)發(fā)人員上手。所以對(duì)hook庫(kù)進(jìn)行一個(gè)二次封裝,也是很多公司在做的一個(gè)事情。方法有很多種,作者基于自己的理解,認(rèn)為配置式的hook才是最簡(jiǎn)單的,畢竟,Android就有g(shù)radle進(jìn)行各種的項(xiàng)目工程配置,那么我們?yōu)槭裁淳筒荒芡ㄟ^(guò)gradle進(jìn)行配置的Hook呢?基于上面的猜想,就有了本文!友情提示:閱讀本文最好對(duì)asm跟transform機(jī)制有所了解

底層選擇

為了更加通用和高效,本次采用asm作為底層,進(jìn)行二次封裝,畢竟android官方的link還有比較出色的aspectj都是基于asm進(jìn)行底層修改的,那我們這次也同樣使用,好了就開(kāi)干!

目標(biāo)流程圖

Transform

為了讓不太了解的ASM的也能夠閱讀本文,所以也會(huì)介紹部分ASM相關(guān)的信息,詳細(xì)了解還需要大家去官網(wǎng)閱讀噢!這里先介紹Transform機(jī)制。 Transform是android 進(jìn)行編譯時(shí),在class 文件生成 dex文件時(shí),給我們開(kāi)發(fā)者預(yù)留的一個(gè)小口,可以理解在這個(gè)階段,我們可以修改已生成的class等文件,編織入自己額外的字節(jié)碼,從而達(dá)到無(wú)需修改項(xiàng)目本身的源代碼就可以行為修改的機(jī)制!如果大家有留意的話(huà),這個(gè)機(jī)制就是gradle 在build階段中,會(huì)存在一個(gè)transformClassesWithXXForXX的task,舉例子:

transformClassesWithSpiderPluginForDebug,就是在這里進(jìn)行的transform修改。 當(dāng)然,一個(gè)項(xiàng)目會(huì)存在多個(gè)transform,如圖所示

就像流水線一樣,我們的transform處理完就會(huì)交給下一個(gè)transform,共同修改生成的字節(jié)碼的行為。大家可以先簡(jiǎn)單理解為這是一個(gè)任務(wù),提供了接口給外部修改生成字節(jié)碼的機(jī)會(huì),具體我們可以google相關(guān)的資料,也可以看下最后例子項(xiàng)目的處理

ASM

ASM是一個(gè)字節(jié)碼修改框架,他就在我們上文提到的Transform里面做了文章。關(guān)于ASM的介紹我們簡(jiǎn)單來(lái)幾下,有個(gè)大概的認(rèn)知就好,就像我們?cè)L問(wèn)一個(gè)方法/屬性一樣,jvm肯定是先加載類(lèi),然后在執(zhí)行方法或者屬性的方法,ASM的運(yùn)行機(jī)制就如圖一樣

封裝開(kāi)始

目標(biāo)

我們的目標(biāo)是建立一個(gè)基于gradle配置即可運(yùn)行的hook庫(kù),先從使用角度考慮,如果我想hook一個(gè)類(lèi)是LogUtils,中的test方法的話(huà),需要哪些參數(shù)呢?快動(dòng)一下你聰明的小腦袋,emmm,比如類(lèi)的名稱(chēng)需要吧!方法名稱(chēng)!還有捏!只靠這兩個(gè)明顯還不夠,因?yàn)槲覀冞€存在著各種重載不是嘛,那怎么表示一個(gè)特定方法呢!沒(méi)錯(cuò),還有函數(shù)簽名對(duì)吧!畢竟編譯器底層就是靠著函數(shù)簽名去識(shí)別某個(gè)方法的呀,還有嘛?找到這個(gè)方法后,我們是在方法前/方法本身/方法后 進(jìn)行自定義修改呢?所以就還需要一個(gè)類(lèi)似于模式一樣的東西吧!這里就稱(chēng)為hook模式好了,還有嘛?找到這個(gè)方法,我們還需要自己自定義的操作吧!就定義為hook操作吧。 總結(jié)起來(lái),我們需要hook模式,類(lèi)的名稱(chēng),方法名稱(chēng),函數(shù)簽名,hook操作就可以完成一次hook某個(gè)方法的需求了對(duì)吧,就比如以下代碼所示

比如hook LogUtils類(lèi)的test方法,簽名是()V,
替換為調(diào)用LogTest類(lèi)的一個(gè)靜態(tài)方法test
hookMethod hookMode.Default(hook模式), 
"com/example/spider/LogUtils"(類(lèi)的名稱(chēng)), 
"test"(方法名稱(chēng)), "()V"(函數(shù)簽名), { MethodVisitor mv ->
    mv.visitMethodInsn(Opcodes.INVOKESTATIC, 
    "com/example/spider/LogTest", "test", "()V", false)
}(hook操作)
 

實(shí)現(xiàn)

為了使只要通過(guò)上面的代碼就能實(shí)現(xiàn)hook操作,我們需要定義: asm相關(guān)的:自定義的classvisitor,methodvisitor gradle:extension參數(shù),比如上面的“hookMethod”,用來(lái)標(biāo)記我們需要哪部分進(jìn)行hook操作 transform:標(biāo)準(zhǔn)transform寫(xiě)法。

gradle 定義extension

我們按照上面思路,是不是需要定義一個(gè)類(lèi),包含hook模式,類(lèi)的名稱(chēng),方法名稱(chēng),函數(shù)簽名,hook操作,才能將參數(shù)傳給transform,從而執(zhí)行自己的ASM操作。 所以就需要定義extension參數(shù): 我們可以在定義plugin的時(shí)候,在apply階段通過(guò)project.extensions.create,創(chuàng)建一個(gè)自己的配置格式參數(shù),比如Hook.class里面就有我們的參數(shù)

project.extensions.create("hook"(標(biāo)識(shí)名稱(chēng)), Hook.class)

使用的話(huà)就可以在任意gradle文件使用

hook{
  參數(shù)1 對(duì)象值
  參數(shù)2 對(duì)象值
}

這樣的話(huà),我們只需要在Transform階段收集到配置信息傳給ASM即可!。

Transform階段收集信息:

gradle聲明的信息我們都可以通過(guò)project.xx(標(biāo)識(shí)名稱(chēng))獲取

比如

hook.methodHooker = project.hook,就拿到了一個(gè)屬于Hook類(lèi)的hook對(duì)象
后續(xù)通過(guò)hook.hook模式就可以拿到屬性是hook模式的參數(shù)了

自定義的classvisitor

我們transform階段會(huì)遍歷所有的類(lèi),但是我們只需要對(duì)特定的類(lèi)進(jìn)行修改對(duì)不對(duì),所以在這里,我們需要針對(duì)只需對(duì)gradle配置的類(lèi),比如例子中的LogUtils進(jìn)行處理即可,而不需要?jiǎng)拥镀渌念?lèi)! transform進(jìn)行時(shí),調(diào)用classvisitor就會(huì)調(diào)用其visit方法,我們?cè)谶@里識(shí)別出我們需要hook的類(lèi)即可對(duì)不對(duì),加入我們需要hook的東西都在 hook.hookMethodList里面,我們只需要遍歷一遍,找到需要的類(lèi),然后打上一個(gè)標(biāo)記

@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 如果配置的類(lèi) == name{
        標(biāo)記就為true
    }
    }
}

調(diào)用visit方法后,就代表了這個(gè)類(lèi)被訪問(wèn)過(guò)了,就會(huì)調(diào)用其visitmethod方法,如果標(biāo)記有效,我們就采用自定義的method visitor進(jìn)行方法的修改,否則就還是原本的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 (標(biāo)記不為true) {
        return mv;
    }
    進(jìn)行我們自定義的method visitor操作
    }
    return mv;
}

自定義method visitor

如果class是我們需要hook的class,就會(huì)走到了自定義的method visitor,這里是ASM的定義

@Override
public void visitCode() {
    if hook模式是方法前{
     hook 行為執(zhí)行
     }
    super.visitCode();
}
@Override
public void visitMethodInsn(int opcode, String owner, String methodName, String descriptor, boolean isInterface) {
if hook模式是方法本身{
     hook 行為執(zhí)行
     }
    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 行為執(zhí)行
     }
    }
    super.visitInsn(opcode);
}

自定義hook操作

在配置階段,一個(gè)hook操作就可以抽象為Closure,如果用groovy語(yǔ)法就是Closure,如果是Kotlin就是一個(gè)函數(shù),代表要進(jìn)行的操作。 在Transform階段我們就可以織入自定義的closure,等滿(mǎn)足條件就觸發(fā)。幸運(yùn)的是,ASM本身就提供了一個(gè)為AndroidStudio,準(zhǔn)備的插件,叫“ASM Bytecode viewer”,通過(guò)這個(gè)插件,我們可以直接生成想要的插入代碼所對(duì)應(yīng)的ASM編碼,如圖:

通過(guò)closure所傳遞的methodvisitor,我們就可以執(zhí)行配置的hook操作了。值得注意一點(diǎn)是,Spider不重新定義hook規(guī)則,而是在ASM基礎(chǔ)上,封裝比較容易編譯錯(cuò)誤的點(diǎn),比如Transform編寫(xiě),visitor類(lèi)的編寫(xiě)等等,便于實(shí)現(xiàn)我們自己的hook規(guī)格,而脫離框架本身,這點(diǎn)是需要運(yùn)用Spider的開(kāi)發(fā)者需要注意的點(diǎn)!

總結(jié)

因?yàn)锳SM體系有很多細(xì)節(jié),文章是沒(méi)辦法列舉出所有細(xì)節(jié),所以只能表露一個(gè)設(shè)計(jì)思路,具體的用法大家可以移步github.com/TestPlanB/S… 上面也是Spider的設(shè)計(jì)思路,具體用法也可以看Readme噢!

以上就是從零開(kāi)始使用gradle配置即可執(zhí)行的Hook庫(kù)詳解的詳細(xì)內(nèi)容,更多關(guān)于gradle配置可執(zhí)行Hook庫(kù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • android文件管理器用法詳解

    android文件管理器用法詳解

    這篇文章主要為大家詳細(xì)介紹了android文件管理器的用法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • android studio 3.4配置Android -jni 開(kāi)發(fā)基礎(chǔ)的教程詳解

    android studio 3.4配置Android -jni 開(kāi)發(fā)基礎(chǔ)的教程詳解

    這篇文章主要介紹了android studio 3.4配置Android -jni 開(kāi)發(fā)基礎(chǔ),本文圖文并茂給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-09-09
  • Android使用SoundPool實(shí)現(xiàn)播放音效

    Android使用SoundPool實(shí)現(xiàn)播放音效

    這篇文章主要為大家詳細(xì)介紹了Android使用SoundPool實(shí)現(xiàn)播放音效,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • android:descendantFocusability方法介紹

    android:descendantFocusability方法介紹

    開(kāi)發(fā)中很常見(jiàn)的一個(gè)問(wèn)題,項(xiàng)目中的listview不僅僅是簡(jiǎn)單的文字,常常需要自己定義listview,問(wèn)題就出現(xiàn)了,可能會(huì)發(fā)生點(diǎn)擊每一個(gè)item的時(shí)候沒(méi)有反應(yīng),無(wú)法獲取的焦點(diǎn)
    2012-11-11
  • Android編程之軟件的安裝和卸載方法

    Android編程之軟件的安裝和卸載方法

    這篇文章主要介紹了Android編程之軟件的安裝和卸載方法,涉及Android編程實(shí)現(xiàn)軟件的安裝、權(quán)限修改及卸載的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-12-12
  • Android10 啟動(dòng)Zygote源碼解析

    Android10 啟動(dòng)Zygote源碼解析

    這篇文章主要為大家介紹了Android 10 啟動(dòng)分析之Zygote篇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • android中webview控件和javascript交互實(shí)例

    android中webview控件和javascript交互實(shí)例

    這篇文章主要介紹了android中webview控件和javascript交互實(shí)例,例子中包括javascript調(diào)用java的方法,java代碼中調(diào)用javascript的方法,需要的朋友可以參考下
    2014-07-07
  • Android數(shù)據(jù)轉(zhuǎn)移之Launcher導(dǎo)出數(shù)據(jù)庫(kù)給另一臺(tái)機(jī)器加載

    Android數(shù)據(jù)轉(zhuǎn)移之Launcher導(dǎo)出數(shù)據(jù)庫(kù)給另一臺(tái)機(jī)器加載

    這篇文章主要介紹了Android系統(tǒng)中Launcher導(dǎo)出數(shù)據(jù)庫(kù)給另一臺(tái)機(jī)器加載的詳細(xì)流程,數(shù)據(jù)轉(zhuǎn)移是少見(jiàn)但早晚要用到的功能,感興趣的朋友快來(lái)提前掌握吧
    2021-11-11
  • Android編程中context及全局變量實(shí)例詳解

    Android編程中context及全局變量實(shí)例詳解

    這篇文章主要介紹了Android編程中context及全局變量的用法,結(jié)合實(shí)例形式較為詳細(xì)的分析講述了context及全局變量的使用技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2015-12-12
  • Android組件化原理詳細(xì)介紹

    Android組件化原理詳細(xì)介紹

    這篇文章主要介紹了Android組件化原理詳細(xì)介紹,組件化架構(gòu)的目的是讓各個(gè)業(yè)務(wù)變得相對(duì)獨(dú)立,各個(gè)組件在組件模式下可以獨(dú)立開(kāi)發(fā)調(diào)試
    2022-07-07

最新評(píng)論

苏尼特右旗| 成安县| 云阳县| 南平市| 呈贡县| 礼泉县| 双峰县| 彰武县| 理塘县| 铜鼓县| 衡东县| 巴青县| 鱼台县| 滦南县| 定远县| 乌恰县| 中西区| 勐海县| 普兰县| 偏关县| 潍坊市| 兴和县| 都昌县| 桓台县| 若尔盖县| 蒙阴县| 开阳县| 西丰县| 忻城县| 孝感市| 康马县| 洞口县| 六枝特区| 北安市| 临清市| 鄂伦春自治旗| 绵阳市| 绥芬河市| 黄梅县| 蒲江县| 慈利县|