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
b2f41e95
Commit
b2f41e95
authored
Mar 27, 2016
by
Skylot
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
core: export as android gradle project
parent
e733c917
Show whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
412 additions
and
29 deletions
+412
-29
README.md
README.md
+1
-0
JadxCLIArgs.java
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
+8
-0
IJadxArgs.java
jadx-core/src/main/java/jadx/api/IJadxArgs.java
+5
-0
JadxArgs.java
jadx-core/src/main/java/jadx/api/JadxArgs.java
+10
-0
JadxDecompiler.java
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
+38
-13
ExportGradleProject.java
...e/src/main/java/jadx/core/export/ExportGradleProject.java
+85
-0
TemplateFile.java
jadx-core/src/main/java/jadx/core/export/TemplateFile.java
+162
-0
build.gradle.tmpl
jadx-core/src/main/resources/export/build.gradle.tmpl
+35
-0
TemplateFileTest.java
...src/test/java/jadx/tests/functional/TemplateFileTest.java
+24
-0
JadxSettings.java
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
+4
-0
MainWindow.java
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
+20
-2
Messages_en_US.properties
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
+1
-0
database_save.png
jadx-gui/src/main/resources/icons-16/database_save.png
+0
-0
build.gradle
jadx-test-app/build.gradle
+19
-14
No files found.
README.md
View file @
b2f41e95
...
@@ -46,6 +46,7 @@ options:
...
@@ -46,6 +46,7 @@ options:
-j, --threads-count - processing threads count
-j, --threads-count - processing threads count
-r, --no-res - do not decode resources
-r, --no-res - do not decode resources
-s, --no-src - do not decompile source code
-s, --no-src - do not decompile source code
-e, --export-gradle - save as android gradle project
--show-bad-code - show inconsistent code (incorrectly decompiled)
--show-bad-code - show inconsistent code (incorrectly decompiled)
--no-replace-consts - don't replace constant value with matching constant field
--no-replace-consts - don't replace constant value with matching constant field
--escape-unicode - escape non latin characters in strings (with \u)
--escape-unicode - escape non latin characters in strings (with \u)
...
...
jadx-cli/src/main/java/jadx/cli/JadxCLIArgs.java
View file @
b2f41e95
...
@@ -40,6 +40,9 @@ public class JadxCLIArgs implements IJadxArgs {
...
@@ -40,6 +40,9 @@ public class JadxCLIArgs implements IJadxArgs {
@Parameter
(
names
=
{
"-s"
,
"--no-src"
},
description
=
"do not decompile source code"
)
@Parameter
(
names
=
{
"-s"
,
"--no-src"
},
description
=
"do not decompile source code"
)
protected
boolean
skipSources
=
false
;
protected
boolean
skipSources
=
false
;
@Parameter
(
names
=
{
"-e"
,
"--export-gradle"
},
description
=
"save as android gradle project"
)
protected
boolean
exportAsGradleProject
=
false
;
@Parameter
(
names
=
{
"--show-bad-code"
},
description
=
"show inconsistent code (incorrectly decompiled)"
)
@Parameter
(
names
=
{
"--show-bad-code"
},
description
=
"show inconsistent code (incorrectly decompiled)"
)
protected
boolean
showInconsistentCode
=
false
;
protected
boolean
showInconsistentCode
=
false
;
...
@@ -281,4 +284,9 @@ public class JadxCLIArgs implements IJadxArgs {
...
@@ -281,4 +284,9 @@ public class JadxCLIArgs implements IJadxArgs {
public
boolean
isReplaceConsts
()
{
public
boolean
isReplaceConsts
()
{
return
replaceConsts
;
return
replaceConsts
;
}
}
@Override
public
boolean
isExportAsGradleProject
()
{
return
exportAsGradleProject
;
}
}
}
jadx-core/src/main/java/jadx/api/IJadxArgs.java
View file @
b2f41e95
...
@@ -37,4 +37,9 @@ public interface IJadxArgs {
...
@@ -37,4 +37,9 @@ public interface IJadxArgs {
* Replace constant values with static final fields with same value
* Replace constant values with static final fields with same value
*/
*/
boolean
isReplaceConsts
();
boolean
isReplaceConsts
();
/**
* Save as gradle project
*/
boolean
isExportAsGradleProject
();
}
}
jadx-core/src/main/java/jadx/api/JadxArgs.java
View file @
b2f41e95
...
@@ -26,6 +26,7 @@ public class JadxArgs implements IJadxArgs {
...
@@ -26,6 +26,7 @@ public class JadxArgs implements IJadxArgs {
private
boolean
escapeUnicode
=
false
;
private
boolean
escapeUnicode
=
false
;
private
boolean
replaceConsts
=
true
;
private
boolean
replaceConsts
=
true
;
private
boolean
exportAsGradleProject
=
false
;
@Override
@Override
public
File
getOutDir
()
{
public
File
getOutDir
()
{
...
@@ -170,4 +171,13 @@ public class JadxArgs implements IJadxArgs {
...
@@ -170,4 +171,13 @@ public class JadxArgs implements IJadxArgs {
public
void
setReplaceConsts
(
boolean
replaceConsts
)
{
public
void
setReplaceConsts
(
boolean
replaceConsts
)
{
this
.
replaceConsts
=
replaceConsts
;
this
.
replaceConsts
=
replaceConsts
;
}
}
@Override
public
boolean
isExportAsGradleProject
()
{
return
exportAsGradleProject
;
}
public
void
setExportAsGradleProject
(
boolean
exportAsGradleProject
)
{
this
.
exportAsGradleProject
=
exportAsGradleProject
;
}
}
}
jadx-core/src/main/java/jadx/api/JadxDecompiler.java
View file @
b2f41e95
...
@@ -3,12 +3,14 @@ package jadx.api;
...
@@ -3,12 +3,14 @@ package jadx.api;
import
jadx.core.Jadx
;
import
jadx.core.Jadx
;
import
jadx.core.ProcessClass
;
import
jadx.core.ProcessClass
;
import
jadx.core.codegen.CodeGen
;
import
jadx.core.codegen.CodeGen
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.dex.visitors.IDexTreeVisitor
;
import
jadx.core.dex.visitors.IDexTreeVisitor
;
import
jadx.core.dex.visitors.SaveCode
;
import
jadx.core.dex.visitors.SaveCode
;
import
jadx.core.export.ExportGradleProject
;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.DecodeException
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
...
@@ -150,7 +152,7 @@ public final class JadxDecompiler {
...
@@ -150,7 +152,7 @@ public final class JadxDecompiler {
return
getSaveExecutor
(!
args
.
isSkipSources
(),
!
args
.
isSkipResources
());
return
getSaveExecutor
(!
args
.
isSkipSources
(),
!
args
.
isSkipResources
());
}
}
private
ExecutorService
getSaveExecutor
(
boolean
saveSources
,
final
boolean
saveResources
)
{
private
ExecutorService
getSaveExecutor
(
boolean
saveSources
,
boolean
saveResources
)
{
if
(
root
==
null
)
{
if
(
root
==
null
)
{
throw
new
JadxRuntimeException
(
"No loaded files"
);
throw
new
JadxRuntimeException
(
"No loaded files"
);
}
}
...
@@ -159,8 +161,38 @@ public final class JadxDecompiler {
...
@@ -159,8 +161,38 @@ public final class JadxDecompiler {
LOG
.
info
(
"processing ..."
);
LOG
.
info
(
"processing ..."
);
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
threadsCount
);
ExecutorService
executor
=
Executors
.
newFixedThreadPool
(
threadsCount
);
File
sourcesOutDir
;
File
resOutDir
;
if
(
args
.
isExportAsGradleProject
())
{
ExportGradleProject
export
=
new
ExportGradleProject
(
root
,
outDir
);
export
.
init
();
sourcesOutDir
=
export
.
getSrcOutDir
();
resOutDir
=
export
.
getResOutDir
();
}
else
{
sourcesOutDir
=
outDir
;
resOutDir
=
outDir
;
}
if
(
saveSources
)
{
if
(
saveSources
)
{
appendSourcesSave
(
executor
,
sourcesOutDir
);
}
if
(
saveResources
)
{
appendResourcesSave
(
executor
,
resOutDir
);
}
return
executor
;
}
private
void
appendResourcesSave
(
ExecutorService
executor
,
File
outDir
)
{
for
(
ResourceFile
resourceFile
:
getResources
())
{
executor
.
execute
(
new
ResourcesSaver
(
outDir
,
resourceFile
));
}
}
private
void
appendSourcesSave
(
ExecutorService
executor
,
final
File
outDir
)
{
for
(
final
JavaClass
cls
:
getClasses
())
{
for
(
final
JavaClass
cls
:
getClasses
())
{
if
(
cls
.
getClassNode
().
contains
(
AFlag
.
DONT_GENERATE
))
{
continue
;
}
executor
.
execute
(
new
Runnable
()
{
executor
.
execute
(
new
Runnable
()
{
@Override
@Override
public
void
run
()
{
public
void
run
()
{
...
@@ -170,13 +202,6 @@ public final class JadxDecompiler {
...
@@ -170,13 +202,6 @@ public final class JadxDecompiler {
});
});
}
}
}
}
if
(
saveResources
)
{
for
(
final
ResourceFile
resourceFile
:
getResources
())
{
executor
.
execute
(
new
ResourcesSaver
(
outDir
,
resourceFile
));
}
}
return
executor
;
}
public
List
<
JavaClass
>
getClasses
()
{
public
List
<
JavaClass
>
getClasses
()
{
if
(
root
==
null
)
{
if
(
root
==
null
)
{
...
...
jadx-core/src/main/java/jadx/core/export/ExportGradleProject.java
0 → 100644
View file @
b2f41e95
package
jadx
.
core
.
export
;
import
jadx.core.dex.attributes.AFlag
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.core.dex.nodes.DexNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.utils.exceptions.JadxRuntimeException
;
import
jadx.core.utils.files.FileUtils
;
import
java.io.File
;
import
java.io.IOException
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
public
class
ExportGradleProject
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
ExportGradleProject
.
class
);
private
static
final
Set
<
String
>
IGNORE_CLS_NAMES
=
new
HashSet
<
String
>(
Arrays
.
asList
(
"R"
,
"BuildConfig"
));
private
final
RootNode
root
;
private
final
File
outDir
;
private
File
srcOutDir
;
private
File
resOutDir
;
public
ExportGradleProject
(
RootNode
root
,
File
outDir
)
{
this
.
root
=
root
;
this
.
outDir
=
outDir
;
this
.
srcOutDir
=
new
File
(
outDir
,
"src/main/java"
);
this
.
resOutDir
=
new
File
(
outDir
,
"src/main"
);
}
public
void
init
()
{
try
{
FileUtils
.
makeDirsForFile
(
srcOutDir
);
FileUtils
.
makeDirsForFile
(
resOutDir
);
saveBuildGradle
();
skipGeneratedClasses
();
}
catch
(
Exception
e
)
{
throw
new
JadxRuntimeException
(
"Gradle export failed"
,
e
);
}
}
private
void
saveBuildGradle
()
throws
IOException
{
TemplateFile
tmpl
=
TemplateFile
.
fromResources
(
"/export/build.gradle.tmpl"
);
String
appPackage
=
root
.
getAppPackage
();
if
(
appPackage
==
null
)
{
appPackage
=
"UNKNOWN"
;
}
tmpl
.
add
(
"applicationId"
,
appPackage
);
// TODO: load from AndroidManifest.xml
tmpl
.
add
(
"minSdkVersion"
,
9
);
tmpl
.
add
(
"targetSdkVersion"
,
21
);
tmpl
.
save
(
new
File
(
outDir
,
"build.gradle"
));
}
private
void
skipGeneratedClasses
()
{
for
(
DexNode
dexNode
:
root
.
getDexNodes
())
{
List
<
ClassNode
>
classes
=
dexNode
.
getClasses
();
for
(
ClassNode
cls
:
classes
)
{
String
shortName
=
cls
.
getClassInfo
().
getShortName
();
if
(
IGNORE_CLS_NAMES
.
contains
(
shortName
))
{
cls
.
add
(
AFlag
.
DONT_GENERATE
);
LOG
.
debug
(
"Skip class: {}"
,
cls
);
}
}
}
}
public
File
getSrcOutDir
()
{
return
srcOutDir
;
}
public
File
getResOutDir
()
{
return
resOutDir
;
}
}
jadx-core/src/main/java/jadx/core/export/TemplateFile.java
0 → 100644
View file @
b2f41e95
package
jadx
.
core
.
export
;
import
java.io.BufferedInputStream
;
import
java.io.ByteArrayOutputStream
;
import
java.io.File
;
import
java.io.FileNotFoundException
;
import
java.io.FileOutputStream
;
import
java.io.IOException
;
import
java.io.InputStream
;
import
java.io.OutputStream
;
import
java.util.HashMap
;
import
java.util.Map
;
import
org.jetbrains.annotations.NotNull
;
import
org.jetbrains.annotations.Nullable
;
import
static
jadx
.
core
.
utils
.
files
.
FileUtils
.
close
;
/**
* Simple template engine
* Syntax for replace variable with value: '{{variable}}'
*/
public
class
TemplateFile
{
private
enum
State
{
NONE
,
START
,
VARIABLE
,
END
}
private
static
class
ParserState
{
private
State
state
=
State
.
NONE
;
private
StringBuilder
curVariable
;
private
boolean
skip
;
}
private
final
String
templateName
;
private
final
InputStream
template
;
private
final
Map
<
String
,
String
>
values
=
new
HashMap
<
String
,
String
>();
public
static
TemplateFile
fromResources
(
String
path
)
throws
FileNotFoundException
{
InputStream
res
=
TemplateFile
.
class
.
getResourceAsStream
(
path
);
if
(
res
==
null
)
{
throw
new
FileNotFoundException
(
"Resource not found: "
+
path
);
}
return
new
TemplateFile
(
path
,
res
);
}
private
TemplateFile
(
String
name
,
InputStream
in
)
throws
FileNotFoundException
{
this
.
templateName
=
name
;
this
.
template
=
in
;
}
public
void
add
(
String
name
,
@NotNull
Object
value
)
{
values
.
put
(
name
,
value
.
toString
());
}
public
String
build
()
throws
IOException
{
ByteArrayOutputStream
out
=
new
ByteArrayOutputStream
();
try
{
process
(
out
);
}
finally
{
close
(
out
);
}
return
out
.
toString
();
}
public
void
save
(
File
outFile
)
throws
IOException
{
OutputStream
out
=
new
FileOutputStream
(
outFile
);
try
{
process
(
out
);
}
finally
{
close
(
out
);
}
}
private
void
process
(
OutputStream
out
)
throws
IOException
{
if
(
template
.
available
()
==
0
)
{
throw
new
IOException
(
"Template already processed"
);
}
InputStream
in
=
null
;
try
{
in
=
new
BufferedInputStream
(
template
);
ParserState
state
=
new
ParserState
();
while
(
true
)
{
int
ch
=
in
.
read
();
if
(
ch
==
-
1
)
{
break
;
}
String
str
=
process
(
state
,
(
char
)
ch
);
if
(
str
!=
null
)
{
out
.
write
(
str
.
getBytes
());
}
else
if
(!
state
.
skip
)
{
out
.
write
(
ch
);
}
}
}
finally
{
close
(
in
);
}
}
@Nullable
private
String
process
(
ParserState
parser
,
char
ch
)
{
State
state
=
parser
.
state
;
switch
(
ch
)
{
case
'{'
:
switch
(
state
)
{
case
START:
parser
.
state
=
State
.
VARIABLE
;
parser
.
curVariable
=
new
StringBuilder
();
break
;
default
:
parser
.
state
=
State
.
START
;
break
;
}
parser
.
skip
=
true
;
return
null
;
case
'}'
:
switch
(
state
)
{
case
VARIABLE:
parser
.
state
=
State
.
END
;
parser
.
skip
=
true
;
return
null
;
case
END:
parser
.
state
=
State
.
NONE
;
String
varName
=
parser
.
curVariable
.
toString
();
parser
.
curVariable
=
new
StringBuilder
();
return
processVar
(
varName
);
}
break
;
default
:
switch
(
state
)
{
case
VARIABLE:
parser
.
curVariable
.
append
(
ch
);
parser
.
skip
=
true
;
return
null
;
case
START:
parser
.
state
=
State
.
NONE
;
return
"{"
+
ch
;
case
END:
throw
new
RuntimeException
(
"Expected variable end: '"
+
parser
.
curVariable
+
"' (missing second '}')"
);
}
break
;
}
parser
.
skip
=
false
;
return
null
;
}
private
String
processVar
(
String
varName
)
{
String
str
=
values
.
get
(
varName
);
if
(
str
==
null
)
{
throw
new
RuntimeException
(
"Unknown variable: '"
+
varName
+
"' in template: "
+
templateName
);
}
return
str
;
}
}
jadx-core/src/main/resources/export/build.gradle.tmpl
0 → 100644
View file @
b2f41e95
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:1.5.0'
}
}
apply plugin: 'com.android.application'
repositories {
mavenCentral()
jcenter()
}
android {
compileSdkVersion 23
buildToolsVersion '23.0.1'
defaultConfig {
applicationId '{{applicationId}}'
minSdkVersion {{minSdkVersion}}
targetSdkVersion {{targetSdkVersion}}
versionCode 1
versionName "1.0"
}
lintOptions {
abortOnError false
}
}
dependencies {
// some dependencies
}
jadx-core/src/test/java/jadx/tests/functional/TemplateFileTest.java
0 → 100644
View file @
b2f41e95
package
jadx
.
tests
.
functional
;
import
jadx.core.export.TemplateFile
;
import
org.junit.Test
;
import
static
org
.
hamcrest
.
Matchers
.
containsString
;
import
static
org
.
junit
.
Assert
.
assertThat
;
public
class
TemplateFileTest
{
@Test
public
void
testBuildGradle
()
throws
Exception
{
TemplateFile
tmpl
=
TemplateFile
.
fromResources
(
"/export/build.gradle.tmpl"
);
tmpl
.
add
(
"applicationId"
,
"SOME_ID"
);
tmpl
.
add
(
"minSdkVersion"
,
1
);
tmpl
.
add
(
"targetSdkVersion"
,
2
);
String
res
=
tmpl
.
build
();
System
.
out
.
println
(
res
);
assertThat
(
res
,
containsString
(
"applicationId 'SOME_ID'"
));
assertThat
(
res
,
containsString
(
"targetSdkVersion 2"
));
}
}
jadx-gui/src/main/java/jadx/gui/settings/JadxSettings.java
View file @
b2f41e95
...
@@ -180,6 +180,10 @@ public class JadxSettings extends JadxCLIArgs {
...
@@ -180,6 +180,10 @@ public class JadxSettings extends JadxCLIArgs {
this
.
autoStartJobs
=
autoStartJobs
;
this
.
autoStartJobs
=
autoStartJobs
;
}
}
public
void
setExportAsGradleProject
(
boolean
exportAsGradleProject
)
{
this
.
exportAsGradleProject
=
exportAsGradleProject
;
}
public
Font
getFont
()
{
public
Font
getFont
()
{
if
(
fontStr
.
isEmpty
())
{
if
(
fontStr
.
isEmpty
())
{
return
DEFAULT_FONT
;
return
DEFAULT_FONT
;
...
...
jadx-gui/src/main/java/jadx/gui/ui/MainWindow.java
View file @
b2f41e95
...
@@ -89,6 +89,7 @@ public class MainWindow extends JFrame {
...
@@ -89,6 +89,7 @@ public class MainWindow extends JFrame {
private
static
final
ImageIcon
ICON_OPEN
=
Utils
.
openIcon
(
"folder"
);
private
static
final
ImageIcon
ICON_OPEN
=
Utils
.
openIcon
(
"folder"
);
private
static
final
ImageIcon
ICON_SAVE_ALL
=
Utils
.
openIcon
(
"disk_multiple"
);
private
static
final
ImageIcon
ICON_SAVE_ALL
=
Utils
.
openIcon
(
"disk_multiple"
);
private
static
final
ImageIcon
ICON_EXPORT
=
Utils
.
openIcon
(
"database_save"
);
private
static
final
ImageIcon
ICON_CLOSE
=
Utils
.
openIcon
(
"cross"
);
private
static
final
ImageIcon
ICON_CLOSE
=
Utils
.
openIcon
(
"cross"
);
private
static
final
ImageIcon
ICON_SYNC
=
Utils
.
openIcon
(
"sync"
);
private
static
final
ImageIcon
ICON_SYNC
=
Utils
.
openIcon
(
"sync"
);
private
static
final
ImageIcon
ICON_FLAT_PKG
=
Utils
.
openIcon
(
"empty_logical_package_obj"
);
private
static
final
ImageIcon
ICON_FLAT_PKG
=
Utils
.
openIcon
(
"empty_logical_package_obj"
);
...
@@ -232,7 +233,13 @@ public class MainWindow extends JFrame {
...
@@ -232,7 +233,13 @@ public class MainWindow extends JFrame {
}
}
}
}
private
void
saveAll
()
{
private
void
saveAll
(
boolean
export
)
{
settings
.
setExportAsGradleProject
(
export
);
if
(
export
)
{
settings
.
setSkipSources
(
false
);
settings
.
setSkipResources
(
false
);
}
JFileChooser
fileChooser
=
new
JFileChooser
();
JFileChooser
fileChooser
=
new
JFileChooser
();
fileChooser
.
setFileSelectionMode
(
JFileChooser
.
DIRECTORIES_ONLY
);
fileChooser
.
setFileSelectionMode
(
JFileChooser
.
DIRECTORIES_ONLY
);
fileChooser
.
setToolTipText
(
NLS
.
str
(
"file.save_all_msg"
));
fileChooser
.
setToolTipText
(
NLS
.
str
(
"file.save_all_msg"
));
...
@@ -351,12 +358,21 @@ public class MainWindow extends JFrame {
...
@@ -351,12 +358,21 @@ public class MainWindow extends JFrame {
Action
saveAllAction
=
new
AbstractAction
(
NLS
.
str
(
"file.save_all"
),
ICON_SAVE_ALL
)
{
Action
saveAllAction
=
new
AbstractAction
(
NLS
.
str
(
"file.save_all"
),
ICON_SAVE_ALL
)
{
@Override
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
public
void
actionPerformed
(
ActionEvent
e
)
{
saveAll
();
saveAll
(
false
);
}
}
};
};
saveAllAction
.
putValue
(
Action
.
SHORT_DESCRIPTION
,
NLS
.
str
(
"file.save_all"
));
saveAllAction
.
putValue
(
Action
.
SHORT_DESCRIPTION
,
NLS
.
str
(
"file.save_all"
));
saveAllAction
.
putValue
(
Action
.
ACCELERATOR_KEY
,
getKeyStroke
(
KeyEvent
.
VK_S
,
KeyEvent
.
CTRL_DOWN_MASK
));
saveAllAction
.
putValue
(
Action
.
ACCELERATOR_KEY
,
getKeyStroke
(
KeyEvent
.
VK_S
,
KeyEvent
.
CTRL_DOWN_MASK
));
Action
exportAction
=
new
AbstractAction
(
NLS
.
str
(
"file.export_gradle"
),
ICON_EXPORT
)
{
@Override
public
void
actionPerformed
(
ActionEvent
e
)
{
saveAll
(
true
);
}
};
exportAction
.
putValue
(
Action
.
SHORT_DESCRIPTION
,
NLS
.
str
(
"file.export_gradle"
));
exportAction
.
putValue
(
Action
.
ACCELERATOR_KEY
,
getKeyStroke
(
KeyEvent
.
VK_E
,
KeyEvent
.
CTRL_DOWN_MASK
));
JMenu
recentFiles
=
new
JMenu
(
NLS
.
str
(
"menu.recent_files"
));
JMenu
recentFiles
=
new
JMenu
(
NLS
.
str
(
"menu.recent_files"
));
recentFiles
.
addMenuListener
(
new
RecentFilesMenuListener
(
recentFiles
));
recentFiles
.
addMenuListener
(
new
RecentFilesMenuListener
(
recentFiles
));
...
@@ -467,6 +483,7 @@ public class MainWindow extends JFrame {
...
@@ -467,6 +483,7 @@ public class MainWindow extends JFrame {
file
.
setMnemonic
(
KeyEvent
.
VK_F
);
file
.
setMnemonic
(
KeyEvent
.
VK_F
);
file
.
add
(
openAction
);
file
.
add
(
openAction
);
file
.
add
(
saveAllAction
);
file
.
add
(
saveAllAction
);
file
.
add
(
exportAction
);
file
.
addSeparator
();
file
.
addSeparator
();
file
.
add
(
recentFiles
);
file
.
add
(
recentFiles
);
file
.
addSeparator
();
file
.
addSeparator
();
...
@@ -523,6 +540,7 @@ public class MainWindow extends JFrame {
...
@@ -523,6 +540,7 @@ public class MainWindow extends JFrame {
toolbar
.
setFloatable
(
false
);
toolbar
.
setFloatable
(
false
);
toolbar
.
add
(
openAction
);
toolbar
.
add
(
openAction
);
toolbar
.
add
(
saveAllAction
);
toolbar
.
add
(
saveAllAction
);
toolbar
.
add
(
exportAction
);
toolbar
.
addSeparator
();
toolbar
.
addSeparator
();
toolbar
.
add
(
syncAction
);
toolbar
.
add
(
syncAction
);
toolbar
.
add
(
flatPkgButton
);
toolbar
.
add
(
flatPkgButton
);
...
...
jadx-gui/src/main/resources/i18n/Messages_en_US.properties
View file @
b2f41e95
...
@@ -16,6 +16,7 @@ menu.update_label=New version %s available!
...
@@ -16,6 +16,7 @@ menu.update_label=New version %s available!
file.open
=
Open file
file.open
=
Open file
file.save_all
=
Save all
file.save_all
=
Save all
file.export_gradle
=
Save as gradle project
file.save_all_msg
=
Select directory for save decompiled sources
file.save_all_msg
=
Select directory for save decompiled sources
file.select
=
Select
file.select
=
Select
file.exit
=
Exit
file.exit
=
Exit
...
...
jadx-gui/src/main/resources/icons-16/database_save.png
0 → 100644
View file @
b2f41e95
755 Bytes
jadx-test-app/build.gradle
View file @
b2f41e95
project
.
ext
{
ext
{
testAppDir
=
'test-app'
testAppDir
=
'test-app'
testAppTmpDir
=
'test-app-tmp'
testAppTmpDir
=
'test-app-tmp'
b
uildFile
=
"${testAppTmpDir}/build.gradle"
tmpB
uildFile
=
"${testAppTmpDir}/build.gradle"
apkFile
=
"${testAppTmpDir}/build/outputs/apk/test-app-tmp-debug.apk"
apkFile
=
"${testAppTmpDir}/build/outputs/apk/test-app-tmp-debug.apk"
outSrcDir
=
"${testAppTmpDir}/src/main/java"
outCodeDir
=
"${testAppTmpDir}/src/main"
outResDir
=
"${testAppTmpDir}/src/main"
checkTask
=
'connectedCheck'
checkTask
=
'connectedCheck'
}
}
...
@@ -32,24 +31,30 @@ task buildApp(type:Exec, dependsOn: copyApp) {
...
@@ -32,24 +31,30 @@ task buildApp(type:Exec, dependsOn: copyApp) {
}
}
task
removeSource
(
type:
Delete
,
dependsOn:
buildApp
)
{
task
removeSource
(
type:
Delete
,
dependsOn:
buildApp
)
{
delete
"${outResDir}/**"
delete
outCodeDir
}
}
task
runJadx
Src
(
type:
JavaExec
,
dependsOn:
removeSource
)
{
task
runJadx
(
type:
JavaExec
,
dependsOn:
removeSource
)
{
classpath
=
sourceSets
.
main
.
output
+
configurations
.
compile
classpath
=
sourceSets
.
main
.
output
+
configurations
.
compile
main
=
project
(
':jadx-cli'
).
mainClassName
main
=
project
(
':jadx-cli'
).
mainClassName
args
=
[
'-d'
,
outSrcDir
,
'-r'
,
apkFile
,
'-v
'
]
args
=
[
'-d'
,
testAppTmpDir
,
apkFile
,
'-v'
,
'-e
'
]
}
}
task
runJadxResources
(
type:
JavaExec
,
dependsOn:
runJadxSrc
)
{
task
decompile
(
dependsOn:
runJadx
)
{
classpath
=
sourceSets
.
main
.
output
+
configurations
.
compile
doLast
{
main
=
project
(
':jadx-cli'
).
mainClassName
injectDependencies
()
args
=
[
'-d'
,
outResDir
,
'-s'
,
apkFile
,
'-v'
]
}
}
}
task
decompile
(
type:
Delete
,
dependsOn:
runJadxResources
)
{
def
injectDependencies
()
{
delete
"${outSrcDir}/com/github/skylot/jadx/testapp/BuildConfig.java"
def
fileContent
=
file
(
tmpBuildFile
).
getText
(
'UTF-8'
)
delete
"${outSrcDir}/com/github/skylot/jadx/testapp/R.java"
def
updatedContent
=
fileContent
.
replaceAll
(
'// some dependencies'
,
"""
androidTestCompile 'junit:junit:4.12'
androidTestCompile 'org.hamcrest:hamcrest-library:1.3'
"""
)
file
(
tmpBuildFile
).
write
(
updatedContent
,
'UTF-8'
)
}
}
task
runChecks
(
type:
Exec
,
dependsOn:
decompile
)
{
task
runChecks
(
type:
Exec
,
dependsOn:
decompile
)
{
...
...
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