CMM

TAEWOO HA·2023년 8월 23일
0

CMM 스크립트

목록 보기
1/2

  • 해당 cmm 파일을 분석

  • 라즈베리파이에 설치된 모듈 드라이버를 출력해주는 동작

  • 이 커널로그가 어느 함수에서 호출이 되는것인가?

  • 다음 함수에서 출력이 된다.
  • modules라는 변수가 있다.

  • 링크드리스트 자료구조가 보인다.

  • list 확인

  • 오프셋 : 0x8
  • 이 주소에서 8만큼 빼주면 struct module 의 시작주소가 됨
  (struct list_head) modules = (
    (struct list_head *) next_=_0xFFFFFFD1682C7688 -> (
      (struct list_head *) next = 0xFFFFFFD1682BA108 -> (
        (struct list_head *) next = 0xFFFFFFD1682B5288 -> (
          (struct list_head *) next = 0xFFFFFFD168139208,
          (struct list_head *) prev = 0xFFFFFFD1682BA108),
        (struct list_head *) prev = 0xFFFFFFD1682C7688),
      (struct list_head *) prev = 0xFFFFFFD1755CF638),
    (struct list_head *) prev = 0xFFFFFFD167D15E08)
  • 0xFFFFFFD1682C7688 -8 = 0xFFFFFFD1682C7680

  • %s 옵션으로 이름을 확인하자.
  • 이 과정을 확인하는데 시간이 너무 오래걸린다. 그렇기 때문에 CMM 스크립트를 작성하는 것

CMM 스크립트

        9|Global &g_modules
       10|Global &g_module_start_addr
       11|Global &g_module_name
       12|
       13|Global &g_modules_list_next
       14|Global &g_modules_list_next_temp
       15|Global &g_modules_list_offset
       16|Global &g_modules_name_offset
       17|
       18|; find the offset
       19|&g_modules_list_offset=address.offset(v.address(((struct module)0x0).list)) // 필드의 구조체의 시작주소에서 list의 오프셋이 무엇인지 알기위한 구문
       20|&g_modules_name_offset=address.offset(v.address(((struct module)0x0).name))
       21|
       22|; find global modules (modules is linked-list)
       23|&g_modules=address.offset(modules)
       24|
       25|&g_modules_list_next=data.quad(d:&g_modules)
       26|
       27|while &g_modules!=&g_modules_list_next
      28|(
      29|        &g_module_start_addr=&g_modules_list_next-&g_modules_list_offset
      30|        &g_module_name=&g_module_start_addr+&g_modules_name_offset
      31|
      32|        print "name: " data.string(d:&g_module_name)
      33|
      34|        &g_modules_list_next_temp=data.quad(d:&g_modules_list_next)
      35|        &g_modules_list_next=&g_modules_list_next_temp  // for debugging purpose
      36|)
       37|
       38|enddo
       39|
       40|
       
  • 변수 앞에는 & 를 붙인다.
  • Global + 변수 => 전역변수

&g_modules_list_offset=address.offset(v.address(((struct module)0x0).list))

  • v.address : 주소를 확인하기위한 명령어

  • struct module이라는 구조체에서 list라는 필드에 오프셋을 계산하는 명령어

  • address.offset : 어드레스의 정보를 다른 변수에 저장할 수 있는 포멧으로 출력.

  • &g_modules=address.offset(modules) : 모듈이라는 전역변수의 시작주소를 확인하기 위한 구문

  • &g_modules_list_next=data.quad(d:&g_modules) : next를 읽어옴

while &g_modules!=&g_modules_list_next
(
&g_module_start_addr=&g_modules_list_next-&g_modules_list_offset
&g_module_name=&g_module_start_addr+&g_modules_name_offset
print "name: " data.string(d:&g_module_name)
&g_modules_list_next_temp=data.quad(d:&g_modules_list_next)
&g_modules_list_next=&g_modules_list_next_temp

  • next라는 모듈이 g모듈(첫주소)와 같지 않을때까지 순회
    • 링크드리스트는 next를 포인팅하는데 가장 마지막의 tail 리스트는 head의 리스트를 가리킨다.
  • start addr = next - offset
  • 시작주소를 알아야 name을 알 수 있기 때문임
  • 더한 주소를 이름으로 업데이트 , 주소에 있는 데이터를 이름으로 출력

  • &g_modules_list_next_temp=data.quad(d:&g_modules_list_next) : 넥스트에서 또다른 넥스트로 변환
  • temp라는 값을 정해놓고 다시 temp를 넣어줌

0개의 댓글