Note:
0. Environment: Linux 3.1.0/xen 4.1.3-rc1-pre/PV domu
1.When running, I directly use the init_task Address [c086f4a0] In system. map. The read value is 0 and the initial process information cannot be obtained.
After comparison with the actual domu address, it is found that the actual address of init_task is 0x6000 more than that in the configuration file (the linux3.1 kernel is started directly without xen, and the address is 0x6000 more ).
Therefore, you need to add a magic number: # define offset 0x6000 to the initial address.
May 4. Re-compile the kernel and solve the problem.
It turns out that the kernel does not match system. Map. Maybe I later compiled a new kernel, but didn't install it?
2. Simulate list_for_each and write a macro for traversing the perspective linked list that is convenient for VMI ~ (Limitation: Global VMI variable, guest kernel virtual address (process = 0 ))
Addr_t vmi_next_ptr (addr_t PTR) {vmi_read_addr_va (VMI, PTR, 0, & PTR); // returns the value of * PTR. Return PTR;} # define vmi_list_for_each (ITER, head) for (iter = vmi_next_ptr (head); iter! = Head; iter = vmi_next_ptr (ITER ))
Declaration part:
# Include <libvmi/libvmi. h> # include <stdio. h> # include "stdlib. H "# define STR _ (x) x # define debug (format ,...) fprintf (stderr, "% s: % d:" str _ (Format) "\ n", _ file __, _ line __, ##__ va_args __) # define assert _ (expr _, extra_op) do {If (! (Expr _) {debug ("in the function '% s': asserted error:" # expr _, _ function _); \ extra_op; exit (-1) ;}}while (0) # define assert (expr) assert _ (expr,) # define vmi_assert (expr) assert (expr) = vmi_success) // # define offset 0x6000 // No need! Char OS _tag [] = "Debian-PV"; char default_name [] = "debian-pv-pv-shot1"; vmi_instance_t VMI; addr_t vmi_next_ptr (addr_t PTR) {vmi_read_addr_va (VMI, PTR, 0, & PTR); Return PTR ;}# define vmi_list_for_each (ITER, head) for (iter = vmi_next_ptr (head); iter! = Head; iter = vmi_next_ptr (ITER ))
Main Program
int main(){Debug("init vmi instance...");vmi_assert(vmi_init(&vmi, VMI_AUTO | VMI_INIT_COMPLETE, default_name));int tasks_offset = vmi_get_offset(vmi, "linux_tasks");int name_offset = vmi_get_offset(vmi, "linux_name");int pid_offset = vmi_get_offset(vmi, "linux_pid");Debug("linux_tasks:0x%x proc_name:0x%x pid:0x%x", tasks_offset, name_offset, pid_offset);Debug("pause the vm");vmi_assert(vmi_pause_vm(vmi));// 1. get address of init_task(idle) process in system.map// the value in System.map is c086f4a0 but actually in DomU it is at c08754a0. why??addr_t init_task_ptr = vmi_translate_ksym2v(vmi, "init_task")/* + OFFSET*/;addr_t list_head, iter;// 2. get "pointer to next task_struct" in "idle process" as list headvmi_read_addr_va(vmi, init_task_ptr + tasks_offset, 0, &list_head);vmi_list_for_each(iter, list_head){//get name & pid of next processchar *proc_name = vmi_read_str_va(vmi, iter + name_offset - tasks_offset, 0); int pid; vmi_read_32_va(vmi, iter + pid_offset - tasks_offset, 0, &pid);//print informationprintf("[%5d] %s\n", pid, proc_name);if (proc_name){free(proc_name);proc_name = NULL;}}Debug("resume vm and exit");vmi_resume_vm(vmi);vmi_destroy(vmi);return 0;}
Configuration file/etc/libvmi. conf
debian-pv-pv-shot1 {ostype = "Linux";sysmap = "/boot/System.map-3.1.0";linux_name = 0x2f8;linux_tasks = 0x1c8;linux_mm = 0x1e4;linux_pid = 0x218;linux_pgd = 0x24;linux_addr = 0x78;}
Run:
viktor@buxiang-OptiPlex-330:~/proj/vmids$ sudo ./proc_list proc_list.c:20: init vmi instance...proc_list.c:26: linux_tasks:0x1c8 proc_name:0x2f8 pid:0x218proc_list.c:28: pause the vm[ 1] init[ 2] kthreadd[ 3] ksoftirqd/0[ 4] kworker/0:0[ 5] kworker/u:0[ 6] migration/0[ 7] watchdog/0[ 8] cpuset[ 9] khelper[ 10] kdevtmpfs[ 11] netns[ 12] xenwatch[ 13] xenbus[ 14] sync_supers[ 15] bdi-default[ 16] kintegrityd[ 17] kblockd[ 18] kworker/0:1[ 19] ata_sff[ 20] khubd[ 21] md[ 22] khungtaskd[ 23] kswapd0[ 24] ksmd[ 25] fsnotify_mark[ 26] ecryptfs-kthrea[ 27] crypto[ 30] kworker/u:1[ 32] khvcd[ 33] kmpathd[ 34] kmpath_handlerd[ 35] kjournald[ 70] udevd[ 127] udevd[ 134] udevd[ 399] rsyslogd[ 451] cron[ 458] sshd[ 475] login[ 476] bash[ 0] swapperproc_list.c:58: resume vm and exit