Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2301_76393173
jadx
提交
91ee7565
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,发现更多精彩内容 >>
提交
91ee7565
编写于
9月 14, 2020
作者:
S
Skylot
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
fix: resolved regression in Kotlin metadata parser
上级
1bbcac2a
变更
4
显示空白变更内容
内联
并排
Showing
4 changed file
with
217 addition
and
51 deletion
+217
-51
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
+37
-51
jadx-core/src/main/java/jadx/core/utils/kotlin/KotlinMetadataUtils.java
...main/java/jadx/core/utils/kotlin/KotlinMetadataUtils.java
+59
-0
jadx-core/src/test/java/jadx/tests/integration/deobf/TestKotlinMetadata.java
...java/jadx/tests/integration/deobf/TestKotlinMetadata.java
+48
-0
jadx-core/src/test/smali/deobf/TestKotlinMetadata.smali
jadx-core/src/test/smali/deobf/TestKotlinMetadata.smali
+73
-0
未找到文件。
jadx-core/src/main/java/jadx/core/deobf/Deobfuscator.java
浏览文件 @
91ee7565
...
...
@@ -28,6 +28,7 @@ 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.kotlin.KotlinMetadataUtils
;
public
class
Deobfuscator
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
Deobfuscator
.
class
);
...
...
@@ -36,9 +37,6 @@ public class Deobfuscator {
public
static
final
String
CLASS_NAME_SEPARATOR
=
"."
;
public
static
final
String
INNER_CLASS_SEPARATOR
=
"$"
;
public
static
final
String
KOTLIN_METADATA_ANNOTATION
=
"kotlin.Metadata"
;
public
static
final
String
KOTLIN_METADATA_D2_PARAMETER
=
"d2"
;
public
static
final
String
KOTLIN_METADATA_CLASSNAME_REGEX
=
"(L.*;)"
;
private
final
JadxArgs
args
;
private
final
RootNode
root
;
...
...
@@ -351,9 +349,8 @@ public class Deobfuscator {
}
else
{
if
(!
clsMap
.
containsKey
(
classInfo
))
{
String
clsShortName
=
classInfo
.
getShortName
();
if
(
shouldRename
(
clsShortName
)
||
reservedClsNames
.
contains
(
clsShortName
))
{
makeClsAlias
(
cls
);
}
boolean
badName
=
shouldRename
(
clsShortName
)
||
reservedClsNames
.
contains
(
clsShortName
);
makeClsAlias
(
cls
,
badName
);
}
}
for
(
ClassNode
innerCls
:
cls
.
getInnerClasses
())
{
...
...
@@ -366,7 +363,7 @@ public class Deobfuscator {
if
(
deobfClsInfo
!=
null
)
{
return
deobfClsInfo
.
getAlias
();
}
return
makeClsAlias
(
cls
);
return
makeClsAlias
(
cls
,
true
);
}
public
String
getPkgAlias
(
ClassNode
cls
)
{
...
...
@@ -387,41 +384,35 @@ public class Deobfuscator {
}
}
private
String
makeClsAlias
(
ClassNode
cls
)
{
ClassInfo
classInfo
=
cls
.
getClassInfo
();
String
metadataClassName
=
""
;
String
metadataPackageName
=
""
;
private
String
makeClsAlias
(
ClassNode
cls
,
boolean
badName
)
{
String
alias
=
null
;
String
pkgName
=
null
;
if
(
this
.
parseKotlinMetadata
)
{
String
rawClassName
=
getRawClassNameFromMetadata
(
cls
);
if
(
rawClassName
!=
null
)
{
metadataClassName
=
rawClassName
.
substring
(
rawClassName
.
lastIndexOf
(
"."
)
+
1
,
rawClassName
.
length
()
-
1
);
if
(
rawClassName
.
lastIndexOf
(
"."
)
!=
-
1
)
{
metadataPackageName
=
rawClassName
.
substring
(
1
,
rawClassName
.
lastIndexOf
(
"."
));
ClassInfo
kotlinCls
=
KotlinMetadataUtils
.
getClassName
(
cls
);
if
(
kotlinCls
!=
null
)
{
alias
=
prepareNameFull
(
kotlinCls
.
getShortName
(),
"C"
);
pkgName
=
kotlinCls
.
getPackage
();
}
}
}
String
alias
=
null
;
if
(
this
.
useSourceNameAsAlias
)
{
if
(
alias
==
null
&&
this
.
useSourceNameAsAlias
)
{
alias
=
getAliasFromSourceFile
(
cls
);
}
ClassInfo
classInfo
=
cls
.
getClassInfo
();
if
(
alias
==
null
)
{
if
(
metadataClassName
.
isEmpty
()
)
{
if
(
badName
)
{
String
clsName
=
classInfo
.
getShortName
();
String
prefix
=
makeClsPrefix
(
cls
);
alias
=
String
.
format
(
"%sC%04d%s"
,
prefix
,
clsIndex
++,
prepareNamePart
(
clsName
));
}
else
{
alias
=
metadataClassName
;
// rename not needed
return
classInfo
.
getShortName
();
}
}
PackageNode
pkg
;
if
(
metadataPackageName
.
isEmpty
())
{
pkg
=
getPackageNode
(
classInfo
.
getPackage
(),
true
);
}
else
{
pkg
=
getPackageNode
(
metadataPackageName
,
true
);
if
(
pkgName
==
null
)
{
pkgName
=
classInfo
.
getPackage
();
}
PackageNode
pkg
=
getPackageNode
(
pkgName
,
true
);
clsMap
.
put
(
classInfo
,
new
DeobfClsInfo
(
this
,
cls
,
pkg
,
alias
));
return
alias
;
}
...
...
@@ -484,29 +475,6 @@ public class Deobfuscator {
return
result
;
}
/**
* Try to get class name form Kotlin meta data
*
* @param cls
* @return
*/
@Nullable
private
String
getRawClassNameFromMetadata
(
ClassNode
cls
)
{
if
(
cls
.
getAnnotation
(
KOTLIN_METADATA_ANNOTATION
)
!=
null
&&
cls
.
getAnnotation
(
KOTLIN_METADATA_ANNOTATION
).
getValues
().
get
(
KOTLIN_METADATA_D2_PARAMETER
)
!=
null
&&
cls
.
getAnnotation
(
KOTLIN_METADATA_ANNOTATION
).
getValues
().
get
(
KOTLIN_METADATA_D2_PARAMETER
)
instanceof
List
)
{
Object
rawClassNameObject
=
((
List
)
cls
.
getAnnotation
(
KOTLIN_METADATA_ANNOTATION
).
getValues
().
get
(
KOTLIN_METADATA_D2_PARAMETER
)).
get
(
0
);
if
(
rawClassNameObject
instanceof
String
)
{
String
rawClassName
=
((
String
)
rawClassNameObject
).
trim
().
replace
(
"/"
,
"."
);
if
(
rawClassName
.
length
()
>
1
&&
rawClassName
.
matches
(
KOTLIN_METADATA_CLASSNAME_REGEX
))
{
return
rawClassName
;
}
}
}
return
null
;
}
@Nullable
private
String
getAliasFromSourceFile
(
ClassNode
cls
)
{
SourceFileAttr
sourceFileAttr
=
cls
.
get
(
AType
.
SOURCE_FILE
);
...
...
@@ -628,6 +596,24 @@ public class Deobfuscator {
return
NameMapper
.
removeInvalidCharsMiddle
(
name
);
}
private
String
prepareNameFull
(
String
name
,
String
prefix
)
{
if
(
name
.
length
()
>
maxLength
)
{
return
makeHashName
(
name
,
prefix
);
}
String
result
=
NameMapper
.
removeInvalidChars
(
name
,
prefix
);
if
(
result
.
isEmpty
())
{
return
makeHashName
(
name
,
prefix
);
}
if
(
NameMapper
.
isReserved
(
result
))
{
return
prefix
+
result
;
}
return
result
;
}
private
static
String
makeHashName
(
String
name
,
String
invalidPrefix
)
{
return
invalidPrefix
+
'x'
+
Integer
.
toHexString
(
name
.
hashCode
());
}
private
void
dumpClassAlias
(
ClassNode
cls
)
{
PackageNode
pkg
=
getPackageNode
(
cls
.
getPackage
(),
false
);
...
...
jadx-core/src/main/java/jadx/core/utils/kotlin/KotlinMetadataUtils.java
0 → 100644
浏览文件 @
91ee7565
package
jadx.core.utils.kotlin
;
import
java.util.List
;
import
org.jetbrains.annotations.Nullable
;
import
org.slf4j.Logger
;
import
org.slf4j.LoggerFactory
;
import
jadx.api.plugins.input.data.annotations.EncodedType
;
import
jadx.api.plugins.input.data.annotations.EncodedValue
;
import
jadx.api.plugins.input.data.annotations.IAnnotation
;
import
jadx.core.dex.info.ClassInfo
;
import
jadx.core.dex.nodes.ClassNode
;
// TODO: parse data from d1 (protobuf encoded) to get original method names and other useful info
public
class
KotlinMetadataUtils
{
private
static
final
Logger
LOG
=
LoggerFactory
.
getLogger
(
KotlinMetadataUtils
.
class
);
private
static
final
String
KOTLIN_METADATA_ANNOTATION
=
"Lkotlin/Metadata;"
;
private
static
final
String
KOTLIN_METADATA_D2_PARAMETER
=
"d2"
;
private
static
final
String
KOTLIN_METADATA_CLASSNAME_REGEX
=
"(L.*;)"
;
/**
* Try to get class info from Kotlin Metadata annotation
*/
@Nullable
public
static
ClassInfo
getClassName
(
ClassNode
cls
)
{
IAnnotation
metadataAnnotation
=
cls
.
getAnnotation
(
KOTLIN_METADATA_ANNOTATION
);
List
<
EncodedValue
>
d2Param
=
getParamAsList
(
metadataAnnotation
,
KOTLIN_METADATA_D2_PARAMETER
);
if
(
d2Param
==
null
||
d2Param
.
isEmpty
())
{
return
null
;
}
EncodedValue
firstValue
=
d2Param
.
get
(
0
);
if
(
firstValue
==
null
||
firstValue
.
getType
()
!=
EncodedType
.
ENCODED_STRING
)
{
return
null
;
}
try
{
String
rawClassName
=
((
String
)
firstValue
.
getValue
()).
trim
();
if
(
rawClassName
.
matches
(
KOTLIN_METADATA_CLASSNAME_REGEX
))
{
return
ClassInfo
.
fromName
(
cls
.
root
(),
rawClassName
);
}
}
catch
(
Exception
e
)
{
LOG
.
error
(
"Failed to parse kotlin metadata"
,
e
);
}
return
null
;
}
@SuppressWarnings
(
"unchecked"
)
private
static
List
<
EncodedValue
>
getParamAsList
(
IAnnotation
annotation
,
String
paramName
)
{
if
(
annotation
==
null
)
{
return
null
;
}
EncodedValue
encodedValue
=
annotation
.
getValues
().
get
(
paramName
);
if
(
encodedValue
==
null
||
encodedValue
.
getType
()
!=
EncodedType
.
ENCODED_ARRAY
)
{
return
null
;
}
return
(
List
<
EncodedValue
>)
encodedValue
.
getValue
();
}
}
jadx-core/src/test/java/jadx/tests/integration/deobf/TestKotlinMetadata.java
0 → 100644
浏览文件 @
91ee7565
package
jadx.tests.integration.deobf
;
import
org.junit.jupiter.api.Test
;
import
jadx.tests.api.SmaliTest
;
import
static
jadx
.
tests
.
api
.
utils
.
assertj
.
JadxAssertions
.
assertThat
;
public
class
TestKotlinMetadata
extends
SmaliTest
{
// @formatter:off
/*
@file:JvmName("TestKotlinMetadata")
class TestMetaData {
@JvmField
val id = 1
@JvmName("makeTwo")
fun double(x: Int): Int {
return 2 * x
}
}
*/
// @formatter:on
@Test
public
void
test
()
{
prepareArgs
(
true
);
assertThat
(
getClassNodeFromSmali
())
.
code
()
.
containsOne
(
"class TestMetaData {"
);
}
@Test
public
void
testIgnoreMetadata
()
{
prepareArgs
(
false
);
assertThat
(
getClassNodeFromSmali
())
.
code
()
.
containsOne
(
"class C0000TestKotlinMetadata {"
);
}
private
void
prepareArgs
(
boolean
parseKotlinMetadata
)
{
enableDeobfuscation
();
args
.
setDeobfuscationMinLength
(
100
);
// rename everything
getArgs
().
setParseKotlinMetadata
(
parseKotlinMetadata
);
disableCompilation
();
}
}
jadx-core/src/test/smali/deobf/TestKotlinMetadata.smali
0 → 100644
浏览文件 @
91ee7565
.class public final Ldeobf/TestKotlinMetadata;
.super Ljava/lang/Object;
.source "TestMetaData.kt"
# annotations
.annotation runtime Lkotlin/Metadata;
bv = {
0x1,
0x0,
0x3
}
d1 = {
"\u0000\u0014\n\u0002\u0018\u0002\n\u0002\u0010\u0000\n\u0002\u0008\u0002\n\u0002\u0010\u0008\n\u0002\u0008\u0004\u0018\u00002\u00020\u0001B\u0005\u00a2\u0006\u0002\u0010\u0002J\u0015\u0010\u0005\u001a\u00020\u00042\u0006\u0010\u0006\u001a\u00020\u0004H\u0007\u00a2\u0006\u0002\u0008\u0007R\u0010\u0010\u0003\u001a\u00020\u00048\u0006X\u0087D\u00a2\u0006\u0002\n\u0000\u00a8\u0006\u0008"
}
d2 = {
"LTestMetaData;",
"",
"()V",
"id",
"",
"double",
"x",
"makeTwo",
"test"
}
k = 0x1
mv = {
0x1,
0x4,
0x0
}
.end annotation
# instance fields
.field public final id:I
.annotation build Lkotlin/jvm/JvmField;
.end annotation
.end field
# direct methods
.method public constructor <init>()V
.registers 2
.prologue
.line 4
invoke-direct {p0}, Ljava/lang/Object;-><init>()V
.line 7
const/4 v0, 0x1
iput v0, p0, Ldeobf/TestKotlinMetadata;->id:I
return-void
.end method
# virtual methods
.method public final makeTwo(I)I
.registers 3
.param p1, "x" # I
.annotation build Lkotlin/jvm/JvmName;
name = "makeTwo"
.end annotation
.prologue
.line 11
mul-int/lit8 v0, p1, 0x2
return v0
.end method
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录