Alert Instead of NPE

This commit is contained in:
Konloch 2024-09-29 19:44:10 -06:00
parent 9b53a74b05
commit 88b2c7f68d

AI 샘플 코드 생성 중입니다

Loading...

View File

@ -11,6 +11,7 @@ import javax.swing.Box;
import javax.swing.JComboBox; import javax.swing.JComboBox;
import javax.swing.JOptionPane; import javax.swing.JOptionPane;
import javax.swing.JPanel; import javax.swing.JPanel;
import org.objectweb.asm.tree.ClassNode; import org.objectweb.asm.tree.ClassNode;
import the.bytecode.club.bytecodeviewer.*; import the.bytecode.club.bytecodeviewer.*;
import the.bytecode.club.bytecodeviewer.api.*; import the.bytecode.club.bytecodeviewer.api.*;
@ -18,27 +19,27 @@ import the.bytecode.club.bytecodeviewer.decompilers.impl.FernFlowerDecompiler;
import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer; import the.bytecode.club.bytecodeviewer.gui.resourceviewer.viewer.ResourceViewer;
/** /**
** This is an Xposed Generator Plugin, used to aid Reverse-Engineering. * * This is an Xposed Generator Plugin, used to aid Reverse-Engineering.
** * *
** @author jowasp * * @author jowasp
**/ **/
public class XposedGenerator extends Plugin { public class XposedGenerator extends Plugin
{
private static final List<String> methodsNames = new ArrayList<>(); private static final List<String> methodsNames = new ArrayList<>();
private static final List<String> cleanMethodsNames = new ArrayList<>(); private static final List<String> cleanMethodsNames = new ArrayList<>();
private static String foundPckg; private static String foundPckg;
public XposedGenerator() {
}
@Override @Override
public void execute(List<ClassNode> classNodeList) { public void execute(List<ClassNode> classNodeList)
{
//Get actual file class content //Get actual file class content
ResourceViewer viewer = BytecodeViewer.getActiveResource(); ResourceViewer viewer = BytecodeViewer.getActiveResource();
if (viewer == null) { if (viewer == null)
BytecodeViewer.showMessage("Open A Class First"); {
BytecodeViewer.showMessage("Open A Classfile First");
return; return;
} }
@ -49,8 +50,10 @@ public class XposedGenerator extends Plugin {
ParseChosenFileContent(className, classnode); ParseChosenFileContent(className, classnode);
} }
public static void ParseChosenFileContent(String classname, ClassNode classNode) { public static void ParseChosenFileContent(String classname, ClassNode classNode)
try { {
try
{
//Parse content - Extract methods after APK /JAR has been extracted //Parse content - Extract methods after APK /JAR has been extracted
byte[] cont = ASMUtil.nodeToBytes(classNode); byte[] cont = ASMUtil.nodeToBytes(classNode);
@ -61,8 +64,7 @@ public class XposedGenerator extends Plugin {
//Decompile using Fern //Decompile using Fern
String decomp = decompilefern.decompileClassNode(classNode, cont); String decomp = decompilefern.decompileClassNode(classNode, cont);
String[] xposedTemplateTypes = {"Empty", "Parameters", "Helper"}; String[] xposedTemplateTypes = {"Empty", "Parameters", "Helper"};
@SuppressWarnings({"unchecked", "rawtypes"}) @SuppressWarnings({"unchecked", "rawtypes"}) JComboBox xposedTemplateList = new JComboBox(xposedTemplateTypes);
JComboBox xposedTemplateList = new JComboBox(xposedTemplateTypes);
//Set results of parsed methods into a list //Set results of parsed methods into a list
List<String> methodsExtracted = ProcessContentExtractedClass(decomp); List<String> methodsExtracted = ProcessContentExtractedClass(decomp);
String packgExtracted = ProcessContentExtractedPackage(decomp); String packgExtracted = ProcessContentExtractedPackage(decomp);
@ -71,7 +73,8 @@ public class XposedGenerator extends Plugin {
List<String> cleanMethods; List<String> cleanMethods;
//clear list //clear list
cleanMethods = ProcessCleanMethodsAll(methodsExtracted); cleanMethods = ProcessCleanMethodsAll(methodsExtracted);
if (!cleanMethods.isEmpty()) { if (!cleanMethods.isEmpty())
{
JComboBox<String> cb = new JComboBox<>(cleanMethods.toArray(new String[0])); JComboBox<String> cb = new JComboBox<>(cleanMethods.toArray(new String[0]));
//Add Panel elements //Add Panel elements
@ -82,49 +85,57 @@ public class XposedGenerator extends Plugin {
myPanel.add(cb); myPanel.add(cb);
//output methods to pane box //output methods to pane box
int result = JOptionPane.showConfirmDialog(null, myPanel, int result = JOptionPane.showConfirmDialog(null, myPanel, "Choose Template and Method for Xposed Module", JOptionPane.OK_CANCEL_OPTION);
"Choose Template and Method for Xposed Module", JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) { if (result == JOptionPane.OK_OPTION)
{
//Read Chosen Class //Read Chosen Class
Object cbItem = cb.getSelectedItem(); Object cbItem = cb.getSelectedItem();
Object xPosedItem = xposedTemplateList.getSelectedItem(); Object xPosedItem = xposedTemplateList.getSelectedItem();
System.out.println("SELECTED CLASS is" + cbItem); System.out.println("SELECTED CLASS is" + cbItem);
if (cbItem != null && xPosedItem != null) { if (cbItem != null && xPosedItem != null)
{
String selectedClass = cbItem.toString(); String selectedClass = cbItem.toString();
String selectedXposedTemplate = xPosedItem.toString(); String selectedXposedTemplate = xPosedItem.toString();
//WriteXposed Class with extracted data //WriteXposed Class with extracted data
try { try
{
WriteXposedModule(selectedClass, packgExtracted, classname, selectedXposedTemplate); WriteXposedModule(selectedClass, packgExtracted, classname, selectedXposedTemplate);
} catch (IllegalArgumentException e) { }
catch (IllegalArgumentException e)
{
e.printStackTrace(); e.printStackTrace();
JOptionPane.showMessageDialog(null, "Error" + e); JOptionPane.showMessageDialog(null, "Error" + e);
} }
} }
} }
} else { }
else
{
JOptionPane.showMessageDialog(null, "Class Not Suitable"); JOptionPane.showMessageDialog(null, "Class Not Suitable");
} }
} catch (IllegalArgumentException e) { }
catch (IllegalArgumentException e)
{
e.printStackTrace(); e.printStackTrace();
JOptionPane.showMessageDialog(null, "Error" + e); JOptionPane.showMessageDialog(null, "Error" + e);
} }
} }
public static void WriteXposedModule(String functionToHook, String packageName, String classToHook, public static void WriteXposedModule(String functionToHook, String packageName, String classToHook, String template)
String template) { {
if (template != null && !template.equals("Empty")) { if (template != null && !template.equals("Empty"))
try { {
try
{
//TODO: Prompt save dialog //TODO: Prompt save dialog
File file = new File("./XposedClassTest.java"); File file = new File("./XposedClassTest.java");
// if file doesn't exist, then create it // if file doesn't exist, then create it
if (!file.exists()) if (!file.exists())
file.createNewFile(); file.createNewFile();
//Extract the package name only //Extract the package name only
String packageNameOnly = packageName.substring(8, packageName.length() - 2).trim(); String packageNameOnly = packageName.substring(8, packageName.length() - 2).trim();
String classToHookNameOnly = classToHook; String classToHookNameOnly = classToHook;
@ -133,41 +144,14 @@ public class XposedGenerator extends Plugin {
String[] classClean = classToHookNameOnly.split("/"); String[] classClean = classToHookNameOnly.split("/");
String[] functionSplitValues = functionToHook.split("\\s+"); String[] functionSplitValues = functionToHook.split("\\s+");
//select //select
String onlyClass = classClean[classClean.length - 1]; String onlyClass = classClean[classClean.length - 1];
String onlyFunction = CleanUpFunction(functionSplitValues); String onlyFunction = CleanUpFunction(functionSplitValues);
//Write Xposed Class //Write Xposed Class
String XposedClassText = "package androidpentesting.com.xposedmodule;" + "\r\n" + String XposedClassText = "package androidpentesting.com.xposedmodule;" + "\r\n" + "import de.robv.android.xposed.IXposedHookLoadPackage;" + "\r\n" + "\r\n" + "import de.robv.android.xposed.XC_MethodHook;" + "\r\n" + "import de.robv.android.xposed.XposedBridge;" + "\r\n" + "import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;" + "\r\n" + "import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;" + "\r\n" + "\r\n" + "public class XposedClassTest implements IXposedHookLoadPackage {" + "\r\n" + "\r\n" + " public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {" + "\r\n" + "\r\n" + " String classToHook = " + "\"" + packageNameOnly + "." + onlyClass + "\";" + "\r\n" + " String functionToHook = " + "\"" + onlyFunction + "\";" + "\r\n" + " if (lpparam.packageName.equals(" + "\"" + packageNameOnly + "\"" + ")){" + "\r" + "\n" + " XposedBridge.log(" + "\" Loaded app: \" " + " + lpparam.packageName);" + "\r\n" + "\r\n" + " findAndHookMethod(" + "\"" + onlyClass + "\"" + ", lpparam.classLoader, " + " \"" + onlyFunction + "\"" + ", int.class," + "\r\n" + " new XC_MethodHook() {" + "\r\n" + " @Override" + "\r\n" + " protected void beforeHookedMethod(MethodHookParam param) throws " + "Throwable {" + "\r\n" + " //TO BE FILLED BY ANALYST" + "\r\n" + " }" + "\r\n" + " });" + "\r\n" + " }" + "\r\n" + " }" + "\r\n" + "}" + "\r\n";
"import de.robv.android.xposed.IXposedHookLoadPackage;" + "\r\n" +
"\r\n" +
"import de.robv.android.xposed.XC_MethodHook;" + "\r\n" +
"import de.robv.android.xposed.XposedBridge;" + "\r\n" +
"import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;" + "\r\n" +
"import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;" + "\r\n" +
"\r\n" +
"public class XposedClassTest implements IXposedHookLoadPackage {" + "\r\n" + "\r\n" +
" public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {" + "\r\n" + "\r\n" +
" String classToHook = " + "\"" + packageNameOnly + "." + onlyClass + "\";" +
"\r\n" +
" String functionToHook = " + "\"" + onlyFunction + "\";" + "\r\n" +
" if (lpparam.packageName.equals(" + "\"" + packageNameOnly + "\"" + ")){" + "\r"
+ "\n" +
" XposedBridge.log(" + "\" Loaded app: \" " + " + lpparam.packageName);" +
"\r\n" + "\r\n" +
" findAndHookMethod(" + "\"" + onlyClass + "\"" + ", lpparam.classLoader, " + " \"" + onlyFunction + "\"" + ", int.class," + "\r\n" +
" new XC_MethodHook() {" + "\r\n" +
" @Override" + "\r\n" +
" protected void beforeHookedMethod(MethodHookParam param) throws "
+ "Throwable {" + "\r\n" +
" //TO BE FILLED BY ANALYST" + "\r\n" +
" }" + "\r\n" +
" });" + "\r\n" +
" }" + "\r\n" +
" }" + "\r\n" +
"}" + "\r\n";
FileWriter fw = new FileWriter(file.getAbsoluteFile()); FileWriter fw = new FileWriter(file.getAbsoluteFile());
BufferedWriter bw = new BufferedWriter(fw); BufferedWriter bw = new BufferedWriter(fw);
bw.write(XposedClassText); bw.write(XposedClassText);
@ -175,68 +159,87 @@ public class XposedGenerator extends Plugin {
bw.close(); bw.close();
JOptionPane.showMessageDialog(null, "Xposed Module Generated"); JOptionPane.showMessageDialog(null, "Xposed Module Generated");
} catch (IOException e) { }
catch (IOException e)
{
JOptionPane.showMessageDialog(null, "Error" + e); JOptionPane.showMessageDialog(null, "Error" + e);
e.printStackTrace(); e.printStackTrace();
} }
} else { }
else
{
JOptionPane.showMessageDialog(null, "Empty Template Chosen, Did Not Generate"); JOptionPane.showMessageDialog(null, "Empty Template Chosen, Did Not Generate");
} }
} }
private static List<String> ProcessContentExtractedClass(String contentFile) { private static List<String> ProcessContentExtractedClass(String contentFile)
{
Scanner scanner = null; Scanner scanner = null;
try { try
{
scanner = new Scanner(contentFile); scanner = new Scanner(contentFile);
//@TODO : Improve patterns to match other excepts 'public' //@TODO : Improve patterns to match other excepts 'public'
String regexclass = "public"; String regexclass = "public";
Pattern pattern = Pattern.compile(regexclass, Pattern.CASE_INSENSITIVE); Pattern pattern = Pattern.compile(regexclass, Pattern.CASE_INSENSITIVE);
while (scanner.hasNextLine()) { while (scanner.hasNextLine())
{
String line = scanner.nextLine(); String line = scanner.nextLine();
// process the line // process the line
Matcher matcher = pattern.matcher(line); Matcher matcher = pattern.matcher(line);
while (matcher.find()) { while (matcher.find())
if (matcher.group() != null) { {
if (matcher.group() != null)
{
System.out.println("find() found the pattern \"" + quote(line.trim())); System.out.println("find() found the pattern \"" + quote(line.trim()));
System.out.println("Function: " + CleanUpFunction(line.trim().split("\\s+"))); System.out.println("Function: " + CleanUpFunction(line.trim().split("\\s+")));
methodsNames.add(quote(line.trim())); methodsNames.add(quote(line.trim()));
} else { }
else
{
methodsNames.add("No methods found"); methodsNames.add("No methods found");
} }
} }
} }
if (methodsNames.isEmpty()) { if (methodsNames.isEmpty())
methodsNames.add("No methods found"); methodsNames.add("No methods found");
} else { else
return methodsNames; return methodsNames;
}
return methodsNames; return methodsNames;
} finally { }
finally
{
if (scanner != null) if (scanner != null)
scanner.close(); scanner.close();
} }
} }
private static List<String> ProcessCleanMethodsAll(List<String> rawMethods) { private static List<String> ProcessCleanMethodsAll(List<String> rawMethods)
for (String m : rawMethods) { {
for (String m : rawMethods)
{
//Exclude class declaration //Exclude class declaration
//TODO:add a list containing all possible types //TODO:add a list containing all possible types
if (!m.contains("extends") && (!m.contains("implements") && (m.contains("(")))) { if (!m.contains("extends") && (!m.contains("implements") && (m.contains("("))))
{
cleanMethodsNames.add(m); cleanMethodsNames.add(m);
} }
} }
return cleanMethodsNames; return cleanMethodsNames;
} }
private static String CleanUpFunction(String[] rawFunction) { private static String CleanUpFunction(String[] rawFunction)
{
String onlyFunc = "functiondummy"; String onlyFunc = "functiondummy";
for (String m : rawFunction) { for (String m : rawFunction)
if (m.contains("(")) { {
if (m.contains("("))
{
String[] split = m.split("\\(")[0].split(" "); String[] split = m.split("\\(")[0].split(" ");
return split[split.length - 1]; return split[split.length - 1];
} }
@ -245,49 +248,63 @@ public class XposedGenerator extends Plugin {
return onlyFunc; return onlyFunc;
} }
private static String ProcessContentExtractedPackage(String contentFile) { private static String ProcessContentExtractedPackage(String contentFile)
{
Scanner scanner = null; Scanner scanner = null;
try { try
{
scanner = new Scanner(contentFile); scanner = new Scanner(contentFile);
String regexPkg = "package"; String regexPkg = "package";
Pattern patternPkg = Pattern.compile(regexPkg, Pattern.CASE_INSENSITIVE); Pattern patternPkg = Pattern.compile(regexPkg, Pattern.CASE_INSENSITIVE);
String line = scanner.nextLine(); String line = scanner.nextLine();
// process the line // process the line
Matcher matcher = patternPkg.matcher(line); Matcher matcher = patternPkg.matcher(line);
while (matcher.find()) { while (matcher.find())
if (matcher.group() != null) { {
if (matcher.group() != null)
{
System.out.println("find() found the pattern \"" + quote(line.trim())); System.out.println("find() found the pattern \"" + quote(line.trim()));
foundPckg = quote(line.trim()); foundPckg = quote(line.trim());
} else { }
else
{
foundPckg = ""; foundPckg = "";
} }
} }
try try
{ {
if (foundPckg == null || foundPckg.isEmpty()) if (foundPckg == null || foundPckg.isEmpty())
foundPckg = "No Package Found"; foundPckg = "No Package Found";
} catch (NullPointerException e) { }
JOptionPane.showMessageDialog(null, catch (NullPointerException e)
"Error - no package was found in the selected class: " + e); {
} finally { JOptionPane.showMessageDialog(null, "Error - no package was found in the selected class: " + e);
}
finally
{
scanner.close(); scanner.close();
} }
} catch (IllegalArgumentException e) { }
catch (IllegalArgumentException e)
{
JOptionPane.showMessageDialog(null, "Error" + e); JOptionPane.showMessageDialog(null, "Error" + e);
if (scanner != null) if (scanner != null)
scanner.close(); scanner.close();
} finally { }
finally
{
if (scanner != null) if (scanner != null)
scanner.close(); scanner.close();
} }
return foundPckg; return foundPckg;
} }
private static String quote(String aText) { private static String quote(String aText)
{
String QUOTE = "'"; String QUOTE = "'";
return QUOTE + aText + QUOTE; return QUOTE + aText + QUOTE;
} }