All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.unidbg.linux.unpack.ElfUnpacker Maven / Gradle / Ivy

There is a newer version: 0.9.8
Show newest version
package com.github.unidbg.linux.unpack;

import com.github.unidbg.Emulator;
import com.github.unidbg.Module;
import com.github.unidbg.arm.backend.Backend;
import com.github.unidbg.arm.backend.UnHook;
import com.github.unidbg.arm.backend.WriteHook;
import com.github.unidbg.memory.MemRegion;
import com.github.unidbg.pointer.UnidbgPointer;
import com.github.unidbg.spi.InitFunctionListener;
import org.apache.commons.io.FileUtils;
import unicorn.UnicornConst;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * Dump 针对 init_array 加密的 so 文件
 * 
 * First before load so:
 *     memory.addModuleListener();
 * Then in onLoaded method:
 *     if ("libxxx.so".equals(module.name)) {
 *         File outFile = new File(FileUtils.getUserDirectory(), "Desktop/libxxx_patched.so");
 *         new ElfUnpacker(libxxxFileData, outFile).register(emulator, module);
 *     }
 * 
*/ public class ElfUnpacker { private final byte[] elfFile; private final File outFile; public ElfUnpacker(byte[] elfFile, File outFile) { this.elfFile = elfFile; this.outFile = outFile; if (outFile.isDirectory()) { throw new IllegalStateException("isDirectory"); } this.buffer = ByteBuffer.allocate(8); this.buffer.order(ByteOrder.LITTLE_ENDIAN); } private final ByteBuffer buffer; private boolean dirty; public void register(final Emulator emulator, final Module module) { module.setInitFunctionListener(new InitFunctionListener() { @Override public void onPreCallInitFunction(Module module, long initFunction, int index) { dirty = false; } @Override public void onPostCallInitFunction(Module module, long initFunction, int index) { try { if (dirty) { System.out.println("Unpack initFunction=" + UnidbgPointer.pointer(emulator, module.base + initFunction)); FileUtils.writeByteArrayToFile(outFile, elfFile); } } catch (IOException e) { throw new IllegalStateException(e); } } }); for (MemRegion region : module.getRegions()) { if ((region.perms & UnicornConst.UC_PROT_WRITE) == 0 && (region.perms & UnicornConst.UC_PROT_EXEC) == UnicornConst.UC_PROT_EXEC) { // 只读代码段 System.out.println("Begin unpack " + module.name + ": 0x" + Long.toHexString(region.begin) + "-0x" + Long.toHexString(region.end)); emulator.getBackend().hook_add_new(new WriteHook() { private UnHook unHook; @Override public void hook(Backend backend, long address, int size, long value, Object user) { long offset = address - module.base; int fileOffset = module.virtualMemoryAddressToFileOffset(offset); if (size < 1 || size > 8) { throw new IllegalStateException("size=" + size); } if (fileOffset >= 0) { buffer.clear(); buffer.putLong(value); System.arraycopy(buffer.array(), 0, elfFile, fileOffset, size); dirty = true; } } @Override public void onAttach(UnHook unHook) { this.unHook = unHook; } @Override public void detach() { this.unHook.unhook(); } }, region.begin, region.end, emulator); } } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy