[参考]dpt-shell 脱壳器

加壳技术原作者

luoyesiqiu/dpt-shell: Android函数抽取壳实现 (github.com)

说明和分析

加壳器会从dex文件中抽取字节码,放入文件OoooooOooo。

文件格式如下

间距(字节)
	字段名
+0x0 short Version
+0x2 short DexCount
+0x4 dword dexCodesIndex
[多个]
+0x2 short Reversed
+0x2 short MethodCount
+0x4 struct instructions
	+0x0 dword MethodIndex
	+0x4 dword OffsetOfDex
	+0x4 dword InstructionDataSize
	+0x4 byte* InstructionsData
...

因此可以写一个对应的脱壳器。在此处给出demo代码。


using System.Text;

public class Program
{
    static void Main(string[] args)
    {

        //此处更改为对应文件大小和路径
        const int SIZEOFDEXENCODED = 0;
        if (SIZEOFDEXENCODED == 0) throw new NotImplementedException("demo版本无法直接编译");

        FileStream DexEncoded = new FileStream(@"OoooooOooo", FileMode.Open, FileAccess.Read, FileShare.Read);
        FileStream classes2_dex = new FileStream(@"classes2.dex", FileMode.Open, FileAccess.Write, FileShare.None);

        byte[] buffer = new byte[SIZEOFDEXENCODED];
        const int sizeofBuffer = SIZEOFDEXENCODED;

        DexEncoded.Read(buffer, 0, sizeofBuffer);

        System.Console.WriteLine("version = " + Bytes2Short(buffer, 0));
        System.Console.WriteLine("dexCount = " + Bytes2Short(buffer, 2));

        //需要按需更改
        System.Console.WriteLine("dexCodesIndex1 = " + Bytes2Dword(buffer, 4));
        System.Console.WriteLine("dexCodesIndex2 = " + Bytes2Dword(buffer, 8));
        int pos = 0x10;
        //这里给出实例数据
        /*
		   01 00 02 00 0C 00 00 00 0E 00 00 00 00 00 22 00
		   FF 00 00 00 20 FA 06 00 58 00 00 00 1A 00 82 16
		   CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC
		   其中自FF 00 00 00开始为instructions结构体。
		*/
        try
        {
            do
            {
                int MethodIndex = Bytes2Dword(buffer, pos); pos += 4;
                int OffsetOfDex = Bytes2Dword(buffer, pos); pos += 4;
                int InstructionDataSize = Bytes2Dword(buffer, pos); pos += 4;
                byte[] ins = new byte[InstructionDataSize];
                Buffer.BlockCopy(buffer, pos, ins, 0, InstructionDataSize);
                System.Console.WriteLine("methodIndex=0x{0:X},offset=0x{1:X},size=0x{2:X}\twriting...", MethodIndex, OffsetOfDex, InstructionDataSize);

                classes2_dex.Seek(OffsetOfDex, SeekOrigin.Begin);
                classes2_dex.Write(ins, 0, InstructionDataSize);
                pos += InstructionDataSize;
                if (pos == SIZEOFDEXENCODED) break;
            } while (true);
        }
        catch
        {
            System.Console.WriteLine("在此处添加错误处理代码...");
        }
        DexEncoded.Close();
        classes2_dex.Close();
        }
        static int Bytes2Short(byte[] array, int offset)
        {
            return array[offset + 1] * 0x100
                 + array[offset + 0] * 0x1;
        }
        static int Bytes2Dword(byte[] array, int offset)
        {
            return array[offset + 3] * 0x1000000
                 + array[offset + 2] * 0x10000
                 + array[offset + 1] * 0x100
                 + array[offset + 0] * 0x1;
        }
    }
}

运行之后即可正常反编译。

posted @ 2022-08-26 17:39  二氢茉莉酮酸甲酯  阅读(118)  评论(0编辑  收藏  举报