diff --git a/jadx-gui/src/main/java/jadx/gui/ui/codearea/FridaAction.java b/jadx-gui/src/main/java/jadx/gui/ui/codearea/FridaAction.java index 79808f4079f8a28aa0fc0a02f4b6933832a4318a..f59c7193ffcb686334cbfa6e5bb890c7c554a127 100644 --- a/jadx-gui/src/main/java/jadx/gui/ui/codearea/FridaAction.java +++ b/jadx-gui/src/main/java/jadx/gui/ui/codearea/FridaAction.java @@ -23,7 +23,6 @@ import jadx.api.utils.CodeUtils; import jadx.core.codegen.TypeGen; import jadx.core.dex.info.MethodInfo; import jadx.core.dex.instructions.args.ArgType; -import jadx.core.dex.nodes.ClassNode; import jadx.core.dex.nodes.MethodNode; import jadx.core.utils.exceptions.JadxRuntimeException; import jadx.gui.treemodel.JClass; @@ -76,45 +75,48 @@ public final class FridaAction extends JNodeAction { } private String generateMethodSnippet(JMethod jMth) { - JavaMethod javaMethod = jMth.getJavaMethod(); - MethodInfo methodInfo = javaMethod.getMethodNode().getMethodInfo(); - String methodName = StringEscapeUtils.escapeEcmaScript(methodInfo.getName()); - + MethodNode mth = jMth.getJavaMethod().getMethodNode(); + MethodInfo methodInfo = mth.getMethodInfo(); + String methodName; if (methodInfo.isConstructor()) { methodName = "$init"; + } else { + methodName = StringEscapeUtils.escapeEcmaScript(methodInfo.getName()); } - - String callMethodName = methodName; - String shortClassName = javaMethod.getDeclaringClass().getName(); - - String functionUntilImplementation; - if (isOverloaded(javaMethod.getMethodNode())) { - List methodArgs = methodInfo.getArgumentsTypes(); - String overloadStr = methodArgs.stream().map(this::parseArgType).collect(Collectors.joining(", ")); - functionUntilImplementation = String.format("%s[\"%s\"].overload(%s).implementation", shortClassName, methodName, overloadStr); + String overload; + if (isOverloaded(mth)) { + String overloadArgs = methodInfo.getArgumentsTypes().stream() + .map(this::parseArgType).collect(Collectors.joining(", ")); + overload = ".overload(" + overloadArgs + ")"; } else { - functionUntilImplementation = String.format("%s[\"%s\"].implementation", shortClassName, methodName); + overload = ""; } - - List methodArgNames = collectMethodArgNames(javaMethod); - - String functionParametersString = String.join(", ", methodArgNames); - String logParametersString = - methodArgNames.stream().map(e -> String.format("'%s: ' + %s", e, e)).collect(Collectors.joining(" + ', ' + ")); - if (logParametersString.length() > 0) { - logParametersString = " + ', ' + " + logParametersString; + List argNames = collectMethodArgNames(jMth.getJavaMethod()); + String args = String.join(", ", argNames); + String logArgs; + if (argNames.isEmpty()) { + logArgs = ""; + } else { + String joinStr = " + ', ' + "; + logArgs = joinStr + argNames.stream().map(a -> "'" + a + ": ' + " + a).collect(Collectors.joining(joinStr)); } - String functionParameterAndBody = String.format( - "%s = function (%s) {\n" - + " console.log('%s is called'%s);\n" - + " let ret = this.%s(%s);\n" - + " console.log('%s ret value is ' + ret);\n" - + " return ret;\n" - + "};", - functionUntilImplementation, functionParametersString, methodName, logParametersString, callMethodName, - functionParametersString, methodName); - - return generateClassSnippet(jMth.getJParent()) + "\n" + functionParameterAndBody; + String shortClassName = mth.getParentClass().getShortName(); + String classSnippet = generateClassSnippet(jMth.getJParent()); + if (methodInfo.isConstructor() || methodInfo.getReturnType() == ArgType.VOID) { + // no return value + return classSnippet + "\n" + + shortClassName + "[\"" + methodName + "\"]" + overload + ".implementation = function (" + args + ") {\n" + + " console.log('" + shortClassName + "." + methodName + " is called'" + logArgs + ");\n" + + " this[\"" + methodName + "\"](" + args + ");\n" + + "};"; + } + return classSnippet + "\n" + + shortClassName + "[\"" + methodName + "\"]" + overload + ".implementation = function (" + args + ") {\n" + + " console.log('" + shortClassName + "." + methodName + " is called'" + logArgs + ");\n" + + " let ret = this[\"" + methodName + "\"](" + args + ");\n" + + " console.log('" + shortClassName + "." + methodName + " return: ' + ret);\n" + + " return ret;\n" + + "};"; } private List collectMethodArgNames(JavaMethod javaMethod) { @@ -159,27 +161,24 @@ public final class FridaAction extends JNodeAction { break; } } - JClass jc = jf.getRootClass(); String classSnippet = generateClassSnippet(jc); return String.format("%s\n%s = %s.%s.value;", classSnippet, fieldName, jc.getName(), rawFieldName); } public Boolean isOverloaded(MethodNode methodNode) { - ClassNode parentClass = methodNode.getParentClass(); - List methods = parentClass.getMethods(); - return methods.stream() + return methodNode.getParentClass().getMethods().stream() .anyMatch(m -> m.getName().equals(methodNode.getName()) && !Objects.equals(methodNode.getMethodInfo().getShortId(), m.getMethodInfo().getShortId())); } private String parseArgType(ArgType x) { - StringBuilder parsedArgType = new StringBuilder("'"); + String typeStr; if (x.isArray()) { - parsedArgType.append(TypeGen.signature(x).replace("/", ".")); + typeStr = TypeGen.signature(x).replace("/", "."); } else { - parsedArgType.append(x); + typeStr = x.toString(); } - return parsedArgType.append("'").toString(); + return "'" + typeStr + "'"; } }