@@ -51,36 +51,68 @@ Error DexKit::InitFullCache() {
5151 return Error::SUCCESS;
5252}
5353
54+ static inline std::vector<uint32_t > ParseLogicalDexOffsets (const std::shared_ptr<MemMap> &image) {
55+ std::vector<uint32_t > offs;
56+ const uint8_t *base = image->data ();
57+ const size_t n = image->len ();
58+
59+ size_t off = 0 ;
60+ while (true ) {
61+ if (off + sizeof (dex::Header) > n) break ;
62+ const auto header = reinterpret_cast <const dex::Header *>(base + off);
63+ uint32_t sz = header->file_size ;
64+ if (sz < sizeof (dex::Header) || off + sz > n) break ;
65+ offs.push_back (static_cast <uint32_t >(off));
66+ off += sz;
67+ if (off >= n) break ;
68+ }
69+ return offs;
70+ }
71+
5472Error DexKit::AddDex (uint8_t *data, size_t size) {
5573 std::lock_guard lock (_mutex);
56- dex_items.emplace_back (std::make_unique<DexItem>(dex_cnt++, data, size, this ));
57- std::sort (dex_items.begin (), dex_items.end (), comp);
74+ images.emplace_back (std::make_shared<MemMap>(data, size));
75+ auto image = images.back ();
76+ for (auto off : ParseLogicalDexOffsets (image)) {
77+ dex_items.emplace_back (std::make_unique<DexItem>(dex_cnt++, image, off, this ));
78+ }
5879 return Error::SUCCESS;
5980}
6081
6182Error DexKit::AddImage (std::unique_ptr<MemMap> dex_image) {
6283 std::lock_guard lock (_mutex);
63- dex_items.emplace_back (std::make_unique<DexItem>(dex_cnt++, std::move (dex_image), this ));
64- std::sort (dex_items.begin (), dex_items.end (), comp);
84+ images.emplace_back (std::move (dex_image));
85+ auto image = images.back ();
86+ for (auto off : ParseLogicalDexOffsets (image)) {
87+ dex_items.emplace_back (std::make_unique<DexItem>(dex_cnt++, image, off, this ));
88+ }
6589 return Error::SUCCESS;
6690}
6791
6892Error DexKit::AddImage (std::vector<std::unique_ptr<MemMap>> dex_images) {
6993 std::lock_guard lock (_mutex);
70- auto old_size = dex_items.size ();
71- auto new_size = old_size + dex_images.size ();
72- dex_items.resize (new_size);
94+ const auto old_size = images.size ();
95+ const auto new_size = old_size + dex_images.size ();
96+ images.resize (new_size);
97+ std::vector<std::pair<std::shared_ptr<MemMap>, uint32_t >> add_items;
98+ for (auto i = old_size; i < new_size; i++) {
99+ images[i] = std::move (dex_images[i]);
100+ for (auto off : ParseLogicalDexOffsets (images[i])) {
101+ add_items.emplace_back (images[i], off);
102+ }
103+ }
104+ dex_items.resize (dex_items.size () + add_items.size ());
73105 {
74106 ThreadPool pool (_thread_num);
75107 auto index = old_size;
76- for (auto &dex_image: dex_images ) {
77- pool.enqueue ([this , &dex_image , index]() {
78- dex_items[index] = std::make_unique<DexItem>(index, std::move (dex_image) , this );
108+ for (auto &[image, offset]: add_items ) {
109+ pool.enqueue ([this , &image , index, offset ]() {
110+ dex_items[index] = std::make_unique<DexItem>(index, std::move (image), offset , this );
79111 });
80112 index++;
81113 }
82114 }
83- std::sort (dex_items. begin (), dex_items. end (), comp );
115+ dex_cnt += add_items. size ( );
84116 return Error::SUCCESS;
85117}
86118
@@ -91,39 +123,55 @@ Error DexKit::AddZipPath(std::string_view apk_path, int unzip_thread_num) {
91123 }
92124 auto zip_file = ZipArchive::Open (map);
93125 if (!zip_file) return Error::OPEN_ZIP_FILE_FAILED;
94- std::vector<std::pair<int , const Entry *>> dex_pairs ;
126+ std::vector<std::pair<int , const Entry *>> image_pairs ;
95127 for (int idx = 1 ;; ++idx) {
96128 auto entry_name = " classes" + (idx == 1 ? std::string () : std::to_string (idx)) + " .dex" ;
97129 auto entry = zip_file->Find (entry_name);
98130 if (!entry) {
99131 break ;
100132 }
101- dex_pairs .emplace_back (idx, entry);
133+ image_pairs .emplace_back (idx, entry);
102134 }
103- int old_size = ( int ) dex_items .size ();
104- int new_size = ( int ) ( old_size + dex_pairs .size () );
105- dex_items .resize (new_size);
135+ const auto old_size = images .size ();
136+ const auto new_size = old_size + image_pairs .size ();
137+ images .resize (new_size);
106138 {
107139 ThreadPool pool (unzip_thread_num == 0 ? _thread_num : unzip_thread_num);
108- for (auto &dex_pair: dex_pairs ) {
140+ for (auto &dex_pair: image_pairs ) {
109141 pool.enqueue ([this , &dex_pair, old_size, &zip_file]() {
110142 auto dex_image = zip_file->GetUncompressData (*dex_pair.second );
111143 auto ptr = std::make_unique<MemMap>(std::move (dex_image));
112144 if (!ptr->ok ()) {
113145 return ;
114146 }
115- int idx = old_size + dex_pair.first - 1 ;
116- dex_items [idx] = std::make_unique<DexItem>(idx, std:: move (ptr), this );
147+ auto idx = old_size + dex_pair.first - 1 ;
148+ images [idx] = std::move (ptr);
117149 });
118150 }
119151 }
120- dex_cnt += (uint32_t ) dex_pairs.size ();
152+ std::vector<std::pair<std::shared_ptr<MemMap>, uint32_t >> add_items;
153+ for (auto i = old_size; i < new_size; i++) {
154+ for (auto off : ParseLogicalDexOffsets (images[i])) {
155+ add_items.emplace_back (images[i], off);
156+ }
157+ }
158+ dex_items.resize (dex_items.size () + add_items.size ());
159+ {
160+ ThreadPool pool (_thread_num);
161+ auto index = old_size;
162+ for (auto &[image, offset]: add_items) {
163+ pool.enqueue ([this , &image, index, offset]() {
164+ dex_items[index] = std::make_unique<DexItem>(index, std::move (image), offset, this );
165+ });
166+ index++;
167+ }
168+ }
169+ dex_cnt += add_items.size ();
121170 return Error::SUCCESS;
122171}
123172
124- Error DexKit::ExportDexFile (std::string_view path) {
125- for (auto &dex_item: dex_items) {
126- auto image = dex_item->GetImage ();
173+ Error DexKit::ExportDexFile (std::string_view path) const {
174+ for (const auto &image: images) {
127175 std::string file_name (path);
128176 if (file_name.back () != ' /' ) {
129177 file_name += ' /' ;
0 commit comments