Another way to HOOK in the kernel

本文介绍了一种利用DRX寄存器进行内核级HOOK的技术,并提供了具体的代码实例。该技术通过设置硬件断点来HOOK ZwCreateFile 函数,实现了对文件创建操作的拦截。
  yykingking

Rk always use HOOK important functions to hide something , and some ARK first recover these hookers ( common by harddisk files) and then call the function.
And this is another way to HOOK in the kernel by DRX register. About the DRX register ,you can google it, there should be much info. So i only post some simple code next because of my poor english, if you know chinese, you can get the comment.

These code should be run in xp, and it simply act HOOK the ZwCreateFile and print the debug information.



/*
drxhook.h
Written By yykingking@126.com
*/

#ifndef _DRX_HOOK
#define _DRX_HOOK

#include <ntddk.h>

typedef unsigned long DWORD;
typedef unsigned char BOOL;

#pragma pack(push,1)
typedef struct _idtr
{
    //定义中断描述符表的限制,长度两字节;
    short        IDTLimit;
    //定义中断描述服表的基址,长度四字节;
    unsigned int    IDTBase;
}IDTR,*PIDTR;

typedef struct _IDTENTRY
{
    unsigned short LowOffset;
    unsigned short selector;
    unsigned char unused_lo;
    unsigned char segment_type:4;    //0x0E is an interrupt gate
    unsigned char system_segment_flag:1;
    unsigned char DPL:2;    // descriptor privilege level
    unsigned char P:1; /* present */
    unsigned short HiOffset;
} IDTENTRY,*PIDTENTRY;

#pragma pack(pop)

DWORD GetDBEntry();
void HookDBInt();
void UnHookDBInt();

#endif


/*
drxhook.cpp
Written By yykingking@126.com
*/


#include "drxhook.h"

DWORD g_OldDBEntry;
IDTR g_IDTR;
DWORD g_OldCreateFile;
DWORD g_HookNumber = 0;
DWORD g_CR0;
BOOL g_bExit;

void ReLoadCR0AndSti()
{
    __asm
    {
        push    eax
            mov        eax, g_CR0
            mov        cr0, eax
            pop        eax
            sti
    }
}

void CliAndDisableWPBit()
{
    __asm
    {
        cli
            push    eax
            mov        eax, cr0
            mov        g_CR0, eax
            and        eax, 0xFFFEFFFF
            mov        cr0, eax
            pop        eax
    }
}


void PrintHook()
{
    DbgPrint(" Now Get In ZwCreateFile Hook: %d...Pid: %d.../n", g_HookNumber++, (DWORD)PsGetCurrentProcessId());
}

__declspec(naked) void NewZwCreateFile()
{
    __asm
    {    
        pushfd;                        // 仅仅适合于 XP 操作系统
        call PrintHook;
        popfd;
        mov eax,0x25;            
        jmp g_OldCreateFile;
    }
}

void SetHB()            // set hardware breakpoint 设置硬件断点
{
    __asm
    {
        mov eax, ZwCreateFile;        // 想要挂接的函数或者地址
        mov dr0, eax;
        mov eax, dr7;
        or  eax, 0x2703;            // 也要修改 dr7:GD 位,以免DrX被操作系统或其他程序修改
        and eax, 0xfff0ffff;
        mov dr7, eax;
    }
}

__declspec(naked) void NewDBEntry()
{
    __asm
    {
        pushfd;
        push eax;

        mov eax, dr6;
        test eax, 0x2000;
        jz  NOT_EDIT_DRX;

        // 以下是如果有对DRX的操作的简单处理,如有需要可以修改
        // 我只是简单的跳过这些指令
        and eax, 0xFFFFDFFF;
        mov dr6, eax;            // 清除DR6的标志

        cmp g_bExit, 0;
        jnz MY_DRV_EXIT;        // 驱动 Unload

        mov eax, [esp+8];        // 获取堆栈中的 EIP
        add eax, 3;                // 由于所有对 DRX 的操作全都是3个字节的
        mov [esp+8], eax;        // 修改 EIP ,跳过当前指令,返回时执行下条指令

        jmp MY_INT_END;

NOT_EDIT_DRX:

        mov eax, dr6;
        test eax, 0x1;
        jz  SYS_INT;            // 如果不是Dr0 产生的中断,则跳回原系统中断

        mov eax, [esp+8];
        cmp eax, ZwCreateFile;    // 判断一下是不是 ZwCreateFile 的线性地址
        jnz SYS_INT;

        mov eax, NewZwCreateFile;
        mov [esp+8],eax;        // 修改堆栈中的 EIP ,实现返回时跳转


MY_INT_END:    

        mov eax, dr7;
        or  eax, 0x2000;        // 恢复 GD 位
        mov dr7, eax;

MY_DRV_EXIT:                    // 整个驱动 UnLoad 时,不恢复 Dr7

        pop eax;
        popfd;
        iretd;

SYS_INT:
        pop eax;
        popfd;
        jmp g_OldDBEntry;
        
    }
}

DWORD GetDBEntry()
{
    PIDTENTRY IdtEntry;
    DWORD Entry;

    __asm sidt g_IDTR;

    IdtEntry = (PIDTENTRY)(g_IDTR.IDTBase + 8);

    Entry = IdtEntry->HiOffset << 16;
    
    Entry |= IdtEntry->LowOffset;

    return Entry;
}

void HookDBInt()
{
    DWORD NewEntry;
    PIDTENTRY IdtEntry;

    NewEntry = (DWORD)NewDBEntry;

    g_OldCreateFile = (DWORD)ZwCreateFile + 5;        // 新的要跳转过去的地址

    g_OldDBEntry = GetDBEntry();

    IdtEntry = (PIDTENTRY)(g_IDTR.IDTBase + 8);

    CliAndDisableWPBit();

    IdtEntry->LowOffset = (USHORT)NewEntry;

    IdtEntry->HiOffset = (USHORT)( NewEntry >> 16 );

    ReLoadCR0AndSti();

    SetHB();

    g_bExit = FALSE;

    return;
}

void UnHookDBInt()
{
    PIDTENTRY IdtEntry;
    DWORD Entry;
    
    __asm sidt g_IDTR;
    
    IdtEntry = (PIDTENTRY)(g_IDTR.IDTBase + 8);

    CliAndDisableWPBit();

    g_bExit = TRUE;

    __asm mov eax, dr7;                // 产生一次例外并且清除Dr7:GD

    if ( g_OldDBEntry != 0 )
    {
        IdtEntry->LowOffset = (USHORT)g_OldDBEntry;
        
        IdtEntry->HiOffset = (USHORT)( g_OldDBEntry >> 16 );        
    }

    ReLoadCR0AndSti();
    
    DbgPrint(" UnLoad drx hook../n");

    return;
}

NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject)
{    
    UnHookDBInt();
    
    return STATUS_SUCCESS;
}

NTSTATUS DriverEntry(
                     IN PDRIVER_OBJECT  DriverObject,
                     IN PUNICODE_STRING RegistryPath
                     )
{
    HookDBInt();
    
    DriverObject->DriverUnload = DriverUnload;

    DbgPrint("Load drxhook Driver Ok.../n");

    return STATUS_SUCCESS;
}
/***********************/

提供了基于BP(Back Propagation)神经网络结合PID(比例-积分-微分)控制策略的Simulink仿真模型。该模型旨在实现对杨艺所著论文《基于S函数的BP神经网络PID控制器及Simulink仿真》中的理论进行实践验证。在Matlab 2016b环境下开发,经过测试,确保能够正常运行,适合学习和研究神经网络在控制系统中的应用。 特点 集成BP神经网络:模型中集成了BP神经网络用于提升PID控制器的性能,使之能更好地适应复杂控制环境。 PID控制优化:利用神经网络的自学习能力,对传统的PID控制算法进行了智能调整,提高控制精度和稳定性。 S函数应用:展示了如何在Simulink中通过S函数嵌入MATLAB代码,实现BP神经网络的定制化逻辑。 兼容性说明:虽然开发于Matlab 2016b,但理论上兼容后续版本,可能会需要调整少量配置以适配不同版本的Matlab。 使用指南 环境要求:确保你的电脑上安装有Matlab 2016b或更高版本。 模型加载: 下载本仓库到本地。 在Matlab中打开.slx文件。 运行仿真: 调整模型参数前,请先熟悉各模块功能和输入输出设置。 运行整个模型,观察控制效果。 参数调整: 用户可以自由调节神经网络的层数、节点数以及PID控制器的参数,探索不同的控制性能。 学习和修改: 通过阅读模型中的注释和查阅相关文献,加深对BP神经网络与PID控制结合的理解。 如需修改S函数内的MATLAB代码,建议有一定的MATLAB编程基础。
Android 内核中,hook 点通常涉及对系统调用表、函数调用流程以及模块加载机制的干预。以下是 Android 内核中常见的 hook 点和技术: ### 1. 系统调用表(sys_call_table)hook Android 内核基于 Linux,其系统调用通过 `sys_call_table` 表进行管理。通过修改该表中的函数指针,可以将系统调用重定向到自定义的处理函数。例如,hook `sys_open` 或 `sys_openat` 系统调用以监控文件访问行为。此方法需要将 `sys_call_table` 所在内存区域从只读更改为可写,然后替换对应的函数指针[^3]。 ```c // 示例:修改 sys_call_table 的只读属性并替换系统调用 unsigned long **sys_call_table; // 修改内存页的读写权限 pte_t *pte = lookup_address((unsigned long)sys_call_table, &flags); pte_clear_flags(pte, _PAGE_RO); // 替换 open 系统调用 sys_call_table[__NR_open] = (unsigned long *)my_custom_open; ``` ### 2. 内核模块(LKM)hook 通过加载可加载内核模块(Loadable Kernel Module, LKM),可以动态地在内核空间插入 hook 逻辑。LKM 可以注册自己的钩子函数,并替换原有函数指针以实现拦截和修改功能。例如,用于 hook 系统调用或特定内核函数的执行流程[^2]。 ### 3. ftrace hook ftrace 是 Linux 内核提供的一个强大的函数跟踪机制,也可以用于 hook 内核函数。通过 `ftrace` 提供的接口,可以注册回调函数来拦截目标函数的执行。此方法常用于调试和性能分析,但也可用于 hook 关键函数。 ```c // 示例:使用 ftrace hook 某个内核函数 static struct ftrace_hook hook; fh_install_hook("target_function_name", my_hook_handler, &hook); ``` ### 4. kprobe hook kprobe 是 Linux 内核提供的动态探测机制,允许在任意内核函数中插入探针以执行自定义逻辑。kprobe 支持 pre-handler 和 post-handler,可以在目标函数执行前后进行干预[^1]。 ```c // 示例:使用 kprobe hook 内核函数 static struct kprobe kp = { .symbol_name = "target_function", .pre_handler = my_pre_handler, .post_handler = my_post_handler, }; register_kprobe(&kp); ``` ### 5. syscall hook 与 compat_sys_call_table 在 64 位系统上,`compat_sys_call_table` 用于支持 32 位应用程序的系统调用。通过 hook 该表,可以拦截兼容模式下的系统调用请求。例如,在 Android 设备上对 `compat_sys_open` 进行 hook 以监控 32 位应用的文件操作[^4]。 ### 6. LSM(Linux Security Module)hook LSM 是 Linux 内核的安全框架,提供了一系列 hook 点用于实现安全策略。Android 使用 SELinux 作为其 LSM 实现,通过注册 LSM 模块可以 hook 安全相关的操作,例如文件访问、进程执行等。 ```c // 示例:在 LSM 中注册 hook static struct security_hook_list my_hooks[] __lsm_ro_after_init = { LSM_HOOK_INIT(file_open, my_file_open_hook), }; ``` ### 7. 模块初始化 hook 在内核模块加载时,可以通过 `init_module` 或 `finit_module` 系统调用进行 hook,以监控或修改模块加载行为。这在实现 rootkit 或安全检测工具中较为常见。 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值