zoukankan      html  css  js  c++  java
  • MonoTouch 二三事(二)

     2013-02-26 更新 真机秒退问题,授权文件格式原来的不对。

    接上篇。

    把client.exe拖入ilspy后发现,授权是靠mac地址+磁盘序列号等信息,授权验证依赖了rsa签名,得了,咱没超级计算机,跑不出对应的私钥,只有直接该代码爆破了。

    但是在改制前呢?我大概浏览了下client.exe的功能,并没有发现有关各种安装的相关代码,也就是说这个东西他只负责验证授权信息,并保存成授权文件到~/Library/MonoTouch/License.v2,验证授权成功就可以安装,验证授权失败那就停止安装。与把程序安装到哪儿,怎么安装并没有任何关系,那我们何不直接越过这个步骤呢?

    别忘了他只是个安装前运行的脚本~

    因为他是个PackageMaker制作的安装包,并不能直接删除我们要删除的preinstall这个脚本,那我们直接看monotouch.pkg里面的PackageInfo文件,

    <pkg-info format-version="2" identifier="com.xamarin.monotouch.pkg" version="1" install-location="/Developer/MonoTouch" auth="root">
        <payload installKBytes="254496" numberOfFiles="4425"/>
        <scripts>
            <preinstall  file="./preinstall"/>
            <postinstall file="./postinstall"/>
        </scripts>
    </pkg-info>

    一种方法是直接删除<preinstall  file="./preinstall"/>这句,然后再次用PackageMaker打包,嗯,自从XCODE4.*以后这个打包工具从XCODE里面被Apple给移除了,想用的话得自己下载安装,我到下载页面用IE说什么也下载不下来,chrome倒是下载下来了,2KB。。。不下了。直接按照上面那个XML文件所给的安装位置,建立好目录

    /Developer/MonoTouch

    (注意这个目录在之前版本是安装XCODE后自动建立的,并且XCODE等开发工具也安装到此目录,但新版XCODE会直接安装到/Application/Xcode.app,导致此目录我们得手动创建)

    并拷贝上文提到的Payload解压后备用的文件到其下,然后把postinstall这个安装后执行文件也拷贝到这个目录下,然后在终端下执行postinstall,OK,安装好了,

    执行我们之前装的MonoDevelop,新建一个iPhone项目,编译模拟器版Debug,会发现如下图

    无授权哦,看看是/Developer/MonoTouch/usr/bin/mtouch这个程序有问题,会验证授权。这个是mkbundle打包的,用之前的方法提取其托管程序集

    我们得到一堆程序集,其中被我选中那几个是关键程序集,其他的都是Mono程序集,把mtouch.exe拖入ilspy,搜索Main方法,这时找到如下图的类

    Main在我选中的类里面,这个程序集比较奇怪,Main在一个internal class MTouch里面,我们看看他的验证过程

    Main调用了Main2

    Main2里关于验证的是

    View Code
        bool show_help = false;
        bool show_version = false;
        bool generate_manifests = true;
        List<string> list2 = new List<string>();
        List<string> references = new List<string>();
        List<MTouch.Resource> res = new List<MTouch.Resource>();
        string user_gcc_flags = null;
        string device_name = null;
        try
        {
            Activation activation = new Activation(Certificates.Server, Certificates.Client, null);
            License license = License.LoadFromFile(activation.Crypto, Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library/MonoTouch/License.v2"));
            if (Sys.Serial == null)
            {
                Console.Error.WriteLine("Invalid license.  Please contact support@xamarin.com");
                Environment.Exit(97);
            }
            MTouch.ComputeHashes(Sys.Serial, Sys.Mac);
            for (int i = 0; i < license.UserData.H1.Length; i++)
            {
                if (MTouch.H1[i] != license.UserData.H1[i])
                {
                    throw new Exception();
                }
            }
            for (int j = 0; j < license.UserData.H2.Length; j++)
            {
                if (MTouch.H2[j] != license.UserData.H2[j])
                {
                    throw new Exception();
                }
            }
            for (int k = 0; k < license.UserData.H3.Length; k++)
            {
                if (MTouch.H3[k] != license.UserData.H3[k])
                {
                    throw new Exception();
                }
            }
            if (license.UserData.ProductVersion < 5)
            {
                throw new Exception();
            }
        }
        catch (FileNotFoundException)
        {
            Console.Error.WriteLine("License file is missing.  Please activate MonoTouch");
            Environment.Exit(98);
        }
        catch (DirectoryNotFoundException)
        {
            Console.Error.WriteLine("License file is missing.  Please activate MonoTouch");
            Environment.Exit(98);
        }
        catch (Exception value)
        {
            Console.Error.WriteLine("Invalid license.  Please reactivate MonoTouch");
            if (MTouch.verbose > 2)
            {
                Console.WriteLine(value);
            }
            Environment.Exit(99);
        }

    这下该修改程序集了,取消验证那段代码,得请出Reflector + reflexil.1.5插件

    去掉相关li代码,并保持托管堆栈的平衡,也就是不用想原来的push和pop,然后另存为新程序集,再次打开

    授权相关代码消失了。。嘎嘎

    把所有解压的程序集包括[处理]后的mtouch.exe(除去Mono自带的系统程序集,需要哪个不需要哪个可以运行起来试试能不能执行),复制到

    /Developer/MonoTouch/usr/bin/

    这个目录,最终我复制了

    Mono.Cecil.dll
    Mono.Cecil.Mdb.dll
    Mono.Touch.Client.dll
    Mono.Touch.Common.dll
    monotouch.dll
    MonoTouch.Linker.dll
    [处理]后的 mtouch.exe

    到/Developer/MonoTouch/usr/bin/

    因为MonoDevelop.IPhone这个MonoDevelop插件在项目编译时调用的是没有exe后缀的那个打包后的Mac原生程序,得让他执行我们的exe,在

    /Developer/MonoTouch/usr/bin/

    建立名为mtouch的bash脚本,替代原来的mtouch,内容如下:

    #!/bin/sh
    # by BinSsy
     
    DIR=$(cd "$(dirname "$0")"; pwd)
    MONO_FRAMEWORK_PATH=/Library/Frameworks/Mono.framework/Versions/Current
    export DYLD_FALLBACK_LIBRARY_PATH="$DIR:$MONO_FRAMEWORK_PATH/lib:/lib:/usr/lib"
    export PATH="$MONO_FRAMEWORK_PATH/bin:$PATH"
    
    #Start mtouch.exe with args
    
    mono "$DIR/mtouch.exe" "$@"

    ok再次编译通过,现在我们改成非模拟器编译,报错

    No valid iPhone code signing keys found in keychain.

    看来涉及签名啊,最终通过查看MonoDevelop.IPhone这个插件代码,发现成功编译需要有开发者证书这个证书的名称必须类似是

    iPhone Developer: BinSys (822ED3R5M7)

    这样以iPhone Developer开头的,按照http://hi.baidu.com/lyugb/item/87f2a0ec0a11ae3b86d9ded1教程建立一个证书,导出成p12文件,稍后在windows下要用

    还有一个放在路径 ~/Library/MobileDevice/Provisioning Profiles/ 里面的以.mobileprovision结尾的设备预置配置文件。这个文件是个pkcs#7消息信封,

    被苹果一个证书签名的,具体格式信息是在

    http://stackoverflow.com/questions/3426467/how-to-determine-at-run-time-if-app-is-for-development-app-store-or-ad-hoc-dist/9874866#9874866

    签名前的内容是个xml文件,如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
        <dict>
            <!--苹果分配,用于保证应用包的唯一性,测试的可随便填写等长的-->
            <key>ApplicationIdentifierPrefix</key>
            <array>
                <string>3NZS985WC5</string>
            </array>
            <!--文件建立日期  UTC时间-->
            <key>CreationDate</key>
            <date>2011-01-20T06:31:45Z</date>
            <!--开发者证书公钥,二进制的东西,可以提取二进制保存成.cer文件,这个和之前建立的开发者证书必须一样-->
            <key>DeveloperCertificates</key>
            <array>
                <data>
                    MIIFZzCCBE+gAwIBAgIICD+6XPu04HUwDQYJKoZIhvcNAQEFBQAwgZYxCzAJ
                    BgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSwwKgYDVQQLDCNBcHBs
                    ZSBXb3JsZHdpZGUgRGV2ZWxvcGVyIFJlbGF0aW9uczFEMEIGA1UEAww7QXBw
                    bGUgV29ybGR3aWRlIERldmVsb3BlciBSZWxhdGlvbnMgQ2VydGlmaWNhdGlv
                    biBBdXRob3JpdHkwHhcNMTEwMTIwMDYyMTQxWhcNMTIwMTIwMDYyMTQxWjBb
                    MRowGAYKCZImiZPyLGQBAQwKOTNFQTlMNDI5SjEwMC4GA1UEAwwnaVBob25l
                    IERldmVsb3BlcjogU3VuIFBlbmcgKDgyMkVEM1I1TTcpMQswCQYDVQQGEwJD
                    TjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJv6G9Q1VS+obG9S
                    MeLRMkPHfv+jh05P98uIO+uyuOFU5bDDQYAgZLr2qcO90m4KTfwLT/PAbnTy
                    PzHYfahTwotyk6yKJrKc+SMVND7MswPVZmHlfnjMWo3C5sVA0ED7PdGPC/eG
                    diUPtUBv/08dDjgNmcCuPouqv37JEsh1wfDxsr9SEVBXpSCtuccZbE5EOjJd
                    i20AYLH5zpBybvpRXKfFAqU66qIw4iKVzGd0kH+7QOa1t+Q/QuPiOyci4RVL
                    FBbPz5MKBwZfMM4TVzy5Zx9vRxtLOabpcXJByEfBzsSowtPAZX6GP8uwqLK8
                    Of+KQOKSR5pbm+czi8vB2eBzAR8CAwEAAaOCAfEwggHtMB0GA1UdDgQWBBTc
                    Z9iLUFFoFqjbwp0WDLo4n3sInjAMBgNVHRMBAf8EAjAAMB8GA1UdIwQYMBaA
                    FIgnFwmpthhgi+zruvZHWcVSVKO3MIIBDwYDVR0gBIIBBjCCAQIwgf8GCSqG
                    SIb3Y2QFATCB8TCBwwYIKwYBBQUHAgIwgbYMgbNSZWxpYW5jZSBvbiB0aGlz
                    IGNlcnRpZmljYXRlIGJ5IGFueSBwYXJ0eSBhc3N1bWVzIGFjY2VwdGFuY2Ug
                    b2YgdGhlIHRoZW4gYXBwbGljYWJsZSBzdGFuZGFyZCB0ZXJtcyBhbmQgY29u
                    ZGl0aW9ucyBvZiB1c2UsIGNlcnRpZmljYXRlIHBvbGljeSBhbmQgY2VydGlm
                    aWNhdGlvbiBwcmFjdGljZSBzdGF0ZW1lbnRzLjApBggrBgEFBQcCARYdaHR0
                    cDovL3d3dy5hcHBsZS5jb20vYXBwbGVjYS8wTQYDVR0fBEYwRDBCoECgPoY8
                    aHR0cDovL2RldmVsb3Blci5hcHBsZS5jb20vY2VydGlmaWNhdGlvbmF1dGhv
                    cml0eS93d2RyY2EuY3JsMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAK
                    BggrBgEFBQcDAzATBgoqhkiG92NkBgECAQH/BAIFADANBgkqhkiG9w0BAQUF
                    AAOCAQEAAmwcHIVQCv0+oUU2MBMzVYFG0U+dCKgSzpM6FER/ysuzQeqVoTSl
                    KflbfVCIVdb6uIOFHymxfv50yyiV6zRF3Y59NuTUaln+Q/wec+OuwxHxMWab
                    NA/mAitotXKfRCAI9ZZyA84dVOuJmEFn6txcNSmiGczuRBAHltwVBrRDU/fj
                    +Bj8RWSyYQajFxm+7wGqDl6jKttNuG1vYPWis4+3mDFRoXBRwX4kpPJtIbn9
                    P0Xv16gBNiJ3B5LBk9DlRsNK/NOLmNlPpRi8NBAtXOeaK+t/UDvnVnX3Xu9Q
                    fyRynjHckY5L4wpLOt7xDZgUS5VBEh7u2+AqYjSvL+OLc9yHjg==
                </data>
            </array>
            <!--应用的权利限制,保持默认吧-->
            <key>Entitlements</key>
            <dict>
                <key>application-identifier</key>
                <string>3NZS985WC5.*</string>
                <key>get-task-allow</key>
                <true/>
                <key>keychain-access-groups</key>
                <array>
                    <string>3NZS985WC5.*</string>
                </array>
            </dict>
            <!--过期日期,这个必须保证没有过期,否则MonoDevelop的iPhone插件不认 UTC时间-->
            <key>ExpirationDate</key>
            <date>2011-04-20T06:31:45Z</date>
    
            <!--配置的名称,自己起一个-->
            <key>Name</key>
            <string>Example Provision</string>
    
            <!--这个就是设备的UDID列表,如果这个是正规从Apple下载的文件,下面就是你的测试设备的UDID-->
            <key>ProvisionedDevices</key>
            <array>
                <string>f9d82b1e14a7becc39cf468a3744d2d927c64ac8</string>
            </array>
            
            <!--此处注意,应该是iOS新特性,网上能找到的所有预置配置文件都无此项,导致新版monotouch MonoDevelop 的 iPhone插件编译异常 空引用异常-->
            <key>TeamIdentifier</key>
            <array>
                <string>3NZS985WC5</string>
            </array>
            
            <!--用途未知-->
            <key>TimeToLive</key>
            <integer>90</integer>
    
            <!--配置文件唯一标识,随机guid-->
            <key>UUID</key>
            <string>8C9691AC-9ABD-49CD-A69A-0DB86319615B</string>
    
            <!--固定-->
            <key>Version</key>
            <integer>1</integer>
        </dict>
    </plist>


    这个文件正规来说是从Apple的开发者计划的页面下载的,但我现在没有开发者帐号,所以自己产生一个,包上面xml保存成utf8编码的xml文件,然后下面代码:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Security.Cryptography.Pkcs;
    using System.Security.Cryptography.X509Certificates;
    using MonoDevelop.MacDev.Plist;
    using System.Xml;
    
    namespace makemp
    {
        class Program
        {
            static void Main(string[] args)
            {
                //从MAC导出的证书文件 和导出时设置的密码
                X509Certificate2 signgercert = new X509Certificate2(@"my.p12", "*****");
    
    
                PlistDocument pd = new PlistDocument();
                
                //模版文件
                pd.LoadFromXmlFile(@"mobileprovision_Template.xml");
    
                //ApplicationIdentifierPrefix
                PlistDictionary root_dic = pd.Root as PlistDictionary;
                //PlistArray ApplicationIdentifierPrefix_s = root_dic["ApplicationIdentifierPrefix"] as PlistArray;
                //PlistString ApplicationIdentifierPrefix_1 = ApplicationIdentifierPrefix_s.Value.FirstOrDefault() as PlistString;
                //ApplicationIdentifierPrefix_1.Value = "123456789";
    
    
                //CreationDate
                PlistDate CreationDate = root_dic["CreationDate"] as PlistDate;
                CreationDate.Value = DateTime.Now;
    
    
                //DeveloperCertificates
                PlistArray DeveloperCertificates_s = root_dic["DeveloperCertificates"] as PlistArray;
                PlistData DeveloperCertificates_1 = DeveloperCertificates_s.Value.FirstOrDefault() as PlistData;
    
                DeveloperCertificates_1.Value = signgercert.Export(X509ContentType.Cert);
                
                //Entitlements
    
                //ExpirationDate
                PlistDate ExpirationDate = root_dic["ExpirationDate"] as PlistDate;
                ExpirationDate.Value = DateTime.Now.AddYears(10);
    
                //Name
                PlistString Name = root_dic["Name"] as PlistString;
                Name.Value = "TestApp";
    
    
                //ProvisionedDevices
                PlistArray ProvisionedDevices_s = root_dic["ProvisionedDevices"] as PlistArray;
                PlistString ProvisionedDevices_1 = ProvisionedDevices_s.Value.FirstOrDefault() as PlistString;
                ProvisionedDevices_1.Value = "e5fb5e41110b57ad370e0725610b7a9ba31df40e";
    
                //UUID
                PlistString UUID = root_dic["UUID"] as PlistString;
                UUID.Value = Guid.NewGuid().ToString().ToUpper();
    
    
                //pd.WriteToFile("aa.xml");
    
                MemoryStream ms = new MemoryStream();
                using (XmlTextWriter xmlTextWriter = new XmlTextWriter(ms, UpperCaseUTF8Encoding.UpperCaseUTF8))
                {
                    xmlTextWriter.Indentation = 1;
                    xmlTextWriter.IndentChar = '\t';
                    xmlTextWriter.Formatting = Formatting.Indented;
                    pd.Write(xmlTextWriter);
                }
    
    
                File.WriteAllBytes("my.mobileprovision", Encode(Encoding.UTF8.GetString(ms.GetBuffer()), signgercert));
    
    
            }
    
    
    
    
            static string Decode(byte[] bytes)
            {
                SignedCms sc = new SignedCms();
                sc.Decode(bytes);
                //foreach (X509Certificate2 cert in sc.Certificates)
                //{
                //    Console.WriteLine(cert.Thumbprint);
                //    File.WriteAllBytes(string.Format("Thumbprint_{0}.cer", cert.Thumbprint), cert.Export(X509ContentType.Cert));
                //}
    
                return Encoding.UTF8.GetString(sc.ContentInfo.Content);
            }
    
    
            static byte[] Encode(string source, X509Certificate2 cert)
            {
                byte[] sourceBytes = Encoding.UTF8.GetBytes(source);
                CmsSigner cs = new CmsSigner(cert);
                cs.IncludeOption = X509IncludeOption.WholeChain;
                ContentInfo ci = new ContentInfo(sourceBytes);
                SignedCms sc2 = new SignedCms(ci, false);
                sc2.ComputeSignature(cs);
                return sc2.Encode();
            }
        }
    }

    详细代码本文后边有打包。那个证书是从mac导出的。

    这样生成了与我们自己的开发者证书想对应的.mobileprovision文件,把他放到

     ~/Library/MobileDevice/Provisioning Profiles/

    目录里。

    真机编译,如下:

    Building: tt1 (Debug|iPhone)
    
    Detecting signing identity...
    Provisioning profile: "TestApp" (07BBFA54-544E-4BB3-83A5-0C5832E25285)
    Signing Identity: "iPhone Developer: BinSys (822ED3R5M7)"
    App ID: "3NZS985WC5.tt1"
    Performing main compilation...
    /Developer/MonoTouch/usr/bin/smcs /noconfig "/out:/Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.exe" "/r:/Developer/MonoTouch/usr/lib/mono/2.1/System.dll" "/r:/Developer/MonoTouch/usr/lib/mono/2.1/System.Xml.dll" "/r:/Developer/MonoTouch/usr/lib/mono/2.1/System.Core.dll" "/r:/Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll" /nologo /warn:4 /debug:full /optimize- /codepage:utf8 "/define:DEBUG"  /t:exe "/Users/binsys/Projects/tt1/tt1/Main.cs" "/Users/binsys/Projects/tt1/tt1/AppDelegate.cs" "/Users/binsys/Projects/tt1/tt1/tt1ViewController.cs" "/Users/binsys/Projects/tt1/tt1/tt1ViewController.designer.cs" 
    Compilation succeeded - 3 warning(s)
    
    /Users/binsys/Projects/tt1/tt1/tt1ViewController.cs(30,38): warning CS0672: Member `tt1.tt1ViewController.ViewDidUnload()' overrides obsolete member `MonoTouch.UIKit.UIViewController.ViewDidUnload()'. Add the Obsolete attribute to `tt1.tt1ViewController.ViewDidUnload()'
    /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll (Location of the symbol related to previous warning)
    /Users/binsys/Projects/tt1/tt1/tt1ViewController.cs(42,38): warning CS0672: Member `tt1.tt1ViewController.ShouldAutorotateToInterfaceOrientation(MonoTouch.UIKit.UIInterfaceOrientation)' overrides obsolete member `MonoTouch.UIKit.UIViewController.ShouldAutorotateToInterfaceOrientation(MonoTouch.UIKit.UIInterfaceOrientation)'. Add the Obsolete attribute to `tt1.tt1ViewController.ShouldAutorotateToInterfaceOrientation(MonoTouch.UIKit.UIInterfaceOrientation)'
    /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll (Location of the symbol related to previous warning)
    /Users/binsys/Projects/tt1/tt1/tt1ViewController.cs(32,30): warning CS0618: `MonoTouch.UIKit.UIViewController.ViewDidUnload()' is obsolete: `Deprecated in iOS 6.0'
    
    
    
    Compiling interface definitions
    /Applications/Xcode.app/Contents/Developer/usr/bin/ibtool --errors --warnings --notices --output-format human-readable-text --compile "/Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/tt1ViewController.nib" "/Users/binsys/Projects/tt1/tt1/tt1ViewController.xib" --sdk "/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk"
    2012-11-29 15:27:41.683 Interface Builder Cocoa Touch Tool[345:14603] CFPreferences: user home directory at file://localhost/Users/binsys/Library/Application%20Support/iPhone%20Simulator/User/ is unavailable. User domains will be volatile.
    构建完成 --0 个错误, 3 个警告
    
    Compiling to native code
    /Developer/MonoTouch/usr/bin/mtouch -sdkroot "/Applications/Xcode.app/Contents/Developer" -v --cache "/Users/binsys/Projects/tt1/tt1/obj/Debug/mtouch-cache" --nomanifest --nosign -dev "/Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app" -r "/Developer/MonoTouch/usr/lib/mono/2.1/System.dll" -r "/Developer/MonoTouch/usr/lib/mono/2.1/System.Xml.dll" -r "/Developer/MonoTouch/usr/lib/mono/2.1/System.Core.dll" -r "/Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll" -debug -profiling -linksdkonly -sdk "6.0" --abi=armv7 "/Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.exe"
    MonoTouch version 6.0.6 using framework: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.0.sdk
    Copied /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.exe to /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/tt1.exe
    Copied /Developer/MonoTouch/usr/lib/mono/2.1/mscorlib.dll to /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/mscorlib.dll
    Copied /Developer/MonoTouch/usr/lib/mono/2.1/monotouch.dll to /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/monotouch.dll
    Copied /Developer/MonoTouch/usr/lib/mono/2.1/System.Core.dll to /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/System.Core.dll
    Copied /Developer/MonoTouch/usr/lib/mono/2.1/System.dll to /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/System.dll
    Copied /Developer/MonoTouch/usr/lib/mono/2.1/Mono.Security.dll to /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/Mono.Security.dll
    Copied /Developer/MonoTouch/usr/lib/mono/2.1/System.Xml.dll to /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/System.Xml.dll
    Linking SDK only for assembly /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.exe into /Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app
    MONO_PATH=/Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app /Developer/MonoTouch/usr/bin/arm-darwin-mono --debug --aot=mtriple=armv7-darwin,full,static,asmonly,direct-icalls,no-direct-calls,iphone-abi,outfile=/var/folders/gn/rs7j2w411rqc159nhqc2rddc0000gn/T/tmp6163d343.tmp/System.Core.dll.armv7.s "/Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/System.Core.dll"
    AOT Compilation exited with code 4, command:
    MONO_PATH=/Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app /Developer/MonoTouch/usr/bin/arm-darwin-mono --debug --aot=mtriple=armv7-darwin,full,static,asmonly,direct-icalls,no-direct-calls,iphone-abi,outfile=/var/folders/gn/rs7j2w411rqc159nhqc2rddc0000gn/T/tmp6163d343.tmp/System.Core.dll.armv7.s "/Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/System.Core.dll"
    MonoTouch license could not be found.  Please activate your MonoTouch installation.
    
    error MT3001: Could not AOT the assembly '/Users/binsys/Projects/tt1/tt1/bin/iPhone/Debug/tt1.app/System.Core.dll'
    
    ---------------------- 完成 ----------------------
    
    Project does not have bundle identifier specified. Generated 'tt1' to match an installed provisioning profile.
    构建:1 个错误, 4 个警告

     编译出错。估计拉下哪个文件没[处理],看MonoDevelop.IPhone代码,可以知道其根据编译参数调用了/Developer/MonoTouch/usr/bin/目录下的arm-darwin-mono和arm-darwin-mono-sgen这两个原生苹果程序。全是Native代码,没发现什么经过打包的痕迹。

    嗯,因为看编译选项发现我们没有选中sgen这个垃圾回收器,所以这此编译调用的应该是arm-darwin-mono这个AOT编译器,用IDA打开等待分析完毕(文件大,有点儿慢)

    发现验证授权时打开了~/Library/MonoTouch/License.v2 这个文件,看了下,也是验证了RSA sha1签名,我们通过把三个在破解领域爆破方法里的关键跳jnz改成nop,(arm-darwin-mono-sgen 同样处理)并伪造一个特定格式的 License.v2文件,这个格式是一个全0的二进制文件,长度为60+N+1+128,60字节是三个长度为20的hash,N任意,1为一个特定值,必须大于1,后边128字节为一个二进制文件被1024位rsa key用sha1算法签名后产生的签名指纹的数据长度,128字节,我么写全0吧。这样把这个文件放到指定目录,把在windows里修改过的两个程序放到mac替换原来的,编译。。。。。各种通过,各种ipa都产生了,剩下的就是把ipa放到越狱的设备里了,进行性能测试。

    这个授权文件格式如下:

    View Code
    string IOPlatformSerialNumber = "VMWVk3P/wPmJkRIwb5ycu1EQw";
    string IOMACAddress = "00:0c:29:ed:44:43";
    
    
    GetLicense(Salt, IOPlatformSerialNumber, IOMACAddress);
    
    
    private static void GetLicense(byte[] salt, string IOPlatformSerialNumber, string IOMACAddress)
    {
        byte[] IOPlatformSerialNumber_Bytes = System.Text.Encoding.UTF8.GetBytes(IOPlatformSerialNumber);
        byte[] IOMACAddress_Bytes = System.Text.Encoding.UTF8.GetBytes(IOMACAddress);
        System.IO.MemoryStream ms = new System.IO.MemoryStream(IOPlatformSerialNumber_Bytes.Length + IOMACAddress_Bytes.Length + salt.Length);
        System.Security.Cryptography.HashAlgorithm alg = System.Security.Cryptography.SHA1.Create();
        byte[] hash1 = GetHash(alg, ms, IOPlatformSerialNumber_Bytes, IOMACAddress_Bytes, salt);
        byte[] hash2 = GetHash(alg, ms, IOPlatformSerialNumber_Bytes, salt, IOMACAddress_Bytes);
        byte[] hash3 = GetHash(alg, ms, salt, IOPlatformSerialNumber_Bytes, IOMACAddress_Bytes);
    
    
        byte[] LicenseHashs = new byte[60];
    
    
        
        Array.Copy(hash1, 00, LicenseHashs, 00, 5);
        Array.Copy(hash2, 00, LicenseHashs, 05, 5);
        Array.Copy(hash3, 00, LicenseHashs, 10, 5);
    
        Array.Copy(hash1, 05, LicenseHashs, 15, 5);
        Array.Copy(hash2, 05, LicenseHashs, 20, 5);
        Array.Copy(hash3, 05, LicenseHashs, 25, 5);
    
        Array.Copy(hash1, 10, LicenseHashs, 30, 5);
        Array.Copy(hash2, 10, LicenseHashs, 35, 5);
        Array.Copy(hash3, 10, LicenseHashs, 40, 5);
    
        Array.Copy(hash1, 15, LicenseHashs, 45, 5);
        Array.Copy(hash2, 15, LicenseHashs, 50, 5);
        Array.Copy(hash3, 15, LicenseHashs, 55, 5);
        
    
    
        byte[] bytesPadding = new byte[400];
    
        for (int index = 0; index < 400; index++)
        {
            bytesPadding[index] = 6;
        }
    
    
        byte[] ret;
        using (MemoryStream msff = new MemoryStream())
        {
            msff.Write(LicenseHashs, 0, LicenseHashs.Length);
            msff.Write(bytesPadding, 0, bytesPadding.Length);
            ret = msff.GetBuffer();
            msff.Close();
        }
    
        File.WriteAllBytes("License.v2", ret);
    
    }
    
    private static byte[] GetHash(System.Security.Cryptography.HashAlgorithm alg, System.IO.MemoryStream ms, byte[] b1, byte[] b2, byte[] b3)
    {
        ms.Position = 0L;
        ms.SetLength(0L);
        ms.Write(b1, 0, b1.Length);
        ms.Write(b2, 0, b2.Length);
        ms.Write(b3, 0, b3.Length);
        return alg.ComputeHash(ms.GetBuffer(), 0, (int)ms.Length);
    }

    至于这个 Salt这个数组,大家动手去找吧,自己动手丰衣足食嘛。。。嘿嘿, 就在mtouch那几个程序集里,是常量,我就不提供了,省的影响较大然后出事儿。 真心想用的不差这几步,看看就走的就别试了,整的乱飞就不好了。

    注意,arm-darwin-mono和sgen这两个原生程序只验证了授权文件的前60个字节和授权文件从后向前数第128个字节大于0, 没有检查这个授权文件的数字签名,所以我们省事了,而mtouch这个验证了数字签名,所以呢,咱得处理它,把数字签名验证相关咔嚓掉。

    下一篇继续开始测试之旅。

    附件:

    https://files.cnblogs.com/binsys/20121129_MonoTouchCrack.7z

  • 相关阅读:
    vuex2 mapActions 报错 `unknown action type: xxxx`
    IE报vuex requires a Promise polyfill in this browser问题解决
    vue路由懒加载
    vue-router各个属性的作用及用法
    JS实现继承的几种方法
    ES6学习笔记--promise对象
    jQuery--data()方法
    原生js实现二级联动下拉列表菜单
    sql server中部分函数功能详解
    js中字符串转换为数值的两种方法的区别
  • 原文地址:https://www.cnblogs.com/binsys/p/2794800.html
Copyright © 2011-2022 走看看