@@ -432,6 +432,8 @@ int AllocLoadElfMemory(box64context_t* context, elfheader_t* head, int mainbin)
432432 head -> file = NULL ;
433433 head -> fileno = -1 ;
434434
435+ PatchLoadedDynamicSection (head );
436+
435437 return 0 ;
436438}
437439
@@ -1474,6 +1476,141 @@ void* GetDynamicSection(elfheader_t* h)
14741476 return box64_is32bits ?((void * )h -> Dynamic ._32 ):((void * )h -> Dynamic ._64 );
14751477}
14761478
1479+ typedef struct {
1480+ void * addr ;
1481+ size_t size ;
1482+ } dynamic_info_t ;
1483+
1484+ static int GetLoadedDynamicInfo (elfheader_t * h , dynamic_info_t * info )
1485+ {
1486+ if (!h ) return 0 ;
1487+ if (box64_is32bits ) {
1488+ for (int i = 0 ; i < h -> numPHEntries ; i ++ ) {
1489+ if (h -> PHEntries ._32 [i ].p_type == PT_DYNAMIC ) {
1490+ info -> addr = (void * )(h -> delta + h -> PHEntries ._32 [i ].p_vaddr );
1491+ info -> size = h -> PHEntries ._32 [i ].p_memsz ;
1492+ return 1 ;
1493+ }
1494+ }
1495+ } else {
1496+ for (int i = 0 ; i < h -> numPHEntries ; i ++ ) {
1497+ if (h -> PHEntries ._64 [i ].p_type == PT_DYNAMIC ) {
1498+ info -> addr = (void * )(h -> delta + h -> PHEntries ._64 [i ].p_vaddr );
1499+ info -> size = h -> PHEntries ._64 [i ].p_memsz ;
1500+ return 1 ;
1501+ }
1502+ }
1503+ }
1504+ return 0 ;
1505+ }
1506+
1507+ void * GetLoadedDynamicSection (elfheader_t * h )
1508+ {
1509+ dynamic_info_t info ;
1510+ if (GetLoadedDynamicInfo (h , & info ))
1511+ return info .addr ;
1512+ return NULL ;
1513+ }
1514+
1515+ static int isDynamicTagPointer (int tag )
1516+ {
1517+ switch (tag ) {
1518+ case DT_PLTGOT :
1519+ case DT_HASH :
1520+ case DT_STRTAB :
1521+ case DT_SYMTAB :
1522+ case DT_RELA :
1523+ case DT_REL :
1524+ case DT_RELR :
1525+ case DT_DEBUG :
1526+ case DT_JMPREL :
1527+ case DT_INIT :
1528+ case DT_FINI :
1529+ case DT_INIT_ARRAY :
1530+ case DT_FINI_ARRAY :
1531+ case DT_PREINIT_ARRAY :
1532+ case DT_VERNEED :
1533+ case DT_VERDEF :
1534+ case DT_VERSYM :
1535+ #ifdef DT_GNU_HASH
1536+ case DT_GNU_HASH :
1537+ #else
1538+ case 0x6ffffef5 :
1539+ #endif
1540+ #ifdef DT_TLSDESC_PLT
1541+ case DT_TLSDESC_PLT :
1542+ #else
1543+ case 0x6ffffef6 :
1544+ #endif
1545+ #ifdef DT_TLSDESC_GOT
1546+ case DT_TLSDESC_GOT :
1547+ #else
1548+ case 0x6ffffef7 :
1549+ #endif
1550+ return 1 ;
1551+ default :
1552+ return 0 ;
1553+ }
1554+ }
1555+
1556+ void PatchLoadedDynamicSection (elfheader_t * h )
1557+ {
1558+ if (!h || !h -> delta || h -> dynamic_patched )
1559+ return ;
1560+
1561+ dynamic_info_t dyninfo ;
1562+ if (!GetLoadedDynamicInfo (h , & dyninfo ))
1563+ return ;
1564+
1565+ uintptr_t dyn_addr = (uintptr_t )dyninfo .addr ;
1566+ uintptr_t dyn_size = dyninfo .size ;
1567+
1568+ uintptr_t page_addr = dyn_addr & ~(box64_pagesize - 1 );
1569+ uintptr_t page_end = (dyn_addr + dyn_size + box64_pagesize - 1 ) & ~(box64_pagesize - 1 );
1570+
1571+ int need_restore = 0 ;
1572+ for (uintptr_t page = page_addr ; page < page_end ; page += box64_pagesize ) {
1573+ uint32_t old_prot = getProtection (page );
1574+ if (old_prot && !(old_prot & PROT_WRITE )) {
1575+ if (mprotect ((void * )page , box64_pagesize , (old_prot | PROT_WRITE ) & ~PROT_CUSTOM )) {
1576+ for (uintptr_t restore = page_addr ; restore < page ; restore += box64_pagesize ) {
1577+ uint32_t restore_prot = getProtection (restore );
1578+ if (restore_prot && !(restore_prot & PROT_WRITE ))
1579+ mprotect ((void * )restore , box64_pagesize , restore_prot & ~PROT_CUSTOM );
1580+ }
1581+ return ;
1582+ }
1583+ need_restore = 1 ;
1584+ }
1585+ }
1586+
1587+ if (box64_is32bits ) {
1588+ Elf32_Dyn * dyn = (Elf32_Dyn * )dyn_addr ;
1589+ for (int j = 0 ; dyn [j ].d_tag != DT_NULL ; j ++ ) {
1590+ if (isDynamicTagPointer (dyn [j ].d_tag ) && dyn [j ].d_un .d_ptr ) {
1591+ dyn [j ].d_un .d_ptr += h -> delta ;
1592+ }
1593+ }
1594+ } else {
1595+ Elf64_Dyn * dyn = (Elf64_Dyn * )dyn_addr ;
1596+ for (int j = 0 ; dyn [j ].d_tag != DT_NULL ; j ++ ) {
1597+ if (isDynamicTagPointer (dyn [j ].d_tag ) && dyn [j ].d_un .d_ptr ) {
1598+ dyn [j ].d_un .d_ptr += h -> delta ;
1599+ }
1600+ }
1601+ }
1602+
1603+ if (need_restore ) {
1604+ for (uintptr_t page = page_addr ; page < page_end ; page += box64_pagesize ) {
1605+ uint32_t old_prot = getProtection (page );
1606+ if (old_prot && !(old_prot & PROT_WRITE ))
1607+ mprotect ((void * )page , box64_pagesize , old_prot & ~PROT_CUSTOM );
1608+ }
1609+ }
1610+
1611+ h -> dynamic_patched = 1 ;
1612+ }
1613+
14771614typedef struct my_dl_phdr_info_s {
14781615 void * dlpi_addr ;
14791616 const char * dlpi_name ;
@@ -1973,4 +2110,4 @@ const char* getAddrFunctionName(uintptr_t addr)
19732110 }
19742111 }
19752112 return ret ;
1976- }
2113+ }
0 commit comments