转载一份老外的 xun 内存读写模块

    xiaoxiao2026-05-23  13

    #include <mach/host_info.h>

    #include <mach/mach_host.h>

    #include <mach/shared_region.h>

    #include <mach/mach.h>

    #include <mach-o/dyld.h>

        

    #include <stdlib.h>

    #include <stdio.h>

    #import <dlfcn.h>

        

    #include <assert.h>

    #include <errno.h>

        

    #include <sys/sysctl.h>

    #include <sys/mman.h>

        

    #pragma mark read and write

        /* Note : buffer must be free'd manually */

        unsigned char * xnu_read (int pid, void* addr, size_t* size)

        {

            assert(*size != 0 || addr != 0);

            *size = _word_align(*size);

            

            unsigned char *rbuffer = (unsigned char*)malloc(*size);

            if (rbuffer == 0)

                printf("Allocation error : xnu_read \n");

            

            mach_msg_type_number_t data_cnt;

            mach_port_t task;

            

            kern_return_t kernret = task_for_pid(mach_task_self(), pid, &task);

            if (kernret != KERN_SUCCESS)

                printf("Error : task_for_pid \n");

            

            kernret = vm_read(task, (vm_address_t)addr, *size, (vm_offset_t*)&rbuffer, &data_cnt);

            

            if(kernret != KERN_SUCCESS)

                free(rbuffer);

            

            return rbuffer;

        }

        

        int xnu_write (int pid, void* addr, unsigned char* data, size_t dsize)

        {

            assert(dsize != 0);

            assert(addr != 0);

            assert(data != 0);

            

            dsize = _word_align(dsize);

            unsigned char * ptxt = (unsigned char*)malloc(dsize);

            

            assert(ptxt != 0);

            memcpy(ptxt, data, dsize);

            

            mach_port_t task;

            //vm_info_region_t  regbackup;

            mach_msg_type_number_t dataCunt = dsize;

            

            kern_return_t kret = task_for_pid(mach_task_self(), pid, &task);

            

            //mach_vm_region_info(task, (vm_address_t)addr, ®backup,0 , 0);

            

            /* retrieve write permision */

            vm_protect(task, (vm_address_t)addr, (vm_size_t)dsize, 0, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_ALL);

            

            kret = vm_write(task, (vm_address_t)addr, (pointer_t)ptxt, dataCunt);

            

            return kret;

        }

        

        mach_error_t setpage_exec(void *address)

        {

            mach_error_t err = err_none;

            vm_size_t pageSize;

            

            host_page_size( mach_host_self(), &pageSize );

            uintptr_t page = (uintptr_t)address & ~(uintptr_t)(pageSize-1);

            int e = err_none;

            

            e |= mprotect((void *)page, pageSize, PROT_EXEC | PROT_READ);

            e |= msync((void *)page, pageSize, MS_INVALIDATE );

            if (e) {

                printf("Cannot create executable page\n");

            }

            

            return err;

        }

        

        

        size_t _word_align(size_t size)

        {

            size_t rsize = 0;

            

            rsize = ((size % sizeof(long)) > 0) ? (sizeof(long) - (size % sizeof(long))) : 0;

            rsize += size;

            

            return rsize;

        }

        

        /* Mach-O format related functions */

    #pragma mark macho

        __uint64_t getAddressOfLibrary( char* libraryPath )

        {

            const struct mach_header* mh;

            

            int n = _dyld_image_count();

            

            int i = 0;

            for( i = 0; i < n; i++ )

            {

                mh = _dyld_get_image_header(i);

                if( mh->filetype != MH_DYLIB ){ continue; }

                

                const char* imageName = _dyld_get_image_name(i);

                printf("%s\n",imageName);

                if( strcmp(imageName, libraryPath) == 0 )

                {

                    struct segment_command_64* seg;

                    struct load_command* cmd;

                    cmd = (struct load_command*)((char*)mh + sizeof(struct mach_header_64));

                    

                    int j = 0;

                    for( j = 0; j < mh->ncmds; j++ )

                    {

                        if( cmd->cmd == LC_SEGMENT_64 )

                        {

                            seg = (struct segment_command_64*)cmd;

                            if( strcmp(seg->segname, SEG_TEXT) == 0 )

                            {

                                return seg->vmaddr + (__uint64_t)_dyld_get_image_vmaddr_slide(i);

                            }

                        }

                        

                        cmd = (struct load_command*)((char*)cmd + cmd->cmdsize);

                    }

                    

                    return _dyld_get_image_vmaddr_slide(i);

                }

            }

            

            return 0;

        }

        

        /* Retrieve symbol pointer at runtime */

        __uint64_t getAddressOfSymbol(char* libpath, char * symbol)

        {

            void* hlib = dlopen(libpath, RTLD_NOW);

            void* funcaddr64 = dlsym(hlib, symbol);

            return (unsigned long long)funcaddr64;

        }

        

        

    #pragma mark processes

        int32_t procpid (char* procname)

        {

            pid_t pid;

            int j;

            kinfo_proc * proclist;

            size_t procCount;

            

            getprocessList(&proclist, &procCount);

            

            for (j = 0; j < procCount +1; j++) {

                if (strcmp(proclist[j].kp_proc.p_comm, procname) == 0 )

                    pid = proclist[j].kp_proc.p_pid;

            }

            

            free(proclist);

            return pid;

        }

        

        static int getprocessList(kinfo_proc **procList, size_t *procCount)

        {

            int                 err;

            kinfo_proc *        result;

            int                 done;

            static const int    name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 };

            

            size_t              length;

            

            assert( procList != NULL);

            //assert(*procList == NULL);

            assert(procCount != NULL);

            

            *procCount = 0;

            

            result = NULL;

            done = 0;

            do {

                assert(result == NULL);

                

                length = 0;

                err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,

                             NULL, &length,

                             NULL, 0);

                if (err == -1) {

                    err = errno;

                }

                

                

                if (err == 0) {

                    result = malloc(length);

                    if (result == NULL) {

                        err = ENOMEM;  

                    }  

                }  

                

                if (err == 0) {  

                    err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1,  

                                 result, &length,  

                                 NULL, 0);  

                    if (err == -1) {  

                        err = errno;  

                    }  

                    if (err == 0) {  

                        done = 1;  

                    } else if (err == ENOMEM) {  

                        assert(result != NULL);  

                        free(result);  

                        result = NULL;  

                        err = 0;  

                    }  

                }  

            } while (err == 0 && ! done);  

            

            

            if (err != 0 && result != NULL) {  

                free(result);  

                result = NULL;  

            }  

            *procList = result;  

            if (err == 0) {  

                *procCount = length / sizeof(kinfo_proc);  

            }  

            

            assert( (err == 0) == (*procList != NULL) );  

            

            return err;  

        }

    相关资源:x64内存读写驱动
    最新回复(0)