Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2301_76393173
jadx
提交
4c03a424
J
jadx
项目概览
2301_76393173
/
jadx
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
J
jadx
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
4c03a424
编写于
9月 08, 2013
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
improve jadx api
上级
4454e013
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
153 addition
and
89 deletion
+153
-89
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
+20
-4
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+8
-12
jadx-core/src/main/java/jadx/api/Decompiler.java
jadx-core/src/main/java/jadx/api/Decompiler.java
+87
-57
jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java
jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java
+29
-0
jadx-core/src/main/java/jadx/api/IJadxArgs.java
jadx-core/src/main/java/jadx/api/IJadxArgs.java
+0
-9
jadx-core/src/main/java/jadx/core/Jadx.java
jadx-core/src/main/java/jadx/core/Jadx.java
+5
-4
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
+4
-3
未找到文件。
jadx-cli/src/main/java/jadx/cli/JadxCLI.java
浏览文件 @
4c03a424
package
jadx.cli
;
import
jadx.api.Decompiler
;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.exceptions.JadxException
;
import
java.io.File
;
...
...
@@ -15,15 +16,30 @@ public class JadxCLI {
try
{
JadxCLIArgs
jadxArgs
=
new
JadxCLIArgs
(
args
);
checkArgs
(
jadxArgs
);
Decompiler
jadx
=
new
Decompiler
(
jadxArgs
);
jadx
.
processAndSaveAll
();
System
.
exit
(
jadx
.
getErrorsCount
());
}
catch
(
Throwable
e
)
{
processAndSave
(
jadxArgs
);
}
catch
(
JadxException
e
)
{
LOG
.
error
(
e
.
getMessage
());
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
{
if
(
jadxArgs
.
getInput
().
isEmpty
())
throw
new
JadxException
(
"Please specify input file"
);
...
...
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
浏览文件 @
4c03a424
...
...
@@ -141,7 +141,10 @@ public final class JadxCLIArgs implements IJadxArgs {
str
.
append
(
' '
);
}
@Override
public
List
<
File
>
getInput
()
{
return
input
;
}
public
File
getOutDir
()
{
return
outputDir
;
}
...
...
@@ -150,6 +153,10 @@ public final class JadxCLIArgs implements IJadxArgs {
this
.
outputDir
=
outputDir
;
}
public
boolean
isPrintHelp
()
{
return
printHelp
;
}
@Override
public
int
getThreadsCount
()
{
return
threadsCount
;
...
...
@@ -165,11 +172,6 @@ public final class JadxCLIArgs implements IJadxArgs {
return
rawCfgOutput
;
}
@Override
public
List
<
File
>
getInput
()
{
return
input
;
}
@Override
public
boolean
isFallbackMode
()
{
return
fallbackMode
;
...
...
@@ -179,10 +181,4 @@ public final class JadxCLIArgs implements IJadxArgs {
public
boolean
isVerbose
()
{
return
verbose
;
}
@Override
public
boolean
isPrintHelp
()
{
return
printHelp
;
}
}
jadx-core/src/main/java/jadx/api/Decompiler.java
浏览文件 @
4c03a424
...
...
@@ -10,11 +10,13 @@ import jadx.core.dex.visitors.SaveCode;
import
jadx.core.utils.ErrorsCounter
;
import
jadx.core.utils.exceptions.CodegenException
;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.InputFile
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
java.util.Collections
;
import
java.util.Comparator
;
import
java.util.HashMap
;
...
...
@@ -28,40 +30,106 @@ import java.util.concurrent.TimeUnit;
import
org.slf4j.Logger
;
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
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
Decompiler
.
class
);
private
final
IJadxArgs
args
;
private
final
List
<
InputFile
>
inputFiles
=
new
ArrayList
<
InputFile
>();
private
File
outDir
;
private
RootNode
root
;
private
List
<
IDexTreeVisitor
>
passes
;
private
int
errorsCount
;
public
Decompiler
()
{
this
.
args
=
new
DefaultJadxArgs
();
init
();
}
public
Decompiler
(
IJadxArgs
jadxArgs
)
{
this
.
args
=
jadxArgs
;
this
.
passes
=
Jadx
.
getPassesList
(
args
);
init
(
);
}
public
void
processAndSaveAll
()
{
try
{
loadInput
();
parseDex
();
ExecutorService
ex
=
saveAll
(
args
.
getOutDir
());
ex
.
awaitTermination
(
100
,
TimeUnit
.
DAYS
);
LOG
.
info
(
"done"
);
}
catch
(
Throwable
e
)
{
LOG
.
error
(
"jadx error:"
,
e
);
}
finally
{
errorsCount
=
ErrorsCounter
.
getErrorCount
();
if
(
errorsCount
!=
0
)
ErrorsCounter
.
printReport
();
public
void
setOutputDir
(
File
outDir
)
{
this
.
outDir
=
outDir
;
init
();
}
void
init
()
{
if
(
outDir
==
null
)
{
outDir
=
new
File
(
"jadx-output"
);
}
this
.
passes
=
Jadx
.
getPassesList
(
args
,
outDir
);
}
public
void
loadFile
(
File
file
)
throws
IOException
,
DecodeException
{
setInput
(
file
);
parseDex
();
loadFiles
(
Arrays
.
asList
(
file
));
}
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
()
{
...
...
@@ -102,48 +170,10 @@ public final class Decompiler {
}
public
int
getErrorsCount
()
{
return
errorsCount
;
}
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
));
return
ErrorsCounter
.
getErrorCount
();
}
private
void
parseDex
()
throws
DecodeException
{
void
parse
()
throws
DecodeException
{
ClassInfo
.
clearCache
();
ErrorsCounter
.
reset
();
...
...
jadx-core/src/main/java/jadx/api/DefaultJadxArgs.java
0 → 100644
浏览文件 @
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
浏览文件 @
4c03a424
package
jadx.api
;
import
java.io.File
;
import
java.util.List
;
public
interface
IJadxArgs
{
List
<
File
>
getInput
();
File
getOutDir
();
int
getThreadsCount
();
boolean
isCFGOutput
();
...
...
@@ -17,6 +10,4 @@ public interface IJadxArgs {
boolean
isFallbackMode
();
boolean
isVerbose
();
boolean
isPrintHelp
();
}
jadx-core/src/main/java/jadx/core/Jadx.java
浏览文件 @
4c03a424
...
...
@@ -20,6 +20,7 @@ import jadx.core.dex.visitors.regions.RegionMakerVisitor;
import
jadx.core.dex.visitors.typeresolver.FinishTypeResolver
;
import
jadx.core.dex.visitors.typeresolver.TypeResolver
;
import
java.io.File
;
import
java.util.ArrayList
;
import
java.util.List
;
...
...
@@ -36,7 +37,7 @@ public class Jadx {
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
>();
if
(
args
.
isFallbackMode
())
{
passes
.
add
(
new
FallbackModeVisitor
());
...
...
@@ -48,13 +49,13 @@ public class Jadx {
passes
.
add
(
new
FinishTypeResolver
());
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
EnumVisitor
());
if
(
args
.
isCFGOutput
())
passes
.
add
(
new
DotGraphVisitor
(
args
.
getOutDir
()
,
false
));
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
false
));
passes
.
add
(
new
RegionMakerVisitor
());
passes
.
add
(
new
PostRegionVisitor
());
...
...
@@ -63,7 +64,7 @@ public class Jadx {
passes
.
add
(
new
ProcessVariables
());
passes
.
add
(
new
CheckRegions
());
if
(
args
.
isCFGOutput
())
passes
.
add
(
new
DotGraphVisitor
(
args
.
getOutDir
()
,
true
));
passes
.
add
(
new
DotGraphVisitor
(
outDir
,
true
));
passes
.
add
(
new
MethodInlinerVisitor
());
passes
.
add
(
new
ClassModifier
());
...
...
jadx-gui/src/main/java/jadx/gui/JadxWrapper.java
浏览文件 @
4c03a424
...
...
@@ -30,9 +30,9 @@ public class JadxWrapper {
try
{
this
.
decompiler
.
loadFile
(
file
);
}
catch
(
IOException
e
)
{
e
.
printStackTrace
(
);
LOG
.
error
(
"Error open file: "
+
file
,
e
);
}
catch
(
DecodeException
e
)
{
e
.
printStackTrace
(
);
LOG
.
error
(
"Error decode file: "
+
file
,
e
);
}
}
...
...
@@ -41,7 +41,8 @@ public class JadxWrapper {
@Override
public
void
run
()
{
try
{
ThreadPoolExecutor
ex
=
decompiler
.
saveAll
(
dir
);
decompiler
.
setOutputDir
(
dir
);
ThreadPoolExecutor
ex
=
decompiler
.
getSaveExecutor
();
while
(
ex
.
isTerminating
())
{
long
total
=
ex
.
getTaskCount
();
long
done
=
ex
.
getCompletedTaskCount
();
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录