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
4c03a424
Commit
4c03a424
authored
Sep 08, 2013
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
improve jadx api
parent
4454e013
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
153 additions
and
89 deletions
+153
-89
JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+20
-4
JadxCLIArgs.java
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+8
-12
Decompiler.java
jadx-core/src/main/java/jadx/api/Decompiler.java
+87
-57
DefaultJadxArgs.java
jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java
+29
-0
IJadxArgs.java
jadx-core/src/main/java/jadx/api/IJadxArgs.java
+0
-9
Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+5
-4
JadxWrapper.java
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
+4
-3
No files found.
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
View file @
4c03a424
package
jadx
.
cli
;
package
jadx
.
cli
;
import
jadx.api.Decompiler
;
import
jadx.api.Decompiler
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxException
;
import
java.io.File
;
import
java.io.File
;
...
@@ -15,15 +16,30 @@ public class JadxCLI {
...
@@ -15,15 +16,30 @@ public class JadxCLI {
try
{
try
{
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
(
args
);
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
(
args
);
checkArgs
(
jadxArgs
);
checkArgs
(
jadxArgs
);
Decompiler
jadx
=
new
Decompiler
(
jadxArgs
);
processAndSave
(
jadxArgs
);
jadx
.
processAndSaveAll
();
}
catch
(
JadxException
e
)
{
System
.
exit
(
jadx
.
getErrorsCount
());
}
catch
(
Throwable
e
)
{
LOG
.
error
(
e
.
getMessage
());
LOG
.
error
(
e
.
getMessage
());
System
.
exit
(
1
);
System
.
exit
(
1
);
}
}
}
}
private
static
void
processAndSave
(
JadxCLIArgs
jadxArgs
)
{
try
{
Decompiler
jadx
=
new
Decompiler
(
jadxArgs
);
jadx
.
loadFiles
(
jadxArgs
.
getInput
());
jadx
.
setOutputDir
(
jadxArgs
.
getOutDir
());
jadx
.
save
();
LOG
.
info
(
"done"
);
}
catch
(
Throwable
e
)
{
LOG
.
error
(
"jadx error:"
,
e
);
}
int
errorsCount
=
ErrorsCounter
.
getErrorCount
();
if
(
errorsCount
!=
0
)
{
ErrorsCounter
.
printReport
();
}
System
.
exit
(
errorsCount
);
}
private
static
void
checkArgs
(
JadxCLIArgs
jadxArgs
)
throws
JadxException
{
private
static
void
checkArgs
(
JadxCLIArgs
jadxArgs
)
throws
JadxException
{
if
(
jadxArgs
.
getInput
().
isEmpty
())
if
(
jadxArgs
.
getInput
().
isEmpty
())
throw
new
JadxException
(
"Please specify input file"
);
throw
new
JadxException
(
"Please specify input file"
);
...
...
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
View file @
4c03a424
...
@@ -141,7 +141,10 @@ public final class JadxCLIArgs implements IJadxArgs {
...
@@ -141,7 +141,10 @@ public final class JadxCLIArgs implements IJadxArgs {
str
.
append
(
' '
);
str
.
append
(
' '
);
}
}
@Override
public
List
<
File
>
getInput
()
{
return
input
;
}
public
File
getOutDir
()
{
public
File
getOutDir
()
{
return
outputDir
;
return
outputDir
;
}
}
...
@@ -150,6 +153,10 @@ public final class JadxCLIArgs implements IJadxArgs {
...
@@ -150,6 +153,10 @@ public final class JadxCLIArgs implements IJadxArgs {
this
.
outputDir
=
outputDir
;
this
.
outputDir
=
outputDir
;
}
}
public
boolean
isPrintHelp
()
{
return
printHelp
;
}
@Override
@Override
public
int
getThreadsCount
()
{
public
int
getThreadsCount
()
{
return
threadsCount
;
return
threadsCount
;
...
@@ -166,11 +173,6 @@ public final class JadxCLIArgs implements IJadxArgs {
...
@@ -166,11 +173,6 @@ public final class JadxCLIArgs implements IJadxArgs {
}
}
@Override
@Override
public
List
<
File
>
getInput
()
{
return
input
;
}
@Override
public
boolean
isFallbackMode
()
{
public
boolean
isFallbackMode
()
{
return
fallbackMode
;
return
fallbackMode
;
}
}
...
@@ -179,10 +181,4 @@ public final class JadxCLIArgs implements IJadxArgs {
...
@@ -179,10 +181,4 @@ public final class JadxCLIArgs implements IJadxArgs {
public
boolean
isVerbose
()
{
public
boolean
isVerbose
()
{
return
verbose
;
return
verbose
;
}
}
@Override
public
boolean
isPrintHelp
()
{
return
printHelp
;
}
}
}
jadx-core/src/main/java/jadx/api/Decompiler.java
View file @
4c03a424
...
@@ -10,11 +10,13 @@ import jadx.core.dex.visitors.SaveCode;
...
@@ -10,11 +10,13 @@ import jadx.core.dex.visitors.SaveCode;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.InputFile
;
import
jadx.core.utils.files.InputFile
;
import
java.io.File
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.Comparator
;
import
java.util.HashMap
;
import
java.util.HashMap
;
...
@@ -28,40 +30,106 @@ import java.util.concurrent.TimeUnit;
...
@@ -28,40 +30,106 @@ import java.util.concurrent.TimeUnit;
import
org.slf4j.Logger
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
org.slf4j.LoggerFactory
;
/**
* Jadx API usage example:
* <pre><code>
* Decompiler jadx = new Decompiler();
* jadx.loadFile(new File("classes.dex"));
* jadx.setOutputDir(new File("out"));
* jadx.save();
* </code></pre>
* <p/>
* Instead of 'save()' you can get list of decompiled classes:
* <pre><code>
* for(JavaClass cls : jadx.getClasses()) {
* System.out.println(cls.getCode());
* }
* </code></pre>
*/
public
final
class
Decompiler
{
public
final
class
Decompiler
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
Decompiler
.
class
);
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
Decompiler
.
class
);
private
final
IJadxArgs
args
;
private
final
IJadxArgs
args
;
private
final
List
<
InputFile
>
inputFiles
=
new
ArrayList
<
InputFile
>();
private
final
List
<
InputFile
>
inputFiles
=
new
ArrayList
<
InputFile
>();
private
File
outDir
;
private
RootNode
root
;
private
RootNode
root
;
private
List
<
IDexTreeVisitor
>
passes
;
private
List
<
IDexTreeVisitor
>
passes
;
private
int
errorsCount
;
public
Decompiler
()
{
this
.
args
=
new
DefaultJadxArgs
();
init
();
}
public
Decompiler
(
IJadxArgs
jadxArgs
)
{
public
Decompiler
(
IJadxArgs
jadxArgs
)
{
this
.
args
=
jadxArgs
;
this
.
args
=
jadxArgs
;
this
.
passes
=
Jadx
.
getPassesList
(
args
);
init
(
);
}
}
public
void
processAndSaveAll
()
{
public
void
setOutputDir
(
File
outDir
)
{
try
{
this
.
outDir
=
outDir
;
loadInput
();
init
();
parseDex
();
}
ExecutorService
ex
=
saveAll
(
args
.
getOutDir
());
ex
.
awaitTermination
(
100
,
TimeUnit
.
DAYS
);
void
init
()
{
LOG
.
info
(
"done"
);
if
(
outDir
==
null
)
{
}
catch
(
Throwable
e
)
{
outDir
=
new
File
(
"jadx-output"
);
LOG
.
error
(
"jadx error:"
,
e
);
}
finally
{
errorsCount
=
ErrorsCounter
.
getErrorCount
();
if
(
errorsCount
!=
0
)
ErrorsCounter
.
printReport
();
}
}
this
.
passes
=
Jadx
.
getPassesList
(
args
,
outDir
);
}
}
public
void
loadFile
(
File
file
)
throws
IOException
,
DecodeException
{
public
void
loadFile
(
File
file
)
throws
IOException
,
DecodeException
{
setInput
(
file
);
loadFiles
(
Arrays
.
asList
(
file
));
parseDex
();
}
public
void
loadFiles
(
List
<
File
>
files
)
throws
IOException
,
DecodeException
{
if
(
files
.
isEmpty
())
{
throw
new
JadxRuntimeException
(
"Empty file list"
);
}
inputFiles
.
clear
();
for
(
File
file
:
files
)
{
inputFiles
.
add
(
new
InputFile
(
file
));
}
parse
();
}
public
void
save
()
{
try
{
ExecutorService
ex
=
getSaveExecutor
();
ex
.
awaitTermination
(
1
,
TimeUnit
.
DAYS
);
}
catch
(
InterruptedException
e
)
{
LOG
.
error
(
"Save interrupted"
,
e
);
}
}
public
ThreadPoolExecutor
getSaveExecutor
()
{
if
(
root
==
null
)
{
throw
new
JadxRuntimeException
(
"No loaded files"
);
}
int
threadsCount
=
args
.
getThreadsCount
();
LOG
.
debug
(
"processing threads count: {}"
,
threadsCount
);
ArrayList
<
IDexTreeVisitor
>
passList
=
new
ArrayList
<
IDexTreeVisitor
>(
passes
);
SaveCode
savePass
=
new
SaveCode
(
outDir
,
args
);
passList
.
add
(
savePass
);
LOG
.
info
(
"processing ..."
);
ThreadPoolExecutor
executor
=
(
ThreadPoolExecutor
)
Executors
.
newFixedThreadPool
(
threadsCount
);
for
(
ClassNode
cls
:
root
.
getClasses
(
false
))
{
if
(
cls
.
getCode
()
==
null
)
{
ProcessClass
job
=
new
ProcessClass
(
cls
,
passList
);
executor
.
execute
(
job
);
}
else
{
try
{
savePass
.
visit
(
cls
);
}
catch
(
CodegenException
e
)
{
LOG
.
error
(
"Can't save class {}"
,
cls
,
e
);
}
}
}
executor
.
shutdown
();
return
executor
;
}
}
public
List
<
JavaClass
>
getClasses
()
{
public
List
<
JavaClass
>
getClasses
()
{
...
@@ -102,48 +170,10 @@ public final class Decompiler {
...
@@ -102,48 +170,10 @@ public final class Decompiler {
}
}
public
int
getErrorsCount
()
{
public
int
getErrorsCount
()
{
return
errorsCount
;
return
ErrorsCounter
.
getErrorCount
();
}
public
ThreadPoolExecutor
saveAll
(
File
dir
)
{
int
threadsCount
=
args
.
getThreadsCount
();
LOG
.
debug
(
"processing threads count: {}"
,
threadsCount
);
ArrayList
<
IDexTreeVisitor
>
passList
=
new
ArrayList
<
IDexTreeVisitor
>(
passes
);
SaveCode
savePass
=
new
SaveCode
(
dir
,
args
);
passList
.
add
(
savePass
);
LOG
.
info
(
"processing ..."
);
ThreadPoolExecutor
executor
=
(
ThreadPoolExecutor
)
Executors
.
newFixedThreadPool
(
threadsCount
);
for
(
ClassNode
cls
:
root
.
getClasses
(
false
))
{
if
(
cls
.
getCode
()
==
null
)
{
ProcessClass
job
=
new
ProcessClass
(
cls
,
passList
);
executor
.
execute
(
job
);
}
else
{
try
{
savePass
.
visit
(
cls
);
}
catch
(
CodegenException
e
)
{
LOG
.
error
(
"Can't save class {}"
,
cls
,
e
);
}
}
}
executor
.
shutdown
();
return
executor
;
}
private
void
loadInput
()
throws
IOException
,
DecodeException
{
inputFiles
.
clear
();
for
(
File
file
:
args
.
getInput
())
{
inputFiles
.
add
(
new
InputFile
(
file
));
}
}
private
void
setInput
(
File
file
)
throws
IOException
,
DecodeException
{
inputFiles
.
clear
();
inputFiles
.
add
(
new
InputFile
(
file
));
}
}
private
void
parseDex
()
throws
DecodeException
{
void
parse
()
throws
DecodeException
{
ClassInfo
.
clearCache
();
ClassInfo
.
clearCache
();
ErrorsCounter
.
reset
();
ErrorsCounter
.
reset
();
...
...
jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java
0 → 100644
View file @
4c03a424
package
jadx
.
api
;
public
class
DefaultJadxArgs
implements
IJadxArgs
{
@Override
public
int
getThreadsCount
()
{
return
Runtime
.
getRuntime
().
availableProcessors
();
}
@Override
public
boolean
isCFGOutput
()
{
return
false
;
}
@Override
public
boolean
isRawCFGOutput
()
{
return
false
;
}
@Override
public
boolean
isFallbackMode
()
{
return
false
;
}
@Override
public
boolean
isVerbose
()
{
return
false
;
}
}
jadx-core/src/main/java/jadx/api/IJadxArgs.java
View file @
4c03a424
package
jadx
.
api
;
package
jadx
.
api
;
import
java.io.File
;
import
java.util.List
;
public
interface
IJadxArgs
{
public
interface
IJadxArgs
{
List
<
File
>
getInput
();
File
getOutDir
();
int
getThreadsCount
();
int
getThreadsCount
();
boolean
isCFGOutput
();
boolean
isCFGOutput
();
...
@@ -17,6 +10,4 @@ public interface IJadxArgs {
...
@@ -17,6 +10,4 @@ public interface IJadxArgs {
boolean
isFallbackMode
();
boolean
isFallbackMode
();
boolean
isVerbose
();
boolean
isVerbose
();
boolean
isPrintHelp
();
}
}
jadx-core/src/main/java/jadx/core/Jadx.java
View file @
4c03a424
...
@@ -20,6 +20,7 @@ import jadx.core.dex.visitors.regions.RegionMakerVisitor;
...
@@ -20,6 +20,7 @@ import jadx.core.dex.visitors.regions.RegionMakerVisitor;
import
jadx.core.dex.visitors.typeresolver.FinishTypeResolver
;
import
jadx.core.dex.visitors.typeresolver.FinishTypeResolver
;
import
jadx.core.dex.visitors.typeresolver.TypeResolver
;
import
jadx.core.dex.visitors.typeresolver.TypeResolver
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.List
;
...
@@ -36,7 +37,7 @@ public class Jadx {
...
@@ -36,7 +37,7 @@ public class Jadx {
LOG
.
info
(
"assertions enabled"
);
LOG
.
info
(
"assertions enabled"
);
}
}
public
static
List
<
IDexTreeVisitor
>
getPassesList
(
IJadxArgs
args
)
{
public
static
List
<
IDexTreeVisitor
>
getPassesList
(
IJadxArgs
args
,
File
outDir
)
{
List
<
IDexTreeVisitor
>
passes
=
new
ArrayList
<
IDexTreeVisitor
>();
List
<
IDexTreeVisitor
>
passes
=
new
ArrayList
<
IDexTreeVisitor
>();
if
(
args
.
isFallbackMode
())
{
if
(
args
.
isFallbackMode
())
{
passes
.
add
(
new
FallbackModeVisitor
());
passes
.
add
(
new
FallbackModeVisitor
());
...
@@ -48,13 +49,13 @@ public class Jadx {
...
@@ -48,13 +49,13 @@ public class Jadx {
passes
.
add
(
new
FinishTypeResolver
());
passes
.
add
(
new
FinishTypeResolver
());
if
(
args
.
isRawCFGOutput
())
if
(
args
.
isRawCFGOutput
())
passes
.
add
(
new
DotGraphVisitor
(
args
.
getOutDir
()
,
false
,
true
));
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
false
,
true
));
passes
.
add
(
new
ModVisitor
());
passes
.
add
(
new
ModVisitor
());
passes
.
add
(
new
EnumVisitor
());
passes
.
add
(
new
EnumVisitor
());
if
(
args
.
isCFGOutput
())
if
(
args
.
isCFGOutput
())
passes
.
add
(
new
DotGraphVisitor
(
args
.
getOutDir
()
,
false
));
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
false
));
passes
.
add
(
new
RegionMakerVisitor
());
passes
.
add
(
new
RegionMakerVisitor
());
passes
.
add
(
new
PostRegionVisitor
());
passes
.
add
(
new
PostRegionVisitor
());
...
@@ -63,7 +64,7 @@ public class Jadx {
...
@@ -63,7 +64,7 @@ public class Jadx {
passes
.
add
(
new
ProcessVariables
());
passes
.
add
(
new
ProcessVariables
());
passes
.
add
(
new
CheckRegions
());
passes
.
add
(
new
CheckRegions
());
if
(
args
.
isCFGOutput
())
if
(
args
.
isCFGOutput
())
passes
.
add
(
new
DotGraphVisitor
(
args
.
getOutDir
()
,
true
));
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
true
));
passes
.
add
(
new
MethodInlinerVisitor
());
passes
.
add
(
new
MethodInlinerVisitor
());
passes
.
add
(
new
ClassModifier
());
passes
.
add
(
new
ClassModifier
());
...
...
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
View file @
4c03a424
...
@@ -30,9 +30,9 @@ public class JadxWrapper {
...
@@ -30,9 +30,9 @@ public class JadxWrapper {
try
{
try
{
this
.
decompiler
.
loadFile
(
file
);
this
.
decompiler
.
loadFile
(
file
);
}
catch
(
IOException
e
)
{
}
catch
(
IOException
e
)
{
e
.
printStackTrace
(
);
LOG
.
error
(
"Error open file: "
+
file
,
e
);
}
catch
(
DecodeException
e
)
{
}
catch
(
DecodeException
e
)
{
e
.
printStackTrace
(
);
LOG
.
error
(
"Error decode file: "
+
file
,
e
);
}
}
}
}
...
@@ -41,7 +41,8 @@ public class JadxWrapper {
...
@@ -41,7 +41,8 @@ public class JadxWrapper {
@Override
@Override
public
void
run
()
{
public
void
run
()
{
try
{
try
{
ThreadPoolExecutor
ex
=
decompiler
.
saveAll
(
dir
);
decompiler
.
setOutputDir
(
dir
);
ThreadPoolExecutor
ex
=
decompiler
.
getSaveExecutor
();
while
(
ex
.
isTerminating
())
{
while
(
ex
.
isTerminating
())
{
long
total
=
ex
.
getTaskCount
();
long
total
=
ex
.
getTaskCount
();
long
done
=
ex
.
getCompletedTaskCount
();
long
done
=
ex
.
getCompletedTaskCount
();
...
...
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