Linux Kernel(4.19) Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

230224
1178
109352


[Linux][Kernel]메모리 디스크립터 - struct mm_struct 구조체 소개 [Linux][Kernel] MM


리눅스 커널에서 돌고 있는 프로세스는 크게 2가지로 분류할 수 있습니다.
유저 공간과 커널 공간에서 생성된 생성된 프로세스들이죠.

유저 공간에서 생성된 프로세스들은 유저 영역 가상 메모리 공간에서 실행됩니다. 이 가상 메모리에 대한 정보는 struct mm_struct 자료구조 구조체로 표현하며 해당 프로세스 태스트 디스크립터에 mm란 멤버로 존재하죠. 
(참고로 여기서 말하는 가상 메모리는 커널 공간에서 실행하는 물리/가상 메모리 개념은 아닙니다. )

그럼 태스크 디스크립터를 한번 열어볼까요? 아래 화살표 친 부분을 보면 역시 mm이란 멤버가 있네요.
  (struct task_struct *) (struct task_struct*)0xE9AFCFC0 = 0xE9AFCFC0 -> (
    (long int) state = 0x1,
    (void *) stack = 0xE8DE2000,
    (atomic_t) usage = ((int) counter = 0x2),
//..
    (struct mm_struct *) mm = 0xEA621880,  //<<--
    (struct mm_struct *) active_mm = 0xEA621880,

그럼 (struct mm_struct *)  구조체 멤버를 실제 코어 덤프에서 살펴볼까요?
상세 내용은 아래 주석문을 참고하세요.
  (struct mm_struct *) (struct mm_struct *)0xEA621880 = 0xEA621880 -> (
    (struct vm_area_struct *) mmap = 0xE8D6BEC8, // 메모리 영역 리스트
    (struct rb_root) mm_rb = ((struct rb_node *) rb_node = 0xEA9C6F30),  // VMA rb 트리,
    (u32) vmacache_seqnum = 0x0270,
    (long unsigned int (*)()) get_unmapped_area = 0xC0117040,
    (long unsigned int) mmap_base = 0xAB9AC000,
    (long unsigned int) mmap_legacy_base = 0x0,
    (long unsigned int) task_size = 0xBF000000, 
    (long unsigned int) highest_vm_end = 0xBEBDD000,
    (pgd_t *) pgd = 0xE8FC0000,
    (atomic_t) mm_users = ((int) counter = 0x7),  // 이 주소 공간을 사용하는 프로세스의 갯수
    (atomic_t) mm_count = ((int) counter = 0x2), // mm_struct 구조체의 주 참조 횟수
    (atomic_long_t) nr_ptes = ((int) counter = 0x1E),
    (int) map_count = 0x93,  // 메모리 영역 갯수
    (spinlock_t) page_table_lock = ((struct raw_spinlock) rlock // 페이지 테이블 락
    (struct rw_semaphore) mmap_sem = ((long int) count = 0x0, (struct list_head) wait_list = ((struc
    (struct list_head) mmlist = ((struct list_head *) next = 0xEABAD1E8, // 전체 mm_struct 리스트
    (long unsigned int) hiwater_rss = 0x25A6,
    (long unsigned int) hiwater_vm = 0x360E,
    (long unsigned int) total_vm = 0x3507,  // 전체 vm 메모리 사용량
    (long unsigned int) locked_vm = 0x0,
    (long unsigned int) pinned_vm = 0x0,
    (long unsigned int) shared_vm = 0x03B3,
    (long unsigned int) exec_vm = 0x022C,
    (long unsigned int) stack_vm = 0x21,
    (long unsigned int) def_flags = 0x0,
    (long unsigned int) start_code = 0x7F555000, // 코드의 시작주소
    (long unsigned int) end_code = 0x7F566B9E, // 코드의 마지막 주소
    (long unsigned int) start_data = 0x7F568A7C, // 데이터의 시작주소
    (long unsigned int) end_data = 0x7F569009,  // 데이터의 끝주소
    (long unsigned int) start_brk = 0x7FDB5000,
    (long unsigned int) brk = 0x7FDB5000,
    (long unsigned int) start_stack = 0xBEAE1960, //스택의 시작주소
    (long unsigned int) arg_start = 0xBEAE1A61, // argument 가 있는 시작 주소
    (long unsigned int) arg_end = 0xBEAE1A72,
    (long unsigned int) env_start = 0xBEAE1A72,
    (long unsigned int) env_end = 0xBEAE1FEB,
    (long unsigned int [42]) saved_auxv = (0x10, 0x003FB0D6, 0x6, 0x1000, 0x11, 0x64, 0x3, 0x7F55503
    (struct mm_rss_stat) rss_stat = ((atomic_long_t [3]) count = (((int) counter = 0x9E), ((int) cou
    (struct linux_binfmt *) binfmt = 0xC1A2A118,
    (cpumask_var_t) cpu_vm_mask_var = (((long unsigned int [1]) bits = (0xFF))),
    (mm_context_t) context = ((atomic64_t) id = ((long long int) counter = 0x000159B0), (unsigned in
    (long unsigned int) flags = 0x8C, //상태 플래그
    (struct core_state *) core_state = 0x0,
    (spinlock_t) ioctx_lock = ((struct raw_spinlock) rlock = ((arch_spinlock_t) raw_lock = ((u32) sl
    (struct kioctx_table *) ioctx_table = 0x0,
    (struct file *) exe_file = 0xE8CFB000,
    (bool) tlb_flush_pending = FALSE,
    (struct uprobes_state) uprobes_state = ())

그리고 당연한 이야기지만 커널 쓰래드는 task_struct 구조체 안의 mm이 NULL이라는 점도 기억하세요.
다음은 워커쓰레드의 태스크 디스크립터입니다. 
  (struct task_struct *) (struct task_struct*)0xE8C595C0 = 0xE8C595C0 -> (
    (long int) state = 0x1,
    (void *) stack = 0xE8D6E000,
    (atomic_t) usage = ((int) counter = 0x2),
 //...
    (struct rb_node) pushable_dl_tasks = ((long unsigned int) __rb_parent_color = 0xE8C5990C, (struc
    (struct mm_struct *) mm = 0x0,
    (struct mm_struct *) active_mm = 0x0,
    (unsigned int:1) brk_randomized = 0x0,
 //...
    (struct cred *) real_cred = 0xEAAF9E80,
    (struct cred *) cred = 0xEAAF9E80,
    (char [16]) comm = "kworker/2:1H",
    (int) link_count = 0x0,
    (int) total_link_count = 0x0,

"이 포스팅이 유익하다고 생각되시면 댓글로 응원해주시면 감사하겠습니다.  
그리고 혹시 궁금점이 있으면 댓글로 질문 남겨주세요. 상세한 답글 올려드리겠습니다!"



핑백

덧글

댓글 입력 영역