首页
社区
课程
招聘
解密U3ddll的函数,一知半解,求指出解密函数在哪
发表于: 2020-10-10 18:06 3225

解密U3ddll的函数,一知半解,求指出解密函数在哪

2020-10-10 18:06
3225
int __fastcall mono_image_open_from_data_with_name(int a1, char *haystack, int a3, _DWORD *a4, char a5, char *haystacka)//这里是原来的参数
参数是我自己加的为了更好分析,结果分析了一天,毛也没看出来
int __fastcall mono_image_open_from_data_with_name(char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, const char *name)
{           //char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, const char *name
  int v6; // r3
  int v7; // r3
  _DWORD *v9; // [sp+0h] [bp-264h]
  int v10; // [sp+4h] [bp-260h]
  char *v11; // [sp+8h] [bp-25Ch]
  int *v12; // [sp+Ch] [bp-258h]
  char s[512]; // [sp+10h] [bp-254h]
  char v14[512]; // [sp+2Dh] [bp-237h]
  char v15[512]; // [sp+31h] [bp-233h]
  int v16; // [sp+210h] [bp-54h]
  int v17; // [sp+214h] [bp-50h]
  int v18; // [sp+218h] [bp-4Ch]
  void *v19; // [sp+21Ch] [bp-48h]
  size_t v20; // [sp+220h] [bp-44h]
  void *v21; // [sp+224h] [bp-40h]
  size_t v22; // [sp+228h] [bp-3Ch]
  void *v23; // [sp+22Ch] [bp-38h]
  void *dest; // [sp+230h] [bp-34h]
  size_t v25; // [sp+234h] [bp-30h]
  unsigned int v26; // [sp+238h] [bp-2Ch]
  unsigned int v27; // [sp+23Ch] [bp-28h]
  size_t n; // [sp+240h] [bp-24h]
  char *v29; // [sp+244h] [bp-20h]
  void *src; // [sp+248h] [bp-1Ch]
  void *v31; // [sp+24Ch] [bp-18h]
  unsigned int i; // [sp+250h] [bp-14h]
  unsigned int j; // [sp+254h] [bp-10h]
  size_t k; // [sp+258h] [bp-Ch]
  void *ptr; // [sp+25Ch] [bp-8h]

  v12 = (int *)data;
  v11 = data_len;
  v10 = need_copy;
  v9 = status;
  v16 = 0;
  if ( strstr(name, "Assembly-CSharp.dll") )
  {
    src = name + 10;
    v29 = strchr(name, 45);
    memset(s, 0, 0x200u);//512
    n = v29 - (name + 10);
    memcpy(s, "/storage/emulated/0/Android/data/", 0x21u);
    memcpy(v15, name + 10, n);
    memcpy(&s[n + 33], "/files/Bundles/Android/Assembly-CSharp.dll", 0x2Au);
    g_log(0, 32, "mono:path1= %s\n", s);
    ptr = (void *)ReadStringFromFile(s, &v16);
    if ( !v16 )
    {
      memset(s, 0, 0x200u);
      memcpy(s, "/storage/sdcard/Android/data/", 0x1Du);
      memcpy(v14, src, n);
      memcpy(&s[n + 29], "/files/Bundles/Android/Assembly-CSharp.dll", 0x2Au);
      g_log(0, 32, "mono:path2= %s\n", s, v9);
      ptr = (void *)ReadStringFromFile(s, &v16);
    }
    if ( v16 <= 0 )
    {
      v20 = (size_t)(v11 - 4);
      dest = (void *)g_malloc(v11 - 4);
      v19 = v12 + 1;
      memcpy(dest, v12 + 1, v20);
      v12 = (int *)dest;
      v11 = (char *)v20;
      for ( i = 0; i < (unsigned int)v11; ++i )
        *((_BYTE *)v12 + i) = ~(*((_BYTE *)v12 + i) ^ 0x78);
      v16 = v20;
    }
    else
    {
      g_log(0, 32, "mono:path3= %s\n", "11111111111111111111111111", v9);
      v27 = *(_DWORD *)ptr;
      v26 = *v12;
      if ( v26 > v27 )
      {
        v22 = (size_t)(v11 - 4);
        dest = (void *)g_malloc(v11 - 4);
        v21 = v12 + 1;
        memcpy(dest, v12 + 1, v22);
        v12 = (int *)dest;
        v11 = (char *)v22;
        for ( j = 0; j < (unsigned int)v11; ++j )
          *((_BYTE *)v12 + j) = ~(*((_BYTE *)v12 + j) ^ 0x78);
        v16 = v22;
        free(ptr);
      }
      else
      {
        v25 = v16 - 4;
        dest = (void *)g_malloc(v16 - 4);
        v23 = (char *)ptr + 4;
        memcpy(dest, (char *)ptr + 4, v25);
        for ( k = 0; k < v25; ++k )
          *((_BYTE *)dest + k) = ~(*((_BYTE *)dest + k) ^ 0x78);
        v12 = (int *)dest;
        v11 = (char *)v25;
        v16 = v25;
        free(ptr);
      }
    }
  }
  if ( !v12 || !v11 )
  {
    if ( v9 )
      *v9 = 3;
    return 0;
  }
  v31 = v12;
  if ( !v10 )
  {
LABEL_31:
    v18 = g_malloc0(872);
    *(_DWORD *)(v18 + 8) = v31;
    *(_DWORD *)(v18 + 12) = v11;
    *(_BYTE *)(v18 + 16) = *(_BYTE *)(v18 + 16) & 0xFD | 2 * (v10 & 1);
    if ( name )
      v7 = g_strdup(name);
    else
      v7 = g_strdup_printf("data-%p", v31);
    *(_DWORD *)(v18 + 20) = v7;
    v17 = g_malloc0(396);
    *(_DWORD *)(v18 + 44) = v17;
    *(_BYTE *)(v18 + 16) = *(_BYTE *)(v18 + 16) & 0xF7 | 8 * (refonly & 1);
    *(_DWORD *)v18 = 1;
    v18 = do_mono_image_load(v18, v9, 1, 1);
    if ( v18 )
      v6 = register_image(v18);
    else
      v6 = 0;
    return v6;
  }
  v31 = (void *)g_malloc(v11);
  if ( v31 )
  {
    memcpy(v31, v12, (size_t)v11);
    if ( v16 > 0 && v12 )
      g_free(v12);
    goto LABEL_31;
  }
  if ( v9 )
    *v9 = 1;
  return 0;
}

看了一天,百度来百度去,没看出来解密函数,求指出是哪一段。C语言也太难了吧


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 2323
活跃值: (636)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2

解密逻辑:跳过文件开头的4个字节(文件头?),对之后的每个字节x进行操作:x = ~(x ^ 0x78)。对应伪代码段为:

      v20 = (size_t)(v11 - 4); // 分配缓冲区的长度length=data_len-4
      dest = (void *)g_malloc(v11 - 4);
      v19 = v12 + 1;
      memcpy(dest, v12 + 1, v20); // v12是int*,memcpy()时跳过了1*sizeof(int)==4个字节的数据
      v12 = (int *)dest;
      v11 = (char *)v20;
      for ( i = 0; i < (unsigned int)v11; ++i )
        *((_BYTE *)v12 + i) = ~(*((_BYTE *)v12 + i) ^ 0x78); // 解密运算
      v16 = v20;

LABEL_31处之后的代码应该是用来初始化MonoImage结构体,为调用do_mono_image_load做准备的,和解密过程无关。我没研究过u3d,不知道分析的对不对。


这个函数是mono框架的一部分,这里应该是被魔改了,加入了解密过程。可以在github上找到原版的源码对比一下,分析起来就容易多了。

2020-10-10 18:34
0
雪    币: 48
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
张三千 解密逻辑:跳过文件开头的4个字节(文件头?),对之后的每个字节x进行操作:x = ~(x ^ 0x78)。对应伪代码段为:&nbsp;&nbsp;&nbsp;&nbsp ...
mono原函数我看了,就几句,难道这个是旧的吗
2020-10-10 18:53
0
雪    币: 48
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
4
张三千 解密逻辑:跳过文件开头的4个字节(文件头?),对之后的每个字节x进行操作:x = ~(x ^ 0x78)。对应伪代码段为:&nbsp;&nbsp;&nbsp;&nbsp ...
顺便问一下,x=~(x^0x78),~是啥意思
2020-10-10 18:56
0
雪    币: 2323
活跃值: (636)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
万神fake mono原函数我看了,就几句,难道这个是旧的吗[em_40]
原函数是对`mono_image_open_from_data_internal`套的一层壳,逻辑在这个internal函数里。编译的时候应该是把internal给内联了,也可能是mono是旧版
2020-10-10 19:20
0
雪    币: 2323
活跃值: (636)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
万神fake 顺便问一下,x=~(x^0x78),~是啥意思
按位取反,`~0x52` = `~01010010` = `10101101` = `0xAD`
2020-10-10 19:22
0
雪    币: 48
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7

谢谢大佬,不过我用代码测试了是,去掉前4个字节,不是跳过,MZ

最后于 2020-10-11 19:35 被万神fake编辑 ,原因:
2020-10-11 19:35
0
雪    币: 48
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8
张三千 按位取反,`~0x52` = `~01010010` = `10101101` = `0xAD`
谢谢大佬,不过我用代码测试了.是去掉前4个字节,不是跳过,MZ
2020-10-11 19:37
0
雪    币: 48
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
9
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace Ddll
{
    class Program
    {
        static List<string> DllFilePath = new List<string>();
        static void Main(string[] args)
        {
            String DllDecodeFilePath = @"D:\Decode\";
            DllFilePath = FileHelper.GetFilePath(@"C:\Users\19256\Desktop\Managed");
            int i = 0;
            Random random = new Random();
            foreach (string path in DllFilePath)
            {
                Console.WriteLine(DllDecodeFilePath + path.Replace("C:\\Users\\19256\\Desktop\\Managed", ""));
                byte[] Dll = FileHelper.FileToByte(path);
                byte[] Dll2 = new byte[Dll.Length];
                for (int i2=0;i2<Dll.Length-4;i2++)
                {
                    Dll2[i] = (byte)~(Dll[i+4] ^ 0x78);
                    i++;
                    //Console.WriteLine(i + 4);
                }
                FileHelper.ByteToFile(Dll2, DllDecodeFilePath+path.Replace("C:\\Users\\19256\\Desktop\\Managed",""));
                i = 0;
                Dll = null;
                Dll2 = null;
                Console.WriteLine("解密完成:"+ path.Replace("C:\\Users\\19256\\Desktop\\Managed", ""));
            }
            Console.ReadLine();
        }   
    }
}

最后于 2021-1-21 18:26 被kanxue编辑 ,原因:
2020-10-11 19:52
0
游客
登录 | 注册 方可回帖
返回
//