2015-11-11 04:16:45 +00:00
|
|
|
package the.bytecode.club.bytecodeviewer.api;
|
|
|
|
|
2018-01-31 15:03:53 +00:00
|
|
|
import org.objectweb.asm.tree.AbstractInsnNode;
|
|
|
|
import org.objectweb.asm.tree.ClassNode;
|
|
|
|
import org.objectweb.asm.tree.FieldInsnNode;
|
|
|
|
import org.objectweb.asm.tree.FieldNode;
|
|
|
|
import org.objectweb.asm.tree.InnerClassNode;
|
|
|
|
import org.objectweb.asm.tree.LocalVariableNode;
|
|
|
|
import org.objectweb.asm.tree.MethodInsnNode;
|
|
|
|
import org.objectweb.asm.tree.MethodNode;
|
|
|
|
import org.objectweb.asm.tree.TypeInsnNode;
|
|
|
|
import the.bytecode.club.bytecodeviewer.BytecodeViewer;
|
|
|
|
|
2015-11-11 04:16:45 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* Bytecode Viewer (BCV) - Java & Android Reverse Engineering Suite *
|
|
|
|
* Copyright (C) 2014 Kalen 'Konloch' Kinloch - http://bytecodeviewer.com *
|
|
|
|
* *
|
|
|
|
* This program is free software: you can redistribute it and/or modify *
|
|
|
|
* it under the terms of the GNU General Public License as published by *
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or *
|
|
|
|
* (at your option) any later version. *
|
|
|
|
* *
|
|
|
|
* This program is distributed in the hope that it will be useful, *
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
|
|
* GNU General Public License for more details. *
|
|
|
|
* *
|
|
|
|
* You should have received a copy of the GNU General Public License *
|
|
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
|
|
|
***************************************************************************/
|
|
|
|
|
|
|
|
/**
|
2021-07-07 03:42:48 +00:00
|
|
|
* Used to interact with classnodes loaded inside of BCV as resources
|
2018-01-31 15:41:24 +00:00
|
|
|
*
|
2015-11-11 04:16:45 +00:00
|
|
|
* @author Konloch
|
|
|
|
*/
|
2021-07-06 22:27:20 +00:00
|
|
|
|
2021-07-07 03:42:48 +00:00
|
|
|
public final class ASMResourceUtil
|
2021-07-06 22:27:20 +00:00
|
|
|
{
|
2021-07-07 03:42:48 +00:00
|
|
|
/**
|
|
|
|
* Attempts to a method main inside of the loaded resources and returns the fully qualified name
|
|
|
|
*/
|
|
|
|
public static String findMainMethod(String defaultFQN)
|
|
|
|
{
|
|
|
|
for (ClassNode cn : BytecodeViewer.getLoadedClasses())
|
|
|
|
{
|
|
|
|
for (Object o : cn.methods.toArray())
|
|
|
|
{
|
|
|
|
MethodNode m = (MethodNode) o;
|
|
|
|
|
|
|
|
if (m.name.equals("main") && m.desc.equals("([Ljava/lang/String;)V"))
|
|
|
|
{
|
|
|
|
return cn.name + "." + m.name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return defaultFQN;
|
|
|
|
}
|
2015-11-11 04:16:45 +00:00
|
|
|
|
2018-01-31 15:41:24 +00:00
|
|
|
public static void renameFieldNode(String originalParentName,
|
|
|
|
String originalFieldName, String originalFieldDesc,
|
2021-07-06 22:27:20 +00:00
|
|
|
String newFieldParent, String newFieldName, String newFieldDesc)
|
|
|
|
{
|
|
|
|
for (ClassNode c : BytecodeViewer.getLoadedClasses())
|
|
|
|
{
|
|
|
|
for (Object o : c.methods.toArray())
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
MethodNode m = (MethodNode) o;
|
2021-07-06 22:27:20 +00:00
|
|
|
for (AbstractInsnNode i : m.instructions.toArray())
|
|
|
|
{
|
|
|
|
if (i instanceof FieldInsnNode)
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
FieldInsnNode field = (FieldInsnNode) i;
|
|
|
|
|
|
|
|
if (field.owner.equals(originalParentName)
|
|
|
|
&& field.name.equals(originalFieldName)
|
2021-07-06 22:27:20 +00:00
|
|
|
&& field.desc.equals(originalFieldDesc))
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
if (newFieldParent != null)
|
|
|
|
field.owner = newFieldParent;
|
|
|
|
if (newFieldName != null)
|
|
|
|
field.name = newFieldName;
|
|
|
|
if (newFieldDesc != null)
|
|
|
|
field.desc = newFieldDesc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void renameMethodNode(String originalParentName,
|
|
|
|
String originalMethodName, String originalMethodDesc,
|
2021-07-06 22:27:20 +00:00
|
|
|
String newParent, String newName, String newDesc)
|
|
|
|
{
|
|
|
|
for (ClassNode c : BytecodeViewer.getLoadedClasses())
|
|
|
|
{
|
|
|
|
for (Object o : c.methods.toArray())
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
MethodNode m = (MethodNode) o;
|
2021-07-06 22:27:20 +00:00
|
|
|
for (AbstractInsnNode i : m.instructions.toArray())
|
|
|
|
{
|
|
|
|
if (i instanceof MethodInsnNode)
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
MethodInsnNode mi = (MethodInsnNode) i;
|
|
|
|
if (mi.owner.equals(originalParentName)
|
|
|
|
&& mi.name.equals(originalMethodName)
|
2021-07-06 22:27:20 +00:00
|
|
|
&& mi.desc.equals(originalMethodDesc))
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
if (newParent != null)
|
|
|
|
mi.owner = newParent;
|
|
|
|
if (newName != null)
|
|
|
|
mi.name = newName;
|
|
|
|
if (newDesc != null)
|
|
|
|
mi.desc = newDesc;
|
|
|
|
}
|
2021-04-12 22:31:22 +00:00
|
|
|
} /*else {
|
|
|
|
System.out.println(i.getOpcode()+":"+c.name+":"+m.name);
|
|
|
|
}*/
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
2021-07-06 22:27:20 +00:00
|
|
|
if (m.signature != null)
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
if (newName != null)
|
|
|
|
m.signature = m.signature.replace(originalMethodName,
|
|
|
|
newName);
|
|
|
|
if (newParent != null)
|
|
|
|
m.signature = m.signature.replace(originalParentName,
|
|
|
|
newParent);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m.name.equals(originalMethodName)
|
|
|
|
&& m.desc.equals(originalMethodDesc)
|
2021-07-06 22:27:20 +00:00
|
|
|
&& c.name.equals(originalParentName))
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
if (newName != null)
|
|
|
|
m.name = newName;
|
|
|
|
if (newDesc != null)
|
|
|
|
m.desc = newDesc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static void renameClassNode(final String oldName,
|
2021-07-06 22:27:20 +00:00
|
|
|
final String newName)
|
|
|
|
{
|
|
|
|
for (ClassNode c : BytecodeViewer.getLoadedClasses())
|
|
|
|
{
|
|
|
|
for (InnerClassNode oo : c.innerClasses)
|
|
|
|
{
|
|
|
|
if (oo.innerName != null && oo.innerName.equals(oldName))
|
2021-04-12 22:31:22 +00:00
|
|
|
oo.innerName = newName;
|
2021-07-06 22:27:20 +00:00
|
|
|
|
|
|
|
if (oo.name.equals(oldName))
|
2021-04-12 22:31:22 +00:00
|
|
|
oo.name = newName;
|
2021-07-06 22:27:20 +00:00
|
|
|
|
|
|
|
if (oo.outerName != null && oo.outerName.equals(oldName))
|
2021-04-12 22:31:22 +00:00
|
|
|
oo.outerName = newName;
|
2018-01-31 15:41:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (c.signature != null)
|
|
|
|
c.signature = c.signature.replace(oldName, newName);
|
|
|
|
|
2021-07-06 22:27:20 +00:00
|
|
|
if (c.superName.equals(oldName))
|
2018-01-31 15:41:24 +00:00
|
|
|
c.superName = newName;
|
2021-07-06 22:27:20 +00:00
|
|
|
|
|
|
|
for (Object o : c.fields.toArray())
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
FieldNode f = (FieldNode) o;
|
|
|
|
f.desc = f.desc.replace(oldName, newName);
|
|
|
|
}
|
2021-07-06 22:27:20 +00:00
|
|
|
|
|
|
|
for (Object o : c.methods.toArray())
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
MethodNode m = (MethodNode) o;
|
|
|
|
|
2021-07-06 22:27:20 +00:00
|
|
|
if (m.localVariables != null)
|
|
|
|
for (LocalVariableNode node : m.localVariables)
|
2018-01-31 15:41:24 +00:00
|
|
|
node.desc = node.desc.replace(oldName, newName);
|
|
|
|
|
|
|
|
if (m.signature != null)
|
|
|
|
m.signature = m.signature.replace(oldName, newName);
|
|
|
|
|
2021-07-06 22:27:20 +00:00
|
|
|
for (int i = 0; i < m.exceptions.size(); i++)
|
2018-01-31 15:41:24 +00:00
|
|
|
if (m.exceptions.get(i).equals(oldName))
|
|
|
|
m.exceptions.set(i, newName);
|
|
|
|
|
2021-07-06 22:27:20 +00:00
|
|
|
for (AbstractInsnNode i : m.instructions.toArray())
|
|
|
|
{
|
|
|
|
if (i instanceof TypeInsnNode)
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
TypeInsnNode t = (TypeInsnNode) i;
|
2021-07-06 22:27:20 +00:00
|
|
|
if (t.desc.equals(oldName))
|
2018-01-31 15:41:24 +00:00
|
|
|
t.desc = newName;
|
|
|
|
}
|
2021-07-06 22:27:20 +00:00
|
|
|
|
|
|
|
if (i instanceof MethodInsnNode)
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
MethodInsnNode mi = (MethodInsnNode) i;
|
|
|
|
if (mi.owner.equals(oldName))
|
|
|
|
mi.owner = newName;
|
|
|
|
mi.desc = mi.desc.replace(oldName, newName);
|
|
|
|
}
|
2021-07-06 22:27:20 +00:00
|
|
|
if (i instanceof FieldInsnNode)
|
|
|
|
{
|
2018-01-31 15:41:24 +00:00
|
|
|
FieldInsnNode fi = (FieldInsnNode) i;
|
|
|
|
if (fi.owner.equals(oldName))
|
|
|
|
fi.owner = newName;
|
|
|
|
fi.desc = fi.desc.replace(oldName, newName);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2015-11-11 04:16:45 +00:00
|
|
|
}
|