|
<
如题所示,U3D的Mono解稀,那个玩意我昨早正在我的手艺群里貌似看到道U3D是要弃用了Mono那个机造,也没有明白是实是假,趁着借出弃用,我也便来讲道那个机造的一个另类解稀。
闭于Mono那工具我便没有烦琐了,我便间接进进正题。尽人皆知,Mono的减稀次要是针对 Assembly-CSharp.dll,此DLL包罗了游戏的一切功用性函数,而且能够经由过程东西dnSpy.exe减载落后止检察。
此DLL公然即是道源码公然,能够经由过程C#工程引进该DLL自写一个GameObject注进到游戏里挪用游戏自带函数完成做弊。
年夜多的减稀手腕便是对那DLL停止两进造处置,也便是把文件字节给停止处置。关于这类减稀的处置方法很简朴,Mono.dll是U3D用去初初化并减载dll的一个模块,他内里有一个函数mono_image_open_from_data_with_name,那里放一下他的函数代码
- MonoImage *
- mono_image_open_from_data_with_name (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, const char *name)
- {
- return mono_image_open_from_data_internal (data, data_len, need_copy, status, refonly, FALSE, name);
- }
复造代码
- MonoImage *
- mono_image_open_from_data_internal (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, gboolean metadata_only,
- const char *name)
- {
- MonoCLIImageInfo *iinfo;
- MonoImage *image;
- char *datac;
-
- if (!data || !data_len) {
- if (status)
- *status = MONO_IMAGE_IMAGE_INVALID;
- return NULL;
- }
- datac = data;
- if (need_copy) {
- datac = (char *)g_try_malloc (data_len);
- if (!datac) {
- if (status)
- *status = MONO_IMAGE_ERROR_ERRNO;
- return NULL;
- }
- memcpy (datac, data, data_len);
- }
-
- image = g_new0 (MonoImage, 1);
- image->raw_data = datac;
- image->raw_data_len = data_len;
- image->raw_data_allocated = need_copy;
- image->name = (name == NULL) ? g_strdup_printf ("data-%p", datac) : g_strdup(name);
- iinfo = g_new0 (MonoCLIImageInfo, 1);
- image->image_info = iinfo;
- image->ref_only = refonly;
- image->metadata_only = metadata_only;
- image->ref_count = 1;
-
- image = do_mono_image_load (image, status, TRUE, TRUE);
- if (image == NULL)
- return NULL;
-
- return register_image (image);
- }
复造代码 看没有懂不妨,我们只需求存眷他的data,data_len,name那三个参数,那三个别离暗示当前被减载模块的两进造内乱容,两进造少度,模块名。年夜部门游戏厂商城市正在那里断定模块名能否为Assembly-CSharp,然落后止两进造内乱容解稀。那末只需求用调试东西正在那个函数下段,然后正在那里阐发结束的地位,然后间接dump便可。那里放一下大要代码
间接正在解稀终了的地位下断,然后把rdi给dump出去便止,获得的便是解稀后的dll。也能够自写剧本。
____________________________________________________________________________________________________________________________________________________________
上里介绍了Assembly-CSharp的一种减稀息争稀方法,虽然说是减稀,可是十分下饭,根本有脚便止。明天便来讲道另外一种减稀方法。小利剑鼠是海内某款游戏,如今该当该当没有开放了,可是游戏照旧躺正在我硬盘里。该游戏一样是减稀Assembly-CSharp,可是有个差别面便是该文件只要1kb,那个便很可疑,由于那即是道那文件是空的,用十六进造翻开文件也能看出内里无内乱容,那末游戏很大要是联网获得新的,大要是内乱存释放。那末除来阐发后解稀,便出有法子拿到解稀后的文件吗,谜底能否定的。那个时分便需求上面硬手艺了。
- static MonoImage *
- register_image (MonoImage *image)
- {
- MonoImage *image2;
- GHashTable *loaded_images = get_loaded_images_hash (image->ref_only); // 重面存眷工具
-
- mono_images_lock ();
- image2 = (MonoImage *)g_hash_table_lookup (loaded_images, image->name);
-
- if (image2) {
- /* Somebody else beat us to it */
- mono_image_addref (image2);
- mono_images_unlock ();
- mono_image_close (image);
- return image2;
- }
-
- GHashTable *loaded_images_by_name = get_loaded_images_by_name_hash (image->ref_only);
- g_hash_table_insert (loaded_images, image->name, image); // 重面存眷工具
- if (image->assembly_name && (g_hash_table_lookup (loaded_images_by_name, image->assembly_name) == NULL))
- g_hash_table_insert (loaded_images_by_name, (char *) image->assembly_name, image);
- mono_images_unlock ();
-
- return image;
- }
复造代码 那里能够明晰的看到,U3D间接把需求的减载的模块插进了一个HashTable,然后完成模块的一个拆载。那里我们先不论那个模块停止了怎样减稀息争稀,既然您要扔给U3D托管,那末您没有大要扔了一个减稀模块的给U3D托管,除非您的U3D引擎停止了一个年夜范围的魔改。以是道,我们只需求找到那个HashTable,然后来遍历一下内里的模块,我们是否是就可以拿到解稀后的Assembly-CSharp,谜底是必定的。那末如今重面工具从 怎样解稀Assembly-CSharp酿成了 怎样利用loaded_images。
我们该当怎样来找到那个loaded_images?出法子,上阐发。调试器翻开游戏跳到mono_image_open_from_data_with_name那个函数然后比较源码停止阐发。
从源码得知,register_image是最初一个挪用的函数,我们间接找到最初一个函数,出来后阐发得知。
拿到loaded_images后,我们下一步便是要来遍历那个HashTabel,两个法子,一个是本人来拆建GHashTable库,然后本人来跑一遍。第两个法子,本人来阐发g_hash_table_insert函数的流程。我挑选后者 =。=
Ida翻开mono.dll后搜刮g_hash_table_insert,有一个
出来F5后无脑暴力阐发。
阐发了一个大要流程后,翻开CE,用数据规划东西阐发考证看看
很明显,那里该当便是模块列表,我们再随便出来一个来看看。经由过程方才IDA的阐发,0x0是模块名,0x8是image。
战我们方才阐发的分歧,如今我们借好一个工具,那便是image的规划,我们正在源码查找一下。
- struct _MonoImage {
- ………
- guint32 raw_data_len;
- char *raw_data; //模块两进造
- char *name; //模块名
- …………
- }
复造代码 那里便揭出主要的。成绩去了,我们怎样明白他的偏偏移。别记了,那里有
[code]MonoImage *mono_image_open_from_data_internal (char *data, guint32 data_len, gboolean need_copy, MonoImageOpenStatus *status, gboolean refonly, gboolean metadata_only, const char *name){ MonoCLIImageInfo *iinfo; MonoImage *image; char *datac; if (!data || !data_len) { if (status) *status = MONO_IMAGE_IMAGE_INVALID; return NULL; } datac = data; if (need_copy) { datac = (char *)g_try_malloc (data_len); if (!datac) { if (status) *status = MONO_IMAGE_ERROR_ERRNO; return NULL; } memcpy (datac, data, data_len); } image = g_new0 (MonoImage, 1); image->raw_data = datac; |
1、本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,按照目前互联网开放的原则,我们将在不通知作者的情况下,转载文章;如果原文明确注明“禁止转载”,我们一定不会转载。如果我们转载的文章不符合作者的版权声明或者作者不想让我们转载您的文章的话,请您发送邮箱:Cdnjson@163.com提供相关证明,我们将积极配合您!
2、本网站转载文章仅为传播更多信息之目的,凡在本网站出现的信息,均仅供参考。本网站将尽力确保所提供信息的准确性及可靠性,但不保证信息的正确性和完整性,且不对因信息的不正确或遗漏导致的任何损失或损害承担责任。
3、任何透过本网站网页而链接及得到的资讯、产品及服务,本网站概不负责,亦不负任何法律责任。
4、本网站所刊发、转载的文章,其版权均归原作者所有,如其他媒体、网站或个人从本网下载使用,请在转载有关文章时务必尊重该文章的著作权,保留本网注明的“稿件来源”,并自负版权等法律责任。
|