从用户空间访问内核内存(task_struct)

时间:2018-01-21 16:05:08

标签: c linux memory linux-kernel

这与这个问题有些相关:

Direct access to structure task_struct from Usermode as root

编写了一个打印任务结构指针的模块(task_struct):

#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/errno.h>   /* error codes */
#include <linux/sched.h>


MODULE_LICENSE("Dual BSD/GPL");

/* Declaration of functions */
void device_exit(void);
int device_init(void);

/* Declaration of the init and exit routines */
module_init(device_init);
module_exit(device_exit);

int device_init(void)
{
    struct task_struct *task = current; // getting global current pointer
    printk(KERN_NOTICE "ptr:%p", task);
    printk(KERN_NOTICE "assignment: current process: %s, PID: %d", task->comm, task->pid);
    do
    {
        task = task->parent;
        printk(KERN_NOTICE "assignment: parent process: %s, PID: %d", task->comm, task->pid);

    } while (task->pid != 0);
    return 0;
}

void device_exit(void) {
  printk(KERN_NOTICE "assignment: exiting module");
}

执行:

[  547.605259] ptr:e6d7f500
[  547.605267] assignment: current process: insmod, PID: 4297
[  547.605273] assignment: parent process: bash, PID: 4255
[  547.605277] assignment: parent process: sudo, PID: 4254
[  547.605282] assignment: parent process: bash, PID: 2967
[  547.605286] assignment: parent process: gnome-terminal-, PID: 2960
[  547.605292] assignment: parent process: upstart, PID: 2086
[  547.605296] assignment: parent process: lightdm, PID: 1958
[  547.605312] assignment: parent process: lightdm, PID: 1700
[  547.605316] assignment: parent process: systemd, PID: 1
[  547.605320] assignment: parent process: swapper/0, PID: 0

似乎是一个task_struct:

(gdb) p (struct task_struct)*0xe6d7f500
$7 = {state = -422057152, stack = 0xf5a32000, usage = {counter = 0}, flags = 4243468, ptrace = 0, wake_entry = {next = 0x0}, on_cpu = 0, 
  wakee_flips = 5, wakee_flip_decay_ts = 2832024, last_wakee = 0xf47a57c0, wake_cpu = 0, on_rq = 0, prio = 120, static_prio = 120, 
  normal_prio = 120, rt_priority = 0, sched_class = 0xc18242a0 <fair_sched_class>, se = {load = {weight = 1024, inv_weight = 4194304}, 
    run_node = {__rb_parent_color = 1, rb_right = 0x0, rb_left = 0x0}, group_node = {next = 0xe6d7f558, prev = 0xe6d7f558}, on_rq = 0, 
    exec_start = 3132329904926, sum_exec_runtime = 2092639, vruntime = 806833810844, prev_sum_exec_runtime = 2052832, nr_migrations = 3, 
    statistics = {wait_start = 0, wait_max = 7856, wait_count = 4, wait_sum = 7856, iowait_count = 0, iowait_sum = 0, sleep_start = 0, 
      sleep_max = 1905612, sum_sleep_runtime = 1905612, block_start = 0, block_max = 0, exec_max = 870311, slice_max = 0, 
      nr_migrations_cold = 0, nr_failed_migrations_affine = 0, nr_failed_migrations_running = 0, nr_failed_migrations_hot = 0, 
      nr_forced_migrations = 0, nr_wakeups = 1, nr_wakeups_sync = 0, nr_wakeups_migrate = 1, nr_wakeups_local = 0, nr_wakeups_remote = 1, 
      nr_wakeups_affine = 0, nr_wakeups_affine_attempts = 0, nr_wakeups_passive = 0, nr_wakeups_idle = 0}, depth = 0, parent = 0x0, 
    cfs_rq = 0xf77b3e80, my_q = 0x0, avg = {last_update_time = 3132329904926, load_sum = 46825188, util_sum = 45723, period_contrib = 827, 
      load_avg = 974, util_avg = 974}}, rt = {run_list = {next = 0xe6d7f694, prev = 0xe6d7f694}, timeout = 0, watchdog_stamp = 0, 
    time_slice = 100, back = 0x0}, sched_task_group = 0xc1be7200 <root_task_group>, dl = {rb_node = {__rb_parent_color = 3872913072, 
      rb_right = 0x0, rb_left = 0x0}, dl_runtime = 0, dl_deadline = 0, dl_period = 0, dl_bw = 0, runtime = 0, deadline = 0, flags = 0, 
    dl_throttled = 0, dl_new = 1, dl_boosted = 0, dl_yielded = 0, dl_timer = {node = {node = {__rb_parent_color = 3872913152, rb_right = 0x0, 
          rb_left = 0x0}, expires = {tv64 = 0}}, _softexpires = {tv64 = 0}, function = 0xc1080ad0 <dl_task_timer>, base = 0xf77e3600, 
      state = 0, start_pid = -1, start_site = 0x0, start_comm = '\000' <repeats 15 times>}}, btrace_seq = 0, policy = 0, nr_cpus_allowed = 4, 
  cpus_allowed = {bits = {15}}, sched_info = {pcount = 3, run_delay = 44302, last_arrival = 3132329614776, last_queued = 0}, tasks = {
    next = 0xc1a8ad2c <init_task+620>, prev = 0x200}, pushable_tasks = {prio = 140, prio_list = {next = 0xe6d7f778, prev = 0xe6d7f778}, 
    node_list = {next = 0xe6d7f780, prev = 0xe6d7f780}}, pushable_dl_tasks = {__rb_parent_color = 3872913288, rb_right = 0x0, rb_left = 0x0}, 
  mm = 0x0, active_mm = 0x0, vmacache_seqnum = 5, vmacache = {0xe6c53e18, 0xe6c53cb8, 0xe6c53d68, 0xe6c531b8}, rss_stat = {events = 0, 
    count = {0, 0, 0}}, exit_state = 16, exit_code = 0, exit_signal = 17, pdeath_signal = 0, jobctl = 0, personality = 0, in_execve = 0, 
  in_iowait = 0, sched_reset_on_fork = 0, sched_contributes_to_load = 0, sched_migrated = 0, atomic_flags = 0, restart_block = {
    fn = 0xc10585b0 <do_no_restart_syscall>, {futex = {uaddr = 0x96f3b20, val = 2, flags = 0, bitset = 0, time = 0, uaddr2 = 0x0}, 
      nanosleep = {clockid = 158284576, rmtp = 0x2, expires = 0}, poll = {ufds = 0x96f3b20, nfds = 2, has_timeout = 0, tv_sec = 0, 
        tv_nsec = 0}}}, pid = 24713, tgid = 24713, real_parent = 0xf47a57c0, parent = 0xf47a57c0, children = {next = 0xe6d7f810, 
    prev = 0xe6d7f810}, sibling = {next = 0xe6d7f818, prev = 0xe6d7f818}, group_leader = 0xe6d7f500, ptraced = {next = 0xe6d7f824, 
    prev = 0xe6d7f824}, ptrace_entry = {next = 0xe6d7f82c, prev = 0xe6d7f82c}, pids = {{node = {next = 0x0, pprev = 0x200}, pid = 0x0}, {
      node = {next = 0xf47a5b00, pprev = 0x200}, pid = 0x0}, {node = {next = 0xf47a5b0c, pprev = 0x200}, pid = 0x0}}, thread_group = {
    next = 0xe6d7f858, prev = 0x200}, thread_node = {next = 0xf44923cc, prev = 0x200}, vfork_done = 0x0, set_child_tid = 0x401fe768, 
  clear_child_tid = 0x0, utime = 1, stime = 1, utimescaled = 1, stimescaled = 1, gtime = 0, prev_cputime = {utime = 0, stime = 0, lock = {
      raw_lock = {val = {counter = 0}}}}, nvcsw = 2, nivcsw = 1, start_time = 3132325756533, real_start_time = 3132325759608, min_flt = 74, 
  maj_flt = 0, cputime_expires = {utime = 0, stime = 0, sum_exec_runtime = 0}, cpu_timers = {{next = 0xe6d7f8c4, prev = 0xe6d7f8c4}, {
      next = 0xe6d7f8cc, prev = 0xe6d7f8cc}, {next = 0xe6d7f8d4, prev = 0xe6d7f8d4}}, real_cred = 0x0, cred = 0x0, 
  comm = "sh\000e\000-terminal-", nameidata = 0x0, sysvsem = {undo_list = 0x0}, sysvshm = {shm_clist = {next = 0xe6d7f8fc, 
      prev = 0xe6d7f8fc}}, fs = 0x0, files = 0x0, nsproxy = 0x0, signal = 0xf44923c0, sighand = 0x0, blocked = {sig = {0, 0}}, 
  real_blocked = {sig = {0, 0}}, saved_sigmask = {sig = {0, 0}}, pending = {list = {next = 0xe6d7f930, prev = 0xe6d7f930}, signal = {sig = {
        0, 0}}}, sas_ss_sp = 0, sas_ss_size = 0, notifier = 0x0, notifier_data = 0x0, notifier_mask = 0x0, 
  task_works = 0xc1be7194 <work_exited>, audit_context = 0x0, loginuid = {val = 4294967295}, sessionid = 4294967295, seccomp = {mode = 0, 
    filter = 0x0}, parent_exec_id = 19, self_exec_id = 20, alloc_lock = {{rlock = {raw_lock = {val = {counter = 0}}}}}, pi_lock = {
    raw_lock = {val = {counter = 0}}}, wake_q = {next = 0x0}, pi_waiters = {rb_node = 0x0}, pi_waiters_leftmost = 0x0, pi_blocked_on = 0x0, 
  journal_info = 0x0, bio_list = 0x0, plug = 0x0, reclaim_state = 0x0, backing_dev_info = 0x0, io_context = 0x0, ptrace_message = 2237, 
---Type <return> to continue, or q <return> to quit---
  last_siginfo = 0x0, ioac = {rchar = 1299, wchar = 0, syscr = 6, syscw = 0, read_bytes = 0, write_bytes = 0, cancelled_write_bytes = 0}, 
  acct_rss_mem1 = 160000, acct_vm_mem1 = 2045000, acct_timexpd = 2, mems_allowed = {bits = {1}}, mems_allowed_seq = {sequence = 0}, 
  cpuset_mem_spread_rotor = -1, cpuset_slab_spread_rotor = -1, cgroups = 0xc1aa17a0 <init_css_set>, cg_list = {next = 0xe6d7fa0c, 
    prev = 0xe6d7fa0c}, robust_list = 0x0, pi_state_list = {next = 0xe6d7fa18, prev = 0xe6d7fa18}, pi_state_cache = 0x0, perf_event_ctxp = {
    0x0, 0x0}, perf_event_mutex = {count = {counter = 1}, wait_lock = {{rlock = {raw_lock = {val = {counter = 0}}}}}, wait_list = {
      next = 0xe6d7fa34, prev = 0xe6d7fa34}, owner = 0x0, osq = {tail = {counter = 0}}}, perf_event_list = {next = 0xe6d7fa44, 
    prev = 0xe6d7fa44}, tlb_ubc = {cpumask = {bits = {0}}, flush_required = false, writable = false}, rcu = {next = 0xf4da8b40, 
    func = 0xc104cc00 <delayed_put_task_struct>}, splice_pipe = 0x0, task_frag = {page = 0x0, offset = 0, size = 0}, delays = 0x0, 
  nr_dirtied = 0, nr_dirtied_pause = 32, dirty_paused_when = 0, timer_slack_ns = 50000, default_timer_slack_ns = 50000, trace = 0, 
  trace_recursion = 0, pagefault_disabled = 0, thread = {tls_array = {{{{a = 692125695, b = 1088418306}, {limit0 = 65535, base0 = 10560, 
            base1 = 2, type = 2, s = 1, dpl = 3, p = 1, limit = 15, avl = 1, l = 0, d = 1, g = 1, base2 = 64}}}, {{{a = 0, b = 0}, {
            limit0 = 0, base0 = 0, base1 = 0, type = 0, s = 0, dpl = 0, p = 0, limit = 0, avl = 0, l = 0, d = 0, g = 0, base2 = 0}}}, {{{
            a = 0, b = 0}, {limit0 = 0, base0 = 0, base1 = 0, type = 0, s = 0, dpl = 0, p = 0, limit = 0, avl = 0, l = 0, d = 0, g = 0, 
            base2 = 0}}}}, sp0 = 4121116664, sp = 4121116408, sysenter_cs = 96, ip = 3246485854, gs = 0, ptrace_bps = {0x0, 0x0, 0x0, 0x0}, 
    debugreg6 = 0, ptrace_dr7 = 0, cr2 = 0, trap_nr = 0, error_code = 0, io_bitmap_ptr = 0x0, iopl = 0, io_bitmap_max = 0, fpu = {
      last_cpu = 4294967295, fpstate_active = 0 '\000', fpregs_active = 0 '\000', counter = 0 '\000', state = {fsave = {cwd = 895, swd = 0, 
          twd = 0, fip = 0, fcs = 0, foo = 0, fos = 8064, st_space = {196607, 0 <repeats 19 times>}, status = 0}, fxsave = {cwd = 895, 
          swd = 0, twd = 0, fop = 0, {{rip = 0, rdp = 0}, {fip = 0, fcs = 0, foo = 0, fos = 0}}, mxcsr = 8064, mxcsr_mask = 196607, 
          st_space = {0 <repeats 32 times>}, xmm_space = {1697592888, 2037544046, 0, 0, 2189525896, 1107330948, 1931502689, 25205, 
            1751347809, 0, 0, 0, 1647211365, 1953261941, 28265, 15, 0 <repeats 48 times>}, padding = {0 <repeats 12 times>}, {padding1 = {
              1179670611, 948, 7, 0, 832, 0, 0, 0, 0, 0, 0, 0}, sw_reserved = {1179670611, 948, 7, 0, 832, 0, 0, 0, 0, 0, 0, 0}}}, soft = {
          cwd = 895, swd = 0, twd = 0, fip = 0, fcs = 0, foo = 0, fos = 8064, st_space = {196607, 0 <repeats 19 times>}, ftop = 0 '\000', 
          changed = 0 '\000', lookahead = 0 '\000', no_update = 0 '\000', rm = 0 '\000', alimit = 0 '\000', info = 0x0, entry_eip = 0}, 
        xsave = {i387 = {cwd = 895, swd = 0, twd = 0, fop = 0, {{rip = 0, rdp = 0}, {fip = 0, fcs = 0, foo = 0, fos = 0}}, mxcsr = 8064, 
            mxcsr_mask = 196607, st_space = {0 <repeats 32 times>}, xmm_space = {1697592888, 2037544046, 0, 0, 2189525896, 1107330948, 
              1931502689, 25205, 1751347809, 0, 0, 0, 1647211365, 1953261941, 28265, 15, 0 <repeats 48 times>}, padding = {
              0 <repeats 12 times>}, {padding1 = {1179670611, 948, 7, 0, 832, 0, 0, 0, 0, 0, 0, 0}, sw_reserved = {1179670611, 948, 7, 0, 
                832, 0, 0, 0, 0, 0, 0, 0}}}, header = {xfeatures = 7, xcomp_bv = 0, reserved = {0, 0, 0, 0, 0, 0}}, 
          __reserved = '\000' <repeats 463 times>}, 
        __padding = "\177\003", '\000' <repeats 22 times>, "\200\037\000\000\377\377\002", '\000' <repeats 129 times>, "\070\066/entry\000\000\000\000\000\000\000\000\210\203\201\202\204\207\000Bad sub\000\000arch", '\000' <repeats 12 times>...}}}}
(gdb)

现在&#34; root&#34;想要读它,尝试了指向地址(0xe6d7f500),但它不起作用,它会出错。我认为它必须在某个地方,但我认为它映射在不同的地址。如何从用户空间访问此地址?

作为奖励,有人可以快速解释在linux下如何映射内存(用户空间,内核空间,什么是物理地址,虚拟地址?)

尝试用这个程序阅读:

readstruct.c

#include <stdio.h>
#include <stdlib.h>

int readbyte(size_t *vaddr)
{
  int val=0;
  val = *vaddr;
  return val;
}



int main(int argc, char *argv[]) {
    size_t phys;
    if (argc < 2) {
        printf("Usage: %s address\n", argv[0]);
        return 0;
    }

    phys = strtoull(argv[1], NULL, 0);


    size_t *vaddr = phys;
    printf("vaddr:%p\n",vaddr);


    int i=0;
    int value[512*4];

    unsigned long task, cred, cred_ptr, real_cred, real_cred_ptr, val;
    unsigned found_cred = 0, uid = getuid();
    unsigned long * task_struct;


    while (1) {

        if(i==512*4)
        {
            task = value[0];

            printf("[*] Looking for task_struct at %lx\n", vaddr);

            task_struct = malloc(sizeof(long) * 0x200);

            printf("[*] Reading task_struct...\n");

            strncpy(task_struct, value, sizeof(long) * 0x200);

            printf("[*] Finding cred struct (grab a coffee)...\n");

            cred_ptr = task + 0x80;

            for (i = 0; i < 0x200; i++) {

                /* Looking for cred */
                if(!found_cred) {
                    cred = task_struct[i];


                    strncpy(&val, value, 4);
                    if((int)val == (int)uid) {

                            strncpy(&val, value, 4);

                        if((int)val == (int)uid) {
                            found_cred = 1;
                            real_cred_ptr = cred_ptr + 4;
                            printf("[*] cred struct ptr at %lx\n", cred_ptr);
                            printf("[*] cred struct at %lx\n", cred);
                            printf("[*] Finding real_cred struct...\n");
                            continue;
                        }
                    }
                    cred_ptr += sizeof(long);
                }
                /* Looking for real_cred */
                else {
                    real_cred = task_struct[i];


                    strncpy(&val, value, 4);

                    if((int)val == (int)uid) {

                        strncpy(&val, value, 4);

                        if((int)val == (int)uid)
                            break;
                    }
                    real_cred_ptr += sizeof(long);
                }
            }

            free(task_struct);

            printf("[*] real_cred struct ptr at %lx\n", real_cred_ptr);
            printf("[*] real_cred struct at %lx\n", real_cred);

            i=0;

        }
        value[i] = readbyte(vaddr);
        vaddr++;
        i++;
    }


    return 0;
}

1 个答案:

答案 0 :(得分:1)

内核内存映射为用户空间不可访问或not mapped at all

如果要访问内核内存,可以通过/dev/kmem进行访问(当内核配置为CONFIG_DEVKMEM时可用)。另一种选择是从/proc/kcore读取内核核心转储(当内核配置为CONFIG_PROC_KCORE时可用)。另一种选择是扩展内核模块,因此它提供/dev/kmem类设备(或只是ioctl)。