20
20
import jadx .api .plugins .utils .CommonFileUtils ;
21
21
import jadx .api .plugins .utils .ZipSecurity ;
22
22
import jadx .plugins .input .dex .sections .DexConsts ;
23
+ import jadx .plugins .input .dex .sections .DexHeaderV41 ;
23
24
import jadx .plugins .input .dex .utils .DexCheckSum ;
24
25
25
26
public class DexFileLoader {
@@ -63,8 +64,7 @@ private List<DexReader> load(@Nullable File file, InputStream inputStream, Strin
63
64
if (isStartWithBytes (magic , DexConsts .DEX_FILE_MAGIC ) || fileName .endsWith (".dex" )) {
64
65
in .reset ();
65
66
byte [] content = readAllBytes (in );
66
- DexReader dexReader = loadDexReader (fileName , content );
67
- return Collections .singletonList (dexReader );
67
+ return loadDexReaders (fileName , content );
68
68
}
69
69
if (file != null ) {
70
70
// allow only top level zip files
@@ -76,11 +76,32 @@ private List<DexReader> load(@Nullable File file, InputStream inputStream, Strin
76
76
}
77
77
}
78
78
79
- public DexReader loadDexReader (String fileName , byte [] content ) {
79
+ public List <DexReader > loadDexReaders (String fileName , byte [] content ) {
80
+ DexHeaderV41 dexHeaderV41 = DexHeaderV41 .readIfPresent (content );
81
+ if (dexHeaderV41 != null ) {
82
+ return DexHeaderV41 .readSubDexOffsets (content , dexHeaderV41 )
83
+ .stream ()
84
+ .map (offset -> loadSingleDex (fileName , content , offset ))
85
+ .collect (Collectors .toList ());
86
+ }
87
+ DexReader dexReader = loadSingleDex (fileName , content , 0 );
88
+ return Collections .singletonList (dexReader );
89
+ }
90
+
91
+ private DexReader loadSingleDex (String fileName , byte [] content , int offset ) {
80
92
if (options .isVerifyChecksum ()) {
81
- DexCheckSum .verify (content , fileName );
93
+ DexCheckSum .verify (fileName , content , offset );
82
94
}
83
- return new DexReader (getNextUniqId (), fileName , content );
95
+ return new DexReader (getNextUniqId (), fileName , content , offset );
96
+ }
97
+
98
+ /**
99
+ * Since DEX v41, several sub DEX structures can be stored inside container of a single DEX file
100
+ * Use {@link DexFileLoader#loadDexReaders(String, byte[])} instead.
101
+ */
102
+ @ Deprecated
103
+ public DexReader loadDexReader (String fileName , byte [] content ) {
104
+ return loadSingleDex (fileName , content , 0 );
84
105
}
85
106
86
107
private List <DexReader > collectDexFromZip (File file ) {
0 commit comments