读取隐藏在jpg中的dex文件
如何把dex隐藏到图片里
把DEX文件隐藏到JPG文件中的过程被称为"文件注入"。下面是一种将DEX文件注入到JPG文件中的方法,但请注意,这种方法仅供学术研究目的使用,不应用于非法活动。
在Java中,我们可以使用以下代码将DEX文件隐藏在JPG文件中:
javaCopy code
import java.io.*;
public class FileInjection {
public static void main(String[] args) throws Exception {
//打开JPG文件
File jpgFile = new File("picture.jpg");
FileInputStream jpgInputStream = new FileInputStream(jpgFile);
ByteArrayOutputStream jpgByteArrayOutputStream = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length;
while ((length = jpgInputStream.read(buffer)) != -1) {
jpgByteArrayOutputStream.write(buffer, 0, length);
}
//读取DEX文件并写入字节数组输出流
File dexFile = new File("classes.dex");
FileInputStream dexInputStream = new FileInputStream(dexFile);
ByteArrayOutputStream dexByteArrayOutputStream = new ByteArrayOutputStream();
while ((length = dexInputStream.read(buffer)) != -1) {
dexByteArrayOutputStream.write(buffer, 0, length);
}
//将DEX文件写入JPG文件的字节数组输出流中
byte[] dexBytes = dexByteArrayOutputStream.toByteArray();
byte[] jpgBytes = jpgByteArrayOutputStream.toByteArray();
ByteArrayOutputStream output = new ByteArrayOutputStream();
output.write(jpgBytes, 0, 10); //在JPG文件头中留出一些空间
output.write(dexBytes);
output.write(jpgBytes, 10, jpgBytes.length - 10); //将JPG文件余下部分写入输出流中
//将输出流中的数据写入文件
FileOutputStream fos = new FileOutputStream("picture_with_dex.jpg");
output.writeTo(fos);
fos.close();
}
}
在这个示例中,我们首先使用FileInputStream
读取JPG文件和DEX文件的内容,并使用ByteArrayOutputStream
将它们写入内存中的字节数组输出流中。然后,我们将DEX文件的字节数组写入JPG文件的字节数组输出流中,使其成为JPG文件的一部分。最后,我们使用FileOutputStream
将输出流中的数据写入到新的JPG文件中,这个新文件中包含了隐藏的DEX文件。
请注意,为了隐藏DEX文件,我们在JPG文件头中留出了一些空间,然后将DEX文件的字节数组写入该空间。在读取JPG文件时,我们只读取文件头的前10个字节。这是因为在JPG文件头中,这10个字节是固定的,它们不包含有用的像素信息。因此,我们可以将DEX文件放在文件头中而不会影响图像质量。
读取图片中的dex文件
从图片加载DEX文件的过程也被称为“DEX动态加载”,通常用于在Android应用程序中动态加载代码以提高灵活性和安全性。下面是一段从JPG文件中加载DEX文件的Java代码:
javaCopy code
import java.io.*;
public class DexClassLoaderExample {
public static void main(String[] args) throws Exception {
//加载包含DEX文件的JPG文件
File jpgFile = new File("picture_with_dex.jpg");
FileInputStream jpgInputStream = new FileInputStream(jpgFile);
byte[] jpgBytes = new byte[(int) jpgFile.length()];
jpgInputStream.read(jpgBytes);
jpgInputStream.close();
//读取DEX文件的字节数组
byte[] dexBytes = getDexBytes(jpgBytes);
//使用DexClassLoader动态加载DEX文件
ClassLoader parent = ClassLoader.getSystemClassLoader();
DexClassLoader classLoader = new DexClassLoader(dexBytes, null, null, parent);
Class<?> loadedClass = classLoader.loadClass("com.example.MyClass");
//调用MyClass中的方法
Object myClassInstance = loadedClass.newInstance();
Method myMethod = loadedClass.getDeclaredMethod("myMethod");
myMethod.invoke(myClassInstance);
}
//从JPG文件中提取DEX文件的字节数组
private static byte[] getDexBytes(byte[] jpgBytes) {
//查找DEX文件在JPG文件中的起始位置
int offset = findDexOffset(jpgBytes);
//将DEX文件的字节数组从JPG文件中提取出来
byte[] dexBytes = new byte[jpgBytes.length - offset];
System.arraycopy(jpgBytes, offset, dexBytes, 0, dexBytes.length);
return dexBytes;
}
//查找DEX文件在JPG文件中的起始位置
private static int findDexOffset(byte[] jpgBytes) {
for (int i = 0; i < jpgBytes.length - 3; i++) {
if (jpgBytes[i] == 'D' && jpgBytes[i + 1] == 'E' && jpgBytes[i + 2] == 'X' && jpgBytes[i + 3] == '\n') {
return i;
}
}
return -1;
}
}
在这个示例中,我们首先使用FileInputStream
读取JPG文件的内容并将其存储在一个字节数组中。然后,我们使用findDexOffset
方法查找DEX文件在JPG文件中的起始位置。该方法通过查找字节序列“DEX\n”来定位DEX文件的位置。一旦找到DEX文件的起始位置,我们就可以使用getDexBytes
方法提取DEX文件的字节数组。
接下来,我们使用DexClassLoader
类动态加载DEX文件。该类需要一个父类加载器,因此我们使用ClassLoader.getSystemClassLoader()
获取系统类加载器作为其父类加载器。然后,我们调用loadClass
方法加载我们需要使用的类。在本例中,我们使用loadedClass.newInstance()
创建一个新的MyClass
实例,并使用反射机制调用其myMethod
方法。
以下是python代码实现的
import os
def create():
# 读取DEX文件
with open('hidden.dex', 'rb') as f:
dex_bytes = f.read()
# 读取JPG文件
with open('hidden.jpg', 'rb') as f:
jpg_bytes = f.read()
# 在JPG文件末尾添加DEX文件内容
jpg_bytes += dex_bytes
# 写入新的JPG文件
with open('new.jpg', 'wb') as f:
f.write(jpg_bytes)
def read_dex():
# 读取包含DEX文件的JPG文件
with open('new.jpg', 'rb') as f:
jpg_bytes = f.read()
# 分离JPG文件内容和DEX文件内容
jpg_size = jpg_bytes.index(b'\xff\xd9') + 2
jpg_content = jpg_bytes[:jpg_size]
dex_content = jpg_bytes[jpg_size:]
# 保存JPG文件和DEX文件
with open('new2.jpg', 'wb') as f:
f.write(jpg_content)
with open('test2.dex', 'wb') as f:
f.write(dex_content)
# # 读取包含DEX文件的JPG文件
# with open('new.jpg', 'rb') as f:
# jpg_bytes = f.read()
read_dex()