Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
colcode
jadx
提交
b55975a3
J
jadx
项目概览
colcode
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
b55975a3
编写于
12月 23, 2014
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
core: reformat code and fix small issues in BinaryXMLParser
上级
4cb34394
变更
7
展开全部
隐藏空白更改
内联
并排
Showing
7 changed file
with
2081 addition
and
178 deletion
+2081
-178
build.gradle
build.gradle
+0
-1
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+0
-7
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+1
-1
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
+9
-6
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
+4
-2
jadx-core/src/main/java/jadx/core/xmlgen/AndroidR.java
jadx-core/src/main/java/jadx/core/xmlgen/AndroidR.java
+1860
-0
jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
...-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
+207
-161
未找到文件。
build.gradle
浏览文件 @
b55975a3
...
...
@@ -41,7 +41,6 @@ subprojects {
}
dependencies
{
compile
'com.google.android:android:4.1.1.4'
compile
'org.slf4j:slf4j-api:1.7.7'
testCompile
'ch.qos.logback:logback-classic:1.1.2'
...
...
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
浏览文件 @
b55975a3
...
...
@@ -8,17 +8,10 @@ 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],args[1]);
bxp.parse();
System.exit(4);
*/
try
{
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
();
if
(
processArgs
(
jadxArgs
,
args
))
{
...
...
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
浏览文件 @
b55975a3
...
...
@@ -47,7 +47,7 @@ public final class JadxCLIArgs implements IJadxArgs {
@Parameter
(
names
=
{
"-h"
,
"--help"
},
description
=
"print this help"
,
help
=
true
)
protected
boolean
printHelp
=
false
;
@Parameter
(
names
=
{
"-x"
,
"--xml"
},
description
=
"try to decode the AndroidManifest.xml
, save at current dir
"
)
@Parameter
(
names
=
{
"-x"
,
"--xml"
},
description
=
"try to decode the AndroidManifest.xml"
)
protected
boolean
xmlTest
=
false
;
private
final
List
<
File
>
input
=
new
ArrayList
<
File
>(
1
);
...
...
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
浏览文件 @
b55975a3
...
...
@@ -203,14 +203,17 @@ public final class JadxDecompiler {
reset
();
root
=
new
RootNode
();
LOG
.
info
(
"loading ..."
);
if
(
this
.
args
.
isXMLTest
())
{
if
(
this
.
args
.
isXMLTest
())
{
InputFile
inf
=
inputFiles
.
get
(
0
);
try
{
BinaryXMLParser
bxp
=
new
BinaryXMLParser
(
InputFile
.
loadXMLBuffer
(
inf
.
getFile
()),
"./AndroidManifest.xml"
);
//BinaryXMLParser bxp = new BinaryXMLParser(InputFile.loadXMLBuffer(inf.getFile()), "AndroidManifest.xml");
bxp
.
parse
();
}
catch
(
IOException
ioe
)
{
LOG
.
info
(
"Decompiling AndroidManifest.xml failed!"
);
byte
[]
buffer
=
InputFile
.
loadXMLBuffer
(
inf
.
getFile
());
if
(
buffer
!=
null
)
{
File
out
=
new
File
(
args
.
getOutDir
(),
"AndroidManifest.xml"
);
BinaryXMLParser
bxp
=
new
BinaryXMLParser
();
bxp
.
parse
(
buffer
,
out
);
}
}
catch
(
Exception
e
)
{
LOG
.
info
(
"Decompiling AndroidManifest.xml failed!"
,
e
);
}
}
root
.
load
(
inputFiles
);
...
...
jadx-core/src/main/java/jadx/core/utils/files/InputFile.java
浏览文件 @
b55975a3
...
...
@@ -77,7 +77,7 @@ public class InputFile {
public
static
byte
[]
loadXMLBuffer
(
File
file
)
throws
IOException
{
// FIXME: Public.. Please fix
ZipFile
zf
=
new
ZipFile
(
file
);
ZipEntry
xml
=
zf
.
getEntry
(
"AndroidManifest.xml"
);
if
(
null
==
xm
l
)
{
if
(
xml
==
nul
l
)
{
zf
.
close
();
return
null
;
}
...
...
@@ -91,7 +91,9 @@ public class InputFile {
bytesOut
.
write
(
buffer
,
0
,
count
);
}
}
finally
{
if
(
null
!=
in
)
in
.
close
();
if
(
null
!=
in
)
{
in
.
close
();
}
zf
.
close
();
}
return
bytesOut
.
toByteArray
();
...
...
jadx-core/src/main/java/jadx/core/xmlgen/AndroidR.java
0 → 100644
浏览文件 @
b55975a3
此差异已折叠。
点击以展开。
jadx-core/src/main/java/jadx/core/xmlgen/BinaryXMLParser.java
浏览文件 @
b55975a3
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
;
import
java.io.PrintWriter
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
java.io.File
;
import
java.lang.reflect.Field
;
import
java.nio.ByteBuffer
;
import
java.nio.charset.Charset
;
import
java.util.HashMap
;
import
java.util.Map
;
import
android.R.style
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/* TODO:
Don't die when error occurs
Check error cases, maybe checked const values are not always the same
Better error messages
What to do, when Binary XML Manifest is > size(int)?
Check for miss
u
ng chunk size types
Check for miss
i
ng chunk size types
Implement missing data types
Use linenumbers to recreate EXACT AndroidManifest
Use line
numbers to recreate EXACT AndroidManifest
Check Element chunk size
*/
public
class
BinaryXMLParser
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
BinaryXMLParser
.
class
);
private
byte
[]
bytes
;
private
String
[]
strings
;
private
int
count
;
private
String
nsPrefix
=
"ERROR"
;
private
String
nsURI
=
"ERROR"
;
private
String
currentTag
=
"ERROR"
;
private
int
numtabs
=-
1
;
private
boolean
wasOneLiner
=
false
;
private
PrintWriter
writer
;
private
String
nsPrefix
=
"ERROR"
;
private
String
nsURI
=
"ERROR"
;
private
String
currentTag
=
"ERROR"
;
private
boolean
firstElement
;
private
boolean
wasOneLiner
=
false
;
private
CodeWriter
writer
;
private
Map
<
Integer
,
String
>
styleMap
=
null
;
public
BinaryXMLParser
(
String
xmlfilepath
,
String
xmloutfilepath
)
{
try
{
writer
=
new
PrintWriter
(
xmloutfilepath
,
"UTF-8"
);
}
catch
(
FileNotFoundException
fnfe
)
{
die
(
"FNFE"
);
}
catch
(
UnsupportedEncodingException
uee
)
{
die
(
"UEE"
);
}
if
(
null
==
writer
)
die
(
"null==writer"
);
writer
.
println
(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
);
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
BinaryXMLParser
()
{
styleMap
=
new
HashMap
<
Integer
,
String
>();
if
(
null
==
styleMap
)
die
(
"null==styleMap"
);
for
(
Field
f
:
android
.
R
.
style
.
class
.
getFields
())
{
try
{
styleMap
.
put
(
f
.
getInt
(
f
.
getType
()),
f
.
getName
());
}
catch
(
IllegalAccessException
iae
)
{
die
(
"IAE"
);
try
{
for
(
Field
f
:
AndroidR
.
style
.
class
.
getFields
())
{
styleMap
.
put
(
f
.
getInt
(
f
.
getType
()),
f
.
getName
());
}
//TODO: also add application constant fields
}
catch
(
IllegalAccessException
e
)
{
throw
new
JadxRuntimeException
(
"BinaryXMLParser init error"
,
e
);
}
}
public
BinaryXMLParser
(
byte
[]
xmlfilebytes
,
String
xmloutfilepath
)
{
System
.
out
.
println
(
"XMLOUTFILEPATH: "
+
xmloutfilepath
);
try
{
writer
=
new
PrintWriter
(
xmloutfilepath
,
"UTF-8"
);
}
catch
(
FileNotFoundException
fnfe
)
{
die
(
"FNFE"
);
}
catch
(
UnsupportedEncodingException
uee
)
{
die
(
"UEE"
);
}
if
(
null
==
writer
)
die
(
"null==writer"
);
writer
.
println
(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
);
bytes
=
xmlfilebytes
;
count
=
0
;
styleMap
=
new
HashMap
<
Integer
,
String
>();
if
(
null
==
styleMap
)
die
(
"null==styleMap"
);
for
(
Field
f
:
android
.
R
.
style
.
class
.
getFields
())
{
try
{
styleMap
.
put
(
f
.
getInt
(
f
.
getType
()),
f
.
getName
());
}
catch
(
IllegalAccessException
iae
)
{
die
(
"IAE"
);
}
}
public
void
parse
(
byte
[]
xmlBytes
,
File
out
)
{
LOG
.
debug
(
"Decoding AndroidManifest.xml, output: {}"
,
out
);
writer
=
new
CodeWriter
();
writer
.
add
(
"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
);
bytes
=
xmlBytes
;
count
=
0
;
firstElement
=
true
;
decode
();
writer
.
save
(
out
);
}
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
((
count
+
2
)<=
bytes
.
length
)
{
void
decode
()
{
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
((
count
+
2
)
<=
bytes
.
length
)
{
int
type
=
cInt16
(
bytes
,
count
);
if
(
type
==
0x0001
)
parseStringPool
();
else
if
(
type
==
0x0180
)
parseResourceMap
();
else
if
(
type
==
0x0100
)
parseNameSpace
();
else
if
(
type
==
0x0101
)
parseNameSpaceEnd
();
else
if
(
type
==
0x0102
)
parseElement
();
else
if
(
type
==
0x0103
)
parseElementEnd
();
else
if
(
type
==
0x0000
)
continue
;
// NullType is just doing nothing
else
die
(
"Type: "
+
Integer
.
toHexString
(
type
)
+
" not yet implemented"
);
switch
(
type
)
{
case
0x0001
:
parseStringPool
();
break
;
case
0x0180
:
parseResourceMap
();
break
;
case
0x0100
:
parseNameSpace
();
break
;
case
0x0101
:
parseNameSpaceEnd
();
break
;
case
0x0102
:
parseElement
();
break
;
case
0x0103
:
parseElementEnd
();
break
;
case
0x0000
:
// NullType is just doing nothing
break
;
default
:
die
(
"Type: "
+
Integer
.
toHexString
(
type
)
+
" not yet implemented"
);
break
;
}
}
writer
.
close
();
}
private
void
parseStringPool
()
{
if
(
cInt16
(
bytes
,
count
)
!=
0x001c
)
die
(
"Header header size not 28"
);
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
);
...
...
@@ -126,161 +119,214 @@ public class BinaryXMLParser {
int
stringsStart
=
cInt32
(
bytes
,
count
);
int
stylesStart
=
cInt32
(
bytes
,
count
);
int
[]
stringsOffsets
=
new
int
[
stringCount
];
for
(
int
i
=
0
;
i
<
stringCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
stringCount
;
i
++)
{
stringsOffsets
[
i
]
=
cInt32
(
bytes
,
count
);
}
strings
=
new
String
[
stringCount
];
for
(
int
i
=
0
;
i
<
stringCount
;
i
++)
{
for
(
int
i
=
0
;
i
<
stringCount
;
i
++)
{
int
off
=
8
+
stringsStart
+
stringsOffsets
[
i
];
int
strlen
=
cInt16
(
bytes
,
off
);
byte
[]
str
=
new
byte
[
strlen
*
2
];
System
.
arraycopy
(
bytes
,
count
,
str
,
0
,
strlen
*
2
);
count
+=
strlen
*
2
;
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"
));
count
+=
2
;
count
+=
2
;
}
}
private
void
parseResourceMap
()
{
if
(
cInt16
(
bytes
,
count
)
!=
0x8
)
die
(
"Header size of resmap is not 8!"
);
if
(
cInt16
(
bytes
,
count
)
!=
0x8
)
{
die
(
"Header size of resmap is not 8!"
);
}
int
rhsize
=
cInt32
(
bytes
,
count
);
int
[]
ids
=
new
int
[(
rhsize
-
8
)/
4
];
for
(
int
i
=
0
;
i
<
ids
.
length
;
i
++)
{
ids
[
i
]
=
cInt32
(
bytes
,
count
);
int
[]
ids
=
new
int
[(
rhsize
-
8
)
/
4
];
for
(
int
i
=
0
;
i
<
ids
.
length
;
i
++)
{
ids
[
i
]
=
cInt32
(
bytes
,
count
);
}
}
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"
);
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
);
int
comment
=
cInt32
(
bytes
,
count
);
int
beginPrefix
=
cInt32
(
bytes
,
count
);
nsPrefix
=
strings
[
beginPrefix
];
int
beginURI
=
cInt32
(
bytes
,
count
);
nsURI
=
strings
[
beginURI
];
nsURI
=
strings
[
beginURI
];
}
private
void
parseNameSpaceEnd
()
{
if
(
cInt16
(
bytes
,
count
)
!=
0x0010
)
die
(
"NAMESPACE header is not 0x0010"
);
if
(
cInt32
(
bytes
,
count
)
!=
0x18
)
die
(
"NAMESPACE header chunk is not 0x18 big"
);
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
endLineNumber
=
cInt32
(
bytes
,
count
);
int
comment
=
cInt32
(
bytes
,
count
);
int
endPrefix
=
cInt32
(
bytes
,
count
);
nsPrefix
=
strings
[
endPrefix
];
int
endURI
=
cInt32
(
bytes
,
count
);
nsURI
=
strings
[
endURI
];
nsURI
=
strings
[
endURI
];
}
private
void
parseElement
()
{
numtabs
+=
1
;
if
(
cInt16
(
bytes
,
count
)
!=
0x0010
)
die
(
"ELEMENT HEADER SIZE is not 0x10"
);
count
+=
4
;
// TODO: Check element chunk size
if
(
firstElement
)
{
firstElement
=
false
;
}
else
{
writer
.
incIndent
();
}
if
(
cInt16
(
bytes
,
count
)
!=
0x0010
)
{
die
(
"ELEMENT HEADER SIZE is not 0x10"
);
}
count
+=
4
;
// TODO: Check element chunk size
int
elementBegLineNumber
=
cInt32
(
bytes
,
count
);
int
comment
=
cInt32
(
bytes
,
count
);
int
startNS
=
cInt32
(
bytes
,
count
);
int
startNSName
=
cInt32
(
bytes
,
count
);
// actually is elementName...
if
(!
wasOneLiner
&&
!
"ERROR"
.
equals
(
currentTag
)
&&
!
currentTag
.
equals
(
strings
[
startNSName
]))
{
writer
.
println
(
">"
);
if
(!
wasOneLiner
&&
!
"ERROR"
.
equals
(
currentTag
)
&&
!
currentTag
.
equals
(
strings
[
startNSName
]))
{
writer
.
add
(
">"
);
}
wasOneLiner
=
false
;
currentTag
=
strings
[
startNSName
];
for
(
int
i
=
0
;
i
<
numtabs
;
i
++)
writer
.
print
(
"\t"
);
writer
.
print
(
"<"
+
strings
[
startNSName
]);
wasOneLiner
=
false
;
currentTag
=
strings
[
startNSName
];
writer
.
startLine
(
"<"
+
strings
[
startNSName
]);
int
attributeStart
=
cInt16
(
bytes
,
count
);
if
(
attributeStart
!=
0x14
)
die
(
"startNS's attributeStart is not 0x14"
);
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
);
if
(
attributeSize
!=
0x14
)
{
die
(
"startNS's attributeSize is not 0x14"
);
}
int
attributeCount
=
cInt16
(
bytes
,
count
);
int
idIndex
=
cInt16
(
bytes
,
count
);
int
classIndex
=
cInt16
(
bytes
,
count
);
int
styleIndex
=
cInt16
(
bytes
,
count
);
if
(
"manifest"
.
equals
(
strings
[
startNSName
]))
writer
.
print
(
" xmlns:\""
+
nsURI
+
"\""
);
if
(
attributeCount
>
0
)
writer
.
print
(
" "
);
for
(
int
i
=
0
;
i
<
attributeCount
;
i
++)
{
if
(
"manifest"
.
equals
(
strings
[
startNSName
]))
{
writer
.
add
(
" xmlns:\""
+
nsURI
+
"\""
);
}
if
(
attributeCount
>
0
)
{
writer
.
add
(
" "
);
}
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
);
if
(
attrValSize
!=
0x08
)
die
(
"attrValSize != 0x08 not supported"
);
if
(
cInt8
(
bytes
,
count
)
!=
0
)
die
(
"res0 is not 0"
);
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
);
if
(
attributeNS
!=
-
1
)
writer
.
print
(
nsPrefix
+
":"
);
writer
.
print
(
strings
[
attributeName
]
+
"=\""
);
if
(
attrValDataType
==
0x3
)
writer
.
print
(
strings
[
attrValData
]);
else
if
(
attrValDataType
==
0x10
)
writer
.
print
(
attrValData
);
else
if
(
attrValDataType
==
0x12
)
{
if
(
attributeNS
!=
-
1
)
{
writer
.
add
(
nsPrefix
+
":"
);
}
writer
.
add
(
strings
[
attributeName
]
+
"=\""
);
if
(
attrValDataType
==
0x3
)
{
writer
.
add
(
strings
[
attrValData
]);
}
else
if
(
attrValDataType
==
0x10
)
{
writer
.
add
(
String
.
valueOf
(
attrValData
));
}
else
if
(
attrValDataType
==
0x12
)
{
// FIXME: What to do, when data is always -1?
if
(
attrValData
==
0
)
writer
.
print
(
"false"
);
else
if
(
attrValData
==
1
||
attrValData
==-
1
)
writer
.
print
(
"true"
);
else
writer
.
print
(
"UNKNOWN_BOOLEAN_TYPE"
);
}
else
if
(
attrValDataType
==
0x1
)
{
if
(
attrValData
<
0x7f000000
)
{
writer
.
print
(
"@*"
);
if
(
attributeNS
!=
-
1
)
writer
.
print
(
nsPrefix
+
":"
);
writer
.
print
(
"style/"
+
styleMap
.
get
(
attrValData
).
replaceAll
(
"_"
,
"."
));
if
(
attrValData
==
0
)
{
writer
.
add
(
"false"
);
}
else
if
(
attrValData
==
1
||
attrValData
==
-
1
)
{
writer
.
add
(
"true"
);
}
else
{
writer
.
print
(
"0x"
+
Integer
.
toHexString
(
attrValData
)
);
writer
.
add
(
"UNKNOWN_BOOLEAN_TYPE"
);
}
}
else
{
if
(
"configChanges"
.
equals
(
strings
[
attributeName
]))
{
if
(
attrValData
==
1152
)
writer
.
print
(
"orientation"
);
else
if
(
attrValData
==
4016
)
writer
.
print
(
"keyboard|keyboardHidden|orientation|screenLayout|uiMode"
);
else
if
(
attrValData
==
176
)
writer
.
print
(
"keyboard|keyboardHidden|orientation"
);
else
if
(
attrValData
==
160
)
writer
.
print
(
"keyboardHidden|orientation"
);
else
writer
.
print
(
"UNKNOWN_DATA_"
+
Integer
.
toHexString
(
attrValData
));
}
else
if
(
attrValDataType
==
0x1
)
{
String
name
=
styleMap
.
get
(
attrValData
);
if
(
name
!=
null
)
{
writer
.
add
(
"@*"
);
if
(
attributeNS
!=
-
1
)
{
writer
.
add
(
nsPrefix
+
":"
);
}
writer
.
add
(
"style/"
+
name
.
replaceAll
(
"_"
,
"."
));
}
else
{
writer
.
add
(
"0x"
+
Integer
.
toHexString
(
attrValData
));
}
}
else
{
// TODO: extract values names from here:
// https://github.com/android/platform_frameworks_base/blob/master/core/res/res/values/attrs_manifest.xml
if
(
"configChanges"
.
equals
(
strings
[
attributeName
]))
{
if
(
attrValData
==
1152
)
{
writer
.
add
(
"orientation"
);
}
else
if
(
attrValData
==
4016
)
{
writer
.
add
(
"keyboard|keyboardHidden|orientation|screenLayout|uiMode"
);
}
else
if
(
attrValData
==
176
)
{
writer
.
add
(
"keyboard|keyboardHidden|orientation"
);
}
else
if
(
attrValData
==
160
)
{
writer
.
add
(
"keyboardHidden|orientation"
);
}
else
{
writer
.
add
(
"UNKNOWN_DATA_"
+
Integer
.
toHexString
(
attrValData
));
}
}
else
{
writer
.
print
(
"UNKNOWN_DATA_TYPE_"
+
attrValDataType
);
writer
.
add
(
"UNKNOWN_DATA_TYPE_"
+
attrValDataType
);
}
}
writer
.
print
(
"\""
);
if
((
i
+
1
)<
attributeCount
)
writer
.
print
(
" "
);
writer
.
add
(
"\""
);
if
((
i
+
1
)
<
attributeCount
)
{
writer
.
add
(
" "
);
}
}
}
private
void
parseElementEnd
()
{
if
(
cInt16
(
bytes
,
count
)
!=
0x0010
)
die
(
"ELEMENT END header is not 0x0010"
);
if
(
cInt32
(
bytes
,
count
)
!=
0x18
)
die
(
"ELEMENT END header chunk is not 0x18 big"
);
if
(
cInt16
(
bytes
,
count
)
!=
0x0010
)
{
die
(
"ELEMENT END header is not 0x0010"
);
}
if
(
cInt32
(
bytes
,
count
)
!=
0x18
)
{
die
(
"ELEMENT END header chunk is not 0x18 big"
);
}
int
endLineNumber
=
cInt32
(
bytes
,
count
);
int
comment
=
cInt32
(
bytes
,
count
);
int
elementNS
=
cInt32
(
bytes
,
count
);
int
elementName
=
cInt32
(
bytes
,
count
);
if
(
currentTag
==
strings
[
elementName
]
)
{
writer
.
println
(
"
/>"
);
wasOneLiner
=
true
;
if
(
currentTag
.
equals
(
strings
[
elementName
])
)
{
writer
.
add
(
"
/>"
);
wasOneLiner
=
true
;
}
else
{
for
(
int
i
=
0
;
i
<
numtabs
;
i
++)
writer
.
print
(
"\t"
);
writer
.
print
(
"</"
);
if
(
elementNS
!=
-
1
)
writer
.
print
(
strings
[
elementNS
]+
":"
);
writer
.
println
(
strings
[
elementName
]+
">"
);
writer
.
startLine
(
"</"
);
if
(
elementNS
!=
-
1
)
{
writer
.
add
(
strings
[
elementNS
]
+
":"
);
}
writer
.
add
(
strings
[
elementName
]
+
">"
);
}
numtabs
-=
1
;
writer
.
decIndent
()
;
}
private
int
cInt8
(
byte
[]
bytes
,
int
offset
)
{
byte
[]
tmp
=
new
byte
[
4
];
tmp
[
3
]
=
bytes
[
count
++];
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
++];
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
;
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
);
throw
new
JadxRuntimeException
(
"Decode error: "
+
message
);
}
}
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录