NDB插件(NDX)命令!ndxlm的实现

2024.06.23
之前猜想过lm命令是如何实现的,也尝试手动分析过:NDB lm命令实现的猜想

GEDU开源分享了NDX的项目,NDX - eXtension module for NDB (Nano Debugger)

这样就可以尝试自己亲自动手实现UEFI list modules命令:!ndxlm,由于有示范代码,上手很快,代码简洁。

DECLARE_API(ndxhelp)
{
    dprintf
    (
        "Help for Nano Debugger eXtension (NDX) rev. 2.6:\n"
        " !lxp: List linux processes.\n"
        " !ndxps [num]: walk task list from init_task.\n"
        " !address <addr>: show memory attributes of specified address.\n"
        " !idt [addr]: show interrupt descriptor table on x86 system or ARM.\n"
        " !dmesg: print kernel message.\n"
        " !arena: watch arenas of the glibc heap.\n"
        " !ready: display ready queue of processors.\n"
        " !ndxlm: UEFI list modules.\n"

    );
}

DECLARE_API(ndxlm)
{
    //cndxhelp
    //ndxhelp(hCurrentProcess, hCurrentThread, dwCurrentPc, dwProcessor, args);
    ULONG64 Address, EfiDebugImageInfoTable, LoadedImageProtocolInstance, Efi_Debug_Image_Info_Normal, ImageBase, ImageSize;
    UINT32 Offset, TableSize;
    UINT16 e_magic;
    UINT32 e_lfanew;
    UINT32 VirtualAddress, Size;
    char filepath[0x200];
    ULONG read = 0;
    char* filename;

    //filepath = (char*)malloc(0x200);
    int i = 0;
        /*
        x DxeCore!mDebugInfoTableHeader
        00000000`3ec6f5f0  DxeCore!mDebugInfoTableHeader
        r $t0 = DxeCore!mDebugInfoTableHeader
        ? $t0
        eval expression: 1053226480 = 00000000`3ec6f5f0
        dt -b EFI_DEBUG_IMAGE_INFO_TABLE_HEADER $t0
           +0x000 UpdateStatus     : 2
           +0x004 TableSize        : 0x62
           +0x008 EfiDebugImageInfoTable : 0x00000000`efdea018
        */

    GetExpressionEx("DxeCore!mDebugInfoTableHeader", &Address, NULL); //00000000`3ec6f5f0
    GetFieldValue(Address, "EFI_DEBUG_IMAGE_INFO_TABLE_HEADER", "TableSize", TableSize); //0x62
    GetFieldValue(Address, "EFI_DEBUG_IMAGE_INFO_TABLE_HEADER", "EfiDebugImageInfoTable", EfiDebugImageInfoTable); //0x00000000`efdea018

    /*    
    dt -b EFI_DEBUG_IMAGE_INFO_NORMAL 00000000`efdfef98
       +0x000 ImageInfoType    : 1
       +0x008 LoadedImageProtocolInstance : 0x00000000`3ec6d900
       +0x010 ImageHandle      : 0x00000000`efdfff98

    dt -b EFI_LOADED_IMAGE_PROTOCOL ImageBase ImageSize 0x00000000`3ec6d900
       +0x040 ImageBase : 0x00000000`3ec42000
       +0x048 ImageSize : 0x49000
    */
    dprintf("ImageBase        ImageEnd        FileName    ModuleSymbolLoading\n");
    while (i < TableSize)
    {
        //GetFieldValue(EfiDebugImageInfoTable-8, "EFI_DEBUG_IMAGE_INFO_NORMAL", "LoadedImageProtocolInstance", Efi_Debug_Image_Info_Normal); //0x00000000`efdfef98, to read at 0x00000000`efdea018-8+8, to be fixed to nicer one later
        ReadMemory(EfiDebugImageInfoTable, &Efi_Debug_Image_Info_Normal, sizeof(Efi_Debug_Image_Info_Normal), &read);
        GetFieldValue(Efi_Debug_Image_Info_Normal, "EFI_DEBUG_IMAGE_INFO_NORMAL", "LoadedImageProtocolInstance", LoadedImageProtocolInstance); //0x00000000`3ec6d900
        GetFieldValue(LoadedImageProtocolInstance, "EFI_LOADED_IMAGE_PROTOCOL", "ImageBase", ImageBase);
        GetFieldValue(LoadedImageProtocolInstance, "EFI_LOADED_IMAGE_PROTOCOL", "ImageSize", ImageSize);
        /*
        dt EFI_IMAGE_DOS_HEADER e_magic e_lfanew
           +0x000 e_magic  : Uint2B
           +0x03c e_lfanew : Uint4B
        */
        GetFieldValue(ImageBase, "EFI_IMAGE_DOS_HEADER", "e_magic", e_magic);
        GetFieldValue(ImageBase, "EFI_IMAGE_DOS_HEADER", "e_lfanew", e_lfanew);
        //dprintf("%x, %x\n", e_magic, e_lfanew);

        /*
        dt EFI_IMAGE_NT_HEADERS64 OptionalHeader.DataDirectory[06].VirtualAddress OptionalHeader.DataDirectory[06].Size 0`e9e74000+0`e58
           +0x018 OptionalHeader                                  :
              +0x070 DataDirectory                                   : [6]EFI_IMAGE_DATA_DIRECTORY[]
                 +0x000 VirtualAddress                                  : 0x2a4f8
                 +0x004 Size                                            : 0x1c
        */
        GetFieldValue(ImageBase+ e_lfanew, "EFI_IMAGE_NT_HEADERS64", "OptionalHeader.DataDirectory[06].VirtualAddress", VirtualAddress);
        GetFieldValue(ImageBase + e_lfanew, "EFI_IMAGE_NT_HEADERS64", "OptionalHeader.DataDirectory[06].Size", Size);
        ReadMemory(ImageBase + VirtualAddress + Size + 0x10, filepath, 0x200, &read);
        if (read < 0x200) {
            dprintf("read filepath failed %d < %d \n", read, 0x200);
            return;
        }
        filename = extract_filename(filepath);
        dprintf("%016llx    %016llx    %s    .reload %s=0`%llx, 0`%x\n", ImageBase, ImageBase + ImageSize, filename, filename, ImageBase, ImageSize );

        EfiDebugImageInfoTable += 8;
        i = i + 1;
    }
    return;
}
/*ndxlm扩展命令结束*/

看看输出,很赞:

.load D:\Gedu\ndx\ndx\x64\Debug\exts\ndx.dll
D:\Gedu\ndx\ndx\x64\Debug\exts\ndx.dll extension is loaded
[ndb]!ndxlm
invalid command name "ndxlm"
!ndxlm
Read system version block failed 1
Read system version block failed 1
Opcode 0x38401401, DSCR.ERR=1, DSCR.EL=2
Opcode 0x38401401, DSCR.ERR=1, DSCR.EL=2
ImageBase        ImageEnd        FileName    ModuleSymbolLoading
000000003ec42000    000000003ec8b000    DxeCore.dll    .reload DxeCore.dll=0`3ec42000, 0`49000
00000000eff8b000    00000000eff90000    StatusLedDxe.dll    .reload StatusLedDxe.dll=0`eff8b000, 0`5000
00000000eff81000    00000000eff8b000    PcdDxe.dll    .reload PcdDxe.dll=0`eff81000, 0`a000
00000000eaf70000    00000000eafb0000    RuntimeDxe.dll    .reload RuntimeDxe.dll=0`eaf70000, 0`40000
00000000eff77000    00000000eff81000    SecurityStubDxe.dll    .reload SecurityStubDxe.dll=0`eff77000, 0`a000
00000000eaee0000    00000000eaf10000    EmbeddedMonotonicCounter.dll    .reload EmbeddedMonotonicCounter.dll=0`eaee0000, 0`30000
00000000eae90000    00000000eaed0000    ResetSystemRuntimeDxe.dll    .reload ResetSystemRuntimeDxe.dll=0`eae90000, 0`40000
00000000eff72000    00000000eff77000    MetronomeDxe.dll    .reload MetronomeDxe.dll=0`eff72000, 0`5000
00000000eff52000    00000000eff72000    HiiDatabase.dll    .reload HiiDatabase.dll=0`eff52000, 0`20000
00000000eadf0000    00000000eae30000    NorFlashDxe.dll    .reload NorFlashDxe.dll=0`eadf0000, 0`40000
00000000ead50000    00000000ead90000    RkFvbDxe.dll    .reload RkFvbDxe.dll=0`ead50000, 0`40000
00000000eacb0000    00000000eacf0000    VariableRuntimeDxe.dll    .reload VariableRuntimeDxe.dll=0`eacb0000, 0`40000
00000000eff4d000    00000000eff52000    SerialDxe.dll    .reload SerialDxe.dll=0`eff4d000, 0`5000
00000000eff46000    00000000eff4d000    ArmGicDxe.dll    .reload ArmGicDxe.dll=0`eff46000, 0`7000
00000000eff3f000    00000000eff46000    ArmScmiDxe.dll    .reload ArmScmiDxe.dll=0`eff3f000, 0`7000
00000000eff34000    00000000eff3f000    AcpiTableDxe.dll    .reload AcpiTableDxe.dll=0`eff34000, 0`b000
00000000eff2c000    00000000eff34000    SmbiosDxe.dll    .reload SmbiosDxe.dll=0`eff2c000, 0`8000
00000000eff27000    00000000eff2c000    RtcPlatformDxe.dll    .reload RtcPlatformDxe.dll=0`eff27000, 0`5000
00000000eff17000    00000000eff27000    Vop2Dxe.dll    .reload Vop2Dxe.dll=0`eff17000, 0`10000
00000000eff0e000    00000000eff17000    AnalogixDpLib.dll    .reload AnalogixDpLib.dll=0`eff0e000, 0`9000
00000000eff07000    00000000eff0e000    DwHdmiQpLib.dll    .reload DwHdmiQpLib.dll=0`eff07000, 0`7000
00000000efeff000    00000000eff07000    DwDpLib.dll    .reload DwDpLib.dll=0`efeff000, 0`8000
00000000efef8000    00000000efeff000    UsbHcdDxe.dll    .reload UsbHcdDxe.dll=0`efef8000, 0`7000
00000000efef2000    00000000efef8000    DpcDxe.dll    .reload DpcDxe.dll=0`efef2000, 0`6000
00000000efeec000    00000000efef2000    HttpUtilitiesDxe.dll    .reload HttpUtilitiesDxe.dll=0`efeec000, 0`6000
00000000efedd000    00000000efeec000    DevicePathDxe.dll    .reload DevicePathDxe.dll=0`efedd000, 0`f000
00000000efed7000    00000000efedd000    ArmPciCpuIo2Dxe.dll    .reload ArmPciCpuIo2Dxe.dll=0`efed7000, 0`6000
00000000efed3000    00000000efed7000    GmacPlatformDxe.dll    .reload GmacPlatformDxe.dll=0`efed3000, 0`4000
00000000eabf0000    00000000eac20000    Reset.dll    .reload Reset.dll=0`eabf0000, 0`30000
00000000efec7000    00000000efed3000    ArmCpuDxe.dll    .reload ArmCpuDxe.dll=0`efec7000, 0`c000
00000000efebe000    00000000efec7000    FaultTolerantWriteDxe.dll    .reload FaultTolerantWriteDxe.dll=0`efebe000, 0`9000
00000000efeb8000    00000000efebe000    ArmTimerDxe.dll    .reload ArmTimerDxe.dll=0`efeb8000, 0`6000
00000000efeb1000    00000000efeb8000    PlatformSmbiosDxe.dll    .reload PlatformSmbiosDxe.dll=0`efeb1000, 0`7000
00000000efe95000    00000000efeb1000    SetupBrowser.dll    .reload SetupBrowser.dll=0`efe95000, 0`1c000
00000000efe7a000    00000000efe95000    BdsDxe.dll    .reload BdsDxe.dll=0`efe7a000, 0`1b000
00000000efe65000    00000000efe7a000    RK3588Dxe.dll    .reload RK3588Dxe.dll=0`efe65000, 0`15000
00000000eaafd000    00000000eabb0000    LogoDxe.dll    .reload LogoDxe.dll=0`eaafd000, 0`b3000
00000000eaab0000    00000000eaae0000    CapsuleRuntimeDxe.dll    .reload CapsuleRuntimeDxe.dll=0`eaab0000, 0`30000
00000000efe60000    00000000efe65000    WatchdogTimer.dll    .reload WatchdogTimer.dll=0`efe60000, 0`5000
00000000eaa70000    00000000eaaa0000    I2cDxe.dll    .reload I2cDxe.dll=0`eaa70000, 0`30000
00000000efe58000    00000000efe60000    LcdGraphicsOutputDxe.dll    .reload LcdGraphicsOutputDxe.dll=0`efe58000, 0`8000
00000000efe4c000    00000000efe58000    OhciDxe.dll    .reload OhciDxe.dll=0`efe4c000, 0`c000
00000000efe3d000    00000000efe4c000    RamDiskDxe.dll    .reload RamDiskDxe.dll=0`efe3d000, 0`f000
00000000efe2c000    00000000efe3d000    TlsAuthConfigDxe.dll    .reload TlsAuthConfigDxe.dll=0`efe2c000, 0`11000
00000000efe15000    00000000efe2c000    DisplayEngine.dll    .reload DisplayEngine.dll=0`efe15000, 0`17000
00000000efe04000    00000000efe15000    PciHostBridgeDxe.dll    .reload PciHostBridgeDxe.dll=0`efe04000, 0`11000
00000000eafc5000    00000000eafcc000    NonCoherentIoMmuDxe.dll    .reload NonCoherentIoMmuDxe.dll=0`eafc5000, 0`7000
00000000eaaf6000    00000000eaafd000    UsbDpPhyDxe.dll    .reload UsbDpPhyDxe.dll=0`eaaf6000, 0`7000
00000000eaaf0000    00000000eaaf6000    AcpiPlatformDxe.dll    .reload AcpiPlatformDxe.dll=0`eaaf0000, 0`6000
00000000eaa65000    00000000eaa70000    FdtPlatformDxe.dll    .reload FdtPlatformDxe.dll=0`eaa65000, 0`b000
00000000eaa20000    00000000eaa50000    RealTimeClock.dll    .reload RealTimeClock.dll=0`eaa20000, 0`30000
00000000eaa18000    00000000eaa20000    ConPlatformDxe.dll    .reload ConPlatformDxe.dll=0`eaa18000, 0`8000
00000000eaa0d000    00000000eaa18000    ConSplitterDxe.dll    .reload ConSplitterDxe.dll=0`eaa0d000, 0`b000
00000000eaa04000    00000000eaa0d000    GraphicsConsoleDxe.dll    .reload GraphicsConsoleDxe.dll=0`eaa04000, 0`9000
00000000ea9f8000    00000000eaa04000    TerminalDxe.dll    .reload TerminalDxe.dll=0`ea9f8000, 0`c000
00000000ea9f2000    00000000ea9f8000    BootGraphicsResourceTableDxe.dll    .reload BootGraphicsResourceTableDxe.dll=0`ea9f2000, 0`6000
00000000ea9e9000    00000000ea9f2000    I2cDxe.dll    .reload I2cDxe.dll=0`ea9e9000, 0`9000
00000000ea9dd000    00000000ea9e9000    EhciDxe.dll    .reload EhciDxe.dll=0`ea9dd000, 0`c000
00000000ea9cc000    00000000ea9dd000    XhciDxe.dll    .reload XhciDxe.dll=0`ea9cc000, 0`11000
00000000ea9bf000    00000000ea9cc000    UsbBusDxe.dll    .reload UsbBusDxe.dll=0`ea9bf000, 0`d000
00000000ea9b5000    00000000ea9bf000    UsbMassStorageDxe.dll    .reload UsbMassStorageDxe.dll=0`ea9b5000, 0`a000
00000000ea9ab000    00000000ea9b5000    UsbKbDxe.dll    .reload UsbKbDxe.dll=0`ea9ab000, 0`a000
00000000ea9a3000    00000000ea9ab000    UsbMouseDxe.dll    .reload UsbMouseDxe.dll=0`ea9a3000, 0`8000
00000000ea99b000    00000000ea9a3000    UsbMouseAbsolutePointerDxe.dll    .reload UsbMouseAbsolutePointerDxe.dll=0`ea99b000, 0`8000
00000000ea993000    00000000ea99b000    NonDiscoverablePciDeviceDxe.dll    .reload NonDiscoverablePciDeviceDxe.dll=0`ea993000, 0`8000
00000000ea98c000    00000000ea993000    SataController.dll    .reload SataController.dll=0`ea98c000, 0`7000
00000000ea97e000    00000000ea98c000    AtaAtapiPassThruDxe.dll    .reload AtaAtapiPassThruDxe.dll=0`ea97e000, 0`e000
00000000ea974000    00000000ea97e000    AtaBusDxe.dll    .reload AtaBusDxe.dll=0`ea974000, 0`a000
00000000ea96c000    00000000ea974000    DiskIoDxe.dll    .reload DiskIoDxe.dll=0`ea96c000, 0`8000
00000000ea962000    00000000ea96c000    PartitionDxe.dll    .reload PartitionDxe.dll=0`ea962000, 0`a000
00000000ea954000    00000000ea962000    Fat.dll    .reload Fat.dll=0`ea954000, 0`e000
00000000eafc0000    00000000eafc5000    EnglishDxe.dll    .reload EnglishDxe.dll=0`eafc0000, 0`5000
00000000ea94a000    00000000ea954000    SnpDxe.dll    .reload SnpDxe.dll=0`ea94a000, 0`a000
00000000ea940000    00000000ea94a000    VlanConfigDxe.dll    .reload VlanConfigDxe.dll=0`ea940000, 0`a000
00000000ea932000    00000000ea940000    MnpDxe.dll    .reload MnpDxe.dll=0`ea932000, 0`e000
00000000ea928000    00000000ea932000    ArpDxe.dll    .reload ArpDxe.dll=0`ea928000, 0`a000
00000000ea91b000    00000000ea928000    Dhcp4Dxe.dll    .reload Dhcp4Dxe.dll=0`ea91b000, 0`d000
00000000ea904000    00000000ea91b000    Ip4Dxe.dll    .reload Ip4Dxe.dll=0`ea904000, 0`17000
00000000ea8f8000    00000000ea904000    Udp4Dxe.dll    .reload Udp4Dxe.dll=0`ea8f8000, 0`c000
00000000ea8ec000    00000000ea8f8000    Mtftp4Dxe.dll    .reload Mtftp4Dxe.dll=0`ea8ec000, 0`c000
00000000ea8de000    00000000ea8ec000    Dhcp6Dxe.dll    .reload Dhcp6Dxe.dll=0`ea8de000, 0`e000
00000000ea8bf000    00000000ea8de000    Ip6Dxe.dll    .reload Ip6Dxe.dll=0`ea8bf000, 0`1f000
00000000ea8b3000    00000000ea8bf000    Udp6Dxe.dll    .reload Udp6Dxe.dll=0`ea8b3000, 0`c000
00000000ea8a6000    00000000ea8b3000    Mtftp6Dxe.dll    .reload Mtftp6Dxe.dll=0`ea8a6000, 0`d000
00000000ea890000    00000000ea8a6000    TcpDxe.dll    .reload TcpDxe.dll=0`ea890000, 0`16000
00000000ea87c000    00000000ea890000    UefiPxeBcDxe.dll    .reload UefiPxeBcDxe.dll=0`ea87c000, 0`14000
00000000ea792000    00000000ea87c000    TlsDxe.dll    .reload TlsDxe.dll=0`ea792000, 0`ea000
00000000ea783000    00000000ea792000    DnsDxe.dll    .reload DnsDxe.dll=0`ea783000, 0`f000
00000000ea772000    00000000ea783000    HttpDxe.dll    .reload HttpDxe.dll=0`ea772000, 0`11000
00000000ea75d000    00000000ea772000    HttpBootDxe.dll    .reload HttpBootDxe.dll=0`ea75d000, 0`15000
0000000180000000    0000000180023000        .reload =0`180000000, 0`23000
00000000ea744000    00000000ea75d000        .reload =0`ea744000, 0`19000
00000000ea73b000    00000000ea744000    Ax88772c.dll    .reload Ax88772c.dll=0`ea73b000, 0`9000
00000000ea725000    00000000ea73b000    PciBusDxe.dll    .reload PciBusDxe.dll=0`ea725000, 0`16000
00000000ea717000    00000000ea725000    NvmExpressDxe.dll    .reload NvmExpressDxe.dll=0`ea717000, 0`e000
00000000ea70b000    00000000ea717000    MmcDxe.dll    .reload MmcDxe.dll=0`ea70b000, 0`c000
00000000ea703000    00000000ea70b000    SdhciHostDxe.dll    .reload SdhciHostDxe.dll=0`ea703000, 0`8000
00000000e9e74000    00000000e9ea0000    UiApp.dll    .reload UiApp.dll=0`e9e74000, 0`2c000
00000000e9c63000    00000000e9d70000    Shell.dll    .reload Shell.dll=0`e9c63000, 0`10d000

通过自己实现!ndxlm,可以更好地学习理解UEFI代码,输出细节中有彩蛋。

作者:朱博渊  创建时间:2024-06-23 22:21
最后编辑:朱博渊  更新时间:2024-10-15 11:09