【干货】【C语言实现HOOK 跳转和用C语言变量存储目标进程的寄存器数值】 CALL / JMP/ MOV 变量内存地址

1、有的时候要构造一个CALL ,那么CALL后面的地址对应的4个字节怎么弄呢?,就用下面的 函数
void WriteCall(DWORD ProcAddr,LPVOID lpData)
{
BYTE _data[5];
_data[0]=0xE8;
DWORD OldPro;
VirtualProtect((LPVOID)(ProcAddr),5,PAGE_EXECUTE_READWRITE,&OldPro);

memcpy((LPVOID)(_data+1),lpData,4);//_data是变量的内存地址

memcpy((LPVOID)(ProcAddr),_data,5);

VirtualProtect((LPVOID)(ProcAddr),5,OldPro,&OldPro);//内存属性恢复为只读

}

2、有的时候要构造一个JMP跳转后的字节, 就用下面的代码,其实和CALL差不多
void WriteCall(DWORD ProcAddr,LPVOID lpData)
{
BYTE _data[5];
_data[0]=0xE9;
DWORD OldPro;
VirtualProtect((LPVOID)(ProcAddr),5,PAGE_EXECUTE_READWRITE,&OldPro);

memcpy((LPVOID)(_data+1),lpData,4);//_data是变量的内存地址

memcpy((LPVOID)(ProcAddr),_data,5);

VirtualProtect((LPVOID)(ProcAddr),5,OldPro,&OldPro);//内存属性恢复为只读

}

RMC.exe+16650 - 89 15 56 34 12 00 - mov [00123456],edx
3、有的时候将某个寄存器数字比如上面的edx数值保存到 C语言变量X里面,就用下面的代码
void WriteMovEdx(DWORD ProcAddr,LPVOID lpData)
{
BYTE _data[6];
_data[0]=0x89;
_data[1]=0x15;

DWORD OldPro;
VirtualProtect((LPVOID)(ProcAddr),6,PAGE_EXECUTE_READWRITE,&OldPro);

memcpy((LPVOID)(_data+2),lpData,4);//_data是变量的内存地址

memcpy((LPVOID)(ProcAddr),_data,6);

VirtualProtect((LPVOID)(ProcAddr),6,OldPro,&OldPro);//内存属性恢复为只读

}

void WriteMovEax(DWORD ProcAddr,LPVOID lpData)
{
BYTE _data[6];
_data[0]=0x89;
_data[1]=0x05;

DWORD OldPro;
VirtualProtect((LPVOID)(ProcAddr),6,PAGE_EXECUTE_READWRITE,&OldPro);

memcpy((LPVOID)(_data+2),lpData,4);//_data是变量的内存地址

memcpy((LPVOID)(ProcAddr),_data,6);

VirtualProtect((LPVOID)(ProcAddr),6,OldPro,&OldPro);//内存属性恢复为只读

}

下面是具体调用如上函数的实际例子,在红月这个游戏上测试通过

有的时候将某个寄存器数字比如上面的edx数值保存到 遍历X里面,就用下面的代码
调用如下
DWORD x=0;
x=(DWORD)&x;//获取变量的内存地址
DWORD addr1=0x123456 ;
WriteMovEdx(addr1,&x); // 构建 mov [&x],edx

//下面是CALL的构造 JMP 跳转构造也是类似下面的
JMP 或者CALL后面的 地址对应的机器码计算 公式:目的代码地址 - 当前代码地址-5
DWORD ad1=hMod +0xAAA6C;
DWORD ad2=hMod2+0xD9C0 ;
DWORD cha =ad2-ad1-5; // 目的代码地址 - 当前代码地址-5
WriteCall(ad1,&cha); //call 打印字符的函数

QQ 1016058890

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
首先,需要明确一点:Linux hook函数是一类内核函数,它们被用来拦截并处理一些系统调用或硬件中断等事件。因此,要实现在write和read设备文件时操作某个寄存器,就需要编写hook函数,将其注册到相应的系统调用中。 以下是一个示例代码,用于在write和read设备文件时访问某个寄存器: ```c #include <linux/module.h> #include <linux/kernel.h> #include <linux/init.h> #include <linux/fs.h> #include <asm/uaccess.h> #define DEVICE_NAME "mydevice" #define DEVICE_MAJOR 240 /* 定义寄存器地址 */ #define REG_ADDR 0x1234 /* 定义hook函数 */ static ssize_t mydevice_read(struct file *file, char __user *buf, size_t count, loff_t *offset) { int value; /* 读取寄存器的值 */ value = inw(REG_ADDR); /* 将寄存器的值写入用户空间 */ if (copy_to_user(buf, &value, sizeof(value))) { return -EFAULT; } return sizeof(value); } static ssize_t mydevice_write(struct file *file, const char __user *buf, size_t count, loff_t *offset) { int value; /* 从用户空间读取数据 */ if (copy_from_user(&value, buf, sizeof(value))) { return -EFAULT; } /* 写入寄存器 */ outw(value, REG_ADDR); return count; } /* 定义file_operations结构体 */ static struct file_operations mydevice_fops = { .owner = THIS_MODULE, .read = mydevice_read, .write = mydevice_write, }; /* 模块初始化函数 */ static int __init mydevice_init(void) { int ret; /* 注册字符设备 */ ret = register_chrdev(DEVICE_MAJOR, DEVICE_NAME, &mydevice_fops); if (ret < 0) { printk(KERN_ERR "Failed to register device.\n"); return ret; } printk(KERN_INFO "Device registered with major number %d.\n", DEVICE_MAJOR); return 0; } /* 模块卸载函数 */ static void __exit mydevice_exit(void) { unregister_chrdev(DEVICE_MAJOR, DEVICE_NAME); printk(KERN_INFO "Device unregistered.\n"); } module_init(mydevice_init); module_exit(mydevice_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Your Name"); MODULE_DESCRIPTION("A simple device driver with hook function."); ``` 上述代码中,我们定义了两个hook函数:mydevice_read和mydevice_write。在mydevice_read函数中,我们使用inw函数读取寄存器的值,并将其写入用户空间;在mydevice_write函数中,我们使用outw函数将从用户空间读取到的数据写入寄存器。 需要注意的是,我们使用了两个内联汇编函数inw和outw来读写寄存器。这些函数会将指定地址处的数据读取到寄存器中,或将寄存器中的数据写入指定地址。这些寄存器通常是与硬件设备相关的寄存器,具体的操作方式和寄存器地址需要根据硬件设备的设计进行调整。 最后,我们将定义好的file_operations结构体注册到字符设备中,并在模块初始化函数和卸载函数中分别调用register_chrdev和unregister_chrdev函数来完成设备的注册和卸载。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

侠客软件开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值