Ignore:
Timestamp:
Jan 28, 2000, 12:45:59 AM (26 years ago)
Author:
bird
Message:

Implemented applyFixups which will apply fixups when a page is being loaded.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/win32k/pe2lx/pe2lx.cpp

    r2501 r2538  
    1 /* $Id: pe2lx.cpp,v 1.15 2000-01-22 18:21:03 bird Exp $
     1/* $Id: pe2lx.cpp,v 1.16 2000-01-27 23:45:59 bird Exp $
    22 *
    33 * Pe2Lx class implementation. Ring 0 and Ring 3
    44 *
    5  * Copyright (c) 1998-1999 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
     5 * Copyright (c) 1998-2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)
    66 * Copyright (c) 1998 Sander van Leeuwen (sandervl@xs4all.nl)
    77 * Copyright (c) 1998 Peter Fitzsimmons
     
    104104#include <exe386.h>                         /* OS/2 LX structs and definitions. */
    105105
    106 #include "malloc.h"                         /* win32k malloc. Not C library! */
     106#include "malloc.h"                         /* win32k malloc (resident). Not C library! */
     107#include "smalloc.h"                        /* win32k swappable heap. */
     108#include "rmalloc.h"                        /* win32k resident heap. */
    107109
    108110#include <string.h>                         /* C library string.h. */
     
    249251    pachImpModuleNames(NULL), offCurImpModuleName(0), cchIMNAllocated(0),
    250252    pachImpFunctionNames(NULL), offCurImpFunctionName(0), cchIFNAllocated(0),
    251     offNtHeaders(0), pNtHdrs(NULL), ulImageBase(0UL)
     253    offNtHeaders(0), pNtHdrs(NULL), ulImageBase(0UL), pBaseRelocs(0),
     254    fApplyFixups(~0UL), fDeltaOnly(0)
    252255{
    253256    memset(&LXHdr, 0, sizeof(LXHdr));
     
    326329        pNtHdrs = NULL;
    327330    }
     331    if (pBaseRelocs != NULL)
     332    {
     333        sfree(pBaseRelocs);
     334        pBaseRelocs = NULL;
     335    }
     336    _res_heapmin();
     337    _swp_heapmin();
    328338}
    329339
     
    705715
    706716    Yield();
     717    _res_heapmin();
     718    #if 0 /* testing */
     719    testApplyFixups();
     720    #endif
    707721
    708722    return NO_ERROR;
     
    10221036 *
    10231037 * @sketch     Find RVA.
     1038 * @remarks    Some more information on relocations:
     1039 * From Web:
     1040 *   IMAGE_REL_I386_ABSOLUTE Reference is absolute, no relocation is necessary
     1041 *   IMAGE_REL_I386_DIR16    Direct 16-bit reference to the symbols virtual address
     1042 *   IMAGE_REL_I386_REL16    PC-relative 16-bit reference to the symbols virtual address
     1043 *   IMAGE_REL_I386_DIR32    Direct 32-bit reference to the symbols virtual address
     1044 *   IMAGE_REL_I386_DIR32NB  Direct 32-bit reference to the symbols virtual address, base not included
     1045 *   IMAGE_REL_I386_SEG12    Direct 16-bit reference to the segment-selector bits of a 32-bit virtual address
     1046 *   IMAGE_REL_I386_SECTION  ?
     1047 *   IMAGE_REL_I386_SECREL   ?
     1048 *   IMAGE_REL_I386_REL32    PC-relative 32-bit reference to the symbols virtual address
     1049 *
     1050 * From TIS:
     1051 *   Type = 4­bit fixup type. This value has the following definitions:
     1052 *   0h     Absolute. This is a NOP. The fixup is skipped.
     1053 *   1h     High. Add the high 16 bits of the delta to the 16 bit field at Offset.
     1054 *          The 16bit field represents the high value of a 32 bit word.
     1055 *   2h     Low. Add the low 16 bits of the delta to the 16 bit field at Offset.
     1056 *          The 16 bit field represents the low half value of a 32 bit word. This
     1057 *          fixup will only be emitted for a RISC machine when the image Object
     1058 *          Align isn't the default of 64K.
     1059 *   3h     Highlow. Apply the 32 bit delta to the 32 bit field at Offset.
     1060 *   4h     Highadjust. This fixup requires a full 32 bit value. The high 16 bits
     1061 *          is located at Offset, and the low 16 bits is located in the next Offset
     1062 *          array element (this array element is included in the Size field). The
     1063 *          two need to be combined into a signed variable. Add the 32 bit delta.
     1064 *          Then add 0x8000 and store the high 16 bits of the signed variable to
     1065 *          the 16 bit field at Offset.
     1066 *   5h ­ Mipsjmpaddr.
     1067 *
     1068 * TODO: implement the above mentioned fixups.
    10241069 */
    10251070ULONG  Pe2Lx::applyFixups(PMTE pMTE, ULONG iObject, ULONG iPageTable, PVOID pvPage,
    10261071                          ULONG ulPageAddress, PVOID pvPTDA)
    10271072{
    1028     ULONG ulRVA;
    1029 
    1030     NOREF(ulRVA);
    1031 
    1032     NOREF(pMTE);
    1033     NOREF(iObject);
     1073    APIRET rc;
     1074
     1075    if (fApplyFixups != FALSE && pBaseRelocs != NULL)
     1076    {
     1077        ULONG ulRVAPage;
     1078        ULONG ulDelta;
     1079        PSMTE pSMTE = pMTE->mte_swapmte;
     1080
     1081        /* validate input */
     1082        if (pSMTE < (PSMTE)0x10000)
     1083        {
     1084            printErr(("Invalid pSMTE(0x%08x)\n", pSMTE));
     1085            return ERROR_INVALID_PARAMETER;
     1086        }
     1087        #ifdef DEBUG
     1088        if (pSMTE->smte_objcnt <= iObject)
     1089        {
     1090            printErr(("Invalid iObject(%d), smte_objcnt=%d\n", iObject, pSMTE->smte_objcnt));
     1091            return ERROR_INVALID_PARAMETER;
     1092        }
     1093        if (cObjects <= iObject)
     1094        {
     1095            printErr(("Invalid iObject(%d), cObjects=%d\n", iObject, cObjects));
     1096            return ERROR_INVALID_PARAMETER;
     1097        }
     1098        #endif
     1099
     1100        /* some calculations */
     1101        ulDelta     = pSMTE->smte_objtab[iObject].ote_base - paObjects[iObject].ulRVA - ulImageBase;
     1102        ulRVAPage   = paObjects[iObject].ulRVA + ulPageAddress - pSMTE->smte_objtab[iObject].ote_base;
     1103
     1104        /* check if the fixup needs to be applied? */
     1105        if (fApplyFixups == ~0UL)
     1106        {
     1107            fDeltaOnly = TRUE;          /* IMPORTANT: Later code assumes that this is true when fAllInOneObject is true. */
     1108            if (fAllInOneObject)
     1109                fApplyFixups = ulImageBase == pSMTE->smte_objtab[0].ote_base;
     1110            else
     1111            {
     1112                int i = 0;
     1113                #ifdef DEBUG
     1114                if (cObjects != pSMTE->smte_objcnt)
     1115                    printErr(("cObject(%d) != smte_objcnt(%d)\n", cObjects, pSMTE->smte_objcnt));
     1116                #endif
     1117                fApplyFixups = FALSE;
     1118                while (i < cObjects && (!fApplyFixups || fDeltaOnly))
     1119                {
     1120                    register ULONG ulTmp = pSMTE->smte_objtab[i].ote_base - ulImageBase - paObjects[i].ulRVA;
     1121                    if (ulTmp != 0)
     1122                        fApplyFixups = TRUE;
     1123                    if (ulTmp != ulDelta)
     1124                        fDeltaOnly = FALSE;
     1125                    i++;
     1126                }
     1127            }
     1128            if (!fApplyFixups)
     1129                return NO_ERROR;
     1130        }
     1131
     1132        PIMAGE_BASE_RELOCATION pbr = pBaseRelocs;
     1133        ULONG ulBefore;
     1134        ULONG ulAfter;
     1135        ULONG flRead = 0;   /* bitmask: 0 = no read, 1 = ulBefore is read, 2 = ulAfter is read */
     1136
     1137        while ((unsigned)pbr - (unsigned)pBaseRelocs + 8 < cbBaseRelocs /* 8= VirtualAddress and SizeOfBlock members */
     1138               && pbr->VirtualAddress < ulRVAPage + PAGESIZE)
     1139        {
     1140            if (pbr->VirtualAddress + PAGESIZE >= ulRVAPage)
     1141            {
     1142                PWORD pwoffFixup   = &pbr->TypeOffset[0];
     1143                ULONG cRelocations = (pbr->SizeOfBlock - offsetof(IMAGE_BASE_RELOCATION, TypeOffset)) / sizeof(WORD); /* note that sizeof(BaseReloc) is 12 bytes! */
     1144
     1145                /* Some bound checking just to be sure it works... */
     1146                if ((unsigned)pbr - (unsigned)pBaseRelocs + pbr->SizeOfBlock > cbBaseRelocs)
     1147                {
     1148                    printWar(("Block ends after BaseRelocation datadirectory.\n"));
     1149                    cRelocations = (((unsigned)pBaseRelocs + cbBaseRelocs) - (unsigned)pbr - offsetof(IMAGE_BASE_RELOCATION, TypeOffset)) / sizeof(WORD);
     1150                }
     1151
     1152                while (cRelocations != 0)
     1153                {
     1154                    static char acbFixupTypes[16] = {0x00, 0x02, 0x02, 0x04,
     1155                                                     0xFF, 0xFF, 0xFF, 0xFF,
     1156                                                     0xFF, 0xFF, 0xFF, 0xFF,
     1157                                                     0xFF, 0xFF, 0xFF, 0xFF};
     1158                    int   offFixup  = *pwoffFixup & (PAGESIZE-1);
     1159                    int   fType     = *pwoffFixup >> 12;
     1160                    int   cbFixup   = acbFixupTypes[fType];
     1161
     1162                    if (cbFixup != 0 && cbFixup <= 4
     1163                        && offFixup + pbr->VirtualAddress + (cbFixup-1) >= ulRVAPage
     1164                        && offFixup + pbr->VirtualAddress < ulRVAPage + PAGESIZE
     1165                        )
     1166                    {
     1167                        ULONG       iObj;
     1168                        ULONG       ulTarget;
     1169                        PULONG      pul;        /* Pointer to fixup target */
     1170                        ULONG       ul;         /* Crosspage fixups: Conent of fixup target */
     1171                        unsigned    uShift1;    /* Crosspage fixups: Shift */
     1172                        unsigned    uShift2;    /* Crosspage fixups: Inverse of Shift1 */
     1173
     1174                        if (offFixup + pbr->VirtualAddress < ulRVAPage)
     1175                        {   /*
     1176                             * Crosspagefixup - from the page before
     1177                             */
     1178                            uShift1 = (unsigned)((offFixup + pbr->VirtualAddress) % cbFixup) * 8;
     1179                            uShift2 = cbFixup * 8 - uShift1;
     1180                            pul     = (PULONG)pvPage;
     1181                            ul      = *pul;
     1182                            if (!fDeltaOnly && fType == IMAGE_REL_BASED_HIGHLOW)
     1183                            {
     1184                                /* Read? */
     1185                                if ((flRead & 1) == 0)
     1186                                {
     1187                                    rc = readAtRVA(ulRVAPage - 4, SSToDS(&ulBefore), sizeof(ulBefore));
     1188                                    if (rc != NO_ERROR)
     1189                                    {
     1190                                        printErr(("readAtRVA(0x%08x, ulBefore..) failed with rc=%d\n", ulRVAPage-4, rc));
     1191                                        return rc;
     1192                                    }
     1193                                    flRead |= 1;
     1194                                }
     1195                                /* Get target pointer, find it's object and apply the fixup */
     1196                                ulTarget = (ulBefore >> uShift1) | (ul << uShift2);
     1197                                ulTarget -= ulImageBase; /* ulTarget is now an RVA */
     1198                                iObj = 0UL;
     1199                                while (iObj < cObjects
     1200                                       && ulTarget >= (iObj + 1 < cObjects ? paObjects[iObj+1].ulRVA
     1201                                                      : ALIGN(paObjects[iObj].cbVirtual, PAGESIZE) + paObjects[iObj].ulRVA)
     1202                                       )
     1203                                    iObj++;
     1204                                if (iObj < cObjects)
     1205                                    *pul = ((pSMTE->smte_objtab[iObj].ote_base + ulTarget - paObjects[iObj].ulRVA) >> uShift2)
     1206                                                         | (ul & ((~0UL) << uShift1));
     1207                                else
     1208                                    *pul = (((ulDelta >> uShift2) + ul) & ((~0UL) >> uShift2)) | (ul & ((~0UL) << uShift1));
     1209                            }
     1210                            else
     1211                            {   /* apply delta fixup */
     1212                                switch (fType)
     1213                                {
     1214                                    case IMAGE_REL_BASED_HIGHLOW:
     1215                                        *pul = (((ulDelta >> uShift2) + ul) & ((~0UL) >> uShift2)) | (ul & ((~0UL) << uShift1));
     1216                                        break;
     1217                                    case IMAGE_REL_BASED_HIGH:
     1218                                    case IMAGE_REL_BASED_HIGHADJ:  /* According to M$ docs these seems to be the same fixups. */
     1219                                    case IMAGE_REL_BASED_HIGH3ADJ:
     1220                                        *pul = (((ulDelta >> 24) + ul) & 0xFF) | (ul & 0xFFFFFF00UL);
     1221                                        break;
     1222                                    case IMAGE_REL_BASED_LOW:
     1223                                        *pul = (((ulDelta >>  8) + ul) & 0xFF) | (ul & 0xFFFFFF00UL);
     1224                                        break;
     1225                                }
     1226                            }
     1227                        }
     1228                        else if (offFixup + pbr->VirtualAddress + cbFixup > ulRVAPage + PAGESIZE)
     1229                        {   /*
     1230                             * Crosspagefixup - into the page afterwards
     1231                             */
     1232                            uShift1 = (unsigned)((offFixup + pbr->VirtualAddress) % cbFixup) * 8;
     1233                            uShift2 = cbFixup * 8 - uShift1;
     1234                            pul = (PULONG)((unsigned)pvPage + PAGESIZE - sizeof(ULONG));
     1235                            ul = *pul;
     1236                            if (!fDeltaOnly && fType == IMAGE_REL_BASED_HIGHLOW)
     1237                            {
     1238                                /* Read? */
     1239                                if ((flRead & 2) == 0)
     1240                                {
     1241                                    rc = readAtRVA(ulRVAPage+PAGESIZE, SSToDS(&ulAfter), sizeof(ulAfter));
     1242                                    if (rc != NO_ERROR)
     1243                                    {
     1244                                        printErr(("readAtRVA(0x%08x, ulAfter..) failed with rc=%d\n", ulRVAPage+PAGESIZE, rc));
     1245                                        return rc;
     1246                                    }
     1247                                    flRead |= 2;
     1248                                }
     1249                                /* Get target pointer, find it's object and apply the fixup */
     1250                                ulTarget = (ulAfter << uShift2) | (ul >> uShift1);
     1251                                ulTarget -= ulImageBase; /* ulTarget is now an RVA */
     1252                                iObj = 0UL;
     1253                                while (iObj < cObjects
     1254                                       && ulTarget >= (iObj + 1 < cObjects ? paObjects[iObj+1].ulRVA
     1255                                                      : ALIGN(paObjects[iObj].cbVirtual, PAGESIZE) + paObjects[iObj].ulRVA)
     1256                                       )
     1257                                    iObj++;
     1258                                if (iObj < cObjects)
     1259                                    *pul = ((pSMTE->smte_objtab[iObj].ote_base + ulTarget - paObjects[iObj].ulRVA) << uShift1)
     1260                                           | (ul & ((~0UL) >> uShift2));
     1261                                else
     1262                                    *pul += ulDelta << uShift1;
     1263                            }
     1264                            else
     1265                            {   /* apply delta fixup */
     1266                                switch (fType)
     1267                                {
     1268                                    case IMAGE_REL_BASED_HIGHLOW:
     1269                                        *pul += ulDelta << uShift1;
     1270                                        break;
     1271                                    case IMAGE_REL_BASED_HIGH:
     1272                                    case IMAGE_REL_BASED_HIGHADJ:  /* According to M$ docs these seems to be the same fixups. */
     1273                                    case IMAGE_REL_BASED_HIGH3ADJ:
     1274                                        *pul += ulDelta << 8;
     1275                                        break;
     1276                                    case IMAGE_REL_BASED_LOW:
     1277                                        *pul += ulDelta << 24;
     1278                                        break;
     1279                                }
     1280                            }
     1281                        }
     1282                        else
     1283                        {   /*
     1284                             * Common fixup
     1285                             */
     1286                            pul = (PULONG)((unsigned)pvPage + offFixup + pbr->VirtualAddress - ulRVAPage);
     1287                            switch (fType)
     1288                            {
     1289                                case IMAGE_REL_BASED_HIGHLOW:
     1290                                    if (fDeltaOnly)
     1291                                        *pul += ulDelta;
     1292                                    else
     1293                                    {
     1294                                        ulTarget = *pul;
     1295                                        ulTarget -= ulImageBase; /* ulTarget is now an RVA */
     1296                                        iObj = 0UL;
     1297                                        while (iObj < cObjects
     1298                                               && ulTarget >= (iObj + 1 < cObjects ? paObjects[iObj+1].ulRVA
     1299                                                              : ALIGN(paObjects[iObj].cbVirtual, PAGESIZE) + paObjects[iObj].ulRVA)
     1300                                               )
     1301                                            iObj++;
     1302                                        if (iObj < cObjects)
     1303                                            *pul = pSMTE->smte_objtab[iObj].ote_base + ulTarget - paObjects[iObj].ulRVA;
     1304                                        else
     1305                                            *pul += ulDelta;
     1306                                    }
     1307                                    break;
     1308                                /* Will probably not work very well until the 64KB object alignment is gone! */
     1309                                case IMAGE_REL_BASED_HIGH:
     1310                                case IMAGE_REL_BASED_HIGHADJ:   /* According to M$ docs these seems to be the same fixups. */
     1311                                case IMAGE_REL_BASED_HIGH3ADJ:
     1312                                    printInf(("IMAGE_REL_BASED_HIGH offset=0x%08x\n", offFixup));
     1313                                    *(PUSHORT)pul += (USHORT)(ulDelta >> 16);
     1314                                    break;
     1315                                /* Will probably not work very well until the 64KB object alignment is gone! */
     1316                                case IMAGE_REL_BASED_LOW:
     1317                                    printInf(("IMAGE_REL_BASED_LOW  offset=0x%08x\n", offFixup));
     1318                                    *(PUSHORT)pul += (USHORT)ulDelta;
     1319                                    break;
     1320                            }
     1321                        }
     1322                    }
     1323
     1324                    /* Next offset/type */
     1325                    pwoffFixup++;
     1326                    cRelocations--;
     1327                }
     1328            }
     1329
     1330            /* next */
     1331            pbr = (PIMAGE_BASE_RELOCATION)((unsigned)pbr + pbr->SizeOfBlock);
     1332        }
     1333    }
    10341334    NOREF(iPageTable);
    1035     NOREF(pvPage);
    1036     NOREF(ulPageAddress);
    10371335    NOREF(pvPTDA);
    10381336
     
    10431341
    10441342#ifndef RING0
     1343/**
     1344 * This method test the applyFixups method.
     1345 * @returns   Last rc from applyFixups.
     1346 * @status
     1347 * @author    knut st. osmundsen
     1348 * @remark    Testing only...
     1349 */
     1350ULONG Pe2Lx::testApplyFixups()
     1351{
     1352    static SMTE smte;
     1353    static MTE  mte;
     1354    static      achPage[PAGESIZE];
     1355    int         i;
     1356    APIRET      rc;
     1357
     1358    mte.mte_swapmte = &smte;
     1359    smte.smte_objcnt = cObjects;
     1360    smte.smte_objtab = (POTE)malloc(cObjects * sizeof(OTE));
     1361    makeObjectTable();
     1362    memcpy(smte.smte_objtab, paObjTab, sizeof(OTE) * cObjects);
     1363    smte.smte_objtab[0].ote_base = 0x125D0000;
     1364    for (i = 1; i < cObjects; i++)
     1365        smte.smte_objtab[i].ote_base = ALIGN(smte.smte_objtab[i-1].ote_size + smte.smte_objtab[i-1].ote_base, 0x10000);
     1366
     1367    rc = loadBaseRelocations();
     1368    if (rc != NO_ERROR)
     1369    {
     1370        printErr(("loadBaseRelocations failed with rc=%d\n", rc));
     1371        return rc;
     1372    }
     1373
     1374    rc = readAtRVA(0x00000000, &achPage[0], PAGESIZE);
     1375    if (rc != NO_ERROR)
     1376    {
     1377        printErr(("readAtRVA failed with rc=%d\n"));
     1378        return rc;
     1379    }
     1380    rc = applyFixups(&mte, 0, ~0UL, &achPage[0], 0x125D0000, NULL);
     1381
     1382    rc = readAtRVA(0x00001000, &achPage[0], PAGESIZE);
     1383    if (rc != NO_ERROR)
     1384    {
     1385        printErr(("readAtRVA failed with rc=%d\n"));
     1386        return rc;
     1387    }
     1388    rc = applyFixups(&mte, 1, 1, &achPage[0], 0x125E0000, NULL);
     1389
     1390    return rc;
     1391}
     1392
     1393
     1394
    10451395/**
    10461396 * Writes the virtual LX file to a file. (Ring 3 only!)
     
    18042154    ULONG                       ulRVAFirstThunk;    /* Current first thunk array RVA. Points at current entry. */
    18052155    ULONG                       ulRVAOrgFirstThunk; /* Current original first thunk array RVA. Points at current entry. */
    1806 
     2156    #ifndef RING0
    18072157    BOOL                        fBaseRelocs;        /* fBaseReloc is set when a valid base reloc directory is present. */
    18082158    ULONG                       ulRVABaseReloc;     /* RVA of the current base relocation chunk. (Not the first!) */
     
    18112161    BufferedRVARead            *pPageReader;        /* Buffered reader for page reads; ie. getting the target address. */
    18122162    BufferedRVARead            *pRelocReader;       /* Buffered reader for relocation reads; ie getting the type/offset word. */
    1813 
     2163    #endif
    18142164    ULONG                       ulRVAPage;          /* RVA for the current page. */
    18152165    ULONG                       ul;                 /* temporary unsigned long variable. Many uses. */
     
    18482198
    18492199    /* Check if empty base relocation directory. */
     2200    #ifndef RING0
    18502201    fBaseRelocs = (cbBaseRelocs = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size) > 0UL
    18512202        &&
     
    18532204        &&
    18542205        ulRVABaseReloc < pNtHdrs->OptionalHeader.SizeOfImage;
    1855 
     2206    #endif
    18562207    printInf(("\n"));
     2208    #ifndef RING0
    18572209    printInf(("Make fixups, fBaseReloc=%s, fImports=%s\n",
    18582210              fBaseRelocs ? "true" : "false",
    18592211              fImports ? "true" : "false"));
     2212    #else
     2213    printInf(("Make fixups, fImports=%s\n", fImports ? "true" : "false"));
     2214    #endif
    18602215    printInf(("\n"));
    18612216
    18622217    /* create reader buffers */
     2218    #ifndef RING0
    18632219    if (fBaseRelocs)
    18642220    {
     
    18702226    else
    18712227        pRelocReader = pPageReader = NULL;
     2228    #endif
    18722229    if (fImports)
    18732230    {
     
    18842241    if (rc != NO_ERROR)
    18852242    {   /* error: clean up and return! */
     2243        #ifndef RING0
    18862244        if (pPageReader != NULL)
    18872245            delete pPageReader;
    18882246        if (pRelocReader != NULL)
    18892247            delete pRelocReader;
     2248        #endif
    18902249        if (pImportReader != NULL)
    18912250            delete pImportReader;
     
    19362295    }
    19372296
     2297
    19382298    /* read start of the first basereloc chunk */
     2299    #ifndef RING0
    19392300    if (fBaseRelocs && rc == NO_ERROR)
    19402301        rc = pRelocReader->readAtRVA(ulRVABaseReloc, SSToDS(&BaseReloc), sizeof(BaseReloc));
     2302    #endif
    19412303
    19422304
     
    20532415
    20542416        /* check for fixups for this page. ASSUMES that fixups are sorted and that each chunk covers one page, no more no less. */
     2417        #ifndef RING0
    20552418        if (fBaseRelocs && BaseReloc.VirtualAddress == ulRVAPage)
    20562419        {
     
    21182481                fBaseRelocs = FALSE;
    21192482        }
     2483        #endif /*ifndef RING */
    21202484
    21212485        /**  next  **/
     
    21402504
    21412505    /* finished! - cleanup! */
     2506    #ifndef RING0
    21422507    if (pPageReader != NULL)
    21432508        delete pPageReader;
    21442509    if (pRelocReader != NULL)
    21452510        delete pRelocReader;
     2511    #endif
    21462512    if (pImportReader != NULL)
    21472513        delete pImportReader;
     
    21572523        finalizeFixups();
    21582524    }
     2525    #ifdef RING0
     2526    /* load base relocations... */
     2527    if (rc == NO_ERROR)
     2528        return loadBaseRelocations();
     2529    #endif
    21592530    return rc;
    21602531}
     
    24022773        pNtHdrs = NULL;
    24032774    }
     2775}
     2776
     2777
     2778/**
     2779 * Loads the baserelocations from the PE-file.
     2780 * @returns   NO_ERROR on success, appropriate error message.
     2781 * @sketch
     2782 * @status    completely implemented; untestd.
     2783 * @author    knut st. osmundsen
     2784 */
     2785ULONG Pe2Lx::loadBaseRelocations()
     2786{
     2787    APIRET rc;
     2788    ULONG ulRVA;
     2789
     2790    /* ? */
     2791    rc = loadNtHeaders();
     2792    if (rc != NO_ERROR)
     2793        return rc;
     2794    /* end ? */
     2795
     2796    ulRVA  = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
     2797    cbBaseRelocs = pNtHdrs->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
     2798
     2799    if (ulRVA > 0UL && cbBaseRelocs > 0UL && ulRVA < ~0UL && cbBaseRelocs < ~0UL)
     2800    {
     2801        pBaseRelocs = (PIMAGE_BASE_RELOCATION)smalloc((size_t)cbBaseRelocs);
     2802        if (pBaseRelocs != NULL)
     2803        {
     2804            rc = readAtRVA(ulRVA, pBaseRelocs, cbBaseRelocs);
     2805            if (rc != NO_ERROR)
     2806            {
     2807                printErr(("readAtRVA(0x%08x, 0x%08x, 0x%08x) failed with rc = %d\n",
     2808                          ulRVA, pBaseRelocs, cbBaseRelocs, rc));
     2809                sfree(pBaseRelocs);
     2810                pBaseRelocs = NULL;
     2811            }
     2812            #ifdef DEBUG
     2813            else
     2814            {
     2815                PIMAGE_BASE_RELOCATION pbrCur = pBaseRelocs;
     2816                while ((void*)pbrCur < (void*)((unsigned)pBaseRelocs + cbBaseRelocs))
     2817                {
     2818                    if ((unsigned)pbrCur->SizeOfBlock + (unsigned)pbrCur > (unsigned)pBaseRelocs + cbBaseRelocs)
     2819                        printErr(("Debug-check - Chunk is larger than the base relocation directory. "
     2820                                  "SizeOfBlock=0x%08x, VirtualAddress=0x%08x\n",
     2821                                  pbrCur->SizeOfBlock, pbrCur->VirtualAddress));
     2822                    pbrCur = (PIMAGE_BASE_RELOCATION)((unsigned)pbrCur + pbrCur->SizeOfBlock);
     2823                }
     2824            }
     2825            #endif
     2826            return rc;
     2827        }
     2828        else
     2829        {
     2830            printErr(("rmalloc failed when allocating memory for pBaseReloc, cbSize=0x%x(%d)\n",
     2831                      cbBaseRelocs, cbBaseRelocs));
     2832            rc = ERROR_NOT_ENOUGH_MEMORY;
     2833        }
     2834    }
     2835    else
     2836    {
     2837        pBaseRelocs = NULL;
     2838        cbBaseRelocs = 0;
     2839    }
     2840
     2841    return NO_ERROR;
    24042842}
    24052843
     
    38674305
    38684306/**
     4307 * Reads a chunk of data at the spcified RVA.
     4308 * @returns   NO_ERROR on success.
     4309 *            ERROR_INVALID_PARAMETER
     4310 *            <Whatever rc ReadAt returns>
     4311 * @param     ulRVA     RVA to read from. Within the filesize.
     4312 * @param     pvBuffer  Pointer to output buffer. pvBuffer > 64KB
     4313 * @param     cbBuffer  Number of bytes to read. 0 < cbBuffer > 256MB
     4314 * @status    completely implemented; tested.
     4315 * @author    knut st. osmundsen
     4316 */
     4317ULONG Pe2Lx::readAtRVA(ULONG ulRVA, PVOID pvBuffer, ULONG cbBuffer)
     4318{
     4319    #ifdef DEBUG
     4320    if (ulRVA == ~0UL || (ULONG)pvBuffer < 0x10000UL || cbBuffer == 0UL || cbBuffer >= 0x10000000UL)
     4321        return ERROR_INVALID_PARAMETER;
     4322    #endif
     4323
     4324    ULONG iObj = 0;
     4325    while (cbBuffer != 0UL)
     4326    {
     4327        while (iObj < cObjects
     4328               && ulRVA >= (iObj + 1 < cObjects ? paObjects[iObj+1].ulRVA
     4329                            : paObjects[iObj].ulRVA + ALIGN(paObjects[iObj].cbVirtual, PAGESIZE))
     4330               )
     4331            iObj++;
     4332        if (iObj >= cObjects)
     4333            return ERROR_INVALID_PARAMETER;
     4334
     4335        /* ulRVA points at physical or virtual data? */
     4336        if (ulRVA < paObjects[iObj].ulRVA + paObjects[iObj].cbPhysical)
     4337        {   /* physical data - read from file */
     4338            APIRET rc;
     4339            ULONG  cbToRead = min(paObjects[iObj].ulRVA + paObjects[iObj].cbPhysical - ulRVA, cbBuffer);
     4340            rc = ReadAt(hFile,
     4341                        ulRVA - paObjects[iObj].ulRVA + paObjects[iObj].offPEFile,
     4342                        pvBuffer,
     4343                        cbToRead
     4344                        );
     4345            if (rc != NO_ERROR)
     4346                return rc;
     4347            ulRVA += cbToRead;
     4348            cbBuffer -= cbToRead;
     4349            pvBuffer = (void*)((unsigned)pvBuffer + cbToRead);
     4350        }
     4351        else
     4352        {   /* virtual data - memset(,0,) */
     4353            ULONG cbToSet = (iObj + 1 < cObjects ? paObjects[iObj+1].ulRVA
     4354                              : paObjects[iObj].ulRVA + ALIGN(paObjects[iObj].cbVirtual, PAGESIZE))
     4355                            - ulRVA; /* calcs size of virtual data left in this object */
     4356            cbToSet = min(cbToSet, cbBuffer);
     4357
     4358            memset(pvBuffer, 0, (size_t)cbToSet);
     4359            ulRVA += cbToSet;
     4360            cbBuffer -= cbToSet;
     4361            pvBuffer = (void*)((unsigned)pvBuffer + cbToSet);
     4362        }
     4363    } /* while */
     4364
     4365    return NO_ERROR;
     4366}
     4367
     4368
     4369
     4370/**
    38694371 * Check if the modulename exists in the lielist. If not the passed in modulename is returned.
    38704372 * @returns   Pointer (readonly) to Odin32 modulename.
     
    42374739
    42384740    /* where to read? */
    4239     if (ulRVA != this->ulRVA + sizeof(achBuffer) != ulRVA || this->ulRVA != ~0UL)
     4741    if (ulRVA != this->ulRVA + sizeof(achBuffer) || this->ulRVA == ~0UL)
    42404742        ulRVARead = this->ulRVA = ulRVA & ~(PAGESIZE-1UL); /* align on page boundrary - ASSUMES: buffersize >= PAGESIZE! */
    42414743    else
     
    42464748    while (cbLeftToRead != 0UL)
    42474749    {
    4248         while (iObj < cObjects && ulRVARead >= (iObj + 1 < cObjects ? paObjects[iObj+1].ulRVA
    4249                                                : paObjects[iObj].ulRVA + ALIGN(paObjects[iObj].cbVirtual, PAGESIZE))
     4750        while (iObj < cObjects
     4751               && ulRVARead >= (iObj + 1 < cObjects ? paObjects[iObj+1].ulRVA
     4752                                : paObjects[iObj].ulRVA + ALIGN(paObjects[iObj].cbVirtual, PAGESIZE))
    42504753              )
    42514754            iObj++;
Note: See TracChangeset for help on using the changeset viewer.