Skip to content

Commit 31a9d1d

Browse files
committed
[MachoView] Add support of __init_offsets
1 parent 10a2c38 commit 31a9d1d

File tree

2 files changed

+52
-22
lines changed

2 files changed

+52
-22
lines changed

view/macho/machoview.cpp

+51-22
Original file line numberDiff line numberDiff line change
@@ -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

view/macho/machoview.h

+1
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ typedef int vm_prot_t;
144144
#define S_THREAD_LOCAL_VARIABLES 0x13
145145
#define S_THREAD_LOCAL_VARIABLE_POINTERS 0x14
146146
#define S_THREAD_LOCAL_INIT_FUNCTION_POINTERS 0x15
147+
#define S_INIT_FUNC_OFFSETS 0x16
147148

148149
//Mach-O Commands
149150
#define LC_REQ_DYLD 0x80000000

0 commit comments

Comments
 (0)