最近研究捕鱼的一些功能,顺手下载了一款鱼,避免不必要的麻烦,几乎看不清楚改款属于什么游戏了。
首先使用Android Killer打开APK如下:
打开工程管理:
看到Assemble-CSharp.dll 可以断定是用Unity3D开发的,一般这个dll是主核心逻辑代码。
我们使用dnSpy打开发现有加密,dnSpy是一款开源的C# DLL反编译工具。
我们需要对Assembly-CSharp.dll 解密才能通过dnSpy解开源码。
1、使用IDA反汇编工具打开libmono.so 找到解密的地方。
查看了一些资料Unity3D加载dll的时候需要先运行libmono.so,其中mono_image_open_from_data_with_name方法是对dll的解密。
2、在IDA找到mono_image_open_from_data_with_name方法位置。
int __fastcall mono_image_open_from_data_with_name(_BYTE *a1, size_t a2, int a3, _DWORD *a4, int a5, int a6, int a7, int a8, int a9, int a10, int a11, int (__fastcall *a12)(_DWORD), char a13, const char *a14)
{
size_t v14; // r10
_BYTE *v15; // r4
int v16; // r8
_DWORD *v17; // r7
signed int v18; // r2
signed int v19; // r12
bool v20; // zf
int v22; // r0
char v23; // r3
int v24; // r5
int v25; // r0
int v26; // r0
int v27; // r12
_BYTE *v28; // r0
_BYTE *v29; // r5
v14 = a2;
v15 = a1;
v16 = a3;
v17 = a4;
if ( strstr(a14, "Assembly-CSharp.dll") )
{
if ( v14 <= 0x1F )
{
v18 = v14;
if ( !v14 )
goto LABEL_6;
}
else
{
v18 = 32;
}
v19 = 0;
do
{
v15[v19] ^= key[v19]; //该位置是解密地方,其中key可以通过IDA静态分析找到。
++v19;
}
while ( v19 < v18 );
}
LABEL_6:
v20 = v15 == 0;
if ( v15 )
v20 = v14 == 0;
if ( v20 )
{
if ( v17 )
*v17 = 3;
return a12(0);
}
if ( v16 )
{
v28 = (_BYTE *)g_malloc(v14);
v29 = v28;
if ( !v28 )
{
if ( v17 )
*v17 = 1;
return a12(0);
}
memcpy(v28, v15, v14);
v15 = v29;
}
v22 = g_malloc0(872);
v23 = *(_BYTE *)(v22 + 16);
v24 = v22;
*(_DWORD *)(v22 + 8) = v15;
*(_DWORD *)(v22 + 12) = v14;
*(_BYTE *)(v22 + 16) = v23 & 0xFD | 2 * (v16 & 1);
if ( a14 )
v25 = g_strdup(a14);
else
v25 = g_strdup_printf("data-%p", v15);
*(_DWORD *)(v24 + 20) = v25;
v26 = g_malloc0(396);
v27 = (unsigned __int8)(*(_BYTE *)(v24 + 16) & 0xF7) | 8 * (a13 & 1);
*(_DWORD *)v24 = 1;
*(_BYTE *)(v24 + 16) = v27;
*(_DWORD *)(v24 + 44) = v26;
if ( !do_mono_image_load(v24, v17, 1) )
return a12(0);
return register_image();
}
3、使用Visual Studio2015 C#创建工程解密DLL。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace sxdec_en
{
class Program
{
static void Main(string[] args)
{
byte[] key = new byte[]
{
177,
218,
94,
21,
70,
87,
167,
141,
157,
132,
144,
216,
171,
0,
140,
188,
211,
10,
247,
228,
88,
5,
184,
179,
69,
6,
208,
44,
30,
143,
202,
51
};
//读取解密的DLL
byte[] bytes = File.ReadAllBytes("E:\\Project\\assets\\bin\\Data\\Managed\\Assembly-CSharp.dll");
int v11 = 0;
//通过IDA分析最终得到解密代码只需要这些就OK了。
do
{
byte[] array = bytes;
int num = v11;
array[num] ^= key[v11];
v11++;
}
while (v11 < 32);
//解密后的DLL
FileStream fileStream = new FileStream("E:\\Project\\assets\\bin\\Data\\Managed\\Assembly-CSharp_dec.dll", FileMode.Create, FileAccess.Write, FileShare.None);
fileStream.Write(bytes, 0, bytes.Length);
fileStream.Close();
}
}
}