[参考]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;
}
}
}
运行之后即可正常反编译。
作者发布、转载的任何文章中所涉及的技术、思路、工具仅供以安全目的的学习交流,并严格遵守《中华人民共和国网络安全法》、《中华人民共和国数据安全法》等网络安全法律法规。
任何人不得将技术用于非法用途、盈利用途。否则作者不对未许可的用途承担任何后果。
本文遵守CC BY-NC-SA 3.0协议,您可以在任何媒介以任何形式复制、发行本作品,或者修改、转换或以本作品为基础进行创作
您必须给出适当的署名,提供指向本文的链接,同时标明是否(对原文)作了修改。您可以用任何合理的方式来署名,但是不得以任何方式暗示作者为您或您的使用背书。
同时,本文不得用于商业目的。混合、转换、基于本作品进行创作,必须基于同一协议(CC BY-NC-SA 3.0)分发。
如有问题, 可发送邮件咨询.