当前位置:网站首页>First!! Is lancet hungry? Official documents
First!! Is lancet hungry? Official documents
2022-07-03 15:53:00 【Code is not difficult to write】
Lancet
Lancet It's a lightweight Android AOP frame .
- Compilation speed is fast , And supports incremental compilation .
- concise API, A few lines Java Code completion injection requirements .
- No extra code to insert apk.
- Support for SDK, Can be in SDK Write injection code to modify dependencies SDK Of App.
Start using
install
At the root build.gradle
add to :
dependencies {
classpath 'com.android.tools.build:gradle:3.3.2'
classpath 'me.ele:lancet-plugin:1.0.6'
}
Be careful : Lancet 1.0.5 And above versions only support gradle 3.3.2 And above .
stay app The directory ’build.gradle’ add to :
apply plugin: 'me.ele.lancet'
dependencies {
provided 'me.ele:lancet-base:1.0.6'
}
Example
Lancet Use annotations to specify the rules and location of code weaving .
First look at the basics API Use :
@Proxy("i")
@TargetClass("android.util.Log")
public static int anyName(String tag, String msg){
msg = msg + "lancet";
return (int) Origin.call();
}
Here are a few key points :
@TargetClass
Specifies the target class to be woven into the codeandroid.util.Log
.@Proxy
Specifies the target method to be woven into the codei
.- The weaving method is
Proxy
( Will be introduced later ). Origin.call()
On behalf ofLog.i()
This goal method .
So this example Hook The function of the method is All that appears in the code Log.i(tag,msg)
Replace code with Log.i(tag,msg + "lancet")
Code weaving method
@Proxy
public @interface Proxy {
String value();
}
@Proxy
New methods will be used Replace The original target method existing in the code .
For example, there are 10 A place called Dog.bark()
, After proxy this method , be-all 10 The code in one place will become _Lancet.xxxx.bark()
. In this new method, you will execute Hook Method .@Proxy
Usually used for system API The hijacking of . Because although we can't inject code into the library provided by the system , But we can hijack all calling systems API The place of .
@NameRegex
@NameRegex Scope used to limit scope operations . Only used for Proxy
In the pattern , For example, you just want to delegate all the target operations under a package name . Or when you are acting for all network requests , I don't want to represent my request . Use NameRegex
Yes TargetClass
, ImplementedInterface
Screened out class Make another match .
@Insert
public @interface Insert {
String value();
boolean mayCreateSuper() default false;
}
@Insert
Insert the new code before and after the original code of the target method .@Insert
Often used to operate App And library Class , And through This
Operate the private properties and methods of the target class ( The following will introduce ).@Insert
When the target method does not exist , You can also use mayCreateSuper
Parameter to create the target method .
For example, the following code is injected into each Activity Of onStop
Life cycle
@TargetClass(value = "android.support.v7.app.AppCompatActivity", scope = Scope.LEAF)
@Insert(value = "onStop", mayCreateSuper = true)
protected void onStop(){
System.out.println("hello world");
Origin.callVoid();
}
Scope
It will be introduced later , The goal here is AppCompatActivity
All final subclasses of .
If a class MyActivity extends AppcompatActivity
No rewriting onStop
Automatically created onStop
Method , and Origin
Here represents super.onStop()
, Finally, this effect :
protected void onStop() {
System.out.println("hello world");
super.onStop();
}
Note:public/protected/private The modifier will completely copy Hook Method modifier .
Match the target class
public @interface TargetClass {
String value();
Scope scope() default Scope.SELF;
}
public @interface ImplementedInterface {
String[] value();
Scope scope() default Scope.SELF;
}
public enum Scope {
SELF,
DIRECT,
ALL,
LEAF
}
Many situations , We won't match just one class , There will be injection of all subclasses of a certain type , Or all classes that implement an interface . So pass TargetClass
, ImplementedInterface
2 A note and Scope
Match the target class .
@TargetClass
Find... Through class .
@TargetClass
Ofvalue
Is the full name of a class .- Scope.SELF Represents only matching
value
Specified target class . - Scope.DIRECT On behalf of the match
value
Specifies the direct subclass of the class . - Scope.All On behalf of the match
value
All subclasses of the specified class . - Scope.LEAF On behalf of the match
value
Specifies the final subclass of the class . as everyone knows java It's single inheritance , So the inheritance relationship is a tree structure , Therefore, this represents all leaf nodes of the inheritance tree with the specified class as vertex .
@ImplementedInterface
Search through the interface . The situation is slightly more complicated than finding through classes .
@ImplementedInterface
Ofvalue
You can fill in the full names of multiple interfaces .- Scope.SELF : Represents a class that directly implements all specified interfaces .
- Scope.DIRECT : Represents the direct implementation of all specified interfaces , And the class of the sub interface of the specified interface .
- Scope.ALL: representative
Scope.DIRECT
All specified classes and all their subclasses . - Scope.LEAF: representative
Scope.ALL
All leaf nodes in the specified forest structure .
Here's the picture :
[ Failed to transfer the external chain picture , The origin station may have anti-theft chain mechanism , It is suggested to save the pictures and upload them directly (img-GDKe4ObV-1656654396985)(https://p1-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/ed56b649f7354f248146f7ccc472b8f0~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]
When we use @ImplementedInterface(value = "I", scope = ...)
when , The target classes are as follows :
- Scope.SELF -> A
- Scope.DIRECT -> A C
- Scope.ALL -> A B C D
- Scope.LEAF -> B D
Match target method
Although in Proxy
, Insert
In, we specify the method name , But the identification method must be more detailed information . We will use Hook Method modifier , Parameter types to match methods .
So be sure to keep Hook Methodical public/protected/private
static
The information is consistent with the target method , Parameter type , The return type is consistent with the target method .
Return type can be used Object Instead of .
Method names are unlimited . Exception declarations are not limited to .
But sometimes we don't have permission to declare the target class . Now what? ?
@ClassOf
have access to ClassOf
Annotation instead of direct to the class import.
Here's an example :
public class A {
protected int execute(B b){
return b.call();
}
private class B {
int call() {
return 0;
}
}
}
@TargetClass("com.dieyidezui.demo.A")
@Insert("execute")
public int hookExecute(@ClassOf("com.dieyidezui.demo.A$B") Object o) {
System.out.println(o);
return (int) Origin.call();
}
ClassOf
Of value Be sure to follow **(package_name.)(outer_class_name$)inner_class_name([]...)
** The template of .
such as :
- java.lang.Object
- java.lang.Integer[][]
- A[]
- A$B
API
We can go through Origin
And This
Some interaction with the target class .
Origin
Origin
Used to call the original target method . Can be called multiple times .Origin.call()
Used to call a method with a return value .Origin.callVoid()
Used to call a method that has no return value .
in addition , If you have a need to catch exceptions . have access to Origin.call/callThrowOne/callThrowTwo/callThrowThree()
Origin.callVoid/callVoidThrowOne/callVoidThrowTwo/callVoidThrowThree()
For example:
@TargetClass("java.io.InputStream")
@Proxy("read")
public int read(byte[] bytes) throws IOException {
try {
return (int) Origin.<IOException>callThrowOne();
} catch (IOException e) {
e.printStackTrace();
throw e;
}
}
This
Only used for Insert
Way of non static method Hook in .( temporary )
get()
Returns the instantiated object to which the target method is called .
putField & getField
You can directly access all properties of the target class , Whether it's protected
or private
.
in addition , If this property does not exist , We will also automatically create this property . Exciting!
Automatic packing and unpacking must also support .
Some known defects :
Proxy
Out of commissionThis
- You cannot access the properties of your parent class . When you try to access a parent property , We will still create new properties .
For example:
package me.ele;
public class Main {
private int a = 1;
public void nothing(){
}
public int getA(){
return a;
}
}
@TargetClass("me.ele.Main")
@Insert("nothing")
public void testThis() {
Log.e("debug", This.get().getClass().getName());
This.putField(3, "a");
Origin.callVoid();
}
Tips
- The inner class should be named
package.outer_class$inner_class
- SDK Developers don't need
apply
plug-in unit , It only needsprovided me.ele:lancet-base:x.y.z
- Although we support incremental compilation . But when we use
Scope.LEAF、Scope.ALL
The class covered has changed Or modify Hook Class time , This compilation will become full compilation .
License
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Last
In the field of Technology , There's no course you can take once and for all , Only by continuous improvement can we not be eliminated by the times .
If you feel that you are inefficient in your studies , Lack of proper guidance , Sure Comment button 1 Or private letter , Free collection Android Related learning materials , And have the opportunity to join the Daniel exchange group to have an in-depth understanding of the industry trend 、 Refined specialty Skill , get Large factory push The opportunity to !!
边栏推荐
- "Remake Apple product UI with Android" (2) -- silky Appstore card transition animation
- Persisting in output requires continuous learning
- Visual upper system design and development (Halcon WinForm) -1 Process node design
- Go language self-study series | if else if statement in golang
- Subclass hides the function with the same name of the parent class
- CString getbuffer and releasebuffer instructions
- App移动端测试【3】ADB命令
- 嵌入式开发:避免开源软件的7个理由
- Driver and application communication
- Detailed pointer advanced 2
猜你喜欢
Tensorflow realizes verification code recognition (III)
Three dimensional reconstruction of deep learning
Popular understanding of linear regression (II)
求字符串函数和长度不受限制的字符串函数的详解
qt使用QZxing生成二维码
CString getbuffer and releasebuffer instructions
Microservice - fuse hystrix
Jvm-06-execution engine
[系统安全] 四十三.Powershell恶意代码检测系列 (5)抽象语法树自动提取万字详解
工资3000,靠“视频剪辑”月入40000:会赚钱的人,从不靠拼命!
随机推荐
Popular understanding of decision tree ID3
秒殺系統3-商品列錶和商品詳情
首发!!lancet饿了么官方文档
请做好3年内随时失业的准备?
Second kill system 3 - list of items and item details
The difference between RAR and zip files
Brush questions -- sword finger offer
大csv拆分和合并
详解指针进阶2
Digital image processing -- popular Canny edge detection
Seckill system 3- product list and product details
阿飞的期望
Under VC, Unicode and ANSI are converted to each other, cstringw and std:: string are converted to each other
Win10 enterprise 2016 long term service activation tutorial
Automatic generation of client code from flask server code -- Introduction to flask native stubs Library
Salary 3000, monthly income 40000 by "video editing": people who can make money never rely on hard work!
Go语言自学系列 | golang switch语句
MongoDB 的安装和基本操作
Halcon and WinForm study section 2
QT common sentence notes