11#include " ObjC.h"
22
3+ #include " SharedCacheController.h"
4+
35using namespace BinaryNinja ;
46using namespace DSCObjC ;
57
6- DSCObjCReader::DSCObjCReader (VirtualMemoryReader reader, size_t addressSize) : m_reader(reader), m_addressSize(addressSize)
8+ SharedCacheObjCReader::SharedCacheObjCReader (VirtualMemoryReader reader, size_t addressSize) : m_reader(reader), m_addressSize(addressSize)
79{
810}
911
10- void DSCObjCReader ::Read (void * dest, size_t len)
12+ void SharedCacheObjCReader ::Read (void * dest, size_t len)
1113{
1214 m_reader.Read (dest, len);
1315}
1416
15- std::string DSCObjCReader ::ReadCString ()
17+ std::string SharedCacheObjCReader ::ReadCString ()
1618{
1719 return m_reader.ReadCString (m_reader.GetOffset ());
1820}
1921
20- uint8_t DSCObjCReader ::Read8 ()
22+ uint8_t SharedCacheObjCReader ::Read8 ()
2123{
2224 return m_reader.ReadUInt8 ();
2325}
2426
25- uint16_t DSCObjCReader ::Read16 ()
27+ uint16_t SharedCacheObjCReader ::Read16 ()
2628{
2729 return m_reader.ReadUInt16 ();
2830}
2931
30- uint32_t DSCObjCReader ::Read32 ()
32+ uint32_t SharedCacheObjCReader ::Read32 ()
3133{
3234 return m_reader.ReadUInt32 ();
3335}
3436
35- uint64_t DSCObjCReader ::Read64 ()
37+ uint64_t SharedCacheObjCReader ::Read64 ()
3638{
3739 return m_reader.ReadUInt64 ();
3840}
3941
40- int8_t DSCObjCReader ::ReadS8 ()
42+ int8_t SharedCacheObjCReader ::ReadS8 ()
4143{
4244 return m_reader.ReadInt8 ();
4345}
4446
45- int16_t DSCObjCReader ::ReadS16 ()
47+ int16_t SharedCacheObjCReader ::ReadS16 ()
4648{
4749 return m_reader.ReadInt16 ();
4850}
4951
50- int32_t DSCObjCReader ::ReadS32 ()
52+ int32_t SharedCacheObjCReader ::ReadS32 ()
5153{
5254 return m_reader.ReadInt32 ();
5355}
5456
55- int64_t DSCObjCReader ::ReadS64 ()
57+ int64_t SharedCacheObjCReader ::ReadS64 ()
5658{
5759 return m_reader.ReadInt64 ();
5860}
5961
60- uint64_t DSCObjCReader ::ReadPointer ()
62+ uint64_t SharedCacheObjCReader ::ReadPointer ()
6163{
6264 return m_reader.ReadPointer ();
6365}
6466
65- uint64_t DSCObjCReader ::GetOffset () const
67+ uint64_t SharedCacheObjCReader ::GetOffset () const
6668{
6769 return m_reader.GetOffset ();
6870}
6971
70- void DSCObjCReader ::Seek (uint64_t offset)
72+ void SharedCacheObjCReader ::Seek (uint64_t offset)
7173{
7274 m_reader.Seek (offset);
7375}
7476
75- void DSCObjCReader ::SeekRelative (int64_t offset)
77+ void SharedCacheObjCReader ::SeekRelative (int64_t offset)
7678{
7779 m_reader.SeekRelative (offset);
7880}
7981
80- VirtualMemoryReader& DSCObjCReader ::GetVMReader ()
82+ VirtualMemoryReader& SharedCacheObjCReader ::GetVMReader ()
8183{
8284 return m_reader;
8385}
8486
85- std::shared_ptr<ObjCReader> DSCObjCProcessor ::GetReader ()
87+ std::shared_ptr<ObjCReader> SharedCacheObjCProcessor ::GetReader ()
8688{
87- auto reader = VirtualMemoryReader (m_cache->GetVirtualMemory ());
88- return std::make_shared<DSCObjCReader>(reader, m_data->GetAddressSize ());
89+ const auto controller = DSC::SharedCacheController::FromView (*m_data);
90+ // TODO: This should never happen.
91+ if (!controller)
92+ throw std::runtime_error (" SharedCacheController not found for SharedCacheObjCProcessor::GetReader!" );
93+ auto reader = VirtualMemoryReader (controller->GetCache ().GetVirtualMemory ());
94+ return std::make_shared<SharedCacheObjCReader>(reader, m_data->GetAddressSize ());
8995}
9096
91- void DSCObjCProcessor ::GetRelativeMethod (ObjCReader* reader, method_t & meth)
97+ void SharedCacheObjCProcessor ::GetRelativeMethod (ObjCReader* reader, method_t & meth)
9298{
9399 if (m_customRelativeMethodSelectorBase.has_value ())
94100 {
@@ -102,12 +108,12 @@ void DSCObjCProcessor::GetRelativeMethod(ObjCReader* reader, method_t& meth)
102108 }
103109}
104110
105- std::optional<ObjCOptimizationHeader> DSCObjCProcessor:: GetObjCOptimizationHeader (VirtualMemoryReader &reader) const
111+ std::optional<ObjCOptimizationHeader> GetObjCOptimizationHeader (SharedCache& cache, VirtualMemoryReader &reader)
106112{
107113 // Find the first primary entry and use that header to read the obj opt header.
108114 // Don't ask me why this is done like this...
109115 std::optional<dyld_cache_header> primaryCacheHeader = std::nullopt ;
110- for (const auto & [_, entry] : m_cache-> GetEntries ())
116+ for (const auto & [_, entry] : cache. GetEntries ())
111117 {
112118 if (entry.GetType () == CacheEntryType::Primary)
113119 {
@@ -122,21 +128,28 @@ std::optional<ObjCOptimizationHeader> DSCObjCProcessor::GetObjCOptimizationHeade
122128
123129 ObjCOptimizationHeader header = {};
124130 // Ignoring `objcOptsSize` in favor of `sizeof(ObjCOptimizationHeader)` matches dyld's behavior.
125- reader.Read (&header, m_cache-> GetBaseAddress () + primaryCacheHeader->objcOptsOffset , sizeof (ObjCOptimizationHeader));
131+ reader.Read (&header, cache. GetBaseAddress () + primaryCacheHeader->objcOptsOffset , sizeof (ObjCOptimizationHeader));
126132
127133 return header;
128134}
129135
130- uint64_t DSCObjCProcessor ::GetObjCRelativeMethodBaseAddress (ObjCReader* reader)
136+ uint64_t SharedCacheObjCProcessor ::GetObjCRelativeMethodBaseAddress (ObjCReader* reader)
131137{
132- // TODO: This is a silly.
133- auto dangerReader = dynamic_cast <DSCObjCReader*>(reader)->GetVMReader ();
134- if (const auto header = GetObjCOptimizationHeader (dangerReader); header.has_value ())
135- m_customRelativeMethodSelectorBase = m_cache->GetBaseAddress () + header->relativeMethodSelectorBaseAddressOffset ;
138+ // Try and retrieve the base address of the selector stuff.
139+ if (const auto controller = DSC::SharedCacheController::FromView (*m_data))
140+ {
141+ auto baseAddress = controller->GetCache ().GetBaseAddress ();
142+ auto dangerReader = dynamic_cast <SharedCacheObjCReader*>(reader)->GetVMReader ();
143+ if (const auto header = GetObjCOptimizationHeader (controller->GetCache (), dangerReader); header.has_value ())
144+ {
145+ m_customRelativeMethodSelectorBase = baseAddress + header->relativeMethodSelectorBaseAddressOffset ;
146+ }
147+ }
148+
136149 return m_customRelativeMethodSelectorBase.value_or (0 );
137150}
138151
139- DSCObjCProcessor::DSCObjCProcessor (BinaryView* data, SharedCache* cache , bool isBackedByDatabase) :
140- ObjCProcessor(data, " SharedCache.ObjC" , isBackedByDatabase, true ), m_cache(cache)
152+ SharedCacheObjCProcessor::SharedCacheObjCProcessor (BinaryView* data, bool isBackedByDatabase) :
153+ ObjCProcessor(data, " SharedCache.ObjC" , isBackedByDatabase, true )
141154{
142155}
0 commit comments