plt로 got 채우기

puts@plt + 0에 puts@plt + 6의 주소가 들어있어서 호출되면 puts@plt+6의 코드가실행

puts@plt + 11 에서 점프하면 pushl, jmp로 분기된다.
pushl로 GOT+4의 주소를 스택에 넣고 GOT+8의 주소로 분기하는데 여기에는_dl_runtime_resolve의 주소가 있다.
_dl_runtime_resolve 에서 _dl_fixup 을 호출한다.

_dl_fixup 함수에서는 edi에 puts의 offset을 넣고 esi에 .strtab의 주소를 넣는다

(.strtab + offset = 'puts' 문자열이 들어가있다.)
eax에는 'puts'문자열의 주소를 넣고 _dl_lookup_symbol_x 함수를 호출한다.

_dl_lookup_symbol_x 함수에서는 SYMTAB의 주소와 lib의 주소를 얻고 _dl_fixup 함수로 나와서 SYMTAB에서 아까전에 넣어논 esi(.strtab), edi(offset)응 이용해 실제 주소를 구하고 GOT에 write하고 _dl_runtime_resolve 함수로 다시와서 puts함수로 넘어가게 된다.

이런식으로 한번 dynamic linker가 주소를 받아오는 과정을 거치게 되면 다음번에는_dl_runtime_resolve함수로 들어가지 않고 바로 puts@plt에서 바로 실제 puts함수의 코드로 들어가게 된다.
--------------------------------------------------------------------------------------------
1. puts@plt
2. puts@plt+6
3. puts@plt+11
4. _dl_runtime_resolve(GOT+8)
 실행 전에는 GOT+8이 0임, 메모리에 올라가면 GOT+8에 _dl_runtime_resolve의 주소가 들어감
5. _dl_fixup
 edi : puts의 offset
 esi : &.strlab
 eax : &"puts"
 <이놈들을 조작할 수 있으면 원하는 함수를 실행 할 수 있다.>
6. _dl_lookup_symbol_x 
 SYMTAB주소 얻음
 lib의 주소 얻음
7. _dl_fixup
 edi : puts의 offset
 esi : &.strlab
 이 두개를 이용해 SYMTAB에서 실제 주소 구해서 GOT에 write
8. _dl_runtime_resolve
 puts의 공유라이브러리(실제 puts함수)로 넘어감
--------------------------------------------------------------------------------------------

댓글 6개:

  1. 좋은 정보 감사합니다.
    got+8부분 까지 보이고, 그 이후를 따라가 보려고하는데 access할 수 없다고 하거나, 안보이는데 dl_runtime_resolve를 디버깅해보려면 어떻게 해야하는지 궁금합니다!~

    답글삭제
    답글
    1. 늦게 봤네요..ㅠ
      아마 심볼이 없어서 안보이는 것 같아요. 그냥 plt에 브레이크 걸고 ni 계속 치면 _dl_runtime_resolve로 진입해요.
      _dl_runtime_resolve 시작 어셈블리는
      push eax
      push ecx
      mov edx, DWORD PTR [esp+0x10]
      mov eax, DWORD PTR [esp+0xc]
      이렇게 시작해요. 칼리나 우분투 말고 centos5에서 해보세요.

      삭제
    2. 우분투나 칼리에서는
      0xffffffff in ?? () from /lib/ld-linux.so.2
      이런식으로 나오네요. ld-linux.so.2 에 들어있는게 _dl_runtime_resolve에요.
      그리고 함수 진입하면 해당함수 라이브러리롤 들어가요.
      0xf7e5ea96 in printf () from /lib32/libc.so.6 이런식으로요.

      삭제
    3. 작성자가 댓글을 삭제했습니다.

      삭제
    4. 저도 늦게 봤네요 ㅠㅠ
      우분투에서는 안되는건가요? ㅋㅓ널영역이여서 안되는줄 알았느데..plt에 bp걸고 ni 하면 그냥 다뛰어넘고 끝나버리는데... 제가 잘못한건가요..ㅋㅋㅋ

      삭제
    5. 저는 우분투에서도 되요. 근데 이름이 보이지 않은 상태에서 따라가져요.
      ni 말고 si를 이용해보세요

      삭제