Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
J
jadx
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
open-source
jadx
Commits
e01789bb
Commit
e01789bb
authored
Dec 21, 2014
by
YASME-Tim
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added first implementation of the AndroidManifest XML Parser
parent
a26d7b5a
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
192 additions
and
0 deletions
+192
-0
JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+5
-0
BinaryXMLParser.java
...-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
+187
-0
No files found.
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
View file @
e01789bb
...
...
@@ -8,10 +8,15 @@ import java.io.File;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.xmlgen.BinaryXMLParser
;
public
class
JadxCLI
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxCLI
.
class
);
public
static
void
main
(
String
[]
args
)
throws
JadxException
{
BinaryXMLParser
bxp
=
new
BinaryXMLParser
(
args
[
0
]);
bxp
.
parse
();
System
.
exit
(
4
);
try
{
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
();
if
(
processArgs
(
jadxArgs
,
args
))
{
...
...
jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
0 → 100644
View file @
e01789bb
package
jadx
.
core
.
xmlgen
;
import
java.nio.ByteBuffer
;
import
java.nio.charset.Charset
;
import
java.io.BufferedInputStream
;
import
java.io.File
;
import
java.io.FileInputStream
;
import
java.io.FileNotFoundException
;
import
java.io.InputStream
;
import
java.io.IOException
;
import
java.io.UnsupportedEncodingException
;
public
class
BinaryXMLParser
{
private
byte
[]
bytes
;
private
String
[]
strings
;
private
int
count
;
private
String
nsPrefix
=
"ERROR"
;
public
BinaryXMLParser
(
String
xmlfilepath
)
{
System
.
out
.
println
(
xmlfilepath
);
File
manifest
=
new
File
(
xmlfilepath
);
if
(
null
==
manifest
)
die
(
"null==manifest"
);
bytes
=
new
byte
[(
int
)
manifest
.
length
()];
try
{
InputStream
is
=
null
;
try
{
is
=
new
BufferedInputStream
(
new
FileInputStream
(
manifest
));
int
total
=
0
;
while
(
total
<
bytes
.
length
)
{
int
remain
=
bytes
.
length
-
total
;
int
read
=
is
.
read
(
bytes
,
total
,
remain
);
if
(
read
>
0
)
total
+=
read
;
}
}
finally
{
is
.
close
();
}
}
catch
(
FileNotFoundException
fnfe
)
{
die
(
"FILE NOT FOUND"
);
}
catch
(
IOException
ioe
)
{
die
(
"IOE"
);
}
count
=
0
;
}
public
void
parse
()
{
if
(
cInt16
(
bytes
,
count
)
!=
0x0003
)
die
(
"Version is not 3"
);
if
(
cInt16
(
bytes
,
count
)
!=
0x0008
)
die
(
"Size of header is not 8"
);
if
(
cInt32
(
bytes
,
count
)
!=
bytes
.
length
)
die
(
"Size of manifest doesn't match"
);
while
(
true
)
{
int
type
=
cInt16
(
bytes
,
count
);
if
(
type
==
0x0001
)
parseStringPool
();
else
if
(
type
==
0x0180
)
parseResourceMap
();
else
if
(
type
==
0x0100
)
parseNameSpace
();
else
if
(
type
==
0x0102
)
parseElement
();
else
die
(
"Type: "
+
Integer
.
toHexString
(
type
)
+
" not yet implemented"
);
System
.
out
.
println
(
"COUNT: "
+
Integer
.
toHexString
(
count
));
}
//die("Done");
}
private
void
parseStringPool
()
{
if
(
cInt16
(
bytes
,
count
)
!=
0x001c
)
die
(
"Header header size not 28"
);
int
hsize
=
cInt32
(
bytes
,
count
);
int
stringCount
=
cInt32
(
bytes
,
count
);
int
styleCount
=
cInt32
(
bytes
,
count
);
int
flags
=
cInt32
(
bytes
,
count
);
int
stringsStart
=
cInt32
(
bytes
,
count
);
int
stylesStart
=
cInt32
(
bytes
,
count
);
/*
System.out.println(hsize);
System.out.println(stringCount);
System.out.println(styleCount);
System.out.println(flags);
System.out.println(stringsStart);
System.out.println(stylesStart);
*/
int
[]
stringsOffsets
=
new
int
[
stringCount
];
for
(
int
i
=
0
;
i
<
stringCount
;
i
++)
{
stringsOffsets
[
i
]
=
cInt32
(
bytes
,
count
);
//System.out.println("i["+i+"]: " + stringsOffsets[i]);
}
strings
=
new
String
[
stringCount
];
for
(
int
i
=
0
;
i
<
stringCount
;
i
++)
{
int
off
=
8
+
stringsStart
+
stringsOffsets
[
i
];
int
strlen
=
cInt16
(
bytes
,
off
);
//System.out.println("strlen: " + strlen);
byte
[]
str
=
new
byte
[
strlen
*
2
];
System
.
arraycopy
(
bytes
,
count
,
str
,
0
,
strlen
*
2
);
count
+=
strlen
*
2
;
strings
[
i
]
=
new
String
(
str
,
Charset
.
forName
(
"UTF-16LE"
));
System
.
out
.
println
(
"index i["
+
i
+
"] string: "
+
strings
[
i
]);
count
+=
2
;
}
}
private
void
parseResourceMap
()
{
if
(
cInt16
(
bytes
,
count
)
!=
0x8
)
die
(
"Header size of resmap is not 8!"
);
int
rhsize
=
cInt32
(
bytes
,
count
);
System
.
out
.
println
(
"RHeader Size: "
+
rhsize
);
int
[]
ids
=
new
int
[(
rhsize
-
8
)/
4
];
for
(
int
i
=
0
;
i
<
ids
.
length
;
i
++)
{
ids
[
i
]=
cInt32
(
bytes
,
count
);
System
.
out
.
println
(
"i["
+
i
+
"] ID: "
+
ids
[
i
]);
System
.
out
.
println
(
"Hex: 0x0"
+
Integer
.
toHexString
(
ids
[
i
])
+
" should be: "
+
strings
[
i
]);
}
}
private
void
parseNameSpace
()
{
if
(
cInt16
(
bytes
,
count
)
!=
0x0010
)
die
(
"NAMESPACE header is not 0x0010"
);
if
(
cInt32
(
bytes
,
count
)
!=
0x18
)
die
(
"NAMESPACE header chunk is not 0x18 big"
);
int
beginLineNumber
=
cInt32
(
bytes
,
count
);
if
(
beginLineNumber
!=
2
)
die
(
"NAMESPACE beginning line number != 2 not supported yet"
);
System
.
out
.
println
(
"Comment: 0x"
+
Integer
.
toHexString
(
cInt32
(
bytes
,
count
)));
int
beginPrefix
=
cInt32
(
bytes
,
count
);
System
.
out
.
println
(
"Prefix: "
+
strings
[
beginPrefix
]);
nsPrefix
=
strings
[
beginPrefix
];
int
beginURI
=
cInt32
(
bytes
,
count
);
System
.
out
.
println
(
"URI: "
+
strings
[
beginURI
]);
System
.
out
.
println
(
"COUNT: "
+
Integer
.
toHexString
(
count
));
}
private
void
parseElement
()
{
if
(
cInt16
(
bytes
,
count
)
!=
0x0010
)
die
(
"ELEMENT HEADER SIZE is not 0x10"
);
if
(
cInt32
(
bytes
,
count
)
!=
0x0060
)
die
(
"ELEMENT CHUNK SIZE is not 0x60"
);
int
elementLineNumber
=
cInt32
(
bytes
,
count
);
System
.
out
.
println
(
"elementLineNumber: "
+
elementLineNumber
);
System
.
out
.
println
(
"Comment: 0x"
+
Integer
.
toHexString
(
cInt32
(
bytes
,
count
)));
System
.
out
.
println
(
"COUNT: "
+
Integer
.
toHexString
(
count
));
int
startNS
=
cInt32
(
bytes
,
count
);
System
.
out
.
println
(
"Namespace: 0x"
+
Integer
.
toHexString
(
startNS
));
int
startNSName
=
cInt32
(
bytes
,
count
);
// what to do with this id?
System
.
out
.
println
(
"Namespace name: "
+
strings
[
startNSName
]);
int
attributeStart
=
cInt16
(
bytes
,
count
);
if
(
attributeStart
!=
0x14
)
die
(
"startNS's attributeStart is not 0x14"
);
int
attributeSize
=
cInt16
(
bytes
,
count
);
if
(
attributeSize
!=
0x14
)
die
(
"startNS's attributeSize is not 0x14"
);
int
attributeCount
=
cInt16
(
bytes
,
count
);
System
.
out
.
println
(
"startNS: attributeCount: "
+
attributeCount
);
int
idIndex
=
cInt16
(
bytes
,
count
);
System
.
out
.
println
(
"startNS: idIndex: "
+
idIndex
);
int
classIndex
=
cInt16
(
bytes
,
count
);
System
.
out
.
println
(
"startNS: classIndex: "
+
classIndex
);
int
styleIndex
=
cInt16
(
bytes
,
count
);
System
.
out
.
println
(
"startNS: styleIndex: "
+
styleIndex
);
for
(
int
i
=
0
;
i
<
attributeCount
;
i
++)
{
int
attributeNS
=
cInt32
(
bytes
,
count
);
int
attributeName
=
cInt32
(
bytes
,
count
);
int
attributeRawValue
=
cInt32
(
bytes
,
count
);
int
attrValSize
=
cInt16
(
bytes
,
count
);
//System.out.println(attrValSize);
if
(
attrValSize
!=
0x08
)
die
(
"attrValSize != 0x08 not supported"
);
if
(
cInt8
(
bytes
,
count
)
!=
0
)
die
(
"res0 is not 0"
);
int
attrValDataType
=
cInt8
(
bytes
,
count
);
int
attrValData
=
cInt32
(
bytes
,
count
);
System
.
out
.
println
(
"ai["
+
i
+
"] ns: "
+
attributeNS
);
System
.
out
.
println
(
"ai["
+
i
+
"] name: "
+
attributeName
);
System
.
out
.
println
(
"ai["
+
i
+
"] rawval: "
+
attributeRawValue
);
System
.
out
.
println
(
"ai["
+
i
+
"] dt: "
+
attrValDataType
);
System
.
out
.
println
(
"ai["
+
i
+
"] d: "
+
attrValData
);
if
(
attributeNS
!=
-
1
)
System
.
out
.
print
(
nsPrefix
+
":"
);
if
(
attrValDataType
==
0x3
)
System
.
out
.
println
(
strings
[
attributeName
]
+
"="
+
strings
[
attrValData
]);
else
if
(
attrValDataType
==
0x10
)
System
.
out
.
println
(
strings
[
attributeName
]
+
"="
+
attrValData
);
else
System
.
out
.
println
(
"UNKNOWN DATA TYPE: "
+
attrValDataType
);
}
}
private
int
cInt8
(
byte
[]
bytes
,
int
offset
)
{
byte
[]
tmp
=
new
byte
[
4
];
tmp
[
3
]=
bytes
[
count
++];
return
ByteBuffer
.
wrap
(
tmp
).
getInt
();
}
private
int
cInt16
(
byte
[]
bytes
,
int
offset
)
{
byte
[]
tmp
=
new
byte
[
4
];
tmp
[
3
]=
bytes
[
count
++];
tmp
[
2
]=
bytes
[
count
++];
return
ByteBuffer
.
wrap
(
tmp
).
getInt
();
}
private
int
cInt32
(
byte
[]
bytes
,
int
offset
)
{
byte
[]
tmp
=
new
byte
[
4
];
for
(
int
i
=
0
;
i
<
4
;
i
++)
tmp
[
3
-
i
]=
bytes
[
count
+
i
];
count
+=
4
;
return
ByteBuffer
.
wrap
(
tmp
).
getInt
();
}
private
void
die
(
String
message
)
{
System
.
err
.
println
(
message
);
System
.
exit
(
3
);
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment