이 방식을 사용하면 바로 태블릿에 설치 가능한 형태로 빌드된다.

커널 소스 혹은 defconfig를 수정한 후 사용하고자 할 때 유용하다

빌드 방법 원문 : https://wiki.lineageos.org/devices/gta4xlwifi/build

0. vm에 ubuntu 18.04.6 설치 (하드 용량은 넉넉히 500기가 정도)

200기가로 빌드 불가능했음

램은 20기가 정도 설정

1. 의존 패키지 설치

sudo apt-get install openssh-server libwxgtk3.0-dev bc bison build-essential ccache curl python flex g++-multilib gcc-multilib git gnupg gperf imagemagick lib32ncurses5-dev lib32readline-dev lib32z1-dev liblz4-tool libncurses5 libncurses5-dev libsdl1.2-dev libssl-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc zip zlib1g-dev vim

2. adb 설치

https://dl.google.com/android/repository/platform-tools-latest-linux.zip

unzip platform-tools-latest-linux.zip -d ~

~/.profile에 아래 추가

# add Android SDK platform tools to path
if [ -d "$HOME/platform-tools" ] ; then
    PATH="$HOME/platform-tools:$PATH"
fi

3. 디렉토리 생성

mkdir -p ~/bin
mkdir -p ~/android/lineage

4. repo 설치

curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo
git config --global user.email "abc@lol.com"
git config --global user.name "kim kim"

5.

export USE_CCACHE=1
export CCACHE_EXEC=/usr/bin/ccache

6. ~/.bashrc 에 아래 추가 

ccache -M 50G

source ~/.profile 실행

7. 리니지OS 소스 전체 다운로드 (OS+소스 =  기가)

cd ~/android/lineage
repo init -u https://github.com/LineageOS/android.git -b lineage-18.1
repo sync

8. 갤럭시 탭 S6용 커널 다운로드

source build/envsetup.sh
breakfast gta4xlwifi

중간에 vendor 어쩌고 Makefile에러가 발생하면 9번 항목 실행후 breakfast 재시도

(대부분의 makefile에러는 make clean과 breakfast반복으로 해결 가능)

breakfast중 sepolicy.mk 에러가 발생한다면

cd ~/android/lineage/device
mkdir samsung_slsi
cd samsung_slsi
git clone https://github.com/LineageOS/android_device_samsung_slsi_sepolicy
mv android_device_samsung_slsi_sepolicy sepolicy

이 후 make clean 후 breakfast 재시도

9. ubuntu vm에 태블릿 연결 후 태블릿에서 충전이 아닌 PTP로 설정

주의 : adb shell에 su권한이 없으면 파일 복사를 실패함 -> 개발자 옵션에서 디버깅 시 루트 권한 사용 반드시 체크

cd ~/android/lineage/device/samsung/gta4xlwifi
./extract-files.sh

10. 커널 보호 기능 해제

~/android/lineage/kernel/samsung/gta4xl/arch/arm64/configs​/exynos9611-gta4xlwifi_defconfig 편집

아래의 각 라인을 찾아 y를 n으로 수정

(그외 참조 : https://kernsec.org/wiki/index.php/Kernel_Self_Protection_Project/Recommended_Settings)

CONFIG_EXYNOS_KERNEL_PROTECTION=y  
CONFIG_ARCH_HAS_STRICT_KERNEL_RWX=y
CONFIG_STRICT_KERNEL_RWX=y
CONFIG_ARCH_HAS_STRICT_MODULE_RWX=y
CONFIG_STRICT_MODULE_RWX=y
CONFIG_EXYNOS_CONTENT_PATH_PROTECTION=y
CONFIG_HAVE_ARCH_SECCOMP_FILTER=n

https://codetronik.tistory.com/155 참조하여 소스도 수정하여야 한다.

11. 빌드

cd ~/android/lineage
source build/envsetup.sh (커널소스 재빌드 시)

brunch gta4xlwifi

12. 출력 파일 확인

cd $OUT

존재 여부 확인 : recovery.img / lineage-18.1-20220418-UNOFFICIAL-gta4xlwifi.zip 

13. 태블릿에 롬 설치 후 adb shell 접속 후 dmesg > grep exynos로 아래의 로그가 뜨는지 확인 (뜨면 defconfig 수정 실패한 것임)

[    0.371387] exynos_protect_kernel_text: Kernel text start VA(0xffffff8008188000), PA(0x80188000)
[    0.371398] exynos_protect_kernel_text: Kernel text end VA(0xffffff8008e28000), PA(0x80e28000)

에러 유형은 dmesg에서 확인할 수 있다.

./insmod 1.ko

1) 에러 유형: 커널 컴파일 시 컴파일러를 android-aach64를 사용하여야 한다. android용이 아니면 에러가 발생한다.

2) 에러 유형: 커널 모듈과 커널 버전이 완전히 일치하여야 한다.

- lkm 버전 확인 : modinfo [lkm.ko]

- 리눅스 커널 버전 확인 : cat /proc/version

insmod: failed to load 1.ko: Invalid argument

(dmesg) 1.ko : disagrees about version of symbol printk

(demsg) 1.ko : Unknown symbol printk (err -22)

 

에러 유형: 커널 모듈과 커널 버전이 완전히 일치하여야 한다.

insmod: failed to load 1.ko: Exec format error

(dmesg) 1.ko : disagrees about version of symbol module_layout

 

에러 유형 : 삼성 단말기에선 LKM을 허용하지 않음 -> 이 경우, 우회하거나 커스텀 os를 새로 설치하여야 한다.

insmod: failed to load 1.ko: Exec format error

(dmesg) LKM is not allowed by Samsung security policy.

0. ubuntu 20.04.4 LTS x64

1. 의존 패키지 설치 Install Dependent Packages (defconfig 및 menuconfig 빌드를 위함)
sudo apt-get install build-essential libncurses5-dev python

2. 커널 소스 다운로드 Download the appropriate kernel source for your device.
Galaxy Tab S6 Lite : git clone https://github.com/LineageOS/android_kernel_samsung_gta4xl

3. 크로스 컴파일러 다운로드 후 경로 설정 Set path after downloading cross-compiler
git clone https://github.com/Shubhamvis98/toolchains

export PATH="/home/code/toolchains/clang-r428724/bin:/home/code/toolchains/aarch64-linux-android-4.9/bin:$PATH"
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-android-
export CLANG_TRIPLE=aarch64-linux-gnu-

4. 커널 소스 디렉토리로 이동 Go to the kernel source path
make clean
make mrproper
make exynos9611-gta4xlwifi_defconfig
make menuconfig  -> 실행 후 <Save> 클릭 

5. 컴파일 Build it
make -j16 CC=clang

6. 커널 소스 수정 (오류 발생 시) Modifying kernel sources (in case of error)
Open Makefile


KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \
   -fno-strict-aliasing -fno-common -fshort-wchar \
   -Werror-implicit-function-declaration \
   -Wno-format-security \
   -Werror \    <------------- 해당 라인 삭제 delete this line
   -std=gnu89

    private boolean checkRootMethod1() {
        for (String str : new String[]{"/system/app/Superuser.apk", "/sbin/su", "/system/bin/su", "/system/xbin/su", "/data/local/xbin/su", "/data/local/bin/su", "/system/sd/xbin/su", "/system/bin/failsafe/su", "/data/local/su"}) {
            if (new File(str).exists()) {
                return true;
            }
        }
        return false;
    }

exist() -> /apex/com.android.art/lib64/libjavacore.so에서 access()를 호출함

access() 후킹 코드 작성으로 우회 가능

int (*Org_access)(const char* __path, int __mode);
int hook_access(const char* __path, int __mode)
{
    register uint64_t result;

    __asm volatile ("MOV %0, LR\n" : "=r" (result));

    LOG("access path - %s %lx", __path, result);
    if (strstr(__path, "su"))
    {
        return -1;
    }
    return Org_access(__path, __mode);
}
A64HookFunction((void*)access, (void*)hook_access, (void**)&Org_access);

https://github.com/codetronik/AArch64Hook_android

테스트 환경 : 갤럭시 S6 Lite (android 11 : P610XXU2CUC3 (2021.03) 펌웨어)

android 7에서 통했던 /system/lib 폴더에 so를 복사하는 방법이 더이상 안됨

아래와 같은 에러 발생함.

dlopen failed: library "/system/lib64/libinject.so" needed or dlopened by "(unknown)" is not accessible for the namespace "classloader-namespace"

심지어 기존에 있던 시스템 라이브러리를 인젝션해도 동일 에러 발생.

해결 방법은 /data/user/0/app name/files/ 에 so를 복사함.

넷플릭스,정부24앱에서 인젝션 테스트 완료

1. 옵션->빌드 버전에서 현재버전 확인 후 각 버전에 맞는 펌웨어 다운로드

(11버전의 2021.03 펌웨어 P610XXU2CUC3 에서 루팅 확인)

samfw.com/firmware/SM-P610/KOO

https://samfrew.com/model/SM-P610/

2. adb 디버그 허용, oem 언락 허용(빌드버전 연타하면 나옴)

3. 파워 off 후 볼륨 상 + 볼륨 하(One UI 3.0이상,보통 안드로이드11버전)를 동시에 누르면서, 1초후에 usb를 연결한다. (연결되어있는 상태면 안되고 타이밍 맞게 연결해줘야됨) 잠시 후 다운로드 모드로 진입하게 된다.

볼륨상을 길게 눌러 부트로더 언락을 진행한다.

4. 초기화 완료되면 다시 빌드버전 연타한 후 oem이 언락되어 있는지 확인

5. ap.tar에서 boot.img.lz4만 추출후 압축해제 후 magisk manager설치 후 boot.img만 패치

그 후 아래의 명령어로 다시 압축 

c:/> lz4 -B6 --content-size boot.img boot.img.lz4

boot.img.lz4를 원본 ap의 boot.img.lz4에 덮어쓰고 다시 tar로 압축

 

lz4_win32_v1_9_3.zip
0.32MB

6. 파워 off후 다시 다운로드 모드에 진입한다. odin 실행 후 패치한 ap선택 후 tar파일을 선택하여 start를 누른다.

bl, csc(home_csc지정) 도 같이 설정해줘야 한다.

반드시 oem lock이 off 상태인지 확인한다. on이면 2부터 다시 반복한다.

Odin3-v3.14.4.zip
4.20MB

7. odin이 성공하면 몇번 재부팅되면서 실행되는데, 만약 try again, reset 하는 화면이 뜨면 reset한다.

이 과정을 거치고 화면이 보여진다면 다시 태블릿을 종료하고, 파워+볼륨상을 길게 눌러 리커버리 모드로 진입한 후에

wipe data/factory reset  과 wipte cache partition을 실행한다.

(안하면 내장 메모리 용량이 16기가로 인식됨)

아래 항목은 실패 시 참조

만약 에러가 발생하면 파워 + 볼륨하 버튼을 누르고 있는다.

태블릿 초록색 화면에 "An error has occurred while updating the device software. Use the Emergency recovery function in the Smart Switch PC software." 에러가 발생하면 아래의 프로그램을 설치한다.

Frp Hijacke rV1.0 setup.rar
1.12MB

위처럼 입력후 HIJACK IT!을 누르면 재부팅이 된다.

태블릿이 공장 초기화 상태로 되는데, 더이상 oem잠금해제가 보이지 않게 된다. 설정->일반 에서 "날짜 및 시간 자동 설정"을 비활성화 후 날짜를 현재 날짜에서 1달전 쯤으로 설정한다. 그다음 소프트웨어 업데이트를 시도하면 oem 잠금해제가 보이게 된다.

만약 다른 에러로 무한 다운로드 모드 상태가 지속된다면, 패치하지 않은 순정 ap, bl, home_csc펌웨어를 odin으로 올린다.

 

레퍼런스

forum.xda-developers.com/t/sm-p610-flash-only-official-released-binaries-are-allowed-to-be-flashed-recovery.4214009/

forum.xda-developers.com/t/howto-unlock-and-root-the-galaxy-tab-s6-lite.4132289/

 

1. Android Studio -> Create New Project -> Native C++

2. app/build.gradle을 열어보면 아래와 같이 되어있다.

android {
    compileSdkVersion 29
    buildToolsVersion "30.0.3"

    defaultConfig {
        applicationId "com.codetronik.myapplication"
        minSdkVersion 24
        targetSdkVersion 29
        versionCode 1
        versionName "1.0"

        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        externalNativeBuild {
            cmake {
                cppFlags ""
            }
        }
    }

arm64만 빌드하기 위해 externalNativeBuild { } 밑줄에 ndk { }를 추가한다. (수정하지 않으면 x86, x86_64, armeabi까지 모두 빌드됨)

        ndk {
            abiFilters 'arm64-v8a'
        }

만약 armeabi-v7a도 추가한다면 nox에서 64비트 모듈을 무시하고 32비트 모듈을 호출하게 되니 주의

3. nox 64비트 다운로드 (32비트를 받으면 arm64-v8a 에뮬레이션이 불가능)

4. 옵션에서 ROOT권한 주고, 개발자 옵션에서 USB 디버깅 허용 (구글에서 "nox 안드로이드 분석 환경" 로 검색해보면 가이드 많이 나옴)

5. 안드로이드 스튜디오에서 nox 기기를 apk 실행용으로 설정한다.

6. 아래와 같이 arm64-v8a 환경에서 잘 동작하는지 확인한다.

1) 아래는 arm64-v8a 전용 어셈블리어이므로, 타 cpu환경에서는 동작하지 않는다.

extern "C" JNIEXPORT jstring JNICALL
Java_com_codetronik_myapplication5_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++";

__asm__ (".byte 0x03\n"\
        ".byte 0x00\n"\
        ".byte 0x00\n"\
        ".byte 0x14\n"\
        ".byte 0xde\n"\
        ".byte 0xad\n"\
        ".byte 0xbe\n"\
        ".byte 0xef\n"\
        ".byte 0xde\n"\
        ".byte 0xad\n"\
        ".byte 0xbe\n"\
        ".byte 0xef\n");

    return env->NewStringUTF(hello.c_str());
}

2) nox-adb을 root로 실행 후 빌드한 jni가 arm64로 동작 중인지 확인한다.

테스트 환경 : windows 10 x64 build 19041

이 방식은 DRIVER_OBJECT -> OBJECT_HEADER_NAME_INFO ->  OBJECT_DIRECTORY -> OBJECT_DIRECTORY_ENTRY 순서대로 구조체를 얻어온 뒤 ENTRY 체인을 끊어 목록에서 제거하는 방식입니다.

이를 위해 먼저 최상위 OBJECT_DIRECTORY 부터 살펴봅니다.

lkd> !object ffffcb83e84023c0
Object: ffffcb83e84023c0  Type: (ffffdc8a4aa9c4e0) Directory
    ObjectHeader: ffffcb83e8402390 (new version)
    HandleCount: 0  PointerCount: 58
    Directory Object: 00000000  Name: \

    Hash Address          Type                      Name
    ---- -------          ----                      ----
     01  ffffdc8a4ccfe450 Mutant                    PendingRenameMutex
         ffffcb83e8451ad0 Directory                 ObjectTypes
     02  ffffdc8a4f6ec6e0 FilterConnectionPort      storqosfltport
     04  ffffdc8a55ba1c20 FilterConnectionPort      TsFltScanPort_V3LITE40
     05  ffffdc8a55ba1670 FilterConnectionPort      TsFltCheckPort_V3LITE40
         ffffcb83e84b6520 SymbolicLink              SystemRoot
     06  ffffcb83e8cfba20 Directory                 Sessions
     08  ffffcb83e848fb80 Directory                 ArcName
     09  ffffdc8a4f6ec9a0 FilterConnectionPort      WcifsPort
         ffffcb83e84ec060 Directory                 NLS
     10  ffffdc8a4fa27760 Event                     LanmanServerAnnounceEvent
         ffffdc8a4f86baa0 ALPC Port                 ThemeApiPort
         ffffdc8a4ce59d40 Device                    UdfsCdRom
         ffffcb83e8ba5380 Directory                 Windows
         ffffcb83e8467c50 Directory                 GLOBAL??
     11  ffffcb83e8cfb2a0 Directory                 RPC Control
         ffffdc8a4c3596a0 ALPC Port                 PdcPort
     13  ffffdc8a55b87400 FilterConnectionPort      MEDSRVPOSTPORT_V3LITE40_2.13.1.63
         ffffdc8a4cd7a4e0 Event                     EFSInitEvent
     14  ffffcb83e8c68930 SymbolicLink              Dfs
         ffffdc8a4c53c870 Device                    clfs
     15  ffffdc8a4c22dc90 Event                     CsrSbSyncEvent
         ffffdc8a4c62a790 ALPC Port                 SeRmCommandPort
     16  ffffcb83e8445830 SymbolicLink              DosDevices
     17  ffffdc8a55b92450 FilterConnectionPort      MEDSRVPENDINGPORT_V3LITE40_2.13.1.63
         ffffcb83e8cfbc00 Directory                 KnownDlls32
     18  ffffdc8a55b88fa0 FilterConnectionPort      MEDSRVSENDPORT_V3LITE40_2.13.1.63
         ffffcb83e849ad20 Key                       \REGISTRY
     19  ffffcb83e8836c00 Directory                 BaseNamedObjects
     20  ffffcb83e8ec49d0 Section                   Win32kCrossSessionGlobals
         ffffdc8a4ab13df0 ALPC Port                 PowerPort
     21  ffffdc8a4f412a10 ALPC Port                 SmSsWinStationApiPort
         ffffdc8a4c22b7b0 Event                     UniqueInteractiveSessionIdEvent
         ffffcb83e84ec920 Directory                 UMDFCommunicationPorts
     22  ffffcb83e8cfb840 Directory                 KnownDlls
         ffffdc8a4cc52d40 Device                    FatCdrom
         ffffdc8a4cc53d40 Device                    Fat
         ffffdc8a4ab46df0 ALPC Port                 PowerMonitorPort
     23  ffffdc8a4c626b50 Device                    Ntfs
         ffffcb83e84ec3e0 Directory                 FileSystem
         ffffcb83e8441cc0 Directory                 KernelObjects
     26  ffffdc8a4ebebd40 ALPC Port                 SeLsaCommandPort
         ffffcb83e8451ca0 Directory                 Callback
     28  ffffdc8a4f6ec580 FilterConnectionPort      BindFltPort
         ffffdc8a4c23dc30 Event                     DSYSDBG.Debug.Trace.Memory.2bc
         ffffcb83e84588d0 Directory                 Security
     29  ffffdc8a4ce31e00 Device                    UdfsDisk
     30  ffffcb83e8490060 Directory                 Device
     32  ffffcb83e84f8190 SymbolicLink              DriverData
     34  ffffcb83ebcfe610 Section                   LsaPerformance
         ffffdc8a4c8aec70 ALPC Port                 SmApiPort
     35  ffffdc8a4f6ec4d0 FilterConnectionPort      CLDMSGPORT
         ffffcb83e84b66d0 SymbolicLink              OSDataRoot
     36  ffffdc8a4c23e9f0 Event                     SAM_SERVICE_STARTED
         ffffcb83e84ec220 Directory                 Driver
         ffffcb83e8489820 Directory                 DriverStores

저의 windows의 windbg 화면으로, OBJECT_DIRECTORY 구조체는 타입과 이름을 가지고 있습니다. 최상위 구조체라서 타입은 HANDLE을 가지고 있습니다.

우리에게 필요한 것은 드라이버 목록인데, 이는 각각 23번, 36번 인덱스 2번째에 속해 있습니다. (FileSystem, Driver) 

일반적으로 드라이버를 로딩하면 Driver의 OBJECT_DIRECTORY에 연결되므로, 36번 인덱스의 Driver만 보도록 하겠습니다. 

위 주소를 다시 구조체로 표현해봅니다.

lkd> dt !_OBJECT_DIRECTORY  ffffcb83e84023c0
nt!_OBJECT_DIRECTORY
   +0x000 HashBuckets      : [37] (null) 
   +0x128 Lock             : _EX_PUSH_LOCK
   +0x130 DeviceMap        : (null) 
   +0x138 ShadowDirectory  : (null) 
   +0x140 NamespaceEntry   : (null) 
   +0x148 SessionObject    : (null) 
   +0x150 Flags            : 0
   +0x154 SessionId        : 0xffffffff

HashBucket은 37개의 배열로 구성되어 있으며, 각각 OBJECT_DIRECTORY_ENTRY로 표현됩니다. 각 OBJECT_DIRECTORY_ENTRY체인으로 연결되어 있습니다. 

운영체제는 각각의 Name에서 Hash Index 를 계산해 각 배열에 삽입하는 방식입니다. 따라서 연결된 Entry의 갯수는 일정하지 않습니다. 

보시면 00, 03번 인덱스는 존재하지 않고, 10번의 경우 5개의 오브젝트가 존재하는데 Name에서 동일한 Hash Index가 계산된 결과입니다. (Hash인덱스를 어떻게 구하는지는 모르겠습니다. 만약 알게되면 기술하도록 하겠습니다.)

HashBucket을 눌러보면 아래와 같이 나옵니다.

lkd> dx -id 0,0,ffffdc8a4aa96040 -r1 (*((ntkrnlmp!_OBJECT_DIRECTORY_ENTRY * (*)[37])0xffffcb83e84023c0))
(*((ntkrnlmp!_OBJECT_DIRECTORY_ENTRY * (*)[37])0xffffcb83e84023c0))                 [Type: _OBJECT_DIRECTORY_ENTRY * [37]]
    [0]              : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [1]              : 0xffffcb83e8ca8b10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [2]              : 0xffffcb83ec36c2e0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [3]              : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [4]              : 0xffffcb83f4a17c00 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [5]              : 0xffffcb83f4a17b70 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [6]              : 0xffffcb83e8caca10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [7]              : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [8]              : 0xffffcb83e84b5060 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [9]              : 0xffffcb83ebf53e70 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [10]             : 0xffffcb83ec371200 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [11]             : 0xffffcb83e8ca8d20 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [12]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [13]             : 0xffffcb83ece2c4c0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [14]             : 0xffffcb83e8b80690 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [15]             : 0xffffcb83e8caec90 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [16]             : 0xffffcb83e84af0c0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [17]             : 0xffffcb83ece2c430 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [18]             : 0xffffcb83ece2c400 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [19]             : 0xffffcb83e854c2e0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [20]             : 0xffffcb83e85439d0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [21]             : 0xffffcb83e8845930 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [22]             : 0xffffcb83e8ca8d80 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [23]             : 0xffffcb83e855f600 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [24]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [25]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [26]             : 0xffffcb83e8841160 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [27]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [28]             : 0xffffcb83ec36cca0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [29]             : 0xffffcb83e8cad460 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [30]             : 0xffffcb83e84b5630 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [31]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [32]             : 0xffffcb83e8545a00 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [33]             : 0x0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [34]             : 0xffffcb83e8841250 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [35]             : 0xffffcb83ec36c430 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [36]             : 0xffffcb83e8842420 [Type: _OBJECT_DIRECTORY_ENTRY *]

36번 인덱스의 주소를 구조체로 확인해봅니다.

lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83e8842420
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8568920 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffdc8a`4c23e9f0 Void
   +0x010 HashValue        : 0x9b5074d

2번째에 위치해있으니 ChainLink를 따라가봅니다.

lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83e8568920
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e84b5b10 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffcb83`e84ec220 Void
   +0x010 HashValue        : 0x80a0801

해당 OBJECT_DIRECTORY_ENTRY에 0xffffcb83e84ec220 오브젝트가 있음을 확인할 수 있습니다. (!object 한 것과 값을 비교해보세요) 이 주소는 OBJECT_DIRECTORY 구조체로 표현됩니다.(그래서 Type명이 Directory입니다.) 이를 다시 !object로 확인해봅니다.

lkd> !object 0xffffcb83e84ec220
Object: ffffcb83e84ec220  Type: (ffffdc8a4aa9c4e0) Directory
    ObjectHeader: ffffcb83e84ec1f0 (new version)
    HandleCount: 0  PointerCount: 124
    Directory Object: ffffcb83e84023c0  Name: Driver

    Hash Address          Type                      Name
    ---- -------          ----                      ----
     00  ffffdc8a50e1eb20 Driver                    kldbgdrv
         ffffdc8a4c9a2e20 Driver                    fvevol
         ffffdc8a4c356d70 Driver                    vdrvroot
     01  ffffdc8a4cd2ee00 Driver                    usbuhci
         ffffdc8a4cc9dd40 Driver                    GpuEnergyDrv
         ffffdc8a4ca4b9e0 Driver                    NetBT
         ffffdc8a4aa3fd00 Driver                    acpiex
         ffffdc8a4aa8bde0 Driver                    Wdf01000
     02  ffffdc8a4faabb70 Driver                    mpsdrv
         ffffdc8a4c53a060 Driver                    storahci
     03  ffffdc8a51c56540 Driver                    BthEnum
         ffffdc8a4fd73e20 Driver                    MMCSS
         ffffdc8a4f924e30 Driver                    lltdio
         ffffdc8a4cbdeb40 Driver                    bam
         ffffdc8a4cc63d80 Driver                    Psched
         ffffdc8a4cb8ae40 Driver                    BasicRender
         ffffdc8a4c9c28f0 Driver                    disk
     04  ffffdc8a4facadf0 Driver                    HTTP
         ffffdc8a4c382d80 Driver                    stornvme
     05  ffffdc8a4cdbe5b0 Driver                    e1i65x64
         ffffdc8a4cb9acb0 Driver                    WscVReg
     06  ffffdc8a4f641a70 Driver                    monitor
         ffffdc8a4cdb7b50 Driver                    usbehci
         ffffdc8a4cb9a6c0 Driver                    ahcache
         ffffdc8a4cafae40 Driver                    vmrawdsk
         ffffdc8a4c9c1dc0 Driver                    iorate
         ffffdc8a4c53b640 Driver                    pcw
     07  ffffdc8a4fcd4df0 Driver                    AMonCDW8
         ffffdc8a4cde8060 Driver                    Ucx01000
         ffffdc8a4cde7060 Driver                    USBXHCI
         ffffdc8a4c359dc0 Driver                    partmgr
     08  ffffdc8a52b98e50 Driver                    AntiStealth_V3LITE40
         ffffdc8a4fd83a10 Driver                    PEAUTH
         ffffdc8a4ab88e40 Driver                    MsLldp
         ffffdc8a4cc6fa30 Driver                    Vid
         ffffdc8a4ab0cd80 Driver                    ACPI_HAL
     09  ffffdc8a4c372850 Driver                    spaceport
     10  ffffdc8a4cf1ae00 Driver                    HidUsb
         ffffdc8a4cc62dd0 Driver                    vwififlt
     11  ffffdc8a50ea0e10 Driver                    condrv
         ffffdc8a4cb9be40 Driver                    DXGKrnl
         ffffdc8a4ab35e20 Driver                    PnpManager
     12  ffffdc8a4c9c9740 Driver                    Null
         ffffdc8a4c35ca80 Driver                    vsock
         ffffdc8a4ab3be20 Driver                    intelpep
     13  ffffdc8a506c4e30 Driver                    MeDCoreD_V3LITE40
         ffffdc8a4aa81e20 Driver                    Telemetry
         ffffdc8a4aae6de0 Driver                    SoftwareDevice
     14  ffffdc8a52e98a70 Driver                    RFCOMM
         ffffdc8a4ca57e10 Driver                    Serenum
         ffffdc8a4c8ae0a0 Driver                    CLFS
         ffffdc8a4ab28e20 Driver                    WindowsTrustedRTProxy
     15  ffffdc8a4ccdae20 Driver                    Serial
         ffffdc8a4cc59d40 Driver                    NdisCap
         ffffdc8a4c8b3d30 Driver                    KSecDD
         ffffdc8a4c35bda0 Driver                    volmgr
         ffffdc8a4aaced80 Driver                    DeviceApi
     16  ffffdc8a4fcd3c90 Driver                    VMMemCtl
         ffffdc8a4ccd6e20 Driver                    umbus
         ffffdc8a4aad9c10 Driver                    MsSecFlt
         ffffdc8a4abd8cc0 Driver                    CNG
     17  ffffdc8a4ce72e20 Driver                    Win32k
         ffffdc8a4cce0dc0 Driver                    i8042prt
         ffffdc8a4cc96d70 Driver                    npsvctrig
         ffffdc8a4c9bed90 Driver                    volume
         ffffdc8a4c8b6e00 Driver                    KSecPkg
     18  ffffdc8a4cca25b0 Driver                    mouclass
     19  ffffdc8a4ea59e00 Driver                    X58a84jzGG36Q
         ffffdc8a4c53d350 Driver                    msisadrv
     20  ffffdc8a4fd79e10 Driver                    Ndu
         ffffdc8a4ccdddb0 Driver                    kbdclass
     21  ffffdc8a4c8b8e00 Driver                    mouhid
         ffffdc8a4c9bf8f0 Driver                    volsnap
     22  ffffdc8a567efe30 Driver                    MeDVpDrv_V3LITE40
         ffffdc8a4cc71dd0 Driver                    nsiproxy
         ffffdc8a4c944bd0 Driver                    AhnRghNt
         ffffdc8a4aaddd80 Driver                    WMIxWDM
     23  ffffdc8a528188f0 Driver                    BthPan
         ffffdc8a4fac3e30 Driver                    MsQuic
         ffffdc8a4cb6f9a0 Driver                    tdx
         ffffdc8a4c360a90 Driver                    vmci
     24  ffffdc8a5102ae30 Driver                    AntiStealth_V3LITE40F
         ffffdc8a52f8b570 Driver                    BTHUSB
         ffffdc8a4ab32e20 Driver                    WindowsTrustedRT
     25  ffffdc8a4cd2fde0 Driver                    HDAudBus
         ffffdc8a4cbbde40 Driver                    BasicDisplay
     26  ffffdc8a4cd62e00 Driver                    rdpbus
     27  ffffdc8a50eaca70 Driver                    Cdm2DrNt
         ffffdc8a4fcd3a70 Driver                    DBGV
         ffffdc8a4c358dc0 Driver                    pdc
     28  ffffdc8a4f92de20 Driver                    rspndr
         ffffdc8a4e14fe00 Driver                    vmusbmouse
     29  ffffdc8a4ce59670 Driver                    HdAudAddService
         ffffdc8a4cc98d60 Driver                    mssmbios
         ffffdc8a4cc97de0 Driver                    CSC
         ffffdc8a4c372d90 Driver                    volmgrx
         ffffdc8a4c536060 Driver                    pci
     30  ffffdc8a545d5e50 Driver                    ArtDrv
         ffffdc8a4cd67ce0 Driver                    NdisVirtualBus
         ffffdc8a4cdeb300 Driver                    CmBatt
         ffffdc8a4cce1e00 Driver                    vm3dmp_loader
         ffffdc8a4ccd8e20 Driver                    kdnic
         ffffdc8a4c9c1ba0 Driver                    cdrom
         ffffdc8a4c8b54e0 Driver                    NDIS
     31  ffffdc8a4cd65dc0 Driver                    swenum
     32  ffffdc8a4ce6ee30 Driver                    usbhub
         ffffdc8a4c9bfb00 Driver                    rdyboost
         ffffdc8a4c997e30 Driver                    WFPLWFS
         ffffdc8a4c8b7e00 Driver                    Tcpip
         ffffdc8a4aad9e20 Driver                    SgrmAgent
     33  ffffdc8a543a7750 Driver                    TSFltDrv_V3LITE40
         ffffdc8a4ce66cb0 Driver                    USBHUB3
         ffffdc8a4cdec940 Driver                    intelppm
         ffffdc8a4cd2fb20 Driver                    gencounter
         ffffdc8a4c162e40 Driver                    Beep
         ffffdc8a4c374410 Driver                    atapi
     34  ffffdc8a4cf18e00 Driver                    usbccgp
         ffffdc8a4cb6b9a0 Driver                    AFD
         ffffdc8a4c373c40 Driver                    mountmgr
         ffffdc8a4c365e30 Driver                    intelide
     35  ffffdc8a4e156410 Driver                    ATamptNt_V3LITE40
         ffffdc8a52bb1b70 Driver                    BTHPORT
         ffffdc8a4fd83e30 Driver                    tcpipreg
         ffffdc8a4ce32060 Driver                    ksthunk
         ffffdc8a4ccd9e30 Driver                    vmmouse
         ffffdc8a4cb6c9a0 Driver                    afunix
     36  ffffdc8a55296750 Driver                    asc_kbc_V3LITE40
         ffffdc8a4ca547b0 Driver                    vm3dmp
         ffffdc8a4cca4db0 Driver                    CompositeBus
         ffffdc8a4caf99a0 Driver                    ws2ifsl
         ffffdc8a4c64edd0 Driver                    EhStorClass
         ffffdc8a4aa954c0 Driver                    ACPI

로딩된 드라이버 목록이 나오는 것을 확인할 수 있습니다. 

위에서 언급했듯이, 각각의 Entry(1줄당 하나의 Entry, 여기서는 드라이버를 의미)는 체인으로 연결되어 있습니다. 아래 그림처럼 특정 Entry를 제거한 후 체인을 이을 수 있습니다.

33번 인덱스의 2번째인 USBHUB3를 목록에서 숨겨본다고 가정하겠습니다. 

우선 위 주소를 구조체로 표현해봅니다.

lkd> dt _OBJECT_DIRECTORY 0xffffcb83e84ec220
nt!_OBJECT_DIRECTORY
   +0x000 HashBuckets      : [37] 0xffffcb83`f16ee960 _OBJECT_DIRECTORY_ENTRY
   +0x128 Lock             : _EX_PUSH_LOCK
   +0x130 DeviceMap        : (null) 
   +0x138 ShadowDirectory  : (null) 
   +0x140 NamespaceEntry   : (null) 
   +0x148 SessionObject    : (null) 
   +0x150 Flags            : 0
   +0x154 SessionId        : 0xffffffff

HashBucket을 눌러보면 아래와 같이 나옵니다.

lkd> dx -id 0,0,ffffdc8a4aa96040 -r1 (*((ntkrnlmp!_OBJECT_DIRECTORY_ENTRY * (*)[37])0xffffcb83e84ec220))
(*((ntkrnlmp!_OBJECT_DIRECTORY_ENTRY * (*)[37])0xffffcb83e84ec220))                 [Type: _OBJECT_DIRECTORY_ENTRY * [37]]
    [0]              : 0xffffcb83f16ee960 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [1]              : 0xffffcb83e8ca9a10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [2]              : 0xffffcb83ec3710b0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [3]              : 0xffffcb83f2246b20 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [4]              : 0xffffcb83ec370900 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [5]              : 0xffffcb83e8ca9e30 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [6]              : 0xffffcb83f66bb380 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [7]              : 0xffffcb83edd0bf70 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [8]              : 0xffffcb83edd081f0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [9]              : 0xffffcb83e8545490 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [10]             : 0xffffcb83e8568860 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [11]             : 0xffffcb83efa5efd0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [12]             : 0xffffcb83e854c820 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [13]             : 0xffffcb83edd05790 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [14]             : 0xffffcb83f2246ac0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [15]             : 0xffffcb83e8ca8c30 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [16]             : 0xffffcb83ec373fc0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [17]             : 0xffffcb83e8b809c0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [18]             : 0xffffcb83e8ca8a50 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [19]             : 0xffffcb83f2245590 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [20]             : 0xffffcb83ece2d4b0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [21]             : 0xffffcb83e8cae4e0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [22]             : 0xffffcb83edd05c10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [23]             : 0xffffcb83f2246eb0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [24]             : 0xffffcb83edd08c70 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [25]             : 0xffffcb83e8ca9a40 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [26]             : 0xffffcb83e8cab330 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [27]             : 0xffffcb83edd08be0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [28]             : 0xffffcb83ec36f310 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [29]             : 0xffffcb83e8cad760 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [30]             : 0xffffcb83edd0cb10 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [31]             : 0xffffcb83e8cab180 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [32]             : 0xffffcb83e8cacda0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [33]             : 0xffffcb83edd0ced0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [34]             : 0xffffcb83e85686b0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [35]             : 0xffffcb83edd087c0 [Type: _OBJECT_DIRECTORY_ENTRY *]
    [36]             : 0xffffcb83edd0cf30 [Type: _OBJECT_DIRECTORY_ENTRY *]

33번 인덱스의 주소를 구조체로 확인해봅니다.

lkd>  dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83edd0ced0
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8cadac0 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffdc8a`543a7750 Void // TSFltDrv_V3LITE40 오브젝트
   +0x010 HashValue        : 0x602bada7

2번째에 위치해있으니 ChainLink주소를 따라가봅니다.

lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83`e8cadac0
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8caa730 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffdc8a`4ce66cb0 Void // USBHUB3 오브젝트
   +0x010 HashValue        : 0x19f5be6d

해당 OBJECT_DIRECTORY_ENTRY에 USBHUB3인 0xffffdc8a4ce66cb0 오브젝트에 도달한 것을 확인할 수 있습니다. 여기서 이전 Entry의 ChainLink를 USBHUB3 Entry가 가리키는 ChainLink로 변경하면 됩니다. 

이제 중요한 것은 해당 OBJECT_DIRECTORY_ENTRY에 어떻게 도달하느냐인데, DriverEntry함수의 PDRIVER_OBJECT는 Directory 타입의 "Driver"에 속해있는 유형입니다. "Driver"에 속해있는 드라이버라면 OBJECT_DIRECTORY(일종의 부모)가 동일합니다. 따라서 타 드라이버의 DRIVER_OBJECT 등을 구할 필요없이 자신의 드라이버 모듈을 Head로 사용하면 됩니다.

"Driver" 의 OBJECT_DIRECTORY에 접근하기 위해서 우선 ObQueryNameInfo함수로 OBJECT_HEADER_NAME_INFO 구조체 주소를 구해야 합니다. 해당 구조체에 OBJECT_DIRECTORY를 가리키는 필드가 있습니다.

POBJECT_HEADER_NAME_INFO pObjectHeaderNameInfo = ObQueryNameInfo(pDriverObject);
POBJECT_DIRECTORY pObjectDirectory = pObjectHeaderNameInfo->Directory;

OBJECT_DIRECTORY를 구했으면 각각의 ENTRY를 순회한 뒤 이름이 일치하면 ChainLink를 변경하는 코드를 작성합니다.

UNICODE_STRING DriverName = RTL_CONSTANT_STRING(L"USBHUB3");
for (int i = 0; i < 37; i++)
{
	POBJECT_DIRECTORY_ENTRY pBlinkObjectDirectoryEntry = NULL; // 이전 노드 저장
	POBJECT_DIRECTORY_ENTRY pObjectDirectoryEntry = pObjectDirectory->HashBuckets[i];

	while (pObjectDirectoryEntry)
	{        
		// 일치하면
		if (RtlEqualUnicodeString(DriverName, &pObjectHeaderNameInfo->Name, TRUE))
		{
			// 체인의 0번째(=헤드)가 자신의 Entry일때
			if (pObjectDirectory->HashBuckets[p] == pObjectDirectoryEntry)
			{			
				pObjectDirectory->HashBuckets[p] = pObjectDirectoryEntry->ChainLink; // 내 Entry의 다음 Entry를 헤드로 만든다.
				pObjectDirectoryEntry->ChainLink = NULL;
			}
			else // 1번째부터
			{			
				pBlinkObjectDirectoryEntry->ChainLink = pObjectDirectoryEntry->ChainLink; // 이전 Entry의 다음 Entry를 내 다음 Entry로 가리킨다.
				pObjectDirectoryEntry->ChainLink = NULL;
			}
		}
	        pBlinkObjectDirectoryEntry = pObjectDirectoryEntry;
		pObjectDirectoryEntry = pObjectDirectoryEntry->ChainLink;
	}
}

코드를 실행하여 체인 연결을 끊은 후 windbg로 확인해보면 TSFltDrv_V3LITE40의 ChainLink가 USBHUB3가 아닌 intelppm을 가리키는 것을 확인할 수 있습니다.

    33  ffffdc8a543a7750 Driver                    TSFltDrv_V3LITE40
        ffffdc8a4cdec940 Driver                    intelppm
        ffffdc8a4cd2fb20 Driver                    gencounter
        ffffdc8a4c162e40 Driver                    Beep
        ffffdc8a4c374410 Driver                    atapi
lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83edd0ced0 // TSFltDrv_V3LITE40 엔트리
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8caa730 _OBJECT_DIRECTORY_ENTRY // intelpm 엔트리
   +0x008 Object           : 0xffffdc8a`543a7750 Void // TSFltDrv_V3LITE40 오브젝트
   +0x010 HashValue        : 0x602bada7
lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83`e8cadac0
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : (null) // 체인이 끊어짐
   +0x008 Object           : 0xffffdc8a`4ce66cb0 Void // USBHUB3 오브젝트
   +0x010 HashValue        : 0x19f5be6d
lkd> dt _OBJECT_DIRECTORY_ENTRY 0xffffcb83e8caa730 // intelppm 엔트리
nt!_OBJECT_DIRECTORY_ENTRY
   +0x000 ChainLink        : 0xffffcb83`e8caaa30 _OBJECT_DIRECTORY_ENTRY
   +0x008 Object           : 0xffffdc8a`4cdec940 Void // intelppm 오브젝트
   +0x010 HashValue        : 0x29f82c1

 

테스트환경 : windows 10 x64 build 19041

OBJECT_HEADER에서 OBJECT_HEADER_NAME_INFO를 어떻게 얻을까 다양한 방법으로 구글링해보다가 ObQueryNameInfo(PVOID pObject) 함수가 있다는 것을 발견했습니다. 이 함수를 쓰면 POBJECT_HEADER_NAME_INFO 주소를 리턴하더군요. 어떻게 얻나 궁금해서 windbg로 까봤습니다.

0: kd> u ObQueryNameInfo
nt!ObQueryNameInfo:
fffff803`6987b920 0fb641ea        movzx   eax,byte ptr [rcx-16h]
fffff803`6987b924 4883c1d0        add     rcx,0FFFFFFFFFFFFFFD0h
fffff803`6987b928 a802            test    al,2
fffff803`6987b92a 7416            je      nt!ObQueryNameInfo+0x22 (fffff803`6987b942)
fffff803`6987b92c 83e003          and     eax,3
fffff803`6987b92f 488d154aa55a00  lea     rdx,[nt!ObpInfoMaskToOffset (fffff803`69e25e80)]
fffff803`6987b936 0fb60410        movzx   eax,byte ptr [rax+rdx]
fffff803`6987b93a 482bc8          sub     rcx,rax
fffff803`6987b93d 488bc1          mov     rax,rcx
fffff803`6987b940 c3              ret

먼저 인자에서 0x16을 뺀것을 포인터 참조해서 저장하고, 그 다음은 0x30만큼 빼고 주소를 저장하네요. (인자로는 DRIVER_OBJECT 0xffffc28f1318ce30 를 줘봤습니다. )

일단 0x30만큼 뺀 것은 OBJECT_HADER 구조체였습니다. (대충 감으로 때려맞춤...)

kd> dt _OBJECT_HEADER 0xffffc28f1318ce30-0x30
nt!_OBJECT_HEADER
   +0x000 PointerCount     : 0n3
   +0x008 HandleCount      : 0n0
   +0x008 NextToFree       : (null) 
   +0x010 Lock             : _EX_PUSH_LOCK
   +0x018 TypeIndex        : 0x13 ''
   +0x019 TraceFlags       : 0 ''
   +0x019 DbgRefTrace      : 0y0
   +0x019 DbgTracePermanent : 0y0
   +0x01a InfoMask         : 0x2 ''
   +0x01b Flags            : 0x12 ''
   +0x01b NewObject        : 0y0
   +0x01b KernelObject     : 0y1
   +0x01b KernelOnlyAccess : 0y0
   +0x01b ExclusiveObject  : 0y0
   +0x01b PermanentObject  : 0y1
   +0x01b DefaultSecurityQuota : 0y0
   +0x01b SingleHandleEntry : 0y0
   +0x01b DeletedInline    : 0y0
   +0x01c Reserved         : 0xffffc28f
   +0x020 ObjectCreateInfo : 0x00000000`00000001 _OBJECT_CREATE_INFORMATION
   +0x020 QuotaBlockCharged : 0x00000000`00000001 Void
   +0x028 SecurityDescriptor : 0xffffb20d`a6735cee Void
   +0x030 Body             : _QUAD

0x16만큼 뺀것은 +0x1A에 위치해 있는 InfoMask 필드네요. InfoMask & 2 가 참이면 InfoMask & 3을 하여 index로 사용합니다. (예제에서는 2 & 3 = 2(index))

그 다음으로 ObpInfoMaskToOffset 에서 index를 사용하여 오프셋을 꺼내옵니다.

(BYTE*)ObpInfoMaskToOffset(0xfffff803`69e25e80) + index(2) (예제는 fffff803`69e25e82가 되겠군요.)

2: kd> db fffff803`69e25e80
fffff803`69e25e80  00 20 20 40 10 30 30 50-20 40 40 60 30 50 50 70  .  @.00P @@`0PPp
fffff803`69e25e90  10 30 30 50 20 40 40 60-30 50 50 70 40 60 60 80  .00P @@`0PPp@``.
fffff803`69e25ea0  10 30 30 50 20 40 40 60-30 50 50 70 40 60 60 80  .00P @@`0PPp@``.
fffff803`69e25eb0  20 40 40 60 30 50 50 70-40 60 60 80 50 70 70 90   @@`0PPp@``.Ppp.
fffff803`69e25ec0  10 30 30 50 20 40 40 60-30 50 50 70 40 60 60 80  .00P @@`0PPp@``.
fffff803`69e25ed0  20 40 40 60 30 50 50 70-40 60 60 80 50 70 70 90   @@`0PPp@``.Ppp.
fffff803`69e25ee0  20 40 40 60 30 50 50 70-40 60 60 80 50 70 70 90   @@`0PPp@``.Ppp.
fffff803`69e25ef0  30 50 50 70 40 60 60 80-50 70 70 90 60 80 80 a0  0PPp@``.Ppp.`...

OBJECT_HEADER 주소에서 꺼내온 0x20(OBJECT_HEADER_NAME_INFO 구조체 사이즈)만큼 빼고 해당 주소를 리턴합니다.

예제는 0xffffc28f1318ce00 - 0x20 = 0xffffc28f1318cde0

kd> dt _OBJECT_HEADER_NAME_INFO 0xffffc28f1318cde0
nt!_OBJECT_HEADER_NAME_INFO
   +0x000 Directory        : 0xffffb20d`a66ec5a0 _OBJECT_DIRECTORY
   +0x008 Name             : _UNICODE_STRING "KernelV"
   +0x018 ReferenceCount   : 0n0
   +0x01c Reserved         : 0

잘 얻어졌습니다.

ObpInfoMaskToOffset는 0x100개의 배열이며, 직접 생성할 수도 있습니다. (아래의 소스에 자세히 나와있습니다.)

github.com/hfiref0x/WinObjEx64/blob/master/Source/WinObjEx64/kldbg.c

 

 

갤탭에서 잘됨

gdb-arm-static-7.11
4.44MB

+ Recent posts