Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
LanBaiCode committed Nov 27, 2023
1 parent ff01314 commit 39225dc
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 49 deletions.
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<div align="center">
<h1>HookCodeGenerator</h1>
<h5 style="margin-top: -5px;">HookCodeGenerator Plugin for IntelliJ IDEA.</h5>

<a href="https://github.com/LanBaiCode/HookCodeGenerator/actions/workflows/build.yml"><img src="https://github.com/LanBaiCode/HookCodeGenerator/actions/workflows/build.yml/badge.svg"></a>
<a href="https://plugins.jetbrains.com/plugin/23194-hook-code-generator/"><img src="https://img.shields.io/jetbrains/plugin/v/23194-hook-code-generator.svg?style=flat-square"></a>
<a href="https://plugins.jetbrains.com/plugin/23194-hook-code-generator/"><img src="https://img.shields.io/jetbrains/plugin/d/23194-hook-code-generator.svg?style=flat-square"></a>
Expand All @@ -22,9 +22,9 @@
# 使用
安装完成后, 将光标停留在需要 Hook 的位置, 右键选择 `XposedCode` 或者 `FridaCode`, 即可自动生成对应的 Hook 代码

- https://github.com/LanBaiCode/HookCodeGenerator/assets/72244576/ac660b65-e618-4e0d-b4e9-5fb30cca4609
- https://github.com/LanBaiCode/HookCodeGenerator/assets/72244576/d1c67a66-10ae-4cce-b5eb-eeab08abc0f9

- https://github.com/LanBaiCode/HookCodeGenerator/assets/72244576/b370bbe4-182a-4723-b225-08ffccaf4e3e
- https://github.com/LanBaiCode/HookCodeGenerator/assets/72244576/bc508844-a047-4cdf-b07a-70389c9be364

# 项目编译
- JVM设置: Preferences -> Build, Execution, Deployment -> Gradle JVM (设置为17)
Expand Down
25 changes: 11 additions & 14 deletions src/main/java/com/lanbaicode/FridaHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,17 @@
import java.util.Objects;

public class FridaHook extends AnAction {
private static final Map<String, String> ARRAY_TYPE_MAPPING = Map.of(
"int", "[I",
"byte", "[B",
"short", "[S",
"long", "[J",
"float", "[F",
"double", "[D",
"char", "[C",
"boolean", "[Z"
);

@Override
public void actionPerformed(AnActionEvent e) {
PsiElement element = (PsiElement) e.getDataContext().getData("psi.Element");
Expand Down Expand Up @@ -42,7 +53,6 @@ private String generateClassSnippet(PsiClass psiClass) {
let %s = Java.use("%s");""", psiClass.getName(), psiClass.getQualifiedName());
}


private String generateMethodSnippet(PsiMethod psiMethod) {
PsiClass psiClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class);
if (psiClass == null) return "";
Expand Down Expand Up @@ -116,19 +126,7 @@ private String generateMethodSnippet(PsiMethod psiMethod) {
private String parseArgType(PsiType type) {
String CanonicalText = type.getCanonicalText();
if (type instanceof PsiArrayType arrayType) {
//frida的基本类型数组需要修改成以下形式
Map<String, String> ARRAY_TYPE_MAPPING = Map.of(
"int", "[I",
"byte", "[B",
"short", "[S",
"long", "[J",
"float", "[F",
"double", "[D",
"char", "[C",
"boolean", "[Z"
);
CanonicalText = ARRAY_TYPE_MAPPING.getOrDefault(arrayType.getCanonicalText(), "");

//<Object>[] (如String[], Set[]等), 改成: L<package>.<Object>;
if (arrayType.getComponentType() instanceof PsiClassType classType) {
CanonicalText = "[L" + Objects.requireNonNull(classType.resolve()).getQualifiedName() + ";";
Expand All @@ -140,7 +138,6 @@ private String parseArgType(PsiType type) {
return CanonicalText;
}


private String generateFieldSnippet(PsiField psiField) {
PsiClass psiClass = PsiTreeUtil.getParentOfType(psiField, PsiClass.class);
if (psiClass != null) {
Expand Down
61 changes: 29 additions & 32 deletions src/main/java/com/lanbaicode/XposedHook.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@
import java.util.stream.Collectors;

public class XposedHook extends AnAction {
private static final Map<String, String> PRIMITIVE_TYPE_MAPPING = Map.of(
"int", "Int",
"byte", "Byte",
"short", "Short",
"long", "Long",
"float", "Float",
"double", "Double",
"char", "Char",
"boolean", "Boolean"
);

@Override
public void actionPerformed(AnActionEvent e) {
Expand All @@ -39,22 +49,28 @@ private String generateXposedSnippet(PsiElement element) {
}
}


private String generateMethodSnippet(PsiMethod psiMethod) {
PsiClass psiClass = PsiTreeUtil.getParentOfType(psiMethod, PsiClass.class);
if (psiClass == null) return "";

//检查是否构造函数
String xposedMethod = psiMethod.isConstructor() ? "findAndHookConstructor" : "findAndHookMethod";
String argsType = "";
String methodName = "";
String xposedMethod;
//检查是否构造函数, 构造函数不需要函数名称
if (psiMethod.isConstructor()) {
xposedMethod = "findAndHookConstructor";
} else {
xposedMethod = "findAndHookMethod";
methodName = "\"" + psiMethod.getName() + "\", ";
}
if (psiMethod.hasParameters()) {
argsType = Arrays.stream(psiMethod.getParameterList().getParameters())
.map(parameter -> parseArgType(parameter.getType()) + ".class, ")
.collect(Collectors.joining());
}

return String.format("""
XposedHelpers.%s("%s", classLoader, "%s", %snew XC_MethodHook() {
XposedHelpers.%s("%s", classLoader, %snew XC_MethodHook() {
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Expand All @@ -64,55 +80,36 @@ protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
}
});
""", xposedMethod, psiClass.getQualifiedName(), psiMethod.getName(), argsType);
""", xposedMethod, psiClass.getQualifiedName(), methodName + argsType);
}

private String parseArgType(PsiType type) {
String CanonicalText = type.getCanonicalText();
//只需要优化Object[], List<>, Map<> ...
if (type instanceof PsiArrayType arrayType) {
if (arrayType.getComponentType() instanceof PsiClassType classType) {
CanonicalText = Objects.requireNonNull(classType.resolve()).getQualifiedName();
//只处理省略类型还有泛型
if (type instanceof PsiEllipsisType ellipsisType) {
if (ellipsisType.getComponentType() instanceof PsiClassType classType) {
CanonicalText = Objects.requireNonNull(classType.resolve()).getQualifiedName() + "[]";
}
} else if (type instanceof PsiClassType classType) {
CanonicalText = Objects.requireNonNull(classType.resolve()).getQualifiedName();
}
return CanonicalText;
}


private String generateFieldSnippet(PsiField psiField) {
PsiClass psiClass = PsiTreeUtil.getParentOfType(psiField, PsiClass.class);
if (psiClass == null) return "";

String xposedMethod = getXposedMethod(psiField);
return String.format("""
Class<?> %s = XposedHelpers.findClass("%s", classLoader);
%s(%s, "%s");
""", psiClass.getName(), psiClass.getQualifiedName(),
xposedMethod, psiClass.getName(), psiField.getName());
}

private String getXposedMethod(PsiField psiField) {
Map<String, String> PRIMITIVE_TYPE_MAPPING = Map.of(
"int", "Int",
"byte", "Byte",
"short", "Short",
"long", "Long",
"float", "Float",
"double", "Double",
"char", "Char",
"boolean", "Boolean"
);
String isStatic = psiField.hasModifierProperty(PsiModifier.STATIC) ? "Static" : "";
String type = PRIMITIVE_TYPE_MAPPING.getOrDefault(psiField.getType().getPresentableText(), "Object");
return "XposedHelpers.get" + isStatic + type + "Field";
}
String xposedMethod = "XposedHelpers.get" + isStatic + type + "Field";

return String.format("%s(/*runtimeObject*/, \"%s\");", xposedMethod, psiField.getName());
}

private String generateClassSnippet(PsiClass psiClass) {
return String.format("""
Class<?> %s = XposedHelpers.findClass("%s", classLoader);
Class<?> %sClass = XposedHelpers.findClass("%s", classLoader);
""", psiClass.getName(), psiClass.getQualifiedName());
}

Expand Down

0 comments on commit 39225dc

Please sign in to comment.