Microsoft MVP성태의 닷넷 이야기
Linux: 93. Ubuntu 22.04 - 커널 이미지로부터 커널 함수 역어셈블 [링크 복사], [링크+제목 복사],
조회: 4812
글쓴 사람
정성태 (seongtaejeong at gmail.com)
홈페이지
첨부 파일
 
(연관된 글이 1개 있습니다.)
(시리즈 글이 2개 있습니다.)
Linux: 92. WSL 2 - 커널 이미지로부터 커널 함수 역어셈블
; https://www.sysnet.pe.kr/2/0/13780

Linux: 93. Ubuntu 22.04 - 커널 이미지로부터 커널 함수 역어셈블
; https://www.sysnet.pe.kr/2/0/13782




Ubuntu 22.04 - 커널 이미지로부터 커널 함수 역어셈블

지난 글에는 WSL 환경에서의 방법을 다뤘는데요,

WSL 2 - 커널 이미지로부터 커널 함수 역어셈블
; https://www.sysnet.pe.kr/2/0/13780

이번에는 (WSL이 아닌) Ubuntu 22.04의 경우를 살펴보겠습니다. 대신 커널 소스코드 빌드는 하지 않고 있는 환경 그대로 구성할 텐데요, 따라서 이번에는 extract-vmlinux 도구로 커널 이미지를 추출하는 것이 필요합니다.

$ wget -O extract-vmlinux https://raw.githubusercontent.com/torvalds/linux/master/scripts/extract-vmlinux

$ chmod +x extract-vmlinux

$ sudo ./extract-vmlinux /boot/vmlinuz > vmlinux

$ uname -r
6.8.0-47-generic

이미지는 준비됐고, 이제 System.map 파일을 찾아야 하는데요 이미 linux-headers 관련 패키지들이 설치돼 있다면,

// System.map: No such file or directory
// https://www.linuxquestions.org/questions/ubuntu-63/system-map-no-such-file-or-directory-840336/

$ sudo apt install linux-headers-$(uname -r)

$ sudo apt list linux-headers-$(uname -r)
Listing... Done
linux-headers-6.8.0-47-generic/jammy-updates,jammy-security,now 6.8.0-47.47~22.04.1 amd64 [installed]

$ ls /lib/modules/$(uname -r)/build
arch   certs   Documentation  fs       init      ipc     Kconfig  lib       mm              net   samples  security  tools   usr
block  crypto  drivers        include  io_uring  Kbuild  kernel   Makefile  Module.symvers  rust  scripts  sound     ubuntu  virt

커널 빌드 번호와 함께 /boot 경로에 있는 System.map 파일이 있을 것입니다.

$ ls -l /boot/System.map-$(uname -r)
-rw------- 1 root root 8657806 10월  2 23:39 /boot/System.map-6.8.0-47-generic

그럼 게임 끝났군요. ^^ 지난 글에 설명한 방법에 따라, System.map 파일에서 커널 함수의 주소를 구하고,

$ sudo cat /boot/System.map-$(uname -r) | grep proc_sys_open
ffffffff815b2200 t __pfx_proc_sys_open
ffffffff815b2210 t proc_sys_open

그 주소로 objdump를 이용해 역어셈블을 수행할 수 있습니다.

$ objdump -S --start-address=0xffffffff815b2210 ./vmlinux | less

./vmlinux:     file format elf64-x86-64

Disassembly of section .text:

ffffffff815b2210 <.text+0x5b2210>:
ffffffff815b2210:       e8 cb 3a b0 ff          call   0xffffffff810b5ce0
ffffffff815b2215:       55                      push   %rbp
ffffffff815b2216:       48 c7 c0 e8 44 67 83    mov    $0xffffffff836744e8,%rax
ffffffff815b221d:       48 89 e5                mov    %rsp,%rbp
ffffffff815b2220:       41 55                   push   %r13
ffffffff815b2222:       49 89 f5                mov    %rsi,%r13
ffffffff815b2225:       41 54                   push   %r12
ffffffff815b2227:       49 89 fc                mov    %rdi,%r12
ffffffff815b222a:       53                      push   %rbx
ffffffff815b222b:       48 8b 5f d8             mov    -0x28(%rdi),%rbx
ffffffff815b222f:       48 c7 c7 b8 b8 f2 83    mov    $0xffffffff83f2b8b8,%rdi
ffffffff815b2236:       48 85 db                test   %rbx,%rbx
ffffffff815b2239:       48 0f 44 d8             cmove  %rax,%rbx
ffffffff815b223d:       e8 8e da c6 00          call   0xffffffff8221fcd0
ffffffff815b2242:       48 83 7b 18 00          cmpq   $0x0,0x18(%rbx)
ffffffff815b2247:       75 70                   jne    0xffffffff815b22b9
ffffffff815b2249:       83 43 0c 01             addl   $0x1,0xc(%rbx)
ffffffff815b224d:       48 c7 c7 b8 b8 f2 83    mov    $0xffffffff83f2b8b8,%rdi
ffffffff815b2254:       e8 b7 db c6 00          call   0xffffffff8221fe10
ffffffff815b2259:       49 8b 44 24 e0          mov    -0x20(%r12),%rax
ffffffff815b225e:       48 81 fb 00 f0 ff ff    cmp    $0xfffffffffffff000,%rbx
ffffffff815b2265:       77 65                   ja     0xffffffff815b22cc
ffffffff815b2267:       48 8b 40 28             mov    0x28(%rax),%rax
ffffffff815b226b:       48 85 c0                test   %rax,%rax
ffffffff815b226e:       74 0a                   je     0xffffffff815b227a
ffffffff815b2270:       48 63 00                movslq (%rax),%rax
ffffffff815b2273:       49 89 85 c8 00 00 00    mov    %rax,0xc8(%r13)
ffffffff815b227a:       48 c7 c7 b8 b8 f2 83    mov    $0xffffffff83f2b8b8,%rdi
ffffffff815b2281:       e8 4a da c6 00          call   0xffffffff8221fcd0
ffffffff815b2286:       83 6b 0c 01             subl   $0x1,0xc(%rbx)
ffffffff815b228a:       74 1d                   je     0xffffffff815b22a9
ffffffff815b228c:       48 c7 c7 b8 b8 f2 83    mov    $0xffffffff83f2b8b8,%rdi
...[생략]...




하지만, 위의 설정으로는 gdb를 이용한 경우,

$ sudo gdb ./vmlinux
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
...[생략]...

Reading symbols from ./vmlinux...
(No debugging symbols found in ./vmlinux)

(gdb) disass do_sys_open
No symbol table is loaded.  Use the "file" command.

저렇게 symbol을 찾을 수 없다고 나옵니다. 분명히 현재 CONFIG_DEBUG_INFO가 활성화된 커널인데,

$ cat /boot/config-6.8.0-47-generic | grep CONFIG_DEBUG_INFO
CONFIG_DEBUG_INFO=y
...[생략]...

// 커널 빌드 시, "make menuconfig", "Kernel hacking" -> "Compile-time checks and compiler options" -> "Debug information" -> "Generate DWARF Version 5 debuginfo" (CONFIG_DEBUG_INFO, CONFIG_DEBUG_INFO_DWARF5) 옵션 설정

음... 어쩔 수 없군요, 이에 대해 검색해 보면,

Installing Ubuntu Kernel Debugging Symbols
; https://hadibrais.wordpress.com/2017/03/13/installing-ubuntu-kernel-debugging-symbols/

디버깅 심벌을 설치하라고 나옵니다. 이를 위해 우선 적절한 repo key를 추가하고,

$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys C8CAB6595FDFF622 
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
Executing: /tmp/apt-key-gpghome.YNAyLbATlr/gpg.1.sh --keyserver keyserver.ubuntu.com --recv-keys C8CAB6595FDFF622
gpg: key C8CAB6595FDFF622: "Ubuntu Debug Symbol Archive Automatic Signing Key (2016) <ubuntu-archive@lists.ubuntu.com>" not changed
gpg: Total number processed: 1
gpg:              unchanged: 1

아래의 내용으로 ddebs.list 파일을 구성한 다음,

$ cat  /etc/apt/sources.list.d/ddebs.list
deb http://ddebs.ubuntu.com/ jammy      main restricted universe multiverse
deb http://ddebs.ubuntu.com/ jammy-security main restricted universe multiverse
deb http://ddebs.ubuntu.com/ jammy-updates  main restricted universe multiverse
deb http://ddebs.ubuntu.com/ jammy-proposed main restricted universe multiverse

디버깅 심벌 패키지를 설치합니다.

$ sudo apt-get update

$ sudo apt-get install linux-image-$(uname -r)-dbgsym
Reading package lists... Done
...[생략]...
Preparing to unpack .../linux-image-unsigned-6.8.0-47-generic-dbgsym_6.8.0-47.47~22.04.1_amd64.ddeb ...
Unpacking linux-image-unsigned-6.8.0-47-generic-dbgsym (6.8.0-47.47~22.04.1) ...
Selecting previously unselected package linux-image-6.8.0-47-generic-dbgsym.
Preparing to unpack .../linux-image-6.8.0-47-generic-dbgsym_6.8.0-47.47~22.04.1_amd64.ddeb ...
Unpacking linux-image-6.8.0-47-generic-dbgsym (6.8.0-47.47~22.04.1) ...
Setting up linux-image-unsigned-6.8.0-47-generic-dbgsym (6.8.0-47.47~22.04.1) ...
Setting up linux-image-6.8.0-47-generic-dbgsym (6.8.0-47.47~22.04.1) ...

$ ll /usr/lib/debug/boot/vmlinux-$(uname -r)
-rw-r--r-- 1 root root 402529448 10월  2 23:39 /usr/lib/debug/boot/vmlinux-6.8.0-47-generic

그럼 저렇게 다운로드한 vmlinux 파일을 gdb로 열어 역어셈블을 하면 됩니다.

$ gdb /usr/lib/debug/boot/vmlinux-$(uname -r)
GNU gdb (Ubuntu 12.1-0ubuntu1~22.04.2) 12.1
...[생략]...

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/lib/debug/boot/vmlinux-6.8.0-47-generic...

(gdb) disass do_sys_open
Dump of assembler code for function do_sys_open:
   0xffffffff814dc5e0 <+0>:     call   0xffffffff810b5ce0 <__fentry__>
   0xffffffff814dc5e5 <+5>:     push   %rbp
   0xffffffff814dc5e6 <+6>:     mov    %rsp,%rbp
    ...[생략]...
   0xffffffff814dc65b <+123>:   jmp    0xffffffff814dc61e <do_sys_open+62>
   0xffffffff814dc65d <+125>:   call   0xffffffff82206840 <__stack_chk_fail>
End of assembler dump.
(gdb) q

$ objdump -t /usr/lib/debug/boot/vmlinux-$(uname -r) | less
/usr/lib/debug/boot/vmlinux-6.8.0-47-generic:     file format elf64-x86-64

SYMBOL TABLE:
ffffffff81000000 l    d  .text  0000000000000000 .text
ffffffff82600000 l    d  .rodata        0000000000000000 .rodata
ffffffff82d46570 l    d  .pci_fixup     0000000000000000 .pci_fixup
ffffffff82d4a170 l    d  .tracedata     0000000000000000 .tracedata
...[생략]...




참고로, 다른 CentOS 9에서 gdb를 이용해 커널 이미지를 열었더니,

$ sudo ./extract-vmlinux /boot/vmlinuz-5.14.0-472.el9.x86_64 > vmlinux

$ gdb ./vmlinux
GNU gdb (CentOS Stream) 14.2-3.el9
...[생략]...

Type "apropos word" to search for commands related to "word"...
Reading symbols from ./vmlinux...

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.centos.org/>
Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
Downloading separate debug info for /home/testusr/temp/ConsoleApp1/vmlinux
Reading symbols from /home/testusr/.cache/debuginfod_client/68eaa56bbb8f83d229a48ad50ee10a95de117103/debuginfo...

저렇게 debuginfod를 활성화할 거냐고 묻고는 자동으로 심벌 정보를 내려받았습니다. 이후, 그냥 아무런 조치 없이 역어셈블을 할 수 있는데요,

(gdb) disass do_sys_open
Dump of assembler code for function do_sys_open:
   0xffffffff81441bf0 <+0>:     call   0xffffffff810774f0 <__fentry__>
   0xffffffff81441bf5 <+5>:     sub    $0x20,%rsp
   0xffffffff81441bf9 <+9>:     mov    %gs:0x28,%rax
   0xffffffff81441c02 <+18>:    mov    %rax,0x18(%rsp)
   0xffffffff81441c07 <+23>:    mov    %edx,%eax
    ...[생략]...

가만 보니까, Ubuntu도 22.04 이후로 저렇게 debuginfod 서비스를 제공한다고 합니다.

Debug symbol packages
; https://ubuntu.com/server/docs/debug-symbol-packages

그런데 이상하군요, 제가 위에서 했던 Ubuntu 실습이 22.04였는데, gdb로 ./vmlinux 파일을 열었을 때 저런 식으로 debuginfod가 관여하지 않고 그냥 곧바로 "(No debugging symbols found in ./vmlinux)"라고 나왔을 뿐입니다. 뭔가 설정이 다를 수 있지만, 암튼... 이번엔 여기까지만. ^^




[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]

[연관 글]






[최초 등록일: ]
[최종 수정일: 10/24/2024]

Creative Commons License
이 저작물은 크리에이티브 커먼즈 코리아 저작자표시-비영리-변경금지 2.0 대한민국 라이센스에 따라 이용하실 수 있습니다.
by SeongTae Jeong, mailto:techsharer at outlook.com

비밀번호

댓글 작성자
 




... 121  122  123  124  125  126  [127]  128  129  130  131  132  133  134  135  ...
NoWriterDateCnt.TitleFile(s)
2880정성태3/7/201521682개발 환경 구성: 260. C# Code Coverage 도구 - Semantic Designs 소개
2879정성태3/3/201526697개발 환경 구성: 259. Visual Studio 없이 Visual C++ 컴파일하는 방법
2878정성태2/28/201527608.NET Framework: 503. == 연산자보다는 Equals 메서드의 호출이 더 권장됩니다. [3]파일 다운로드1
2877정성태2/28/201521759.NET Framework: 502. 연산자 재정의(operator overloading)와 메서드 재정의(method overriding)의 다른 점 - 가상 함수 호출 여부 [3]파일 다운로드1
2876정성태2/27/201524218VS.NET IDE: 98. IntegraStudio - Visual Studio에서 Java 프로그램 개발
2875정성태2/26/201522844디버깅 기술: 72. Visual Studio 2013에서의 sos.dll 사용 제한
2874정성태2/26/201519585디버깅 기술: 71. windbg + 닷넷 디버깅 (2) - null 체크 패턴
2873정성태2/25/201537112.NET Framework: 501. FtpWebRequest 타입을 이용해 FTP 파일 업로드 [4]파일 다운로드1
2872정성태2/25/201521256디버깅 기술: 70. windbg + 닷넷 디버깅 (1) - 배열 인덱스 사용 패턴
2871정성태2/24/201525219개발 환경 구성: 258. 윈도우 8.1에서 방화벽과 함께 FTP 서버 여는 (하지만, 권장하지 않는) 방법 [1]
2870정성태2/24/201526361개발 환경 구성: 257. 윈도우 8.1에서 방화벽과 함께 FTP 서버 여는 방법
2869정성태2/23/201520317.NET Framework: 500. struct로 정의한 값 형식(Value Type)의 경우 Equals 재정의를 권장합니다.파일 다운로드1
2868정성태2/23/201524829VS.NET IDE: 97. Visual C++ 프로젝트 디버깅 시에 Step-Into(F11) 동작이 원치 않는 함수로 진입하는 것을 막는 방법 [2]
2867정성태2/23/201518552오류 유형: 273. File History - Failed to initiate user data backup (error 80070005)
2866정성태2/23/201520379오류 유형: 272. WAT080 : Failed to locate the Windows Azure SDK. Please make sure the Windows Azure SDK v2.1 is installed.
1868정성태2/20/201517681오류 유형: 271. The type '...' cannot be used as type parameter 'TContext' in the generic type or method 'System.ServiceModel.DomainServices.EntityFramework.LinqToEntitiesDomainService&lt;T&gt;
1866정성태2/20/201518615오류 유형: 270. "aspnet_regiis -i" 실행 시 0x00000006 오류 해결 방법
1865정성태2/20/201519918.NET Framework: 499. 특정 닷넷 프레임워크 버전 이후부터 제공되는 타입을 사용해야 한다면?
1864정성태2/18/201524870.NET Framework: 498. C#으로 간단하게 만들어 본 ASCII Art 프로그램 [2]파일 다운로드1
1862정성태2/18/201528722.NET Framework: 497. .NET Garbage Collection에 대한 정리 [6]
1861정성태2/18/201524070.NET Framework: 496. 마우스 커서가 놓인 지점의 문자열 얻는 방법 [1]파일 다운로드1
1860정성태2/18/201523898.NET Framework: 495. CorElementType의 요소 값 설명파일 다운로드1
1859정성태2/17/201524306Windows: 106. 컴퓨터를 재부팅하면 절전(Power Saver) 전원 모드로 돌아가는 경우
1858정성태2/16/201534267Windows: 105. 자동으로 로그아웃/잠김 화면 상태로 전환된다면? [2]
1857정성태2/16/201522288.NET Framework: 494. 값(struct) 형식의 제네릭(Generic) 타입이 박싱되는 경우의 메타데이터 토큰 값파일 다운로드1
1856정성태2/15/201521265.NET Framework: 493. TypeRef 메타테이블에 등록되는 타입의 조건파일 다운로드1
... 121  122  123  124  125  126  [127]  128  129  130  131  132  133  134  135  ...