use of jadx.core.dex.info.ClassInfo in project jadx by skylot.
the class RenameVisitor method checkClassName.
private void checkClassName(ClassNode cls) {
ClassInfo classInfo = cls.getClassInfo();
String clsName = classInfo.getAlias().getShortName();
String newShortName = null;
char firstChar = clsName.charAt(0);
if (Character.isDigit(firstChar)) {
newShortName = Consts.ANONYMOUS_CLASS_PREFIX + clsName;
} else if (firstChar == '$') {
newShortName = "C" + clsName;
}
if (newShortName != null) {
classInfo.rename(cls.dex(), classInfo.makeFullClsName(newShortName, true));
}
if (classInfo.getAlias().getPackage().isEmpty()) {
String fullName = classInfo.makeFullClsName(classInfo.getAlias().getShortName(), true);
String newFullName = Consts.DEFAULT_PACKAGE_NAME + "." + fullName;
classInfo.rename(cls.dex(), newFullName);
}
}
use of jadx.core.dex.info.ClassInfo in project jadx by skylot.
the class RenameVisitor method checkClasses.
private void checkClasses(RootNode root) {
Set<String> clsNames = new HashSet<String>();
for (ClassNode cls : root.getClasses(true)) {
checkClassName(cls);
if (!CASE_SENSITIVE_FS) {
ClassInfo classInfo = cls.getClassInfo();
String clsFileName = classInfo.getAlias().getFullPath();
if (!clsNames.add(clsFileName.toLowerCase())) {
String newShortName = deobfuscator.getClsAlias(cls);
String newFullName = classInfo.makeFullClsName(newShortName, true);
classInfo.rename(cls.dex(), newFullName);
clsNames.add(classInfo.getAlias().getFullPath().toLowerCase());
}
}
}
}
use of jadx.core.dex.info.ClassInfo in project jadx by skylot.
the class ModVisitor method processAnonymousConstructor.
private static void processAnonymousConstructor(MethodNode mth, ConstructorInsn co) {
MethodInfo callMth = co.getCallMth();
MethodNode callMthNode = mth.dex().resolveMethod(callMth);
if (callMthNode == null) {
return;
}
ClassNode classNode = callMthNode.getParentClass();
ClassInfo classInfo = classNode.getClassInfo();
ClassNode parentClass = mth.getParentClass();
if (!classInfo.isInner() || !Character.isDigit(classInfo.getShortName().charAt(0)) || !parentClass.getInnerClasses().contains(classNode)) {
return;
}
if (!classNode.getAccessFlags().isStatic() && (callMth.getArgsCount() == 0 || !callMth.getArgumentsTypes().get(0).equals(parentClass.getClassInfo().getType()))) {
return;
}
// TODO: calculate this constructor and other constructor usage
Map<InsnArg, FieldNode> argsMap = getArgsToFieldsMapping(callMthNode, co);
if (argsMap.isEmpty()) {
return;
}
// all checks passed
classNode.add(AFlag.ANONYMOUS_CLASS);
callMthNode.add(AFlag.DONT_GENERATE);
for (Map.Entry<InsnArg, FieldNode> entry : argsMap.entrySet()) {
FieldNode field = entry.getValue();
if (field == null) {
continue;
}
InsnArg arg = entry.getKey();
field.addAttr(new FieldReplaceAttr(arg));
field.add(AFlag.DONT_GENERATE);
if (arg.isRegister()) {
RegisterArg reg = (RegisterArg) arg;
SSAVar sVar = reg.getSVar();
if (sVar != null) {
sVar.add(AFlag.FINAL);
sVar.add(AFlag.DONT_INLINE);
}
reg.add(AFlag.SKIP_ARG);
}
}
}
use of jadx.core.dex.info.ClassInfo in project jadx by skylot.
the class MethodNode method initTryCatches.
private void initTryCatches(Code mthCode) {
InsnNode[] insnByOffset = instructions;
CatchHandler[] catchBlocks = mthCode.getCatchHandlers();
Try[] tries = mthCode.getTries();
if (catchBlocks.length == 0 && tries.length == 0) {
return;
}
int hc = 0;
Set<Integer> addrs = new HashSet<Integer>();
List<TryCatchBlock> catches = new ArrayList<TryCatchBlock>(catchBlocks.length);
for (CatchHandler handler : catchBlocks) {
TryCatchBlock tcBlock = new TryCatchBlock();
catches.add(tcBlock);
for (int i = 0; i < handler.getAddresses().length; i++) {
int addr = handler.getAddresses()[i];
ClassInfo type = ClassInfo.fromDex(parentClass.dex(), handler.getTypeIndexes()[i]);
tcBlock.addHandler(this, addr, type);
addrs.add(addr);
hc++;
}
int addr = handler.getCatchAllAddress();
if (addr >= 0) {
tcBlock.addHandler(this, addr, null);
addrs.add(addr);
hc++;
}
}
if (hc > 0 && hc != addrs.size()) {
// each handler must be only in one try/catch block
for (TryCatchBlock ct1 : catches) {
for (TryCatchBlock ct2 : catches) {
if (ct1 != ct2 && ct2.containsAllHandlers(ct1)) {
for (ExceptionHandler h : ct1.getHandlers()) {
ct2.removeHandler(this, h);
h.setTryBlock(ct1);
}
}
}
}
}
// attach EXC_HANDLER attributes to instructions
addrs.clear();
for (TryCatchBlock ct : catches) {
for (ExceptionHandler eh : ct.getHandlers()) {
int addr = eh.getHandleOffset();
ExcHandlerAttr ehAttr = new ExcHandlerAttr(ct, eh);
insnByOffset[addr].addAttr(ehAttr);
}
}
// attach TRY_ENTER, TRY_LEAVE attributes to instructions
for (Try aTry : tries) {
int catchNum = aTry.getCatchHandlerIndex();
TryCatchBlock catchBlock = catches.get(catchNum);
int offset = aTry.getStartAddress();
int end = offset + aTry.getInstructionCount() - 1;
InsnNode insn = insnByOffset[offset];
insn.add(AFlag.TRY_ENTER);
while (offset <= end && offset >= 0) {
insn = insnByOffset[offset];
catchBlock.addInsn(insn);
offset = InsnDecoder.getNextInsnOffset(insnByOffset, offset);
}
if (insnByOffset[end] != null) {
insnByOffset[end].add(AFlag.TRY_LEAVE);
} else {
insn.add(AFlag.TRY_LEAVE);
}
}
}
use of jadx.core.dex.info.ClassInfo in project jadx by skylot.
the class ClassGen method isBothClassesInOneTopClass.
private static boolean isBothClassesInOneTopClass(ClassInfo useCls, ClassInfo extClsInfo) {
ClassInfo a = useCls.getTopParentClass();
ClassInfo b = extClsInfo.getTopParentClass();
if (a != null) {
return a.equals(b);
}
// useCls - is a top class
return useCls.equals(b);
}
Aggregations