Skip to content

Commit

Permalink
update doc example
Browse files Browse the repository at this point in the history
  • Loading branch information
teble committed Dec 12, 2023
1 parent 271a2fa commit 1f9100b
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 7 deletions.
72 changes: 67 additions & 5 deletions doc-source/src/en/guide/example.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Usage Examples

During the reading of this section, you may need to refer to the [Structural Quick Reference Table](./structural-zoom-table) for a better understanding.
During the reading of this section, you may need to refer to
the [Structural Quick Reference Table](./structural-zoom-table) for a better understanding.

> You can get the source code and some test cases for the demo below.
Expand All @@ -9,11 +10,11 @@ During the reading of this section, you may need to refer to the [Structural Qui

## Demo App

Here is a simple Demo Activity, PlayActivity, where the internal properties and methods are obfuscated, and they change in each version.
Here is a simple Demo Activity, PlayActivity, where the internal properties and methods are
obfuscated, and they change in each version.

> The four major components are not obfuscated by default. We assume this Activity is obfuscated.

```java
package org.luckypray.dexkit.demo;

Expand Down Expand Up @@ -82,7 +83,7 @@ public class PlayActivity extends AppCompatActivity {

In this scenario, we want to find the PlayActivity using the following code:

> This is just an example. In actual use, you don't need conditions as complex and comprehensive
> This is just an example. In actual use, you don't need conditions as complex and comprehensive
> as this. Use as needed.
```kotlin
Expand Down Expand Up @@ -179,7 +180,7 @@ org.luckypray.dexkit.demo.PlayActivity

## Parent Class Condition Nesting

if there is such a class, its only feature is that the ancestors are not obfuscated,
if there is such a class, its only feature is that the ancestors are not obfuscated,
and the middle parents are all obfuscated, we can also use `DexKit` to find it.

```kotlin
Expand Down Expand Up @@ -218,3 +219,64 @@ org.luckypray.dexkit.demo.PlayActivity
::: tip
In `DexKit`, any logical relationship can be used as a query condition
:::

## Fuzzy Parameter Matching

If we need to find a method with an obfuscated parameter, we can use `null` to replace it,
so that it can match any type of parameter.

```kotlin
private fun findMethodWithFuzzyParam(bridge: DexKitBridge) {
bridge.findMethod {
matcher {
modifiers = Modifier.PUBLIC or Modifier.STATIC
returnType = "void"
// Specify the parameters of the method, if the parameters are uncertain, use null
paramTypes("android.view.View", null)
// paramCount = 2 // paramTypes length is 2, which has implicitly determined the number of parameters
usingStrings("onClick")
}
}.single().let {
println(it)
}
}
```

## Saving and Retrieving Query Results

How can you serialize and save the results obtained from DexKit queries for later use?

DexKit provides corresponding packaging classes for Class, Method, and Field,
namely `DexClass`, `DexMethod`, and `DexField`. The wrapper class inherits the `Serializable`
interface, so it can be saved directly using Java's serialization method. For the objects returned
by the query, you can directly use `toDexClass()`, `toDexMethod()`, `toDexField()` methods to
convert to a wrapper class. Of course, you can also use the Data object's `descriptor` attribute,
which is a `Dailvik description` that identifies a unique object.

```kotlin
private fun saveData(bridge: DexKitBridge) {
bridge.findMethod {
matcher {
modifiers = Modifier.PUBLIC or Modifier.STATIC
returnType = "void"
paramTypes("android.view.View", null)
usingStrings("onClick")
}
}.single().let {
val descriptor = it.toDexMethod().descriptor
val sp = getSharedPreferences("dexkit", Context.MODE_PRIVATE)
sp.edit().putString("onClickMethod", descriptor).apply()
}
}

private fun readData(): Method {
val sp = getSharedPreferences("dexkit", Context.MODE_PRIVATE)
val descriptor = sp.getString("onClickMethod", null)
if (descriptor != null) {
val dexMethod = DexMethod(descriptor)
val method = dexMethod.getMethodInstance(hostClassLoader)
return method
}
error("No saved")
}
```
61 changes: 59 additions & 2 deletions doc-source/src/zh-cn/guide/example.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,7 @@ public class PlayActivity extends AppCompatActivity {
}
```


## 多条件匹配类多条件用法示例。
## 多条件匹配类多条件用法示例

此时我们想得到这个 PlayActivity 可以使用如下代码:

Expand Down Expand Up @@ -216,3 +215,61 @@ org.luckypray.dexkit.demo.PlayActivity
::: tip
`DexKit` 中,一切符合逻辑的关系都可以作为查询条件
:::

## 模糊参数匹配

如果我们需要寻找的方法中存在一个被混淆的参数,我们可以使用 `null` 来替代,这样它就能匹配任意类型的参数。

```kotlin
private fun findMethodWithFuzzyParam(bridge: DexKitBridge) {
bridge.findMethod {
matcher {
modifiers = Modifier.PUBLIC or Modifier.STATIC
returnType = "void"
// 指定方法的参数类型,如果参数类型不确定,使用 null
paramTypes("android.view.View", null)
// paramCount = 2 // paramTypes 长度为 2 已经隐式确定了参数个数
usingStrings("onClick")
}
}.single().let {
println(it)
}
}
```

## 查询结果保存与读取

使用 DexKit 查询到的结果如何序列化保存下来,以便下次使用呢?

DexKit 中对 Class、Method、Field 提供了相应的包装类,分别是 `DexClass``DexMethod``DexField`
包装类继承了 `Serializable` 接口,因此可以直接使用 Java 的序列化方式来保存。对于查询返回的对象,可以直接使用
`toDexClass()``toDexMethod()``toDexField()` 方法来转换为包装类。当然,您也可以使用 Data 对象的
`descriptor` 属性来保存,它是一个 `Dailvik 描述` 标识了唯一的对象。

```kotlin
private fun saveData(bridge: DexKitBridge) {
bridge.findMethod {
matcher {
modifiers = Modifier.PUBLIC or Modifier.STATIC
returnType = "void"
paramTypes("android.view.View", null)
usingStrings("onClick")
}
}.single().let {
val descriptor = it.toDexMethod().descriptor
val sp = getSharedPreferences("dexkit", Context.MODE_PRIVATE)
sp.edit().putString("onClickMethod", descriptor).apply()
}
}

private fun readData(): Method {
val sp = getSharedPreferences("dexkit", Context.MODE_PRIVATE)
val descriptor = sp.getString("onClickMethod", null)
if (descriptor != null) {
val dexMethod = DexMethod(descriptor)
val method = dexMethod.getMethodInstance(hostClassLoader)
return method
}
error("No saved")
}
```

0 comments on commit 1f9100b

Please sign in to comment.