RM新时代网站-首页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

AOSP源碼定制-內(nèi)核驅(qū)動(dòng)編寫(xiě)

哆啦安全 ? 來(lái)源:gakki的童養(yǎng)夫 ? 作者:新垣結(jié)衣唯一丈夫 ? 2024-04-23 11:15 ? 次閱讀

AOSP源碼定制-內(nèi)核驅(qū)動(dòng)編寫(xiě)

介紹

有時(shí)候?yàn)榱朔治鲆恍さ?a target="_blank">檢測(cè),需要在內(nèi)核層面對(duì)讀寫(xiě)相關(guān)的操作進(jìn)行監(jiān)控,每次去修改對(duì)應(yīng)的內(nèi)核源碼編譯重刷過(guò)于耗時(shí)耗力,這里就來(lái)嘗試編寫(xiě)一個(gè)內(nèi)核驅(qū)動(dòng),載入后監(jiān)控讀寫(xiě)。

前提

已經(jīng)同步對(duì)應(yīng)版本的內(nèi)核源碼并編譯,這里不贅述。

真機(jī)測(cè)試并root。

開(kāi)啟配置

比起直接改源碼,編譯模塊載入模塊,不需要反復(fù)修改源碼并刷入內(nèi)核,相比較用frida等框架更不容易檢測(cè)(就是因?yàn)閒rida檢測(cè)才用這個(gè))。

先為編譯配置開(kāi)啟內(nèi)核可加載、卸載等選項(xiàng):

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

在內(nèi)核源碼目錄下執(zhí)行命令(前面編譯過(guò)一次,會(huì)有導(dǎo)入過(guò)系統(tǒng)變量):

make menuconfig

然后出現(xiàn)一個(gè)圖像化的配置頁(yè)面。

wKgZomYnJ9eAQ_IeAAEK9MOQbVk021.png

通過(guò)"/",打開(kāi)搜索頁(yè)面,查找上面對(duì)應(yīng)的配置所在位置,以CONFIG_DEVKMEM為例,可以看到會(huì)給出定義路徑。

wKgZomYnJ9eAYMMFAACHVn-Ju1g953.png

去對(duì)應(yīng)路徑找到這個(gè)目錄,drivers/char/Kconfig。

wKgZomYnJ9eAVrDQAAFj1oVZ0nU074.png

找到定義的位置,改成y即可。按照配置改好,重新編譯內(nèi)核,后面就可以開(kāi)始編寫(xiě)驅(qū)動(dòng)模塊了

編譯第一個(gè)內(nèi)核驅(qū)動(dòng)

這里我們編譯一個(gè)內(nèi)核模塊有兩種模式,一種是直接編譯進(jìn)內(nèi)核,另一種是編譯成單獨(dú)的ko文件通過(guò)insmod,rmmod命令來(lái)加載與卸載。這里我們講的是單獨(dú)編譯成ko文件。 在內(nèi)核目錄下創(chuàng)建一個(gè)modules目錄,用于存放編寫(xiě)各類(lèi)驅(qū)動(dòng)模塊。 先來(lái)寫(xiě)個(gè)helloworld模塊進(jìn)行測(cè)試。

wKgZomYnJ9eAebBOAABEvmCwNig012.png

簡(jiǎn)單加個(gè)代碼測(cè)試,驅(qū)動(dòng)代碼編寫(xiě)有格式規(guī)范:

#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);

編寫(xiě)Makefile:

# 設(shè)置內(nèi)核源碼編譯的輸出目錄

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

# 設(shè)置arm64交叉編譯鏈工具路徑

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

# 設(shè)置arm32交叉編譯鏈工具路徑

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

# 設(shè)置模塊

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執(zhí)行模塊查看內(nèi)核日志輸出即可:

wKgZomYnJ9eAVdhCAAGm2dZMjWo642.png

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

編寫(xiě)監(jiān)控模塊

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

echo 0 > /proc/sys/kernel/kptr_restrict

cat /proc/kallsyms

wKgZomYnJ9eAaIt2AABT-LKPSI8098.png

然后編寫(xiě)代碼,增加了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

已經(jīng)有監(jiān)控輸出了。 為了對(duì)上面的監(jiān)控更加細(xì)化,修改補(bǔ)充一部分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;

}

在啟動(dòng)模塊的時(shí)候,增加啟動(dòng)參數(shù),只打印對(duì)應(yīng)uid的app讀寫(xiě)監(jiān)控。

insmod helloworld.ko mm_uid=10067

演示略。 只是這個(gè)模塊好像卸載的時(shí)候會(huì)死機(jī)重啟。

總結(jié)

簡(jiǎn)單學(xué)習(xí)下內(nèi)核驅(qū)動(dòng)的編寫(xiě)與加載,簡(jiǎn)化內(nèi)核監(jiān)控,還可以補(bǔ)充定制用于繞過(guò)一些反調(diào)試。

審核編輯:劉清
聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • Modules
    +關(guān)注

    關(guān)注

    0

    文章

    10

    瀏覽量

    7995
  • AOSP
    +關(guān)注

    關(guān)注

    0

    文章

    16

    瀏覽量

    6195
  • 內(nèi)核驅(qū)動(dòng)

    關(guān)注

    0

    文章

    5

    瀏覽量

    2651

原文標(biāo)題:AOSP源碼定制-內(nèi)核驅(qū)動(dòng)編寫(xiě)

文章出處:【微信號(hào):哆啦安全,微信公眾號(hào):哆啦安全】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏

    評(píng)論

    相關(guān)推薦

    淺談Linux內(nèi)核源碼的Makefile、Kconfig和.config文件

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

    Google AOSP 正式宣布支持HiKey 極大壓縮Android SDK開(kāi)發(fā)軟件周期

    Android內(nèi)核源碼及板級(jí)系統(tǒng)支持,使得開(kāi)發(fā)者們能夠輕松創(chuàng)建和調(diào)試新的或現(xiàn)有的外圍設(shè)備驅(qū)動(dòng)程序,甚至進(jìn)行內(nèi)核開(kāi)發(fā)等其他更為困難的開(kāi)發(fā)工作,由此OEM廠商的開(kāi)發(fā)困難將大大降低。LeMa
    發(fā)表于 03-08 11:38

    Linux內(nèi)核模塊的驅(qū)動(dòng)程序怎么編寫(xiě)

    Linux中的大部分驅(qū)動(dòng)程序,是以模塊的形式編寫(xiě)的.這些驅(qū)動(dòng)程序源碼可以修改到內(nèi)核中,也可以把他們編譯成模塊形勢(shì),在需要的時(shí)候動(dòng)態(tài)加載.
    發(fā)表于 03-24 07:09

    linux自帶驅(qū)動(dòng)存放于內(nèi)核源碼

    linux自帶驅(qū)動(dòng)存放于內(nèi)核源碼目錄具體目錄如下1. 按鍵驅(qū)動(dòng)kernal\drivers\input\keyboard\kernal\drivers\char2. LED
    發(fā)表于 11-04 07:13

    編寫(xiě)Linux內(nèi)核的步驟有哪些

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

    如何對(duì)RK3568環(huán)境上的AOSP源碼進(jìn)行調(diào)試呢

    如何對(duì)RK3568環(huán)境上的AOSP源碼進(jìn)行編譯呢?如何對(duì)RK3568環(huán)境上的AOSP源碼進(jìn)行調(diào)試呢?
    發(fā)表于 03-02 06:25

    VisionFive 2成功集成Android開(kāi)源項(xiàng)目(AOSP)!

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

    華為鴻蒙系統(tǒng)內(nèi)核源碼分析上冊(cè)

    鴻蒙內(nèi)核源碼注釋中文版【 Gitee倉(cāng)】給 Harmoηy○S源碼逐行加上中文注解,詳細(xì)闡述設(shè)計(jì)細(xì)節(jié),助你快速精讀 Harmonyos內(nèi)核源碼,掌握整個(gè)鴻蒙
    發(fā)表于 04-09 14:40 ?17次下載

    openharmony原理 aosp和openharmony關(guān)系

    。 OpenHarmony的技術(shù)架構(gòu)是按分層設(shè)計(jì)來(lái)的,從下向上是內(nèi)核層、系統(tǒng)服務(wù)層、框架層和應(yīng)用層。而系統(tǒng)功能是逐級(jí)展開(kāi),為系統(tǒng) 子系統(tǒng) 組件。 AOSP為安卓開(kāi)放源代碼項(xiàng)目,AOSP 是基于 Linux 的。可以
    的頭像 發(fā)表于 06-23 09:35 ?2941次閱讀

    使用Kotlin替代Java重構(gòu)AOSP應(yīng)用

    兩年前,Android 開(kāi)源項(xiàng)目 (AOSP) 應(yīng)用團(tuán)隊(duì)開(kāi)始使用 Kotlin 替代 Java 重構(gòu) AOSP 應(yīng)用。之所以重構(gòu)主要有兩個(gè)原因: 一是確保 AOSP 應(yīng)用能夠遵循 Android
    的頭像 發(fā)表于 09-16 09:26 ?1861次閱讀
    使用Kotlin替代Java重構(gòu)<b class='flag-5'>AOSP</b>應(yīng)用

    AOSP Android11系統(tǒng)源碼內(nèi)核源碼簡(jiǎn)析

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

    獲取Linux內(nèi)核源碼的方法

    (ELF1/ELF1S開(kāi)發(fā)板及顯示屏)Linux內(nèi)核是操作系統(tǒng)中最核心的部分,它負(fù)責(zé)管理計(jì)算機(jī)硬件資源,并提供對(duì)應(yīng)用程序和其他系統(tǒng)組件的訪問(wèn)接口,控制著計(jì)算機(jī)的內(nèi)存、處理器、設(shè)備驅(qū)動(dòng)程序和文件系統(tǒng)等
    的頭像 發(fā)表于 12-13 09:49 ?645次閱讀
    獲取Linux<b class='flag-5'>內(nèi)核</b><b class='flag-5'>源碼</b>的方法

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

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

    AOSP源碼定制-對(duì)root定制的補(bǔ)充流程

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

    linux驅(qū)動(dòng)程序如何加載進(jìn)內(nèi)核

    在Linux系統(tǒng)中,驅(qū)動(dòng)程序是內(nèi)核與硬件設(shè)備之間的橋梁。它們?cè)试S內(nèi)核與硬件設(shè)備進(jìn)行通信,從而實(shí)現(xiàn)對(duì)硬件設(shè)備的控制和管理。 驅(qū)動(dòng)程序的編寫(xiě)
    的頭像 發(fā)表于 08-30 15:02 ?439次閱讀
    RM新时代网站-首页