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
948f9456
Commit
948f9456
authored
Feb 10, 2018
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: change jadx args api for easier processing and validation
parent
32f94b46
Hide whitespace changes
Inline
Side-by-side
Showing
32 changed files
with
461 additions
and
512 deletions
+461
-512
JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+4
-38
JadxCLIArgs.java
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+44
-78
JadxCLIArgsTest.java
jadx-cli/src/test/java/jadx/cli/JadxCLIArgsTest.java
+1
-1
IJadxArgs.java
jadx-core/src/main/java/jadx/api/IJadxArgs.java
+0
-51
JadxArgs.java
jadx-core/src/main/java/jadx/api/JadxArgs.java
+39
-39
JadxArgsValidator.java
jadx-core/src/main/java/jadx/api/JadxArgsValidator.java
+89
-0
JadxDecompiler.java
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
+52
-94
Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+16
-17
ClassGen.java
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
+3
-3
CodeGen.java
jadx-core/src/main/java/jadx/core/codegen/CodeGen.java
+1
-9
Deobfuscator.java
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
+4
-4
ConstStorage.java
jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java
+2
-2
ClassNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
+2
-2
DexNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
+1
-1
RootNode.java
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
+25
-26
DotGraphVisitor.java
...src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
+23
-19
RenameVisitor.java
...e/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
+2
-3
SaveCode.java
jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java
+2
-2
DebugUtils.java
jadx-core/src/main/java/jadx/core/utils/DebugUtils.java
+3
-3
StringUtils.java
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
+3
-3
FileUtils.java
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
+8
-0
TestAPI.groovy
jadx-core/src/test/groovy/jadx/tests/TestAPI.groovy
+0
-68
JadxArgsValidatorOutDirsTest.java
.../src/test/java/jadx/api/JadxArgsValidatorOutDirsTest.java
+72
-0
JadxDecompilerTest.java
jadx-core/src/test/java/jadx/api/JadxDecompilerTest.java
+23
-0
IntegrationTest.java
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
+8
-8
JadxVisitorsOrderTest.java
...est/java/jadx/tests/functional/JadxVisitorsOrderTest.java
+1
-2
JadxGUI.java
jadx-gui/src/main/java/jadx/gui/JadxGUI.java
+6
-14
JadxWrapper.java
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
+13
-13
JadxSettings.java
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
+4
-3
JadxSettingsWindow.java
...i/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
+3
-2
MainWindow.java
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
+5
-5
JSourcesTest.java
jadx-gui/src/test/java/jadx/gui/treemodel/JSourcesTest.java
+2
-2
No files found.
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
View file @
948f9456
package
jadx
.
cli
;
import
java.io.File
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.JadxDecompiler
;
import
jadx.core.utils.exceptions.JadxException
;
public
class
JadxCLI
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxCLI
.
class
);
...
...
@@ -14,7 +11,7 @@ public class JadxCLI {
public
static
void
main
(
String
[]
args
)
{
try
{
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
();
if
(
processArgs
(
jadxArgs
,
args
))
{
if
(
jadxArgs
.
processArgs
(
args
))
{
processAndSave
(
jadxArgs
);
}
}
catch
(
Exception
e
)
{
...
...
@@ -23,10 +20,9 @@ public class JadxCLI {
}
}
static
void
processAndSave
(
JadxCLIArgs
jadxArgs
)
throws
JadxException
{
JadxDecompiler
jadx
=
new
JadxDecompiler
(
jadxArgs
);
jadx
.
setOutputDir
(
jadxArgs
.
getOutDir
());
jadx
.
loadFiles
(
jadxArgs
.
getInput
());
static
void
processAndSave
(
JadxCLIArgs
inputArgs
)
{
JadxDecompiler
jadx
=
new
JadxDecompiler
(
inputArgs
.
toJadxArgs
());
jadx
.
load
();
jadx
.
save
();
if
(
jadx
.
getErrorsCount
()
!=
0
)
{
jadx
.
printErrorsReport
();
...
...
@@ -35,34 +31,4 @@ public class JadxCLI {
LOG
.
info
(
"done"
);
}
}
static
boolean
processArgs
(
JadxCLIArgs
jadxArgs
,
String
[]
args
)
throws
JadxException
{
if
(!
jadxArgs
.
processArgs
(
args
))
{
return
false
;
}
if
(
jadxArgs
.
getInput
().
isEmpty
())
{
LOG
.
error
(
"Please specify input file"
);
jadxArgs
.
printUsage
();
return
false
;
}
File
outputDir
=
jadxArgs
.
getOutDir
();
if
(
outputDir
==
null
)
{
String
outDirName
;
File
file
=
jadxArgs
.
getInput
().
get
(
0
);
String
name
=
file
.
getName
();
int
pos
=
name
.
lastIndexOf
(
'.'
);
if
(
pos
!=
-
1
)
{
outDirName
=
name
.
substring
(
0
,
pos
);
}
else
{
outDirName
=
name
+
"-jadx-out"
;
}
LOG
.
info
(
"output directory: {}"
,
outDirName
);
outputDir
=
new
File
(
outDirName
);
jadxArgs
.
setOutputDir
(
outputDir
);
}
if
(
outputDir
.
exists
()
&&
!
outputDir
.
isDirectory
())
{
throw
new
JadxException
(
"Output directory exists as file "
+
outputDir
);
}
return
true
;
}
}
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
View file @
948f9456
package
jadx
.
cli
;
import
java.io.File
;
import
java.io.PrintStream
;
import
java.lang.reflect.Field
;
import
java.util.ArrayList
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.stream.Collectors
;
import
ch.qos.logback.classic.spi.ILoggingEvent
;
import
ch.qos.logback.core.Appender
;
...
...
@@ -18,28 +18,27 @@ import com.beust.jcommander.ParameterException;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.
I
JadxArgs
;
import
jadx.api.JadxArgs
;
import
jadx.api.JadxDecompiler
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.files.FileUtils
;
public
class
JadxCLIArgs
implements
IJadxArgs
{
protected
static
final
int
DEFAULT_THREADS_COUNT
=
Math
.
max
(
1
,
Runtime
.
getRuntime
().
availableProcessors
()
/
2
);
public
class
JadxCLIArgs
{
@Parameter
(
description
=
"<input file> (.dex, .apk, .jar or .class)"
)
protected
List
<
String
>
files
;
protected
List
<
String
>
files
=
new
ArrayList
<>(
1
)
;
@Parameter
(
names
=
{
"-d"
,
"--output-dir"
},
description
=
"output directory"
)
protected
String
outDir
Name
;
protected
String
outDir
;
@Parameter
(
names
=
{
"-ds"
,
"--output-dir-src"
},
description
=
"output directory for sources"
)
protected
String
outDir
Name
Src
;
protected
String
outDirSrc
;
@Parameter
(
names
=
{
"-dr"
,
"--output-dir-res"
},
description
=
"output directory for resources"
)
protected
String
outDir
Name
Res
;
protected
String
outDirRes
;
@Parameter
(
names
=
{
"-j"
,
"--threads-count"
},
description
=
"processing threads count"
)
protected
int
threadsCount
=
DEFAULT_THREADS_COUNT
;
protected
int
threadsCount
=
JadxArgs
.
DEFAULT_THREADS_COUNT
;
@Parameter
(
names
=
{
"-r"
,
"--no-res"
},
description
=
"do not decode resources"
)
protected
boolean
skipResources
=
false
;
...
...
@@ -94,11 +93,6 @@ public class JadxCLIArgs implements IJadxArgs {
@Parameter
(
names
=
{
"-h"
,
"--help"
},
description
=
"print this help"
,
help
=
true
)
protected
boolean
printHelp
=
false
;
private
final
List
<
File
>
input
=
new
ArrayList
<>(
1
);
private
File
outputDir
;
private
File
outputDirSrc
;
private
File
outputDirRes
;
public
boolean
processArgs
(
String
[]
args
)
{
return
parse
(
args
)
&&
process
();
}
...
...
@@ -123,35 +117,6 @@ public class JadxCLIArgs implements IJadxArgs {
if
(
threadsCount
<=
0
)
{
throw
new
JadxException
(
"Threads count must be positive, got: "
+
threadsCount
);
}
if
(
files
!=
null
)
{
for
(
String
fileName
:
files
)
{
File
file
=
new
File
(
fileName
);
if
(
file
.
exists
())
{
input
.
add
(
file
);
}
else
{
throw
new
JadxException
(
"File not found: "
+
file
);
}
}
}
if
(
input
.
size
()
>
1
)
{
throw
new
JadxException
(
"Only one input file is supported"
);
}
if
(
outDirNameSrc
!=
null
)
{
outputDirSrc
=
new
File
(
outDirNameSrc
);
}
if
(
outDirNameRes
!=
null
)
{
outputDirRes
=
new
File
(
outDirNameRes
);
}
if
(
outDirName
!=
null
)
{
outputDir
=
new
File
(
outDirName
);
if
(
outputDirSrc
==
null
)
{
outputDirSrc
=
new
File
(
outputDir
,
"source"
);
}
if
(
outputDirRes
==
null
)
{
outputDirRes
=
new
File
(
outputDir
,
"res"
);
}
}
if
(
isVerbose
())
{
ch
.
qos
.
logback
.
classic
.
Logger
rootLogger
=
(
ch
.
qos
.
logback
.
classic
.
Logger
)
LoggerFactory
.
getLogger
(
Logger
.
ROOT_LOGGER_NAME
);
...
...
@@ -212,6 +177,31 @@ public class JadxCLIArgs implements IJadxArgs {
}
}
public
JadxArgs
toJadxArgs
()
{
JadxArgs
args
=
new
JadxArgs
();
args
.
setInputFiles
(
files
.
stream
().
map
(
FileUtils:
:
toFile
).
collect
(
Collectors
.
toList
()));
args
.
setOutDir
(
FileUtils
.
toFile
(
outDir
));
args
.
setOutDirSrc
(
FileUtils
.
toFile
(
outDirSrc
));
args
.
setOutDirRes
(
FileUtils
.
toFile
(
outDirRes
));
args
.
setThreadsCount
(
threadsCount
);
args
.
setSkipSources
(
skipSources
);
args
.
setSkipResources
(
skipResources
);
args
.
setFallbackMode
(
fallbackMode
);
args
.
setShowInconsistentCode
(
showInconsistentCode
);
args
.
setCfgOutput
(
cfgOutput
);
args
.
setRawCFGOutput
(
rawCfgOutput
);
args
.
setReplaceConsts
(
replaceConsts
);
args
.
setDeobfuscationOn
(
deobfuscationOn
);
args
.
setDeobfuscationForceSave
(
deobfuscationForceSave
);
args
.
setDeobfuscationMinLength
(
deobfuscationMinLength
);
args
.
setDeobfuscationMaxLength
(
deobfuscationMaxLength
);
args
.
setUseSourceNameAsClassAlias
(
deobfuscationUseSourceNameAsAlias
);
args
.
setEscapeUnicode
(
escapeUnicode
);
args
.
setExportAsGradleProject
(
exportAsGradleProject
);
args
.
setUseImports
(
useImports
);
return
args
;
}
public
static
class
InvertedBooleanConverter
implements
IStringConverter
<
Boolean
>
{
@Override
public
Boolean
convert
(
String
value
)
{
...
...
@@ -219,114 +209,90 @@ public class JadxCLIArgs implements IJadxArgs {
}
}
public
List
<
File
>
getInput
()
{
return
input
;
}
@Override
public
File
getOutDir
()
{
return
outputDir
;
public
List
<
String
>
getFiles
()
{
return
files
;
}
@Override
public
File
getOutDirSrc
()
{
return
outputDirSrc
;
public
String
getOutDir
()
{
return
outDir
;
}
@Override
public
File
getOutDirRes
()
{
return
outputDirRes
;
public
String
getOutDirSrc
()
{
return
outDirSrc
;
}
public
void
setOutputDir
(
File
outputDir
)
{
this
.
outputDir
=
outputDir
;
public
String
getOutDirRes
(
)
{
return
outDirRes
;
}
public
boolean
isPrintHelp
()
{
return
printHelp
;
}
@Override
public
boolean
isSkipResources
()
{
return
skipResources
;
}
@Override
public
boolean
isSkipSources
()
{
return
skipSources
;
}
@Override
public
int
getThreadsCount
()
{
return
threadsCount
;
}
@Override
public
boolean
isCFGOutput
()
{
return
cfgOutput
;
}
@Override
public
boolean
isRawCFGOutput
()
{
return
rawCfgOutput
;
}
@Override
public
boolean
isFallbackMode
()
{
return
fallbackMode
;
}
@Override
public
boolean
isShowInconsistentCode
()
{
return
showInconsistentCode
;
}
@Override
public
boolean
isUsingImports
()
{
public
boolean
isUseImports
()
{
return
useImports
;
}
@Override
public
boolean
isVerbose
()
{
return
verbose
;
}
@Override
public
boolean
isDeobfuscationOn
()
{
return
deobfuscationOn
;
}
@Override
public
int
getDeobfuscationMinLength
()
{
return
deobfuscationMinLength
;
}
@Override
public
int
getDeobfuscationMaxLength
()
{
return
deobfuscationMaxLength
;
}
@Override
public
boolean
isDeobfuscationForceSave
()
{
return
deobfuscationForceSave
;
}
@Override
public
boolean
useSourceNameAsClassAlias
()
{
public
boolean
isDeobfuscationUseSourceNameAsAlias
()
{
return
deobfuscationUseSourceNameAsAlias
;
}
@Override
public
boolean
escapeUnicode
()
{
return
escapeUnicode
;
}
@Override
public
boolean
isReplaceConsts
()
{
return
replaceConsts
;
}
@Override
public
boolean
isExportAsGradleProject
()
{
return
exportAsGradleProject
;
}
...
...
jadx-cli/src/test/java/jadx/cli/JadxCLIArgsTest.java
View file @
948f9456
...
...
@@ -8,7 +8,7 @@ import static org.junit.Assert.assertThat;
public
class
JadxCLIArgsTest
{
@Test
public
void
testInvertedBooleanOption
()
throws
Exception
{
public
void
testInvertedBooleanOption
()
{
assertThat
(
parse
(
"--no-replace-consts"
).
isReplaceConsts
(),
is
(
false
));
assertThat
(
parse
(
""
).
isReplaceConsts
(),
is
(
true
));
}
...
...
jadx-core/src/main/java/jadx/api/IJadxArgs.java
deleted
100644 → 0
View file @
32f94b46
package
jadx
.
api
;
import
java.io.File
;
public
interface
IJadxArgs
{
File
getOutDir
();
File
getOutDirSrc
();
File
getOutDirRes
();
int
getThreadsCount
();
boolean
isCFGOutput
();
boolean
isRawCFGOutput
();
boolean
isFallbackMode
();
boolean
isShowInconsistentCode
();
boolean
isUsingImports
();
boolean
isVerbose
();
boolean
isSkipResources
();
boolean
isSkipSources
();
boolean
isDeobfuscationOn
();
int
getDeobfuscationMinLength
();
int
getDeobfuscationMaxLength
();
boolean
isDeobfuscationForceSave
();
boolean
useSourceNameAsClassAlias
();
boolean
escapeUnicode
();
/**
* Replace constant values with static final fields with same value
*/
boolean
isReplaceConsts
();
/**
* Save as gradle project
*/
boolean
isExportAsGradleProject
();
}
jadx-core/src/main/java/jadx/api/JadxArgs.java
View file @
948f9456
package
jadx
.
api
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
public
class
JadxArgs
implements
IJadxArgs
{
public
class
JadxArgs
{
private
File
outDir
=
new
File
(
"jadx-output"
);
private
File
outDirSrc
=
new
File
(
outDir
,
"source"
);
private
File
outDirRes
=
new
File
(
outDir
,
"res"
);
private
int
threadsCount
=
Math
.
max
(
1
,
Runtime
.
getRuntime
().
availableProcessors
()
-
1
);
public
static
final
int
DEFAULT_THREADS_COUNT
=
Math
.
max
(
1
,
Runtime
.
getRuntime
().
availableProcessors
()
/
2
);
public
static
final
String
DEFAULT_OUT_DIR
=
"jadx-output"
;
public
static
final
String
DEFAULT_SRC_DIR
=
"sources"
;
public
static
final
String
DEFAULT_RES_DIR
=
"resources"
;
private
List
<
File
>
inputFiles
=
new
ArrayList
<>(
1
);
private
File
outDir
;
private
File
outDirSrc
;
private
File
outDirRes
;
private
int
threadsCount
=
DEFAULT_THREADS_COUNT
;
private
boolean
cfgOutput
=
false
;
private
boolean
rawCFGOutput
=
false
;
private
boolean
isVerbose
=
false
;
private
boolean
fallbackMode
=
false
;
private
boolean
showInconsistentCode
=
false
;
private
boolean
useImports
=
true
;
private
boolean
isSkipResources
=
false
;
...
...
@@ -32,7 +42,24 @@ public class JadxArgs implements IJadxArgs {
private
boolean
replaceConsts
=
true
;
private
boolean
exportAsGradleProject
=
false
;
@Override
public
JadxArgs
()
{
// use default options
}
public
void
setRootDir
(
File
rootDir
)
{
setOutDir
(
rootDir
);
setOutDirSrc
(
new
File
(
rootDir
,
DEFAULT_SRC_DIR
));
setOutDirRes
(
new
File
(
rootDir
,
DEFAULT_RES_DIR
));
}
public
List
<
File
>
getInputFiles
()
{
return
inputFiles
;
}
public
void
setInputFiles
(
List
<
File
>
inputFiles
)
{
this
.
inputFiles
=
inputFiles
;
}
public
File
getOutDir
()
{
return
outDir
;
}
...
...
@@ -41,7 +68,6 @@ public class JadxArgs implements IJadxArgs {
this
.
outDir
=
outDir
;
}
@Override
public
File
getOutDirSrc
()
{
return
outDirSrc
;
}
...
...
@@ -50,7 +76,6 @@ public class JadxArgs implements IJadxArgs {
this
.
outDirSrc
=
outDirSrc
;
}
@Override
public
File
getOutDirRes
()
{
return
outDirRes
;
}
...
...
@@ -59,7 +84,6 @@ public class JadxArgs implements IJadxArgs {
this
.
outDirRes
=
outDirRes
;
}
@Override
public
int
getThreadsCount
()
{
return
threadsCount
;
}
...
...
@@ -68,8 +92,7 @@ public class JadxArgs implements IJadxArgs {
this
.
threadsCount
=
threadsCount
;
}
@Override
public
boolean
isCFGOutput
()
{
public
boolean
isCfgOutput
()
{
return
cfgOutput
;
}
...
...
@@ -77,7 +100,6 @@ public class JadxArgs implements IJadxArgs {
this
.
cfgOutput
=
cfgOutput
;
}
@Override
public
boolean
isRawCFGOutput
()
{
return
rawCFGOutput
;
}
...
...
@@ -86,7 +108,6 @@ public class JadxArgs implements IJadxArgs {
this
.
rawCFGOutput
=
rawCFGOutput
;
}
@Override
public
boolean
isFallbackMode
()
{
return
fallbackMode
;
}
...
...
@@ -95,7 +116,6 @@ public class JadxArgs implements IJadxArgs {
this
.
fallbackMode
=
fallbackMode
;
}
@Override
public
boolean
isShowInconsistentCode
()
{
return
showInconsistentCode
;
}
...
...
@@ -104,8 +124,7 @@ public class JadxArgs implements IJadxArgs {
this
.
showInconsistentCode
=
showInconsistentCode
;
}
@Override
public
boolean
isUsingImports
()
{
public
boolean
isUseImports
()
{
return
useImports
;
}
...
...
@@ -113,16 +132,6 @@ public class JadxArgs implements IJadxArgs {
this
.
useImports
=
useImports
;
}
@Override
public
boolean
isVerbose
()
{
return
isVerbose
;
}
public
void
setVerbose
(
boolean
verbose
)
{
isVerbose
=
verbose
;
}
@Override
public
boolean
isSkipResources
()
{
return
isSkipResources
;
}
...
...
@@ -131,7 +140,6 @@ public class JadxArgs implements IJadxArgs {
isSkipResources
=
skipResources
;
}
@Override
public
boolean
isSkipSources
()
{
return
isSkipSources
;
}
...
...
@@ -140,7 +148,6 @@ public class JadxArgs implements IJadxArgs {
isSkipSources
=
skipSources
;
}
@Override
public
boolean
isDeobfuscationOn
()
{
return
isDeobfuscationOn
;
}
...
...
@@ -149,7 +156,6 @@ public class JadxArgs implements IJadxArgs {
isDeobfuscationOn
=
deobfuscationOn
;
}
@Override
public
boolean
isDeobfuscationForceSave
()
{
return
isDeobfuscationForceSave
;
}
...
...
@@ -158,8 +164,7 @@ public class JadxArgs implements IJadxArgs {
isDeobfuscationForceSave
=
deobfuscationForceSave
;
}
@Override
public
boolean
useSourceNameAsClassAlias
()
{
public
boolean
isUseSourceNameAsClassAlias
()
{
return
useSourceNameAsClassAlias
;
}
...
...
@@ -167,7 +172,6 @@ public class JadxArgs implements IJadxArgs {
this
.
useSourceNameAsClassAlias
=
useSourceNameAsClassAlias
;
}
@Override
public
int
getDeobfuscationMinLength
()
{
return
deobfuscationMinLength
;
}
...
...
@@ -176,7 +180,6 @@ public class JadxArgs implements IJadxArgs {
this
.
deobfuscationMinLength
=
deobfuscationMinLength
;
}
@Override
public
int
getDeobfuscationMaxLength
()
{
return
deobfuscationMaxLength
;
}
...
...
@@ -185,8 +188,7 @@ public class JadxArgs implements IJadxArgs {
this
.
deobfuscationMaxLength
=
deobfuscationMaxLength
;
}
@Override
public
boolean
escapeUnicode
()
{
public
boolean
isEscapeUnicode
()
{
return
escapeUnicode
;
}
...
...
@@ -194,7 +196,6 @@ public class JadxArgs implements IJadxArgs {
this
.
escapeUnicode
=
escapeUnicode
;
}
@Override
public
boolean
isReplaceConsts
()
{
return
replaceConsts
;
}
...
...
@@ -203,7 +204,6 @@ public class JadxArgs implements IJadxArgs {
this
.
replaceConsts
=
replaceConsts
;
}
@Override
public
boolean
isExportAsGradleProject
()
{
return
exportAsGradleProject
;
}
...
...
jadx-core/src/main/java/jadx/api/JadxArgsValidator.java
0 → 100644
View file @
948f9456
package
jadx
.
api
;
import
java.io.File
;
import
org.jetbrains.annotations.NotNull
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
public
class
JadxArgsValidator
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxArgsValidator
.
class
);
public
static
void
validate
(
JadxArgs
args
)
{
if
(
args
.
getInputFiles
().
isEmpty
())
{
throw
new
JadxRuntimeException
(
"Please specify input file"
);
}
for
(
File
file
:
args
.
getInputFiles
())
{
checkFile
(
file
);
}
validateOutDirs
(
args
);
}
private
static
void
validateOutDirs
(
JadxArgs
args
)
{
File
outDir
=
args
.
getOutDir
();
File
srcDir
=
args
.
getOutDirSrc
();
File
resDir
=
args
.
getOutDirRes
();
if
(
outDir
==
null
)
{
if
(
srcDir
!=
null
)
{
outDir
=
srcDir
;
}
else
if
(
resDir
!=
null
)
{
outDir
=
resDir
;
}
else
{
outDir
=
makeDirFromInput
(
args
);
}
}
args
.
setOutDir
(
outDir
);
setFromOut
(
args
);
checkDir
(
args
.
getOutDir
());
checkDir
(
args
.
getOutDirSrc
());
checkDir
(
args
.
getOutDirRes
());
}
@NotNull
private
static
File
makeDirFromInput
(
JadxArgs
args
)
{
File
outDir
;
String
outDirName
;
File
file
=
args
.
getInputFiles
().
get
(
0
);
String
name
=
file
.
getName
();
int
pos
=
name
.
lastIndexOf
(
'.'
);
if
(
pos
!=
-
1
)
{
outDirName
=
name
.
substring
(
0
,
pos
);
}
else
{
outDirName
=
name
+
"-"
+
JadxArgs
.
DEFAULT_OUT_DIR
;
}
LOG
.
info
(
"output directory: {}"
,
outDirName
);
outDir
=
new
File
(
outDirName
);
return
outDir
;
}
private
static
void
setFromOut
(
JadxArgs
args
)
{
if
(
args
.
getOutDirSrc
()
==
null
)
{
args
.
setOutDirSrc
(
new
File
(
args
.
getOutDir
(),
JadxArgs
.
DEFAULT_SRC_DIR
));
}
if
(
args
.
getOutDirRes
()
==
null
)
{
args
.
setOutDirRes
(
new
File
(
args
.
getOutDir
(),
JadxArgs
.
DEFAULT_RES_DIR
));
}
}
private
static
void
checkFile
(
File
file
)
{
if
(!
file
.
exists
())
{
throw
new
JadxRuntimeException
(
"File not found "
+
file
.
getAbsolutePath
());
}
if
(
file
.
isDirectory
())
{
throw
new
JadxRuntimeException
(
"Expected file but found directory instead: "
+
file
.
getAbsolutePath
());
}
}
private
static
void
checkDir
(
File
dir
)
{
if
(
dir
!=
null
&&
dir
.
exists
()
&&
!
dir
.
isDirectory
())
{
throw
new
JadxRuntimeException
(
"Output directory exists as file "
+
dir
);
}
}
private
JadxArgsValidator
()
{
}
}
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
View file @
948f9456
package
jadx
.
api
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.TimeUnit
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.Jadx
;
import
jadx.core.ProcessClass
;
import
jadx.core.codegen.CodeGen
;
...
...
@@ -11,38 +26,24 @@ import jadx.core.dex.nodes.RootNode;
import
jadx.core.dex.visitors.IDexTreeVisitor
;
import
jadx.core.dex.visitors.SaveCode
;
import
jadx.core.export.ExportGradleProject
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.InputFile
;
import
jadx.core.xmlgen.BinaryXMLParser
;
import
jadx.core.xmlgen.ResourcesSaver
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.concurrent.ConcurrentHashMap
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
java.util.concurrent.TimeUnit
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
/**
* Jadx API usage example:
* <pre><code>
* JadxDecompiler jadx = new JadxDecompiler();
* jadx.loadFile(new File("classes.dex"));
* jadx.setOutputDir(new File("out"));
* jadx.save();
* JadxArgs args = new JadxArgs();
* args.getInputFiles().add(new File("test.apk"));
* args.setOutDir(new File("jadx-test-output"));
*
* JadxDecompiler jadx = new JadxDecompiler(args);
* jadx.load();
* jadx.save();
* </code></pre>
* <p/>
* Instead of 'save()' you can
get list of
decompiled classes:
* Instead of 'save()' you can
iterate over
decompiled classes:
* <pre><code>
* for(JavaClass cls : jadx.getClasses()) {
* System.out.println(cls.getCode());
...
...
@@ -52,12 +53,9 @@ import org.slf4j.LoggerFactory;
public
final
class
JadxDecompiler
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxDecompiler
.
class
);
private
final
IJadxArgs
args
;
private
final
List
<
InputFile
>
inputFiles
=
new
ArrayList
<>();
private
JadxArgs
args
;
private
File
outDir
;
private
File
outDirRes
;
private
File
outDirSrc
;
private
final
List
<
InputFile
>
inputFiles
=
new
ArrayList
<>();
private
RootNode
root
;
private
List
<
IDexTreeVisitor
>
passes
;
...
...
@@ -72,54 +70,35 @@ public final class JadxDecompiler {
private
Map
<
MethodNode
,
JavaMethod
>
methodsMap
=
new
ConcurrentHashMap
<>();
private
Map
<
FieldNode
,
JavaField
>
fieldsMap
=
new
ConcurrentHashMap
<>();
public
JadxDecompiler
()
throws
JadxException
{
public
JadxDecompiler
()
{
this
(
new
JadxArgs
());
}
public
JadxDecompiler
(
IJadxArgs
jadxArgs
)
throws
JadxException
{
this
.
args
=
jadxArgs
;
this
.
outDir
=
jadxArgs
.
getOutDir
();
this
.
outDirSrc
=
jadxArgs
.
getOutDirSrc
();
this
.
outDirRes
=
jadxArgs
.
getOutDirRes
();
reset
();
init
();
public
JadxDecompiler
(
JadxArgs
args
)
{
this
.
args
=
args
;
}
public
void
setOutputDir
(
File
outDir
)
throws
JadxException
{
this
.
outDir
=
outDir
;
public
void
load
()
{
reset
();
JadxArgsValidator
.
validate
(
args
);
init
();
}
LOG
.
info
(
"loading ..."
);
public
void
setOutputDirSrc
(
File
outDirSrc
)
throws
JadxException
{
this
.
outDirSrc
=
outDirSrc
;
init
();
}
loadFiles
(
args
.
getInputFiles
());
public
void
setOutputDirRes
(
File
outDirRes
)
throws
JadxException
{
this
.
outDirRes
=
outDirRes
;
init
();
root
=
new
RootNode
(
args
);
root
.
load
(
inputFiles
);
root
.
initClassPath
();
root
.
loadResources
(
getResources
());
root
.
initAppResClass
();
initVisitors
();
}
void
init
()
throws
JadxException
{
if
(
outDir
==
null
&&
outDirSrc
==
null
)
{
outDirSrc
=
new
JadxArgs
().
getOutDirSrc
();
}
if
(
outDir
==
null
&&
outDirRes
==
null
)
{
outDirRes
=
new
JadxArgs
().
getOutDirRes
();
}
if
(
outDir
==
null
)
{
outDir
=
new
JadxArgs
().
getOutDir
();
}
else
{
if
(
outDirSrc
==
null
&&
outDirRes
!=
null
&&
!
args
.
isSkipSources
())
{
throw
new
JadxException
(
"--output-dir-src must be specified"
);
}
if
(
outDirSrc
!=
null
&&
outDirRes
==
null
&&
!
args
.
isSkipResources
())
{
throw
new
JadxException
(
"--output-dir-res must be specified"
);
}
}
this
.
passes
=
Jadx
.
getPassesList
(
args
,
outDir
);
this
.
codeGen
=
new
CodeGen
(
args
);
void
init
()
{
this
.
passes
=
Jadx
.
getPassesList
(
args
);
this
.
codeGen
=
new
CodeGen
();
}
void
reset
()
{
...
...
@@ -135,23 +114,18 @@ public final class JadxDecompiler {
return
Jadx
.
getVersion
();
}
public
void
loadFile
(
File
file
)
throws
JadxException
{
loadFiles
(
Collections
.
singletonList
(
file
));
}
public
void
loadFiles
(
List
<
File
>
files
)
throws
JadxException
{
private
void
loadFiles
(
List
<
File
>
files
)
{
if
(
files
.
isEmpty
())
{
throw
new
JadxException
(
"Empty file list"
);
throw
new
Jadx
Runtime
Exception
(
"Empty file list"
);
}
inputFiles
.
clear
();
for
(
File
file
:
files
)
{
try
{
InputFile
.
addFilesFrom
(
file
,
inputFiles
,
args
.
isSkipSources
());
}
catch
(
IO
Exception
e
)
{
throw
new
JadxException
(
"Error load file: "
+
file
,
e
);
}
catch
(
Exception
e
)
{
throw
new
Jadx
Runtime
Exception
(
"Error load file: "
+
file
,
e
);
}
}
parse
();
}
public
void
save
()
{
...
...
@@ -194,13 +168,13 @@ public final class JadxDecompiler {
File
sourcesOutDir
;
File
resOutDir
;
if
(
args
.
isExportAsGradleProject
())
{
ExportGradleProject
export
=
new
ExportGradleProject
(
root
,
outDir
);
ExportGradleProject
export
=
new
ExportGradleProject
(
root
,
args
.
getOutDir
()
);
export
.
init
();
sourcesOutDir
=
export
.
getSrcOutDir
();
resOutDir
=
export
.
getResOutDir
();
}
else
{
sourcesOutDir
=
outDirSrc
;
resOutDir
=
outDirRes
;
sourcesOutDir
=
args
.
getOutDirSrc
()
;
resOutDir
=
args
.
getOutDirRes
()
;
}
if
(
saveSources
)
{
appendSourcesSave
(
executor
,
sourcesOutDir
);
...
...
@@ -294,21 +268,6 @@ public final class JadxDecompiler {
root
.
getErrorsCounter
().
printReport
();
}
void
parse
()
throws
JadxException
{
reset
();
init
();
root
=
new
RootNode
(
args
);
LOG
.
info
(
"loading ..."
);
root
.
load
(
inputFiles
);
root
.
initClassPath
();
root
.
loadResources
(
getResources
());
root
.
initAppResClass
();
initVisitors
();
}
private
void
initVisitors
()
{
for
(
IDexTreeVisitor
pass
:
passes
)
{
try
{
...
...
@@ -346,7 +305,7 @@ public final class JadxDecompiler {
return
fieldsMap
;
}
public
I
JadxArgs
getArgs
()
{
public
JadxArgs
getArgs
()
{
return
args
;
}
...
...
@@ -354,5 +313,4 @@ public final class JadxDecompiler {
public
String
toString
()
{
return
"jadx decompiler "
+
getVersion
();
}
}
jadx-core/src/main/java/jadx/core/Jadx.java
View file @
948f9456
package
jadx
.
core
;
import
jadx.api.IJadxArgs
;
import
java.net.URL
;
import
java.util.ArrayList
;
import
java.util.Enumeration
;
import
java.util.List
;
import
java.util.jar.Manifest
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.JadxArgs
;
import
jadx.core.dex.visitors.ClassModifier
;
import
jadx.core.dex.visitors.CodeShrinker
;
import
jadx.core.dex.visitors.ConstInlineVisitor
;
...
...
@@ -33,16 +42,6 @@ import jadx.core.dex.visitors.ssa.SSATransform;
import
jadx.core.dex.visitors.typeinference.FinishTypeInference
;
import
jadx.core.dex.visitors.typeinference.TypeInference
;
import
java.io.File
;
import
java.net.URL
;
import
java.util.ArrayList
;
import
java.util.Enumeration
;
import
java.util.List
;
import
java.util.jar.Manifest
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
Jadx
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
Jadx
.
class
);
...
...
@@ -55,7 +54,7 @@ public class Jadx {
}
}
public
static
List
<
IDexTreeVisitor
>
getPassesList
(
IJadxArgs
args
,
File
outDir
)
{
public
static
List
<
IDexTreeVisitor
>
getPassesList
(
JadxArgs
args
)
{
List
<
IDexTreeVisitor
>
passes
=
new
ArrayList
<>();
if
(
args
.
isFallbackMode
())
{
passes
.
add
(
new
FallbackModeVisitor
());
...
...
@@ -71,7 +70,7 @@ public class Jadx {
passes
.
add
(
new
TypeInference
());
if
(
args
.
isRawCFGOutput
())
{
passes
.
add
(
DotGraphVisitor
.
dumpRaw
(
outDir
));
passes
.
add
(
DotGraphVisitor
.
dumpRaw
());
}
passes
.
add
(
new
ConstInlineVisitor
());
...
...
@@ -83,8 +82,8 @@ public class Jadx {
passes
.
add
(
new
CodeShrinker
());
passes
.
add
(
new
ReSugarCode
());
if
(
args
.
isC
FG
Output
())
{
passes
.
add
(
DotGraphVisitor
.
dump
(
outDir
));
if
(
args
.
isC
fg
Output
())
{
passes
.
add
(
DotGraphVisitor
.
dump
());
}
passes
.
add
(
new
RegionMakerVisitor
());
...
...
@@ -95,8 +94,8 @@ public class Jadx {
passes
.
add
(
new
SimplifyVisitor
());
passes
.
add
(
new
CheckRegions
());
if
(
args
.
isC
FG
Output
())
{
passes
.
add
(
DotGraphVisitor
.
dumpRegions
(
outDir
));
if
(
args
.
isC
fg
Output
())
{
passes
.
add
(
DotGraphVisitor
.
dumpRegions
());
}
passes
.
add
(
new
MethodInlineVisitor
());
...
...
jadx-core/src/main/java/jadx/core/codegen/ClassGen.java
View file @
948f9456
...
...
@@ -12,7 +12,7 @@ import java.util.Set;
import
com.android.dx.rop.code.AccessFlags
;
import
jadx.api.
I
JadxArgs
;
import
jadx.api.JadxArgs
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.AttrNode
;
...
...
@@ -48,8 +48,8 @@ public class ClassGen {
private
final
Set
<
ClassInfo
>
imports
=
new
HashSet
<>();
private
int
clsDeclLine
;
public
ClassGen
(
ClassNode
cls
,
I
JadxArgs
jadxArgs
)
{
this
(
cls
,
null
,
jadxArgs
.
isUs
ing
Imports
(),
jadxArgs
.
isFallbackMode
(),
jadxArgs
.
isShowInconsistentCode
());
public
ClassGen
(
ClassNode
cls
,
JadxArgs
jadxArgs
)
{
this
(
cls
,
null
,
jadxArgs
.
isUs
e
Imports
(),
jadxArgs
.
isFallbackMode
(),
jadxArgs
.
isShowInconsistentCode
());
}
public
ClassGen
(
ClassNode
cls
,
ClassGen
parentClsGen
)
{
...
...
jadx-core/src/main/java/jadx/core/codegen/CodeGen.java
View file @
948f9456
package
jadx
.
core
.
codegen
;
import
jadx.api.IJadxArgs
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.visitors.AbstractVisitor
;
import
jadx.core.utils.exceptions.CodegenException
;
public
class
CodeGen
extends
AbstractVisitor
{
private
final
IJadxArgs
args
;
public
CodeGen
(
IJadxArgs
args
)
{
this
.
args
=
args
;
}
@Override
public
boolean
visit
(
ClassNode
cls
)
throws
CodegenException
{
ClassGen
clsGen
=
new
ClassGen
(
cls
,
args
);
ClassGen
clsGen
=
new
ClassGen
(
cls
,
cls
.
root
().
getArgs
()
);
CodeWriter
clsCode
=
clsGen
.
makeClass
();
clsCode
.
finish
();
cls
.
setCode
(
clsCode
);
return
false
;
}
}
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
View file @
948f9456
package
jadx
.
core
.
deobf
;
import
jadx.api.
I
JadxArgs
;
import
jadx.api.JadxArgs
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.SourceFileAttr
;
import
jadx.core.dex.info.ClassInfo
;
...
...
@@ -34,7 +34,7 @@ public class Deobfuscator {
public
static
final
String
CLASS_NAME_SEPARATOR
=
"."
;
public
static
final
String
INNER_CLASS_SEPARATOR
=
"$"
;
private
final
I
JadxArgs
args
;
private
final
JadxArgs
args
;
@NotNull
private
final
List
<
DexNode
>
dexNodes
;
private
final
DeobfPresets
deobfPresets
;
...
...
@@ -58,13 +58,13 @@ public class Deobfuscator {
private
int
fldIndex
=
0
;
private
int
mthIndex
=
0
;
public
Deobfuscator
(
I
JadxArgs
args
,
@NotNull
List
<
DexNode
>
dexNodes
,
File
deobfMapFile
)
{
public
Deobfuscator
(
JadxArgs
args
,
@NotNull
List
<
DexNode
>
dexNodes
,
File
deobfMapFile
)
{
this
.
args
=
args
;
this
.
dexNodes
=
dexNodes
;
this
.
minLength
=
args
.
getDeobfuscationMinLength
();
this
.
maxLength
=
args
.
getDeobfuscationMaxLength
();
this
.
useSourceNameAsAlias
=
args
.
u
seSourceNameAsClassAlias
();
this
.
useSourceNameAsAlias
=
args
.
isU
seSourceNameAsClassAlias
();
this
.
deobfPresets
=
new
DeobfPresets
(
this
,
deobfMapFile
);
}
...
...
jadx-core/src/main/java/jadx/core/dex/info/ConstStorage.java
View file @
948f9456
...
...
@@ -8,7 +8,7 @@ import java.util.Set;
import
org.jetbrains.annotations.Nullable
;
import
jadx.api.
I
JadxArgs
;
import
jadx.api.JadxArgs
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.instructions.args.LiteralArg
;
import
jadx.core.dex.instructions.args.PrimitiveType
;
...
...
@@ -60,7 +60,7 @@ public class ConstStorage {
private
Map
<
Integer
,
String
>
resourcesNames
=
new
HashMap
<>();
public
ConstStorage
(
I
JadxArgs
args
)
{
public
ConstStorage
(
JadxArgs
args
)
{
this
.
replaceEnabled
=
args
.
isReplaceConsts
();
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/ClassNode.java
View file @
948f9456
...
...
@@ -65,7 +65,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
// cache maps
private
Map
<
MethodInfo
,
MethodNode
>
mthInfoMap
=
Collections
.
emptyMap
();
public
ClassNode
(
DexNode
dex
,
ClassDef
cls
)
throws
DecodeException
{
public
ClassNode
(
DexNode
dex
,
ClassDef
cls
)
{
this
.
dex
=
dex
;
this
.
clsInfo
=
ClassInfo
.
fromDex
(
dex
,
cls
.
getTypeIndex
());
try
{
...
...
@@ -128,7 +128,7 @@ public class ClassNode extends LineAttrNode implements ILoadable, IDexNode {
buildCache
();
}
catch
(
Exception
e
)
{
throw
new
Decod
eException
(
"Error decode class: "
+
clsInfo
,
e
);
throw
new
JadxRuntim
eException
(
"Error decode class: "
+
clsInfo
,
e
);
}
}
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/DexNode.java
View file @
948f9456
...
...
@@ -46,7 +46,7 @@ public class DexNode implements IDexNode {
this
.
dexId
=
dexId
;
}
public
void
loadClasses
()
throws
DecodeException
{
public
void
loadClasses
()
{
for
(
ClassDef
cls
:
dexBuf
.
classDefs
())
{
ClassNode
clsNode
=
new
ClassNode
(
this
,
cls
);
classes
.
add
(
clsNode
);
...
...
jadx-core/src/main/java/jadx/core/dex/nodes/RootNode.java
View file @
948f9456
package
jadx
.
core
.
dex
.
nodes
;
import
jadx.api.IJadxArgs
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.JadxArgs
;
import
jadx.api.ResourceFile
;
import
jadx.api.ResourceType
;
import
jadx.api.ResourcesLoader
;
...
...
@@ -11,28 +20,19 @@ import jadx.core.dex.info.InfoStorage;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.StringUtils
;
import
jadx.core.utils.android.AndroidResourcesUtils
;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.DexFile
;
import
jadx.core.utils.files.InputFile
;
import
jadx.core.xmlgen.ResContainer
;
import
jadx.core.xmlgen.ResTableParser
;
import
jadx.core.xmlgen.ResourceStorage
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.util.ArrayList
;
import
java.util.List
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
RootNode
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
RootNode
.
class
);
private
final
ErrorsCounter
errorsCounter
=
new
ErrorsCounter
();
private
final
I
JadxArgs
args
;
private
final
JadxArgs
args
;
private
final
StringUtils
stringUtils
;
private
final
ConstStorage
constValues
;
private
final
InfoStorage
infoStorage
=
new
InfoStorage
();
...
...
@@ -43,13 +43,13 @@ public class RootNode {
private
ClassNode
appResClass
;
private
ClspGraph
clsp
;
public
RootNode
(
I
JadxArgs
args
)
{
public
RootNode
(
JadxArgs
args
)
{
this
.
args
=
args
;
this
.
stringUtils
=
new
StringUtils
(
args
);
this
.
constValues
=
new
ConstStorage
(
args
);
}
public
void
load
(
List
<
InputFile
>
inputFiles
)
throws
DecodeException
{
public
void
load
(
List
<
InputFile
>
inputFiles
)
{
dexNodes
=
new
ArrayList
<>();
for
(
InputFile
input
:
inputFiles
)
{
for
(
DexFile
dexFile
:
input
.
getDexFiles
())
{
...
...
@@ -58,7 +58,7 @@ public class RootNode {
DexNode
dexNode
=
new
DexNode
(
this
,
dexFile
,
dexNodes
.
size
());
dexNodes
.
add
(
dexNode
);
}
catch
(
Exception
e
)
{
throw
new
Decod
eException
(
"Error decode file: "
+
dexFile
,
e
);
throw
new
JadxRuntim
eException
(
"Error decode file: "
+
dexFile
,
e
);
}
}
}
...
...
@@ -103,22 +103,22 @@ public class RootNode {
appResClass
=
AndroidResourcesUtils
.
searchAppResClass
(
this
);
}
public
void
initClassPath
()
throws
DecodeException
{
public
void
initClassPath
()
{
try
{
if
(
this
.
clsp
==
null
)
{
ClspGraph
c
lsp
=
new
ClspGraph
();
c
lsp
.
load
();
ClspGraph
newC
lsp
=
new
ClspGraph
();
newC
lsp
.
load
();
List
<
ClassNode
>
classes
=
new
ArrayList
<>();
for
(
DexNode
dexNode
:
dexNodes
)
{
classes
.
addAll
(
dexNode
.
getClasses
());
}
c
lsp
.
addApp
(
classes
);
newC
lsp
.
addApp
(
classes
);
this
.
clsp
=
c
lsp
;
this
.
clsp
=
newC
lsp
;
}
}
catch
(
IO
Exception
e
)
{
throw
new
Decod
eException
(
"Error loading classpath"
,
e
);
}
catch
(
Exception
e
)
{
throw
new
JadxRuntim
eException
(
"Error loading classpath"
,
e
);
}
}
...
...
@@ -188,10 +188,6 @@ public class RootNode {
return
appResClass
;
}
public
IJadxArgs
getArgs
()
{
return
args
;
}
public
StringUtils
getStringUtils
()
{
return
stringUtils
;
}
...
...
@@ -204,4 +200,7 @@ public class RootNode {
return
infoStorage
;
}
public
JadxArgs
getArgs
()
{
return
args
;
}
}
jadx-core/src/main/java/jadx/core/dex/visitors/DotGraphVisitor.java
View file @
948f9456
...
...
@@ -23,42 +23,33 @@ import java.util.HashSet;
import
java.util.List
;
import
java.util.Set
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
DotGraphVisitor
extends
AbstractVisitor
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
DotGraphVisitor
.
class
);
private
static
final
String
NL
=
"\\l"
;
private
static
final
boolean
PRINT_DOMINATORS
=
false
;
private
final
File
dir
;
private
final
boolean
useRegions
;
private
final
boolean
rawInsn
;
public
static
DotGraphVisitor
dump
(
File
outDir
)
{
return
new
DotGraphVisitor
(
outDir
,
false
,
false
);
public
static
DotGraphVisitor
dump
()
{
return
new
DotGraphVisitor
(
false
,
false
);
}
public
static
DotGraphVisitor
dumpRaw
(
File
outDir
)
{
return
new
DotGraphVisitor
(
outDir
,
false
,
true
);
public
static
DotGraphVisitor
dumpRaw
()
{
return
new
DotGraphVisitor
(
false
,
true
);
}
public
static
DotGraphVisitor
dumpRegions
(
File
outDir
)
{
return
new
DotGraphVisitor
(
outDir
,
true
,
false
);
public
static
DotGraphVisitor
dumpRegions
()
{
return
new
DotGraphVisitor
(
true
,
false
);
}
public
static
DotGraphVisitor
dumpRawRegions
(
File
outDir
)
{
return
new
DotGraphVisitor
(
outDir
,
true
,
true
);
public
static
DotGraphVisitor
dumpRawRegions
()
{
return
new
DotGraphVisitor
(
true
,
true
);
}
private
DotGraphVisitor
(
File
outDir
,
boolean
useRegions
,
boolean
rawInsn
)
{
this
.
dir
=
outDir
;
private
DotGraphVisitor
(
boolean
useRegions
,
boolean
rawInsn
)
{
this
.
useRegions
=
useRegions
;
this
.
rawInsn
=
rawInsn
;
LOG
.
debug
(
"DOT {}{}graph dump dir: {}"
,
useRegions
?
"regions "
:
""
,
rawInsn
?
"raw "
:
""
,
outDir
.
getAbsolutePath
());
}
@Override
...
...
@@ -66,12 +57,25 @@ public class DotGraphVisitor extends AbstractVisitor {
if
(
mth
.
isNoCode
())
{
return
;
}
new
DumpDotGraph
().
process
(
mth
);
File
outRootDir
=
mth
.
root
().
getArgs
().
getOutDir
();
new
DumpDotGraph
(
outRootDir
).
process
(
mth
);
}
public
void
save
(
File
dir
,
MethodNode
mth
)
{
if
(
mth
.
isNoCode
())
{
return
;
}
new
DumpDotGraph
(
dir
).
process
(
mth
);
}
private
class
DumpDotGraph
{
private
final
CodeWriter
dot
=
new
CodeWriter
();
private
final
CodeWriter
conn
=
new
CodeWriter
();
private
final
File
dir
;
public
DumpDotGraph
(
File
dir
)
{
this
.
dir
=
dir
;
}
public
void
process
(
MethodNode
mth
)
{
dot
.
startLine
(
"digraph \"CFG for"
);
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
View file @
948f9456
...
...
@@ -7,7 +7,7 @@ import java.util.Set;
import
org.apache.commons.io.FilenameUtils
;
import
jadx.api.
I
JadxArgs
;
import
jadx.api.JadxArgs
;
import
jadx.core.Consts
;
import
jadx.core.codegen.TypeGen
;
import
jadx.core.deobf.Deobfuscator
;
...
...
@@ -31,8 +31,6 @@ public class RenameVisitor extends AbstractVisitor {
@Override
public
void
init
(
RootNode
root
)
{
IJadxArgs
args
=
root
.
getArgs
();
List
<
DexNode
>
dexNodes
=
root
.
getDexNodes
();
if
(
dexNodes
.
isEmpty
())
{
return
;
...
...
@@ -43,6 +41,7 @@ public class RenameVisitor extends AbstractVisitor {
String
inputName
=
FilenameUtils
.
getBaseName
(
firstInputFileName
);
File
deobfMapFile
=
new
File
(
inputPath
,
inputName
+
".jobf"
);
JadxArgs
args
=
root
.
getArgs
();
deobfuscator
=
new
Deobfuscator
(
args
,
dexNodes
,
deobfMapFile
);
boolean
deobfuscationOn
=
args
.
isDeobfuscationOn
();
if
(
deobfuscationOn
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/SaveCode.java
View file @
948f9456
...
...
@@ -2,7 +2,7 @@ package jadx.core.dex.visitors;
import
java.io.File
;
import
jadx.api.
I
JadxArgs
;
import
jadx.api.JadxArgs
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.dex.nodes.ClassNode
;
...
...
@@ -10,7 +10,7 @@ public class SaveCode {
private
SaveCode
()
{}
public
static
void
save
(
File
dir
,
I
JadxArgs
args
,
ClassNode
cls
)
{
public
static
void
save
(
File
dir
,
JadxArgs
args
,
ClassNode
cls
)
{
CodeWriter
clsCode
=
cls
.
getCode
();
String
fileName
=
cls
.
getClassInfo
().
getFullPath
()
+
".java"
;
if
(
args
.
isFallbackMode
())
{
...
...
jadx-core/src/main/java/jadx/core/utils/DebugUtils.java
View file @
948f9456
...
...
@@ -44,9 +44,9 @@ public class DebugUtils {
public
static
void
dump
(
MethodNode
mth
,
String
desc
)
{
File
out
=
new
File
(
"test-graph"
+
desc
+
"-tmp"
);
DotGraphVisitor
.
dump
(
out
).
visit
(
mth
);
DotGraphVisitor
.
dumpRaw
(
out
).
visit
(
mth
);
DotGraphVisitor
.
dumpRegions
(
out
).
visit
(
mth
);
DotGraphVisitor
.
dump
(
).
save
(
out
,
mth
);
DotGraphVisitor
.
dumpRaw
(
).
save
(
out
,
mth
);
DotGraphVisitor
.
dumpRegions
(
).
save
(
out
,
mth
);
}
public
static
void
printRegionsWithBlock
(
MethodNode
mth
,
BlockNode
block
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/StringUtils.java
View file @
948f9456
package
jadx
.
core
.
utils
;
import
jadx.api.
I
JadxArgs
;
import
jadx.api.JadxArgs
;
public
class
StringUtils
{
private
final
boolean
escapeUnicode
;
public
StringUtils
(
I
JadxArgs
args
)
{
this
.
escapeUnicode
=
args
.
e
scapeUnicode
();
public
StringUtils
(
JadxArgs
args
)
{
this
.
escapeUnicode
=
args
.
isE
scapeUnicode
();
}
public
String
unescapeString
(
String
str
)
{
...
...
jadx-core/src/main/java/jadx/core/utils/files/FileUtils.java
View file @
948f9456
...
...
@@ -214,4 +214,12 @@ public class FileUtils {
}
return
IOCase
.
SYSTEM
.
isCaseSensitive
();
}
public
static
File
toFile
(
String
path
)
{
if
(
path
==
null
)
{
return
null
;
}
return
new
File
(
path
);
}
}
jadx-core/src/test/groovy/jadx/tests/TestAPI.groovy
deleted
100644 → 0
View file @
32f94b46
package
jadx.tests
import
jadx.api.IJadxArgs
import
jadx.api.JadxDecompiler
import
jadx.core.utils.exceptions.JadxException
import
jadx.core.utils.exceptions.JadxRuntimeException
import
spock.lang.Specification
class
TestAPI
extends
Specification
{
def
"no loaded files"
()
{
setup:
def
d
=
new
JadxDecompiler
()
when:
def
classes
=
d
.
getClasses
()
def
packages
=
d
.
getPackages
()
then:
notThrown
(
NullPointerException
)
classes
?.
isEmpty
()
packages
?.
isEmpty
()
}
def
"save with no loaded files"
()
{
when:
new
JadxDecompiler
().
save
()
then:
def
e
=
thrown
(
JadxRuntimeException
)
e
.
message
==
"No loaded files"
}
def
"load empty files list"
()
{
when:
new
JadxDecompiler
().
loadFiles
(
Collections
.
emptyList
())
then:
def
e
=
thrown
(
JadxException
)
e
.
message
==
"Empty file list"
}
def
"load null"
()
{
when:
new
JadxDecompiler
().
loadFile
(
null
)
then:
thrown
(
NullPointerException
)
}
def
"load missing file"
()
{
when:
new
JadxDecompiler
().
loadFile
(
new
File
(
"_.dex"
))
then:
def
e
=
thrown
(
JadxException
)
e
.
message
==
"Error load file: _.dex"
e
.
cause
.
class
==
IOException
}
def
"pass decompiler args"
()
{
setup:
def
args
=
Mock
(
IJadxArgs
)
when:
new
JadxDecompiler
(
args
)
then:
noExceptionThrown
()
}
def
"get errors count for new decompiler"
()
{
expect:
new
JadxDecompiler
().
getErrorsCount
()
==
0
}
}
jadx-core/src/test/java/jadx/api/JadxArgsValidatorOutDirsTest.java
0 → 100644
View file @
948f9456
package
jadx
.
api
;
import
org.junit.Test
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.utils.files.FileUtils
;
import
static
jadx
.
core
.
utils
.
files
.
FileUtils
.
toFile
;
import
static
org
.
hamcrest
.
Matchers
.
is
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
JadxArgsValidatorOutDirsTest
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxArgsValidatorOutDirsTest
.
class
);
public
JadxArgs
args
;
@Test
public
void
checkAllSet
()
{
setOutDirs
(
"r"
,
"s"
,
"r"
);
checkOutDirs
(
"r"
,
"s"
,
"r"
);
}
@Test
public
void
checkRootOnly
()
{
setOutDirs
(
"out"
,
null
,
null
);
checkOutDirs
(
"out"
,
"out/"
+
JadxArgs
.
DEFAULT_SRC_DIR
,
"out/"
+
JadxArgs
.
DEFAULT_RES_DIR
);
}
@Test
public
void
checkSrcOnly
()
{
setOutDirs
(
null
,
"src"
,
null
);
checkOutDirs
(
"src"
,
"src"
,
"src/"
+
JadxArgs
.
DEFAULT_RES_DIR
);
}
@Test
public
void
checkResOnly
()
{
setOutDirs
(
null
,
null
,
"res"
);
checkOutDirs
(
"res"
,
"res/"
+
JadxArgs
.
DEFAULT_SRC_DIR
,
"res"
);
}
@Test
public
void
checkNone
()
{
setOutDirs
(
null
,
null
,
null
);
String
inputFileBase
=
args
.
getInputFiles
().
get
(
0
).
getName
().
replace
(
".apk"
,
""
);
checkOutDirs
(
inputFileBase
,
inputFileBase
+
"/"
+
JadxArgs
.
DEFAULT_SRC_DIR
,
inputFileBase
+
"/"
+
JadxArgs
.
DEFAULT_RES_DIR
);
}
private
void
setOutDirs
(
String
outDir
,
String
srcDir
,
String
resDir
)
{
args
=
makeArgs
();
args
.
setOutDir
(
toFile
(
outDir
));
args
.
setOutDirSrc
(
toFile
(
srcDir
));
args
.
setOutDirRes
(
toFile
(
resDir
));
LOG
.
debug
(
"Set dirs: out={}, src={}, res={}"
,
outDir
,
srcDir
,
resDir
);
}
private
void
checkOutDirs
(
String
outDir
,
String
srcDir
,
String
resDir
)
{
JadxArgsValidator
.
validate
(
args
);
LOG
.
debug
(
"Got dirs: out={}, src={}, res={}"
,
args
.
getOutDir
(),
args
.
getOutDirSrc
(),
args
.
getOutDirRes
());
assertThat
(
args
.
getOutDir
(),
is
(
toFile
(
outDir
)));
assertThat
(
args
.
getOutDirSrc
(),
is
(
toFile
(
srcDir
)));
assertThat
(
args
.
getOutDirRes
(),
is
(
toFile
(
resDir
)));
}
private
JadxArgs
makeArgs
()
{
JadxArgs
args
=
new
JadxArgs
();
args
.
getInputFiles
().
add
(
FileUtils
.
createTempFile
(
"some.apk"
));
return
args
;
}
}
jadx-core/src/test/java/jadx/api/JadxDecompilerTest.java
0 → 100644
View file @
948f9456
package
jadx
.
api
;
import
java.io.File
;
import
org.junit.Ignore
;
import
org.junit.Test
;
public
class
JadxDecompilerTest
{
@Test
@Ignore
public
void
testExampleUsage
()
{
JadxArgs
args
=
new
JadxArgs
();
args
.
getInputFiles
().
add
(
new
File
(
"test.apk"
));
args
.
setOutDir
(
new
File
(
"jadx-test-output"
));
JadxDecompiler
jadx
=
new
JadxDecompiler
(
args
);
jadx
.
load
();
jadx
.
save
();
}
// TODO make more tests
}
jadx-core/src/test/java/jadx/tests/api/IntegrationTest.java
View file @
948f9456
...
...
@@ -10,7 +10,6 @@ import java.net.URISyntaxException;
import
java.net.URL
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.Iterator
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.jar.JarOutputStream
;
...
...
@@ -29,7 +28,6 @@ import jadx.core.dex.nodes.RootNode;
import
jadx.core.dex.visitors.DepthTraversal
;
import
jadx.core.dex.visitors.IDexTreeVisitor
;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.tests.api.compiler.DynamicCompiler
;
import
jadx.tests.api.compiler.StaticCompiler
;
import
jadx.tests.api.utils.TestUtils
;
...
...
@@ -65,6 +63,7 @@ public abstract class IntegrationTest extends TestUtils {
public
IntegrationTest
()
{
args
=
new
JadxArgs
();
args
.
setOutDir
(
new
File
(
outDir
));
args
.
setShowInconsistentCode
(
true
);
args
.
setThreadsCount
(
1
);
args
.
setSkipResources
(
true
);
...
...
@@ -84,9 +83,10 @@ public abstract class IntegrationTest extends TestUtils {
public
ClassNode
getClassNodeFromFile
(
File
file
,
String
clsName
)
{
JadxDecompiler
d
=
null
;
try
{
args
.
setInputFiles
(
Collections
.
singletonList
(
file
));
d
=
new
JadxDecompiler
(
args
);
d
.
load
File
(
file
);
}
catch
(
Jadx
Exception
e
)
{
d
.
load
(
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
}
...
...
@@ -114,18 +114,18 @@ public abstract class IntegrationTest extends TestUtils {
}
private
void
decompile
(
JadxDecompiler
jadx
,
ClassNode
cls
)
{
List
<
IDexTreeVisitor
>
passes
=
Jadx
.
getPassesList
(
jadx
.
getArgs
()
,
new
File
(
outDir
)
);
ProcessClass
.
process
(
cls
,
passes
,
new
CodeGen
(
jadx
.
getArgs
()
));
List
<
IDexTreeVisitor
>
passes
=
Jadx
.
getPassesList
(
jadx
.
getArgs
());
ProcessClass
.
process
(
cls
,
passes
,
new
CodeGen
());
}
private
void
decompileWithoutUnload
(
JadxDecompiler
d
,
ClassNode
cls
)
{
cls
.
load
();
List
<
IDexTreeVisitor
>
passes
=
Jadx
.
getPassesList
(
d
.
getArgs
()
,
new
File
(
outDir
)
);
List
<
IDexTreeVisitor
>
passes
=
Jadx
.
getPassesList
(
d
.
getArgs
());
for
(
IDexTreeVisitor
visitor
:
passes
)
{
DepthTraversal
.
visit
(
visitor
,
cls
);
}
try
{
new
CodeGen
(
d
.
getArgs
()
).
visit
(
cls
);
new
CodeGen
().
visit
(
cls
);
}
catch
(
CodegenException
e
)
{
e
.
printStackTrace
();
fail
(
e
.
getMessage
());
...
...
jadx-core/src/test/java/jadx/tests/functional/JadxVisitorsOrderTest.java
View file @
948f9456
package
jadx
.
tests
.
functional
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
...
...
@@ -24,7 +23,7 @@ public class JadxVisitorsOrderTest {
@Test
public
void
testOrder
()
{
List
<
IDexTreeVisitor
>
passes
=
Jadx
.
getPassesList
(
new
JadxArgs
()
,
new
File
(
"out"
)
);
List
<
IDexTreeVisitor
>
passes
=
Jadx
.
getPassesList
(
new
JadxArgs
());
List
<
String
>
errors
=
check
(
passes
);
for
(
String
str
:
errors
)
{
...
...
jadx-gui/src/main/java/jadx/gui/JadxGUI.java
View file @
948f9456
...
...
@@ -5,7 +5,6 @@ import javax.swing.*;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.gui.settings.JadxSettings
;
import
jadx.gui.settings.JadxSettingsAdapter
;
import
jadx.gui.ui.MainWindow
;
...
...
@@ -17,24 +16,17 @@ public class JadxGUI {
public
static
void
main
(
String
[]
args
)
{
try
{
LogCollector
.
register
();
final
JadxSettings
jadxAr
gs
=
JadxSettingsAdapter
.
load
();
final
JadxSettings
settin
gs
=
JadxSettingsAdapter
.
load
();
// overwrite loaded settings by command line arguments
if
(!
jadxAr
gs
.
processArgs
(
args
))
{
if
(!
settin
gs
.
processArgs
(
args
))
{
return
;
}
UIManager
.
setLookAndFeel
(
UIManager
.
getSystemLookAndFeelClassName
());
SwingUtilities
.
invokeLater
(
new
Runnable
()
{
public
void
run
()
{
try
{
MainWindow
window
=
new
MainWindow
(
jadxArgs
);
window
.
open
();
}
catch
(
JadxException
e
)
{
throw
new
RuntimeException
(
e
);
}
}
SwingUtilities
.
invokeLater
(()
->
{
MainWindow
window
=
new
MainWindow
(
settings
);
window
.
open
();
});
}
catch
(
Throwable
e
)
{
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error: {}"
,
e
.
getMessage
(),
e
);
System
.
exit
(
1
);
}
...
...
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
View file @
948f9456
...
...
@@ -2,38 +2,38 @@ package jadx.gui;
import
javax.swing.*
;
import
java.io.File
;
import
java.util.Collections
;
import
java.util.List
;
import
java.util.concurrent.ThreadPoolExecutor
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.IJadxArgs
;
import
jadx.api.JadxDecompiler
;
import
jadx.api.JavaClass
;
import
jadx.api.JavaPackage
;
import
jadx.api.ResourceFile
;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.gui.settings.JadxSettings
;
public
class
JadxWrapper
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
JadxWrapper
.
class
);
private
final
JadxDecompiler
decompiler
;
private
final
JadxSettings
settings
;
private
JadxDecompiler
decompiler
;
private
File
openFile
;
public
JadxWrapper
(
IJadxArgs
jadxArgs
)
throws
JadxException
{
this
.
decompiler
=
new
JadxDecompiler
(
jadxArgs
)
;
public
JadxWrapper
(
JadxSettings
settings
)
{
this
.
settings
=
settings
;
}
public
void
openFile
(
File
file
)
{
this
.
openFile
=
file
;
try
{
this
.
decompiler
.
loadFile
(
file
);
}
catch
(
DecodeException
e
)
{
LOG
.
error
(
"Error decode file: {}"
,
file
,
e
);
}
catch
(
Jadx
Exception
e
)
{
LOG
.
error
(
"Error
open
file: {}"
,
file
,
e
);
this
.
decompiler
=
new
JadxDecompiler
(
settings
.
toJadxArgs
()
);
this
.
decompiler
.
getArgs
().
setInputFiles
(
Collections
.
singletonList
(
file
));
this
.
decompiler
.
load
(
);
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Error
load
file: {}"
,
file
,
e
);
}
}
...
...
@@ -42,7 +42,7 @@ public class JadxWrapper {
@Override
public
void
run
()
{
try
{
decompiler
.
setOutpu
tDir
(
dir
);
decompiler
.
getArgs
().
setRoo
tDir
(
dir
);
ThreadPoolExecutor
ex
=
(
ThreadPoolExecutor
)
decompiler
.
getSaveExecutor
();
ex
.
shutdown
();
while
(
ex
.
isTerminating
())
{
...
...
@@ -53,7 +53,7 @@ public class JadxWrapper {
}
progressMonitor
.
close
();
LOG
.
info
(
"done"
);
}
catch
(
InterruptedException
|
JadxException
e
)
{
}
catch
(
InterruptedException
e
)
{
LOG
.
error
(
"Save interrupted"
,
e
);
Thread
.
currentThread
().
interrupt
();
}
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
View file @
948f9456
...
...
@@ -11,6 +11,7 @@ import java.util.Set;
import
org.fife.ui.rsyntaxtextarea.RSyntaxTextArea
;
import
jadx.api.JadxArgs
;
import
jadx.cli.JadxCLIArgs
;
public
class
JadxSettings
extends
JadxCLIArgs
{
...
...
@@ -44,7 +45,7 @@ public class JadxSettings extends JadxCLIArgs {
public
void
fixOnLoad
()
{
if
(
threadsCount
<=
0
)
{
threadsCount
=
DEFAULT_THREADS_COUNT
;
threadsCount
=
JadxArgs
.
DEFAULT_THREADS_COUNT
;
}
}
...
...
@@ -165,8 +166,8 @@ public class JadxSettings extends JadxCLIArgs {
this
.
deobfuscationForceSave
=
deobfuscationForceSave
;
}
public
void
set
UseSourceNameAsClassAlias
(
boolean
u
seSourceNameAsAlias
)
{
this
.
deobfuscationUseSourceNameAsAlias
=
u
seSourceNameAsAlias
;
public
void
set
DeobfuscationUseSourceNameAsAlias
(
boolean
deobfuscationU
seSourceNameAsAlias
)
{
this
.
deobfuscationUseSourceNameAsAlias
=
deobfuscationU
seSourceNameAsAlias
;
}
public
void
setEscapeUnicode
(
boolean
escapeUnicode
)
{
...
...
jadx-gui/src/main/java/jadx/gui/settings/JadxSettingsWindow.java
View file @
948f9456
...
...
@@ -145,10 +145,10 @@ public class JadxSettingsWindow extends JDialog {
});
JCheckBox
deobfSourceAlias
=
new
JCheckBox
();
deobfSourceAlias
.
setSelected
(
settings
.
useSourceNameAsClas
sAlias
());
deobfSourceAlias
.
setSelected
(
settings
.
isDeobfuscationUseSourceNameA
sAlias
());
deobfSourceAlias
.
addItemListener
(
new
ItemListener
()
{
public
void
itemStateChanged
(
ItemEvent
e
)
{
settings
.
set
UseSourceNameAsClas
sAlias
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
settings
.
set
DeobfuscationUseSourceNameA
sAlias
(
e
.
getStateChange
()
==
ItemEvent
.
SELECTED
);
needReload
();
}
});
...
...
@@ -219,6 +219,7 @@ public class JadxSettingsWindow extends JDialog {
@Override
public
void
stateChanged
(
ChangeEvent
e
)
{
settings
.
setThreadsCount
((
Integer
)
threadsCount
.
getValue
());
needReload
();
}
});
...
...
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
View file @
948f9456
...
...
@@ -27,12 +27,13 @@ import java.util.Arrays;
import
java.util.EnumSet
;
import
java.util.Timer
;
import
java.util.TimerTask
;
import
java.util.concurrent.ExecutorService
;
import
java.util.concurrent.Executors
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.ResourceFile
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.gui.JadxWrapper
;
import
jadx.gui.jobs.BackgroundWorker
;
import
jadx.gui.jobs.DecompileJob
;
...
...
@@ -101,7 +102,7 @@ public class MainWindow extends JFrame {
private
transient
ProgressPanel
progressPane
;
private
transient
BackgroundWorker
backgroundWorker
;
public
MainWindow
(
JadxSettings
settings
)
throws
JadxException
{
public
MainWindow
(
JadxSettings
settings
)
{
this
.
wrapper
=
new
JadxWrapper
(
settings
);
this
.
settings
=
settings
;
this
.
cacheObject
=
new
CacheObject
();
...
...
@@ -119,10 +120,10 @@ public class MainWindow extends JFrame {
setLocationRelativeTo
(
null
);
setDefaultCloseOperation
(
WindowConstants
.
EXIT_ON_CLOSE
);
if
(
settings
.
get
Input
().
isEmpty
())
{
if
(
settings
.
get
Files
().
isEmpty
())
{
openFile
();
}
else
{
openFile
(
settings
.
getInput
().
get
(
0
));
openFile
(
new
File
(
settings
.
getFiles
().
get
(
0
)
));
}
}
...
...
@@ -689,5 +690,4 @@ public class MainWindow extends JFrame {
public
void
menuCanceled
(
MenuEvent
e
)
{
}
}
}
jadx-gui/src/test/java/jadx/gui/treemodel/JSourcesTest.java
View file @
948f9456
...
...
@@ -7,7 +7,7 @@ import org.junit.Before;
import
org.junit.Test
;
import
jadx.api.Factory
;
import
jadx.api.
I
JadxArgs
;
import
jadx.api.JadxArgs
;
import
jadx.api.JadxDecompiler
;
import
jadx.api.JavaClass
;
import
jadx.api.JavaPackage
;
...
...
@@ -30,7 +30,7 @@ public class JSourcesTest {
when
(
root
.
isFlatPackages
()).
thenReturn
(
false
);
JadxWrapper
wrapper
=
mock
(
JadxWrapper
.
class
);
sources
=
new
JSources
(
root
,
wrapper
);
decompiler
=
new
JadxDecompiler
(
mock
(
IJadxArgs
.
class
));
decompiler
=
new
JadxDecompiler
(
new
JadxArgs
(
));
}
@Test
...
...
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