首页
社区
课程
招聘
linux内核模块:不读pagemap计算物理内存地址
发表于: 2022-11-6 17:19 10010

linux内核模块:不读pagemap计算物理内存地址

2022-11-6 17:19
10010

模块源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#include <linux/semaphore.h>
#include <linux/etherdevice.h>
#include <linux/module.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/poll.h>
#include <linux/string.h>
#include <linux/pci.h>
#include <linux/wait.h>        /* wait_queue_head_t */
#include <linux/interrupt.h>
#include <linux/version.h>
 
#include <linux/types.h>
#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/inet.h>
#include <linux/errno.h>
#include <linux/net.h>
#include <linux/in.h>
#include <linux/uaccess.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/init.h>
 
#include <linux/if_packet.h>
 
#include <asm/pgtable_types.h>
 
//#define    DEBUG
 
#ifndef    DRV_NAME
#define    DRV_NAME    "virt2phys"
#endif
#define    DRV_VERSION    "0.1.0"
#define    virt2phys_DRIVER_NAME    DRV_NAME " driver " DRV_VERSION
 
#if LINUX_VERSION_CODE > KERNEL_VERSION(3,8,0)
#define    __devinit
#define    __devexit
#define    __devexit_p
#endif
 
static int bad_address(void *p)
{
    unsigned long dummy;
    return probe_kernel_address((unsigned long*)p, dummy);
}
 
/*
 * map any virtual address of the current process to its
 * physical one.
 */
static unsigned long long any_v2p(unsigned long long vaddr)
{
    pgd_t *pgd = pgd_offset(current->mm, vaddr);
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
    p4d_t *p4d;
#endif
    pud_t *pud;
    pmd_t *pmd;
    pte_t *pte;
 
    /* to lock the page */
    struct page *pg;
    unsigned long long paddr;
 
    if (bad_address(pgd)) {
        printk(KERN_ALERT "[nskk] Alert: bad address of pgd %p\n", pgd);
        goto bad;
    }
    if (!pgd_present(*pgd)) {
        printk(KERN_ALERT "[nskk] Alert: pgd not present %lu\n", *pgd);
        goto out;
    }
 
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 12, 0)
    p4d = p4d_offset(pgd, vaddr);
    if (p4d_none(*p4d))
        return 0;
    pud = pud_offset(p4d, vaddr);
#else
    pud = pud_offset(pgd, vaddr);
#endif
    if (bad_address(pud)) {
        printk(KERN_ALERT "[nskk] Alert: bad address of pud %p\n", pud);
        goto bad;
    }
    if (!pud_present(*pud) || pud_large(*pud)) {
        printk(KERN_ALERT "[nskk] Alert: pud not present %lu\n", *pud);
        goto out;
    }
 
    pmd = pmd_offset(pud, vaddr);
    if (bad_address(pmd)) {
        printk(KERN_ALERT "[nskk] Alert: bad address of pmd %p\n", pmd);
        goto bad;
    }
    if (!pmd_present(*pmd) || pmd_large(*pmd)) {
        printk(KERN_ALERT "[nskk] Alert: pmd not present %lu\n", *pmd);
        goto out;
    }
 
    pte = pte_offset_kernel(pmd, vaddr);
    if (bad_address(pte)) {
        printk(KERN_ALERT "[nskk] Alert: bad address of pte %p\n", pte);
        goto bad;
    }
    if (!pte_present(*pte)) {
        printk(KERN_ALERT "[nskk] Alert: pte not present %lu\n", *pte);
        goto out;
    }
 
    pg = pte_page(*pte);
#if 1
    paddr = (pte_val(*pte) & PHYSICAL_PAGE_MASK) | (vaddr&(PAGE_SIZE-1));
#else
    pte->pte |= _PAGE_RW; // | _PAGE_USER;
    paddr = pte_val(*pte);
#endif
 
out:
    return paddr;
bad:
    printk(KERN_ALERT "[nskk] Alert: Bad address\n");
    return 0;
}
 
static int virt2phys_open(struct inode *inode, struct file *filp)
{
    printk("%s\n", __func__);
 
    return 0;
}
 
static ssize_t virt2phys_read(struct file *filp, char __user *buf,
               size_t count, loff_t *ppos)
{
    int copy_len;
#ifdef DEBUG
    printk("%s\n", __func__);
#endif
    copy_len = 0;
 
    return copy_len;
}
 
static ssize_t virt2phys_write(struct file *filp, const char __user *buf,
                size_t count, loff_t *ppos)
 
{
    int copy_len;
 
    copy_len = 0;
 
    return copy_len;
}
 
static int virt2phys_release(struct inode *inode, struct file *filp)
{
    printk("%s\n", __func__);
 
    return 0;
}
 
static unsigned int virt2phys_poll( struct file* filp, poll_table* wait )
{
    unsigned int retmask = 0;
 
#ifdef DEBUG
    printk("%s\n", __func__);
#endif
 
    retmask |= POLLHUP;
/*
   Set POLLHUP in retmask if read device is EOF
   Set POLLERR if the device is in error
   Set POLLPRI if out-of-band data can be read
 */
 
    return retmask;
}
 
 
static long virt2phys_ioctl(struct file *filp,
            unsigned int cmd, unsigned long arg)
{
    unsigned long long *ptr, ret;
    printk("%s\n", __func__);
    if (cmd == 1) {
        ptr = (unsigned long long *)arg;
printk( "VA=%p\n", (unsigned long long *)*ptr);
        ret = any_v2p(*ptr);
printk( "PA=%p\n", (unsigned long long *)ret);
        *ptr = ret;
        return 0;
    }
 
    return  -ENOTTY;
}
 
static struct file_operations virt2phys_fops = {
    .owner        = THIS_MODULE,
    .read        = virt2phys_read,
    .write        = virt2phys_write,
    .poll        = virt2phys_poll,
    .unlocked_ioctl        = virt2phys_ioctl,
    .open        = virt2phys_open,
    .release    = virt2phys_release,
};
 
static struct miscdevice virt2phys_dev = {
    .minor = MISC_DYNAMIC_MINOR,
    .name = DRV_NAME,
    .fops = &virt2phys_fops,
};
 
static int __init virt2phys_init(void)
{
    int ret;
 
#ifdef MODULE
    pr_info(virt2phys_DRIVER_NAME "\n");
#endif
    printk("%s\n", __func__);
 
    ret = misc_register(&virt2phys_dev);
    if (ret) {
        printk("fail to misc_register (MISC_DYNAMIC_MINOR)\n");
        goto error;
    }
 
    return 0;
 
error:
    return ret;
}
 
static void __exit virt2phys_cleanup(void)
{
    misc_deregister(&virt2phys_dev);
 
    printk("%s\n", __func__);
}
 
MODULE_LICENSE("GPL");
module_init(virt2phys_init);
module_exit(virt2phys_cleanup);

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <arpa/inet.h>
 
//#define DEBUG
 
#define    MEM_DEVICE    "/dev/virt2phys"
#define    BUF_SIZE    (256)
 
int main(int argc,char **argv)
{
    unsigned long long pa;
    int i, fd;
    if ((fd=open(MEM_DEVICE,O_RDONLY)) <0) {
        fprintf(stderr,"cannot open %s\n",MEM_DEVICE);
        return 1;
    }
    pa = (unsigned long long)&i;
    if ( ioctl( fd, 1, &pa) < 0 ) {
        fprintf(stderr,"cannot IOCTL\n");
        return 1;
    }
    printf("physical address=%012llX\n", pa);
    close(fd);
 
    i = 123;
    while (1) {
        printf ("i=%d, &i=%p, Physical Address=%012llx\n", i, &i, pa);
        usleep(10000);
    }
}

编译

1
2
3
4
5
6
7
8
9
10
11
12
13
MODULE_NAME := virt2phys
RESMAN_CORE_OBJS:=virt2phys.o
RESMAN_GLUE_OBJS:=
ifneq ($(KERNELRELEASE),)
obj-m :=virt2phys.o
else
KDIR :=/lib/modules/$(shell uname -r)/build
PWD        := $(shell pwd)
all:
    make -C $(KDIR) M=$(PWD) modules
clean:
    rm -f *.ko *.o *.mod.o *.mod.c *.symvers *.order
endif

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 2
支持
分享
最新回复 (9)
雪    币: 4583
活跃值: (6836)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
赞一个先,有空在细看
2022-11-7 01:28
0
雪    币: 22
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
收藏
2022-11-9 12:14
0
雪    币: 21
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
怎么用
2022-11-15 11:56
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
5
感谢哥
2022-11-15 16:39
0
雪    币: 21
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
6
大佬可知888处理的手机insmod 模块就死机了怎么回事 最基础的输出helloworld都这样
2022-11-15 20:40
0
雪    币: 183
活跃值: (249)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
厂家做了限制,模块就算加载成功了,物理地址也获取不到,自己编译内核吧
2022-11-16 11:00
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
在linux终端运行这个返回 “已杀死”
2022-11-17 00:37
0
雪    币: 1
活跃值: (150)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
老板接开发吗?可否留个联系方式
2023-4-1 22:29
0
雪    币: 5
活跃值: (2675)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10

error: implicit declaration of function 'probe_kernel_address'

少这个啊

最后于 2023-4-7 10:50 被wx_范迪塞尔编辑 ,原因:
2023-4-7 10:28
0
游客
登录 | 注册 方可回帖
返回
//