Microsoft MVP성태의 닷넷 이야기
Linux: 93. Ubuntu 22.04 - 커널 이미지로부터 커널 함수 역어셈블 [링크 복사], [링크+제목 복사],
조회: 4709
글쓴 사람
정성태 (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

비밀번호

댓글 작성자
 




... [76]  77  78  79  80  81  82  83  84  85  86  87  88  89  90  ...
NoWriterDateCnt.TitleFile(s)
12036정성태10/14/201925378.NET Framework: 866. C# - 고성능이 필요한 환경에서 GC가 발생하지 않는 네이티브 힙 사용파일 다운로드1
12035정성태10/13/201919569개발 환경 구성: 461. C# 8.0의 #nulable 관련 특성을 .NET Framework 프로젝트에서 사용하는 방법 [2]파일 다운로드1
12034정성태10/12/201918883개발 환경 구성: 460. .NET Core 환경에서 (프로젝트가 아닌) C# 코드 파일을 입력으로 컴파일하는 방법 [1]
12033정성태10/11/201923066개발 환경 구성: 459. .NET Framework 프로젝트에서 C# 8.0/9.0 컴파일러를 사용하는 방법
12032정성태10/8/201919202.NET Framework: 865. .NET Core 2.2/3.0 웹 프로젝트를 IIS에서 호스팅(Inproc, out-of-proc)하는 방법 - AspNetCoreModuleV2 소개
12031정성태10/7/201916461오류 유형: 569. Azure Site Extension 업그레이드 시 "System.IO.IOException: There is not enough space on the disk" 예외 발생
12030정성태10/5/201923259.NET Framework: 864. .NET Conf 2019 Korea - "닷넷 17년의 변화 정리 및 닷넷 코어 3.0" 발표 자료 [1]파일 다운로드1
12029정성태9/27/201924100제니퍼 .NET: 29. Jennifersoft provides a trial promotion on its APM solution such as JENNIFER, PHP, and .NET in 2019 and shares the examples of their application.
12028정성태9/26/201919052.NET Framework: 863. C# - Thread.Suspend 호출 시 응용 프로그램 hang 현상을 해결하기 위한 시도파일 다운로드1
12027정성태9/26/201914798오류 유형: 568. Consider app.config remapping of assembly "..." from Version "..." [...] to Version "..." [...] to solve conflict and get rid of warning.
12026정성태9/26/201920226.NET Framework: 862. C# - Active Directory의 LDAP 경로 및 정보 조회
12025정성태9/25/201918525제니퍼 .NET: 28. APM 솔루션 제니퍼, PHP, .NET 무료 사용 프로모션 2019 및 적용 사례 (8) [1]
12024정성태9/20/201920426.NET Framework: 861. HttpClient와 HttpClientHandler의 관계 [2]
12023정성태9/18/201920895.NET Framework: 860. ServicePointManager.DefaultConnectionLimit와 HttpClient의 관계파일 다운로드1
12022정성태9/12/201924855개발 환경 구성: 458. C# 8.0 (Preview) 신규 문법을 위한 개발 환경 구성 [3]
12021정성태9/12/201940652도서: 시작하세요! C# 8.0 프로그래밍 [4]
12020정성태9/11/201923832VC++: 134. SYSTEMTIME 값 기준으로 특정 시간이 지났는지를 판단하는 함수
12019정성태9/11/201917386Linux: 23. .NET Core + 리눅스 환경에서 Environment.CurrentDirectory 접근 시 주의 사항
12018정성태9/11/201916181오류 유형: 567. IIS - Unrecognized attribute 'targetFramework'. Note that attribute names are case-sensitive. (D:\lowSite4\web.config line 11)
12017정성태9/11/201919993오류 유형: 566. 비주얼 스튜디오 - Failed to register URL "http://localhost:6879/" for site "..." application "/". Error description: Access is denied. (0x80070005)
12016정성태9/5/201920011오류 유형: 565. git fetch - warning: 'C:\ProgramData/Git/config' has a dubious owner: '(unknown)'.
12015정성태9/3/201925392개발 환경 구성: 457. 윈도우 응용 프로그램의 Socket 연결 시 time-out 시간 제어
12014정성태9/3/201919132개발 환경 구성: 456. 명령행에서 AWS, Azure 등의 원격 저장소에 파일 관리하는 방법 - cyberduck/duck 소개
12013정성태8/28/201922048개발 환경 구성: 455. 윈도우에서 (테스트) 인증서 파일 만드는 방법 [3]
12012정성태8/28/201926607.NET Framework: 859. C# - HttpListener를 이용한 HTTPS 통신 방법
12011정성태8/27/201926209사물인터넷: 57. C# - Rapsberry Pi Zero W와 PC 간 Bluetooth 통신 예제 코드파일 다운로드1
... [76]  77  78  79  80  81  82  83  84  85  86  87  88  89  90  ...