Unity 游戏脚本解密

现在用Unity的游戏大多都加密了Assembly-CSharp.dll, 这篇文章给出一个通用的解密方法。

原理是通过调用游戏自身的libmono.so的导出函数mono_image_open_from_data_with_name
对游戏自身脚本文件的解密。

#include <stdio.h>
#include <dlfcn.h>
struct _MonoImage {
	/*
	 * The number of assemblies which reference this MonoImage though their 'image'
	 * field plus the number of images which reference this MonoImage through their 
	 * 'modules' field, plus the number of threads holding temporary references to
	 * this image between calls of mono_image_open () and mono_image_close ().
	 */
	int   ref_count;
	void *raw_data_handle;
	char *raw_data;
	int raw_data_len;
};
int main()
{
	void * libm_handle = NULL;
    struct _MonoImage* (*mono_image_open_from_data_with_name) (char *data, int data_len, int need_copy, char *status, char *filename);
	void (*mono_image_close)(struct _MonoImage *);
    char *errorInfo;
    struct _MonoImage* result;
    
    // dlopen 函数还会自动解析共享库中的依赖项。这样,如果您打开了一个依赖于其他共享库的对象,它就会自动加载它们。
    // 函数返回一个句柄,该句柄用于后续的 API 调用
    libm_handle = dlopen("/data/local/tmp/libmono.so", RTLD_LAZY );
    // 如果返回 NULL 句柄,表示无法找到对象文件,过程结束。否则的话,将会得到对象的一个句柄,可以进一步询问对象
    if (!libm_handle){
        // 如果返回 NULL 句柄,通过dlerror方法可以取得无法访问对象的原因
        printf("Open Error:%s.\n",dlerror());
        return 0;
    }
    // 使用 dlsym 函数,尝试解析新打开的对象文件中的符号。您将会得到一个有效的指向该符号的指针,或者是得到一个 NULL 并返回一个错误
    mono_image_open_from_data_with_name = dlsym(libm_handle,"mono_image_open_from_data_with_name");
    errorInfo = dlerror();// 调用dlerror方法,返回错误信息的同时,内存中的错误信息被清空
    if (errorInfo != NULL){
        printf("Dlsym Error:%s.\n",errorInfo);
        return 0;
    }
	printf("call mono_image_open_from_data:0x%x\n", mono_image_open_from_data_with_name);
	const char* pDll = "/data/local/tmp/Assembly-CSharp.dll";
	FILE *fpDll;
	fpDll = fopen(pDll, "r");
	if(fpDll == NULL)
	{
		printf("open  fail\n");
	}
	fseek(fpDll, 0, SEEK_END);
	int len = ftell(fpDll);
	fseek(fpDll, 0, SEEK_SET);
	char *data = (char *)malloc(len);
	fread(data, 1, len, fpDll);
	fclose(fpDll);
    result = (*mono_image_open_from_data_with_name)(data, len, 0, 0, "Assembly-CSharp.dll");
	printf("call result:0x%x\n", result);
    char *pData = result->raw_data;
	int size = result->raw_data_len;
	printf("%d", size);
	FILE* pFile = fopen("dump.dll","wb");
	fwrite(pData,size,1,pFile);
	fclose(pFile);	
    dlclose(libm_handle);
    return 0;
}


这里提供一份编译好的文件

https://yunpan.cn/cqGdHYi2P7g5K  访问密码 36eb


评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值