use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class RenameVisitor method checkMethods.
private void checkMethods(ClassNode cls) {
Set<String> names = new HashSet<String>();
for (MethodNode mth : cls.getMethods()) {
if (mth.contains(AFlag.DONT_GENERATE)) {
continue;
}
MethodInfo methodInfo = mth.getMethodInfo();
String signature = makeMethodSignature(methodInfo);
if (!names.add(signature)) {
methodInfo.setAlias(deobfuscator.makeMethodAlias(mth));
}
}
}
use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class SimplifyVisitor method convertInvoke.
private static InsnNode convertInvoke(MethodNode mth, InsnNode insn) {
MethodInfo callMth = ((InvokeNode) insn).getCallMth();
// convert it to STRING_CONCAT pseudo instruction.
if (callMth.getDeclClass().getFullName().equals(Consts.CLASS_STRING_BUILDER) && callMth.getShortId().equals(Consts.MTH_TOSTRING_SIGNATURE) && insn.getArg(0).isInsnWrap()) {
try {
List<InsnNode> chain = flattenInsnChain(insn);
//RAF
int constrIndex = -1;
// string is created using .append() calls:
if (chain.size() > 1 && chain.get(0).getType() == InsnType.CONSTRUCTOR) {
constrIndex = 0;
} else if (chain.size() > 2 && chain.get(1).getType() == InsnType.CONSTRUCTOR) {
//RAF Case where the first string element is String arg to the
// new StringBuilder("xxx") constructor
constrIndex = 1;
} else if (chain.size() > 3 && chain.get(2).getType() == InsnType.CONSTRUCTOR) {
//RAF Case where the first string element is String.valueOf() arg
// to the new StringBuilder(String.valueOf(zzz)) constructor
constrIndex = 2;
}
if (constrIndex != -1) {
// If we found a CONSTRUCTOR, is it a StringBuilder?
ConstructorInsn constr = (ConstructorInsn) chain.get(constrIndex);
if (constr.getClassType().getFullName().equals(Consts.CLASS_STRING_BUILDER)) {
int len = chain.size(), argInd = 1;
InsnNode concatInsn = new InsnNode(InsnType.STR_CONCAT, len - 1);
InsnNode argInsn;
if (constrIndex > 0) {
// There was an arg to the StringBuilder constr
InsnWrapArg iwa;
if (constrIndex == 2 && (argInsn = chain.get(1)).getType() == InsnType.INVOKE && ((InvokeNode) argInsn).getCallMth().getName().compareTo("valueOf") == 0) {
// The argument of new StringBuilder() is a String.valueOf(chainElement0)
iwa = (InsnWrapArg) argInsn.getArg(0);
// Cause for loop below to skip to after the constructor
argInd = 3;
} else {
InsnNode firstNode = chain.get(0);
if (firstNode instanceof ConstStringNode) {
ConstStringNode csn = (ConstStringNode) firstNode;
iwa = new InsnWrapArg(csn);
// Cause for loop below to skip to after the constructor
argInd = 2;
} else {
return null;
}
}
concatInsn.addArg(iwa);
}
for (; argInd < len; argInd++) {
// Add the .append(xxx) arg string to concat
concatInsn.addArg(chain.get(argInd).getArg(1));
}
concatInsn.setResult(insn.getResult());
return concatInsn;
}
// end of if constructor is for StringBuilder
}
// end of if we found a constructor early in the chain
} catch (Throwable e) {
LOG.debug("Can't convert string concatenation: {} insn: {}", mth, insn, e);
}
}
return null;
}
use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class PostTypeInference method process.
public static boolean process(MethodNode mth, InsnNode insn) {
DexNode dex = mth.dex();
switch(insn.getType()) {
case CONST:
RegisterArg res = insn.getResult();
LiteralArg litArg = (LiteralArg) insn.getArg(0);
if (res.getType().isObject()) {
long lit = litArg.getLiteral();
if (lit != 0) {
// incorrect literal value for object
ArgType type = lit == 1 ? ArgType.BOOLEAN : ArgType.INT;
// can't merge with object -> force it
litArg.setType(type);
res.getSVar().setType(type);
return true;
}
}
return litArg.merge(dex, res);
case MOVE:
{
boolean change = false;
if (insn.getResult().merge(dex, insn.getArg(0))) {
change = true;
}
if (insn.getArg(0).merge(dex, insn.getResult())) {
change = true;
}
return change;
}
case AGET:
return fixArrayTypes(dex, insn.getArg(0), insn.getResult());
case APUT:
return fixArrayTypes(dex, insn.getArg(0), insn.getArg(2));
case IF:
{
boolean change = false;
if (insn.getArg(1).merge(dex, insn.getArg(0))) {
change = true;
}
if (insn.getArg(0).merge(dex, insn.getArg(1))) {
change = true;
}
return change;
}
// check argument types for overloaded methods
case INVOKE:
{
boolean change = false;
InvokeNode inv = (InvokeNode) insn;
MethodInfo callMth = inv.getCallMth();
MethodNode node = mth.dex().resolveMethod(callMth);
if (node != null && node.isArgsOverload()) {
List<ArgType> args = callMth.getArgumentsTypes();
int j = inv.getArgsCount() - 1;
for (int i = args.size() - 1; i >= 0; i--) {
ArgType argType = args.get(i);
InsnArg insnArg = inv.getArg(j--);
if (insnArg.isRegister() && !argType.equals(insnArg.getType())) {
insnArg.setType(argType);
change = true;
}
}
}
return change;
}
case CHECK_CAST:
{
ArgType castType = (ArgType) ((IndexInsnNode) insn).getIndex();
RegisterArg result = insn.getResult();
ArgType resultType = result.getType();
// don't override generic types of same base class
boolean skip = castType.isObject() && resultType.isObject() && castType.getObject().equals(resultType.getObject());
if (!skip) {
// workaround for compiler bug (see TestDuplicateCast)
result.getSVar().setType(castType);
}
return true;
}
case PHI:
case MERGE:
{
ArgType type = insn.getResult().getType();
if (!type.isTypeKnown()) {
for (InsnArg arg : insn.getArguments()) {
if (arg.getType().isTypeKnown()) {
type = arg.getType();
break;
}
}
}
boolean changed = false;
if (updateType(insn.getResult(), type)) {
changed = true;
}
for (int i = 0; i < insn.getArgsCount(); i++) {
RegisterArg arg = (RegisterArg) insn.getArg(i);
if (updateType(arg, type)) {
changed = true;
}
}
return changed;
}
default:
break;
}
return false;
}
use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class InsnGen method makeInvoke.
private void makeInvoke(InvokeNode insn, CodeWriter code) throws CodegenException {
MethodInfo callMth = insn.getCallMth();
// inline method
MethodNode callMthNode = mth.dex().deepResolveMethod(callMth);
if (callMthNode != null) {
if (inlineMethod(callMthNode, insn, code)) {
return;
}
callMth = callMthNode.getMethodInfo();
}
int k = 0;
InvokeType type = insn.getInvokeType();
switch(type) {
case DIRECT:
case VIRTUAL:
case INTERFACE:
InsnArg arg = insn.getArg(0);
// FIXME: add 'this' for equals methods in scope
if (!arg.isThis()) {
addArgDot(code, arg);
}
k++;
break;
case SUPER:
// use 'super' instead 'this' in 0 arg
code.add("super").add('.');
k++;
break;
case STATIC:
ClassInfo insnCls = mth.getParentClass().getAlias();
ClassInfo declClass = callMth.getDeclClass();
if (!insnCls.equals(declClass)) {
useClass(code, declClass);
code.add('.');
}
break;
}
if (callMthNode != null) {
code.attachAnnotation(callMthNode);
}
code.add(callMth.getAlias());
generateMethodArguments(code, insn, k, callMthNode);
}
use of jadx.core.dex.info.MethodInfo in project jadx by skylot.
the class DeobfPresets method dumpMapping.
/**
* Saves DefaultDeobfuscator presets
*/
private void dumpMapping() throws IOException {
List<String> list = new ArrayList<String>();
// packages
for (PackageNode p : deobfuscator.getRootPackage().getInnerPackages()) {
for (PackageNode pp : p.getInnerPackages()) {
dfsPackageName(list, p.getName(), pp);
}
if (p.hasAlias()) {
list.add(String.format("p %s = %s", p.getName(), p.getAlias()));
}
}
// classes
for (DeobfClsInfo deobfClsInfo : deobfuscator.getClsMap().values()) {
if (deobfClsInfo.getAlias() != null) {
list.add(String.format("c %s = %s", deobfClsInfo.getCls().getClassInfo().getFullName(), deobfClsInfo.getAlias()));
}
}
for (FieldInfo fld : deobfuscator.getFldMap().keySet()) {
list.add(String.format("f %s = %s", fld.getFullId(), fld.getAlias()));
}
for (MethodInfo mth : deobfuscator.getMthMap().keySet()) {
list.add(String.format("m %s = %s", mth.getFullId(), mth.getAlias()));
}
Collections.sort(list);
FileUtils.writeLines(deobfMapFile, MAP_FILE_CHARSET, list);
list.clear();
}
Aggregations