• 微软原版系统

  • 一键重装系统

  • 纯净系统

  • 在线技术客服

魔法猪系统重装大师 一键在线制作启动 U 盘 PE 系统 用一键重装的魔法拯救失去灵魂的系统
当前位置:首页 > 教程 > 电脑教程

用Cecil任意修改破解xap文件的.Net程序集+源码

时间:2015年04月02日 15:27:20    来源:魔法猪系统重装大师官网    人气:4595

本文以破解WP的XBL(Xbox LIVE)游戏为例讲解如何使用Cecil这把尚方宝剑,让ILDasm修改IL的方法彻底成为历史。

最近在Windows Phone Store的Nokia collection里面发现了《Parking Mania(疯狂停车场)》这款游戏。试玩了一下觉得非常有趣,但只能试玩前面少数几关。手痒痒的就开始了“盗版”部署。由于Parking Manin是XBL游戏,其调用GamerServicesComponent组件。但直接部署的XAP的应用无法使用此组件,从而会在使用了组件的地方会直接终止应用(DFT成就版ROM除外)。所以我们要做的就是在整个游戏中找到所有调用了XBL服务的地方并将其去除或跳过。但这样有个明显的缺点:XBL最重要的成就和排名功能被阉割掉了。DFT成就版就是为了解决这一问题而产生的。

为了破解,当然是要先找到所有调用了XBL服务的地方。直接在IL中搜索GamerServicesComponent,只有ParkingMania.ParkingManiaGame中枪。然后在Initialize方法中前两句指令给删掉,清空HandleGameUpdateRequired、Update方法。即下图中红框中的代码要干掉。

找到其对应的IL代码:

对应用C#代码操作的代码如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
if (type.FullName == "ParkingMania.ParkingManiaGame")
{
    var field = type.Fields.FirstOrDefault(s => s.Name == "GamerServiceInstance");
    type.Fields.Remove(field);
    foreach (var method in type.Methods)
    {
        if (method.Body == null)
            continue;
        var worker = method.Body.GetILProcessor();
        if (method.Name == "Initialize")
        {
            var list = method.Body.Instructions.Skip(1).Take(9).ToList();
            list.ForEach(i => { worker.Remove(i); });
        }
        if (method.Name == "HandleGameUpdateRequired")
        {
            var list = method.Body.Instructions.Skip(3).Take(4).ToList();
            list.ForEach(i => { worker.Remove(i); });
        }
        if (method.Name == "Update")
        {
            var list = method.Body.Instructions.Skip(8).Take(8).ToList();
            list.ForEach(i => { worker.Remove(i); });
        }
    }
}

再进一步阅读分析源码可以发现有ParkingMania.Services.Data.Achievments.XBLAService这个类。这里面要把Event、LoadMoneyLeaderboard、LoadStarsLeaderboard、GetAchievmentsForMenu方法统统干掉。具体方法也类似,就不重复贴代码的。

需要注意的是:离开try…catch…模块的时候需要leave.s指令、离开一个方法的时候需要ret指令。删除的时候记得保留这些指令。

最后贴出完整的代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using Mono.Cecil;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CecilParkingMania
{
    class Program
    {
        static void Main(string[] args)
        {
            var bas = @"D:\Til\Parking_0\";
            var src = bas + @"ParkingMania.org.dll";
            var dst = bas + @"0\ParkingMania.dll";
            var resolver = new DefaultAssemblyResolver();
            resolver.AddSearchDirectory(bas + @"0");
            var parameters = new ReaderParameters
            {
                AssemblyResolver = resolver,
                ReadSymbols = false,
            };
            var assembly = AssemblyDefinition.ReadAssembly(src, parameters);
            foreach (var module in assembly.Modules)
            {
                foreach (var type in module.Types)
                {
                    if (type.FullName == "ParkingMania.ParkingManiaGame")
                    {
                        var field = type.Fields.FirstOrDefault(s => s.Name == "GamerServiceInstance");
                        type.Fields.Remove(field);
                        foreach (var method in type.Methods)
                        {
                            if (method.Body == null)
                                continue;
                            var worker = method.Body.GetILProcessor();
                            if (method.Name == "Initialize")
                            {
                                var list = method.Body.Instructions.Skip(1).Take(9).ToList();
                                list.ForEach(i => { worker.Remove(i); });
                            }
                            if (method.Name == "HandleGameUpdateRequired")
                            {
                                var list = method.Body.Instructions.Skip(3).Take(4).ToList();
                                list.ForEach(i => { worker.Remove(i); });
                            }
                            if (method.Name == "Update")
                            {
                                var list = method.Body.Instructions.Skip(8).Take(8).ToList();
                                list.ForEach(i => { worker.Remove(i); });
                            }
                        }
                    }
                    if (type.FullName == "ParkingMania.Services.Data.Achievments.XBLAService")
                    {
                        foreach (var method in type.Methods)
                        {
                            if (method.Body == null)
                                continue;
                            var worker = method.Body.GetILProcessor();
                            if (method.Name == "Event")
                            {
                                var list = method.Body.Instructions.Take(method.Body.Instructions.Count - 1).ToList();
                                list.ForEach(i => { worker.Remove(i); });
                            }
                            if (method.Name == "LoadMoneyLeaderboard")
                            {
                                var list = method.Body.Instructions.Take(method.Body.Instructions.Count - 1).ToList();
                                list.ForEach(i => { worker.Remove(i); });
                            }
                            if (method.Name == "LoadStarsLeaderboard")
                            {
                                var list = method.Body.Instructions.Take(method.Body.Instructions.Count - 1).ToList();
                                list.ForEach(i => { worker.Remove(i); });
                            }
                            if (method.Name == "GetAchievmentsForMenu")
                            {
                                var list = method.Body.Instructions.Take(method.Body.Instructions.Count - 1).ToList();
                                list.ForEach(i => { worker.Remove(i); });
                            }
                        }
                    }
                }
            }
            assembly.Write(dst, new WriterParameters { WriteSymbols = false });
        }
    }
}

续,

快速代理等写IL的需求可以用Emit实现,并且是官方支持的方法;简单修改或破解IL的需求可以用ILDasm实现。那么对我们来说,Cecil到底有什么用?

1、对代码程序集进行反编译并规范化的修改其流程,特别是对于复杂的程序集的修改非常有优势

2、按照自己的需求额外的优化代码

3、插入特殊的操作指令,例如编译时后自动完成WPF中观察者模式中的通知接口

这里也顺便说一下DFT成就版吧

首先要说一下XBL最大的优势是提供了游戏中“成就”和“排名”等服务的支持,这些服务非常有助于提高用户粘性。@马宁 为此还弄出了OpenXLive 这个开放的SNS平台。可以看看马宁的一篇博客《OpenXLive——开启Windows Phone 7游戏社交平台新时代》中关于Leaderboard、Achievements、Social Network的介绍。

XNA自身在Microsoft.Xna.Framework.Game.dll集成了类似的服务,并提供了开发接口。WP7中许多XBL游戏都使用此接口。可能是微软自身的保护策略,禁止从市场安装的应用访问XBL服务接口。DFT成就版就是在ROM中修改了此接口,并xxxx了。

有了Cecil这个玩意,我们完全可以设计出一种机制自动识别出使用了XBL服务接口的代码并使其使用另外编写好的第三方接口。在第三方接口中可以在本地或其他网络中提供第三方服务。有了这样的第三方服务才能算作是“完美”的破解。使用Cecil替换接口的调用并无什么复杂的技术(上一篇文章中就对调用的方法进行了替换),难就难在要设计出一种完善的处理机制使其可以自动的处理任何一种情况。

好了,这只是一种想法,而且是一种邪恶的想法。本着支持正版的精神,大家还是力所能及的购买一些正版吧。

最后的最后,本文重点讲述的已破解完的xap文件放置在群1749907的群共享中,从今天算起只有30天的存储时间。

用,Cecil,任意,修改,破解,xap,文件,的,.Net
栏目:电脑教程 阅读:1000 2023/12/27
Win7教程 更多>>
U盘教程 更多>>
Win10教程 更多>>
魔法猪学院 更多>>

Copyright © 2015-2023 魔法猪 魔法猪系统重装大师

本站发布的系统仅为个人学习测试使用,请在下载后24小时内删除,不得用于任何商业用途,否则后果自负,请支持购买微软正版软件。

在线客服 查看微信 返回顶部