BIN
Images/logo.png
Normal file
|
After Width: | Height: | Size: 27 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
|
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 9.5 KiB |
BIN
Images/screenshot.v0.4.png
Normal file
|
After Width: | Height: | Size: 7.0 KiB |
BIN
Images/screenshot.v0.5.png
Normal file
|
After Width: | Height: | Size: 9.8 KiB |
BIN
Images/wiki/qq/1.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
Images/wiki/qq/10.png
Normal file
|
After Width: | Height: | Size: 167 KiB |
BIN
Images/wiki/qq/11.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
Images/wiki/qq/12.png
Normal file
|
After Width: | Height: | Size: 161 KiB |
BIN
Images/wiki/qq/13.png
Normal file
|
After Width: | Height: | Size: 151 KiB |
BIN
Images/wiki/qq/2.png
Normal file
|
After Width: | Height: | Size: 47 KiB |
BIN
Images/wiki/qq/3.png
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
Images/wiki/qq/4.png
Normal file
|
After Width: | Height: | Size: 154 KiB |
BIN
Images/wiki/qq/5.png
Normal file
|
After Width: | Height: | Size: 49 KiB |
BIN
Images/wiki/qq/6.png
Normal file
|
After Width: | Height: | Size: 165 KiB |
BIN
Images/wiki/qq/7.png
Normal file
|
After Width: | Height: | Size: 162 KiB |
BIN
Images/wiki/qq/8.png
Normal file
|
After Width: | Height: | Size: 161 KiB |
BIN
Images/wiki/qq/9.png
Normal file
|
After Width: | Height: | Size: 53 KiB |
BIN
Images/wiki/wechat/10_mutex.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
Images/wiki/wechat/11_push_ebp_to_ret.png
Normal file
|
After Width: | Height: | Size: 148 KiB |
BIN
Images/wiki/wechat/12_push_ebp_to_ret.png
Normal file
|
After Width: | Height: | Size: 142 KiB |
BIN
Images/wiki/wechat/13_push_ebp_to_ret.png
Normal file
|
After Width: | Height: | Size: 144 KiB |
BIN
Images/wiki/wechat/14_patch_dll.png
Normal file
|
After Width: | Height: | Size: 132 KiB |
BIN
Images/wiki/wechat/1_start.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
Images/wiki/wechat/2_click_attach.png
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
Images/wiki/wechat/3_attach_wechat_exe.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
Images/wiki/wechat/4_wechatwin_dll.png
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
Images/wiki/wechat/5_search_string.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
BIN
Images/wiki/wechat/6_revokemsg_1.png
Normal file
|
After Width: | Height: | Size: 137 KiB |
BIN
Images/wiki/wechat/7_je_to_jmp.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
BIN
Images/wiki/wechat/8_je_to_jmp.png
Normal file
|
After Width: | Height: | Size: 159 KiB |
BIN
Images/wiki/wechat/9_je_to_jmp.png
Normal file
|
After Width: | Height: | Size: 158 KiB |
48
README.md
|
|
@ -1,13 +1,13 @@
|
|||
|
||||
<p align="center">
|
||||
<a><img width="380px" src="https://raw.githubusercontent.com/huiyadanli/RevokeMsgPatcher/master/Images/logo.jpg"/></a>
|
||||
<a><img width="100px" src="https://raw.githubusercontent.com/huiyadanli/RevokeMsgPatcher/master/Images/logo.png"/></a>
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://www.microsoft.com/download/details.aspx?id=30653">
|
||||
<img src="https://img.shields.io/badge/platform-windows-lightgrey.svg?style=flat-square"/>
|
||||
</a>
|
||||
<a href="https://github.com/huiyadanli/RevokeMsgPatcher/releases">
|
||||
<img src="https://img.shields.io/github/downloads/huiyadanli/RevokeMsgPatcher/total.svg?style=flat-squares"/>
|
||||
<img src="https://img.shields.io/github/downloads/huiyadanli/RevokeMsgPatcher/total.svg?style=flat-square"/>
|
||||
</a>
|
||||
<a href="http://hits.dwyl.io/huiyadanli/RevokeMsgPatcher">
|
||||
<img src="http://hits.dwyl.io/huiyadanli/RevokeMsgPatcher.svg"/>
|
||||
|
|
@ -17,43 +17,49 @@
|
|||
</a>
|
||||
</p>
|
||||
|
||||
# :eyes:微信防撤回补丁
|
||||
适用于 Windows 下PC版微信的防撤回补丁。
|
||||
# 👀微信/QQ/TIM防撤回补丁
|
||||
适用于 Windows 下 PC 版微信/QQ/TIM的防撤回补丁。
|
||||
|
||||
<img width="180px" src="https://raw.githubusercontent.com/huiyadanli/RevokeMsgPatcher/master/Images/revoke.jpg"/>
|
||||
|
||||
支持最新测试版本:2.7.0.70
|
||||
|
||||
支持最新稳定版本:2.6.8.68
|
||||
|
||||
支持历史版本:2.6.6.28、2.6.7.32、2.6.7.40、2.6.7.57、2.6.8.37、2.6.8.51、2.6.8.52、2.6.8.65、2.7.0.65
|
||||
|
||||
下载地址:
|
||||
[:zap:点我下载最新版本](https://github.com/huiyadanli/RevokeMsgPatcher/releases/download/0.4/RevokeMsgPatcher.v0.4.zip)
|
||||
**[⚡️点我下载最新版本](https://github.com/huiyadanli/RevokeMsgPatcher/releases/download/0.6/RevokeMsgPatcher.v0.6.zip)** |
|
||||
[☁备用下载-蓝奏云](https://www.lanzous.com/i75gffi) |
|
||||
[☁备用下载-百度云](https://pan.baidu.com/s/1M8rNYrhS85pFjpAASZqKlw) 提取码:coco
|
||||
|
||||
## :camera:截图
|
||||
相关文档:
|
||||
**[✔支持哪些版本](https://github.com/huiyadanli/RevokeMsgPatcher/wiki/%E7%89%88%E6%9C%AC%E6%94%AF%E6%8C%81)** |
|
||||
[❓常见问题](https://github.com/huiyadanli/RevokeMsgPatcher/wiki#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98) |
|
||||
[📖查看完整文档](https://github.com/huiyadanli/RevokeMsgPatcher/wiki)
|
||||
|
||||
原理与方法:
|
||||
[📗微信](https://github.com/huiyadanli/RevokeMsgPatcher/wiki/%E5%BE%AE%E4%BF%A1%E9%98%B2%E6%92%A4%E5%9B%9E%E4%B8%8E%E5%A4%9A%E5%BC%80%E6%95%99%E7%A8%8B) |
|
||||
[📕QQ](https://github.com/huiyadanli/RevokeMsgPatcher/wiki/QQ%E6%88%96TIM%E9%98%B2%E6%92%A4%E5%9B%9E%E6%95%99%E7%A8%8B) |
|
||||
[📘TIM](https://github.com/huiyadanli/RevokeMsgPatcher/wiki/QQ%E6%88%96TIM%E9%98%B2%E6%92%A4%E5%9B%9E%E6%95%99%E7%A8%8B)
|
||||
|
||||
## 📷截图
|
||||

|
||||
|
||||
## 🔨使用方法
|
||||
|
||||
**请以管理员身份运行本程序,由于修改了微信的 `WeChatWin.dll` 文件,杀毒软件可能会弹出警告,放行即可。**
|
||||
1. 首先,你的系统需要满足以下条件:
|
||||
|
||||
启动时会自动从注册表中获取微信的安装路径,如果没找到,需要手动选择微信路径。
|
||||
* Windows 7 或更高版本,**不支持XP**。
|
||||
* [.NET Framework 4.5](https://www.microsoft.com/zh-cn/download/details.aspx?id=30653) 或更高版本。**低于此版本在打开程序时可能无反应,或者直接报错**。
|
||||
|
||||
环境要求:
|
||||
2. 使用本程序前,先关闭微信/QQ/TIM。
|
||||
|
||||
* Windows 7 或更高版本。
|
||||
* [.NET Framework 4.5](https://www.microsoft.com/zh-cn/download/details.aspx?id=30653) 或更高版本。
|
||||
3. **以管理员身份运行本程序**,等待右下角获取最新的补丁信息。
|
||||
|
||||
4. 选择微信/QQ/TIM的安装路径。如果你用的安装版的微信/QQ/TIM,正常情况下本程序会自动从注册表中获取安装路径,绿色版需要手动选择路径。
|
||||
|
||||
5. 点击防撤回。界面可能会出现一段时间的无响应,请耐心等待。**由于修改了微信的 WeChatWin.dll 文件、QQ/TIM的 IM.dll 文件,杀毒软件可能会弹出警告,放行即可。**
|
||||
|
||||
如果你想得到本软件最新版本的推送,请点击 Watch -> Release only
|
||||

|
||||
## ❤️Thanks
|
||||
|
||||
## :heart:Thanks
|
||||
[wechat_anti_revoke](https://github.com/36huo/wechat_anti_revoke)
|
||||
|
||||
## 📃License
|
||||
## 📄License
|
||||
GPLv3
|
||||
|
||||

|
||||
|
|
|
|||
6
RevokeMsgPatcher.Assistant/App.config
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
</configuration>
|
||||
1
RevokeMsgPatcher.Assistant/Data/0.6/patch.json
Normal file
61
RevokeMsgPatcher.Assistant/FormAssisant.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
namespace RevokeMsgPatcher.Assistant
|
||||
{
|
||||
partial class FormAssisant
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows 窗体设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.txtInfo = new System.Windows.Forms.TextBox();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// txtInfo
|
||||
//
|
||||
this.txtInfo.Location = new System.Drawing.Point(12, 12);
|
||||
this.txtInfo.Multiline = true;
|
||||
this.txtInfo.Name = "txtInfo";
|
||||
this.txtInfo.Size = new System.Drawing.Size(484, 238);
|
||||
this.txtInfo.TabIndex = 0;
|
||||
//
|
||||
// FormAssisant
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(508, 262);
|
||||
this.Controls.Add(this.txtInfo);
|
||||
this.Name = "FormAssisant";
|
||||
this.Text = "冷血无情的助手界面";
|
||||
this.Load += new System.EventHandler(this.FormMain_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox txtInfo;
|
||||
}
|
||||
}
|
||||
|
||||
38
RevokeMsgPatcher.Assistant/FormAssisant.cs
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace RevokeMsgPatcher.Assistant
|
||||
{
|
||||
public partial class FormAssisant : Form
|
||||
{
|
||||
public FormAssisant()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
private void FormMain_Load(object sender, EventArgs e)
|
||||
{
|
||||
JsonData obj = new JsonData();
|
||||
string json = obj.BagJson();
|
||||
Console.WriteLine(json);
|
||||
|
||||
DirectoryInfo directory = new DirectoryInfo("../../Data/" + obj.Bag().LatestVersion);
|
||||
if (!directory.Exists)
|
||||
{
|
||||
directory.Create();
|
||||
}
|
||||
string path = Path.Combine(directory.FullName, "patch.json");
|
||||
File.WriteAllText(path, json);
|
||||
|
||||
txtInfo.AppendText("生成完毕!位置:" + path);
|
||||
}
|
||||
}
|
||||
}
|
||||
120
RevokeMsgPatcher.Assistant/FormAssisant.resx
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
539
RevokeMsgPatcher.Assistant/JsonData.cs
Normal file
|
|
@ -0,0 +1,539 @@
|
|||
using RevokeMsgPatcher.Model;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Script.Serialization;
|
||||
|
||||
namespace RevokeMsgPatcher
|
||||
{
|
||||
/// <summary>
|
||||
/// 补丁信息
|
||||
/// </summary>
|
||||
public class JsonData
|
||||
{
|
||||
|
||||
public Bag Bag()
|
||||
{
|
||||
return new Bag
|
||||
{
|
||||
Apps = AppConfig(),
|
||||
LatestVersion = "0.6",
|
||||
Notice = ""
|
||||
};
|
||||
}
|
||||
|
||||
public string BagJson()
|
||||
{
|
||||
JavaScriptSerializer serializer = new JavaScriptSerializer();
|
||||
return serializer.Serialize(Bag());
|
||||
}
|
||||
|
||||
public Dictionary<string, App> AppConfig()
|
||||
{
|
||||
return new Dictionary<string, App>
|
||||
{
|
||||
{ "Wechat" , Wechat() },
|
||||
{ "QQ" , QQ() },
|
||||
{ "TIM" , TIM() },
|
||||
{ "QQLite" , QQLite() }
|
||||
};
|
||||
}
|
||||
|
||||
public string AppConfigJson()
|
||||
{
|
||||
JavaScriptSerializer serializer = new JavaScriptSerializer();
|
||||
return serializer.Serialize(AppConfig());
|
||||
}
|
||||
|
||||
public App Wechat()
|
||||
{
|
||||
return new App
|
||||
{
|
||||
Name = "Wechat",
|
||||
FileTargetInfos = new Dictionary<string, TargetInfo>
|
||||
{
|
||||
{
|
||||
"WeChatWin.dll",
|
||||
new TargetInfo
|
||||
{
|
||||
Name = "WeChatWin.dll",
|
||||
RelativePath = "WeChatWin.dll"
|
||||
}
|
||||
}
|
||||
},
|
||||
FileModifyInfos = new Dictionary<string, List<ModifyInfo>>
|
||||
{
|
||||
{
|
||||
"WeChatWin.dll",
|
||||
new List<ModifyInfo>
|
||||
{
|
||||
new ModifyInfo {
|
||||
Name="WeChatWin.dll",
|
||||
Version="2.7.1.88",
|
||||
SHA1Before="034059bad50dd793140952391bfa7936133e69b4",
|
||||
SHA1After="dd6d80c30ca9e0ea9f7d2f1add498fc9aa4bc7a0",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position =0x00262389,
|
||||
Content =new byte[] { 0xEB }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position =0x007957B0,
|
||||
Content =new byte[] { 0xC3 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo {
|
||||
Name="WeChatWin.dll",
|
||||
Version="2.7.1.85",
|
||||
SHA1Before="de0df4e138b72460450f66c029e33f4510f5e2df",
|
||||
SHA1After="fbd35720aaff3cdcfd3ff18ea503dc06450e5c99",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position =0x00262389,
|
||||
Content =new byte[] { 0xEB }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position =0x00795680,
|
||||
Content =new byte[] { 0xC3 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo {
|
||||
Name="WeChatWin.dll",
|
||||
Version="2.7.1.82",
|
||||
SHA1Before="20e111a18872bf6c7148a897c11da26c1ec95520",
|
||||
SHA1After="1e0741d325ca6b1cd2402b829a3d13a2524af617",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position =0x00262389,
|
||||
Content =new byte[] { 0xEB }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position =0x00795650,
|
||||
Content =new byte[] { 0xC3 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo {
|
||||
Name="WeChatWin.dll",
|
||||
Version="2.7.1.74",
|
||||
SHA1Before="b1eaf7edc074a88be5d0f89230436cc2084d24d2",
|
||||
SHA1After="eb3d74ccd87a09059a005f4972861898fc3de463",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position =0x00262389,
|
||||
Content =new byte[] { 0xEB }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position =0x00795550,
|
||||
Content =new byte[] { 0xC3 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo {
|
||||
Name="WeChatWin.dll",
|
||||
Version="2.7.1.65",
|
||||
SHA1Before="8346b97d264725da924d240c6eb77df3e693385e",
|
||||
SHA1After="42bab2c9c79ef4f2088c00ea6d817973e14a5e6e",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position =2495545,
|
||||
Content =new byte[] { 235}
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo {Name="WeChatWin.dll",Version="2.7.1.59",SHA1Before="df954d403edaca89cd5394927a325a0023e93281",SHA1After="6aa22460c91bb5c5e2f0ec1af99b8a5f6d4318c0",Changes = new List<Change> { new Change {Position=2496073,Content=new byte[] { 235} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.7.1.43",SHA1Before="39cd9e09e1a3eac09e6808749bff525c9e3216ce",SHA1After="7b829f1ff0217e346a80f9510fdd7634ddd49445",Changes = new List<Change> { new Change {Position=2494169,Content=new byte[] { 235} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.7.0.70",SHA1Before="3b0601864aff3c1d792f812ad1ca05f02aa761e3",SHA1After="1e8734d32b0a8c12758e30f99c77f729991fb071",Changes = new List<Change> { new Change {Position=2475657,Content=new byte[] { 235} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.7.0.65",SHA1Before="063c2e05a0df1bdb8987c2d978d93499bd2052ba",SHA1After="5ed4c09a4f18643b967f063a824d7e65d0567f8a",Changes = new List<Change> { new Change {Position=2475449,Content=new byte[] { 117} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.6.8.68",SHA1Before="2e9417f4276b12fe32ca7b4fee49272a4a2af334",SHA1After="699602ee3cbb9ae5714f6e6ebc658c875a6c66e6",Changes = new List<Change> { new Change {Position=2454006,Content=new byte[] { 116} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.6.8.65",SHA1Before="e01f6855a96c12c30808960903ed199a33e4952c",SHA1After="d9120569cfd0433aebea107d7b90805cbbac7518",Changes = new List<Change> { new Change {Position=2454265,Content=new byte[] { 117} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.6.8.52",SHA1Before="88131302f664df6a657c9ca49d152da536fe5729",SHA1After="8d1454b73831644181e962c1fa0ea4e2da4124a3",Changes = new List<Change> { new Change {Position=2453049,Content=new byte[] { 117} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.6.8.51",SHA1Before="d0a5517b1292a751501b00b4b1f0702db2d9fc30",SHA1After="53e7b1525d49bf2c3250a8131ff0ba2510779b78",Changes = new List<Change> { new Change {Position=2452614,Content=new byte[] { 116} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.6.8.37",SHA1Before="7e01f8b04a158a4a50bc5a6e67c2fb8b02233170",SHA1After="a1895004415fe9bcd7e690bd6e482b833b515599",Changes = new List<Change> { new Change {Position=2452614,Content=new byte[] { 116} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.6.7.57",SHA1Before="80a91aaf941bcb1c24a7d672838ac73e9ebb2e40",SHA1After="a0d3f9a45a835f97aef7fe0872387d8cfb5c25a4",Changes = new List<Change> { new Change {Position=2433413,Content=new byte[] { 116} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.6.7.40",SHA1Before="04bd0cb28df6630b518f42a3f9c2caa4a9359fbc",SHA1After="13c91cf1d4609959771fd137b9a86a5ca365e1b6",Changes = new List<Change> { new Change {Position=2432934,Content=new byte[] { 116} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.6.7.32",SHA1Before="a02519c1007ee6723947c262c720d63c619f633e",SHA1After="f3007471ca8734c29783c25f0bb49949a783a44",Changes = new List<Change> { new Change {Position=2432806,Content=new byte[] { 116} } } },new ModifyInfo {Name="WeChatWin.dll",Version="2.6.6.28",SHA1Before="0b19cb17a62c3ea0efce0fb675a1d3b17845cba3",SHA1After="260948656725446b818ea668273ceff02ddfb44d",Changes = new List<Change> { new Change {Position=2401678,Content=new byte[] { 116} } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public App QQ()
|
||||
{
|
||||
return new App
|
||||
{
|
||||
Name = "QQ",
|
||||
FileTargetInfos = new Dictionary<string, TargetInfo>
|
||||
{
|
||||
{
|
||||
"IM.dll",
|
||||
new TargetInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
RelativePath = @"Bin\IM.dll"
|
||||
}
|
||||
}
|
||||
},
|
||||
FileModifyInfos = new Dictionary<string, List<ModifyInfo>>
|
||||
{
|
||||
{
|
||||
"IM.dll",
|
||||
new List<ModifyInfo>
|
||||
{
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "9.2.2.26569",
|
||||
SHA1Before = "434254e76c520789558e075af677821258536311",
|
||||
SHA1After = "237c9e489a97858a175f0f7c72ade4ebcbac7a69",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005A9CA,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005ABE7,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005AD95,
|
||||
Content = new byte[] { 0xEB, 0x08, 0x90, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "9.2.1.26546",
|
||||
SHA1Before = "8d8ea2c2cbf43f5acf8d684b153e90035352d5f5",
|
||||
SHA1After = "7d194dd5be03982b533d7375c93d9a72587fe28d",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005A389,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005A5A6,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005A754,
|
||||
Content = new byte[] { 0xEB, 0x08, 0x90, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "9.2.0.26453",
|
||||
SHA1Before = "c1935ca6347b0c2a7e6108a7f8ee0643d39deb66",
|
||||
SHA1After = "42811188a7e7b346a6a3c1066936b98c747acaf6",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x00056602,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005681F,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x000569CF,
|
||||
Content = new byte[] { 0xEB, 0x08, 0x90, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "9.2.0.26389",
|
||||
SHA1Before = "6f8855fb80acfa456f8f69989fe949308fe4d154",
|
||||
SHA1After = "f6b8e05a178b9b10ba17c597fa0a44b7a2a966a8",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x000571C8,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x000573E5,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x00057595,
|
||||
Content = new byte[] { 0xEB, 0x08, 0x90, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "9.1.9.26361",
|
||||
SHA1Before = "022d3433d13d07a354c38816f61cb0b7ac60d3fd",
|
||||
SHA1After = "873a57c1fb51cdd099c8cb7108b5ab5cb4459557",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x000567DE,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x000569FB,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x00056BAB,
|
||||
Content = new byte[] { 0xEB, 0x08, 0x90, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "9.1.9.26346",
|
||||
SHA1Before = "895eb70f707b8222e6460c91492b1281e525059b",
|
||||
SHA1After = "0bb83990e2b5b5f23b7b43249941ff638201af54",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x000567DE,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x000569FB,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x00056BAB,
|
||||
Content = new byte[] { 0xEB, 0x08, 0x90, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "9.1.8.26211",
|
||||
SHA1Before = "a950d3cf5e8925f7775624271105ef78d9c5cb57",
|
||||
SHA1After = "dffc1cb87b91e6467e13c935611f2f7fd76b9a8d",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x000524EF,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005270C,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x000528BC,
|
||||
Content = new byte[] { 0xEB, 0x08, 0x90, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "9.1.7.25980",
|
||||
SHA1Before = "c6632339fbe675312a70ae4620e70699c258cd36",
|
||||
SHA1After = "e9ddc5cc681950796fc8fe4c55f580428c890b51",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005009F,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x000502BC,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0005046C,
|
||||
Content = new byte[] { 0xEB, 0x08, 0x90, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "9.0.4.23786",
|
||||
SHA1Before = "69a714f4eadb09f1453f6f022d4adbcd801cfab8",
|
||||
SHA1After = "b48e77a924076b3ebdffc4af514c868c551d2bca",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x0004DB71,
|
||||
Content = new byte[] { 0xEB, 0x07, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0004DD8E,
|
||||
Content = new byte[] { 0xEB, 0x07, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0004DF93,
|
||||
Content = new byte[] { 0xEB, 0x07, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public App TIM()
|
||||
{
|
||||
return new App
|
||||
{
|
||||
Name = "TIM",
|
||||
FileTargetInfos = new Dictionary<string, TargetInfo>
|
||||
{
|
||||
{
|
||||
"IM.dll",
|
||||
new TargetInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
RelativePath = @"Bin\IM.dll"
|
||||
}
|
||||
}
|
||||
},
|
||||
FileModifyInfos = new Dictionary<string, List<ModifyInfo>>
|
||||
{
|
||||
{
|
||||
"IM.dll",
|
||||
new List<ModifyInfo>
|
||||
{
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "2.3.2.21173",
|
||||
SHA1Before = "ecf3e69f3fb100ffe2fee095ffded591b9781024",
|
||||
SHA1After = "0514d1304e7ac46b4d33386ec3313888f5ae7171",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x0004D78A,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0004D9A7,
|
||||
Content = new byte[] { 0xEB, 0x09, 0x90, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x0004DB57,
|
||||
Content = new byte[] { 0xEB, 0x08, 0x90, 0x90, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public App QQLite()
|
||||
{
|
||||
return new App
|
||||
{
|
||||
Name = "QQLite",
|
||||
FileTargetInfos = new Dictionary<string, TargetInfo>
|
||||
{
|
||||
{
|
||||
"IM.dll",
|
||||
new TargetInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
RelativePath = @"Bin\IM.dll"
|
||||
}
|
||||
}
|
||||
},
|
||||
FileModifyInfos = new Dictionary<string, List<ModifyInfo>>
|
||||
{
|
||||
{
|
||||
"IM.dll",
|
||||
new List<ModifyInfo>
|
||||
{
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "7.9.14314.0",
|
||||
SHA1Before = "2e97d7671963fa148a1beeda6ce4964314310593",
|
||||
SHA1After = "723c008fb53435ead20fa6f2e951c9a4a8ff46da",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x00024505,
|
||||
Content = new byte[] { 0xEB, 0x02, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x000248B9,
|
||||
Content = new byte[] { 0xEB, 0x02, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
},
|
||||
new ModifyInfo
|
||||
{
|
||||
Name = "IM.dll",
|
||||
Version = "7.9.14308.0",
|
||||
SHA1Before = "b8a7a873178706b97be11c25f13bcf09e9e578a2",
|
||||
SHA1After = "c5bf533c7af6996b42d1fb2a0fb3f26dfd52f8bf",
|
||||
Changes = new List<Change>
|
||||
{
|
||||
new Change
|
||||
{
|
||||
Position = 0x00024505,
|
||||
Content = new byte[] { 0xEB, 0x02, 0x90, 0x90 }
|
||||
},
|
||||
new Change
|
||||
{
|
||||
Position = 0x000248B9,
|
||||
Content = new byte[] { 0xEB, 0x02, 0x90, 0x90 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
22
RevokeMsgPatcher.Assistant/Program.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace RevokeMsgPatcher.Assistant
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用程序的主入口点。
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new FormAssisant());
|
||||
}
|
||||
}
|
||||
}
|
||||
36
RevokeMsgPatcher.Assistant/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("RevokeMsgPatcher.Assistant")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("RevokeMsgPatcher.Assistant")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("6992004f-17e6-45bf-8d72-180a31e9c23c")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
// 方法是按如下所示使用“*”: :
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
71
RevokeMsgPatcher.Assistant/Properties/Resources.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本: 4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能导致不正确的行为,如果
|
||||
// 重新生成代码,则所做更改将丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace RevokeMsgPatcher.Assistant.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 强类型资源类,用于查找本地化字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RevokeMsgPatcher.Assistant.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 覆盖当前线程的 CurrentUICulture 属性
|
||||
/// 使用此强类型的资源类的资源查找。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
RevokeMsgPatcher.Assistant/Properties/Resources.resx
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
30
RevokeMsgPatcher.Assistant/Properties/Settings.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace RevokeMsgPatcher.Assistant.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
RevokeMsgPatcher.Assistant/Properties/Settings.settings
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
113
RevokeMsgPatcher.Assistant/RevokeMsgPatcher.Assistant.csproj
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{6992004F-17E6-45BF-8D72-180A31E9C23C}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>RevokeMsgPatcher.Assistant</RootNamespace>
|
||||
<AssemblyName>RevokeMsgPatcher.Assistant</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
<PublishUrl>publish\</PublishUrl>
|
||||
<Install>true</Install>
|
||||
<InstallFrom>Disk</InstallFrom>
|
||||
<UpdateEnabled>false</UpdateEnabled>
|
||||
<UpdateMode>Foreground</UpdateMode>
|
||||
<UpdateInterval>7</UpdateInterval>
|
||||
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
|
||||
<UpdatePeriodically>false</UpdatePeriodically>
|
||||
<UpdateRequired>false</UpdateRequired>
|
||||
<MapFileExtensions>true</MapFileExtensions>
|
||||
<ApplicationRevision>0</ApplicationRevision>
|
||||
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
|
||||
<IsWebBootstrapper>false</IsWebBootstrapper>
|
||||
<UseApplicationTrust>false</UseApplicationTrust>
|
||||
<BootstrapperEnabled>true</BootstrapperEnabled>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FormAssisant.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FormAssisant.Designer.cs">
|
||||
<DependentUpon>FormAssisant.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="JsonData.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="FormAssisant.resx">
|
||||
<DependentUpon>FormAssisant.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="Data\0.6\patch.json" />
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\RevokeMsgPatcher\RevokeMsgPatcher.csproj">
|
||||
<Project>{977bf781-ced8-4389-9404-0fa08fdf21df}</Project>
|
||||
<Name>RevokeMsgPatcher</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
|
||||
<Visible>False</Visible>
|
||||
<ProductName>.NET Framework 3.5 SP1</ProductName>
|
||||
<Install>false</Install>
|
||||
</BootstrapperPackage>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
6
RevokeMsgPatcher.MultiInstance/App.config
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||
</startup>
|
||||
</configuration>
|
||||
186
RevokeMsgPatcher.MultiInstance/FormMultiInstance.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,186 @@
|
|||
namespace RevokeMsgPatcher.MultiInstance
|
||||
{
|
||||
partial class FormMultiInstance
|
||||
{
|
||||
/// <summary>
|
||||
/// 必需的设计器变量。
|
||||
/// </summary>
|
||||
private System.ComponentModel.IContainer components = null;
|
||||
|
||||
/// <summary>
|
||||
/// 清理所有正在使用的资源。
|
||||
/// </summary>
|
||||
/// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
|
||||
protected override void Dispose(bool disposing)
|
||||
{
|
||||
if (disposing && (components != null))
|
||||
{
|
||||
components.Dispose();
|
||||
}
|
||||
base.Dispose(disposing);
|
||||
}
|
||||
|
||||
#region Windows 窗体设计器生成的代码
|
||||
|
||||
/// <summary>
|
||||
/// 设计器支持所需的方法 - 不要修改
|
||||
/// 使用代码编辑器修改此方法的内容。
|
||||
/// </summary>
|
||||
private void InitializeComponent()
|
||||
{
|
||||
this.txtPath = new System.Windows.Forms.TextBox();
|
||||
this.lblPathTag = new System.Windows.Forms.Label();
|
||||
this.btnChoosePath = new System.Windows.Forms.Button();
|
||||
this.label1 = new System.Windows.Forms.Label();
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.startNum = new System.Windows.Forms.NumericUpDown();
|
||||
this.btnStart = new System.Windows.Forms.Button();
|
||||
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
|
||||
this.label3 = new System.Windows.Forms.Label();
|
||||
this.label4 = new System.Windows.Forms.Label();
|
||||
((System.ComponentModel.ISupportInitialize)(this.startNum)).BeginInit();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// txtPath
|
||||
//
|
||||
this.txtPath.Location = new System.Drawing.Point(86, 60);
|
||||
this.txtPath.Name = "txtPath";
|
||||
this.txtPath.Size = new System.Drawing.Size(332, 21);
|
||||
this.txtPath.TabIndex = 7;
|
||||
//
|
||||
// lblPathTag
|
||||
//
|
||||
this.lblPathTag.AutoSize = true;
|
||||
this.lblPathTag.Location = new System.Drawing.Point(15, 63);
|
||||
this.lblPathTag.Name = "lblPathTag";
|
||||
this.lblPathTag.Size = new System.Drawing.Size(65, 12);
|
||||
this.lblPathTag.TabIndex = 6;
|
||||
this.lblPathTag.Text = "微信路径:";
|
||||
//
|
||||
// btnChoosePath
|
||||
//
|
||||
this.btnChoosePath.Location = new System.Drawing.Point(424, 59);
|
||||
this.btnChoosePath.Name = "btnChoosePath";
|
||||
this.btnChoosePath.Size = new System.Drawing.Size(36, 23);
|
||||
this.btnChoosePath.TabIndex = 8;
|
||||
this.btnChoosePath.Text = "...";
|
||||
this.btnChoosePath.UseVisualStyleBackColor = true;
|
||||
this.btnChoosePath.Click += new System.EventHandler(this.btnChoosePath_Click);
|
||||
//
|
||||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(84, 151);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(293, 24);
|
||||
this.label1.TabIndex = 9;
|
||||
this.label1.Text = "只要我打开微信的速度足够快,我就多开无限个微信。\r\n我为什么能手动双开微信,别问,问就是手速快。";
|
||||
//
|
||||
// label2
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(15, 95);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(65, 12);
|
||||
this.label2.TabIndex = 11;
|
||||
this.label2.Text = "多开个数:";
|
||||
//
|
||||
// startNum
|
||||
//
|
||||
this.startNum.Location = new System.Drawing.Point(86, 91);
|
||||
this.startNum.Maximum = new decimal(new int[] {
|
||||
1000,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.startNum.Minimum = new decimal(new int[] {
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
this.startNum.Name = "startNum";
|
||||
this.startNum.Size = new System.Drawing.Size(55, 21);
|
||||
this.startNum.TabIndex = 12;
|
||||
this.startNum.Value = new decimal(new int[] {
|
||||
2,
|
||||
0,
|
||||
0,
|
||||
0});
|
||||
//
|
||||
// btnStart
|
||||
//
|
||||
this.btnStart.Location = new System.Drawing.Point(369, 91);
|
||||
this.btnStart.Name = "btnStart";
|
||||
this.btnStart.Size = new System.Drawing.Size(91, 23);
|
||||
this.btnStart.TabIndex = 13;
|
||||
this.btnStart.Text = "点击启动!";
|
||||
this.btnStart.UseVisualStyleBackColor = true;
|
||||
this.btnStart.Click += new System.EventHandler(this.btnStart_Click);
|
||||
//
|
||||
// linkLabel1
|
||||
//
|
||||
this.linkLabel1.AutoSize = true;
|
||||
this.linkLabel1.Location = new System.Drawing.Point(284, 95);
|
||||
this.linkLabel1.Name = "linkLabel1";
|
||||
this.linkLabel1.Size = new System.Drawing.Size(41, 12);
|
||||
this.linkLabel1.TabIndex = 15;
|
||||
this.linkLabel1.TabStop = true;
|
||||
this.linkLabel1.Text = "GitHub";
|
||||
this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.linkLabel1_LinkClicked);
|
||||
//
|
||||
// label3
|
||||
//
|
||||
this.label3.AutoSize = true;
|
||||
this.label3.Location = new System.Drawing.Point(177, 95);
|
||||
this.label3.Name = "label3";
|
||||
this.label3.Size = new System.Drawing.Size(101, 12);
|
||||
this.label3.TabIndex = 14;
|
||||
this.label3.Text = "软件主页(开源):";
|
||||
//
|
||||
// label4
|
||||
//
|
||||
this.label4.AutoSize = true;
|
||||
this.label4.Location = new System.Drawing.Point(12, 9);
|
||||
this.label4.Name = "label4";
|
||||
this.label4.Size = new System.Drawing.Size(323, 36);
|
||||
this.label4.TabIndex = 16;
|
||||
this.label4.Text = "注意:\r\n1. 使用本程序多开前不能存在正在运行的微信进程。\r\n2. 多开的成功率取决于你的机器性能,不保证每次都能成功";
|
||||
//
|
||||
// FormMultiInstance
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(472, 133);
|
||||
this.Controls.Add(this.label4);
|
||||
this.Controls.Add(this.linkLabel1);
|
||||
this.Controls.Add(this.label3);
|
||||
this.Controls.Add(this.btnStart);
|
||||
this.Controls.Add(this.startNum);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.txtPath);
|
||||
this.Controls.Add(this.lblPathTag);
|
||||
this.Controls.Add(this.btnChoosePath);
|
||||
this.Name = "FormMultiInstance";
|
||||
this.Text = "微信多开小工具";
|
||||
((System.ComponentModel.ISupportInitialize)(this.startNum)).EndInit();
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private System.Windows.Forms.TextBox txtPath;
|
||||
private System.Windows.Forms.Label lblPathTag;
|
||||
private System.Windows.Forms.Button btnChoosePath;
|
||||
private System.Windows.Forms.Label label1;
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.NumericUpDown startNum;
|
||||
private System.Windows.Forms.Button btnStart;
|
||||
private System.Windows.Forms.LinkLabel linkLabel1;
|
||||
private System.Windows.Forms.Label label3;
|
||||
private System.Windows.Forms.Label label4;
|
||||
}
|
||||
}
|
||||
|
||||
111
RevokeMsgPatcher.MultiInstance/FormMultiInstance.cs
Normal file
|
|
@ -0,0 +1,111 @@
|
|||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace RevokeMsgPatcher.MultiInstance
|
||||
{
|
||||
public partial class FormMultiInstance : Form
|
||||
{
|
||||
public FormMultiInstance()
|
||||
{
|
||||
InitializeComponent();
|
||||
string installFolder = FindInstallPathFromRegistry("Wechat");
|
||||
if (!string.IsNullOrEmpty(installFolder))
|
||||
{
|
||||
string wechatPath = Path.Combine(installFolder, "WeChat.exe");
|
||||
if (File.Exists(wechatPath))
|
||||
{
|
||||
txtPath.Text = wechatPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnChoosePath_Click(object sender, EventArgs e)
|
||||
{
|
||||
OpenFileDialog dialog = new OpenFileDialog
|
||||
{
|
||||
Multiselect = false,
|
||||
Title = "请选择微信启动主程序",
|
||||
Filter = "微信主程序|WeChat.exe"
|
||||
};
|
||||
if (dialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
txtPath.Text = dialog.FileName;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnStart_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (File.Exists(txtPath.Text))
|
||||
{
|
||||
// 检测微信进程是否存在
|
||||
Process[] ps = Process.GetProcessesByName("WeChat");
|
||||
if (ps.Length > 0)
|
||||
{
|
||||
DialogResult result = MessageBox.Show("当前存在运行中的微信进程,请先关闭当前微信才能使用该功能。点击【确定】强制关闭当前所有微信进程并进行多开,点击【取消】不做任何处理。", "当前存在运行中的微信进程", MessageBoxButtons.OKCancel, MessageBoxIcon.Question);
|
||||
if (result == DialogResult.OK)
|
||||
{
|
||||
foreach (Process p in ps)
|
||||
p.Kill();
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
// 启动多个实例
|
||||
for (int i = 0; i < startNum.Value; i++)
|
||||
{
|
||||
Process.Start(txtPath.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
{
|
||||
Process.Start("https://github.com/huiyadanli/RevokeMsgPatcher");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从注册表中寻找安装路径
|
||||
/// </summary>
|
||||
/// <param name="uninstallKeyName">
|
||||
/// 安装信息的注册表键名
|
||||
/// 微信:WeChat
|
||||
/// QQ:{052CFB79-9D62-42E3-8A15-DE66C2C97C3E}
|
||||
/// TIM:TIM
|
||||
/// </param>
|
||||
/// <returns>安装路径</returns>
|
||||
public static string FindInstallPathFromRegistry(string uninstallKeyName)
|
||||
{
|
||||
try
|
||||
{
|
||||
RegistryKey key = Registry.LocalMachine.OpenSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{uninstallKeyName}");
|
||||
if (key == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
object installLocation = key.GetValue("InstallLocation");
|
||||
key.Close();
|
||||
if (installLocation != null && !string.IsNullOrEmpty(installLocation.ToString()))
|
||||
{
|
||||
return installLocation.ToString();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
120
RevokeMsgPatcher.MultiInstance/FormMultiInstance.resx
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" use="required" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
<xsd:attribute ref="xml:space" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
22
RevokeMsgPatcher.MultiInstance/Program.cs
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace RevokeMsgPatcher.MultiInstance
|
||||
{
|
||||
static class Program
|
||||
{
|
||||
/// <summary>
|
||||
/// 应用程序的主入口点。
|
||||
/// </summary>
|
||||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new FormMultiInstance());
|
||||
}
|
||||
}
|
||||
}
|
||||
36
RevokeMsgPatcher.MultiInstance/Properties/AssemblyInfo.cs
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// 有关程序集的一般信息由以下
|
||||
// 控制。更改这些特性值可修改
|
||||
// 与程序集关联的信息。
|
||||
[assembly: AssemblyTitle("RevokeMsgPatcher.MultiInstance")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("")]
|
||||
[assembly: AssemblyProduct("RevokeMsgPatcher.MultiInstance")]
|
||||
[assembly: AssemblyCopyright("Copyright © 2019")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// 将 ComVisible 设置为 false 会使此程序集中的类型
|
||||
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
|
||||
//请将此类型的 ComVisible 特性设置为 true。
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
|
||||
[assembly: Guid("73043ca8-af54-4591-9174-40fb6e0a3d36")]
|
||||
|
||||
// 程序集的版本信息由下列四个值组成:
|
||||
//
|
||||
// 主版本
|
||||
// 次版本
|
||||
// 生成号
|
||||
// 修订号
|
||||
//
|
||||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
// 方法是按如下所示使用“*”: :
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
71
RevokeMsgPatcher.MultiInstance/Properties/Resources.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// 此代码由工具生成。
|
||||
// 运行时版本: 4.0.30319.42000
|
||||
//
|
||||
// 对此文件的更改可能导致不正确的行为,如果
|
||||
// 重新生成代码,则所做更改将丢失。
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace RevokeMsgPatcher.MultiInstance.Properties
|
||||
{
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 强类型资源类,用于查找本地化字符串等。
|
||||
/// </summary>
|
||||
// 此类是由 StronglyTypedResourceBuilder
|
||||
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
|
||||
// 若要添加或删除成员,请编辑 .ResX 文件,然后重新运行 ResGen
|
||||
// (以 /str 作为命令选项),或重新生成 VS 项目。
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
internal class Resources
|
||||
{
|
||||
|
||||
private static global::System.Resources.ResourceManager resourceMan;
|
||||
|
||||
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||
|
||||
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||
internal Resources()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 返回此类使用的缓存 ResourceManager 实例。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Resources.ResourceManager ResourceManager
|
||||
{
|
||||
get
|
||||
{
|
||||
if ((resourceMan == null))
|
||||
{
|
||||
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RevokeMsgPatcher.MultiInstance.Properties.Resources", typeof(Resources).Assembly);
|
||||
resourceMan = temp;
|
||||
}
|
||||
return resourceMan;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 覆盖当前线程的 CurrentUICulture 属性
|
||||
/// 使用此强类型的资源类的资源查找。
|
||||
/// </summary>
|
||||
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||
internal static global::System.Globalization.CultureInfo Culture
|
||||
{
|
||||
get
|
||||
{
|
||||
return resourceCulture;
|
||||
}
|
||||
set
|
||||
{
|
||||
resourceCulture = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
117
RevokeMsgPatcher.MultiInstance/Properties/Resources.resx
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
30
RevokeMsgPatcher.MultiInstance/Properties/Settings.Designer.cs
generated
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace RevokeMsgPatcher.MultiInstance.Properties
|
||||
{
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
</SettingsFile>
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProjectGuid>{73043CA8-AF54-4591-9174-40FB6E0A3D36}</ProjectGuid>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<RootNamespace>RevokeMsgPatcher.MultiInstance</RootNamespace>
|
||||
<AssemblyName>RevokeMsgPatcher.MultiInstance</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<Deterministic>true</Deterministic>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="Microsoft.CSharp" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Deployment" />
|
||||
<Reference Include="System.Drawing" />
|
||||
<Reference Include="System.Net.Http" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="FormMultiInstance.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FormMultiInstance.Designer.cs">
|
||||
<DependentUpon>FormMultiInstance.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<EmbeddedResource Include="FormMultiInstance.resx">
|
||||
<DependentUpon>FormMultiInstance.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Properties\Resources.resx">
|
||||
<Generator>ResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<Compile Include="Properties\Resources.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
<None Include="Properties\Settings.settings">
|
||||
<Generator>SettingsSingleFileGenerator</Generator>
|
||||
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||
</None>
|
||||
<Compile Include="Properties\Settings.Designer.cs">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Settings.settings</DependentUpon>
|
||||
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="App.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
</Project>
|
||||
|
|
@ -5,6 +5,10 @@ VisualStudioVersion = 15.0.28010.2016
|
|||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevokeMsgPatcher", "RevokeMsgPatcher\RevokeMsgPatcher.csproj", "{977BF781-CED8-4389-9404-0FA08FDF21DF}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevokeMsgPatcher.Assistant", "RevokeMsgPatcher.Assistant\RevokeMsgPatcher.Assistant.csproj", "{6992004F-17E6-45BF-8D72-180A31E9C23C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RevokeMsgPatcher.MultiInstance", "RevokeMsgPatcher.MultiInstance\RevokeMsgPatcher.MultiInstance.csproj", "{73043CA8-AF54-4591-9174-40FB6E0A3D36}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -15,6 +19,14 @@ Global
|
|||
{977BF781-CED8-4389-9404-0FA08FDF21DF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{977BF781-CED8-4389-9404-0FA08FDF21DF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{977BF781-CED8-4389-9404-0FA08FDF21DF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{6992004F-17E6-45BF-8D72-180A31E9C23C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{6992004F-17E6-45BF-8D72-180A31E9C23C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{6992004F-17E6-45BF-8D72-180A31E9C23C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{6992004F-17E6-45BF-8D72-180A31E9C23C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{73043CA8-AF54-4591-9174-40FB6E0A3D36}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{73043CA8-AF54-4591-9174-40FB6E0A3D36}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{73043CA8-AF54-4591-9174-40FB6E0A3D36}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{73043CA8-AF54-4591-9174-40FB6E0A3D36}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
|||
14
RevokeMsgPatcher/BusinessException.cs
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
using System;
|
||||
|
||||
namespace RevokeMsgPatcher
|
||||
{
|
||||
class BusinessException : ApplicationException
|
||||
{
|
||||
public string ErrorCode { get; protected set; }
|
||||
|
||||
public BusinessException(string errcode, string message) : base(message)
|
||||
{
|
||||
ErrorCode = errcode;
|
||||
}
|
||||
}
|
||||
}
|
||||
159
RevokeMsgPatcher/FormMain.Designer.cs
generated
|
|
@ -29,7 +29,7 @@
|
|||
private void InitializeComponent()
|
||||
{
|
||||
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormMain));
|
||||
this.label2 = new System.Windows.Forms.Label();
|
||||
this.lblPathTag = new System.Windows.Forms.Label();
|
||||
this.btnPatch = new System.Windows.Forms.Button();
|
||||
this.txtPath = new System.Windows.Forms.TextBox();
|
||||
this.btnChoosePath = new System.Windows.Forms.Button();
|
||||
|
|
@ -37,21 +37,29 @@
|
|||
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
|
||||
this.btnRestore = new System.Windows.Forms.Button();
|
||||
this.lblUpdatePachJson = new System.Windows.Forms.Label();
|
||||
this.lblVersion = new System.Windows.Forms.Label();
|
||||
this.lblVersionTag = new System.Windows.Forms.Label();
|
||||
this.rbtWechat = new System.Windows.Forms.RadioButton();
|
||||
this.rbtQQ = new System.Windows.Forms.RadioButton();
|
||||
this.rbtTIM = new System.Windows.Forms.RadioButton();
|
||||
this.label5 = new System.Windows.Forms.Label();
|
||||
this.panelMask = new System.Windows.Forms.Panel();
|
||||
this.rbtQQLite = new System.Windows.Forms.RadioButton();
|
||||
this.SuspendLayout();
|
||||
//
|
||||
// label2
|
||||
// lblPathTag
|
||||
//
|
||||
this.label2.AutoSize = true;
|
||||
this.label2.Location = new System.Drawing.Point(17, 15);
|
||||
this.label2.Name = "label2";
|
||||
this.label2.Size = new System.Drawing.Size(65, 12);
|
||||
this.label2.TabIndex = 1;
|
||||
this.label2.Text = "微信路径:";
|
||||
this.lblPathTag.AutoSize = true;
|
||||
this.lblPathTag.Location = new System.Drawing.Point(12, 34);
|
||||
this.lblPathTag.Name = "lblPathTag";
|
||||
this.lblPathTag.Size = new System.Drawing.Size(65, 12);
|
||||
this.lblPathTag.TabIndex = 1;
|
||||
this.lblPathTag.Text = "应用路径:";
|
||||
//
|
||||
// btnPatch
|
||||
//
|
||||
this.btnPatch.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnPatch.Location = new System.Drawing.Point(409, 10);
|
||||
this.btnPatch.Location = new System.Drawing.Point(372, 56);
|
||||
this.btnPatch.Name = "btnPatch";
|
||||
this.btnPatch.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnPatch.TabIndex = 3;
|
||||
|
|
@ -63,15 +71,16 @@
|
|||
//
|
||||
this.txtPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
|
||||
| System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.txtPath.Location = new System.Drawing.Point(88, 12);
|
||||
this.txtPath.Location = new System.Drawing.Point(82, 29);
|
||||
this.txtPath.Name = "txtPath";
|
||||
this.txtPath.Size = new System.Drawing.Size(275, 21);
|
||||
this.txtPath.Size = new System.Drawing.Size(352, 21);
|
||||
this.txtPath.TabIndex = 4;
|
||||
this.txtPath.TextChanged += new System.EventHandler(this.txtPath_TextChanged);
|
||||
//
|
||||
// btnChoosePath
|
||||
//
|
||||
this.btnChoosePath.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnChoosePath.Location = new System.Drawing.Point(369, 10);
|
||||
this.btnChoosePath.Location = new System.Drawing.Point(440, 27);
|
||||
this.btnChoosePath.Name = "btnChoosePath";
|
||||
this.btnChoosePath.Size = new System.Drawing.Size(34, 23);
|
||||
this.btnChoosePath.TabIndex = 5;
|
||||
|
|
@ -82,7 +91,7 @@
|
|||
// label1
|
||||
//
|
||||
this.label1.AutoSize = true;
|
||||
this.label1.Location = new System.Drawing.Point(17, 44);
|
||||
this.label1.Location = new System.Drawing.Point(12, 87);
|
||||
this.label1.Name = "label1";
|
||||
this.label1.Size = new System.Drawing.Size(101, 12);
|
||||
this.label1.TabIndex = 6;
|
||||
|
|
@ -91,7 +100,7 @@
|
|||
// linkLabel1
|
||||
//
|
||||
this.linkLabel1.AutoSize = true;
|
||||
this.linkLabel1.Location = new System.Drawing.Point(112, 44);
|
||||
this.linkLabel1.Location = new System.Drawing.Point(119, 87);
|
||||
this.linkLabel1.Name = "linkLabel1";
|
||||
this.linkLabel1.Size = new System.Drawing.Size(41, 12);
|
||||
this.linkLabel1.TabIndex = 7;
|
||||
|
|
@ -102,7 +111,7 @@
|
|||
// btnRestore
|
||||
//
|
||||
this.btnRestore.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.btnRestore.Location = new System.Drawing.Point(409, 39);
|
||||
this.btnRestore.Location = new System.Drawing.Point(264, 56);
|
||||
this.btnRestore.Name = "btnRestore";
|
||||
this.btnRestore.Size = new System.Drawing.Size(102, 23);
|
||||
this.btnRestore.TabIndex = 8;
|
||||
|
|
@ -112,32 +121,122 @@
|
|||
//
|
||||
// lblUpdatePachJson
|
||||
//
|
||||
this.lblUpdatePachJson.AutoSize = true;
|
||||
this.lblUpdatePachJson.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
|
||||
this.lblUpdatePachJson.Cursor = System.Windows.Forms.Cursors.Hand;
|
||||
this.lblUpdatePachJson.Location = new System.Drawing.Point(198, 44);
|
||||
this.lblUpdatePachJson.ForeColor = System.Drawing.SystemColors.Highlight;
|
||||
this.lblUpdatePachJson.Location = new System.Drawing.Point(166, 89);
|
||||
this.lblUpdatePachJson.Name = "lblUpdatePachJson";
|
||||
this.lblUpdatePachJson.Size = new System.Drawing.Size(131, 12);
|
||||
this.lblUpdatePachJson.Size = new System.Drawing.Size(308, 12);
|
||||
this.lblUpdatePachJson.TabIndex = 9;
|
||||
this.lblUpdatePachJson.Text = "获取最新补丁信息中...";
|
||||
this.lblUpdatePachJson.Text = "[ 获取最新补丁信息中... ]";
|
||||
this.lblUpdatePachJson.TextAlign = System.Drawing.ContentAlignment.TopRight;
|
||||
this.lblUpdatePachJson.Click += new System.EventHandler(this.lblUpdatePachJson_Click);
|
||||
//
|
||||
// lblVersion
|
||||
//
|
||||
this.lblVersion.AutoSize = true;
|
||||
this.lblVersion.Location = new System.Drawing.Point(83, 61);
|
||||
this.lblVersion.Name = "lblVersion";
|
||||
this.lblVersion.Size = new System.Drawing.Size(0, 12);
|
||||
this.lblVersion.TabIndex = 10;
|
||||
//
|
||||
// lblVersionTag
|
||||
//
|
||||
this.lblVersionTag.AutoSize = true;
|
||||
this.lblVersionTag.Location = new System.Drawing.Point(12, 61);
|
||||
this.lblVersionTag.Name = "lblVersionTag";
|
||||
this.lblVersionTag.Size = new System.Drawing.Size(65, 12);
|
||||
this.lblVersionTag.TabIndex = 9;
|
||||
this.lblVersionTag.Text = "当前版本:";
|
||||
//
|
||||
// rbtWechat
|
||||
//
|
||||
this.rbtWechat.AutoSize = true;
|
||||
this.rbtWechat.Checked = true;
|
||||
this.rbtWechat.Location = new System.Drawing.Point(82, 7);
|
||||
this.rbtWechat.Name = "rbtWechat";
|
||||
this.rbtWechat.Size = new System.Drawing.Size(47, 16);
|
||||
this.rbtWechat.TabIndex = 12;
|
||||
this.rbtWechat.TabStop = true;
|
||||
this.rbtWechat.Text = "微信";
|
||||
this.rbtWechat.UseVisualStyleBackColor = true;
|
||||
this.rbtWechat.CheckedChanged += new System.EventHandler(this.radioButtons_CheckedChanged);
|
||||
//
|
||||
// rbtQQ
|
||||
//
|
||||
this.rbtQQ.AutoSize = true;
|
||||
this.rbtQQ.Location = new System.Drawing.Point(140, 7);
|
||||
this.rbtQQ.Name = "rbtQQ";
|
||||
this.rbtQQ.Size = new System.Drawing.Size(35, 16);
|
||||
this.rbtQQ.TabIndex = 13;
|
||||
this.rbtQQ.Text = "QQ";
|
||||
this.rbtQQ.UseVisualStyleBackColor = true;
|
||||
this.rbtQQ.CheckedChanged += new System.EventHandler(this.radioButtons_CheckedChanged);
|
||||
//
|
||||
// rbtTIM
|
||||
//
|
||||
this.rbtTIM.AutoSize = true;
|
||||
this.rbtTIM.Location = new System.Drawing.Point(186, 7);
|
||||
this.rbtTIM.Name = "rbtTIM";
|
||||
this.rbtTIM.Size = new System.Drawing.Size(41, 16);
|
||||
this.rbtTIM.TabIndex = 14;
|
||||
this.rbtTIM.Text = "TIM";
|
||||
this.rbtTIM.UseVisualStyleBackColor = true;
|
||||
this.rbtTIM.CheckedChanged += new System.EventHandler(this.radioButtons_CheckedChanged);
|
||||
//
|
||||
// label5
|
||||
//
|
||||
this.label5.AutoSize = true;
|
||||
this.label5.Location = new System.Drawing.Point(12, 9);
|
||||
this.label5.Name = "label5";
|
||||
this.label5.Size = new System.Drawing.Size(65, 12);
|
||||
this.label5.TabIndex = 16;
|
||||
this.label5.Text = "选择应用:";
|
||||
//
|
||||
// panelMask
|
||||
//
|
||||
this.panelMask.Location = new System.Drawing.Point(140, 127);
|
||||
this.panelMask.Name = "panelMask";
|
||||
this.panelMask.Size = new System.Drawing.Size(157, 58);
|
||||
this.panelMask.TabIndex = 17;
|
||||
this.panelMask.Visible = false;
|
||||
//
|
||||
// rbtQQLite
|
||||
//
|
||||
this.rbtQQLite.AutoSize = true;
|
||||
this.rbtQQLite.Location = new System.Drawing.Point(235, 7);
|
||||
this.rbtQQLite.Name = "rbtQQLite";
|
||||
this.rbtQQLite.Size = new System.Drawing.Size(71, 16);
|
||||
this.rbtQQLite.TabIndex = 18;
|
||||
this.rbtQQLite.Text = "QQ轻聊版";
|
||||
this.rbtQQLite.UseVisualStyleBackColor = true;
|
||||
//
|
||||
// FormMain
|
||||
//
|
||||
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
|
||||
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||
this.ClientSize = new System.Drawing.Size(523, 69);
|
||||
this.ClientSize = new System.Drawing.Size(490, 110);
|
||||
this.Controls.Add(this.rbtQQLite);
|
||||
this.Controls.Add(this.lblUpdatePachJson);
|
||||
this.Controls.Add(this.panelMask);
|
||||
this.Controls.Add(this.lblVersion);
|
||||
this.Controls.Add(this.lblVersionTag);
|
||||
this.Controls.Add(this.label5);
|
||||
this.Controls.Add(this.txtPath);
|
||||
this.Controls.Add(this.rbtTIM);
|
||||
this.Controls.Add(this.lblPathTag);
|
||||
this.Controls.Add(this.rbtQQ);
|
||||
this.Controls.Add(this.btnRestore);
|
||||
this.Controls.Add(this.rbtWechat);
|
||||
this.Controls.Add(this.btnPatch);
|
||||
this.Controls.Add(this.btnChoosePath);
|
||||
this.Controls.Add(this.linkLabel1);
|
||||
this.Controls.Add(this.label1);
|
||||
this.Controls.Add(this.btnChoosePath);
|
||||
this.Controls.Add(this.txtPath);
|
||||
this.Controls.Add(this.btnPatch);
|
||||
this.Controls.Add(this.label2);
|
||||
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
|
||||
this.MinimumSize = new System.Drawing.Size(506, 149);
|
||||
this.Name = "FormMain";
|
||||
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
|
||||
this.Text = "微信防撤回补丁";
|
||||
this.Text = "微信/QQ/TIM防撤回补丁";
|
||||
this.Load += new System.EventHandler(this.FormMain_Load);
|
||||
this.ResumeLayout(false);
|
||||
this.PerformLayout();
|
||||
|
|
@ -145,7 +244,7 @@
|
|||
}
|
||||
|
||||
#endregion
|
||||
private System.Windows.Forms.Label label2;
|
||||
private System.Windows.Forms.Label lblPathTag;
|
||||
private System.Windows.Forms.Button btnPatch;
|
||||
private System.Windows.Forms.TextBox txtPath;
|
||||
private System.Windows.Forms.Button btnChoosePath;
|
||||
|
|
@ -153,6 +252,14 @@
|
|||
private System.Windows.Forms.LinkLabel linkLabel1;
|
||||
private System.Windows.Forms.Button btnRestore;
|
||||
private System.Windows.Forms.Label lblUpdatePachJson;
|
||||
private System.Windows.Forms.Label lblVersion;
|
||||
private System.Windows.Forms.Label lblVersionTag;
|
||||
private System.Windows.Forms.RadioButton rbtWechat;
|
||||
private System.Windows.Forms.RadioButton rbtQQ;
|
||||
private System.Windows.Forms.RadioButton rbtTIM;
|
||||
private System.Windows.Forms.Label label5;
|
||||
private System.Windows.Forms.Panel panelMask;
|
||||
private System.Windows.Forms.RadioButton rbtQQLite;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,126 +1,205 @@
|
|||
using System;
|
||||
using RevokeMsgPatcher.Model;
|
||||
using RevokeMsgPatcher.Modifier;
|
||||
using RevokeMsgPatcher.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web.Script.Serialization;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace RevokeMsgPatcher
|
||||
{
|
||||
public partial class FormMain : Form
|
||||
{
|
||||
Patcher patcher = null;
|
||||
// 当前使用的修改者
|
||||
private AppModifier modifier = null;
|
||||
|
||||
private WechatModifier wechatModifier = null;
|
||||
private QQModifier qqModifier = null;
|
||||
private TIMModifier timModifier = null;
|
||||
private QQLiteModifier qqLiteModifier = null;
|
||||
|
||||
private string thisVersion;
|
||||
private bool needUpdate = false;
|
||||
|
||||
private GAHelper ga = new GAHelper(); // Google Analytics 记录
|
||||
|
||||
public void InitModifier()
|
||||
{
|
||||
// 从配置文件中读取配置
|
||||
JavaScriptSerializer serializer = new JavaScriptSerializer();
|
||||
Bag bag = serializer.Deserialize<Bag>(Properties.Resources.PatchJson);
|
||||
|
||||
// 初始化每个应用对应的修改者
|
||||
wechatModifier = new WechatModifier(bag.Apps["Wechat"]);
|
||||
qqModifier = new QQModifier(bag.Apps["QQ"]);
|
||||
timModifier = new TIMModifier(bag.Apps["TIM"]);
|
||||
qqLiteModifier = new QQLiteModifier(bag.Apps["QQLite"]);
|
||||
|
||||
rbtWechat.Tag = wechatModifier;
|
||||
rbtQQ.Tag = qqModifier;
|
||||
rbtTIM.Tag = timModifier;
|
||||
rbtQQLite.Tag = qqLiteModifier;
|
||||
|
||||
// 默认微信
|
||||
rbtWechat.Enabled = true;
|
||||
modifier = wechatModifier;
|
||||
}
|
||||
|
||||
public FormMain()
|
||||
{
|
||||
InitializeComponent();
|
||||
patcher = new Patcher();
|
||||
txtPath.Text = Util.AutoFindInstallPath();
|
||||
if (!string.IsNullOrEmpty(txtPath.Text))
|
||||
{
|
||||
patcher.IntallPath = txtPath.Text;
|
||||
btnRestore.Enabled = File.Exists(patcher.BakPath);
|
||||
}
|
||||
|
||||
// 标题加上版本号
|
||||
string currentVersion = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version.ToString();
|
||||
if (currentVersion.Length > 3)
|
||||
{
|
||||
currentVersion = " v" + currentVersion.Substring(0, 3);
|
||||
thisVersion = currentVersion.Substring(0, 3);
|
||||
currentVersion = " v" + thisVersion;
|
||||
}
|
||||
this.Text += currentVersion;
|
||||
|
||||
InitModifier();
|
||||
InitControls();
|
||||
|
||||
ga.RequestPageView($"/main/{thisVersion}", $"进入{thisVersion}版本主界面");
|
||||
}
|
||||
|
||||
private void InitControls()
|
||||
{
|
||||
// 自动获取应用安装路径
|
||||
txtPath.Text = modifier.FindInstallPath();
|
||||
btnRestore.Enabled = false;
|
||||
// 显示是否能够备份还原
|
||||
if (!string.IsNullOrEmpty(txtPath.Text))
|
||||
{
|
||||
modifier.InitEditors(txtPath.Text);
|
||||
lblVersion.Text = modifier.GetVersion();
|
||||
btnRestore.Enabled = modifier.BackupExists();
|
||||
}
|
||||
}
|
||||
|
||||
private void btnPatch_Click(object sender, EventArgs e)
|
||||
{
|
||||
if (string.IsNullOrEmpty(txtPath.Text) || !Util.IsWechatInstallPath(txtPath.Text))
|
||||
if (!modifier.IsAllFilesExist(txtPath.Text))
|
||||
{
|
||||
MessageBox.Show("请选择微信安装路径!");
|
||||
MessageBox.Show("请选择正确的安装路径!");
|
||||
return;
|
||||
}
|
||||
patcher.IntallPath = txtPath.Text;
|
||||
|
||||
// 记录点了什么应用的防撤回
|
||||
string enName = GetCheckedRadioButtonNameEn(); // 应用英文名
|
||||
string version = modifier.GetVersion(); // 应用版本
|
||||
ga.RequestPageView($"{enName}/{version}/patch", "点击防撤回");
|
||||
|
||||
EnableAllButton(false);
|
||||
// a.重新初始化编辑器
|
||||
modifier.InitEditors(txtPath.Text);
|
||||
// b.计算SHA1,验证文件完整性,寻找对应的补丁信息
|
||||
try
|
||||
{
|
||||
btnPatch.Enabled = false;
|
||||
string version = patcher.JudgeVersion();
|
||||
if (!string.IsNullOrEmpty(version))
|
||||
{
|
||||
if (version == "done")
|
||||
{
|
||||
MessageBox.Show("已经安装过防撤回补丁了");
|
||||
btnPatch.Enabled = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (patcher.Patch())
|
||||
{
|
||||
MessageBox.Show("成功安装防撤回补丁!原 WeChatWin.dll 文件已经备份到 " + patcher.BakPath + " ,如果有问题可以手动覆盖恢复");
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("防撤回补丁安装失败!");
|
||||
}
|
||||
btnRestore.Enabled = File.Exists(patcher.BakPath);
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("当前微信版本不被支持:" + Util.GetFileVersion(patcher.DllPath));
|
||||
}
|
||||
modifier.ValidateAndFindModifyInfo();
|
||||
}
|
||||
catch (BusinessException ex)
|
||||
{
|
||||
ga.RequestPageView($"{enName}/{version}/patch/sha1/ex/{ex.ErrorCode}", ex.Message);
|
||||
MessageBox.Show(ex.Message);
|
||||
return;
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
ga.RequestPageView($"{enName}/{version}/patch/sha1/ex/{ex.HResult.ToString("x4")}", ex.Message);
|
||||
MessageBox.Show(ex.Message + " 请以管理员权限启动本程序,并确认当前应用(微信/QQ/TIM)处于关闭状态。");
|
||||
return;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
ga.RequestPageView($"{enName}/{version}/patch/sha1/ex/{ex.HResult.ToString("x4")}", ex.Message);
|
||||
MessageBox.Show(ex.Message);
|
||||
return;
|
||||
}
|
||||
finally
|
||||
{
|
||||
EnableAllButton(true);
|
||||
btnRestore.Enabled = modifier.BackupExists();
|
||||
}
|
||||
// c.打补丁
|
||||
try
|
||||
{
|
||||
modifier.Patch();
|
||||
ga.RequestPageView($"{enName}/{version}/patch/succ", "防撤回成功");
|
||||
MessageBox.Show("补丁安装成功!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
MessageBox.Show(ex.Message + " 请以管理员权限启动本程序,并确认微信处于关闭状态。");
|
||||
ga.RequestPageView($"{enName}/{version}/patch/ex/{ex.HResult.ToString("x4")}", ex.Message);
|
||||
MessageBox.Show(ex.Message + " 请以管理员权限启动本程序,并确认当前应用(微信/QQ/TIM)处于关闭状态。");
|
||||
}
|
||||
btnPatch.Enabled = true;
|
||||
finally
|
||||
{
|
||||
EnableAllButton(true);
|
||||
btnRestore.Enabled = modifier.BackupExists();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void txtPath_TextChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(txtPath.Text))
|
||||
if (modifier.IsAllFilesExist(txtPath.Text))
|
||||
{
|
||||
patcher.IntallPath = txtPath.Text;
|
||||
btnRestore.Enabled = File.Exists(patcher.BakPath);
|
||||
modifier.InitEditors(txtPath.Text);
|
||||
btnRestore.Enabled = modifier.BackupExists();
|
||||
}
|
||||
else
|
||||
{
|
||||
btnPatch.Enabled = false;
|
||||
btnRestore.Enabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void btnChoosePath_Click(object sender, EventArgs e)
|
||||
{
|
||||
FolderBrowserDialog dialog = new FolderBrowserDialog();
|
||||
dialog.Description = "请选择微信安装路径";
|
||||
dialog.Description = "请选择安装路径";
|
||||
if (dialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
if (string.IsNullOrEmpty(dialog.SelectedPath) || !Util.IsWechatInstallPath(dialog.SelectedPath))
|
||||
if (string.IsNullOrEmpty(dialog.SelectedPath) || !modifier.IsAllFilesExist(dialog.SelectedPath))
|
||||
{
|
||||
MessageBox.Show("无法找到微信关键文件,请选择正确的微信安装路径!");
|
||||
MessageBox.Show("无法找到此应用的关键文件,请选择正确的安装路径!");
|
||||
}
|
||||
else
|
||||
{
|
||||
txtPath.Text = dialog.SelectedPath;
|
||||
btnRestore.Enabled = false;
|
||||
// 显示是否能够备份还原
|
||||
if (!string.IsNullOrEmpty(txtPath.Text))
|
||||
{
|
||||
modifier.InitEditors(txtPath.Text);
|
||||
lblVersion.Text = modifier.GetVersion();
|
||||
btnRestore.Enabled = modifier.BackupExists();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void btnRestore_Click(object sender, EventArgs e)
|
||||
{
|
||||
btnRestore.Enabled = false;
|
||||
EnableAllButton(false);
|
||||
try
|
||||
{
|
||||
if (File.Exists(patcher.BakPath))
|
||||
{
|
||||
File.Copy(patcher.BakPath, patcher.DllPath, true);
|
||||
MessageBox.Show("还原成功");
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("备份文件不存在");
|
||||
}
|
||||
modifier.Restore();
|
||||
MessageBox.Show("还原成功!");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
MessageBox.Show(ex.Message);
|
||||
}
|
||||
btnRestore.Enabled = File.Exists(patcher.BakPath);
|
||||
EnableAllButton(true);
|
||||
btnRestore.Enabled = modifier.BackupExists();
|
||||
}
|
||||
|
||||
private void linkLabel1_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
|
||||
|
|
@ -131,32 +210,127 @@ namespace RevokeMsgPatcher
|
|||
private async void FormMain_Load(object sender, EventArgs e)
|
||||
{
|
||||
// 异步获取最新的补丁信息
|
||||
Task<string> t = new Task<string>(() =>
|
||||
string json = await HttpUtil.GetPatchJsonAsync();
|
||||
if (string.IsNullOrEmpty(json))
|
||||
{
|
||||
return new WebClient().DownloadString("https://huiyadanli.coding.me/i/patch.json");
|
||||
});
|
||||
t.Start();
|
||||
string json = await t;
|
||||
if(string.IsNullOrEmpty(json))
|
||||
{
|
||||
lblUpdatePachJson.Text = "获取失败";
|
||||
|
||||
} else
|
||||
{
|
||||
patcher.SetNewPatchJson(json);
|
||||
lblUpdatePachJson.Text = "获取成功";
|
||||
lblUpdatePachJson.Text = "[ 获取最新补丁信息失败 ]";
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
JavaScriptSerializer serializer = new JavaScriptSerializer();
|
||||
Bag bag = serializer.Deserialize<Bag>(json);
|
||||
|
||||
wechatModifier.Config = bag.Apps["Wechat"];
|
||||
qqModifier.Config = bag.Apps["QQ"];
|
||||
timModifier.Config = bag.Apps["TIM"];
|
||||
qqLiteModifier.Config = bag.Apps["QQLite"];
|
||||
|
||||
if (Convert.ToDecimal(bag.LatestVersion) > Convert.ToDecimal(thisVersion))
|
||||
{
|
||||
needUpdate = true;
|
||||
lblUpdatePachJson.Text = $"[ 存在最新版本 {bag.LatestVersion} ]";
|
||||
}
|
||||
else
|
||||
{
|
||||
needUpdate = false;
|
||||
lblUpdatePachJson.Text = "[ 获取成功,点击查看更多信息 ]";
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine(ex.Message);
|
||||
lblUpdatePachJson.Text = "[ 更换新配置时异常 ]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void lblUpdatePachJson_Click(object sender, EventArgs e)
|
||||
{
|
||||
string versions = "";
|
||||
patcher.TargetFiles.ForEach(t =>
|
||||
string tips = "";
|
||||
if (needUpdate)
|
||||
{
|
||||
versions += t.Version + Environment.NewLine;
|
||||
});
|
||||
MessageBox.Show("当前所支持的微信版本:" + Environment.NewLine + versions);
|
||||
tips += "【当前存在最新版本,点击确定进入软件主页下载最新版本。】" + Environment.NewLine + Environment.NewLine;
|
||||
}
|
||||
tips += "支持以下版本" + Environment.NewLine;
|
||||
tips += " ➯ 微信:" + wechatModifier.Config.GetSupportVersionStr() + Environment.NewLine;
|
||||
tips += " ➯ QQ:" + qqModifier.Config.GetSupportVersionStr() + Environment.NewLine;
|
||||
tips += " ➯ QQ轻聊版:" + qqLiteModifier.Config.GetSupportVersionStr() + Environment.NewLine;
|
||||
tips += " ➯ TIM:" + timModifier.Config.GetSupportVersionStr() + Environment.NewLine;
|
||||
|
||||
DialogResult dr = MessageBox.Show(tips, "当前支持防撤回的版本", MessageBoxButtons.OKCancel);
|
||||
if (dr == DialogResult.OK && needUpdate)
|
||||
{
|
||||
System.Diagnostics.Process.Start("https://github.com/huiyadanli/RevokeMsgPatcher/releases");
|
||||
}
|
||||
}
|
||||
|
||||
private void radioButtons_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
EnableAllButton(false);
|
||||
RadioButton radioButton = sender as RadioButton;
|
||||
// 切换使用不同的防撤回对象
|
||||
if (rbtWechat.Checked)
|
||||
{
|
||||
modifier = (WechatModifier)rbtWechat.Tag;
|
||||
}
|
||||
else if (rbtQQ.Checked)
|
||||
{
|
||||
modifier = (QQModifier)rbtQQ.Tag;
|
||||
}
|
||||
else if (rbtTIM.Checked)
|
||||
{
|
||||
modifier = (TIMModifier)rbtTIM.Tag;
|
||||
}
|
||||
else if (rbtQQLite.Checked)
|
||||
{
|
||||
modifier = (QQLiteModifier)rbtQQLite.Tag;
|
||||
}
|
||||
txtPath.Text = modifier.FindInstallPath();
|
||||
ga.RequestPageView($"{GetCheckedRadioButtonNameEn()}/{lblVersion.Text}/switch", "切换标签页");
|
||||
EnableAllButton(true);
|
||||
lblVersion.Text = "";
|
||||
btnRestore.Enabled = false;
|
||||
// 显示是否能够备份还原
|
||||
if (!string.IsNullOrEmpty(txtPath.Text))
|
||||
{
|
||||
modifier.InitEditors(txtPath.Text);
|
||||
lblVersion.Text = modifier.GetVersion();
|
||||
btnRestore.Enabled = modifier.BackupExists();
|
||||
}
|
||||
}
|
||||
|
||||
private string GetCheckedRadioButtonNameEn()
|
||||
{
|
||||
if (rbtWechat.Checked)
|
||||
{
|
||||
return "wechat";
|
||||
}
|
||||
else if (rbtQQ.Checked)
|
||||
{
|
||||
return "qq";
|
||||
}
|
||||
else if (rbtTIM.Checked)
|
||||
{
|
||||
return "tim";
|
||||
}
|
||||
else if (rbtQQLite.Checked)
|
||||
{
|
||||
return "qqlite";
|
||||
}
|
||||
return "none";
|
||||
}
|
||||
|
||||
private void EnableAllButton(bool state)
|
||||
{
|
||||
foreach (Control c in this.Controls)
|
||||
{
|
||||
if (c is Button)
|
||||
{
|
||||
c.Enabled = state;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,78 +120,289 @@
|
|||
<assembly alias="System.Drawing" name="System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
|
||||
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>
|
||||
AAABAAEAICAAAAEAIACoEAAAFgAAACgAAAAgAAAAQAAAAAEAIAAAAAAAABAAAAAAAAAAAAAAAAAAAAAA
|
||||
AADn7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/W2t//zdHW/+bt8f/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5u3y/6Omqf/N1Nb/sbW4/83R1v/m7fH/5+3y/+ft
|
||||
8v/m7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5Oru/7O3uf/O0tf/y9DU/7C0
|
||||
t/+5vcD/s7i6/9TZ3f/n7PL/5+zy/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+zy/8jN
|
||||
0f+1ubz/6Ozx/8LGyf/Bxsn/ioyN/56ho/+us7f/19zg/+bt8v/m7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5u3y/9/l6f+foqT/qq2w/6isrf/e5Of/rLCy/7vAw/+bnqD/rrK0/83S1v/m7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/ur7C/6eqrf/Axcj/5u3y/8PHy/+anZ//mJqc/87S1f/m7fL/tru+/6isr//n7fH/xcrN/6yw
|
||||
s//d4uf/5+3x/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+zy/7a6vf+6v8L/5evx/66ytf/S2Nz/5+zy/7GzuP9vcHH/hoiI/5+jpP/L0NP/wMTI/+ft
|
||||
8v/m7PH/5uzx/7a5vf+xtbj/5Orv/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7PL/pKmr/7m9wP+7wMT/tbm7/7e8v//n7PL/5+zy/9HU2f+fo6X/ztTX/62w
|
||||
s/+Hi43/zdLX/+bt8f/m7fL/5+zy/+Hn7f+vsrb/tbm9/+fs8f/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+fs8v+5vcH/4efr/+Tp7v/n7PL/t7u//+fs8v/n7fL/5+3y/7i8
|
||||
v/+ipaj/5u3x/9bc4P/Cx8v/dHd5/+Lo7f/n7fH/5+3y/+bt8v/d4+b/q6+y/8DFyf/m7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/9/l6f+8wcT/293x/+To8f+3u77/5+zy/+ft
|
||||
8v/n7fH/5u3x/9DV2f+nqq3/0tbb/+bt8v/M0db/kZWY/7zAxP/h5+z/5+3y/+fs8v/m7PL/0Nbb/6mt
|
||||
sP/W2+D/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3x/7a5vf+7se3/0M7w/7a7
|
||||
vv/n7PH/5+3y/+ft8v/n7fL/5u3y/+ft8f+9wMT/qq6x/+Lo7P/g5+z/vcLG/2FkZv/S19z/4efr/+ft
|
||||
8v/m7fL/6Ozy/7q+wf+zt7r/5uzx/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/m7fH/trm9/+fs
|
||||
8f/n7fL/uL2//+ft8f/n7fL/6Ozy/+Xr8v+2u7//s7e6/+br8f/k6e7/q6+y/7i9wP/m7fH/4Obq/5OW
|
||||
mf+nq6//3ePn/+bs8f/n7fL/5+3y/9zi5/+prrH/p6uu/+Hl6f/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/Gys//2t/j/+bt8v+4vcD/5evw/+bs8f+5vcH/rbK1/97k6v/T2Nz/pqms/+Dl6v/m7fL/1tve/6er
|
||||
rv/N0tb/5+3y/+ft8v+kqKz/4+nu/97k6P/m7PL/5+3y/9LX2/+5vcH/o6ap/+fs8//n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8f+xtbj/trq8/7e8v//Axcn/rbK1/9vh5f/n7fL/5u3x/8LGyv/m7PH/qa2v/9je
|
||||
4v/n7PL/6Ozx/8DFyP+qrrH/5Orv/+bs8v/Q1dr/zNHW/83T1/+tsLP/s7e5/6yvsv/Z3+P/6Ozy/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+fs8f/Y3eH/rK+z/9PX3P/n7fL/5+3y/+ft8v/m7fH/wMXI/+bs
|
||||
8v/m7PL/sLW3/9LY2//m7fH/6Ozy/+Ho7P+orK//xcrN/+Po7f+1ubz/rLCy/6+ytf/P1Nj/5+3x/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/7a6vv/n7PH/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8f/Cx8r/5uzx/+ft8v/m7PL/q6+y/+bs8v/n7fL/5+3y/+bt8v/JztL/oaSn/6irrv/Hy8//5+3x/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/2+Hm/7y/wv/n7fL/5+3y/+jt
|
||||
8f/m7PD/ztTY/9Xa3v/m7fL/5+3y/+fs8f+wtbf/5uzy/+ft8v/n7fL/5+3y/+fs8v/m7PH/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/sba4/+Xq
|
||||
7//Z3uL/sbW4/7C0uP/X29//4ujs/8DEx//m7PH/4ufr/7W5vP/n7fH/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/k6e3/rbCz/7G1t/+1ubv/oKKl/+Xq7//n7PL/4+jt/7S4uv+tsbT/5evv/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/P1Nj/k5aY/7zBxP/m7PL/5+zz/+Tp7f+yt7r/r7O2/8jN0f/n7fH/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+bt8v/h5+v/rLCz/7q/wv+vsrb/rrO2/+Ln7P/m7fL/5u3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/29/k/+Xq7//m7PP/5u3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+bt8v/m7PL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5u3y/+bt
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft8v/n7fL/5+3y/+ft
|
||||
8v/n7fL/5+3y/+ft8v/n7fL/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAABAAEAQEAAAAEAIAAoQgAAFgAAACgAAABAAAAAgAAAAAEAIAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FOAJPRTgOT0U4KE5EN1BPRTh2T0U4jU9FN5FPRTiRT0U4kU9F
|
||||
OJFPRTiRT0Q4j09FN35PRTdcT0U4ME9FOBRPRTgET0U4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTcATkQ4Ek9FOEZORTiHT0U3yU9FN+VPRDf3T0Q3/09F
|
||||
Nv9PRDb/T0Q1/09ENf9PRDX/T0Q1/09FNv9PRDf/T0Q3+09FN+tPRTfTTkU4m09FOFhPRTgcT0U4Ak9F
|
||||
OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FOAJPRTcqT0U4eE9FOM1ORDf1T0Q2/09E
|
||||
Nv9ORTn/TkZD/05IVf9NSmP/TUxt/01Ndv9NTnr/TU13/01Mb/9NS2X/TklY/05HR/9ORTr/T0U2/09E
|
||||
Nv9PRTf7T0U4209FOJVPRTg8T0Q4CE9FOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4Ak5FOCRPRTiNT0Q4409F
|
||||
N/1PRDX/TkU8/01JVv9MTn//S1Ol/0pWvP9KWM7/SlnU/0pZ1/9KWtj/SlrZ/0pa2P9KWtf/SlnV/0pZ
|
||||
0f9KV8L/S1Ss/0xQi/9NSl//TkZC/09ENv9PRDb/T0U48U9FOKtPRTg6T0U4BAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTcATkU3Ek5F
|
||||
OHJPRTjfT0Q3/05FN/9OR0n/TE59/0tUrv9KWdD/SlrY/0pa2P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa2P9KWtj/SlnU/0pWuv9MUIz/TUhV/05FOf9PRDb/T0Q3709F
|
||||
OJdPRTgkT0U4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AABPRTgCT0U4Mk9FOLtPRDf7T0Q2/05HR/9MT4f/SlfC/0pZ1/9KWtj/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtj/SlnY/0pY
|
||||
y/9MUZj/TUhV/05FN/9PRDf9T0U4105FN1RPRTgGAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABPRTgGTkU3XE9FN+FPRDf/TkU8/01Mc/9KVr3/SlnX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrY/0pYyv9MT4j/TkZF/05ENv9ORTfxTkU3h09FOA5PRTcAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTgIT0U4ek9FN/FPRTb/TkdM/0tSn/9KWdT/SlrY/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnX/0tVtf9NSl//TkU3/09F
|
||||
N/tPRTelT0U4GE5ENwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTgKT0U4iU9FN/dORTj/TUpg/0pW
|
||||
vP9KWdj/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtj/SljK/01NeP9ORTn/T0Q3/U9FOLdPRTgcT0U4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTgIT0U4hU9F
|
||||
N/lPRTf/TkdJ/0pWv/9KWtn/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWdP/TE+L/05FO/9PRDf/T0U4s09FNxgAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AABPRTgCT0U4bE9FN/VPRTf/T0U3/05FOP9NTXP/SljO/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ1f9MT4z/TkU7/09E
|
||||
N/1PRTihT0U3DgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABPRTgAT0U4Rk9FN+1ORTb/TUtn/0xNe/9ORTn/TkU3/01Mcf9KWM3/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlnV/0xPiP9ORTj/T0U3+09FOHxPRTgEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4Ik9FONFPRTb/TUlX/0pXxP9KWdL/TE6A/05F
|
||||
Of9ORTf/TUxv/0pYzf9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWdL/TUxz/05FN/9PRTftT0U4SE9FOAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAATkU4Bk5FOJ1PRDf9TkZD/0tU
|
||||
sP9KWtj/SlrX/0pZ0v9MToD/TkU5/05FN/9NTHD/SljN/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pXx/9NSVn/T0Q2/09F
|
||||
OM1PRTgcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4AE9F
|
||||
OEhPRTfzTkU4/0xQjP9KWdf/SlrX/0pa1/9KWtf/SlnS/0xOgP9ORTn/TkU3/01McP9KWM3/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtj/S1St/05GQP9PRTf9T0U4g09FOAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAE9FOA5PRTi9T0Q2/01JWv9KWM3/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWdL/TE6B/05F
|
||||
OP9ORTf/TUxx/0pYzf9KWdf/SlrX/0pa1/9KWtf/SlrX/0pZ1P9KWcz/SlrW/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlnW/0pZzf9MTXv/TkQ2/09FN+VPRDgsT0U4AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FOABORThYT0U4905FPP9LU6X/SlrY/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pZ0/9MToL/TkU5/05FN/9NTG//SljN/0pa1/9KWtf/SlrX/0pZ1P9LToL/TlOQ/0pa
|
||||
1v9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pYzf9QUHH/Sla//05HTP9PRDf/T0U4k09F
|
||||
OAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTgKT0U4vU9ENv9NSmT/SlnS/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnS/0xOgv9ORTj/TkU2/01Mb/9KWMz/SlrX/0pZ
|
||||
0/9LToP/TkQ1/01Tlv9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ0v9NTXL/T0xh/0pa
|
||||
1v9MT4n/TkU3/09FN+VPRTgmAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTgAT0U4PE9F
|
||||
N/FORTr/S1Ol/0pZ2P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWdP/TE+C/05F
|
||||
Of9ORTf/TUxt/0pXyf9LTX//TkQ2/05ENP9NUpb/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrW/0pZ
|
||||
0v9PUoX/T0U2/05Mav9KWtf/SlfC/05HSv9PRTf9T0U4eE9FOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAATkU3Ak9FOI1PRTf/TkhV/0pYzv9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pZ0v9MToL/TkU5/05FNv9NR0//TkQ1/09FNf9ORDT/TVKW/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pYzv9OUHr/T0U3/05ENf9MTXX/SlrX/0pZ1/9NTXX/T0Q2/05FOMVORTgOAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FNxRPRTfRTkQ2/0xOgP9KWtj/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnS/0xOgP9NRDb/TkQ1/09FNf9PRTX/TkQ0/01S
|
||||
lv9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlnW/0tYw/9NSmH/TkU1/09FNf9ORDX/T1Wb/0pa1/9KWtj/S1Oq/05F
|
||||
Ov9PRTfzT0U4OAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTg8T0U38U5FPP9LVLH/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ0v9MTHT/TkQ1/09F
|
||||
Nf9PRTX/T0U1/05ENP9NU5b/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtb/SlnP/01SlP9PR0b/TkQ0/09FNf9PRTX/TkQ3/0xX
|
||||
uf9KWtf/SlrX/0pYyv9OSE7/T0Q3/U9FOHpPRTcAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTgAT0U4eE5E
|
||||
N/1OSFD/SljK/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ
|
||||
0v9MTHP/TkQ1/09FNf9PRTX/T0U1/09FNf9ORDT/TVKV/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWc3/TFOc/09KVv9PRTb/T0U1/09F
|
||||
Nf9PRTX/T0U1/09KUv9LWcz/SlrX/0pa1/9KWdf/TExz/09ENv9PRTixT0U4CAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAT0U4Bk9FOKVPRTb/TUxt/0pZ1v9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pZ0P9MS2//TkQ1/09FNf9PRTX/T0U1/09FNf9PRTX/TkQ0/09MZP9KWMv/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1v9KWdP/S1nO/0tUp/9UVof/iYaO/7u3
|
||||
sv9ORDT/T0U1/2phVP/Mycb/YllL/05ENP9OTnP/SlrW/0pa1/9KWtf/SlrZ/0tQkP9ORTb/T0U41U9F
|
||||
OBoAAAAAAAAAAAAAAAAAAAAAAAAAAE5FOBBPRTjFTkQ1/0xPhP9KWtn/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZz/9MS27/TkQ1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/05E
|
||||
NP9PRTf/UU1g/0xRlP9LUpv/TFat/01Yuv9NWcH/TVnB/01Zvv9NV7L/S1Oh/0tRlv9PUon/Tkpb/09I
|
||||
Sf9iWk7/zsvH/9jW0/+qpZ7/T0U1/8K/u//Kx8T/0c/M/1NKOv9ORDT/TVex/0pa1/9KWtf/SlrX/0pa
|
||||
2P9LVLD/TkU8/09FN/FPRTg4AAAAAAAAAAAAAAAAAAAAAAAAAABPRTgkTkU35U5FN/9LU6H/SlrY/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pYz/9MS2r/TkQ1/09FNf9PRTX/T0U1/09F
|
||||
Nf9PRTX/T0U1/09FNf9PRTX/T0Q0/05ENP9ORDT/TkQ1/09GOf9PRj7/T0dA/09HQP9PRz//T0Y7/05F
|
||||
Nv9ORDT/TkQ0/05ENP9PRTX/mJKJ/6unoP+HgXb/zcrG/2ZeUP/Ewb3/nJeP/66qo/9waFz/T0pX/0pZ
|
||||
zv9KWtf/SlrX/0pa1/9KWtf/SlfC/05GRP9PRTf5TkU4TgAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4Mk9F
|
||||
N+9ORTv/S1W0/0pa2P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pYzv9MSmf/TkQ1/09F
|
||||
Nf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09F
|
||||
Nf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/6Kdlf9waFv/T0U1/8TBvP9vZ1r/o56X/09F
|
||||
Nf+gm5P/cmpf/0xSl/9KWtb/SlrX/0pa1/9KWtf/SlrX/0pYyv9OR0z/T0U3+09FOFgAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAE9FODpPRTfzTkU+/0tVuv9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pY
|
||||
zf9MSmX/TkQ1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09F
|
||||
Nf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf+QioD/jIZ8/09F
|
||||
Nf/DwLv/YFdI/7y5s/9PRTX/sa2m/2FcZv9KWMr/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWM7/TkhT/09E
|
||||
NvtPRThYAAAAAAAAAAAAAAAAAAAAAAAAAABPRTdCT0U39U5GQP9KVr7/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pYzP94eJT/XFNE/09FNf9+d2z/VEo7/09FNf9SSTn/f3ht/4mDeP9bUkP/T0U1/1NJ
|
||||
Of+AeW7/gntw/09FNf9yal3/YFdJ/09FNf91bmH/XVRF/1ZNPv+HgHb/c2tf/3t0af9PRTX/Ukk5/4iB
|
||||
d/9qYVT/WVBB/7Wxq/+uqaL/enJn/09FNf+inZX/qaWe/5yXkf9MU5z/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlnQ/01JV/9PRDb7T0U4WAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U3Qk9FN/VORkD/Sla+/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pYy/9UUWn/9PT0/6GclP9dU0X/+Pj4/4mDeP9PRTX/raih/9XT
|
||||
0P+3s63/wL24/09FNf/LyMT/1NHO/8fEwP95cWX/trKt/4N8cf9PRTX/wb25/3lxZf+tqaL/zszI/9nX
|
||||
1f/T0c7/T0U1/4uEev/d3Nr/nJaO/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/05ENP9OTGX/SlnT/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ0P9NSVf/T0Q2+09FOFgAAAAAAAAAAAAAAAAAAAAAAAAAAE9F
|
||||
ODpPRTfzTkY+/0tWuv9KWtf/SlrX/0pa1/9KWtf/SlrX/0pYyf9MSVz/h4B2/8XCvv/PzMn/koyC/9LQ
|
||||
zf/Bvrn/T0U1/+Xj4v+2sq3/qqWf/6mknf9kW03/5+bl/1BGNv9PRTX/T0U1/7ayrf+DfHH/T0U1/8G9
|
||||
uf95cWX/rKeg/7ayrf+dmI//09HO/09FNf+Ykon/opyV/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09E
|
||||
NP9PSUr/S1jD/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWM7/TkhT/09ENvtPRThYAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABPRTcyT0Q3705FO/9LVbT/SlrY/0pa1/9KWtf/SlrX/0pXyP9NSVv/TkQ1/8G+
|
||||
uf+IgXf/ycbC/97c2/94cWX/6Ofm/1VMPP/f3dv/qaSd/5SOhf/x8fH/YFdJ/+rp6f9WTD3/T0U1/09F
|
||||
Nf+2sq3/mZSL/09FNf/IxcD/eXFl/1hPQP+WkIf/wLy3/9PRzv9PRTX/mJKJ/6Kclf9PRTX/T0U1/09F
|
||||
Nf9PRTX/T0U1/09FNf9ORTr/TFOg/0pa1v9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SljK/05H
|
||||
TP9PRTf7T0U4WAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4JE9FOOdORDj/S1Kj/0pa2f9KWtf/SlrX/0pZ
|
||||
z/9NSVj/TkQ1/1hOP//o5+b/U0o6/4uEev/r6un/UEY2/7y4s/+Ignf/hn90/+fl5P/b2db/sq2n/09F
|
||||
Nf+uqqP/5uXk/9LQzf95cWX/trKt/+vq6f/Qzcr/7e3s/1xSRP9kXE7/5ePi/93b2f+rpp//W1JD/+De
|
||||
3P/i4d//m5WN/09FNf9PRTX/T0U1/09FNf9ORTn/TlOX/0pZ1v9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pXw/9ORkT/T0U3+U9FOE4AAAAAAAAAAAAAAAAAAAAAAAAAAE9EOBBPRTjHTkQ1/0xP
|
||||
hf9KWtn/SlrX/0pa1/9KWdP/TE5+/05FNv9SSDn/aF9S/09FNf9USjv/Zl1Q/09FNf9dVEX/XVRF/09F
|
||||
Nf9fVkf/aWFT/09FNf9PRTX/T0U1/2deUf9uZln/UEY2/7ayrf+EfXL/bmZZ/1lQQf9PRTX/T0U1/15V
|
||||
R/9uZln/UUc4/1JIOP+qpZ7/sq6o/2JZS/9PRTX/T0U1/09FNf9ORTj/T1ON/0pa1f9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa2P9LVbL/TkU9/09FN/NPRTg6AAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AABPRTgGT0U4pU9FNv9NTG7/SlrX/0pa1/9KWtf/SlrX/0pZ0/9LToL/TkU2/09FNf9PRTX/T0U1/09F
|
||||
Nf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf+2sqz/g3xx/09F
|
||||
Nf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/XVRF/2lgU/9PRTX/T0U1/09FNf9ORTr/T1SU/0pZ
|
||||
1P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtn/TFGR/05FN/9PRTjXT0U4HAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAT0U4AE9FOHpPRDf9TkhS/0pYyv9KWtf/SlrX/0pa1/9KWtf/SlnV/0tP
|
||||
hv9ORTf/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09F
|
||||
Nf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/05E
|
||||
NP9ORkH/TVSh/0pa1v9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnX/01N
|
||||
dP9PRDb/T0U4tU9FOAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTg+TkQ3805FPf9LVbP/SlrY/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWdT/S0+J/05FN/9PRTX/T0U1/09FNf9PRTX/xMG9/2JZS/9WTD3/2dfU/46H
|
||||
fv+EfXL/gHlu/5+akv+Nh33/m5aN/4uFev9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/09F
|
||||
Nf9PRTX/T0U1/05ENP9QTF3/S1a3/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pYy/9OSFD/T0Q2/U9FOHxPRTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U3Fk9F
|
||||
N9VPRDb/TE+E/0pa2P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ1f9LT4v/TkU4/09FNf9PRTX/T0U1/9XT
|
||||
0P9lXE7/T0U1/7i0r/9aUUL/i4V6/4qDef/g393/1NLP/6ijnP+UjoT/T0U1/09FNf9PRTX/T0U1/09F
|
||||
Nf9PRTX/T0U1/09FNf9ORDT/TkQ0/05ENf9QSk7/S1e//0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa2P9LVK7/TkU7/09FN/VPRTg6AAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAE9FOAJPRTiRT0U2/05JVv9KWM7/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnV/0tQ
|
||||
j/9ORTj/T0U1/09FNf/V09D/ZVxO/09FNf+4tK//WlFC/4uFev/Fwr7/p6Ka/7Svqf/V0s//lI6E/09F
|
||||
Nf9PRTX/T0U1/09FNf9PRTX/T0U1/09FNf9ORDX/TkdB/05MYf9PRjz/TkU2/01LZv9KWMn/SlrY/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWdf/TU13/09ENv9PRTjJT0U4EAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4QE9FN/NORTv/S1Oo/0pa2P9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWdX/S1CS/05FOP9TSjr/1tTR/2lhU/9QRjb/uLSv/1pRQv+LhXr/+Pj4/2Rb
|
||||
Tf9xaV3/+vn6/5SOhP9PRTX/T0U1/05ENP9ORDT/TkU1/05ENv9PSlX/TVCF/0tXwv9KWdT/TE+J/05F
|
||||
Ov9ORTb/TUto/0pXyf9KWtj/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlfE/05H
|
||||
TP9PRTf9T0U4fE9FOAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FOAxPRTjBT0Q2/01L
|
||||
Z/9KWdL/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ1f9LUZT/19bY/+Xk4//l5OP/fXZq/9jW
|
||||
1P+Oh37/g3xy/7OvqP9PRTX/TkU1/7y4s/+LhXz/TkU4/05FOv9ORkL/T01o/01PgP9MV7b/SlnP/0pa
|
||||
1/9KWtf/SlrX/0pZ1P9MUIv/TkU7/09FNv9NS2b/SlfK/0pa2P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrY/0xQjf9ORTf/T0U3509FOCgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AABPRTgAT0U4Xk9FN/lORT3/S1Op/0pa2P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnV/0tR
|
||||
mP9ORTn/T0U1/09FNf9PRTX/T0U1/09FNf9PRTX/T0U1/0xLZf9NUYv/TlSY/05Ysf9KV8H/SljH/0pZ
|
||||
1P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnU/0xPiv9ORTr/TkQ2/01LaP9KV8n/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pXxf9OSE7/T0U3/09FOJtPRTgGAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FOBBPRTjBTkQ2/01JXf9KWc7/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWdb/S1Gb/05FO/9PRTX/T0U1/09FNf9PRTX/T0U1/05ENP9NUpf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWdX/TFCM/05F
|
||||
PP9ORTb/TUpl/0pXyP9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ1/9MTn//TkU2/09FN+lPRTgwT0U4AAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABPRTcAT0U4Tk9FN/VORTn/TFCR/0pa
|
||||
2P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ1v9KUp3/TkU7/09FNf9PRTX/T0U1/09F
|
||||
Nf9ORDT/TVKW/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pZ1P9MUIv/TkU7/09FNv9NSmb/SlfH/0pa2P9KWtf/SlrX/0pa2P9LVbL/TkZC/09F
|
||||
N/1PRDiJT0U4AgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE5F
|
||||
OAhPRDihT0Q3/05GRf9LVbP/SlnY/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnW/0tS
|
||||
oP9ORT3/T0U1/09FNf9PRTX/TkQ0/01Slv9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnV/0xPjP9ORTz/TkU2/01KZf9KV8j/SlrX/0pa
|
||||
1/9KWMn/TUlb/05FNv9PRTjRT0U4HgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAT0U3Jk9FONdORDb/TUlb/0pXyP9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWdb/SlOj/05FPv9PRTX/T0U1/05ENP9NUpb/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWdT/TFCK/05F
|
||||
O/9ORTb/TUpl/0pXyP9KWdT/TE15/05FN/9PRTfxT0U4UE9FOAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FNwBPRTdOT0U3705FN/9NS2z/SljO/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ1v9KU6b/TkU+/05FNf9ORDT/TVKW/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pZ1f9MUI3/TkU7/05FNv9NS2b/TE+D/05FOv9PRTf7T0U4g09FOAQAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4BE9F
|
||||
N3RPRTf3TkU3/01Ndf9KWM//SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnW/0pT
|
||||
qP9ORkD/TkQ0/01Slv9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlnV/0xQjf9ORj7/T0Q3/09FN/9PRTf9T0U4qU9F
|
||||
OBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABPRTgIT0U4jU9FN/tORTj/TUxy/0pYzP9KWtj/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWdb/SlSr/01FP/9NU5b/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWdH/TUtn/09F
|
||||
Nv9PRTf/T0U3u09FOBxPRTcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FOA5PRTiVT0U3+U5FNv9NS2b/SlbA/0pZ
|
||||
2P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pZ1v9KU6f/TlOT/0pa1v9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
2P9KWM3/TE6A/05FPP9PRDf9T0U4v09FOCBPRTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4Ck9F
|
||||
OINPRTf1TkU2/05IT/9LU6X/SlnW/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa2P9KVrr/TUpk/05EOP9PRDf9T0U3r09FNx5ORDcAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAABPRTgGT0U4ZE9FN+VPRDb/TkU+/0xNe/9KV8H/SlrY/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrY/0pYzf9MUJD/TkdI/05ENv9PRTfzT0U4kU9FOBJPRTcAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FNwJPRTc6T0U4w09EN/tPRDb/TkdK/0xQ
|
||||
jf9KV8X/SlrY/0pa2P9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtj/SljO/0tSn/9OSVr/TkU4/09EN/9PRTjdT0U3XE9F
|
||||
OAYAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4AE9F
|
||||
NxRPRTd+T0U35U9FN/9ORDf/TkdO/0xOg/9KVbf/SlnR/0pa2f9KWtj/SlrX/0pa1/9KWtf/SlrX/0pa
|
||||
1/9KWtf/SlrX/0pa1/9KWtf/SlrX/0pa1/9KWtj/SlrZ/0pZ1f9KV8D/S1GU/01JWv9ORTn/T0Q2/09F
|
||||
N/FPRTehT0U4Kk9FOAIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAT0U4Ak9FOCxORTeVT0U36U9FN/9PRDb/TkY+/01KXf9MT4P/S1St/0pX
|
||||
xP9KWM7/SlnV/0pZ2P9KWtj/SlnY/0pZ2P9KWtj/SlnW/0pZ0P9KV8f/S1W2/0xQjv9NS2j/TkZD/09E
|
||||
N/9PRTf/T0U3809FN7NPRThET0U3BgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAT0U4BE9FODBPRTiHT0U31U9F
|
||||
N/dPRDb/T0U2/05FO/9ORkb/TUhV/01Mbf9NTXr/TE6A/0xPhP9MToH/TE58/01Mcf9NSVz/TkdJ/05G
|
||||
Pf9ORTf/T0Q2/09EN/tORDflT0U4nU9EOEZPRTgKT0U4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAT0U4Ak9FNxZPRTdMT0U4mU9FOMtPRTfvT0U3+U9ENv1PRDb/T0U2/09FNv9PRTb/T0U2/09F
|
||||
Nv9PRDb/T0Q2/09EN/lPRTfzT0U32U9FOKdPRTdgT0U4Ik9FOARPRTgAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAE9FOARPRTgST0U4ME9FN1JPRTh+TkU3o09F
|
||||
OLFPRTi9T0U4wU9FOL9PRTi1T0U4qU9FOItPRThaT0U4Ok5FNxhPRTcGT0U4AAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AABPRTgAT0U4Ak9FOARPRTgET0U4Bk9FOAZPRTgGT0U4BE9FOARPRTgCT0U4AE9FOAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
|
||||
AAAAAAAA////////////////////////////////////8B////////4AAP//////+AAAH//////AAAAH
|
||||
/////4AAAAH////+AAAAAP////wAAAAAP///+AAAAAAf///gAAAAAA///8AAAAAAB///wAAAAAAD//+A
|
||||
AAAAAAP//wAAAAAAAf/+AAAAAAAA//4AAAAAAAB//AAAAAAAAH/8AAAAAAAAP/gAAAAAAAA/+AAAAAAA
|
||||
AD/wAAAAAAAAH/AAAAAAAAAf8AAAAAAAAB/wAAAAAAAAD+AAAAAAAAAP4AAAAAAAAA/gAAAAAAAAD+AA
|
||||
AAAAAAAP4AAAAAAAAA/gAAAAAAAAD+AAAAAAAAAP4AAAAAAAAA/gAAAAAAAAD+AAAAAAAAAP4AAAAAAA
|
||||
AA/gAAAAAAAAD/AAAAAAAAAP8AAAAAAAAB/wAAAAAAAAH/AAAAAAAAAf+AAAAAAAAD/4AAAAAAAAP/wA
|
||||
AAAAAAA//AAAAAAAAH/+AAAAAAAAf/4AAAAAAAD//wAAAAAAAf//gAAAAAAB///AAAAAAAP//8AAAAAA
|
||||
B///4AAAAAAP///wAAAAAB////wAAAAAP////gAAAAD/////gAAAAf/////AAAAH//////AAAB//////
|
||||
/gAA////////8A////////////////////////////////////8=
|
||||
</value>
|
||||
</data>
|
||||
</root>
|
||||
45
RevokeMsgPatcher/Model/App.cs
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Model
|
||||
{
|
||||
public class App
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public Dictionary<string, TargetInfo> FileTargetInfos { get; set; }
|
||||
|
||||
public Dictionary<string, List<ModifyInfo>> FileModifyInfos { get; set; }
|
||||
|
||||
public HashSet<string> GetSupportVersions()
|
||||
{
|
||||
// 使用 HashSet 防重
|
||||
HashSet<string> versions = new HashSet<string>();
|
||||
foreach (List<ModifyInfo> modifyInfos in FileModifyInfos.Values)
|
||||
{
|
||||
foreach (ModifyInfo modifyInfo in modifyInfos)
|
||||
{
|
||||
versions.Add(modifyInfo.Version);
|
||||
}
|
||||
}
|
||||
return versions;
|
||||
}
|
||||
|
||||
public string GetSupportVersionStr()
|
||||
{
|
||||
string str = "";
|
||||
foreach (string v in GetSupportVersions())
|
||||
{
|
||||
str += v + "、";
|
||||
}
|
||||
if (str.Length > 1)
|
||||
{
|
||||
str = str.Substring(0, str.Length - 1);
|
||||
}
|
||||
return str;
|
||||
}
|
||||
}
|
||||
}
|
||||
17
RevokeMsgPatcher/Model/Bag.cs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Model
|
||||
{
|
||||
public class Bag
|
||||
{
|
||||
public Dictionary<string, App> Apps { get; set; }
|
||||
|
||||
public string LatestVersion { get; set; }
|
||||
|
||||
public string Notice { get; set; }
|
||||
}
|
||||
}
|
||||
23
RevokeMsgPatcher/Model/Change.cs
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Model
|
||||
{
|
||||
public class Change
|
||||
{
|
||||
public long Position { get; set; }
|
||||
|
||||
public byte[] Content { get; set; }
|
||||
|
||||
public Change Clone()
|
||||
{
|
||||
Change o = new Change();
|
||||
o.Position = Position;
|
||||
o.Content = Content;
|
||||
return o;
|
||||
}
|
||||
}
|
||||
}
|
||||
40
RevokeMsgPatcher/Model/ModifyInfo.cs
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Model
|
||||
{
|
||||
public class ModifyInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
//public string RelativePath { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public string SHA1Before { get; set; }
|
||||
|
||||
public string SHA1After { get; set; }
|
||||
|
||||
public List<Change> Changes { get; set; }
|
||||
|
||||
public ModifyInfo Clone()
|
||||
{
|
||||
ModifyInfo o = new ModifyInfo();
|
||||
o.Name = Name;
|
||||
o.Version = Version;
|
||||
o.SHA1Before = SHA1Before;
|
||||
o.SHA1After = SHA1After;
|
||||
List<Change> cs = new List<Change>();
|
||||
foreach(Change c in Changes)
|
||||
{
|
||||
cs.Add(c.Clone());
|
||||
}
|
||||
o.Changes = cs;
|
||||
return o;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,23 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Model
|
||||
{
|
||||
public class TargetFile
|
||||
{
|
||||
public string FileName { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public string SHA1Before { get; set; }
|
||||
|
||||
public string SHA1After { get; set; }
|
||||
|
||||
public long Position { get; set; }
|
||||
|
||||
public byte Content { get; set; }
|
||||
}
|
||||
}
|
||||
26
RevokeMsgPatcher/Model/TargetInfo.cs
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Model
|
||||
{
|
||||
public class TargetInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string RelativePath { get; set; }
|
||||
|
||||
public string Memo { get; set; }
|
||||
|
||||
public TargetInfo Clone()
|
||||
{
|
||||
TargetInfo o = new TargetInfo();
|
||||
o.Name = Name;
|
||||
o.RelativePath = RelativePath;
|
||||
o.Memo = Memo;
|
||||
return o;
|
||||
}
|
||||
}
|
||||
}
|
||||
215
RevokeMsgPatcher/Modifier/AppModifier.cs
Normal file
|
|
@ -0,0 +1,215 @@
|
|||
using RevokeMsgPatcher.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Modifier
|
||||
{
|
||||
/// <summary>
|
||||
/// 1. 自动获取安装目录(已验证) 或者手动填写安装目录
|
||||
/// 2. 验证安装目录 验证要修改的 dll 是否存在
|
||||
/// 3. 判断所有 dll 是否符合防撤回要求
|
||||
/// 4. 备份所有 dll // *.h.bak
|
||||
/// 5. 根据每个 dll 匹配的 修改信息 循环修改
|
||||
/// </summary>
|
||||
public abstract class AppModifier
|
||||
{
|
||||
protected App config;
|
||||
|
||||
public App Config { set { config = value; } get { return config; } }
|
||||
|
||||
protected List<FileHexEditor> editors;
|
||||
|
||||
public string InstallPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 自动搜索应用安装路径
|
||||
/// </summary>
|
||||
/// <returns>应用安装路径</returns>
|
||||
public abstract string FindInstallPath();
|
||||
|
||||
//public abstract bool ValidateAndInitialize(string installPath);
|
||||
|
||||
/// <summary>
|
||||
/// 获取版本号
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract string GetVersion();
|
||||
|
||||
/// <summary>
|
||||
/// 判断APP安装路径内是否都存在要修改的文件
|
||||
/// </summary>
|
||||
/// <param name="installPath">APP安装路径</param>
|
||||
/// <returns></returns>
|
||||
public bool IsAllFilesExist(string installPath)
|
||||
{
|
||||
if (string.IsNullOrEmpty(installPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
int success = 0;
|
||||
foreach (TargetInfo info in config.FileTargetInfos.Values)
|
||||
{
|
||||
string filePath = Path.Combine(installPath, info.RelativePath);
|
||||
if (File.Exists(filePath))
|
||||
{
|
||||
success++;
|
||||
}
|
||||
}
|
||||
if (success == config.FileTargetInfos.Count)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// a.初始化修改器
|
||||
/// </summary>
|
||||
/// <param name="installPath">APP安装路径</param>
|
||||
public void InitEditors(string installPath)
|
||||
{
|
||||
// 初始化文件修改器
|
||||
editors = new List<FileHexEditor>();
|
||||
foreach (TargetInfo info in config.FileTargetInfos.Values)
|
||||
{
|
||||
FileHexEditor editor = new FileHexEditor(installPath, info);
|
||||
editors.Add(editor);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// b.验证文件完整性,寻找对应的补丁信息
|
||||
/// </summary>
|
||||
public void ValidateAndFindModifyInfo()
|
||||
{
|
||||
// 寻找对应文件版本与SHA1的修改信息
|
||||
foreach (FileHexEditor editor in editors) // 多种文件
|
||||
{
|
||||
// 通过SHA1和文件版本判断是否可以打补丁 根据不同结果返回不同的提示
|
||||
ModifyInfo matchingSHA1Before = null, matchingSHA1After = null, matchingVersion = null;
|
||||
foreach (ModifyInfo modifyInfo in config.FileModifyInfos[editor.FileName]) // 多个版本信息
|
||||
{
|
||||
if (modifyInfo.Name == editor.FileName) // 保险用的无用判断
|
||||
{
|
||||
if (editor.FileSHA1 == modifyInfo.SHA1After)
|
||||
{
|
||||
matchingSHA1After = modifyInfo;
|
||||
}
|
||||
else if (editor.FileSHA1 == modifyInfo.SHA1Before)
|
||||
{
|
||||
matchingSHA1Before = modifyInfo;
|
||||
}
|
||||
|
||||
if (editor.FileVersion == modifyInfo.Version)
|
||||
{
|
||||
matchingVersion = modifyInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 补丁前SHA1匹配上,肯定是正确的dll
|
||||
if (matchingSHA1Before != null)
|
||||
{
|
||||
editor.FileModifyInfo = matchingSHA1Before;
|
||||
continue;
|
||||
}
|
||||
// 补丁后SHA1匹配上,肯定已经打过补丁
|
||||
if (matchingSHA1After != null)
|
||||
{
|
||||
throw new BusinessException("installed", $"你已经安装过此补丁,文件路径:{editor.FilePath}");
|
||||
}
|
||||
// 全部不匹配,说明不支持
|
||||
if (matchingSHA1Before == null && matchingSHA1After == null && matchingVersion == null)
|
||||
{
|
||||
throw new BusinessException("not_support", $"不支持此版本:{editor.FileVersion},文件路径:{editor.FilePath}");
|
||||
}
|
||||
// SHA1不匹配,版本匹配,可能dll已经被其他补丁程序修改过
|
||||
if ((matchingSHA1Before == null && matchingSHA1After == null) && matchingVersion != null)
|
||||
{
|
||||
throw new BusinessException("maybe_modified", $"程序支持此版本:{editor.FileVersion}。但是文件校验不通过,请确认是否使用过其他补丁程序。文件路径:{editor.FilePath}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// c.根据补丁信息,安装补丁
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool Patch()
|
||||
{
|
||||
// 首先验证文件修改器是否没问题
|
||||
foreach (FileHexEditor editor in editors)
|
||||
{
|
||||
if (editor.FileModifyInfo == null)
|
||||
{
|
||||
throw new Exception("补丁安装失败,原因:文件修改器初始化失败!");
|
||||
}
|
||||
}
|
||||
// 再备份所有文件
|
||||
foreach (FileHexEditor editor in editors)
|
||||
{
|
||||
editor.Backup();
|
||||
}
|
||||
// 打补丁!
|
||||
List<FileHexEditor> done = new List<FileHexEditor>(); // 已经打上补丁的
|
||||
try
|
||||
{
|
||||
foreach (FileHexEditor editor in editors)
|
||||
{
|
||||
bool success = editor.Patch();
|
||||
if (!success)
|
||||
{
|
||||
editor.Restore();
|
||||
}
|
||||
done.Add(editor);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// 恢复所有已经打上补丁的文件
|
||||
foreach (FileHexEditor editor in done)
|
||||
{
|
||||
editor.Restore();
|
||||
}
|
||||
throw ex;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool BackupExists()
|
||||
{
|
||||
foreach (FileHexEditor editor in editors)
|
||||
{
|
||||
if (!File.Exists(editor.FileBakPath))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Restore()
|
||||
{
|
||||
if (BackupExists())
|
||||
{
|
||||
foreach (FileHexEditor editor in editors)
|
||||
{
|
||||
editor.Restore();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new Exception("备份文件不存在,还原失败!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
74
RevokeMsgPatcher/Modifier/FileHexEditor.cs
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
using RevokeMsgPatcher.Model;
|
||||
using RevokeMsgPatcher.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Modifier
|
||||
{
|
||||
public class FileHexEditor
|
||||
{
|
||||
public string FileName { get; set; }
|
||||
|
||||
public string FilePath { get; set; }
|
||||
|
||||
public string FileBakPath { get; set; }
|
||||
|
||||
private string version;
|
||||
public string FileVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (version == null)
|
||||
{
|
||||
version = FileUtil.GetFileVersion(FilePath);
|
||||
}
|
||||
return version;
|
||||
}
|
||||
}
|
||||
|
||||
public string sha1;
|
||||
public string FileSHA1
|
||||
{
|
||||
get
|
||||
{
|
||||
if (sha1 == null)
|
||||
{
|
||||
sha1 = FileUtil.ComputeFileSHA1(FilePath);
|
||||
}
|
||||
return sha1;
|
||||
}
|
||||
}
|
||||
|
||||
public TargetInfo FileTargetInfo { get; set; }
|
||||
|
||||
public ModifyInfo FileModifyInfo { get; set; }
|
||||
|
||||
public FileHexEditor(string installPath, TargetInfo target)
|
||||
{
|
||||
FileTargetInfo = target.Clone();
|
||||
FileName = FileTargetInfo.Name;
|
||||
FilePath = Path.Combine(installPath, FileTargetInfo.RelativePath);
|
||||
FileBakPath = FilePath + ".h.bak";
|
||||
}
|
||||
|
||||
public void Backup()
|
||||
{
|
||||
File.Copy(FilePath, FileBakPath, true);
|
||||
}
|
||||
|
||||
public bool Patch()
|
||||
{
|
||||
FileUtil.EditMultiHex(FilePath, FileModifyInfo.Changes);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Restore()
|
||||
{
|
||||
File.Copy(FileBakPath, FilePath, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
56
RevokeMsgPatcher/Modifier/QQLiteModifier.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using RevokeMsgPatcher.Model;
|
||||
using RevokeMsgPatcher.Utils;
|
||||
|
||||
namespace RevokeMsgPatcher.Modifier
|
||||
{
|
||||
class QQLiteModifier : AppModifier
|
||||
{
|
||||
public QQLiteModifier(App config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动寻找获取微信安装路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string FindInstallPath()
|
||||
{
|
||||
string installPath = PathUtil.FindInstallPathFromRegistry("QQLite");
|
||||
if (!IsAllFilesExist(installPath))
|
||||
{
|
||||
foreach (string defaultPath in PathUtil.GetDefaultInstallPaths(@"Tencent\QQLite"))
|
||||
{
|
||||
if (IsAllFilesExist(defaultPath))
|
||||
{
|
||||
return defaultPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return installPath;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取整个APP的当前版本
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string GetVersion()
|
||||
{
|
||||
if (editors != null && editors.Count > 0)
|
||||
{
|
||||
foreach (FileHexEditor editor in editors)
|
||||
{
|
||||
if (editor.FileName == "IM.dll")
|
||||
{
|
||||
return editor.FileVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
56
RevokeMsgPatcher/Modifier/QQModifier.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using RevokeMsgPatcher.Model;
|
||||
using RevokeMsgPatcher.Utils;
|
||||
|
||||
namespace RevokeMsgPatcher.Modifier
|
||||
{
|
||||
class QQModifier : AppModifier
|
||||
{
|
||||
public QQModifier(App config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动寻找获取微信安装路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string FindInstallPath()
|
||||
{
|
||||
string installPath = PathUtil.FindInstallPathFromRegistry("{052CFB79-9D62-42E3-8A15-DE66C2C97C3E}");
|
||||
if (!IsAllFilesExist(installPath))
|
||||
{
|
||||
foreach (string defaultPath in PathUtil.GetDefaultInstallPaths(@"Tencent\QQ"))
|
||||
{
|
||||
if (IsAllFilesExist(defaultPath))
|
||||
{
|
||||
return defaultPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return installPath;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取整个APP的当前版本
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string GetVersion()
|
||||
{
|
||||
if (editors != null && editors.Count > 0)
|
||||
{
|
||||
foreach (FileHexEditor editor in editors)
|
||||
{
|
||||
if (editor.FileName == "IM.dll")
|
||||
{
|
||||
return editor.FileVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
56
RevokeMsgPatcher/Modifier/TIMModifier.cs
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
using RevokeMsgPatcher.Model;
|
||||
using RevokeMsgPatcher.Utils;
|
||||
|
||||
namespace RevokeMsgPatcher.Modifier
|
||||
{
|
||||
class TIMModifier : AppModifier
|
||||
{
|
||||
|
||||
public TIMModifier(App config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
/// <summary>
|
||||
/// 自动寻找获取微信安装路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string FindInstallPath()
|
||||
{
|
||||
string installPath = PathUtil.FindInstallPathFromRegistry("TIM");
|
||||
if (!IsAllFilesExist(installPath))
|
||||
{
|
||||
foreach (string defaultPath in PathUtil.GetDefaultInstallPaths(@"Tencent\TIM"))
|
||||
{
|
||||
if (IsAllFilesExist(defaultPath))
|
||||
{
|
||||
return defaultPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return installPath;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取整个APP的当前版本
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string GetVersion()
|
||||
{
|
||||
if (editors != null && editors.Count > 0)
|
||||
{
|
||||
foreach (FileHexEditor editor in editors)
|
||||
{
|
||||
if (editor.FileName == "IM.dll")
|
||||
{
|
||||
return editor.FileVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
72
RevokeMsgPatcher/Modifier/WechatModifier.cs
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
using RevokeMsgPatcher.Model;
|
||||
using RevokeMsgPatcher.Utils;
|
||||
|
||||
namespace RevokeMsgPatcher.Modifier
|
||||
{
|
||||
class WechatModifier : AppModifier
|
||||
{
|
||||
|
||||
public WechatModifier(App config)
|
||||
{
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 自动寻找获取微信安装路径
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string FindInstallPath()
|
||||
{
|
||||
string installPath = PathUtil.FindInstallPathFromRegistry("Wechat");
|
||||
if (!IsAllFilesExist(installPath))
|
||||
{
|
||||
foreach (string defaultPath in PathUtil.GetDefaultInstallPaths(@"Tencent\Wechat"))
|
||||
{
|
||||
if (IsAllFilesExist(defaultPath))
|
||||
{
|
||||
return defaultPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return installPath;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取整个APP的当前版本
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public override string GetVersion()
|
||||
{
|
||||
if (editors != null && editors.Count > 0)
|
||||
{
|
||||
foreach (FileHexEditor editor in editors)
|
||||
{
|
||||
if (editor.FileName == "WeChatWin.dll")
|
||||
{
|
||||
return editor.FileVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
//public override bool ValidateAndInitialize(string installPath)
|
||||
//{
|
||||
// // 判断是否是安装路径
|
||||
// if (!IsAllBinaryFilesExist(installPath))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// // 初始化十六进制文件编辑器
|
||||
// // 并寻找与之配对的版本修改信息
|
||||
// InitEditors(installPath);
|
||||
|
||||
// return true;
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,91 +0,0 @@
|
|||
using RevokeMsgPatcher.Model;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Web.Script.Serialization;
|
||||
|
||||
namespace RevokeMsgPatcher
|
||||
{
|
||||
public class Patcher
|
||||
{
|
||||
private string intallPath;
|
||||
public string IntallPath
|
||||
{
|
||||
get { return intallPath; }
|
||||
set
|
||||
{
|
||||
intallPath = value;
|
||||
if (!string.IsNullOrEmpty(intallPath) && Util.IsWechatInstallPath(intallPath))
|
||||
{
|
||||
dllPath = Path.Combine(intallPath, "WeChatWin.dll");
|
||||
bakPath = Path.Combine(intallPath, "WeChatWin.dll.h.bak");
|
||||
}
|
||||
else
|
||||
{
|
||||
intallPath = null;
|
||||
dllPath = null;
|
||||
bakPath = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string dllPath;
|
||||
private string bakPath;
|
||||
|
||||
public string DllPath { get => dllPath; }
|
||||
public string BakPath { get => bakPath; }
|
||||
|
||||
private List<TargetFile> targetFiles;
|
||||
private TargetFile currentFile;
|
||||
|
||||
public List<TargetFile> TargetFiles { get => targetFiles; }
|
||||
|
||||
public Patcher()
|
||||
{
|
||||
JavaScriptSerializer serializer = new JavaScriptSerializer();
|
||||
targetFiles = serializer.Deserialize<List<TargetFile>>(Properties.Resources.PatchJson);
|
||||
}
|
||||
|
||||
public void SetNewPatchJson(string json)
|
||||
{
|
||||
JavaScriptSerializer serializer = new JavaScriptSerializer();
|
||||
targetFiles = serializer.Deserialize<List<TargetFile>>(json);
|
||||
}
|
||||
|
||||
public string JudgeVersion()
|
||||
{
|
||||
string sha1 = Util.ComputeFileSHA1(dllPath);
|
||||
Debug.WriteLine(sha1);
|
||||
|
||||
foreach (TargetFile t in targetFiles)
|
||||
{
|
||||
if (sha1 == t.SHA1After)
|
||||
{
|
||||
return "done";
|
||||
}
|
||||
if (sha1 == t.SHA1Before)
|
||||
{
|
||||
currentFile = t;
|
||||
return t.Version;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public bool Patch()
|
||||
{
|
||||
if (currentFile != null)
|
||||
{
|
||||
File.Copy(dllPath, bakPath, true);
|
||||
bool done = Util.EditHex(dllPath, currentFile.Position, currentFile.Content);
|
||||
if (!done)
|
||||
{
|
||||
File.Copy(bakPath, dllPath, true);
|
||||
}
|
||||
return done;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -14,14 +14,18 @@ namespace RevokeMsgPatcher
|
|||
[STAThread]
|
||||
static void Main()
|
||||
{
|
||||
|
||||
|
||||
#if DEBUG
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
Application.Run(new FormMain());
|
||||
#else
|
||||
try
|
||||
{
|
||||
Application.EnableVisualStyles();
|
||||
Application.SetCompatibleTextRenderingDefault(false);
|
||||
|
||||
#if DEBUG
|
||||
Application.Run(new FormMain());
|
||||
#else
|
||||
//当前用户是管理员的时候,直接启动应用程序
|
||||
//如果不是管理员,则使用启动对象启动程序,以确保使用管理员身份运行
|
||||
//获得当前登录的Windows用户标示
|
||||
|
|
@ -53,12 +57,13 @@ namespace RevokeMsgPatcher
|
|||
//退出
|
||||
Application.Exit();
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -32,5 +32,5 @@ using System.Runtime.InteropServices;
|
|||
// 可以指定所有值,也可以使用以下所示的 "*" 预置版本号和修订号
|
||||
// 方法是按如下所示使用“*”: :
|
||||
//[assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("0.4")]
|
||||
[assembly: AssemblyFileVersion("0.4")]
|
||||
[assembly: AssemblyVersion("0.6")]
|
||||
[assembly: AssemblyFileVersion("0.6")]
|
||||
|
|
|
|||
|
|
@ -61,7 +61,7 @@ namespace RevokeMsgPatcher.Properties {
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 [{"FileName":"WeChatWin.dll","Version":"2.6.8.65","SHA1Before":"e01f6855a96c12c30808960903ed199a33e4952c","SHA1After":"d9120569cfd0433aebea107d7b90805cbbac7518","Position":2454265,"Content":117},{"FileName":"WeChatWin.dll","Version":"2.6.8.52","SHA1Before":"88131302f664df6a657c9ca49d152da536fe5729","SHA1After":"8d1454b73831644181e962c1fa0ea4e2da4124a3","Position":2453049,"Content":117},{"FileName":"WeChatWin.dll","Version":"2.6.8.51","SHA1Before":"d0a5517b1292a751501b00b4b1f0702db2d9fc30","SHA1After":"53e7b [字符串的其余部分被截断]"; 的本地化字符串。
|
||||
/// 查找类似 {"Apps":{"Wechat":{"Name":"Wechat","FileTargetInfos":{"WeChatWin.dll":{"Name":"WeChatWin.dll","RelativePath":"WeChatWin.dll","Memo":null}},"FileModifyInfos":{"WeChatWin.dll":[{"Name":"WeChatWin.dll","Version":"2.7.1.88","SHA1Before":"034059bad50dd793140952391bfa7936133e69b4","SHA1After":"dd6d80c30ca9e0ea9f7d2f1add498fc9aa4bc7a0","Changes":[{"Position":2499465,"Content":[235]},{"Position":7952304,"Content":[195]}]},{"Name":"WeChatWin.dll","Version":"2.7.1.85","SHA1Before":"de0df4e138b72460450f66c029e33f4510f [字符串的其余部分被截断]"; 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string PatchJson {
|
||||
get {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@
|
|||
<ItemGroup>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Core" />
|
||||
<Reference Include="System.Management" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
<Reference Include="System.Xml.Linq" />
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
|
|
@ -49,17 +50,31 @@
|
|||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="BusinessException.cs" />
|
||||
<Compile Include="FormMain.cs">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Include="FormMain.Designer.cs">
|
||||
<DependentUpon>FormMain.cs</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="Model\TargetFile.cs" />
|
||||
<Compile Include="Patcher.cs" />
|
||||
<Compile Include="Model\App.cs" />
|
||||
<Compile Include="Model\Bag.cs" />
|
||||
<Compile Include="Model\Change.cs" />
|
||||
<Compile Include="Model\ModifyInfo.cs" />
|
||||
<Compile Include="Model\TargetInfo.cs" />
|
||||
<Compile Include="Modifier\AppModifier.cs" />
|
||||
<Compile Include="Modifier\FileHexEditor.cs" />
|
||||
<Compile Include="Modifier\QQLiteModifier.cs" />
|
||||
<Compile Include="Modifier\QQModifier.cs" />
|
||||
<Compile Include="Modifier\TIMModifier.cs" />
|
||||
<Compile Include="Modifier\WechatModifier.cs" />
|
||||
<Compile Include="Utils\Device.cs" />
|
||||
<Compile Include="Utils\FileUtil.cs" />
|
||||
<Compile Include="Utils\GAHelper.cs" />
|
||||
<Compile Include="Utils\HttpUtil.cs" />
|
||||
<Compile Include="Utils\PathUtil.cs" />
|
||||
<Compile Include="Program.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Util.cs" />
|
||||
<EmbeddedResource Include="FormMain.resx">
|
||||
<DependentUpon>FormMain.cs</DependentUpon>
|
||||
</EmbeddedResource>
|
||||
|
|
|
|||
|
|
@ -1,109 +0,0 @@
|
|||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace RevokeMsgPatcher
|
||||
{
|
||||
public class Util
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 自动查找安装路径
|
||||
/// </summary>
|
||||
/// <returns>安装路径</returns>
|
||||
public static string AutoFindInstallPath()
|
||||
{
|
||||
// 微信的注册表路径
|
||||
try
|
||||
{
|
||||
RegistryKey key = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\Windows\CurrentVersion\Uninstall\WeChat");
|
||||
object installLocation = key.GetValue("InstallLocation");
|
||||
key.Close();
|
||||
if (installLocation == null || string.IsNullOrEmpty(installLocation.ToString()) || !IsWechatInstallPath(installLocation.ToString()))
|
||||
{
|
||||
// 从默认安装目录查找
|
||||
string[] drives = Environment.GetLogicalDrives(); //获取当前计算机逻辑磁盘名称列表
|
||||
foreach (string d in drives)
|
||||
{
|
||||
string assertPath = Path.Combine(d, @"Program Files (x86)\Tencent\WeChat");
|
||||
if (IsWechatInstallPath(assertPath))
|
||||
{
|
||||
return assertPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return installLocation.ToString();
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 通过文件是否存在判断是否是安装目录
|
||||
/// </summary>
|
||||
/// <param name="path">安装目录</param>
|
||||
/// <returns></returns>
|
||||
public static bool IsWechatInstallPath(string path)
|
||||
{
|
||||
return File.Exists(Path.Combine(path, "WeChatWin.dll")) && File.Exists(Path.Combine(path, "WeChat.exe"));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取文件版本
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFileVersion(string path)
|
||||
{
|
||||
FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(path);
|
||||
return fileVersionInfo.FileVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算文件SHA1
|
||||
/// </summary>
|
||||
/// <param name="s"></param>
|
||||
/// <returns></returns>
|
||||
public static string ComputeFileSHA1(string s)
|
||||
{
|
||||
FileStream file = new FileStream(s, FileMode.Open);
|
||||
SHA1 sha1 = new SHA1CryptoServiceProvider();
|
||||
byte[] retval = sha1.ComputeHash(file);
|
||||
file.Close();
|
||||
|
||||
StringBuilder sc = new StringBuilder();
|
||||
for (int i = 0; i < retval.Length; i++)
|
||||
{
|
||||
sc.Append(retval[i].ToString("x2"));
|
||||
}
|
||||
return sc.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改文件指定位置的字节
|
||||
/// </summary>
|
||||
/// <param name="path">WeChatWin.dll 的路径</param>
|
||||
/// <param name="position">偏移位置</param>
|
||||
/// <param name="after">修改后的值</param>
|
||||
/// <returns></returns>
|
||||
public static bool EditHex(string path, long position, byte after)
|
||||
{
|
||||
using (var stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
|
||||
{
|
||||
stream.Position = position;
|
||||
stream.WriteByte(after);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
151
RevokeMsgPatcher/Utils/Device.cs
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Net;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace RevokeMsgPatcher.Utils
|
||||
{
|
||||
public class Device
|
||||
{
|
||||
private static string macID = null;
|
||||
private static string osVersion = null;
|
||||
|
||||
private static string fingerPrint = null;
|
||||
|
||||
#region PROP, get it only once
|
||||
|
||||
public static string MacID
|
||||
{
|
||||
get
|
||||
{
|
||||
if (macID == null)
|
||||
{
|
||||
macID = ObtainMacID();
|
||||
}
|
||||
return macID;
|
||||
}
|
||||
}
|
||||
|
||||
public static string OSVersion
|
||||
{
|
||||
get
|
||||
{
|
||||
if (osVersion == null)
|
||||
{
|
||||
var name = (from x in new ManagementObjectSearcher("SELECT Caption FROM Win32_OperatingSystem").Get().Cast<ManagementObject>()
|
||||
select x.GetPropertyValue("Caption")).FirstOrDefault();
|
||||
osVersion = name != null ? name.ToString() : "Unknown";
|
||||
}
|
||||
return osVersion;
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Calculate GUID
|
||||
/// </summary>
|
||||
/// <returns>GUID</returns>
|
||||
public static string Value()
|
||||
{
|
||||
if (fingerPrint == null)
|
||||
{
|
||||
fingerPrint = GetHash(
|
||||
"MAC >> " + MacID
|
||||
);
|
||||
}
|
||||
return fingerPrint;
|
||||
}
|
||||
|
||||
private static string GetHash(string s)
|
||||
{
|
||||
MD5 sec = new MD5CryptoServiceProvider();
|
||||
ASCIIEncoding enc = new ASCIIEncoding();
|
||||
byte[] bt = enc.GetBytes(s);
|
||||
return GetHexString(sec.ComputeHash(bt));
|
||||
}
|
||||
|
||||
private static string GetHexString(byte[] bt)
|
||||
{
|
||||
string s = string.Empty;
|
||||
for (int i = 0; i < bt.Length; i++)
|
||||
{
|
||||
byte b = bt[i];
|
||||
int n, n1, n2;
|
||||
n = (int)b;
|
||||
n1 = n & 15;
|
||||
n2 = (n >> 4) & 15;
|
||||
if (n2 > 9)
|
||||
s += ((char)(n2 - 10 + (int)'A')).ToString();
|
||||
else
|
||||
s += n2.ToString();
|
||||
if (n1 > 9)
|
||||
s += ((char)(n1 - 10 + (int)'A')).ToString();
|
||||
else
|
||||
s += n1.ToString();
|
||||
if ((i + 1) != bt.Length && (i + 1) % 2 == 0) s += "-";
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
#region Original Device ID Getting Code
|
||||
|
||||
public static string ObtainMacID()
|
||||
{
|
||||
return Identifier("Win32_NetworkAdapterConfiguration", "MACAddress", "IPEnabled");
|
||||
}
|
||||
|
||||
private static string Identifier(string wmiClass, string wmiProperty, string wmiMustBeTrue)
|
||||
{
|
||||
string result = "";
|
||||
try
|
||||
{
|
||||
ManagementClass mc = new ManagementClass(wmiClass);
|
||||
ManagementObjectCollection moc = mc.GetInstances();
|
||||
foreach (ManagementObject mo in moc)
|
||||
{
|
||||
if (mo[wmiMustBeTrue].ToString() == "True")
|
||||
{
|
||||
//Only get the first one
|
||||
if (result == "")
|
||||
{
|
||||
result = mo[wmiProperty].ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static string Identifier(string wmiClass, string wmiProperty)
|
||||
{
|
||||
string result = "";
|
||||
try
|
||||
{
|
||||
ManagementClass mc = new ManagementClass(wmiClass);
|
||||
ManagementObjectCollection moc = mc.GetInstances();
|
||||
foreach (ManagementObject mo in moc)
|
||||
{
|
||||
//Only get the first one
|
||||
if (result == "")
|
||||
{
|
||||
result = mo[wmiProperty].ToString();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
78
RevokeMsgPatcher/Utils/FileUtil.cs
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
using RevokeMsgPatcher.Model;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace RevokeMsgPatcher.Utils
|
||||
{
|
||||
public class FileUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取文件版本
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetFileVersion(string path)
|
||||
{
|
||||
FileVersionInfo fileVersionInfo = FileVersionInfo.GetVersionInfo(path);
|
||||
return fileVersionInfo.FileVersion;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算文件SHA1
|
||||
/// </summary>
|
||||
/// <param name="s">文件路径</param>
|
||||
/// <returns></returns>
|
||||
public static string ComputeFileSHA1(string s)
|
||||
{
|
||||
FileStream file = new FileStream(s, FileMode.Open);
|
||||
SHA1 sha1 = new SHA1CryptoServiceProvider();
|
||||
byte[] retval = sha1.ComputeHash(file);
|
||||
file.Close();
|
||||
|
||||
StringBuilder sc = new StringBuilder();
|
||||
for (int i = 0; i < retval.Length; i++)
|
||||
{
|
||||
sc.Append(retval[i].ToString("x2"));
|
||||
}
|
||||
return sc.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改文件指定位置的字节
|
||||
/// </summary>
|
||||
/// <param name="path">文件对象的路径</param>
|
||||
/// <param name="position">偏移位置</param>
|
||||
/// <param name="after">修改后的值</param>
|
||||
/// <returns></returns>
|
||||
public static bool EditHex(string path, long position, byte after)
|
||||
{
|
||||
using (var stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
|
||||
{
|
||||
stream.Position = position;
|
||||
stream.WriteByte(after);
|
||||
}
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 修改文件多个指定位置的多个字节
|
||||
/// </summary>
|
||||
/// <param name="path">文件对象的路径</param>
|
||||
/// <param name="changes">需要修改的位置和内容</param>
|
||||
public static void EditMultiHex(string path, List<Change> changes)
|
||||
{
|
||||
using (var stream = new FileStream(path, FileMode.Open, FileAccess.ReadWrite))
|
||||
{
|
||||
foreach (Change change in changes)
|
||||
{
|
||||
stream.Seek(change.Position, SeekOrigin.Begin);
|
||||
stream.Write(change.Content, 0, change.Content.Length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
RevokeMsgPatcher/Utils/GAHelper.cs
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Forms;
|
||||
|
||||
namespace RevokeMsgPatcher.Utils
|
||||
{
|
||||
/// <summary>
|
||||
/// 用于软件的 Google Analytics 实现 By huiyadanli
|
||||
/// 相关文档:
|
||||
/// 指南 https://developers.google.com/analytics/devguides/collection/protocol/v1/devguide
|
||||
/// 参数 https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters
|
||||
/// 测试 https://ga-dev-tools.appspot.com/hit-builder/
|
||||
/// </summary>
|
||||
public class GAHelper
|
||||
{
|
||||
// 根据实际情况修改
|
||||
private static readonly HttpClient client = HttpUtil.Client;
|
||||
|
||||
private const string GAUrl = "https://www.google-analytics.com/collect";
|
||||
|
||||
// 根据实际使用分析账号设置
|
||||
private const string tid = "UA-80358493-2"; // GA Tracking ID / Property ID.
|
||||
|
||||
private static readonly string cid = Device.Value(); // Anonymous Client ID. // Guid.NewGuid().ToString()
|
||||
|
||||
// 屏幕分辨率(可选)
|
||||
private static readonly string sr = Screen.PrimaryScreen.Bounds.Width + "x" + Screen.PrimaryScreen.Bounds.Height;
|
||||
|
||||
public string UserAgent { get; set; }
|
||||
|
||||
public GAHelper()
|
||||
{
|
||||
UserAgent = string.Format("Hui Google Analytics Tracker/1.0 ({0}; {1}; {2})", Environment.OSVersion.Platform.ToString(), Environment.OSVersion.Version.ToString(), Environment.OSVersion.VersionString);
|
||||
}
|
||||
|
||||
public async Task RequestPageViewAsync(string page, string title = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!page.StartsWith("/"))
|
||||
{
|
||||
page = "/" + page;
|
||||
}
|
||||
// 请求参数
|
||||
var values = new Dictionary<string, string>
|
||||
{
|
||||
{ "v", "1" }, // 当前必填1
|
||||
{ "tid", tid },
|
||||
{ "cid", cid },
|
||||
{ "ua", UserAgent },
|
||||
{ "t", "pageview" },
|
||||
{ "sr", sr },
|
||||
{ "dp", page },
|
||||
{ "dt", title },
|
||||
};
|
||||
var content = new FormUrlEncodedContent(values);
|
||||
var response = await client.PostAsync(GAUrl, content);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
|
||||
Console.WriteLine("GAHelper:" + ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
public void RequestPageView(string page, string title = null)
|
||||
{
|
||||
Task.Run(() => RequestPageViewAsync(page, title));
|
||||
}
|
||||
}
|
||||
}
|
||||
55
RevokeMsgPatcher/Utils/HttpUtil.cs
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Utils
|
||||
{
|
||||
public class HttpUtil
|
||||
{
|
||||
public static HttpClient Client { get; } = new HttpClient();
|
||||
|
||||
static HttpUtil()
|
||||
{
|
||||
Client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36");
|
||||
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12 | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 补丁路径
|
||||
/// 已经弃用的路径
|
||||
/// https://swordmaker-hauls-51508.netlify.com/i/revokemsg/05.json
|
||||
/// https://huiyadanli.github.io/i/revokemsg/05.json
|
||||
/// </summary>
|
||||
private static readonly string[] urls = new string[]
|
||||
{
|
||||
"https://coding.net/u/huiyadanli/p/RevokeMsgPatcher/git/raw/master/RevokeMsgPatcher.Assistant/Data/0.6/patch.json",
|
||||
"https://gitee.com/huiyadanli/RevokeMsgPatcher/raw/master/RevokeMsgPatcher.Assistant/Data/0.6/patch.json",
|
||||
"https://raw.githubusercontent.com/huiyadanli/RevokeMsgPatcher/master/RevokeMsgPatcher.Assistant/Data/0.6/patch.json"
|
||||
};
|
||||
|
||||
private static int i = 0;
|
||||
|
||||
public static async Task<string> GetPatchJsonAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
return await Client.GetStringAsync(urls[i]);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Console.WriteLine("第" + (i + 1) + "次请求异常:[" + ex.Message + "]\nURL:" + urls[i]);
|
||||
i++;
|
||||
if (i > urls.Length)
|
||||
{
|
||||
i = 0;
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
return await GetPatchJsonAsync();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
81
RevokeMsgPatcher/Utils/PathUtil.cs
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace RevokeMsgPatcher.Utils
|
||||
{
|
||||
public class PathUtil
|
||||
{
|
||||
public static void DisplayAllProgram()
|
||||
{
|
||||
RegistryKey uninstallKey, programKey;
|
||||
uninstallKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall");
|
||||
string[] programKeys = uninstallKey.GetSubKeyNames();
|
||||
foreach (string keyName in programKeys)
|
||||
{
|
||||
programKey = uninstallKey.OpenSubKey(keyName);
|
||||
Console.WriteLine(keyName + " , " + programKey.GetValue("DisplayName") + " , " + programKey.GetValue("InstallLocation"));
|
||||
programKey.Close();
|
||||
}
|
||||
uninstallKey.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从注册表中寻找安装路径
|
||||
/// </summary>
|
||||
/// <param name="uninstallKeyName">
|
||||
/// 安装信息的注册表键名
|
||||
/// 微信:WeChat
|
||||
/// QQ:{052CFB79-9D62-42E3-8A15-DE66C2C97C3E}
|
||||
/// TIM:TIM
|
||||
/// </param>
|
||||
/// <returns>安装路径</returns>
|
||||
public static string FindInstallPathFromRegistry(string uninstallKeyName)
|
||||
{
|
||||
try
|
||||
{
|
||||
RegistryKey key = Registry.LocalMachine.OpenSubKey($@"Software\Microsoft\Windows\CurrentVersion\Uninstall\{uninstallKeyName}");
|
||||
if (key == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
object installLocation = key.GetValue("InstallLocation");
|
||||
key.Close();
|
||||
if (installLocation != null && !string.IsNullOrEmpty(installLocation.ToString()))
|
||||
{
|
||||
return installLocation.ToString();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取所有可能的默认安装路径
|
||||
/// </summary>
|
||||
/// <param name="relativePath">Tencent\*</param>
|
||||
/// <returns></returns>
|
||||
public static List<string> GetDefaultInstallPaths(string relativePath)
|
||||
{
|
||||
List<string> list = new List<string>();
|
||||
// 从默认安装目录查找
|
||||
string[] drives = Environment.GetLogicalDrives(); //获取当前计算机逻辑磁盘名称列表
|
||||
foreach (string d in drives)
|
||||
{
|
||||
string path = Path.Combine(d, $@"Program Files (x86)\{relativePath}");
|
||||
if (Directory.Exists(path))
|
||||
{
|
||||
list.Add(path);
|
||||
}
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 17 KiB |