VirtualBox

Changeset 41059 in vbox


Ignore:
Timestamp:
Apr 26, 2012 12:52:15 AM (13 years ago)
Author:
vboxsync
Message:

tstLdr-3: Extended the tool.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/testcase/tstLdr-3.cpp

    r38636 r41059  
    3939
    4040
    41 static bool MyDisBlock(PDISCPUSTATE pCpu, RTHCUINTPTR pvCodeBlock, int32_t cbMax, RTUINTPTR off, RTUINTPTR Addr)
    42 {
    43     int32_t i = 0;
    44     while (i < cbMax)
    45     {
    46         char        szOutput[256];
    47         uint32_t    cbInstr;
    48         if (RT_FAILURE(DISInstr(pCpu, pvCodeBlock + i, off, &cbInstr, szOutput)))
    49             return false;
    50 
    51         RTPrintf("%s", szOutput);
    52         if (pvCodeBlock + i + off == Addr)
    53             RTPrintf("^^^^^^^^\n");
    54 
    55         /* next */
    56         i += cbInstr;
    57     }
    58     return true;
    59 }
    60 
    61 
    62 
    63 /**
    64  * Resolve an external symbol during RTLdrGetBits().
    65  *
    66  * @returns iprt status code.
    67  * @param   hLdrMod         The loader module handle.
    68  * @param   pszModule       Module name.
    69  * @param   pszSymbol       Symbol name, NULL if uSymbol should be used.
    70  * @param   uSymbol         Symbol ordinal, ~0 if pszSymbol should be used.
    71  * @param   pValue          Where to store the symbol value (address).
    72  * @param   pvUser          User argument.
    73  */
    74 static DECLCALLBACK(int) testGetImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser)
    75 {
    76     RTUINTPTR BaseAddr = *(PCRTUINTPTR)pvUser;
    77     *pValue = BaseAddr + UINT32_C(0x604020f0);
    78     return VINF_SUCCESS;
    79 }
    80 
    81 
    82 /**
    83  * Enumeration callback function used by RTLdrEnumSymbols().
    84  *
    85  * @returns iprt status code. Failure will stop the enumeration.
    86  * @param   hLdrMod         The loader module handle.
    87  * @param   pszSymbol       Symbol name. NULL if ordinal only.
    88  * @param   uSymbol         Symbol ordinal, ~0 if not used.
    89  * @param   Value           Symbol value.
    90  * @param   pvUser          The user argument specified to RTLdrEnumSymbols().
    91  */
    92 static DECLCALLBACK(int) testEnumSymbol1(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser)
    93 {
    94     RTPrintf("  %RTptr %s (%d)\n", Value, pszSymbol, uSymbol);
    95     return VINF_SUCCESS;
    96 }
     41/*******************************************************************************
     42*   Global Variables                                                           *
     43*******************************************************************************/
     44static RTUINTPTR g_uLoadAddr;
     45static RTLDRMOD  g_hLdrMod;
     46static void     *g_pvBits;
    9747
    9848/**
     
    163113}
    164114
     115static int FindNearSymbol(RTUINTPTR uAddr, PTESTNEARSYM pNearSym)
     116{
     117    RT_ZERO(*pNearSym);
     118    pNearSym->Addr = (RTUINTPTR)uAddr;
     119    pNearSym->aSyms[1].Value = ~(RTUINTPTR)0;
     120    int rc = RTLdrEnumSymbols(g_hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, g_pvBits, g_uLoadAddr, testEnumSymbol2, pNearSym);
     121    if (RT_FAILURE(rc))
     122        RTPrintf("tstLdr-3: Failed to enumerate symbols: %Rra\n", rc);
     123    return rc;
     124}
     125
     126static DECLCALLBACK(int) MyGetSymbol(PCDISCPUSTATE pCpu, uint32_t u32Sel, RTUINTPTR uAddress,
     127                                     char *pszBuf, size_t cchBuf, RTINTPTR *poff,
     128                                     void *pvUser)
     129{
     130    if (   uAddress > RTLdrSize(g_hLdrMod) + g_uLoadAddr
     131        || uAddress < g_uLoadAddr)
     132        return VERR_SYMBOL_NOT_FOUND;
     133
     134    TESTNEARSYM NearSym;
     135    int rc = FindNearSymbol(uAddress, &NearSym);
     136    if (RT_FAILURE(rc))
     137        return rc;
     138
     139    RTStrCopy(pszBuf, cchBuf, NearSym.aSyms[0].szName);
     140    *poff = uAddress - NearSym.aSyms[0].Value;
     141    return VINF_SUCCESS;
     142}
     143
     144
     145static DECLCALLBACK(int) MyReadBytes(RTUINTPTR uSrc, uint8_t *pbDst, unsigned cb, void *pvUser)
     146{
     147    PDISCPUSTATE pCpu = (PDISCPUSTATE)pvUser;
     148    memcpy(pbDst, (uint8_t const *)((uintptr_t)uSrc + (uintptr_t)pCpu->apvUserData[0]), cb);
     149    return VINF_SUCCESS;
     150}
     151
     152
     153static bool MyDisBlock(PDISCPUSTATE pCpu, RTHCUINTPTR pvCodeBlock, int32_t cbMax, RTUINTPTR off,
     154                       RTUINTPTR uNearAddr, RTUINTPTR uSearchAddr)
     155{
     156    int32_t i = 0;
     157    while (i < cbMax)
     158    {
     159        bool        fQuiet    = RTAssertSetQuiet(true);
     160        bool        fMayPanic = RTAssertSetMayPanic(false);
     161        char        szOutput[256];
     162        unsigned    cbInstr;
     163        int rc = DISCoreOneEx(uNearAddr + i, pCpu->mode,
     164                              MyReadBytes, (uint8_t *)pvCodeBlock - (uintptr_t)uNearAddr,
     165                              pCpu, &cbInstr);
     166        RTAssertSetMayPanic(fMayPanic);
     167        RTAssertSetQuiet(fQuiet);
     168        if (RT_FAILURE(rc))
     169            return false;
     170
     171        DISFormatYasmEx(pCpu, szOutput, sizeof(szOutput),
     172                        DIS_FMT_FLAGS_RELATIVE_BRANCH | DIS_FMT_FLAGS_BYTES_RIGHT | DIS_FMT_FLAGS_ADDR_LEFT  | DIS_FMT_FLAGS_BYTES_SPACED,
     173                        MyGetSymbol, NULL);
     174
     175        RTPrintf("%s\n", szOutput);
     176        if (pvCodeBlock + i + off == uSearchAddr)
     177            RTPrintf("^^^^^^^^\n");
     178
     179        /* next */
     180        i += cbInstr;
     181    }
     182    return true;
     183}
     184
     185
     186
     187/**
     188 * Resolve an external symbol during RTLdrGetBits().
     189 *
     190 * @returns iprt status code.
     191 * @param   hLdrMod         The loader module handle.
     192 * @param   pszModule       Module name.
     193 * @param   pszSymbol       Symbol name, NULL if uSymbol should be used.
     194 * @param   uSymbol         Symbol ordinal, ~0 if pszSymbol should be used.
     195 * @param   pValue          Where to store the symbol value (address).
     196 * @param   pvUser          User argument.
     197 */
     198static DECLCALLBACK(int) testGetImport(RTLDRMOD hLdrMod, const char *pszModule, const char *pszSymbol, unsigned uSymbol, RTUINTPTR *pValue, void *pvUser)
     199{
     200#if 1
     201    RTUINTPTR BaseAddr = *(PCRTUINTPTR)pvUser;
     202    *pValue = BaseAddr + UINT32_C(0x604020f0);
     203#else
     204    *pValue = UINT64_C(0xffffff7f820df000);
     205#endif
     206    return VINF_SUCCESS;
     207}
     208
     209
     210/**
     211 * Enumeration callback function used by RTLdrEnumSymbols().
     212 *
     213 * @returns iprt status code. Failure will stop the enumeration.
     214 * @param   hLdrMod         The loader module handle.
     215 * @param   pszSymbol       Symbol name. NULL if ordinal only.
     216 * @param   uSymbol         Symbol ordinal, ~0 if not used.
     217 * @param   Value           Symbol value.
     218 * @param   pvUser          The user argument specified to RTLdrEnumSymbols().
     219 */
     220static DECLCALLBACK(int) testEnumSymbol1(RTLDRMOD hLdrMod, const char *pszSymbol, unsigned uSymbol, RTUINTPTR Value, void *pvUser)
     221{
     222    RTPrintf("  %RTptr %s (%d)\n", Value, pszSymbol, uSymbol);
     223    return VINF_SUCCESS;
     224}
     225
     226
     227static int testDisasNear(uint64_t uAddr)
     228{
     229    TESTNEARSYM NearSym;
     230    int rc = FindNearSymbol(uAddr, &NearSym);
     231    if (RT_FAILURE(rc))
     232        return rc;
     233
     234    RTPrintf("tstLdr-3: Addr=%RTptr\n"
     235             "%RTptr %s (%d) - %RTptr %s (%d)\n",
     236             NearSym.Addr,
     237             NearSym.aSyms[0].Value, NearSym.aSyms[0].szName, NearSym.aSyms[0].uSymbol,
     238             NearSym.aSyms[1].Value, NearSym.aSyms[1].szName, NearSym.aSyms[1].uSymbol);
     239    if (NearSym.Addr - NearSym.aSyms[0].Value < 0x10000)
     240    {
     241        DISCPUSTATE Cpu;
     242        memset(&Cpu, 0, sizeof(Cpu));
     243#ifdef RT_ARCH_X86 /** @todo select according to the module type. */
     244        Cpu.mode = CPUMODE_32BIT;
     245#else
     246        Cpu.mode = CPUMODE_64BIT;
     247#endif
     248        uint8_t *pbCode = (uint8_t *)g_pvBits + (NearSym.aSyms[0].Value - g_uLoadAddr);
     249        MyDisBlock(&Cpu, (uintptr_t)pbCode,
     250                   RT_MAX(NearSym.aSyms[1].Value - NearSym.aSyms[0].Value, 0x20000),
     251                   NearSym.aSyms[0].Value - (RTUINTPTR)pbCode,
     252                   NearSym.aSyms[0].Value,
     253                   NearSym.Addr);
     254    }
     255
     256    return VINF_SUCCESS;
     257}
    165258
    166259int main(int argc, char **argv)
     
    178271     * Load the module.
    179272     */
    180     RTUINTPTR LoadAddr = (RTUINTPTR)RTStrToUInt64(argv[1]);
    181     RTLDRMOD hLdrMod;
    182     int rc = RTLdrOpen(argv[2], 0, RTLDRARCH_WHATEVER, &hLdrMod);
     273    g_uLoadAddr = (RTUINTPTR)RTStrToUInt64(argv[1]);
     274    int rc = RTLdrOpen(argv[2], 0, RTLDRARCH_WHATEVER, &g_hLdrMod);
    183275    if (RT_FAILURE(rc))
    184276    {
     
    187279    }
    188280
    189     void *pvBits = RTMemAlloc(RTLdrSize(hLdrMod));
    190     rc = RTLdrGetBits(hLdrMod, pvBits, LoadAddr, testGetImport, &LoadAddr);
     281    g_pvBits = RTMemAlloc(RTLdrSize(g_hLdrMod));
     282    rc = RTLdrGetBits(g_hLdrMod, g_pvBits, g_uLoadAddr, testGetImport, &g_uLoadAddr);
    191283    if (RT_SUCCESS(rc))
    192284    {
    193         if (argc > 3)
     285        if (   argc == 4
     286            && argv[3][0] == '*')
    194287        {
     288            /*
     289             * Wildcard address mode.
     290             */
     291            uint64_t uWild       = RTStrToUInt64(&argv[3][1]);
     292            uint64_t uIncrements = strchr(argv[3], '/') ? RTStrToUInt64(strchr(argv[3], '/') + 1) : 0x1000;
     293            if (!uIncrements)
     294                uIncrements = 0x1000;
     295            uint64_t uMax        = RTLdrSize(g_hLdrMod) + g_uLoadAddr;
     296            for (uint64_t uCur = g_uLoadAddr + uWild; uCur < uMax; uCur += uIncrements)
     297                testDisasNear(uCur);
     298        }
     299        else if (argc > 3)
     300        {
     301            /*
     302             * User specified addresses within the module.
     303             */
    195304            for (int i = 3; i < argc; i++)
    196305            {
    197                 TESTNEARSYM NearSym;
    198                 RT_ZERO(NearSym);
    199                 NearSym.Addr = (RTUINTPTR)RTStrToUInt64(argv[i]);
    200                 NearSym.aSyms[1].Value = ~(RTUINTPTR)0;
    201                 rc = RTLdrEnumSymbols(hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, pvBits, LoadAddr, testEnumSymbol2, &NearSym);
    202                 if (RT_SUCCESS(rc))
    203                 {
    204                     RTPrintf("tstLdr-3: Addr=%RTptr\n"
    205                              "%RTptr %s (%d) - %RTptr %s (%d)\n",
    206                              NearSym.Addr,
    207                              NearSym.aSyms[0].Value, NearSym.aSyms[0].szName, NearSym.aSyms[0].uSymbol,
    208                              NearSym.aSyms[1].Value, NearSym.aSyms[1].szName, NearSym.aSyms[1].uSymbol);
    209                     if (NearSym.Addr - NearSym.aSyms[0].Value < 0x10000)
    210                     {
    211                         DISCPUSTATE Cpu;
    212                         memset(&Cpu, 0, sizeof(Cpu));
    213 #ifdef RT_ARCH_X86 /** @todo select according to the module type. */
    214                         Cpu.mode = CPUMODE_32BIT;
    215 #else
    216                         Cpu.mode = CPUMODE_64BIT;
    217 #endif
    218                         uint8_t *pbCode = (uint8_t *)pvBits + (NearSym.aSyms[0].Value - LoadAddr);
    219                         MyDisBlock(&Cpu, (uintptr_t)pbCode,
    220                                    RT_MAX(NearSym.aSyms[1].Value - NearSym.aSyms[0].Value, 0x20000),
    221                                    NearSym.aSyms[0].Value - (RTUINTPTR)pbCode,
    222                                    NearSym.Addr);
    223                     }
    224                 }
    225                 else
    226                 {
    227                     RTPrintf("tstLdr-3: Failed to enumerate symbols: %Rra\n", rc);
     306                rc = testDisasNear(RTStrToUInt64(argv[i]));
     307                if (RT_FAILURE(rc))
    228308                    rcRet++;
    229                 }
    230309            }
    231310        }
     
    235314             * Enumerate symbols.
    236315             */
    237             rc = RTLdrEnumSymbols(hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, pvBits, LoadAddr, testEnumSymbol1, NULL);
     316            rc = RTLdrEnumSymbols(g_hLdrMod, RTLDR_ENUM_SYMBOL_FLAGS_ALL, g_pvBits, g_uLoadAddr, testEnumSymbol1, NULL);
    238317            if (RT_FAILURE(rc))
    239318            {
     
    245324    else
    246325    {
    247         RTPrintf("tstLdr-3: Failed to get bits for '%s' at %RTptr: %Rra\n", argv[2], LoadAddr, rc);
     326        RTPrintf("tstLdr-3: Failed to get bits for '%s' at %RTptr: %Rra\n", argv[2], g_uLoadAddr, rc);
    248327        rcRet++;
    249328    }
    250     RTMemFree(pvBits);
    251     RTLdrClose(hLdrMod);
     329    RTMemFree(g_pvBits);
     330    RTLdrClose(g_hLdrMod);
    252331
    253332    /*
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette