When Doing Reverse Engineering for Crawlers, How Does Python Properly Call JAR Encryption Logic?

1. Introduction
During mobile app crawling, when encountering unknown parameters, we often need to reverse engineer the app. For parameter generation logic, we can use Python to implement it. However, some app parameter generation logic might already be written into multiple JAR files. In such cases, we only need Python to execute the JAR.

This article will discuss how Python can call methods from JAR files.

2. Merging JAR Files
Taking an Android App as an example, assuming the encryption parameter generation logic is spread across multiple JAR files, we first need to merge all JAR files into a single JAR file.

PS: For AAR files, you can first extract them using decompression software, then merge the JAR files.

Merging JAR files involves 2 steps:

  • Extract JAR files
  • Merge all source code

2.1 Extract JAR Files
After installing JDK, use the jar -xvf command to extract individual JAR files. This will generate JAVA compiled class files in the same directory according to the package structure.

bash

# Extract JAR files one by one
# Generate class files locally
jar -xvf a.jar
jar -xvf b.jar
jar -xvf c.jar

2.2 Merge All Source Code
Use the jar -cvfM command to generate a new JAR from all local class files.

bash

# Merge all source code in current directory into one JAR
# Where: output.jar represents the new JAR
jar -cvfM output.jar .

3. Python Calling JAR
First, we install the dependency package: jpype

bash

# Install dependency package
pip3 install JPype1

Assume the encryption logic in the JAR is implemented as follows:

java

package com.xingag.common;

public class EncryHelper {
    public String encrypt(String content) {
          // Encryption logic
    }
}

Using Python to call methods in JAR involves 3 steps:

  1. Start the JVM
  2. Instantiate JAVA object and call the corresponding method
  3. Close the JVM

3.1 Start JVM

python

import jpype

# Local path to JAR
jar_path = os.path.join(os.path.abspath('.'), './output.jar')

# Start jvm
jpype.startJVM(jpype.getDefaultJVMPath(), "-ea", "-Djava.class.path=%s" % (jar_path))

3.2 Instantiate JAVA Object and Call Method
Based on the package name of the method to be called, use the JClass() method in jpype to instantiate the JAVA class object, then call the method of the JAVA object.

Note: Since this is an instance method in JAVA, you need to instantiate the object first, then call the method. If it were a static method, you could call the method directly.

python

# Instantiate JAVA object via package name
EncryClass = jpype.JClass("com.xingag.common.EncryHelper")
encryClass = EncryClass()

# Call encryption method in JAVA
content_encry = encryClass.encrypt("xag")
print(content_encry)

3.3 Close JVM
You can choose to actively close the JVM, or let it close automatically when the Python program finishes running, to release resources.

python

import jpype

# Close jvm
jpype.shutdownJVM()

4. Conclusion
Python directly calling methods in JAR files can help us reuse existing solutions and reduce the workload of web crawling!