Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
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
0c041120
Commit
0c041120
authored
Aug 20, 2018
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: show all decompilation errors in code comments (#313)
parent
ecbb53aa
Show whitespace changes
Inline
Side-by-side
Showing
30 changed files
with
254 additions
and
120 deletions
+254
-120
JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+10
-5
JadxDecompiler.java
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
+7
-0
ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+26
-3
CodeWriter.java
jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
+5
-0
ConditionGen.java
jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java
+1
-1
InsnGen.java
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
+1
-1
MethodGen.java
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
+10
-29
NameGen.java
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
+4
-3
RegionGen.java
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
+1
-1
AType.java
jadx-core/src/main/java/jadx/core/dex/attributes/AType.java
+5
-2
AttrList.java
...core/src/main/java/jadx/core/dex/attributes/AttrList.java
+2
-2
JadxError.java
...c/main/java/jadx/core/dex/attributes/nodes/JadxError.java
+17
-13
JadxWarn.java
...rc/main/java/jadx/core/dex/attributes/nodes/JadxWarn.java
+21
-0
RegisterArg.java
...ain/java/jadx/core/dex/instructions/args/RegisterArg.java
+1
-1
BlockNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/BlockNode.java
+2
-7
ClassNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
+6
-3
DexNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
+5
-1
IDexNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/IDexNode.java
+2
-0
MethodNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
+14
-0
DebugInfoVisitor.java
...rc/main/java/jadx/core/dex/visitors/DebugInfoVisitor.java
+1
-1
DotGraphVisitor.java
...src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
+1
-2
ModVisitor.java
...core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
+1
-1
BlockFinallyExtract.java
...dx/core/dex/visitors/blocksmaker/BlockFinallyExtract.java
+1
-1
CheckRegions.java
...ain/java/jadx/core/dex/visitors/regions/CheckRegions.java
+29
-7
ProcessTryCatchRegions.java
...adx/core/dex/visitors/regions/ProcessTryCatchRegions.java
+2
-2
RegionMaker.java
...main/java/jadx/core/dex/visitors/regions/RegionMaker.java
+3
-3
CheckTypeVisitor.java
...adx/core/dex/visitors/typeinference/CheckTypeVisitor.java
+1
-1
ErrorsCounter.java
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
+47
-28
Utils.java
jadx-core/src/main/java/jadx/core/utils/Utils.java
+26
-0
JadxException.java
...c/main/java/jadx/core/utils/exceptions/JadxException.java
+2
-2
No files found.
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
View file @
0c041120
...
...
@@ -10,31 +10,36 @@ public class JadxCLI {
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxCLI
.
class
);
public
static
void
main
(
String
[]
args
)
{
int
result
=
0
;
try
{
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
();
if
(
jadxArgs
.
processArgs
(
args
))
{
processAndSave
(
jadxArgs
);
result
=
processAndSave
(
jadxArgs
);
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"jadx error: {}"
,
e
.
getMessage
(),
e
);
System
.
exit
(
1
);
result
=
1
;
}
finally
{
System
.
exit
(
result
);
}
}
static
void
processAndSave
(
JadxCLIArgs
inputArgs
)
{
static
int
processAndSave
(
JadxCLIArgs
inputArgs
)
{
JadxDecompiler
jadx
=
new
JadxDecompiler
(
inputArgs
.
toJadxArgs
());
try
{
jadx
.
load
();
}
catch
(
JadxArgsValidateException
e
)
{
LOG
.
error
(
"Incorrect arguments: {}"
,
e
.
getMessage
());
System
.
exit
(
1
)
;
return
1
;
}
jadx
.
save
();
if
(
jadx
.
getErrorsCount
()
!=
0
)
{
int
errorsCount
=
jadx
.
getErrorsCount
();
if
(
errorsCount
!=
0
)
{
jadx
.
printErrorsReport
();
LOG
.
error
(
"finished with errors"
);
}
else
{
LOG
.
info
(
"done"
);
}
return
errorsCount
;
}
}
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
View file @
0c041120
...
...
@@ -264,6 +264,13 @@ public final class JadxDecompiler {
return
root
.
getErrorsCounter
().
getErrorCount
();
}
public
int
getWarnsCount
()
{
if
(
root
==
null
)
{
return
0
;
}
return
root
.
getErrorsCounter
().
getWarnsCount
();
}
public
void
printErrorsReport
()
{
if
(
root
==
null
)
{
return
;
...
...
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
View file @
0c041120
...
...
@@ -18,6 +18,8 @@ import jadx.core.dex.attributes.AType;
import
jadx.core.dex.attributes.AttrNode
;
import
jadx.core.dex.attributes.nodes.EnumClassAttr
;
import
jadx.core.dex.attributes.nodes.EnumClassAttr.EnumField
;
import
jadx.core.dex.attributes.nodes.JadxError
;
import
jadx.core.dex.attributes.nodes.JadxWarn
;
import
jadx.core.dex.attributes.nodes.LineAttrNode
;
import
jadx.core.dex.attributes.nodes.SourceFileAttr
;
import
jadx.core.dex.info.AccessInfo
;
...
...
@@ -253,6 +255,7 @@ public class ClassGen {
if
(
code
.
getLine
()
!=
clsDeclLine
)
{
code
.
newLine
();
}
int
savedIndent
=
code
.
getIndent
();
try
{
addMethod
(
code
,
mth
);
}
catch
(
Exception
e
)
{
...
...
@@ -260,6 +263,7 @@ public class ClassGen {
code
.
newLine
().
add
(
ErrorsCounter
.
methodError
(
mth
,
"Method generation error"
,
e
));
code
.
newLine
().
add
(
Utils
.
getStackTrace
(
e
));
code
.
newLine
().
add
(
"*/"
);
code
.
setIndent
(
savedIndent
);
}
}
}
...
...
@@ -292,12 +296,11 @@ public class ClassGen {
}
code
.
add
(
';'
);
}
else
{
insertDecompilationProblems
(
code
,
mth
);
boolean
badCode
=
mth
.
contains
(
AFlag
.
INCONSISTENT_CODE
);
if
(
badCode
)
{
code
.
startLine
(
"/* JADX WARNING: inconsistent code. */"
);
code
.
startLine
(
"/* Code decompiled incorrectly, please refer to instructions dump. */"
);
ErrorsCounter
.
methodError
(
mth
,
"Inconsistent code"
);
if
(
showInconsistentCode
)
{
code
.
startLine
(
"/* Code decompiled incorrectly, please refer to instructions dump. */"
);
mth
.
remove
(
AFlag
.
INCONSISTENT_CODE
);
badCode
=
false
;
}
...
...
@@ -324,6 +327,26 @@ public class ClassGen {
}
}
private
void
insertDecompilationProblems
(
CodeWriter
code
,
MethodNode
mth
)
{
List
<
JadxError
>
errors
=
mth
.
getAll
(
AType
.
JADX_ERROR
);
List
<
JadxWarn
>
warns
=
mth
.
getAll
(
AType
.
JADX_WARN
);
if
(!
errors
.
isEmpty
())
{
errors
.
forEach
(
err
->
{
code
.
startLine
(
"/* JADX ERROR: "
).
add
(
err
.
getError
());
Throwable
cause
=
err
.
getCause
();
if
(
cause
!=
null
)
{
code
.
incIndent
();
Utils
.
appendStackTrace
(
code
,
cause
);
code
.
decIndent
();
}
code
.
add
(
"*/"
);
});
}
if
(!
warns
.
isEmpty
())
{
warns
.
forEach
(
warn
->
code
.
startLine
(
"/* JADX WARNING: "
).
add
(
warn
.
getWarn
()).
add
(
" */"
));
}
}
private
void
addFields
(
CodeWriter
code
)
throws
CodegenException
{
addEnumFields
(
code
);
for
(
FieldNode
f
:
cls
.
getFields
())
{
...
...
jadx-core/src/main/java/jadx/core/codegen/CodeWriter.java
View file @
0c041120
...
...
@@ -191,6 +191,11 @@ public class CodeWriter {
return
indent
;
}
public
void
setIndent
(
int
indent
)
{
this
.
indent
=
indent
;
updateIndent
();
}
public
int
getLine
()
{
return
line
;
}
...
...
jadx-core/src/main/java/jadx/core/codegen/ConditionGen.java
View file @
0c041120
...
...
@@ -122,7 +122,7 @@ public class ConditionGen extends InsnGen {
wrap
(
code
,
firstArg
);
return
;
}
ErrorsCounter
.
method
Error
(
mth
,
"Unsupported boolean condition "
+
op
.
getSymbol
());
ErrorsCounter
.
method
Warn
(
mth
,
"Unsupported boolean condition "
+
op
.
getSymbol
());
}
addArg
(
code
,
firstArg
,
isArgWrapNeeded
(
firstArg
));
...
...
jadx-core/src/main/java/jadx/core/codegen/InsnGen.java
View file @
0c041120
...
...
@@ -580,7 +580,7 @@ public class InsnGen {
// anonymous class construction
if
(
cls
.
contains
(
AFlag
.
DONT_GENERATE
))
{
code
.
add
(
"/* anonymous class already generated */"
);
ErrorsCounter
.
method
Error
(
mth
,
"Anonymous class already generated: "
+
cls
);
ErrorsCounter
.
method
Warn
(
mth
,
"Anonymous class already generated: "
+
cls
);
return
;
}
ArgType
parent
;
...
...
jadx-core/src/main/java/jadx/core/codegen/MethodGen.java
View file @
0c041120
...
...
@@ -10,7 +10,6 @@ import org.slf4j.LoggerFactory;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.annotations.MethodParameters
;
import
jadx.core.dex.attributes.nodes.JadxErrorAttr
;
import
jadx.core.dex.info.AccessInfo
;
import
jadx.core.dex.instructions.InsnType
;
import
jadx.core.dex.instructions.args.ArgType
;
...
...
@@ -23,7 +22,6 @@ import jadx.core.dex.visitors.DepthTraversal;
import
jadx.core.dex.visitors.FallbackModeVisitor
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.InsnUtils
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.DecodeException
;
...
...
@@ -108,7 +106,7 @@ public class MethodGen {
}
else
if
(
args
.
size
()
>
2
)
{
args
=
args
.
subList
(
2
,
args
.
size
());
}
else
{
LOG
.
warn
(
ErrorsCounter
.
format
Error
Msg
(
mth
,
LOG
.
warn
(
ErrorsCounter
.
formatMsg
(
mth
,
"Incorrect number of args for enum constructor: "
+
args
.
size
()
+
" (expected >= 2)"
));
...
...
@@ -143,7 +141,7 @@ public class MethodGen {
classGen
.
useType
(
argsCode
,
elType
);
argsCode
.
add
(
"..."
);
}
else
{
LOG
.
warn
(
ErrorsCounter
.
format
Error
Msg
(
mth
,
"Last argument in varargs method not array"
));
LOG
.
warn
(
ErrorsCounter
.
formatMsg
(
mth
,
"Last argument in varargs method not array"
));
classGen
.
useType
(
argsCode
,
arg
.
getType
());
}
}
else
{
...
...
@@ -163,17 +161,6 @@ public class MethodGen {
if
(
mth
.
contains
(
AType
.
JADX_ERROR
)
||
mth
.
contains
(
AFlag
.
INCONSISTENT_CODE
)
||
mth
.
getRegion
()
==
null
)
{
JadxErrorAttr
err
=
mth
.
get
(
AType
.
JADX_ERROR
);
if
(
err
!=
null
)
{
code
.
startLine
(
"/* JADX: method processing error */"
);
Throwable
cause
=
err
.
getCause
();
if
(
cause
!=
null
)
{
code
.
newLine
();
code
.
add
(
"/*"
);
code
.
newLine
().
add
(
"Error: "
).
addMultiLine
(
Utils
.
getStackTrace
(
cause
));
code
.
add
(
"*/"
);
}
}
code
.
startLine
(
"/*"
);
addFallbackMethodCode
(
code
);
code
.
startLine
(
"*/"
);
...
...
@@ -189,10 +176,6 @@ public class MethodGen {
public
void
addFallbackMethodCode
(
CodeWriter
code
)
{
if
(
mth
.
getInstructions
()
==
null
)
{
JadxErrorAttr
errorAttr
=
mth
.
get
(
AType
.
JADX_ERROR
);
if
(
errorAttr
==
null
||
errorAttr
.
getCause
()
==
null
||
!
errorAttr
.
getCause
().
getClass
().
equals
(
DecodeException
.
class
))
{
// load original instructions
try
{
mth
.
load
();
...
...
@@ -203,7 +186,6 @@ public class MethodGen {
return
;
}
}
}
InsnNode
[]
insnArr
=
mth
.
getInstructions
();
if
(
insnArr
==
null
)
{
code
.
startLine
(
"// Can't load method instructions."
);
...
...
@@ -251,5 +233,4 @@ public class MethodGen {
public
static
String
getLabelName
(
int
offset
)
{
return
"L_"
+
InsnUtils
.
formatOffset
(
offset
);
}
}
jadx-core/src/main/java/jadx/core/codegen/NameGen.java
View file @
0c041120
...
...
@@ -7,6 +7,7 @@ import java.util.Set;
import
jadx.core.Consts
;
import
jadx.core.deobf.NameMapper
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.nodes.LoopLabelAttr
;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.info.MethodInfo
;
...
...
@@ -136,11 +137,11 @@ public class NameGen {
private
String
makeNameForType
(
ArgType
type
)
{
if
(
type
.
isPrimitive
())
{
return
makeNameForPrimitive
(
type
);
}
else
if
(
type
.
isArray
())
{
}
if
(
type
.
isArray
())
{
return
makeNameForType
(
type
.
getArrayRootElement
())
+
"Arr"
;
}
else
{
return
makeNameForObject
(
type
);
}
return
makeNameForObject
(
type
);
}
private
static
String
makeNameForPrimitive
(
ArgType
type
)
{
...
...
jadx-core/src/main/java/jadx/core/codegen/RegionGen.java
View file @
0c041120
...
...
@@ -153,7 +153,7 @@ public class RegionGen extends InsnGen {
if
(
header
!=
null
)
{
List
<
InsnNode
>
headerInsns
=
header
.
getInstructions
();
if
(
headerInsns
.
size
()
>
1
)
{
ErrorsCounter
.
method
Error
(
mth
,
"Found not inlined instructions from loop header"
);
ErrorsCounter
.
method
Warn
(
mth
,
"Found not inlined instructions from loop header"
);
int
last
=
headerInsns
.
size
()
-
1
;
for
(
int
i
=
0
;
i
<
last
;
i
++)
{
InsnNode
insn
=
headerInsns
.
get
(
i
);
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AType.java
View file @
0c041120
...
...
@@ -9,7 +9,8 @@ import jadx.core.dex.attributes.nodes.EnumMapAttr;
import
jadx.core.dex.attributes.nodes.FieldReplaceAttr
;
import
jadx.core.dex.attributes.nodes.ForceReturnAttr
;
import
jadx.core.dex.attributes.nodes.IgnoreEdgeAttr
;
import
jadx.core.dex.attributes.nodes.JadxErrorAttr
;
import
jadx.core.dex.attributes.nodes.JadxError
;
import
jadx.core.dex.attributes.nodes.JadxWarn
;
import
jadx.core.dex.attributes.nodes.JumpInfo
;
import
jadx.core.dex.attributes.nodes.LoopInfo
;
import
jadx.core.dex.attributes.nodes.LoopLabelAttr
;
...
...
@@ -33,13 +34,15 @@ public class AType<T extends IAttribute> {
public
static
final
AType
<
AttrList
<
LoopInfo
>>
LOOP
=
new
AType
<>();
public
static
final
AType
<
AttrList
<
EdgeInsnAttr
>>
EDGE_INSN
=
new
AType
<>();
public
static
final
AType
<
AttrList
<
JadxError
>>
JADX_ERROR
=
new
AType
<>();
public
static
final
AType
<
AttrList
<
JadxWarn
>>
JADX_WARN
=
new
AType
<>();
public
static
final
AType
<
ExcHandlerAttr
>
EXC_HANDLER
=
new
AType
<>();
public
static
final
AType
<
CatchAttr
>
CATCH_BLOCK
=
new
AType
<>();
public
static
final
AType
<
SplitterBlockAttr
>
SPLITTER_BLOCK
=
new
AType
<>();
public
static
final
AType
<
ForceReturnAttr
>
FORCE_RETURN
=
new
AType
<>();
public
static
final
AType
<
FieldInitAttr
>
FIELD_INIT
=
new
AType
<>();
public
static
final
AType
<
FieldReplaceAttr
>
FIELD_REPLACE
=
new
AType
<>();
public
static
final
AType
<
JadxErrorAttr
>
JADX_ERROR
=
new
AType
<>();
public
static
final
AType
<
MethodInlineAttr
>
METHOD_INLINE
=
new
AType
<>();
public
static
final
AType
<
EnumClassAttr
>
ENUM_CLASS
=
new
AType
<>();
public
static
final
AType
<
EnumMapAttr
>
ENUM_MAP
=
new
AType
<>();
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/AttrList.java
View file @
0c041120
package
jadx
.
core
.
dex
.
attributes
;
import
java.util.
Linked
List
;
import
java.util.
Array
List
;
import
java.util.List
;
import
jadx.core.utils.Utils
;
...
...
@@ -8,7 +8,7 @@ import jadx.core.utils.Utils;
public
class
AttrList
<
T
>
implements
IAttribute
{
private
final
AType
<
AttrList
<
T
>>
type
;
private
final
List
<
T
>
list
=
new
Linked
List
<>();
private
final
List
<
T
>
list
=
new
Array
List
<>();
public
AttrList
(
AType
<
AttrList
<
T
>>
type
)
{
this
.
type
=
type
;
...
...
jadx-core/src/main/java/jadx/core/dex/attributes/nodes/JadxError
Attr
.java
→
jadx-core/src/main/java/jadx/core/dex/attributes/nodes/JadxError.java
View file @
0c041120
package
jadx
.
core
.
dex
.
attributes
.
nodes
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.IAttribute
;
import
jadx.core.utils.Utils
;
public
class
JadxError
Attr
implements
IAttribute
{
public
class
JadxError
{
private
final
String
error
;
private
final
Throwable
cause
;
public
JadxErrorAttr
(
Throwable
cause
)
{
public
JadxError
(
Throwable
cause
)
{
this
(
null
,
cause
);
}
public
JadxError
(
String
error
,
Throwable
cause
)
{
this
.
error
=
error
;
this
.
cause
=
cause
;
}
public
Throwable
getCause
()
{
return
cause
;
public
String
getError
()
{
return
error
;
}
@Override
public
AType
<
JadxErrorAttr
>
getType
()
{
return
AType
.
JADX_ERROR
;
public
Throwable
getCause
()
{
return
cause
;
}
@Override
public
String
toString
()
{
StringBuilder
str
=
new
StringBuilder
();
str
.
append
(
"JadxError: "
);
if
(
cause
==
null
)
{
str
.
append
(
"null"
);
}
else
{
if
(
error
!=
null
)
{
str
.
append
(
error
);
str
.
append
(
' '
);
}
if
(
cause
!=
null
)
{
str
.
append
(
cause
.
getClass
());
str
.
append
(
":"
);
str
.
append
(
cause
.
getMessage
());
...
...
@@ -36,5 +41,4 @@ public class JadxErrorAttr implements IAttribute {
}
return
str
.
toString
();
}
}
jadx-core/src/main/java/jadx/core/dex/attributes/nodes/JadxWarn.java
0 → 100644
View file @
0c041120
package
jadx
.
core
.
dex
.
attributes
.
nodes
;
import
java.util.Objects
;
public
class
JadxWarn
{
private
final
String
warn
;
public
JadxWarn
(
String
warn
)
{
this
.
warn
=
Objects
.
requireNonNull
(
warn
);
}
public
String
getWarn
()
{
return
warn
;
}
@Override
public
String
toString
()
{
return
"JadxWarn: "
+
warn
;
}
}
jadx-core/src/main/java/jadx/core/dex/instructions/args/RegisterArg.java
View file @
0c041120
...
...
@@ -55,7 +55,7 @@ public class RegisterArg extends InsnArg implements Named {
}
public
void
setName
(
String
name
)
{
if
(
sVar
!=
null
)
{
if
(
sVar
!=
null
&&
name
!=
null
)
{
sVar
.
setName
(
name
);
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/BlockNode.java
View file @
0c041120
...
...
@@ -2,8 +2,6 @@ package jadx.core.dex.nodes;
import
java.util.ArrayList
;
import
java.util.BitSet
;
import
java.util.Collections
;
import
java.util.LinkedList
;
import
java.util.List
;
import
jadx.core.dex.attributes.AFlag
;
...
...
@@ -35,7 +33,7 @@ public class BlockNode extends AttrNode implements IBlock {
// immediate dominator
private
BlockNode
idom
;
// blocks on which dominates this block
private
List
<
BlockNode
>
dominatesOn
=
Collections
.
emptyList
(
);
private
List
<
BlockNode
>
dominatesOn
=
new
ArrayList
<>(
3
);
public
BlockNode
(
int
id
,
int
offset
)
{
this
.
id
=
id
;
...
...
@@ -84,7 +82,7 @@ public class BlockNode extends AttrNode implements IBlock {
if
(
sucList
.
isEmpty
())
{
return
sucList
;
}
List
<
BlockNode
>
toRemove
=
new
LinkedList
<>(
);
List
<
BlockNode
>
toRemove
=
new
ArrayList
<>(
sucList
.
size
()
);
for
(
BlockNode
b
:
sucList
)
{
if
(
BlockUtils
.
isBlockMustBeCleared
(
b
))
{
toRemove
.
add
(
b
);
...
...
@@ -159,9 +157,6 @@ public class BlockNode extends AttrNode implements IBlock {
}
public
void
addDominatesOn
(
BlockNode
block
)
{
if
(
dominatesOn
.
isEmpty
())
{
dominatesOn
=
new
LinkedList
<>();
}
dominatesOn
.
add
(
block
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
View file @
0c041120
...
...
@@ -22,7 +22,6 @@ import org.slf4j.LoggerFactory;
import
jadx.core.Consts
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.dex.attributes.annotations.Annotation
;
import
jadx.core.dex.attributes.nodes.JadxErrorAttr
;
import
jadx.core.dex.attributes.nodes.LineAttrNode
;
import
jadx.core.dex.attributes.nodes.SourceFileAttr
;
import
jadx.core.dex.info.AccessInfo
;
...
...
@@ -248,8 +247,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
try
{
mth
.
load
();
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Method load error: {}"
,
mth
,
e
);
mth
.
addAttr
(
new
JadxErrorAttr
(
e
));
mth
.
addError
(
"Method load error"
,
e
);
}
}
for
(
ClassNode
innerCls
:
getInnerClasses
())
{
...
...
@@ -418,6 +416,11 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
return
dex
.
root
();
}
@Override
public
String
typeName
()
{
return
"class"
;
}
public
String
getRawName
()
{
return
clsInfo
.
getRawName
();
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
View file @
0c041120
...
...
@@ -235,6 +235,11 @@ public class DexNode implements IDexNode {
return
this
;
}
@Override
public
String
typeName
()
{
return
"dex"
;
}
public
int
getDexId
()
{
return
dexId
;
}
...
...
@@ -243,5 +248,4 @@ public class DexNode implements IDexNode {
public
String
toString
()
{
return
"DEX: "
+
file
;
}
}
jadx-core/src/main/java/jadx/core/dex/nodes/IDexNode.java
View file @
0c041120
...
...
@@ -2,6 +2,8 @@ package jadx.core.dex.nodes;
public
interface
IDexNode
{
String
typeName
();
DexNode
dex
();
RootNode
root
();
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/MethodNode.java
View file @
0c041120
...
...
@@ -39,6 +39,7 @@ import jadx.core.dex.regions.Region;
import
jadx.core.dex.trycatch.ExcHandlerAttr
;
import
jadx.core.dex.trycatch.ExceptionHandler
;
import
jadx.core.dex.trycatch.TryCatchBlock
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.Utils
;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
...
@@ -605,6 +606,19 @@ public class MethodNode extends LineAttrNode implements ILoadable, IDexNode {
return
dex
().
root
();
}
@Override
public
String
typeName
()
{
return
"method"
;
}
public
void
addWarn
(
String
errStr
)
{
ErrorsCounter
.
methodWarn
(
this
,
errStr
);
}
public
void
addError
(
String
errStr
,
Exception
e
)
{
ErrorsCounter
.
methodError
(
this
,
errStr
,
e
);
}
public
MethodInfo
getMethodInfo
()
{
return
mthInfo
;
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DebugInfoVisitor.java
View file @
0c041120
...
...
@@ -26,7 +26,7 @@ public class DebugInfoVisitor extends AbstractVisitor {
processDebugInfo
(
mth
,
debugOffset
);
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error in debug info parser: {}"
,
ErrorsCounter
.
format
Error
Msg
(
mth
,
e
.
getMessage
()),
e
);
LOG
.
error
(
"Error in debug info parser: {}"
,
ErrorsCounter
.
formatMsg
(
mth
,
e
.
getMessage
()),
e
);
}
finally
{
mth
.
unloadInsnArr
();
}
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
View file @
0c041120
...
...
@@ -259,8 +259,7 @@ public class DotGraphVisitor extends AbstractVisitor {
}
else
{
CodeWriter
code
=
new
CodeWriter
();
List
<
InsnNode
>
instructions
=
block
.
getInstructions
();
MethodGen
.
addFallbackInsns
(
code
,
mth
,
instructions
.
toArray
(
new
InsnNode
[
instructions
.
size
()]),
false
);
MethodGen
.
addFallbackInsns
(
code
,
mth
,
instructions
.
toArray
(
new
InsnNode
[
0
]),
false
);
String
str
=
escape
(
code
.
newLine
().
toString
());
if
(
str
.
startsWith
(
NL
))
{
str
=
str
.
substring
(
NL
.
length
());
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/ModVisitor.java
View file @
0c041120
...
...
@@ -366,7 +366,7 @@ public class ModVisitor extends AbstractVisitor {
elType
=
insnElementType
;
}
if
(!
elType
.
equals
(
insnElementType
)
&&
!
insnArrayType
.
equals
(
ArgType
.
OBJECT
))
{
ErrorsCounter
.
method
Error
(
mth
,
ErrorsCounter
.
method
Warn
(
mth
,
"Incorrect type for fill-array insn "
+
InsnUtils
.
formatOffset
(
insn
.
getOffset
())
+
", element type: "
+
elType
+
", insn element type: "
+
insnElementType
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/blocksmaker/BlockFinallyExtract.java
View file @
0c041120
...
...
@@ -529,7 +529,7 @@ public class BlockFinallyExtract extends AbstractVisitor {
return
false
;
}
if
(
removeInfo
.
getOuts
().
isEmpty
())
{
ErrorsCounter
.
method
Error
(
mth
,
"Failed to extract finally block: empty outs"
);
ErrorsCounter
.
method
Warn
(
mth
,
"Failed to extract finally block: empty outs"
);
return
false
;
}
// safe checks finished, altering blocks tree
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/CheckRegions.java
View file @
0c041120
...
...
@@ -6,15 +6,19 @@ import java.util.Set;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.codegen.InsnGen
;
import
jadx.core.codegen.MethodGen
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.nodes.BlockNode
;
import
jadx.core.dex.nodes.IBlock
;
import
jadx.core.dex.nodes.IRegion
;
import
jadx.core.dex.nodes.InsnNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.regions.loops.LoopRegion
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.
ErrorsCounter
;
import
jadx.core.utils.
exceptions.CodegenException
;
import
jadx.core.utils.exceptions.JadxException
;
public
class
CheckRegions
extends
AbstractVisitor
{
...
...
@@ -23,6 +27,7 @@ public class CheckRegions extends AbstractVisitor {
@Override
public
void
visit
(
MethodNode
mth
)
throws
JadxException
{
if
(
mth
.
isNoCode
()
||
mth
.
getRegion
()
==
null
||
mth
.
getBasicBlocks
().
isEmpty
()
||
mth
.
contains
(
AType
.
JADX_ERROR
))
{
return
;
...
...
@@ -44,9 +49,10 @@ public class CheckRegions extends AbstractVisitor {
&&
!
block
.
contains
(
AFlag
.
SKIP
)
&&
!
block
.
contains
(
AFlag
.
SYNTHETIC
)
&&
!
block
.
getInstructions
().
isEmpty
())
{
// TODO
// mth.add(AFlag.INCONSISTENT_CODE);
LOG
.
debug
(
" Duplicated block: {} in {}"
,
block
,
mth
);
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Duplicated block: {} - {}"
,
mth
,
block
);
}
//mth.addWarn("Duplicated block: " + block);
}
}
});
...
...
@@ -55,8 +61,8 @@ public class CheckRegions extends AbstractVisitor {
if
(!
blocksInRegions
.
contains
(
block
)
&&
!
block
.
getInstructions
().
isEmpty
()
&&
!
block
.
contains
(
AFlag
.
SKIP
))
{
mth
.
add
(
AFlag
.
INCONSISTENT_CODE
);
LOG
.
debug
(
" Missing block: {} in {}"
,
block
,
mth
);
String
blockCode
=
getBlockInsnStr
(
mth
,
block
);
mth
.
addWarn
(
"Missing block: "
+
block
+
", code:"
+
CodeWriter
.
NL
+
blockCode
);
}
}
}
...
...
@@ -68,11 +74,27 @@ public class CheckRegions extends AbstractVisitor {
if
(
region
instanceof
LoopRegion
)
{
BlockNode
loopHeader
=
((
LoopRegion
)
region
).
getHeader
();
if
(
loopHeader
!=
null
&&
loopHeader
.
getInstructions
().
size
()
!=
1
)
{
ErrorsCounter
.
methodError
(
mth
,
"Incorrect condition in loop: "
+
loopHeader
);
mth
.
addWarn
(
"Incorrect condition in loop: "
+
loopHeader
);
}
}
return
true
;
}
});
}
private
static
String
getBlockInsnStr
(
MethodNode
mth
,
BlockNode
block
)
{
CodeWriter
code
=
new
CodeWriter
();
code
.
setIndent
(
3
);
MethodGen
mg
=
MethodGen
.
getFallbackMethodGen
(
mth
);
InsnGen
ig
=
new
InsnGen
(
mg
,
true
);
for
(
InsnNode
insn
:
block
.
getInstructions
())
{
try
{
ig
.
makeInsn
(
insn
,
code
);
}
catch
(
CodegenException
ignored
)
{
}
}
code
.
newLine
().
addIndent
();
code
.
finish
();
return
code
.
toString
();
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/regions/ProcessTryCatchRegions.java
View file @
0c041120
...
...
@@ -93,7 +93,7 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
}
TryCatchBlock
prevTB
=
tryBlocksMap
.
put
(
domBlock
,
tb
);
if
(
prevTB
!=
null
)
{
ErrorsCounter
.
method
Error
(
mth
,
"Failed to process nested try/catch"
);
ErrorsCounter
.
method
Warn
(
mth
,
"Failed to process nested try/catch"
);
}
}
}
...
...
@@ -105,7 +105,7 @@ public class ProcessTryCatchRegions extends AbstractRegionVisitor {
if
(
region
.
getSubBlocks
().
contains
(
dominator
))
{
TryCatchBlock
tb
=
tryBlocksMap
.
get
(
dominator
);
if
(!
wrapBlocks
(
region
,
tb
,
dominator
))
{
ErrorsCounter
.
method
Error
(
mth
,
"Can't wrap try/catch for "
+
region
);
ErrorsCounter
.
method
Warn
(
mth
,
"Can't wrap try/catch for "
+
region
);
}
tryBlocksMap
.
remove
(
dominator
);
return
true
;
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/regions/RegionMaker.java
View file @
0c041120
...
...
@@ -532,7 +532,7 @@ public class RegionMaker {
BlockNode
body
=
getNextBlock
(
block
);
if
(
body
==
null
)
{
ErrorsCounter
.
method
Error
(
mth
,
"Unexpected end of synchronized block"
);
ErrorsCounter
.
method
Warn
(
mth
,
"Unexpected end of synchronized block"
);
return
null
;
}
BlockNode
exit
=
null
;
...
...
@@ -904,7 +904,7 @@ public class RegionMaker {
blocks
.
add
(
handlerBlock
);
splitters
.
addAll
(
handlerBlock
.
getPredecessors
());
}
else
{
LOG
.
debug
(
ErrorsCounter
.
format
Error
Msg
(
mth
,
"No exception handler block: "
+
handler
));
LOG
.
debug
(
ErrorsCounter
.
formatMsg
(
mth
,
"No exception handler block: "
+
handler
));
}
}
Set
<
BlockNode
>
exits
=
new
HashSet
<>();
...
...
@@ -912,7 +912,7 @@ public class RegionMaker {
for
(
BlockNode
handler
:
blocks
)
{
List
<
BlockNode
>
s
=
splitter
.
getSuccessors
();
if
(
s
.
isEmpty
())
{
LOG
.
debug
(
ErrorsCounter
.
format
Error
Msg
(
mth
,
"No successors for splitter: "
+
splitter
));
LOG
.
debug
(
ErrorsCounter
.
formatMsg
(
mth
,
"No successors for splitter: "
+
splitter
));
continue
;
}
BlockNode
ss
=
s
.
get
(
0
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/typeinference/CheckTypeVisitor.java
View file @
0c041120
...
...
@@ -23,6 +23,6 @@ public class CheckTypeVisitor {
}
private
static
void
error
(
String
msg
,
MethodNode
mth
,
InsnNode
insn
)
{
ErrorsCounter
.
method
Error
(
mth
,
msg
+
": "
+
insn
);
ErrorsCounter
.
method
Warn
(
mth
,
msg
+
": "
+
insn
);
}
}
jadx-core/src/main/java/jadx/core/utils/ErrorsCounter.java
View file @
0c041120
...
...
@@ -11,9 +11,12 @@ import org.slf4j.Logger;
import
org.slf4j.LoggerFactory
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.IAttributeNode
;
import
jadx.core.dex.attributes.nodes.JadxErrorAttr
;
import
jadx.core.dex.attributes.nodes.JadxError
;
import
jadx.core.dex.attributes.nodes.JadxWarn
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.IDexNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.utils.exceptions.JadxOverflowException
;
...
...
@@ -22,34 +25,53 @@ public class ErrorsCounter {
private
final
Set
<
IAttributeNode
>
errorNodes
=
new
HashSet
<>();
private
int
errorsCount
;
private
final
Set
<
IAttributeNode
>
warnNodes
=
new
HashSet
<>();
private
int
warnsCount
;
public
int
getErrorCount
()
{
return
errorsCount
;
}
private
synchronized
void
addError
(
IAttributeNode
node
,
String
msg
,
@Nullable
Throwable
e
)
{
public
int
getWarnsCount
()
{
return
warnsCount
;
}
private
synchronized
<
N
extends
IDexNode
&
IAttributeNode
>
String
addError
(
N
node
,
String
error
,
@Nullable
Throwable
e
)
{
errorNodes
.
add
(
node
);
errorsCount
++;
if
(
e
!=
null
)
{
if
(
e
instanceof
JadxOverflowException
)
{
String
msg
=
formatMsg
(
node
,
error
);
if
(
e
==
null
)
{
LOG
.
error
(
msg
);
}
else
if
(
e
instanceof
JadxOverflowException
)
{
// don't print full stack trace
e
=
new
JadxOverflowException
(
e
.
getMessage
());
LOG
.
error
(
"{}, message
: {}"
,
msg
,
e
.
getMessage
());
LOG
.
error
(
"{}, details
: {}"
,
msg
,
e
.
getMessage
());
}
else
{
LOG
.
error
(
msg
,
e
);
}
node
.
addAttr
(
new
JadxErrorAttr
(
e
));
}
else
{
node
.
addAttr
(
AType
.
JADX_ERROR
,
new
JadxError
(
error
,
e
));
node
.
remove
(
AFlag
.
INCONSISTENT_CODE
);
return
msg
;
}
private
synchronized
<
N
extends
IDexNode
&
IAttributeNode
>
String
addWarning
(
N
node
,
String
warn
)
{
warnNodes
.
add
(
node
);
warnsCount
++;
node
.
addAttr
(
AType
.
JADX_WARN
,
new
JadxWarn
(
warn
));
if
(!
node
.
contains
(
AType
.
JADX_ERROR
))
{
node
.
add
(
AFlag
.
INCONSISTENT_CODE
);
LOG
.
error
(
msg
);
}
String
msg
=
formatMsg
(
node
,
warn
);
LOG
.
warn
(
msg
);
return
msg
;
}
public
static
String
classError
(
ClassNode
cls
,
String
errorMsg
,
Throwable
e
)
{
String
msg
=
formatErrorMsg
(
cls
,
errorMsg
);
cls
.
dex
().
root
().
getErrorsCounter
().
addError
(
cls
,
msg
,
e
);
return
msg
;
return
cls
.
dex
().
root
().
getErrorsCounter
().
addError
(
cls
,
errorMsg
,
e
);
}
public
static
String
classError
(
ClassNode
cls
,
String
errorMsg
)
{
...
...
@@ -57,13 +79,15 @@ public class ErrorsCounter {
}
public
static
String
methodError
(
MethodNode
mth
,
String
errorMsg
,
Throwable
e
)
{
String
msg
=
formatErrorMsg
(
mth
,
errorMsg
);
mth
.
dex
().
root
().
getErrorsCounter
().
addError
(
mth
,
msg
,
e
);
return
msg
;
return
mth
.
root
().
getErrorsCounter
().
addError
(
mth
,
errorMsg
,
e
);
}
public
static
String
methodError
(
MethodNode
mth
,
String
errorMsg
)
{
return
methodError
(
mth
,
errorMsg
,
null
);
public
static
String
methodWarn
(
MethodNode
mth
,
String
warnMsg
)
{
return
mth
.
root
().
getErrorsCounter
().
addWarning
(
mth
,
warnMsg
);
}
public
static
String
formatMsg
(
IDexNode
node
,
String
msg
)
{
return
msg
+
" in "
+
node
.
typeName
()
+
": "
+
node
+
", dex: "
+
node
.
dex
().
getDexFile
().
getName
();
}
public
void
printReport
()
{
...
...
@@ -79,13 +103,8 @@ public class ErrorsCounter {
LOG
.
error
(
" {}"
,
err
);
}
}
if
(
getWarnsCount
()
>
0
)
{
LOG
.
warn
(
"{} warnings in {} nodes"
,
getWarnsCount
(),
warnNodes
.
size
());
}
public
static
String
formatErrorMsg
(
ClassNode
cls
,
String
msg
)
{
return
msg
+
" in class: "
+
cls
+
", dex: "
+
cls
.
dex
().
getDexFile
().
getName
();
}
public
static
String
formatErrorMsg
(
MethodNode
mth
,
String
msg
)
{
return
msg
+
" in method: "
+
mth
+
", dex: "
+
mth
.
dex
().
getDexFile
().
getName
();
}
}
jadx-core/src/main/java/jadx/core/utils/Utils.java
View file @
0c041120
package
jadx
.
core
.
utils
;
import
java.io.OutputStream
;
import
java.io.PrintWriter
;
import
java.io.StringWriter
;
import
java.util.Arrays
;
...
...
@@ -9,6 +10,7 @@ import java.util.List;
import
java.util.function.Function
;
import
jadx.api.JadxDecompiler
;
import
jadx.core.codegen.CodeWriter
;
public
class
Utils
{
...
...
@@ -80,6 +82,30 @@ public class Utils {
return
sw
.
getBuffer
().
toString
();
}
public
static
void
appendStackTrace
(
CodeWriter
code
,
Throwable
throwable
)
{
if
(
throwable
==
null
)
{
return
;
}
code
.
startLine
();
OutputStream
w
=
new
OutputStream
()
{
@Override
public
void
write
(
int
b
)
{
char
c
=
(
char
)
b
;
if
(
c
==
'\r'
)
{
// ignore
}
else
if
(
c
==
'\n'
)
{
code
.
startLine
();
}
else
{
code
.
add
(
c
);
}
}
};
PrintWriter
pw
=
new
PrintWriter
(
w
,
true
);
filterRecursive
(
throwable
);
throwable
.
printStackTrace
(
pw
);
pw
.
flush
();
}
private
static
void
filterRecursive
(
Throwable
th
)
{
try
{
filter
(
th
);
...
...
jadx-core/src/main/java/jadx/core/utils/exceptions/JadxException.java
View file @
0c041120
...
...
@@ -17,11 +17,11 @@ public class JadxException extends Exception {
}
public
JadxException
(
ClassNode
cls
,
String
msg
,
Throwable
th
)
{
super
(
ErrorsCounter
.
format
Error
Msg
(
cls
,
msg
),
th
);
super
(
ErrorsCounter
.
formatMsg
(
cls
,
msg
),
th
);
}
public
JadxException
(
MethodNode
mth
,
String
msg
,
Throwable
th
)
{
super
(
ErrorsCounter
.
format
Error
Msg
(
mth
,
msg
),
th
);
super
(
ErrorsCounter
.
formatMsg
(
mth
,
msg
),
th
);
}
}
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