Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitLabGitLab/akabulous/so_you_want_to_build_a_nethunter_kernel
Android SecurityEmbedded Systems SecurityPenetration TestingMobile SecurityLearning & EducationLearning Paths & Courses
GitLabakabulous/so_you_want_to_build_a_nethunter_kernel

So You Want To Build A Nethunter Kernel

Android용 맞춤형 Kali NetHunter 커널 빌드에 대한 단계별 가이드: 소스 확보, 툴체인 선택, 크로스 컴파일, 플래싱.

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기웹사이트
31개월 전아직 검토되지 않음

So You Want To Build A Nethunter Kernel

소개

Nethunter 기기를 설정하려는 대부분의 사람들에게 가장 큰 장벽은 커널 요구 사항입니다. 기기에 이미 사전 빌드된(그리고 유지 관리되는) 커널이 없다면, 직접 커널을 빌드하라는 안내를 받게 될 것입니다. 이 과정에 대한 문서는 이미 많이 있지만, 제 경험상 어떤 내용이 자신의 경우에 해당하는지 아닌지 파악하기 어려울 수 있습니다.

이 문제는 나쁜 놈들 클릭베이트성 제목의 가이드를 쓰는 사람들, 예를 들어 “어떤 Android 기기에서든 Nethunter 커널을 빌드하자!” 또는 “10분 만에 Nethunter 커널 컴파일하는 법 배우기!” 같은 거짓 약속을 하는 사람들 때문에 더 악화됩니다. 또한 2025년 인터넷의 불행한 현실로, 많은 멍청이들 사람들이 ChatGPT나 다른 대규모 언어 모델이 자신의 질문에 대한 권위 있는 답변을 가지고 있다고 생각하지만, 그 모델들이 실제로 가진 것은 앞서 언급한 나쁜 놈들에게서 긁어 모은 정보일 뿐입니다.

저는 이 가이드를 가능한 한 철저하고 정직하게 작성하고 있습니다. 하지만 이 문서가 이 과정에서 읽어야 할 유일한 문서가 되도록 의도된 것은 아닙니다. 분명 이 문서가 답할 수 없는 질문이 생길 것입니다. 그러한 질문에 대한 답은 관련 소프트웨어 문서에서 찾으시고, YouTube나 ChatGPT에서는 찾지 마시기 바랍니다.

요구 사항

이 과정의 어떤 단계를 시작하기 전에, 이미 다음을 완료해 두어야 합니다:

  • 기기의 부트로더 잠금을 해제
  • AOSP(Android Open-Source Project) 기반 ROM(LineageOS, crDroid 등) 설치 (선택 사항: 커스텀 리커버리 설치)
  • Magisk 28.1로 휴대폰을 루팅 + Zygisk 활성화 (편집: 최신 버전의 NHTerm에서는 이제 Magisk를 최신 버전으로 안전하게 업데이트할 수 있지만, NHTerm을 열 때 문제가 발생하면 28.1로 되돌리십시오)
  • Magisk에 kali-nethunter-2025.4-generic-arm64-minimal.zip 플래시 (작성 시점 기준 최신 버전)
  • Nethunter 앱 + Nethunter 터미널 앱이 작동하는지 확인
  • 설치된 모든 패키지 업데이트 apt update && apt upgrade -y (선택 사항: 메타패키지 추가)
  • Nethunter용 무선 펌웨어 Magisk 모듈 플래시

이 과정을 완료하려면 다음이 필요합니다:

  • GNU/Linux가 설치된 x86_64 프로세서 아키텍처(Intel/AMD)를 사용하는 데스크톱/노트북 컴퓨터 - (네, 필요한 경우 가상 머신이나 Docker 인스턴스를 사용할 수 있지만, 저는 단순히 “베어 메탈”에서 GNU/Linux를 실행하므로 그러한 도구의 사용법을 안내해 드릴 수 없습니다. 성능상의 이유로 같은 방식으로 실행하시길 권장합니다)
  • 최소 8GB RAM + 20GB의 여유 디스크 공간
  • 좋은 인터넷 연결 - (반 선택 사항: GitHub 또는 GitLab 계정. 변경 사항을 추적하기 쉬워지고, 커널 빌드에 성공하면 배포도 쉬워집니다. 계정을 만들지 않는다면 다른 사람과 커널을 공유할 수 있다고 기대하지 마세요. 소스 코드가 제공되지 않는 GPL 비준수 커널 이미지에는 아무도 관심이 없으니까요!)
  • Linux 명령줄 탐색에 대한 기본 지식 (cd, rm, ls, mkdir, find, diff, grep, 등)
  • 명령줄 기반 편집기 사용에 대한 기본 지식 (멋진 사람들은 vim, 그 외에는 nano)
  • C 프로그래밍 언어/Makefile 구문에 대한 기본 지식
  • 배포판의 소스 빌드용 메타패키지 설치 (Arch 계열 배포판은 build-devel, Debian 계열은 build-essential) – 일부 커널 Makefile에서 필요로 하므로 Perl + Python3도 설치하는 것이 좋습니다.

내 기기에서도 가능할까?

Linux 커널은 카피레프트 라이선스인 GNU General Public License 2.0으로 라이선스되어 있습니다. 즉, Linux 커널의 소스 코드는 자유롭게 배포되며 원하는 대로 소스 코드를 수정할 수 있지만(각 Android 제조사가 그렇게 해 왔듯이), 그러나 수정 결과물인 소스 코드 역시 자유롭게 배포되어야 합니다.

놀랍지도 않게도, GPL 라이선스 코드를 사용하는 거대 기업들 중 상당수가 이 라이선스의 조항을 무시합니다. 그들은 소스 코드 배포를 거부하거나 일부만 공개합니다(대개 망가졌거나 오래되었거나 인라인 바이너리 블롭이 포함된 형태로). 기기용 커널의 소스 코드를 구할 수 없다면, 그 기기용 Nethunter 커널을 만들 방법은 없습니다.

부트로더 잠금을 해제하고 커스텀 ROM을 설치할 수 있는지 여부도 기기 제조사의 변덕에 크게 좌우됩니다. 제조사가 부트로더 잠금 해제를 허용하고 Magisk로 휴대폰을 루팅할 수 있었다 하더라도, 디바이스 트리를 공개하지 않으면 기기용 커스텀 ROM이 없을 가능성이 높습니다. 이런 경우, 그들이 공개한 커널 소스 코드(있다면)가 출시 이후 전혀 관리되지 않았거나, 수정 없이는 빌드조차 되지 않을 가능성이 매우 높습니다. 다른 누군가가 당신의 기기를 위해 무언가(커널, ROM, 리커버리)를 유지 관리하고 있는 모습이 보이지 않는다면, 그 기기를 완전한 Nethunter로 만드는 것은 불가능하지는 않더라도 매우 어려울 것입니다.

커널 버전에 관한 참고 사항

당신의 기기에 정기적으로 업데이트되고 유지 관리되는 커스텀 ROM/커널/리커버리가 있다고 가정해 봅시다. 하지만 Nethunter 커널만 존재하지 않는다고요. 이 경우에는 이 과정을 완료할 수 있어야 하지만, 그 과정은 기기가 사용하는 Linux 커널 버전에 따라 달라집니다.

이 가이드의 정보는 제가 4.14.x 커널을 수정한 경험을 바탕으로 합니다. 3.x 커널에 적용되는 GCC 툴체인(우리가 사용할 LLVM/clang 대신) 사용에 대해 다루는 오래된 가이드도 있습니다. 기기가 5.x/6.x 버전의 Linux 커널을 사용한다면, 이 가이드의 정보만으로는 이 과정을 완료하기에 충분하지 않습니다. Android 빌드 방식은 수시로 바뀌므로, GKI 커널과 Bazel/Kleaf 사용을 다루는 가이드를 찾아보시기 바랍니다.

첫 단계: 소스, 툴체인, 구성

기기용 커널 소스가 포함된 저장소를 찾는 좋은 방법은 해당 기기의 코드네임을 사용하는 것입니다. 모든 Android 기기에는 코드네임이 있습니다. 일부 제조사(예: OnePlus)는 다른 제조사(예: Samsung)보다 이 작명을 조금 더 재미있게 하기도 하지만요. 제 Xiaomi Poco X3 NFC의 코드네임은 “surya”이고, 제 Samsung A51의 코드네임은 “SM-A515F”입니다. 일반적으로 커널 소스 저장소는 android_kernel_MANUFACTURER_CODENAME 명명 규칙을 따릅니다. 여기서 제조사는 모회사, 즉 android_kernel_xiaomi_surya이지 android_kernel_poco_surya가 아닙니다. 하지만 기기의 SoC(시스템 온 칩)를 기준으로 한 저장소도 있을 수 있으며, 같은 SoC를 사용하는 다른 기기의 소스 파일을 포함하도록 “통합”된 경우도 있습니다. 제가 언급한 Samsung이 그런 경우로, 소스 저장소 이름은 android_kernel_samsung_exynos9611입니다. github/gitlab을 살펴보고 무엇을 찾을 수 있는지 확인해 보세요.

이 가이드에서는 surya에 최신 LineageOS 22.2(2025-08-04 빌드)를 사용할 예정이므로, LineageOS 저장소에서 커널 소스를 클론하려고 합니다. 하지만 그 전에 기기에서 커널 빌드에 사용할 컴퓨터로 두 파일 /proc/config.gz와 /proc/version을 복사하고 싶습니다.

첫 번째 파일인 /proc/config.gz를 /sdcard에 복사하고, ADB로 기기에서 가져온 다음 gunzip으로 압축을 풀고 이름을 바꿀 수도 있습니다. 하지만 단계가 너무 많아 보여서, 대신 저는 이렇게 했습니다:

01

그런 다음 기기 자체에서 (root로) 다음을 실행했습니다:

02

여기서 무슨 일이 일어나고 있는 걸까요?

내 노트북에서: nc(netcat) -l(들어오는 연결 수신 대기) -p(포트) 4545(실제로는 1024-65535 사이의 아무 숫자나 가능하지만, 저는 보통 4545를 사용합니다) >(파일에 쓰기) surya-defconfig-lineageos22.2-20250804(설명적인 파일 이름) <(파일에서 입력받기) /dev/null(널 장치 – 키보드를 건드리더라도 입력된 키 입력이 수신 중인 파일로 전송되어 망치는 일을 방지합니다).

휴대폰에서: zcat(연결을 위한 cat 명령과 비슷하지만 gzip 압축 파일용) /proc/config.gz(현재 실행 중인 커널이 빌드될 때 사용된 커널 구성) |(그 프로세스의 출력을 다음 프로세스의 입력으로 전송) nc(다시 netcat) 192.168.1.42(내 노트북의 로컬 IP 주소) 4545(앞서 설정한 포트)

이렇게 하면 현재 실행 중인 커널을 빌드할 때 사용된 .config 파일을 얻을 수 있을 것으로 예상되지만, 항상 그런 것은 아닙니다. 일부 최신 기기/최신 ROM 빌드는 /proc/config.gz에 저장된 config가 스톡 커널 빌드에 사용된 .config와 일치하지 않으면 부팅을 거부합니다. 다행히도 이 검사가 전부입니다(커널 전체의 SHA256 체크섬처럼 훨씬 깨기 어려운 것이 아니라). 그래서 몇몇 영리한 사람들은 자신들의 수정에도 불구하고 /proc/config.gz의 파일을 스톡 커널과 일치하도록 스푸핑하는 방법을 고안했습니다. 기기의 파일이 진짜인지 스푸핑된 것인지 확실하지 않다면, zcat /proc/config.gz | head를 실행한 다음 uname -r을 실행해 보세요. 릴리스 번호가 일치하지 않으면 /proc 안의 파일은 스푸핑된 것입니다. 그런 경우에도 이 가이드를 계속 진행할 수는 있지만, 추출된 config와 커널 소스의 arch/arm64/configs 디렉터리에서 찾을 수 있는 일부 파일을 비교하기 위해 diff를 실행하는 것이 좋습니다.

/proc/version의 경우, 그 파일을 보내는 것이 그렇게 필요하지 않을 수도 있습니다. 실제로 필요한 것은 커널을 컴파일하는 데 사용된 clang/ld.lld 버전 정보뿐이니까요. 그러니 그냥 cat /proc/version을 실행해서 살펴보면 됩니다:

03

이런! 이 커널을 빌드한 사람이 약간 “실수”를 한 것 같습니다. Makefile에 clang으로 실행한 모든 -CFLAGS는 기록했지만 Clang 버전을 기록하지 않았네요. 하지만 그들이 사전 빌드된 Android 툴체인과 ld.lld 버전 19.0.1을 사용했다는 것은 알 수 있습니다.

여기 조금 더 도움이 되는 이미지가 있습니다. 첫 번째 출력은 Samsung A51에 새 커널을 수정, 빌드, 설치하기 전의 /proc/version이고, 두 번째 출력은 현재의 /proc/version입니다.

04

뭔가 눈에 띄나요? (아니요, 제 이상한 사용자 이름과 호스트네임 말고요).

사용할 툴체인을 고르는 가장 좋은 비결은 현재 실행 중인 커널을 컴파일한 정확한 툴체인을 사용하는 것입니다.

이 경우에는 Neutron clang 18.0.0git이었고, 찾기가 꽤 쉬웠습니다:

05

그런데 이것 좀 보세요. md5sum까지 모두 일치합니다.

재미 삼아, 훨씬 오래된 기기인 Samsung J7(2016), 코드네임 j7xelte의 /proc/version 문자열을 잠깐 살펴보겠습니다:

06

이 기기는 커널 컴파일에 여전히 GCC 툴체인을 사용할 만큼 오래된 기기입니다.

그런데 “gcc version 4.9.x 20150123 prerelease”로 검색하면 저장소가 두 개 나옵니다:

07

그렇다면 어떤 것을 다운로드해야 할까요?

답: 둘 다. GCC는 Clang과 다른 점이 있는데, 크로스 컴파일용 컴파일러/binutils/링커 등을 빌드할 때 각 “타깃 트리플”마다 별도의 툴체인을 빌드해야 한다는 것입니다. 타깃 트리플은 (아마도) 다음 형식을 취합니다:

machine-vendor-operating_system

하지만 곧 알게 되겠지만, 이 “규칙”에는 수백만 가지 예외가 있습니다. 그럼 “machine”부터 시작해 봅시다.

이 문서의 “필요한 것” 섹션에서 저는 GNU/Linux를 실행하는 Intel 또는 AMD 프로세서를 사용하는 64비트 컴퓨터가 필요하다고 말했습니다. 그 이유는 우리가 사용할 툴체인이 x86_64-linux-gnu에서 실행되도록 컴파일되었기 때문입니다.

하지만 이러한 툴체인은 크로스 컴파일러입니다. 즉, C 소스 코드 파일에서 생성하는 기계어 코드는 그 컴퓨터에서 실행되는 것이 아니라, 고유한 target triple을 가진 다른 컴퓨터에서 실행된다는 뜻입니다.

arm64라고도 알려진 Aarch64는 거의 모든 Android 기기가 사용하는 아키텍처입니다. “64”가 빠진 Arm은 ARM 칩의 32비트 구현을 말합니다. 대부분의 Android 커널은 32비트 소프트웨어와의 하위 호환성을 제공하기 위해 aarch64와 arm 트리플을 모두 사용하여 컴파일됩니다.

다음 부분인 “Linux”로 넘어가 보면, 설명이 필요 없습니다. Linux 커널이니까요.

하지만 이러한 “트리플”의 마지막 부분은 최소한 간단히라도 설명해 둘 가치가 있습니다. 너무 복잡하게 얽힌 난장판이고, “트리플”을 사용하는 각 컴파일러(GCC, Rust, Go, LLVM)가 조금씩 다르게 사용하기 때문입니다. 첫 번째 예시인 “Android”는 말이 되지만, “androideabi”는 무엇일까요? EABI는 “embedded application binary interface”의 약자입니다. 하지만 그에 대해 너무 걱정할 필요는 없습니다. EABI를 그냥 “기본” 세 번째 값이라고 생각합시다. “gnueabi”도 볼 수 있을 텐데, 이제 조금 더 이해가 되죠? EABI의 GNU 구현이니까요, 맞죠? (이것이 실제로 가리키는 것은 GNU의 C 라이브러리인 glibc입니다. 그래서 musl 같은 대체 C 라이브러리를 대상으로 빌드할 때 arm-linux-musleabi 같은 트리플도 보게 되는 것입니다.) “gnueabihf”도 볼 수 있을 겁니다. HF는 “hard float”를 뜻합니다. ARM이 부동 소수점 정수 연산을 위한 온칩 솔루션을 어떻게 구현했는지 알고 싶다면 Wikipedia 문서를 읽어 보세요.

우리가 알아야 할 것은 다음과 같습니다:

LLVM 툴체인을 사용하는 경우, 명령줄에서 CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi- (이렇게 끝에 -를 붙여서)를 설정하여 크로스 컴파일 의도를 선언합니다.

매우 오래된 기기용으로 컴파일하는 경우, 따라서 GCC 툴체인을 사용하는 경우에는 서로 다른 트리플로 접두사가 붙은 두 세트의 파일이 필요합니다. 이들은 LLVM 예시의 값과 같을 수도 있고, j7xelte용 툴체인처럼 다를 수도 있습니다.

그런데 왜 같은 것을 표현하는 방법이 이렇게나 많을까요? i386, i686, 386, i32, i64, x86, x64, x86_64, amd64 -- 이런 다양함에는 대체 무슨 이유가 있을까요?!

관련된 xkcd 만화:

08

오늘 컴파일할 예제(surya)로 돌아가서, 저는 우연히 다른 커널의 /proc/version 정보를 저장해 두었는데, 그 내용은 다음과 같았습니다:

09

이것이 대체로 있어야 할 모습입니다. 링크, 체크섬, 컴파일러/링커 버전 등이 포함되어 있죠. 여기서 clang과 LLD 버전이 모두 17.0.3이고, 현재 LineageOS의 망가진 /proc/version이 LLD 19.0.3을 보여주므로, 둘 다 19.0.3인 툴체인을 찾는 것이 타당하다고 생각합니다. 약 3분 검색 끝에 재현 가능한 빌드를 더 쉽게 만들기 위해 서브모듈로 클론할 수 있는 저장소를 찾았습니다: https://gitlab.com/kei-space/clang/r536225/ 그 툴체인은 심각한 문제가 있는 것으로 드러나서 Neutron Clang 19로 진행했습니다. (이 부분은 나중에 다시 다루겠습니다).

이제 클론할 소스와 툴체인이 준비되었습니다. 그럼 다음 단계로 넘어가겠습니다:

환경 설정

이 튜토리얼을 위해 새 사용자를 만들기로 결정했습니다. 주로 gh auth login을 사용하고 실수로 제 기본 GitHub 계정에 커밋하지 않도록 하기 위해서입니다. 하지만 그러려면 (브라우저에서) 계정을 만들고, 새 사용자를 설정하고, 그 사용자용 SSH 키를 생성해야 했습니다…

10

.ssh/id_ed25519.pub를 GitHub에 복사한 다음, 터미널로 돌아와 gh를 실행합니다

11

그러면 준비 완료입니다

12

…거의요. 아직 브라우저에서 저장소를 포크해야 합니다.

13

그런 다음 터미널에서 init/클론합니다.

14

모든 준비가 끝나면(소스 최신 상태, origin 설정 등) 서브모듈 클론을 시작할 수 있습니다.

15

구문은 git submodule add URL directory/입니다.

16

커밋 히스토리를 매우 깔끔하게 유지하려면 각 변경 후에 git add .와 git commit -a를 실행해야 한다는 점을 기억하세요.

17

아직 git push를 실행하지는 않겠지만, 나중에 실행하게 되면 모든 커밋이 업데이트됩니다.

테스트 커널

이쯤에서 아마 이 가이드가 Nethunter 지원을 추가하기 위해 커널 소스를 수정하는 방법을 다루기를 기대하고 계실 것입니다. 곧 나옵니다. 하지만 먼저, 수정되지 않은 소스가 우리의 툴체인과 구성으로 어떻게 컴파일되는지 살펴보겠습니다.

18

현재 실행 중인 커널의 config를 커널 소스 디렉터리로 복사해야 하지만, 컴파일된 바이너리에 out/을 사용할 것이므로 그곳에도 복사해야 합니다. 또한 PATH 변수에 툴체인의 bin/ 디렉터리를 추가해야 합니다. export PATH=/home/build_user/android_kernel_xiaomi_surya/toolchain/bin:$PATH이라고 작성해도 되지만, 더 쉬운 방법은 그 디렉터리로 cd한 다음 export PATH=$(pwd):$PATH를 실행하는 것입니다. $()는 그 안에 포함된 명령의 결과로 확장되며, pwd는 현재 작업 디렉터리의 전체 경로를 표시합니다.

또한 툴체인의 bin/ 디렉터리 내용도 나열했습니다. LLVM binutils가 고유한 접두사를 가지고 있는지 확인할 수 있도록요. 이상적으로는 Makefile에 LLVM=1을 선언하면 AR=llvm-ar, AS=llvm-as 등을 자동으로 설정하는 지시문이 들어 있습니다. 그럼 Makefile에 무엇이 있는지 살펴보겠습니다.

19

훌륭합니다! 간단히 LLVM=1을 선언하면 나머지를 개별적으로 선언할 필요가 없습니다… 대부분은요. LLVM 어셈블러도 사용해야 하는데, 여기에는 자체 선언인 LLVM_IAS가 있습니다:

20

이제 선언해야 할 것은 ARCH=arm64 LLVM=1 LLVM_IAS=1 AS=llvm-as O=out CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi-뿐입니다. 많아 보일 수 있지만 각각의 binutil을 개별적으로 선언하는 것보다 훨씬 적습니다.

그럼 구성을 열기 위한 명령을 실행해 보겠습니다….

잠깐. 이 툴체인에 문제가 있는 것 같습니다. 그래서 서브모듈을 deinit하고, 대신 Neutron Clang 19.0.0을 여기에서 받기로 결정했습니다. wget으로 다운로드할 것입니다.

21

그런 다음 새로 만든 toolchain/ 디렉터리에 압축을 풉니다 (처음에는 .tar.zst 파일 추출 구문을 잊어버렸지만요)

22

그런 다음 이 디렉터리를 .gitignore 파일에 추가합니다.

이제 이 명령을 실행하면:

23

작동합니다. nconfig 메뉴가 열립니다:

24

많은 튜토리얼이 menuconfig를 사용하라고 하겠지만, 저는 nconfig를 선호합니다. 1) 더 보기 좋고 2) 이미 설치한 ncurses 라이브러리를 찾지 못해 로드되지 않는 menuconfig의 그런 경향이 없기 때문입니다. 어쨌든 이것은 테스트 커널일 뿐이므로 .config를 로드하고 저장하고(다시 .config로) 일단 끝내면 됩니다.

이제 Image.gz 빌드를 시도해 보면…

25

첫 번째 오류입니다! 만세!

이 글에 따르면, Arch 업데이트가 무언가를 망가뜨렸기 때문입니다.

Arch가 가져가기도 하지만, Arch는 주기도 합니다. 이번에는 AUR 패키지 libxml-legacy의 형태로 말이죠. 그래서 그것을 설치하고 make를 다시 실행했더니, 이번에는:

26

LineageOS 유지 관리자들에게 박수를 보냅니다. 전체 커널이 단 하나의 경고만으로 빌드되었으니까요:

27

이제 out/arch/arm64/boot/에서 Image.gz를 찾을 수 있습니다. 하지만 이것을 어떻게 기기에 플래시할까요?

AnyKernel3 zip을 만들어야 합니다.

이 작업에는 두 가지 방법이 있습니다:

  1. 처음부터 만들기
  2. 기기용으로 이미 존재하는 커널 zip을 가져와서 그 안의 커널 이미지를 새로 컴파일한 파일로 교체하기저는 2번이 훨씬 노력이 덜 들어서 선호합니다. 또한, 우리 기기가 커널 zip에 무엇을 포함해야 하는지 알 수 있다는 장점도 있습니다. 압축되지 않은 Image 이미지일 수도 있고, 우리가 만든 Image.gz 하나뿐일 수도 있으며, Image.gz-dtb(디바이스 트리/커널 결합 이미지 – 요즘은 흔하지 않지만, 기기가 이것을 요구한다면 커널 구성에서 "Build a concatenated Image.gz-dtb"를 활성화해야 합니다)일 수도 있고, Image.gz, dtbo.img, 그리고/또는 dtb.img일 수도 있습니다.

28

이 가이드의 목적을 위해, 텔레그램에 소스 링크 없이 배포되는 수많은 커널 중 하나를 다운로드했습니다. 바보 같은 애니메이션 이름을 가진 커널이었죠. 이런 커널은 절대 설치하지 마세요.

하지만 우리는 그렇게 하지 않을 겁니다. 걱정 마세요. 우리는 그들의 AnyKernel zip 구성을 빌려쓸 뿐입니다. 그래서 파일 이름을 바꾸고 압축을 풉니다.

29

그리고 anykernel.sh 스크립트를 편집하여 커널 이름 문자열도 변경했습니다. 이제 그 zip에 들어 있는 Image.gz를 우리 새 파일로 덮어씁시다.

30

zip -f("freshen"의 약자)를 사용하면 내부의 파일을 새 버전으로 간단히 교체합니다. 0은 압축 없음을 의미합니다.

이 커널을 플래시할 수 있는지, 부팅되는지 확인해 봅시다. 하지만 그 전에:

31

커널 zip에 시간과 날짜 문자열을 포함하면 관리하기가 훨씬 쉽습니다.

32

하지만 철저함을 기하기 위해(그리고 텔레그램 커널에 최대한 의존하지 않기 위해), 직접 dtb.img 및/또는 dtbo.img 파일을 만드는 방법도 알려드리겠습니다. 관련 문서가 형편없을 정도로 부족하기 때문입니다.

이 목적을 위해 존재하는 두 가지 AOSP 프로그램이 있습니다. 그중 하나인 mkdtboimg는 Python으로 작성되어 있어 공식 AOSP 웹사이트에서 mkdtboimg.py를 다운로드하여 실행하기 쉽습니다. 하지만 C로 작성되었고 Makefile 없이 배포되는 다른 프로그램인 mkdtimg도 필요할 수 있습니다. 문서에 따르면, Android.bp 파일이면 충분합니다. 거기에 나열된 명령어를 실행하려면 AOSP 전체 코드를 체크아웃하기만 하면 됩니다. 저는 이것이 완전히 미친 짓이라고 생각해서, 오래전에 누군가가 이 도구를 단독으로 빌드하기 위해 만든 Makefile을 가져와 소스 파일을 최신 버전으로 업데이트한 다음, Musl에 대해 static-PIE로 빌드했습니다. 이 바이너리(커널을 빌드하는 데 사용하는 것과 같은 모든 x86_64 Linux 컴퓨터에서 실행됩니다)는 여기에서 다운로드하거나 소스 코드에서 직접 빌드할 수 있습니다.

이제 까다로운 부분입니다. 커널 빌드 중에 생성되는 .dtbo 파일은 약간의 추가 작업 없이는 dtb.img/dtbo.img 파일로 변환할 수 없습니다. Android는 dtc 호출에 -a 64 플래그를 포함해야 합니다. 이미 DTC_EXT=/usr/bin/dtc를 호출하여 Makefile이 많은 커널에서 발견되는 고장난 DTC가 아닌 패키지 관리자의 멋진 업데이트된 DTC를 사용하도록 강제하고 있으므로, 해당 명령을 작은따옴표 안에 넣고 플래그를 추가하는 것은 그리 어렵지 않습니다. DTC_EXT='/usr/bin/dtc -a 64'를 전달하기만 하면 됩니다. 하지만 제 경우에는 제가 관리하는 모든 커널에 대해 build.sh 스크립트를 만들고(테스트)하는 것을 좋아합니다. 그래야 이 가이드를 읽지 않더라도 아무리 초보라도 소스에서 직접 빌드할 수 있기 때문입니다. 단일 따옴표와 이중 따옴표가 겹겹이 쌓인 bash 로직과 씨름하던 중, DTC가 올바른 플래그로 호출되도록 보장하는 간단하면서도 우아하지 않은 해결책을 찾았습니다: 래퍼 스크립트입니다.

커널 최상위 디렉토리에 dtc라는 실행 파일을 만들고 다음 줄을 넣었습니다.

#!/bin/sh

exec /usr/bin/dtc -a 64 $@

그런 다음 DTC_EXT=를 해당 파일로 지정하면 해결됩니다.

"도대체 무슨 .dtbo 파일? 내 커널 빌드는 그런 걸 생성한 적이 없는데!"라고 궁금해할 수도 있습니다. 그렇다면 이 커널 심볼이 활성화되어 있는지 확인하세요:

61

그럼 이 도구들을 어떻게 사용할까요? 가장 먼저 한 일은 다른 커널 zip에서 찾은 dtb.img와 dtbo.img 파일을 분석하여 어떤 종류의 파일인지 확인하는 것이었습니다. (알아요, 알아요. 우리는 이상한 커스텀 ROM 씬 커널에 의존하고 싶지 않지만, 확인해 볼 가치는 있습니다.) file dtb.img 명령은 다음을 반환했습니다:

dtb.img: Device Tree Blob version 17, size=345849, boot CPU=0, string block size=31481, DT structure block size=314312

이는 file ../arch/arm64/boot/dts/qcom/sdmmagpie.dtb를 실행했을 때 얻는 결과와 (거의) 정확히 동일합니다:

../arch/arm64/boot/dts/qcom/sdmmagpie.dtb: Device Tree Blob version 17, size=345856, boot CPU=0, string block size=31481, DT structure block size=314312

그 약간의 차이가 걱정되었지만, diff <(strings dtb.img) <(strings ../arch/arm64/boot/dts/qcom/sdmmagpie.dtb)를 실행해 보니 정확히 동일한 내용이 포함되어 있다는 것을 알게 되었습니다. 따라서 sdmmagpie.dtb를 복사하고 이름만 바꾸면 자체 dtb.img를 만드는 것이 가능하다고 안전하게 가정할 수 있었습니다.

dtbo.img의 경우, file 명령이 별 도움이 되지 않습니다:

dtbo.img: data

하지만 여기서 mkdtimg 또는 mkdtboimg.py를 사용하여 분석할 수 있습니다. mkdtimg dump dtbo.img를 실행하면 다음을 얻습니다:

61

그래서 직접 만들 때는 다음 중 하나를 전달해야 한다는 것을 알게 되었습니다:

mkdtimg create dtbo.img --page_size=4096 ../arch/arm64/boot/dts/qcom/sdmmagpie-idp-overlay.dtbo

또는

mkdtboimg create --page_size=4096 dtbo.img ../arch/arm64/boot/dts/qcom/sdmmagpie-idp-overlay.dtbo

두 명령 모두 동일한 파일을 생성합니다. 이후 mkdtimg dump dtbo.img를 실행하여 값을 다른 파일과 비교할 수도 있습니다. 이미지에 .dtbo 파일을 두 개 이상 포함해야 하는 경우, 두 명령 중 하나의 끝에 해당 경로를 추가하기만 하면 됩니다.

이제 우리가 만든 테스트 커널로 돌아갑시다. 좋은 소식은 아무 문제 없이 플래시되었다는 것이고, 나쁜 소식은 그렇게 못생긴 /proc/version을 만드는 Makefile을 고쳐야 한다는 것입니다.

하지만 그것은 나중에 할 수 있습니다. 이제 마침내 우리가 도달한 곳은:

커널을 Nethunter 커널로 만들기

이제 서브모듈을 추가할 차례입니다. 먼저 이것은 따라 하기 매우 쉬운 지침이 함께 제공됩니다. (편집: 이제 CAN 서브시스템 커널 심볼도 포함합니다. 제 풀 리퀘스트가 병합되어 추가되었기 때문입니다. 아래 스크린샷에서는 보이지 않지만요).

33

이제 다시 make nconfig를 실행하면(이전과 동일한 명령)

34

이 멋진 새 옵션이 보입니다.

35

이것이 이 모든 것들을 활성화합니다. 그것을 선택하고 .config로 저장하세요. 하지만 주의하세요. 그것은 out/.config에 저장되며, 우리는 다시 빌드하기 전에 해당 디렉토리 전체를 삭제할 것입니다. 따라서 nconfig를 종료한 후 해당 파일을 커널 소스 디렉토리로 복사하세요.

이제 일부 소스 파일을 패치할 차례입니다. nethunter 빌드 스크립트 저장소를 서브모듈로 추가합시다:

36

새 디렉토리로 cd하고 ./build.sh를 실행한 다음 옵션 4: Apply Nethunter kernel patches를 선택합니다.

37

"테스트 실행이 오류로 완료되었습니다"라는 메시지가 표시되면 패치를 적용하지 마세요. 그렇지 않으면 적용하세요. 제 경우에는 패치 4, 5, 8을 적용했습니다.

이제 변경 사항을 만들었으니 커널 소스 최상위 디렉토리로 돌아가 커밋합시다.

38

이 시점에서 커널을 다시 빌드하기만 하면 끝납니다.

하지만 저는 과할 정도로 철저한 사람이라 수많은 추가 기능에 대한 지원을 포함하고 싶습니다. 즉:

  • rtl88xxau/rtl8188eus용 Aircrack-ng 드라이버 – 이건 그리 어렵지 않아야 함
  • rtl88x2bu 및 rtl8188fu용 Realtek 드라이버 – 이것들을 모듈로 빌드하기만 하면 괜찮을 것임
  • Mediatek 드라이버 mt76 (mt76x0u 및 mt76x2u) – 이것들은 4.19에서 업스트림에 도입되었고 이것은 4.14 커널이라 조금 더 까다롭습니다. 하지만 생각만큼 까다롭지는 않습니다
  • WireGuard 커널 레벨 지원 – 이건 매우 쉽습니다. 커널 구성에서 활성화하기만 하면 됩니다
  • Docker 지원 – Nethunter 변경에 방금 사용한 것과 유사한 Kconfig가 있어서 쉬울 것임

과할 정도로 철저하게

39

구성에서 새로 추가된 드라이버를 인식하도록 하려면 drivers/net/wireless/realtek에 있는 Kconfig와 Makefile을 수정해야 합니다. 하지만 또한:

40

rtl8812au/Makefile에서 플랫폼을 ANDROID_ARM64로 전환했는지 확인하세요 (rtl8188eus도 마찬가지).

새로 추가된 드라이버의 Kconfig에서 구성 옵션이 무엇이라고 불리는지 다시 확인하는 것도 가치가 있습니다:

41

이제 한 단계 위의 Makefile에서 88XXAU라고 참조해야 한다는 것을 압니다.

42

운 좋게도 Kconfig는 이렇게 소스로 포함되기만 하면 됩니다:

43

rtl88x2bu와 rtl8188fu의 ARM 브랜치를 추가한 후에도 이 파일들을 다시 편집해야 할 것입니다. (그리고 알고 보니 rtl88x2bu의 구성 옵션 이름은 RTL8822BU입니다. 그래서 항상 확인해 볼 가치가 있는 것입니다).

이제 MediaTek 백포트 드라이버입니다. 이 커밋을 가이드로 삼아 4.14.x 커널을 사용하는 두 대의 다른 기기에 이 드라이버를 성공적으로 포팅했습니다. (커밋 기록이 왜 중요한지 보이시죠?) 하지만 먼저 모든 파일이 포함된 mt76 디렉토리가 필요합니다.

Akabulous가 당신을 위해 준비했습니다

4.19 커널을 git clone해서 파일을 복사한 다음 새 복사본에서 필요한 패치를 만드는 대신, 간단히 https://github.com/akabul0us/mt76.git을 서브모듈로 추가하면 됩니다. 그런 다음 drivers/net/wireless/mediatek 디렉토리의 Makefile과 Kconfig를 편집하세요:

44

앞서 언급한 커밋의 패치가 이미 소스에 적용된 이 저장소를 추가함으로써, 우리가 다른 커널 파일에 적용해야 할 수정 작업으로 건너뛸 수 있습니다. 첫 번째는 이것입니다:

45

하지만 우리 커널 소스에는 이미 이 구조체가 있습니다:

46

그래서 다음 수정 대상 파일인 include/linux/overflow.h로 넘어갑니다. 이 파일에는 일부 수정 사항이 있지만 원래 커밋에서 매우 명확하게 읽을 수 있으므로 더 이상 스크린샷을 보여드리지 않겠습니다. include/linux/skbuff.h와 include/linux/scatterplot.h에도 변경 사항이 있지만 include/net/cfg80211.h에는 필요하지 않습니다. include/net/mac80211.h에 필요한 변경 사항은 사소합니다. enum mac80211_rx_encoding { } 안에 마지막 줄로 RX_ENC_HE를 삽입하고 struct ieee80211_rx_status { }에 u8 vht_flag;를 추가하는 것뿐입니다. net/wireless/of.c 파일은 이미 존재하며 우리가 체리픽하는 커밋의 파일과 동일하므로 그걸로 끝입니다. (휴!)

Docker 지원의 경우, (다시 한 번) cyberknight777의 이것 덕분에 복사해서 붙여넣기만 하면 됩니다.

47

이제 다시 nconfig를 실행할 준비가 되었습니다! …거의 다 됐습니다. 먼저 변경 사항을 커밋하고 푸시한 다음, rm -rf out/(.config를 그 밖에 저장했는지 확인)하고, mkdir -p out을 실행한 다음에야 구성으로 돌아갈 수 있습니다.

48

커널에 추가한 out-of-tree Realtek USB 드라이버에 대한 참고 사항: 그것들은 약간 형편없습니다. 그중 두 개 이상을 인라인으로 빌드하려고 하면 링크 시간에 오류가 발생합니다. 오랫동안 사용된 해결책은 하나(1)만 인라인으로 빌드하고 나머지는 모듈로 빌드하는 것입니다. 그러나 Mediatek 드라이버는 문제없이 인라인으로 빌드할 수 있습니다.

저는 결국 다른 여러 가지 것들도 활성화했습니다. 전체 diff를 보고 싶다면 여기에 올려 두었습니다. 어쨌든, 빌드합시다!

49

좋은 시작입니다. 방금 추가한 새 객체 파일이 오류나 경고 없이 컴파일되는 것을 보는 것은 언제나 기분 좋은 일입니다.

50

이건? 덜 기분 좋지만 고치기 쉽습니다. 경고 플래그로 -Wno-stringop-overread가 있는 Makefile에서 그냥 제거하면 됩니다. 그 김에 말인데, -Werror는 좀 과격하지 않나요? (이 플래그는 '모든 경고를 오류로 처리'한다는 뜻으로, 알 수 없는 -W 플래그를 포함한 어떤 문제든 컴파일을 중단시킵니다).

51

적어도 이건 고치기 쉽습니다.

52

그 줄 앞에 #을 하나 붙이면 다시 make를 실행할 준비가 됩니다. 그리고 이번에는 끝까지 완주했습니다!

하지만 일부 드라이버를 모듈로 구성했기 때문에 아직 끝난 것이 아닙니다. make modules를 실행해야 합니다. 더 정확히는 make -j $(nproc --all) ARCH=arm64 O=out CROSS_COMPILE=aarch64-linux-gnu- CROSS_COMPILE_32=arm-linux-gnueabi- LLVM=1 LLVM_IAS=1 AS=llvm-as modules입니다. 그리고 세상에, rtl8188fu용 Realtek 드라이버 코드는 정말 엉망입니다:

53

이 경고를 일으키는 각 줄을 수동으로 고칠 수 있을까요? 물론이죠. 고칠까요? 아니요. 제가 이 드라이버들을 인라인이 아닌 모듈로 컴파일하고 Realtek 기반 어댑터를 피하도록 적극 권장하는 데는 이유가 있습니다. 하지만:

54

적어도 컴파일은 성공했습니다. 잠시 후에 다시 다루겠습니다. 먼저 커널 zip을 새로 고칩시다:

55

(거의 잊을 뻔했습니다. 이제 이건 "테스트" 커널이 아니라 제대로 된 Nethunter 커널입니다.)

모듈의 경우 .tar 파일이 정말 최선의 방법입니다. 포함된 파일에 대한 모든 것을 보존하기 때문입니다. 하지만 경로도 보존합니다. 특별한 조치를 취하지 않으면 모듈 타르볼을 추출할 때 drivers/net/wireless/realtek/rtl8188fu/rtl8188fu.ko 같은 여러 디렉토리가 생성됩니다. 그러니 디렉토리를 하나 만들고(.gitignore에 추가), 그 안에 복사한 다음 아카이브를 만듭시다.

56

이것들을 커널처럼 플래시할 수 있을까요?

57

이것들은 기기의 어딘가에 추출해야 합니다. insmod /어떤/경로/whatever.ko를 실행했을 때 모듈이 로드되기만 하면 위치가 어디든 상관없다고 해서 "어딘가"라고 말하는 것입니다. /sdcard에 해도 괜찮습니다. 하지만 기억하세요, 저는 과할 정도로 철저한 사람이라 이 기기의 "적절한" 위치인 /vendor/lib/modules에 추출하겠습니다. 물론 /vendor는 읽기 전용으로 마운트되어 있으므로, 먼저 루트 셸을 실행하고(Nethunter 터미널이 아닙니다. 그건 chroot입니다. 다만 "새 세션 → 루트 셸"을 선택하면 Nethunter 터미널 앱을 사용할 수 있습니다) 해당 파티션에 무언가를 하기 전에 mount -o rw,remount /vendor를 실행해야 합니다. 그런 다음 cd /vendor/lib/modules; tar xzvf /sdcard/또는/저장한/위치/tarball.tgz; mount -o ro,remount /vendor를 실행하면 모듈 작업은 끝납니다.

해당 파티션에 공간이 없다는 오류가 발생하면 심볼릭 링크를 사용할 수도 있습니다. 예를 들어 /sdcard/modules에 파일을 보관한 다음 절대 경로를 사용하여 링크를 만드는 것입니다. 88x2bu.ko로 이 작업을 한다면 ln -s /storage/emulated/0/modules/88x2bu.ko /vendor/lib/modules/88x2bu.ko를 실행하면 됩니다.

58

저장소를 마지막으로 한 번 푸시하고, 원한다면 사용한 .config를 nethunter용 새 defconfig로 저장하세요. (이것은 소스에서 빌드하는 사람들에게 정말 큰 도움이 됩니다).

그리고 이제 - 하이라이트

작동할까요? 플래시는 잘 되죠, 물론입니다. 하지만 정말로 작동할까요?

음, 지금은 시간이 꽤 늦어서 모든 기능을 하나하나 테스트하지는 않겠습니다. 하지만 핵심적인 것부터 확인해 봅시다: 제가 커널에 추가한 드라이버의 모니터 모드/패킷 인젝션입니다. rtl88x2bu부터 시작합시다:

59

Realtek 드라이버치고는 나쁘지 않습니다.

이제 메인 이벤트입니다: mt76x2u:

60

이제 이건 펜테스팅 장비입니다!

마지막 단계는 .zip과 .tar.gz를 릴리스 형태로 github에 업로드하는 것입니다. 그런 다음 xdaforums, 텔레그램, 트위터 등 같은 기기/ROM 사용자들이 보고 혜택을 받을 만한 곳 어디든 게시하세요.

그리고 어떤 씻지도 않은 고마운 줄 모르는 멍청이가 "이제 BUTTPHONE 34AC PRO EDITION 기기용 커널 만들어줘?!!"라고 답글을 달면, 이 가이드 링크를 주고 실력을 키우라고 하세요.

여러분, 좋은 밤 되세요.

--Akabul0us

도구 다운로드