上期分享了actconfigid hook dll 提取,这期分析xml构建
csharp
private const string AtoReqTemplate = @"<?xml version=""1.0"" encoding=""utf-8""?>
<soap:Envelope
xmlns:soapenc=""http://schemas.xmlsoap.org/soap/encoding/""
xmlns:soap=""http://schemas.xmlsoap.org/soap/envelope/""
xmlns:xsd=""http://www.w3.org/2001/XMLSchema""
xmlns:xsi=""http://www.w3.org/2001/XMLSchema-instance"">
<soap:Body>
<RequestSecurityToken
xmlns=""http://schemas.xmlsoap.org/ws/2004/04/security/trust"">
<TokenType>ProductActivation</TokenType>
<RequestType>http://schemas.xmlsoap.org/ws/2004/04/security/trust/Issue</RequestType>
<UseKey>
<Values
xmlns:q1=""http://schemas.xmlsoap.org/ws/2004/04/security/trust"" soapenc:arrayType=""q1:TokenEntry[1]"">
<TokenEntry>
<Name>PublishLicense</Name>
<Value>{plxml}</Value>
</TokenEntry>
</Values>
</UseKey>
<Claims>
<Values
xmlns:q1=""http://schemas.xmlsoap.org/ws/2004/04/security/trust"" soapenc:arrayType=""q1:TokenEntry[14]"">
<TokenEntry>
<Name>BindingType</Name>
<Value>msft:rm/algorithm/hwid/4.0</Value>
</TokenEntry>
<TokenEntry>
<Name>Binding</Name>
<Value>{binding}</Value>
</TokenEntry>
<TokenEntry>
<Name>ProductKey</Name>
<Value>{pkey}</Value>
</TokenEntry>
<TokenEntry>
<Name>ProductKeyType</Name>
<Value>msft:rm/algorithm/pkey/2009</Value>
</TokenEntry>
<TokenEntry>
<Name>ProductKeyActConfigId</Name>
<Value>{act_config_id}</Value>
</TokenEntry>
<TokenEntry>
<Name>otherInfoPublic.licenseCategory</Name>
<Value>msft:sl/EUL/ACTIVATED/PUBLIC</Value>
</TokenEntry>
<TokenEntry>
<Name>otherInfoPrivate.licenseCategory</Name>
<Value>msft:sl/EUL/ACTIVATED/PRIVATE</Value>
</TokenEntry>
<TokenEntry>
<Name>otherInfoPublic.sysprepAction</Name>
<Value>rearm</Value>
</TokenEntry>
<TokenEntry>
<Name>otherInfoPrivate.sysprepAction</Name>
<Value>rearm</Value>
</TokenEntry>
<TokenEntry>
<Name>ClientInformation</Name>
<Value>SystemUILanguageId=1033;UserUILanguageId=1033;GeoId=244</Value>
</TokenEntry>
<TokenEntry>
<Name>ClientSystemTime</Name>
<Value>{systime}</Value>
</TokenEntry>
<TokenEntry>
<Name>ClientSystemTimeUtc</Name>
<Value>{utctime}</Value>
</TokenEntry>
<TokenEntry>
<Name>otherInfoPublic.secureStoreId</Name>
<Value>{secure_store_id}</Value>
</TokenEntry>
<TokenEntry>
<Name>otherInfoPrivate.secureStoreId</Name>
<Value>{secure_store_id}</Value>
</TokenEntry>
</Values>
</Claims>
</RequestSecurityToken>
</soap:Body>
</soap:Envelope>";
var actConfigId = Utils.XmlEscape($"actConfigId_byhook"); //我们hook到的那串字符串
var ProductKeyType = string.IsNullOrEmpty(actConfigId)? "msft:rm/algorithm/pkey/2009" : actConfigId.Contains("2009")? "msft:rm/algorithm/pkey/2009":"msft:rm/algorithm/pkey/2005";
var now = DateTime.Now;
var timestamp = Utils.FormatTimestamp(now);
var secureStoreId = Guid.NewGuid().ToString();
var binding = Utils.GenerateBinding();
// 检查 PL 是否已经转义过
string processedPl;
if (plXmlPublishLicense.StartsWith("<"))
{
// 如果已经转义过,直接使用,不要再调用 XmlEscape
processedPl = plXmlPublishLicense;
}
else
{
// 如果是原始 XML,则进行转义
processedPl = Utils.XmlEscape(plXmlPublishLicense);
}
var payload = AtoReqTemplate
.Replace("{plxml}", processedPl) //PublishLicense xml , 自己实机测试个密钥抓包提取,可采用固定值,注意同时配合服务器接口
.Replace("{binding}", binding) //硬件信息,可固定也可随机
.Replace("{pkey}", pkey) //密钥
.Replace("{act_config_id}", actConfigId) //我们hook到的那串字符串
.Replace("{systime}", timestamp) //本地时间(ISO 8601格式,带Z标识)
.Replace("{utctime}", timestamp) //utc时间(ISO 8601格式,带Z标识)
.Replace("{secure_store_id}", secureStoreId); //guid
.Replace("{ProductKeyType}", ProductKeyType); //actconfigid 类型2009或2005
// httpclient 请求接口和 请求参数,自己抓包
//随机硬件
public static string GenerateBinding()
{
// 16进制转字节数组
var fixedBytes = HexStringToBytes("2A0000000100020001000100000000000000010001000100");
// 生成18位随机字节(.NET 4.8 写法)
var randomBytes = new byte[18];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(randomBytes);
}
// 拼接固定字节和随机字节
var binding = new byte[fixedBytes.Length + randomBytes.Length];
Buffer.BlockCopy(fixedBytes, 0, binding, 0, fixedBytes.Length);
Buffer.BlockCopy(randomBytes, 0, binding, fixedBytes.Length, randomBytes.Length);
return Convert.ToBase64String(binding);
}