吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

AOSP源碼定制-內核驅動編寫

哆啦安全 ? 來源:gakki的童養夫 ? 作者:新垣結衣唯一丈夫 ? 2024-04-23 11:15 ? 次閱讀

AOSP源碼定制-內核驅動編寫

介紹

有時候為了分析一些殼的檢測,需要在內核層面對讀寫相關的操作進行監控,每次去修改對應的內核源碼編譯重刷過于耗時耗力,這里就來嘗試編寫一個內核驅動,載入后監控讀寫。

前提

已經同步對應版本的內核源碼并編譯,這里不贅述。

真機測試并root。

開啟配置

比起直接改源碼,編譯模塊載入模塊,不需要反復修改源碼并刷入內核,相比較用frida等框架更不容易檢測(就是因為frida檢測才用這個)。

先為編譯配置開啟內核可加載、卸載等選項:

CONFIG_MODULES=Y

CONFIG_STRICT_MEMORY_RWX=N / CONFIG_DEBUG_RODATA=N

CONFIG_DEVMEM=Y

CONFIG_DEVKMEM=Y

CONFIG_KALLSYMS=Y

CONFIG_KALLSYMS_ALL=Y

CONFIG_HAVE_KPROBES=Y

CONFIG_HAVE_KRETPROBES=Y

CONFIG_HAVE_FUNCTION_TRACER=Y

CONFIG_HAVE_FUNCTION_GRAPH_TRACER=Y

CONFIG_TRACING=Y

CONFIG_FTRACE=Y

在內核源碼目錄下執行命令(前面編譯過一次,會有導入過系統變量):

make menuconfig

然后出現一個圖像化的配置頁面。

wKgZomYnJ9eAQ_IeAAEK9MOQbVk021.png

通過"/",打開搜索頁面,查找上面對應的配置所在位置,以CONFIG_DEVKMEM為例,可以看到會給出定義路徑。

wKgZomYnJ9eAYMMFAACHVn-Ju1g953.png

去對應路徑找到這個目錄,drivers/char/Kconfig。

wKgZomYnJ9eAVrDQAAFj1oVZ0nU074.png

找到定義的位置,改成y即可。按照配置改好,重新編譯內核,后面就可以開始編寫驅動模塊了

編譯第一個內核驅動

這里我們編譯一個內核模塊有兩種模式,一種是直接編譯進內核,另一種是編譯成單獨的ko文件通過insmod,rmmod命令來加載與卸載。這里我們講的是單獨編譯成ko文件。 在內核目錄下創建一個modules目錄,用于存放編寫各類驅動模塊。 先來寫個helloworld模塊進行測試。

wKgZomYnJ9eAebBOAABEvmCwNig012.png

簡單加個代碼測試,驅動代碼編寫有格式規范:

#include

#include

#include

static int __init hello_init(void){

printk(KERN_ALERT "Hello World! ");

return 0;

}

static void __exit hello_exit(void){

printk(KERN_ALERT "Bye ");

}

module_init(hello_init);

module_exit(hello_exit);

編寫Makefile:

# 設置內核源碼編譯的輸出目錄

KERNEL_OUT=/home/fukuyama/sourceCode/msm/out

# 設置arm64交叉編譯鏈工具路徑

TOOLCHAIN=/home/fukuyama/sourceCode/Android8/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9/bin/aarch64-linux-android-

# 設置arm32交叉編譯鏈工具路徑

TOOLCHAIN32=/home/fukuyama/sourceCode/Android8/prebuilts/gcc/linux-x86/arm/arm-linux-androideabi-4.9/bin/arm-linux-androideabi-

# 設置模塊

obj-m := helloworld.o

# 編譯命令配置

all:

make ARCH=arm64 CROSS_COMPILE_ARM32=$(TOOLCHAIN32) CROSS_COMPILE=$(TOOLCHAIN) -C $(KERNEL_OUT) M=$(shell pwd) modules

# 清理編譯命令

clean:

make -C $(KERNEL_OUT) M=$(shell pwd) cleancd

直接make編譯:

wKgZomYnJ9eAFW1-AADdF1-Rn6M190.png

編譯完后,adb 推送到 data/local/tmp目錄,然后insmod執行模塊查看內核日志輸出即可:

wKgZomYnJ9eAVdhCAAGm2dZMjWo642.png

可以看到已經有輸出了,卸載模塊也有輸出,證明模塊已經生效了。

編寫監控模塊

比如要監控open和read,我們需要獲取到syscalltable的基址。

echo 0 > /proc/sys/kernel/kptr_restrict

cat /proc/kallsyms

wKgZomYnJ9eAaIt2AABT-LKPSI8098.png

然后編寫代碼,增加了uid大于10000篩選:

#include "linux/kernel.h"

#include "linux/init.h"

#include "linux/module.h"

#include "linux/moduleparam.h"

#include "asm/unistd.h"

#include "linux/slab.h"

#include "linux/sched.h"

#include "linux/uaccess.h"

#include

void ** sys_call_table64 = (void**)0xffffffc001000000;

#define SURPRESS_WARNING __attribute__((unused))

#define LL unsigned long long

// int mm_uid = 10067;

// module_param(mm_uid, int, 0664);

SURPRESS_WARNING int getCurrentPid(void)

{

int pid = get_current()->pid;

return pid;

}

SURPRESS_WARNING LL isUserPid(void)

{

const struct cred * m_cred = current_cred();

kuid_t uid = m_cred->uid;

int m_uid = uid.val;

if(m_uid >10000)

{

return true;

}

return false;

}

SURPRESS_WARNING asmlinkage LL (*old_openat64)(int dirfd, const char __user* pathname, int flags, umode_t modex);

SURPRESS_WARNING LL new_openat64(int dirfd, const char __user* pathname, int flags, umode_t modex)

{

const struct cred * m_cred = current_cred();

kuid_t uid = m_cred->uid;

int m_uid = uid.val;

LL ret = -1;

ret = old_openat64(dirfd, pathname, flags, modex);

if(isUserPid())

{

char bufname[256] = {0};

strncpy_from_user(bufname, pathname, 255);

if(strstr("/sdcard/trace.txt",bufname)){

}else{

printk("myLog::openat64 pathname:[%s] ret:[%llu] current->pid:[%d] current->uid:[%d] ", bufname,ret , getCurrentPid(),m_uid);

}

}

return ret;

}

SURPRESS_WARNING asmlinkage LL (*old_read)(unsigned int fd, char __user *buf, size_t count);

SURPRESS_WARNING LL new_read(unsigned int fd, char __user *buf, size_t count)

{

const struct cred * m_cred = current_cred();

kuid_t uid = m_cred->uid;

int m_uid = uid.val;

LL ret = -1;

ret = old_read(fd, buf, count);

if(isUserPid())

{

char bufname[256] = {0};

strncpy_from_user(bufname, buf, 24);

printk("myLog::read fd:[%d] context:[%s] current->pid:[%d] current->uid:[%d] ", fd,bufname, getCurrentPid(),m_uid);

}

return ret;

}

SURPRESS_WARNING int hook_init(void){

printk("myLog::hook init success ");

if(sys_call_table64){

old_openat64 = (void*)(sys_call_table64[__NR_openat]);

printk("myLog::old_openat64 : %p ", old_openat64);

sys_call_table64[__NR_openat] = (void*)new_openat64;

old_read = (void*)(sys_call_table64[__NR_read]);

printk("myLog::old_read : %p ", old_read);

sys_call_table64[__NR_read] = (void*)new_read;

printk("myLog::hook init end ");

}

else{

printk("mylog::fail to find sys_call_table ");

}

return 0;

}

int __init myInit(void){

printk("myLog::hooksyscall Loaded1 ");

hook_init();

return 0;

}

void __exit myExit(void){

if(sys_call_table64){

printk("myLog::cleanup start ");

sys_call_table64[__NR_openat] = (void*)old_openat64;

sys_call_table64[__NR_read] = (void*)old_read;

printk("myLog::cleanup finish ");

}

printk("myLog::hooksyscall Quited ");

}

module_init(myInit);

module_exit(myExit);

載入后查看效果:

wKgZomYnJ9iAULZoAAEqeS9vezE172.png

已經有監控輸出了。 為了對上面的監控更加細化,修改補充一部分uid的限制:

......

void ** sys_call_table64 = (void**)0xffffffc001000000;

#define SURPRESS_WARNING __attribute__((unused))

#define LL unsigned long long

int mm_uid = 10067;

module_param(mm_uid, int, 0664);

......

SURPRESS_WARNING LL isUserPid(void)

{

const struct cred * m_cred = current_cred();

kuid_t uid = m_cred->uid;

int m_uid = uid.val;

if(m_uid == mm_uid)

{

return true;

}

return false;

}

在啟動模塊的時候,增加啟動參數,只打印對應uid的app讀寫監控。

insmod helloworld.ko mm_uid=10067

演示略。 只是這個模塊好像卸載的時候會死機重啟。

總結

簡單學習下內核驅動的編寫與加載,簡化內核監控,還可以補充定制用于繞過一些反調試。

審核編輯:劉清
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Modules
    +關注

    關注

    0

    文章

    10

    瀏覽量

    8012
  • AOSP
    +關注

    關注

    0

    文章

    16

    瀏覽量

    6222
  • 內核驅動
    +關注

    關注

    0

    文章

    5

    瀏覽量

    2681

原文標題:AOSP源碼定制-內核驅動編寫

文章出處:【微信號:哆啦安全,微信公眾號:哆啦安全】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    淺談Linux內核源碼的Makefile、Kconfig和.config文件

    Linux內核源碼文件繁多,搞不清Makefile、Kconfig、.config間的關系,不了解內核編譯體系,編譯修改內核有問題無從下手,自己寫的
    發表于 10-17 16:19 ?4425次閱讀
    淺談Linux<b class='flag-5'>內核</b><b class='flag-5'>源碼</b>的Makefile、Kconfig和.config文件

    Google AOSP 正式宣布支持HiKey 極大壓縮Android SDK開發軟件周期

    Android內核源碼及板級系統支持,使得開發者們能夠輕松創建和調試新的或現有的外圍設備驅動程序,甚至進行內核開發等其他更為困難的開發工作,由此OEM廠商的開發困難將大大降低。LeMa
    發表于 03-08 11:38

    Linux內核模塊的驅動程序怎么編寫

    Linux中的大部分驅動程序,是以模塊的形式編寫的.這些驅動程序源碼可以修改到內核中,也可以把他們編譯成模塊形勢,在需要的時候動態加載.
    發表于 03-24 07:09

    linux自帶驅動存放于內核源碼

    linux自帶驅動存放于內核源碼目錄具體目錄如下1. 按鍵驅動kernal\drivers\input\keyboard\kernal\drivers\char2. LED
    發表于 11-04 07:13

    編寫Linux內核的步驟有哪些

    編譯工具鏈,在此就不再贅述。編寫Linux內核需要內核源碼內核編譯配置文件kernel_config,如下圖:具體編譯步驟如下:1.解壓
    發表于 11-04 07:42

    如何對RK3568環境上的AOSP源碼進行調試呢

    如何對RK3568環境上的AOSP源碼進行編譯呢?如何對RK3568環境上的AOSP源碼進行調試呢?
    發表于 03-02 06:25

    VisionFive 2成功集成Android開源項目(AOSP)!

    的開創性合作(https://github.com/android-risc-v, Peter Yoon)。 賽昉團隊利用AOSP的開源性質定制了軟件,與VisionFive 2的硬件功能保持一致
    發表于 10-16 13:11

    華為鴻蒙系統內核源碼分析上冊

    鴻蒙內核源碼注釋中文版【 Gitee倉】給 Harmoηy○S源碼逐行加上中文注解,詳細闡述設計細節,助你快速精讀 Harmonyos內核源碼,掌握整個鴻蒙
    發表于 04-09 14:40 ?17次下載

    openharmony原理 aosp和openharmony關系

    。 OpenHarmony的技術架構是按分層設計來的,從下向上是內核層、系統服務層、框架層和應用層。而系統功能是逐級展開,為系統 子系統 組件。 AOSP為安卓開放源代碼項目,AOSP 是基于 Linux 的??梢?/div>
    的頭像 發表于 06-23 09:35 ?3005次閱讀

    使用Kotlin替代Java重構AOSP應用

    兩年前,Android 開源項目 (AOSP) 應用團隊開始使用 Kotlin 替代 Java 重構 AOSP 應用。之所以重構主要有兩個原因: 一是確保 AOSP 應用能夠遵循 Android
    的頭像 發表于 09-16 09:26 ?1923次閱讀
    使用Kotlin替代Java重構<b class='flag-5'>AOSP</b>應用

    AOSP Android11系統源碼內核源碼簡析

    AOSP源碼中并不包括內核源碼,需要單獨下載,內核源碼有很多版本,比如common是通用的Lin
    的頭像 發表于 01-29 09:25 ?5748次閱讀

    獲取Linux內核源碼的方法

    (ELF1/ELF1S開發板及顯示屏)Linux內核是操作系統中最核心的部分,它負責管理計算機硬件資源,并提供對應用程序和其他系統組件的訪問接口,控制著計算機的內存、處理器、設備驅動程序和文件系統等
    的頭像 發表于 12-13 09:49 ?717次閱讀
    獲取Linux<b class='flag-5'>內核</b><b class='flag-5'>源碼</b>的方法

    基于Android13的AOSP源碼下載及編譯指南

    AOSP(Android Open Source Project)是Android操作系統的開源項目,通過下載和編譯AOSP源碼,您可以獲得原始的Android系統,并進行定制和開發。
    的頭像 發表于 01-17 09:49 ?4169次閱讀
    基于Android13的<b class='flag-5'>AOSP</b><b class='flag-5'>源碼</b>下載及編譯指南

    AOSP源碼定制-對root定制的補充流程

    前面通過修改build.prop中的指紋以及對su的修改,完成了基礎的定制修改,但是碰上一些app還是能被檢測到,再進行深入修改。
    的頭像 發表于 04-01 11:04 ?1604次閱讀
    <b class='flag-5'>AOSP</b><b class='flag-5'>源碼</b><b class='flag-5'>定制</b>-對root<b class='flag-5'>定制</b>的補充流程

    linux驅動程序如何加載進內核

    在Linux系統中,驅動程序是內核與硬件設備之間的橋梁。它們允許內核與硬件設備進行通信,從而實現對硬件設備的控制和管理。 驅動程序的編寫
    的頭像 發表于 08-30 15:02 ?587次閱讀
    怎样赢百家乐官网的玩法技巧和规则 | 百家乐官网网址皇冠现金网| 尊龙百家乐娱乐场| 大家旺百家乐官网娱乐城| 百家乐微笑心法搜索| 太阳城娱乐城网站| 百家乐投注网址| 百家乐官网二号博彩正网| 百家乐怎样玩才会赢钱| 百家乐官网看| 六合彩网页| 做生意摆放老虎好不好| 肯博| 足球百家乐投注| 百家乐官网开户送彩金28| 百家乐赌博赌博平台| 百家乐官网三珠投注法| 大发888 大发888娱乐城| 属虎属龙做生意| 浦东新区| 威尼斯人娱乐网注册| 888百家乐官网的玩法技巧和规则 大发百家乐官网的玩法技巧和规则 | 康莱德百家乐的玩法技巧和规则| 百家乐官网怎么看大小| 大发娱乐| 百家乐网站源码| 广东百家乐官网主论坛| 姚记娱乐城信誉最好| 百家乐翻天片尾曲| 百家乐官网与龙虎斗怎么玩| 亚洲顶级赌场的微博| 豪华百家乐桌子厂家| 百家乐官网网上投注作弊| 百家乐庄最高连开几把| 百家乐看单技术| 足球百家乐官网投注计算| 网上娱乐城老虎机| 贵宾百家乐的玩法技巧和规则| 一筒百家乐官网的玩法技巧和规则 | 百家乐赌的技巧| 网络百家乐官网游戏机怎么破解|