@@ -21,25 +21,23 @@ plugins {
21
21
### Quick start
22
22
23
23
Create ` methodhook_activity.conf ` file to instruct plugin what and where to inject calls. You can
24
- place it adjacent to
25
- application's build.gradle[ .kts] file
24
+ place it adjacent to application's build.gradle[ .kts] file
26
25
27
26
``` conf
28
27
activity {
28
+ type = "default"
29
+ package = "*"
29
30
superClass = "android.app.Activity"
30
- methods = [
31
- "onCreate"
32
- ]
33
- packageId = "org.example"
34
- beginMethodWith = "org.example.MethodHook.start"
35
- endMethodWith = "org.example.MethodHook.end"
31
+ interfaces = []
32
+ class = "*"
33
+ methods = [ "onCreate" ]
34
+ enter = "org.example.MethodHook.enter"
35
+ exit = "org.example.MethodHook.exit"
36
36
}
37
37
```
38
38
39
39
Add plugin's configuration to an Android application's ` build.gradle[.kts] ` file. In ` addConfig `
40
- method specify a path
41
- to
42
- a created ` methodhook_activity.conf ` file previously
40
+ method specify a path to a created ` methodhook_activity.conf ` file previously
43
41
44
42
``` gradle
45
43
// build.gradle.kts
@@ -66,21 +64,22 @@ package org.example
66
64
67
65
object MethodHook {
68
66
@JvmStatic
69
- fun start ( runtimeClazz : String , clazz : String , method : String ) {
70
- println (" MethodHook::start ::$runtimeClazz :: $ clazz:: $method " )
67
+ fun enter ( clazz : String , method : String , descriptor : String ) {
68
+ println (" MethodHook::enter ::$clazz . $method . $descriptor " )
71
69
}
72
70
73
71
@JvmStatic
74
- fun end ( runtimeClazz : String , clazz : String , method : String ) {
75
- println (" MethodHook::end ::$runtimeClazz :: $ clazz:: $method " )
72
+ fun exit ( clazz : String , method : String , descriptor : String ) {
73
+ println (" MethodHook::exit ::$clazz . $method . $descriptor " )
76
74
}
77
75
}
78
76
```
79
77
80
78
Build project's ` debug ` buildType.
81
- Now, ` onCreate(savedInstanceState: Bundle?) ` method of all activities defined in ` org.example `
82
- package should be
83
- instructed with ` MethodHook::start ` and ` MethodHook::end ` calls.
79
+ Now, ` onCreate(savedInstanceState: Bundle?) ` method of all activities should be
80
+ instructed with ` MethodHook::enter ` and ` MethodHook::exit ` calls.
81
+
82
+ ![ !methodhook example] ( ./doc/methodhook_example.png )
84
83
85
84
### Example
86
85
@@ -107,53 +106,72 @@ You can define multiple configs inside one file. Start a config with a name
107
106
108
107
``` config
109
108
activity {
110
- superClass = "android.app.Activity"
111
- methods = [
112
- "onCreate"
113
- ]
114
- packageId = "org.example"
115
- beginMethodWith = "org.example.MethodHook.start"
116
- endMethodWith = "org.example.MethodHook.end"
109
+ ...
117
110
}
118
111
frgament {
119
- exactClass = "org.example.SomeFragment"
120
- methods = [
121
- "onResume"
122
- ]
123
- beginMethodWith = "org.example.MethodHook.start"
124
- endMethodWith = "org.example.MethodHook.end"
112
+ ...
125
113
}
126
114
```
127
115
128
- Each config supports following options:
129
-
130
- * ` superClass ` : Specifies the parent class (__ canonical name__ ) for which the plugin should target
131
- methods in its
132
- subclasses, e.g. ` android.app.Activity ` . Must not be defined along with ` exactClass ` .
133
- * ` exactClass ` : Specifies the exact class (__ canonical name__ ) for which the plugin should target
134
- methods,
135
- ` e.g. org.example.SomeClass ` . Must not be defined along with ` superClass ` .
136
- * ` methods ` : Specifies an array of methods (identified by their names) where the plugin will
137
- inject additional code, e.g. ` onCreate ` .
138
- * ` beginMethodWith ` : Specifies a reference to a method to be injected at the beginning of instructed
139
- methods,
140
- e.g. ` org.example.MethodHook.start ` .
141
- * ` endMethodWith ` : Specifies a reference to a method to be injected at the end of instructed
142
- methods,
143
- e.g. ` org.example.MethodHook.end ` .
144
- * ` packageId ` : Specifies the package name that identifies the group of classes where the plugin will
145
- target methods for
146
- injection, e.g. ` org.example ` .
147
- Not required, if not defined, the config will be applied to all files in your project, including
148
- third-party libraries
149
-
150
- > [ !IMPORTANT]
151
- > * Each config must have either ` superClass ` or ` exactClass ` option, but not both.
152
- > * Do not duplicate configs with same ` superClass ` or ` exactClass ` option.
153
- > * Each config must have ` methods ` option.
154
- > * Each config must have at least one of the options (or both): ` beginMethodWith ` , ` endMethodWith ` .
155
- > * Bear in mind that, a class, targeted by the plugin, must be associated with only one config.
156
- Otherwise, you will get an error.
116
+ #### Config file parameters
117
+
118
+ * ` type ` : Specifies type of instrumentation to apply.
119
+ * ** Required**
120
+ * Variants:
121
+ * __ default__ - instrument methods with ` enter ` and ` exit ` static method calls, with following arguments:
122
+ ` className: String ` , ` methodName: String ` , ` methodDescriptor: String ` .
123
+ * __ trace__ - instrument methods with ` android.os.Trace.beginSection ` and ` android.os.Trace.endSection ` calls.
124
+ * __ descriptor__ - instrument methods with ` enter ` and ` exit ` static method calls. ` enter ` method must have same
125
+ list of arguments as instrumented method, ` exit ` must have single nullable argument of ` android.lang.Object ` (
126
+ ` kotlin.Any ` ) type.
127
+
128
+ * ` package ` : Specifies the package name that identifies the group of classes where the plugin will target methods for
129
+ injection.
130
+ * ** Required**
131
+ * Variants:
132
+ * /* - any package.
133
+ * __ package__ , e.g. ` "org.example" `
134
+
135
+
136
+ * ` superClass ` : Specifies the parent class (__ canonical name__ ) for which the plugin should target methods in its
137
+ subclasses.
138
+ * ** Required**
139
+ * Variants:
140
+ * \* - any parent class or none.
141
+ * __ canonical name__ , e.g. ` "android.app.Activity" ` .
142
+
143
+ * ` interfaces ` : Specifies a list of interfaces (by __ canonical name__ ). If a class implements any of the specified
144
+ interfaces, its methods will be instrumented.
145
+ * ** Required**
146
+ * Variants:
147
+ * \* - any interface or none.
148
+ * __ canonical name__ , e.g. ` [ "java.util.RandomAccess" ] ` .
149
+
150
+ * ` class ` : Specifies the exact class (__ canonical name__ ) for which the plugin should target methods.
151
+ * ** Required**
152
+ * Variants:
153
+ * \* - any class.
154
+ * __ canonical name__ , e.g. ` "org.example.SomeClass" ` .
155
+
156
+ * ` methods ` : Specifies an array of methods (identified by their names) where the plugin will inject additional code.
157
+ * ** Required**
158
+ * Variants:
159
+ * \* - all methods including constructor.
160
+ * __ method name__ - exact method name to be instrumented, e.g. ` [ "onCreate" ] ` .
161
+
162
+ * ` descriptor ` : Specifies instrumented method descriptor.
163
+ * ** Not required**
164
+ * Variants:
165
+ * __ method descriptor__ , e.g. ` "(Landroid/content/Context;)V" ` .
166
+
167
+ * ` enter ` : Specifies a reference to a method to be injected at the beginning of instructed methods.
168
+ * ** Not required**
169
+ * Variants:
170
+ * __ static method reference__ , e.g. ` org.example.MethodHook.enter `
171
+ * ` exit ` : Specifies a reference to a method to be injected at the end of instructed methods.
172
+ * ** Not required**
173
+ * Variants:
174
+ * __ static method reference__ , e.g. ` org.example.MethodHook.exit `
157
175
158
176
#### Plugin configuration
159
177
@@ -190,67 +208,19 @@ androidMethodHook {
190
208
191
209
The ` androidMethodHook ` configuration supports next options:
192
210
193
- * ` forceLogging ` : Enables info logs of the plugin. Same as if executing gradle command with ` --info `
194
- flag,
195
- e.g. ` ./gradlew assembleDebug --info ` . Default value is ` false ` .
196
- * ` configs ` : Creates plugin's config for specific build variant. The name of config must be the same
197
- as name of build
198
- variant, e.g. buildType: ` debug ` , or if you have productFlavor named ` demo ` : ` demoDebug ` . You can
199
- have separate sets
211
+ * ` forceLogging ` : Enables info logs of the plugin. Same as if executing gradle command with ` --info ` flag, e.g.
212
+ ` ./gradlew assembleDebug --info ` . Default value is ` false ` .
213
+
214
+ * ` configs ` : Creates plugin's config for specific build variant. The name of config must be the same as name of build
215
+ variant, e.g. buildType: ` debug ` , or if you have productFlavor named ` demo ` : ` demoDebug ` . You can have separate sets
200
216
of config for different build variants.
201
217
* ` addConfig ` : Adds relative path to a config file.
202
218
203
- #### Inject method calls
204
-
205
- Plugin allows to inject a single method call to the beginning or the end of a target method.
206
- Injected method must be ` public static void ` and have three ` String ` arguments.
207
- Create a separate method to be injected at the beginning and end of the target method
208
-
209
- ``` kotlin
210
- @file:Suppress(" UNUSED_PARAMETER" )
211
-
212
- package org.example
213
-
214
- object MethodHook {
215
- @JvmStatic
216
- fun start (runtimeClazz : String , clazz : String , method : String ) {
217
- // some logic to be executed at the beginning of a [method]
218
- }
219
-
220
- @JvmStatic
221
- fun end (runtimeClazz : String , clazz : String , method : String ) {
222
- // some logic to be executed at the end of a [method]
223
- }
224
- }
225
- ```
226
-
227
- ``` java
228
- package org.example ;
229
-
230
- public class MethodHook {
231
- public static void start (String runtimeClazz , String clazz , String method ) {
232
- // some logic to be executed at the beginning of a [method]
233
- }
219
+ ## References
234
220
235
- public static void end (String runtimeClazz , String clazz , String method ) {
236
- // some logic to be executed at the end of a [method]
237
- }
238
- }
239
- ```
240
-
241
- * first argument is a runtime class, ` this.getClass().getName() ` , e.g. ` org.example.MainActivity ` .
242
- * second argument is an actual class where method was called, e.g. ` org.example.AbstractActivity ` .
243
- * third argument is a method name, arguments, return type, e.g. ` onCreate(Bundle)->void ` .
244
-
245
- Specify created methods in config
246
-
247
- ``` conf
248
- activity {
249
- …
250
- beginMethodWith = "org.example.MethodHook.start"
251
- endMethodWith = "org.example.MethodHook.end"
252
- }
253
- ```
221
+ * [ Using the ASM framework to implement common Java bytecode transformation patterns] ( https://lsieun.github.io/assets/pdf/asm-transformations.pdf )
222
+ * [ ASM framework - Eugene Kuleshov] ( https://wiki.jvmlangsummit.com/pdf/23_Kuleshov_asm.pdf )
223
+ * [ ASM guide] ( https://asm.ow2.io/asm4-guide.pdf )
254
224
255
225
## License
256
226
0 commit comments