1. 程式人生 > >linux核心模組替換系統呼叫

linux核心模組替換系統呼叫

安裝核心模組,使自己的程式碼進入核心空間執行,可以替換linux原有的系統呼叫。

更改mkdir的系統呼叫的核心模組程式碼如下:(ubuntu1510 X86_64)

#include <linux/module.h>
#include <linux/kernel.h>

// 更改83號mkdir中斷處理
#define callnumber 83

// grep sys_call_table /boot/System.map-`uname -r`
unsigned long* sys_call_table = (unsigned long*) 0xffffffff818001c0;

unsigned long bak_syscall = 0;

asmlinkage long mysyscall(void)
{
    printk(KERN_INFO "this is skm syscall");
    return 0;
}

void change_call(unsigned long address)
{
    unsigned long callnumbe = callnumber;
    unsigned long syscalltb = (unsigned long)sys_call_table;
    __asm__ __volatile__  
        (  
         ".intel_syntax noprefix\n"  
         "mov rax,cr0\n"
         "push rax\n"     
         "and rax,0xfffffffffffeffff\n"  
         "mov cr0,rax\n"
         "mov rax,%1\n"
         "mov rbx,%2\n"
         "lea rax,[rax+rbx*8]\n"
         "mov rbx,[rax]\n"
         "mov %0,rbx\n"
         "mov rbx,%3\n"
         "mov [rax],rbx\n"
         "pop rax\n"
         "mov cr0,rax\n"     
         :"=m"(bak_syscall)  
         :"m"(syscalltb),"m"(callnumbe),"m"(address)  
         :"rax","rbx"  
         );  
    printk(KERN_INFO "src syscall method address is 0x%lx\n",bak_syscall);
    printk(KERN_INFO "our syscall method address is 0x%lx\n",address);
}

void recover_call(unsigned long address)
{    
    printk(KERN_INFO "will recover syscall address is 0x%lx\n",address);
    unsigned long callnumbe = callnumber;
    unsigned long syscalltb = (unsigned long)sys_call_table;
    unsigned long result = 0;
    __asm__ __volatile__  
        (  
         ".intel_syntax noprefix\n"  
         "mov rax,cr0\n"
         "push rax\n"     
         "and rax,0xfffffffffffeffff\n"  
         "mov cr0,rax\n"
         "mov rax,%1\n"
         "mov rbx,%2\n"
         "lea rax,[rax+rbx*8]\n"
         "mov %0,rax\n"
         "mov rbx,%3\n"
         "mov [rax],rbx\n"
         "pop rax\n"
         "mov cr0,rax\n"     
         :"=m"(result)
         :"m"(syscalltb),"m"(callnumbe),"m"(address)  
         :"rax","rbx"  
         );  
    printk(KERN_INFO "recover syscall table  address is 0x%lx\n",result);
    printk(KERN_INFO "recover syscall method address is 0x%lx\n",address);
}

int insmod_init(void)
{
    unsigned long para = (unsigned long)(&mysyscall);
    change_call(para);
    return 0;
}
void rmmod_exit(void)
{
    recover_call(bak_syscall);
}


module_init(insmod_init);
module_exit(rmmod_exit);

使用下面語句建立Makefile檔案

obj-m += test.o
VERSIONID = /lib/modules/$(shell uname -r)/build/
all:
	make -C $(VERSIONID) M=$(PWD) modules
clean:
	make -C $(VERSIONID) M=$(PWD) clean

由於程式碼中使用了intel彙編,編譯時Makefile會報錯

需要修改Makefile的對應的程式碼原始碼檔案編譯位置新增 -masm=intel語句

[email protected]:~/program/sun_c/kernel$ make
make -C /lib/modules/4.2.0-25-generic/build/ M=/home/sun/program/sun_c/kernel modules
make[1]: Entering directory '/usr/src/linux-headers-4.2.0-25-generic'
skm===================================
@make -f ./scripts/Makefile.build obj=/home/sun/program/sun_c/kernel
skm==================================
  CC [M]  /home/sun/program/sun_c/kernel/test.o
/home/sun/program/sun_c/kernel/test.c: In function ‘insmod_init’:
/home/sun/program/sun_c/kernel/test.c:79:2: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement]
  unsigned long para = (unsigned long)(&mysyscall);
  ^
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/sun/program/sun_c/kernel/test.mod.o
  LD [M]  /home/sun/program/sun_c/kernel/test.ko
make[1]: Leaving directory '/usr/src/linux-headers-4.2.0-25-generic'

編譯成功使用 sudo insmod test.ko 安裝編譯好的核心模組

然後使用命令dmesg檢視核心日誌會顯示:

[17795.236888] skm change syscall mkdir
[17795.236893] CR0 value is 0x80050033

然後直接在終端執行命令新建目錄 mkdir 123

核心日誌會記錄我們核心模組的相應日誌,表示系統呼叫被我們截斷了

[17795.236888] skm change syscall mkdir
[17795.236893] CR0 value is 0x80050033
[17869.650698] this is skm syscall
[17871.123488] this is skm syscall


相關推薦

linux核心模組替換系統呼叫

安裝核心模組,使自己的程式碼進入核心空間執行,可以替換linux原有的系統呼叫。 更改mkdir的系統呼叫的核心模組程式碼如下:(ubuntu1510 X86_64) #include <linux/module.h> #include <linux/k

Linux核心模組間函式呼叫正確方法

模組之間發生呼叫關係是常有的事情,下面以兩個模組A、B,B使用A模組提供的函式為例,講解正確使用的方法。 模組A中使用EXPORT_SYMBOL或EXPORT_SYMBOL_GPL將要提供給B模組的函式匯出; 模組B中用extern 宣告需要用到的A模組

Linux核心分析——扒開系統呼叫的三層皮(下)

張瑜 《Linux核心分析》MOOC課程 http://mooc.study.163.com/course/USTC-1000029000 一、實驗內容 1. 通過核心的方式使用系統呼叫 上週是從使用者態來看系統呼叫,這周是從核心方面來看這個問題

linux核心分析之系統呼叫

在核心入口函式start_kernel中呼叫trap_init實現系統呼叫的初始化工作 void __init trap_init(void) { ... set_system_trap_gate(SYSCALL_VECTOR, &system_call);

Linux 核心增加一個系統呼叫

實驗原理:核心:核心是整個作業系統的最底層,它負責了整個硬體的驅動以及提供了各種系統所需的核心功能,包括防火牆機制,是否支援LVM或Quota檔案系統,以及程序和記憶體管理和通訊功能。其實核心就是系統上面的一個檔案而已,它包含了驅動主機各項硬體的檢測程式與驅動模組。核心檔案通

Linux核心模組程式設計(列出系統中所有核心執行緒的程式名、PID 號、程序狀態及程序優先順序、父程序的PID)

(1) 設計一個模組,要求列出系統中所有核心執行緒的程式名、PID 號、程序狀態及程序優先順序、父程序的PID。 1.首先,我們開始編寫模組程式碼,這是Linux核心程式設計的核心程式碼,程式碼如下: #include <linux/init.h&

Linux核心模組程式設計-proc檔案系統

什麼是proc proc檔案系統是一個偽檔案系統,它只存在記憶體當中,而不佔用外存空間。它以檔案系統的方式為訪問系統核心資料的操作提供介面。使用者和應用程式可以通過proc得到系統的資訊,並可以改變核心的某些引數。由於系統的資訊,如程序,是動態改變的,所以使用

LINUX核心模組載入Windows下驅動

最近一段時間以來,幾乎每一臺行動式計算機都內建了無線功能,但是它們中有很多並不支援Linux。因此,除非這些計算機設定了雙啟動,這樣做LINUX使用者也未必可以使用無線網絡卡,儘管如此,除非Windows正在執行,否則這些便攜計算機可能依然無法連線到無線網路。   最近一段時間以來,幾乎每一臺行

Linux核心模組程式設計

Linux核心模組程式設計 (作者:Baron_wu 禁止轉載) 首先,建立一個核心模組並插入Linux核心中。這是實驗第一部分 首先檢視當前核心模組使用情概況:lsmod Module:模組名 Size:模組大小 Used by:這些模組在哪被使用 接下來編寫一個simple.c

linux 核心模組程式設計之LED驅動程式(六)

我使用的是tiny6410的核心板,板子如下,淘寶可以買到 為了不與板子上的任何驅動發生IO衝突,我使用CON1那一排沒用到的IO口,引腳如下   LED1 LED2 LED3 LED4

linux 核心模組程式設計之核心符號匯出(五)

/proc/kallsyms 記錄了核心中所有匯出的符號的名字與地址 我們需要編譯2個核心模組,然後其中一個核心模組去呼叫另一個核心模組中的函式 hello.c程式碼如下 #include <linux/module.h> #include <linux/in

linux 核心模組程式設計之模組引數(四)

通過巨集module_param指定模組引數,模組引數用於在載入模組時傳遞給模組。 module_param(name, type, perm) name是模組引數的名字 type是這個引數的型別,常見值:bool、int、charp(字串型) perm是模組

linux 核心模組程式設計之編譯多個原始檔(三)

編譯擁有多個原始檔的核心模組的方式和編譯一個原始檔的方式差不多,我們先來看下我們需要的檔案都有哪些。 首先是main.c檔案 #include <linux/module.h> #include <linux/init.h> MODULE_LICENSE

linux 核心模組程式設計之hello word(二)

我們的目的是要編譯個hello.ko的檔案,然後安裝到核心中。 先來看下需要的程式碼,hello.c檔案如下 #include <linux/module.h> #include <linux/init.h> static int hello_init(vo

linux 核心模組程式設計之環境搭建(一)

這裡介紹些關於Tiny6410開發板核心的編譯,為後期驅動開發做前期的準備。 開發環境:64位的Ubuntu 14.01虛擬機器 目標機:友善之臂Tiny6410開發板 核心:linux-2.6.38-20110325.tar.gz 核心原始碼下載地址 htt

Linux fsync和fdatasync系統呼叫實現分析(Ext4檔案系統

參考:https://blog.csdn.net/luckyapple1028/article/details/61413724 在Linux系統中,對檔案系統上檔案的讀寫一般是通過頁快取(page cache)進行的(DirectIO除外),這樣設計的可以延時磁碟IO的操作,從而可以減少磁碟讀

Linux核心模組程式設計——Hello World

一、實驗環境: 環境配置:VMware® Workstation 15 Pro、ubuntu Desktop 18.10、記憶體 2GB、處理器數量2、每個處理器核心數量1、硬碟大小30GB……還有一個就是用的咱Xidian的源(因為校內不需要流量啊,而且還很快!) 二、知識儲備

Linux核心模組程式設計系列1

1.準備工作 使用如下命令檢視自己Linux的核心版本 uname -a 結果如下: Linux VM-73-203-debian 4.9.0-6-amd64 #1 SMP Debian 4.9.88-1+deb9u1 (2018-05-07) x86_64 GNU/Lin

Linux核心模組開發 Slab快取記憶體介面與用例

在核心模組開發或者驅動開發中經常會使用到記憶體分配,常見的方式是呼叫 kmalloc 介面分配記憶體。 static __always_inline void *kmalloc(size_t size, gfp_t flags); kmalloc介面使用簡單,並且不會對所

關於linux核心模組程式設計時,多個原始碼檔案Makefile書寫的問題

在學習核心模組程式設計的時候遇到了一些由於Makefile書寫不正確導致的問題。一個.c原始檔的Makefile按照網上的大部分資料介紹那樣是沒有問題的,多個原始檔的核心模組程式設計時,就出現問題了,自己糾結了半天,最後查資料、請教大神才搞定的。把過程和解決方法貼出來,供