冰河 发表于 2013-1-27 21:22:17

Windows 8应用商店付费软件的破解

[开头说几句]
看本帖之前先要对win8进行越狱(我之前的帖子:http://bbs.cnhonker.com/forum.php?mod=viewthread&tid=8221&extra=page%3D1),本来越狱的目的只是为了获取完全的控制权,并不是为了破解付费软件,但考虑到我国的国情,还是研究一下吧,本文还是站在前人的肩膀上完成的,感谢kost的努力。
[原理]
win8应用商店的很多软件都要付费,且要使用信用卡购买,但微软并未把穷人的路封死,它为软件开发者提供了颁发OEM批量许可的方式,但仅限于支持sideloading的计算机上安装,所以我们需要先越狱,这个办法的前提是要破解的应用需要提供试用版,如图中例子所示:


应用商店的所有许可证均保存在C:\Windows\ServiceProfiles\LocalService\AppData\Local\Microsoft\WSLicense\tokens.dat文件中。
具体过程是:先下载好试用版,然后将其license从tokens.dat中读取出来,将其中的软件信息替换为OEM版本,再添加数字签名,最后将其重新写入,如下图所示:


再打开应用,已经变成了正式版。

[具体过程]
1. 读取license
tokens.dat并非文本文件,license以byte形式存储,kost提供了一个函数ReadTokens用来读取,我做了修改:
..........
private static bool ReadTokens(string appID,Boolean isALL){//appID就是应用的产品ID号,isALL为true时可输出查看所有已安装应用的appID。
//isALL为false时,以appID为参数传入。
      try
            {
                byte[] Tokens;
                string TokensFileName;
               TokensFileName = Environment.GetEnvironmentVariable("SystemRoot") +
                  "\\ServiceProfiles\\LocalService\\AppData\\Local\\Microsoft\\WSLicense\\tokens.dat";
                Tokens = File.ReadAllBytes(TokensFileName);
                byte[] LicenseStartPattern = Encoding.ASCII.GetBytes("<License");
                byte[] LicenseEndPattern = Encoding.ASCII.GetBytes("</License>");
                for (int pos = 0, pos_end; ; )//以"<License“为关键字循环读取
         {
                  pos = BinIndexOf(Tokens, LicenseStartPattern, pos);
                  if (pos < 0) break;
                  pos_end = BinIndexOf(Tokens, LicenseEndPattern, pos + 1);
                  if (pos_end < 0) break;
                  pos_end += LicenseEndPattern.Length;
                  XmlDocument x = new XmlDocument();
                  x.PreserveWhitespace = true;
                  try
                  {//将读取到的数据写入xml中
               x.InnerXml = Encoding.ASCII.GetString(Tokens, pos, pos_end - pos);
                        XmlNode nodeRoot = x.FirstChild;
                        XmlNode nodeBinding = nodeRoot["Binding"];
                        XmlNode nodePFM = nodeBinding["PFM"];
                        if (isALL)//如果isALL为true,输出所有产品ID信息
               {
                            Console.WriteLine(nodePFM.InnerText);
                        }
                        else //否则将传入 appID指向的应用许可证保存为tokens.xml临时文件
                        {
                            if (nodePFM.InnerText == appID)
                            {
                              File.WriteAllText(Environment.GetEnvironmentVariable("TEMP")+"\\tokens.xml", x.InnerXml, Encoding.UTF8);
                            }
                        }
                  }
                  catch (Exception)
                  {
                        pos_end = pos + 1;
                  }
                        pos = pos_end;
                }
            }
            catch (Exception ex)
            {
               Console.WriteLine("ReadTokens " + ex.Message);
                return false;
            }
            return true;
      }
2.将读取到的license转换为OEM:

首先需要一个空白的license框架,以填充内容:
<License Version="1" Source="OEM" xmlns="urn:schemas-microsoft-com:windows:store:licensing:ls">
<Binding Binding_Type="Machine">
<ProductID></ProductID>
<PFM></PFM></Binding>
<LicenseInfo Type="Full">
<IssuedDate></IssuedDate>
<LastUpdateDate></LastUpdateDate>
</LicenseInfo>
</License>
................
private static xmlClass READ_LIC,WRITE_OEM; //xmlClass为事先写好的xml操作类,由于license文件带有命名空间,故要先进行定义。
private static string LIC_PRODUCTID,LIC_PFM;
private static string LIC_NAMESPACE = "urn:schemas-microsoft-com:windows:store:licensing:ls";//命名空间
....................
      private static XmlDocument ConvertLicToOEM(string Lic)//Lic为为tokens.xml临时文件的完整路径
      {
            try
            {
                READ_LIC = new xmlClass(Lic, LIC_NAMESPACE);
                WRITE_OEM = new xmlClass("lictemp.xml", LIC_NAMESPACE);//准备向lictemp.xml框架文件写入数据
          LIC_PRODUCTID = READ_LIC.getNodeWithNameSpace(@"/root:License/root:Binding/root:ProductID");//从tokens.xml临时文件读取ProductID和PFM
                LIC_PFM = READ_LIC.getNodeWithNameSpace(@"/root:License/root:Binding/root:PFM");
                WRITE_OEM.setNodeWithNameSpace(@"/root:License/root:Binding/root:ProductID", LIC_PRODUCTID);
                WRITE_OEM.setNodeWithNameSpace(@"/root:License/root:Binding/root:PFM", LIC_PFM);
                WRITE_OEM.setNodeWithNameSpace(@"/root:License/root:LicenseInfo/root:IssuedDate", "2022-11-01T14:25:14Z");
                WRITE_OEM.setNodeWithNameSpace(@"/root:License/root:LicenseInfo/root:LastUpdateDate", "2022-11-01T14:25:14Z");//这两个日期为随机
          WRITE_OEM.Save();

                XmlDocument XMLLIC = new XmlDocument();
                XMLLIC.Load("lictemp.xml");
                SignXml(XMLLIC);//下一步,对license 进行数字签名
                return XMLLIC;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                return null;
            }
      }
3.进行数字签名
对商店付费应用的app签名,必须使用RSA-SHA256算法,.net framework中没有,微软提供了一个补充类RSAPKCS1SHA256SignatureDescription的源码,包含在Security.Cryptography命名空间。
         .....................
            SignedXml signedXml = new SignedXml(xmlDoc);//创建SignedXml对象
            signedXml.SigningKey = key;//设置密钥
            signedXml.SignedInfo.CanonicalizationMethod = "http://www.w3.org/2001/10/xml-exc-c14n#";
            signedXml.SignedInfo.SignatureMethod = @http://www.w3.org/2001/04/xmldsig-more#rsa-sha256;//规范算法信息
            Reference reference = new Reference();//定义Reference元素
            reference.DigestMethod = @"http://www.w3.org/2001/04/xmlenc#sha256";//设置标识符
            reference.Uri = "";
            XmlDsigEnvelopedSignatureTransform env = new XmlDsigEnvelopedSignatureTransform();//封装签名转换
            reference.AddTransform(env);
            signedXml.AddReference(reference);
            signedXml.ComputeSignature();//计算数字签名

            XmlElement xmlDigitalSignature = signedXml.GetXml();
            xmlDoc.DocumentElement.AppendChild(xmlDoc.ImportNode(xmlDigitalSignature, true));//为xml添加签名信息
            xmlDoc.Save("lictemp.xml");
.................................

                                                                                                                                                                                                                   转载与:b41k3r
页: [1]
查看完整版本: Windows 8应用商店付费软件的破解