Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Quincy379
jadx
提交
3bbb6b10
J
jadx
项目概览
Quincy379
/
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,体验更适合开发者的 AI 搜索 >>
提交
3bbb6b10
编写于
12月 21, 2020
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: rename all related overridden methods in deobf map file (#1058)
上级
3a4895b2
变更
6
隐藏空白更改
内联
并排
Showing
6 changed file
with
223 addition
and
170 deletion
+223
-170
jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java
jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java
+61
-62
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
+52
-4
jadx-core/src/main/java/jadx/core/dex/visitors/OverrideMethodVisitor.java
...in/java/jadx/core/dex/visitors/OverrideMethodVisitor.java
+36
-13
jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
...e/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
+1
-7
jadx-core/src/test/java/jadx/tests/integration/deobf/TestRenameOverriddenMethod2.java
.../tests/integration/deobf/TestRenameOverriddenMethod2.java
+53
-0
jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java
jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java
+20
-84
未找到文件。
jadx-core/src/main/java/jadx/core/deobf/DeobfPresets.java
浏览文件 @
3bbb6b10
package
jadx.core.deobf
;
import
java.io.File
;
import
java.io.IOException
;
import
java.nio.charset.Charset
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.StandardOpenOption
;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashMap
;
import
java.util.List
;
import
java.util.Map
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.info.FieldInfo
;
import
jadx.core.dex.info.MethodInfo
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.utils.files.FileUtils
;
import
static
java
.
nio
.
charset
.
StandardCharsets
.
UTF_8
;
class
DeobfPresets
{
public
class
DeobfPresets
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
DeobfPresets
.
class
);
private
static
final
Charset
MAP_FILE_CHARSET
=
UTF_8
;
private
final
Deobfuscator
deobfuscator
;
private
final
Path
deobfMapFile
;
private
final
Map
<
String
,
String
>
pkgPresetMap
=
new
HashMap
<>();
private
final
Map
<
String
,
String
>
clsPresetMap
=
new
HashMap
<>();
private
final
Map
<
String
,
String
>
fldPresetMap
=
new
HashMap
<>();
private
final
Map
<
String
,
String
>
mthPresetMap
=
new
HashMap
<>();
public
DeobfPresets
(
Deobfuscator
deobfuscator
,
Path
deobfMapFile
)
{
this
.
deobfuscator
=
deobfuscator
;
@Nullable
public
static
DeobfPresets
build
(
RootNode
root
)
{
Path
deobfMapPath
=
getPathDeobfMapPath
(
root
);
if
(
deobfMapPath
==
null
)
{
return
null
;
}
return
new
DeobfPresets
(
deobfMapPath
);
}
@Nullable
private
static
Path
getPathDeobfMapPath
(
RootNode
root
)
{
List
<
File
>
inputFiles
=
root
.
getArgs
().
getInputFiles
();
if
(
inputFiles
.
isEmpty
())
{
return
null
;
}
Path
inputFilePath
=
inputFiles
.
get
(
0
).
getAbsoluteFile
().
toPath
();
String
baseName
=
FileUtils
.
getPathBaseName
(
inputFilePath
);
return
inputFilePath
.
getParent
().
resolve
(
baseName
+
".jobf"
);
}
private
DeobfPresets
(
Path
deobfMapFile
)
{
this
.
deobfMapFile
=
deobfMapFile
;
}
...
...
@@ -57,17 +81,22 @@ class DeobfPresets {
}
String
origName
=
va
[
0
];
String
alias
=
va
[
1
];
if
(
l
.
startsWith
(
"p "
))
{
deobfuscator
.
addPackagePreset
(
origName
,
alias
);
}
else
if
(
l
.
startsWith
(
"c "
))
{
clsPresetMap
.
put
(
origName
,
alias
);
}
else
if
(
l
.
startsWith
(
"f "
))
{
fldPresetMap
.
put
(
origName
,
alias
);
}
else
if
(
l
.
startsWith
(
"m "
))
{
mthPresetMap
.
put
(
origName
,
alias
);
switch
(
l
.
charAt
(
0
))
{
case
'p'
:
pkgPresetMap
.
put
(
origName
,
alias
);
break
;
case
'c'
:
clsPresetMap
.
put
(
origName
,
alias
);
break
;
case
'f'
:
fldPresetMap
.
put
(
origName
,
alias
);
break
;
case
'm'
:
mthPresetMap
.
put
(
origName
,
alias
);
break
;
}
}
}
catch
(
IO
Exception
e
)
{
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to load deobfuscation map file '{}'"
,
deobfMapFile
.
toAbsolutePath
(),
e
);
}
}
...
...
@@ -80,66 +109,28 @@ class DeobfPresets {
return
v
;
}
public
void
save
(
boolean
forceSave
)
{
try
{
if
(
Files
.
exists
(
deobfMapFile
))
{
if
(
forceSave
)
{
dumpMapping
();
}
else
{
LOG
.
warn
(
"Deobfuscation map file '{}' exists. Use command line option '--deobf-rewrite-cfg' to rewrite it"
,
deobfMapFile
.
toAbsolutePath
());
}
}
else
{
dumpMapping
();
}
}
catch
(
IOException
e
)
{
LOG
.
error
(
"Failed to load deobfuscation map file '{}'"
,
deobfMapFile
.
toAbsolutePath
(),
e
);
}
}
/**
* Saves DefaultDeobfuscator presets
*/
private
void
dumpMapping
()
throws
IOException
{
public
void
save
()
throws
IOException
{
List
<
String
>
list
=
new
ArrayList
<>();
// packages
for
(
PackageNode
p
:
deobfuscator
.
getRootPackage
().
getInnerPackages
())
{
for
(
PackageNode
pp
:
p
.
getInnerPackages
())
{
dfsPackageName
(
list
,
p
.
getName
(),
pp
);
}
if
(
p
.
hasAlias
())
{
list
.
add
(
String
.
format
(
"p %s = %s"
,
p
.
getName
(),
p
.
getAlias
()));
}
for
(
Map
.
Entry
<
String
,
String
>
pkgEntry
:
pkgPresetMap
.
entrySet
())
{
list
.
add
(
String
.
format
(
"p %s = %s"
,
pkgEntry
.
getKey
(),
pkgEntry
.
getValue
()));
}
// classes
for
(
DeobfClsInfo
deobfClsInfo
:
deobfuscator
.
getClsMap
().
values
())
{
if
(
deobfClsInfo
.
getAlias
()
!=
null
)
{
list
.
add
(
String
.
format
(
"c %s = %s"
,
deobfClsInfo
.
getCls
().
getClassInfo
().
makeRawFullName
(),
deobfClsInfo
.
getAlias
()));
}
for
(
Map
.
Entry
<
String
,
String
>
clsEntry
:
clsPresetMap
.
entrySet
())
{
list
.
add
(
String
.
format
(
"c %s = %s"
,
clsEntry
.
getKey
(),
clsEntry
.
getValue
()));
}
for
(
FieldInfo
fld
:
deobfuscator
.
getFldMap
().
ke
ySet
())
{
list
.
add
(
String
.
format
(
"f %s = %s"
,
fld
.
getRawFullId
(),
fld
.
getAlias
()));
for
(
Map
.
Entry
<
String
,
String
>
fldEntry
:
fldPresetMap
.
entr
ySet
())
{
list
.
add
(
String
.
format
(
"f %s = %s"
,
fld
Entry
.
getKey
(),
fldEntry
.
getValue
()));
}
for
(
M
ethodInfo
mth
:
deobfuscator
.
getMthMap
().
ke
ySet
())
{
list
.
add
(
String
.
format
(
"m %s = %s"
,
mth
.
getRawFullId
(),
mth
.
getAlias
()));
for
(
M
ap
.
Entry
<
String
,
String
>
mthEntry
:
mthPresetMap
.
entr
ySet
())
{
list
.
add
(
String
.
format
(
"m %s = %s"
,
mth
Entry
.
getKey
(),
mthEntry
.
getValue
()));
}
Collections
.
sort
(
list
);
Files
.
write
(
deobfMapFile
,
list
,
MAP_FILE_CHARSET
);
Files
.
write
(
deobfMapFile
,
list
,
MAP_FILE_CHARSET
,
StandardOpenOption
.
WRITE
,
StandardOpenOption
.
CREATE
,
StandardOpenOption
.
TRUNCATE_EXISTING
);
if
(
LOG
.
isDebugEnabled
())
{
LOG
.
debug
(
"Deobfuscation map file saved as: {}"
,
deobfMapFile
);
}
}
private
static
void
dfsPackageName
(
List
<
String
>
list
,
String
prefix
,
PackageNode
node
)
{
for
(
PackageNode
pp
:
node
.
getInnerPackages
())
{
dfsPackageName
(
list
,
prefix
+
'.'
+
node
.
getName
(),
pp
);
}
if
(
node
.
hasAlias
())
{
list
.
add
(
String
.
format
(
"p %s.%s = %s"
,
prefix
,
node
.
getName
(),
node
.
getAlias
()));
}
}
public
String
getForCls
(
ClassInfo
cls
)
{
return
clsPresetMap
.
get
(
cls
.
makeRawFullName
());
}
...
...
@@ -158,6 +149,14 @@ class DeobfPresets {
mthPresetMap
.
clear
();
}
public
Path
getDeobfMapFile
()
{
return
deobfMapFile
;
}
public
Map
<
String
,
String
>
getPkgPresetMap
()
{
return
pkgPresetMap
;
}
public
Map
<
String
,
String
>
getClsPresetMap
()
{
return
clsPresetMap
;
}
...
...
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
浏览文件 @
3bbb6b10
package
jadx.core.deobf
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.util.Collections
;
import
java.util.HashMap
;
...
...
@@ -58,28 +59,75 @@ public class Deobfuscator {
private
int
fldIndex
=
0
;
private
int
mthIndex
=
0
;
public
Deobfuscator
(
JadxArgs
args
,
RootNode
root
,
Path
deobfMapFile
)
{
this
.
args
=
args
;
public
Deobfuscator
(
RootNode
root
)
{
this
.
root
=
root
;
this
.
args
=
root
.
getArgs
();
this
.
minLength
=
args
.
getDeobfuscationMinLength
();
this
.
maxLength
=
args
.
getDeobfuscationMaxLength
();
this
.
useSourceNameAsAlias
=
args
.
isUseSourceNameAsClassAlias
();
this
.
parseKotlinMetadata
=
args
.
isParseKotlinMetadata
();
this
.
deobfPresets
=
new
DeobfPresets
(
this
,
deobfMapFile
);
this
.
deobfPresets
=
DeobfPresets
.
build
(
root
);
}
public
void
execute
()
{
if
(!
args
.
isDeobfuscationForceSave
())
{
deobfPresets
.
load
();
for
(
Map
.
Entry
<
String
,
String
>
pkgEntry
:
deobfPresets
.
getPkgPresetMap
().
entrySet
())
{
addPackagePreset
(
pkgEntry
.
getKey
(),
pkgEntry
.
getValue
());
}
deobfPresets
.
getPkgPresetMap
().
clear
();
// not needed anymore
initIndexes
();
}
process
();
}
public
void
savePresets
()
{
deobfPresets
.
save
(
args
.
isDeobfuscationForceSave
());
Path
deobfMapFile
=
deobfPresets
.
getDeobfMapFile
();
if
(
Files
.
exists
(
deobfMapFile
)
&&
!
args
.
isDeobfuscationForceSave
())
{
LOG
.
warn
(
"Deobfuscation map file '{}' exists. Use command line option '--deobf-rewrite-cfg' to rewrite it"
,
deobfMapFile
.
toAbsolutePath
());
return
;
}
try
{
deobfPresets
.
clear
();
fillDeobfPresets
();
deobfPresets
.
save
();
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to save deobfuscation map file '{}'"
,
deobfMapFile
.
toAbsolutePath
(),
e
);
}
}
private
void
fillDeobfPresets
()
{
for
(
PackageNode
p
:
getRootPackage
().
getInnerPackages
())
{
for
(
PackageNode
pp
:
p
.
getInnerPackages
())
{
dfsPackageName
(
p
.
getName
(),
pp
);
}
if
(
p
.
hasAlias
())
{
deobfPresets
.
getPkgPresetMap
().
put
(
p
.
getName
(),
p
.
getAlias
());
}
}
for
(
DeobfClsInfo
deobfClsInfo
:
clsMap
.
values
())
{
if
(
deobfClsInfo
.
getAlias
()
!=
null
)
{
deobfPresets
.
getClsPresetMap
().
put
(
deobfClsInfo
.
getCls
().
getClassInfo
().
makeRawFullName
(),
deobfClsInfo
.
getAlias
());
}
}
for
(
FieldInfo
fld
:
fldMap
.
keySet
())
{
deobfPresets
.
getFldPresetMap
().
put
(
fld
.
getRawFullId
(),
fld
.
getAlias
());
}
for
(
MethodInfo
mth
:
mthMap
.
keySet
())
{
deobfPresets
.
getMthPresetMap
().
put
(
mth
.
getRawFullId
(),
mth
.
getAlias
());
}
}
private
void
dfsPackageName
(
String
prefix
,
PackageNode
node
)
{
for
(
PackageNode
pp
:
node
.
getInnerPackages
())
{
dfsPackageName
(
prefix
+
'.'
+
node
.
getName
(),
pp
);
}
if
(
node
.
hasAlias
())
{
deobfPresets
.
getPkgPresetMap
().
put
(
node
.
getName
(),
node
.
getAlias
());
}
}
public
void
clear
()
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/OverrideMethodVisitor.java
浏览文件 @
3bbb6b10
...
...
@@ -2,10 +2,12 @@ package jadx.core.dex.visitors;
import
java.util.ArrayList
;
import
java.util.Collections
;
import
java.util.HashSet
;
import
java.util.LinkedHashMap
;
import
java.util.List
;
import
java.util.Map
;
import
java.util.Objects
;
import
java.util.Set
;
import
java.util.stream.Collectors
;
import
org.jetbrains.annotations.NotNull
;
...
...
@@ -74,16 +76,12 @@ public class OverrideMethodVisitor extends AbstractVisitor {
for
(
ArgType
superType
:
superTypes
)
{
ClassNode
classNode
=
cls
.
root
().
resolveClass
(
superType
);
if
(
classNode
!=
null
)
{
for
(
MethodNode
supMth
:
classNode
.
getMethods
())
{
String
mthShortId
=
supMth
.
getMethodInfo
().
getShortId
();
if
(!
supMth
.
getAccessFlags
().
isStatic
()
&&
mthShortId
.
startsWith
(
signature
)
&&
isMethodVisibleInCls
(
supMth
,
cls
))
{
overrideList
.
add
(
supMth
);
MethodOverrideAttr
attr
=
supMth
.
get
(
AType
.
METHOD_OVERRIDE
);
if
(
attr
!=
null
)
{
return
buildOverrideAttr
(
mth
,
overrideList
,
attr
);
}
MethodNode
ovrdMth
=
searchOverriddenMethod
(
classNode
,
signature
);
if
(
ovrdMth
!=
null
&&
isMethodVisibleInCls
(
ovrdMth
,
cls
))
{
overrideList
.
add
(
ovrdMth
);
MethodOverrideAttr
attr
=
ovrdMth
.
get
(
AType
.
METHOD_OVERRIDE
);
if
(
attr
!=
null
)
{
return
buildOverrideAttr
(
mth
,
overrideList
,
attr
);
}
}
}
else
{
...
...
@@ -102,25 +100,50 @@ public class OverrideMethodVisitor extends AbstractVisitor {
return
buildOverrideAttr
(
mth
,
overrideList
,
null
);
}
@Nullable
private
MethodNode
searchOverriddenMethod
(
ClassNode
cls
,
String
signature
)
{
for
(
MethodNode
supMth
:
cls
.
getMethods
())
{
if
(!
supMth
.
getAccessFlags
().
isStatic
()
&&
supMth
.
getMethodInfo
().
getShortId
().
startsWith
(
signature
))
{
return
supMth
;
}
}
return
null
;
}
@Nullable
private
MethodOverrideAttr
buildOverrideAttr
(
MethodNode
mth
,
List
<
IMethodDetails
>
overrideList
,
@Nullable
MethodOverrideAttr
attr
)
{
if
(
overrideList
.
isEmpty
()
&&
attr
==
null
)
{
return
null
;
}
List
<
IMethodDetails
>
cleanOverrideList
=
overrideList
.
stream
().
distinct
().
collect
(
Collectors
.
toList
());
if
(
attr
==
null
)
{
// traced to base method
List
<
IMethodDetails
>
cleanOverrideList
=
overrideList
.
stream
().
distinct
().
collect
(
Collectors
.
toList
());
return
applyOverrideAttr
(
mth
,
cleanOverrideList
,
false
);
}
// trace stopped at already processed method -> start merging
List
<
IMethodDetails
>
mergedOverrideList
=
Utils
.
mergeLists
(
cleanOverrideList
,
attr
.
getOverrideList
());
return
applyOverrideAttr
(
mth
,
mergedOverrideList
,
true
);
List
<
IMethodDetails
>
mergedOverrideList
=
Utils
.
mergeLists
(
overrideList
,
attr
.
getOverrideList
());
List
<
IMethodDetails
>
cleanOverrideList
=
mergedOverrideList
.
stream
().
distinct
().
collect
(
Collectors
.
toList
());
return
applyOverrideAttr
(
mth
,
cleanOverrideList
,
true
);
}
private
MethodOverrideAttr
applyOverrideAttr
(
MethodNode
mth
,
List
<
IMethodDetails
>
overrideList
,
boolean
update
)
{
// don't rename method if override list contains not resolved method
boolean
dontRename
=
overrideList
.
stream
().
anyMatch
(
m
->
!(
m
instanceof
MethodNode
));
List
<
MethodNode
>
mthNodes
=
getMethodNodes
(
mth
,
overrideList
);
if
(
update
)
{
// merge related methods from all override attributes
Set
<
MethodNode
>
relatedMthSet
=
new
HashSet
<>(
mthNodes
);
for
(
MethodNode
mthNode
:
mthNodes
)
{
MethodOverrideAttr
ovrdAttr
=
mthNode
.
get
(
AType
.
METHOD_OVERRIDE
);
if
(
ovrdAttr
!=
null
)
{
relatedMthSet
.
addAll
(
ovrdAttr
.
getRelatedMthNodes
());
}
}
if
(
relatedMthSet
.
size
()
!=
mthNodes
.
size
())
{
mthNodes
=
new
ArrayList
<>(
relatedMthSet
);
Collections
.
sort
(
mthNodes
);
}
}
int
depth
=
0
;
for
(
MethodNode
mthNode
:
mthNodes
)
{
if
(
dontRename
)
{
...
...
jadx-core/src/main/java/jadx/core/dex/visitors/RenameVisitor.java
浏览文件 @
3bbb6b10
package
jadx.core.dex.visitors
;
import
java.io.File
;
import
java.nio.file.Path
;
import
java.util.ArrayList
;
import
java.util.HashSet
;
import
java.util.List
;
...
...
@@ -23,7 +22,6 @@ import jadx.core.dex.nodes.ClassNode;
import
jadx.core.dex.nodes.FieldNode
;
import
jadx.core.dex.nodes.MethodNode
;
import
jadx.core.dex.nodes.RootNode
;
import
jadx.core.utils.files.FileUtils
;
public
class
RenameVisitor
extends
AbstractVisitor
{
...
...
@@ -33,12 +31,8 @@ public class RenameVisitor extends AbstractVisitor {
if
(
inputFiles
.
isEmpty
())
{
return
;
}
Path
inputFilePath
=
inputFiles
.
get
(
0
).
getAbsoluteFile
().
toPath
();
String
baseName
=
FileUtils
.
getPathBaseName
(
inputFilePath
);
Path
deobfMapPath
=
inputFilePath
.
getParent
().
resolve
(
baseName
+
".jobf"
);
Deobfuscator
deobfuscator
=
new
Deobfuscator
(
root
);
JadxArgs
args
=
root
.
getArgs
();
Deobfuscator
deobfuscator
=
new
Deobfuscator
(
args
,
root
,
deobfMapPath
);
if
(
args
.
isDeobfuscationOn
())
{
deobfuscator
.
execute
();
}
...
...
jadx-core/src/test/java/jadx/tests/integration/deobf/TestRenameOverriddenMethod2.java
0 → 100644
浏览文件 @
3bbb6b10
package
jadx.tests.integration.deobf
;
import
org.junit.jupiter.api.Test
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.nodes.ClassNode
;
import
jadx.tests.api.IntegrationTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestRenameOverriddenMethod2
extends
IntegrationTest
{
public
static
class
TestCls
{
public
interface
I
{
int
call
();
}
public
static
class
A
implements
I
{
@Override
public
int
call
()
{
return
1
;
}
}
public
static
class
B
implements
I
{
@Override
public
int
call
()
{
return
2
;
}
}
}
@Test
public
void
test
()
{
enableDeobfuscation
();
args
.
setDeobfuscationMinLength
(
100
);
// rename everything
ClassNode
cls
=
getClassNode
(
TestCls
.
class
);
assertThat
(
cls
)
.
code
()
.
countString
(
2
,
"@Override"
)
.
countString
(
3
,
"int mo0call()"
);
assertThat
(
searchCls
(
cls
.
getInnerClasses
(),
"I"
)).
isNotNull
()
.
extracting
(
c
->
c
.
searchMethodByShortName
(
"call"
)).
isNotNull
()
.
extracting
(
m
->
m
.
get
(
AType
.
METHOD_OVERRIDE
)).
isNotNull
()
.
satisfies
(
ovrdAttr
->
{
assertThat
(
ovrdAttr
.
getRelatedMthNodes
()).
hasSize
(
3
);
assertThat
(
ovrdAttr
.
getOverrideList
()).
isEmpty
();
});
}
}
jadx-gui/src/main/java/jadx/gui/ui/RenameDialog.java
浏览文件 @
3bbb6b10
...
...
@@ -4,13 +4,6 @@ import java.awt.BorderLayout;
import
java.awt.Container
;
import
java.awt.Dimension
;
import
java.awt.FlowLayout
;
import
java.io.File
;
import
java.io.IOException
;
import
java.io.Writer
;
import
java.nio.charset.StandardCharsets
;
import
java.nio.file.Files
;
import
java.nio.file.Path
;
import
java.nio.file.StandardCopyOption
;
import
java.util.ArrayList
;
import
java.util.List
;
import
java.util.Map
;
...
...
@@ -39,6 +32,7 @@ import jadx.api.JavaField;
import
jadx.api.JavaMethod
;
import
jadx.api.JavaNode
;
import
jadx.core.codegen.CodeWriter
;
import
jadx.core.deobf.DeobfPresets
;
import
jadx.core.dex.attributes.AType
;
import
jadx.core.dex.attributes.nodes.MethodOverrideAttr
;
import
jadx.core.dex.nodes.MethodNode
;
...
...
@@ -117,85 +111,25 @@ public class RenameDialog extends JDialog {
return
false
;
// TODO: can't open dialog, 'node' is replaced with new one after reopen
}
private
Path
getDeobfMapPath
(
RootNode
root
)
{
List
<
File
>
inputFiles
=
root
.
getArgs
().
getInputFiles
();
if
(
inputFiles
.
isEmpty
())
{
return
null
;
}
File
firstInputFile
=
inputFiles
.
get
(
0
);
Path
inputFilePath
=
firstInputFile
.
getAbsoluteFile
().
toPath
();
String
inputName
=
inputFilePath
.
getFileName
().
toString
();
String
baseName
=
inputName
.
substring
(
0
,
inputName
.
lastIndexOf
(
'.'
));
return
inputFilePath
.
getParent
().
resolve
(
baseName
+
".jobf"
);
}
private
String
getNodeAlias
(
String
renameText
)
{
String
type
=
""
;
String
id
=
""
;
private
void
updateDeobfMap
(
DeobfPresets
deobfPresets
,
String
renameText
)
{
if
(
node
instanceof
JMethod
)
{
JavaMethod
javaMethod
=
(
JavaMethod
)
node
.
getJavaNode
();
type
=
"m"
;
MethodNode
mthNode
=
javaMethod
.
getMethodNode
();
MethodNode
mthNode
=
((
JavaMethod
)
node
.
getJavaNode
()).
getMethodNode
();
MethodOverrideAttr
overrideAttr
=
mthNode
.
get
(
AType
.
METHOD_OVERRIDE
);
if
(
overrideAttr
!=
null
)
{
// use method closest to base method
mthNode
=
Objects
.
requireNonNull
(
Utils
.
last
(
overrideAttr
.
getRelatedMthNodes
()));
for
(
MethodNode
relatedMth
:
overrideAttr
.
getRelatedMthNodes
())
{
deobfPresets
.
getMthPresetMap
().
put
(
relatedMth
.
getMethodInfo
().
getRawFullId
(),
renameText
);
}
}
id
=
mthNode
.
getMethodInfo
().
getRawFullId
(
);
deobfPresets
.
getMthPresetMap
().
put
(
mthNode
.
getMethodInfo
().
getRawFullId
(),
renameText
);
}
else
if
(
node
instanceof
JField
)
{
JavaField
javaField
=
(
JavaField
)
node
.
getJavaNode
();
type
=
"f"
;
id
=
javaField
.
getFieldNode
().
getFieldInfo
().
getRawFullId
();
deobfPresets
.
getFldPresetMap
().
put
(
javaField
.
getFieldNode
().
getFieldInfo
().
getRawFullId
(),
renameText
);
}
else
if
(
node
instanceof
JClass
)
{
JavaClass
javaClass
=
(
JavaClass
)
node
.
getJavaNode
();
type
=
"c"
;
id
=
javaClass
.
getRawName
();
deobfPresets
.
getClsPresetMap
().
put
(
javaClass
.
getRawName
(),
renameText
);
}
else
if
(
node
instanceof
JPackage
)
{
type
=
"p"
;
id
=
((
JPackage
)
node
).
getFullName
();
}
return
String
.
format
(
"%s %s = %s"
,
type
,
id
,
renameText
);
}
private
void
writeDeobfMapFile
(
Path
deobfMapPath
,
List
<
String
>
deobfMap
)
throws
IOException
{
if
(
deobfMapPath
==
null
)
{
LOG
.
error
(
"updateDeobfMapFile(): deobfMapPath is null!"
);
return
;
}
Path
deobfMapDir
=
deobfMapPath
.
getParent
();
Path
tmpFile
=
Files
.
createTempFile
(
deobfMapDir
,
"deobf_tmp_"
,
".txt"
);
try
(
Writer
writer
=
Files
.
newBufferedWriter
(
tmpFile
,
StandardCharsets
.
UTF_8
))
{
for
(
String
entry
:
deobfMap
)
{
writer
.
write
(
entry
);
writer
.
write
(
System
.
lineSeparator
());
}
deobfPresets
.
getPkgPresetMap
().
put
(((
JPackage
)
node
).
getFullName
(),
renameText
);
}
Files
.
move
(
tmpFile
,
deobfMapPath
,
StandardCopyOption
.
REPLACE_EXISTING
,
StandardCopyOption
.
ATOMIC_MOVE
);
LOG
.
info
(
"Updated deobf file {}"
,
deobfMapPath
);
}
@NotNull
private
List
<
String
>
readDeobfMap
(
Path
deobfMapPath
)
throws
IOException
{
return
Files
.
readAllLines
(
deobfMapPath
,
StandardCharsets
.
UTF_8
);
}
private
List
<
String
>
updateDeobfMap
(
List
<
String
>
deobfMap
,
String
alias
)
{
String
id
=
alias
.
substring
(
0
,
alias
.
indexOf
(
'='
)
+
1
);
int
i
=
0
;
while
(
i
<
deobfMap
.
size
())
{
String
entry
=
deobfMap
.
get
(
i
);
if
(
entry
.
startsWith
(
id
))
{
LOG
.
debug
(
"updateDeobfMap(): Removing entry {}"
,
entry
);
deobfMap
.
remove
(
i
);
}
else
{
i
++;
}
}
LOG
.
debug
(
"updateDeobfMap(): placing alias = {}"
,
alias
);
deobfMap
.
add
(
alias
);
return
deobfMap
;
}
private
void
rename
()
{
...
...
@@ -223,18 +157,20 @@ public class RenameDialog extends JDialog {
}
private
boolean
refreshDeobfMapFile
(
String
renameText
,
RootNode
root
)
{
List
<
String
>
deobfMap
;
Path
deobfMapPath
=
getDeobfMapPath
(
root
);
DeobfPresets
deobfPresets
=
DeobfPresets
.
build
(
root
);
if
(
deobfPresets
==
null
)
{
return
false
;
}
try
{
deobf
Map
=
readDeobfMap
(
deobfMapPath
);
}
catch
(
IO
Exception
e
)
{
deobf
Presets
.
load
(
);
}
catch
(
Exception
e
)
{
LOG
.
error
(
"rename(): readDeobfMap() failed"
);
return
false
;
}
updateDeobfMap
(
deobf
Map
,
getNodeAlias
(
renameText
)
);
updateDeobfMap
(
deobf
Presets
,
renameText
);
try
{
writeDeobfMapFile
(
deobfMapPath
,
deobfMap
);
}
catch
(
IO
Exception
e
)
{
deobfPresets
.
save
(
);
}
catch
(
Exception
e
)
{
LOG
.
error
(
"rename(): writeDeobfMap() failed"
);
return
false
;
}
...
...
@@ -301,7 +237,7 @@ public class RenameDialog extends JDialog {
cls
.
reload
();
IndexJob
.
refreshIndex
(
cache
,
cls
.
getCls
());
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to reload class: {}"
,
cls
,
e
);
LOG
.
error
(
"Failed to reload class: {}"
,
cls
.
getFullName
()
,
e
);
}
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录