@@ -448,7 +448,7 @@ MachOHeader MachoView::HeaderForAddress(BinaryView* data, uint64_t address, bool
448448 sect.flags ,
449449 sect.reserved1 ,
450450 sect.reserved2 );
451- if (!strncmp (sect.sectname , " __mod_init_func" , 15 ))
451+ if (!strncmp (sect.sectname , " __mod_init_func" , 15 ) || ! strncmp (sect. sectname , " __init_offsets " , 14 ) )
452452 header.moduleInitSections .push_back (sect);
453453 if ((sect.flags & (S_ATTR_SELF_MODIFYING_CODE | S_SYMBOL_STUBS)) == (S_ATTR_SELF_MODIFYING_CODE | S_SYMBOL_STUBS))
454454 header.symbolStubSections .push_back (sect);
@@ -551,7 +551,7 @@ MachOHeader MachoView::HeaderForAddress(BinaryView* data, uint64_t address, bool
551551 sect.reserved1 ,
552552 sect.reserved2 ,
553553 sect.reserved3 );
554- if (!strncmp (sect.sectname , " __mod_init_func" , 15 ))
554+ if (!strncmp (sect.sectname , " __mod_init_func" , 15 ) || ! strncmp (sect. sectname , " __init_offsets " , 14 ) )
555555 header.moduleInitSections .push_back (sect);
556556 if ((sect.flags & (S_ATTR_SELF_MODIFYING_CODE | S_SYMBOL_STUBS)) == (S_ATTR_SELF_MODIFYING_CODE | S_SYMBOL_STUBS))
557557 header.symbolStubSections .push_back (sect);
@@ -1640,7 +1640,7 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
16401640
16411641 string type;
16421642 BNSectionSemantics semantics = DefaultSectionSemantics;
1643- switch (header.sections [i].flags & 0xff )
1643+ switch (header.sections [i].flags & SECTION_TYPE )
16441644 {
16451645 case S_REGULAR:
16461646 if (header.sections [i].flags & S_ATTR_PURE_INSTRUCTIONS)
@@ -1731,6 +1731,10 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
17311731 case S_THREAD_LOCAL_INIT_FUNCTION_POINTERS:
17321732 type = " THREAD_LOCAL_INIT_FUNCTION_POINTERS" ;
17331733 break ;
1734+ case S_INIT_FUNC_OFFSETS:
1735+ type = " INIT_FUNC_OFFSETS" ;
1736+ semantics = ReadOnlyDataSectionSemantics;
1737+ break ;
17341738 default :
17351739 type = " UNKNOWN" ;
17361740 break ;
@@ -1897,30 +1901,55 @@ bool MachoView::InitializeHeader(MachOHeader& header, bool isMainHeader, uint64_
18971901 if (find (threadStarts.begin (), threadStarts.end (), moduleInitSection.offset ) != threadStarts.end ())
18981902 continue ;
18991903
1900- // The mod_init section contains a list of function pointers called at initialization
1901- // if we don't have a defined entrypoint then use the first one in the list as the entrypoint
19021904 size_t i = 0 ;
19031905 reader.Seek (moduleInitSection.offset );
1904- for (; i < (moduleInitSection.size / m_addressSize); i++)
1906+
1907+ if (!strncmp (moduleInitSection.sectname , " __mod_init_func" , 15 ))
1908+ {
1909+ // The mod_init section contains a list of function pointers called at initialization
1910+ // if we don't have a defined entrypoint then use the first one in the list as the entrypoint
1911+ for (; i < (moduleInitSection.size / m_addressSize); i++)
1912+ {
1913+ uint64_t target = (m_addressSize == 4 ) ? reader.Read32 () : reader.Read64 ();
1914+ target += m_imageBaseAdjustment;
1915+ if (m_header.ident .filetype == MH_FILESET)
1916+ {
1917+ // FIXME: This isn't a super robust way of detagging,
1918+ // should look into xnu source and the tools used to build this cache (if they're public)
1919+ // and see if anything better can be done
1920+
1921+ // mask out top 8 bits
1922+ uint64_t tag = 0xFFFFFFFF00000000 & header.textBase ;
1923+ // and combine them with bottom 8 of the original entry
1924+ target = tag | (target & 0xFFFFFFFF );
1925+ }
1926+ Ref<Platform> targetPlatform = GetDefaultPlatform ()->GetAssociatedPlatformByAddress (target);
1927+ auto name = " mod_init_func_" + to_string (modInitFuncCnt++);
1928+ AddEntryPointForAnalysis (targetPlatform, target);
1929+ auto symbol = new Symbol (FunctionSymbol, name, target, GlobalBinding);
1930+ DefineAutoSymbol (symbol);
1931+ }
1932+ }
1933+ else if (!strncmp (moduleInitSection.sectname , " __init_offsets" , 14 ))
19051934 {
1906- uint64_t target = (m_addressSize == 4 ) ? reader. Read32 () : reader. Read64 ();
1907- target += m_imageBaseAdjustment;
1908- if (m_header. ident . filetype == MH_FILESET )
1935+ // The init_offsets section contains a list of 32-bit RVA offsets to functions called at initialization
1936+ // if we don't have a defined entrypoint then use the first one in the list as the entrypoint
1937+ for (; i < (moduleInitSection. size / 4 ); i++ )
19091938 {
1910- // FIXME: This isn't a super robust way of detagging,
1911- // should look into xnu source and the tools used to build this cache (if they're public)
1912- // and see if anything better can be done
1913-
1914- // mask out top 8 bits
1915- uint64_t tag = 0xFFFFFFFF00000000 & header.textBase ;
1916- // and combine them with bottom 8 of the original entry
1917- target = tag | (target & 0xFFFFFFFF );
1939+ uint64_t target = reader.Read32 ();
1940+ target += header.textBase ;
1941+ Ref<Platform> targetPlatform = GetDefaultPlatform ()->GetAssociatedPlatformByAddress (target);
1942+ auto name = " mod_init_func_" + to_string (modInitFuncCnt++);
1943+ AddEntryPointForAnalysis (targetPlatform, target);
1944+ auto symbol = new Symbol (FunctionSymbol, name, target, GlobalBinding);
1945+ DefineAutoSymbol (symbol);
1946+
1947+ // FIXME: i don't know how to define proper pointer type at this stage of analysis
1948+ Ref<Type> pointerVar = TypeBuilder::PointerType (4 , Type::VoidType ())
1949+ .SetPointerBase (RelativeToConstantPointerBaseType, header.textBase )
1950+ .Finalize ();
1951+ DefineDataVariable (GetStart () + reader.GetOffset () - 4 , pointerVar);
19181952 }
1919- Ref<Platform> targetPlatform = GetDefaultPlatform ()->GetAssociatedPlatformByAddress (target);
1920- auto name = " mod_init_func_" + to_string (modInitFuncCnt++);
1921- AddEntryPointForAnalysis (targetPlatform, target);
1922- auto symbol = new Symbol (FunctionSymbol, name, target, GlobalBinding);
1923- DefineAutoSymbol (symbol);
19241953 }
19251954 }
19261955
0 commit comments