Changeset 61 for trunk/kLdr/kLdrModMachO.c
- Timestamp:
- Oct 14, 2013, 4:11:57 AM (12 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/kLdr/kLdrModMachO.c
r60 r61 355 355 && s.Hdr32.filetype != MH_EXECUTE 356 356 && s.Hdr32.filetype != MH_DYLIB 357 && s.Hdr32.filetype != MH_BUNDLE 357 358 && s.Hdr32.filetype != MH_DSYM 358 359 && s.Hdr32.filetype != MH_KEXT_BUNDLE) … … 463 464 case MH_EXECUTE: pMod->enmType = KLDRTYPE_EXECUTABLE_FIXED; break; 464 465 case MH_DYLIB: pMod->enmType = KLDRTYPE_SHARED_LIBRARY_RELOCATABLE; break; 466 case MH_BUNDLE: pMod->enmType = KLDRTYPE_SHARED_LIBRARY_RELOCATABLE; break; 465 467 case MH_KEXT_BUNDLE:pMod->enmType = KLDRTYPE_SHARED_LIBRARY_RELOCATABLE; break; 466 468 case MH_DSYM: pMod->enmType = KLDRTYPE_DEBUG_INFO; break; … … 709 711 KLDRMODMACHO_CHECK_RETURN(!pSect->reserved1, KLDR_ERR_MACHO_BAD_SECTION); \ 710 712 /* reserved2 == stub size. 0 has been seen (corecrypto.kext) */ \ 711 KLDRMODMACHO_CHECK_RETURN(pSect->reserved2 >64, KLDR_ERR_MACHO_BAD_SECTION); \713 KLDRMODMACHO_CHECK_RETURN(pSect->reserved2 < 64, KLDR_ERR_MACHO_BAD_SECTION); \ 712 714 fFileBits = 1; \ 713 715 break; \ … … 815 817 case MH_EXECUTE: \ 816 818 case MH_DYLIB: \ 819 case MH_BUNDLE: \ 817 820 case MH_DSYM: \ 818 821 case MH_KEXT_BUNDLE: \ … … 1029 1032 case MH_EXECUTE: 1030 1033 case MH_DYLIB: 1034 case MH_BUNDLE: 1031 1035 case MH_DSYM: 1032 1036 case MH_KEXT_BUNDLE: … … 1192 1196 /* Section data extract. */ \ 1193 1197 pSectExtra->cb = pSect->size; \ 1194 pSectExtra->RVA = pSect->addr ; \1198 pSectExtra->RVA = pSect->addr - pDstSeg->LinkAddress; \ 1195 1199 pSectExtra->LinkAddress = pSect->addr; \ 1196 1200 if (pSect->offset) \ … … 1246 1250 case MH_EXECUTE: 1247 1251 case MH_DYLIB: /** @todo ??? */ 1252 case MH_BUNDLE: /** @todo ??? */ 1248 1253 case MH_DSYM: 1249 1254 case MH_KEXT_BUNDLE: … … 1267 1272 kHlpAssert(pDstSeg == &pModMachO->pMod->aSegments[cSegments - pModMachO->fMakeGot]); 1268 1273 1269 #if 01270 {1271 /*1272 * Make sure the segments are sorted by link address, or we'll get screwed1273 * further down.1274 */1275 KLDRADDR cb1;1276 KSIZE cb2;1277 KU32 i;1278 KU32 c = pDstSeg - &pModMachO->pMod->aSegments[0];1279 1280 pDstSeg = &pModMachO->pMod->aSegments[0];1281 for (i = 0; i < c - 1; i++)1282 {1283 KLDRADDR LinkAddress = pDstSeg[i + 1].LinkAddress;1284 if (LinkAddress < pDstSeg[i].LinkAddress)1285 {1286 /* Gotta move the next segment, find the correct location. */1287 KLDRMODMACHOSEG TmpSegExtra;1288 KLDRSEG TmpSeg;1289 KU32 j = i;1290 KU32 cShift = 1;1291 1292 while (j > 0 && LinkAddress < pDstSeg[j - 1].LinkAddress)1293 j--, cShift++;1294 1295 TmpSegExtra = pModMachO->aSegments[i + 1];1296 kHlpMemMove(&pModMachO->aSegments[j + 1], &pModMachO->aSegments[j],1297 cShift * sizeof(pModMachO->aSegments[0]));1298 pModMachO->aSegments[j] = TmpSegExtra;1299 1300 TmpSeg = pDstSeg[i + 1];1301 kHlpMemMove(&pDstSeg[j + 1], &pDstSeg[j], cShift * sizeof(pDstSeg[0]));1302 pDstSeg[j] = TmpSeg;1303 }1304 }1305 1306 /*1307 * Adjust mapping addresses calculating the image size.1308 */1309 pDstSeg = &pModMachO->pMod->aSegments[0];1310 for (i = 0; i < cSegments - 1; i++)1311 {1312 cb1 = pDstSeg[i + 1].LinkAddress - pDstSeg[i].LinkAddress;1313 cb2 = (KSIZE)cb1;1314 pDstSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(KSIZE)0;1315 }1316 cb1 = KLDR_ALIGN_ADDR(pDstSeg[i].cb, pDstSeg[i].Alignment);1317 cb2 = (KSIZE)cb1;1318 pDstSeg[i].cbMapped = cb2 == cb1 ? cb2 : ~(KSIZE)0;1319 1320 pModMachO->cbImage = pDstSeg[i].RVA + cb1;1321 }1322 #else1323 1274 /* 1324 1275 * Adjust mapping addresses calculating the image size. 1325 1276 */ 1326 1277 { 1327 KLDRADDR uNextRVA = 0; 1328 KLDRADDR cb; 1329 KU32 c; 1278 PKLDRMODMACHOSECT pSectExtraItr; 1279 KLDRADDR uNextRVA = 0; 1280 KLDRADDR cb; 1281 KU32 c; 1330 1282 1331 1283 /* Adjust RVAs. */ … … 1353 1305 pDstSeg->cbMapped = (KSIZE)cb == cb ? (KSIZE)cb : KSIZE_MAX; 1354 1306 1355 /* And finally,the image size. */1307 /* Set the image size. */ 1356 1308 pModMachO->cbImage = pDstSeg->RVA + cb; 1357 } 1358 #endif 1359 1309 1310 /* Fixup the section RVA (internal). */ 1311 c = cSegments - pModMachO->fMakeGot; 1312 uNextRVA = pModMachO->cbImage; 1313 pDstSeg = &pModMachO->pMod->aSegments[0]; 1314 for (pSectExtraItr = pModMachO->paSections; pSectExtraItr != pSectExtra; pSectExtraItr++) 1315 { 1316 if (pSectExtraItr->iSegment < c) 1317 pSectExtraItr->RVA += pDstSeg[pSectExtraItr->iSegment].RVA; 1318 else 1319 { 1320 pSectExtraItr->RVA = uNextRVA; 1321 uNextRVA += KLDR_ALIGN_ADDR(pSectExtraItr->cb, 64); 1322 } 1323 } 1324 } 1360 1325 1361 1326 /* … … 1646 1611 || pModMachO->Hdr.filetype == MH_EXECUTE /** @todo dylib, execute, dsym: symbols */ 1647 1612 || pModMachO->Hdr.filetype == MH_DYLIB 1613 || pModMachO->Hdr.filetype == MH_BUNDLE 1648 1614 || pModMachO->Hdr.filetype == MH_DSYM 1649 1615 || pModMachO->Hdr.filetype == MH_KEXT_BUNDLE) … … 1779 1745 { 1780 1746 PKLDRMODMACHOSECT pSect; 1781 KLDRADDR RVA; 1782 if ((KU32)(paSyms[iSymbol].n_sect - 1) >= pModMachO->cSections) 1783 return KLDR_ERR_MACHO_BAD_SYMBOL; 1747 KLDRADDR offSect; 1748 KLDRMODMACHO_CHECK_RETURN((KU32)(paSyms[iSymbol].n_sect - 1) < pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL); 1784 1749 pSect = &pModMachO->paSections[paSyms[iSymbol].n_sect - 1]; 1785 1750 1786 RVA = paSyms[iSymbol].n_value - pModMachO->LinkAddress; 1787 if (RVA - pSect->RVA >= pSect->cb) 1788 return KLDR_ERR_MACHO_BAD_SYMBOL; 1751 offSect = paSyms[iSymbol].n_value - pSect->LinkAddress; 1752 KLDRMODMACHO_CHECK_RETURN( offSect <= pSect->cb 1753 || ( paSyms[iSymbol].n_sect == 1 /* special hack for __mh_execute_header */ 1754 && offSect == 0U - pSect->RVA 1755 && pModMachO->Hdr.filetype != MH_OBJECT), 1756 KLDR_ERR_MACHO_BAD_SYMBOL); 1789 1757 if (puValue) 1790 *puValue = RVA + BaseAddress;1758 *puValue = BaseAddress + pSect->RVA + offSect; 1791 1759 1792 1760 if ( pfKind … … 1905 1873 { 1906 1874 PKLDRMODMACHOSECT pSect; 1907 KLDRADDR RVA; 1908 if ((KU32)(paSyms[iSymbol].n_sect - 1) >= pModMachO->cSections) 1909 return KLDR_ERR_MACHO_BAD_SYMBOL; 1875 KLDRADDR offSect; 1876 KLDRMODMACHO_CHECK_RETURN((KU32)(paSyms[iSymbol].n_sect - 1) < pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL); 1910 1877 pSect = &pModMachO->paSections[paSyms[iSymbol].n_sect - 1]; 1911 1878 1912 RVA = paSyms[iSymbol].n_value - pModMachO->LinkAddress; 1913 if (RVA - pSect->RVA >= pSect->cb) 1914 return KLDR_ERR_MACHO_BAD_SYMBOL; 1879 offSect = paSyms[iSymbol].n_value - pSect->LinkAddress; 1880 KLDRMODMACHO_CHECK_RETURN( offSect <= pSect->cb 1881 || ( paSyms[iSymbol].n_sect == 1 /* special hack for __mh_execute_header */ 1882 && offSect == 0U - pSect->RVA 1883 && pModMachO->Hdr.filetype != MH_OBJECT), 1884 KLDR_ERR_MACHO_BAD_SYMBOL); 1915 1885 if (puValue) 1916 *puValue = RVA + BaseAddress;1886 *puValue = BaseAddress + pSect->RVA + offSect; 1917 1887 1918 1888 if ( pfKind … … 1960 1930 || pModMachO->Hdr.filetype == MH_EXECUTE /** @todo dylib, execute, dsym: symbols */ 1961 1931 || pModMachO->Hdr.filetype == MH_DYLIB 1932 || pModMachO->Hdr.filetype == MH_BUNDLE 1962 1933 || pModMachO->Hdr.filetype == MH_DSYM 1963 1934 || pModMachO->Hdr.filetype == MH_KEXT_BUNDLE) … … 2040 2011 2041 2012 /* name */ 2042 if ((KU32)paSyms[iSym].n_un.n_strx >= cchStrings) 2043 return KLDR_ERR_MACHO_BAD_SYMBOL; 2013 KLDRMODMACHO_CHECK_RETURN((KU32)paSyms[iSym].n_un.n_strx < cchStrings, KLDR_ERR_MACHO_BAD_SYMBOL); 2044 2014 psz = &pchStrings[paSyms[iSym].n_un.n_strx]; 2045 2015 cch = kHlpStrLen(psz); … … 2056 2026 { 2057 2027 PKLDRMODMACHOSECT pSect; 2058 if ((KU32)(paSyms[iSym].n_sect - 1) >= pModMachO->cSections) 2059 return KLDR_ERR_MACHO_BAD_SYMBOL; 2028 KLDRMODMACHO_CHECK_RETURN((KU32)(paSyms[iSym].n_sect - 1) < pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL); 2060 2029 pSect = &pModMachO->paSections[paSyms[iSym].n_sect - 1]; 2061 2030 2062 uValue = paSyms[iSym].n_value - pModMachO->LinkAddress; 2063 if (uValue - pSect->RVA > pSect->cb) 2064 return KLDR_ERR_MACHO_BAD_SYMBOL; 2065 uValue += BaseAddress; 2031 uValue = paSyms[iSym].n_value - pSect->LinkAddress; 2032 KLDRMODMACHO_CHECK_RETURN( uValue <= pSect->cb 2033 || ( paSyms[iSym].n_sect == 1 /* special hack for __mh_execute_header */ 2034 && uValue == 0U - pSect->RVA 2035 && pModMachO->Hdr.filetype != MH_OBJECT), 2036 KLDR_ERR_MACHO_BAD_SYMBOL); 2037 uValue += BaseAddress + pSect->RVA; 2066 2038 2067 2039 if (pSect->fFlags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SELF_MODIFYING_CODE)) … … 2151 2123 2152 2124 /* name */ 2153 if ((KU32)paSyms[iSym].n_un.n_strx >= cchStrings) 2154 return KLDR_ERR_MACHO_BAD_SYMBOL; 2125 KLDRMODMACHO_CHECK_RETURN((KU32)paSyms[iSym].n_un.n_strx < cchStrings, KLDR_ERR_MACHO_BAD_SYMBOL); 2155 2126 psz = &pchStrings[paSyms[iSym].n_un.n_strx]; 2156 2127 cch = kHlpStrLen(psz); … … 2167 2138 { 2168 2139 PKLDRMODMACHOSECT pSect; 2169 if ((KU32)(paSyms[iSym].n_sect - 1) >= pModMachO->cSections) 2170 return KLDR_ERR_MACHO_BAD_SYMBOL; 2140 KLDRMODMACHO_CHECK_RETURN((KU32)(paSyms[iSym].n_sect - 1) < pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL); 2171 2141 pSect = &pModMachO->paSections[paSyms[iSym].n_sect - 1]; 2172 2142 2173 uValue = paSyms[iSym].n_value - pModMachO->LinkAddress; 2174 if (uValue - pSect->RVA > pSect->cb) 2175 return KLDR_ERR_MACHO_BAD_SYMBOL; 2176 uValue += BaseAddress; 2143 uValue = paSyms[iSym].n_value - pSect->LinkAddress; 2144 KLDRMODMACHO_CHECK_RETURN( uValue <= pSect->cb 2145 || ( paSyms[iSym].n_sect == 1 /* special hack for __mh_execute_header */ 2146 && uValue == 0U - pSect->RVA 2147 && pModMachO->Hdr.filetype != MH_OBJECT), 2148 KLDR_ERR_MACHO_BAD_SYMBOL); 2149 uValue += BaseAddress + pSect->RVA; 2177 2150 2178 2151 if (pSect->fFlags & (S_ATTR_PURE_INSTRUCTIONS | S_ATTR_SELF_MODIFYING_CODE)) … … 2552 2525 2553 2526 /* Get the symbol name. */ 2554 if ((KU32)paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings) 2555 return KLDR_ERR_MACHO_BAD_SYMBOL; 2527 KLDRMODMACHO_CHECK_RETURN((KU32)paSyms[iSym].n_un.n_strx < pModMachO->cchStrings, KLDR_ERR_MACHO_BAD_SYMBOL); 2556 2528 pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx]; 2557 2529 cchSymbol = kHlpStrLen(pszSymbol); … … 2613 2585 2614 2586 /* Get the symbol name. */ 2615 if (paSyms[iSym].n_un.n_strx >= pModMachO->cchStrings) 2616 return KLDR_ERR_MACHO_BAD_SYMBOL; 2587 KLDRMODMACHO_CHECK_RETURN(paSyms[iSym].n_un.n_strx < pModMachO->cchStrings, KLDR_ERR_MACHO_BAD_SYMBOL); 2617 2588 pszSymbol = &pModMachO->pchStrings[paSyms[iSym].n_un.n_strx]; 2618 2589 cchSymbol = kHlpStrLen(pszSymbol); … … 2818 2789 { 2819 2790 PKLDRMODMACHOSECT pSymSect; 2820 if ((KU32)pSym->n_sect - 1 > pModMachO->cSections) 2821 return KLDR_ERR_MACHO_BAD_SYMBOL; 2791 KLDRMODMACHO_CHECK_RETURN((KU32)pSym->n_sect - 1 <= pModMachO->cSections, KLDR_ERR_MACHO_BAD_SYMBOL); 2822 2792 pSymSect = &pModMachO->paSections[pSym->n_sect - 1]; 2823 2793 … … 3074 3044 case MACHO_N_UNDF: 3075 3045 /* branch to an external symbol may have to take a short detour. */ 3076 if ( 3077 && SymAddr + Fixup.r.r_address + pFixupSect->RVA + NewBaseAddress3078 - pSym->n_value3079 + KU64_C(0x80000000)3046 if ( Fixup.r.r_type == X86_64_RELOC_BRANCH 3047 && SymAddr + Fixup.r.r_address + pFixupSect->RVA + NewBaseAddress 3048 - pSym->n_value 3049 + KU64_C(0x80000000) 3080 3050 >= KU64_C(0xffffff20)) 3081 3051 SymAddr += pModMachO->cbJmpStub * Fixup.r.r_symbolnum + pModMachO->JmpStubsRVA + NewBaseAddress;
Note:
See TracChangeset
for help on using the changeset viewer.