Note

软件名称: 极简·单行阅读器
软件官网: Read133

离线版

Tip

强制开启离线版

  1. 搜索"登录"
    image
  2. 找到方法"BindLoginResult"
private void BindLoginResult(LoginResult result)
{
	if (result.LoginStatus == LoginStatus.UnLogin)
	{
		this.lblInfo.Text = "欢迎使用极简单行阅读器,请点击右键菜单注册或登录";
		...
	}
	this.lblInfo.Text = "欢迎使用极简单行阅读器,请点击右键菜单打开文本或者网页";
	...
	if (result.LoginStatus == LoginStatus.Login)
	{
		...
	}
	if (result.LoginStatus == LoginStatus.Offline || result.LoginStatus == LoginStatus.Error)
	{
		this.lblInfo.Text = "欢迎使用极简单行阅读器[离线],请点击右键菜单打开文本";
		...
	}
	...
}

由此可见,通过"result.LoginStatus"来识别当前登录状态

  1. 修改 result.LoginStatusLoginStatus.Offline
  2. 完成修改

image

缺少在线功能

在线版

模拟登录

Tip

目的: 绕过手动登录,模拟用户已经登陆过了,即触发AutoLogin方法

AutoLogin方法

public static void AutoLogin()
{
    if (string.IsNullOrEmpty(Bis.UID))
    {
        ...
    }
    try
    {
        ApiResult apiResult2 = Util.GetApiResult(Constants.API_AutoLogin, 10);
        if (apiResult2.Status == 200)
        {
            Bis.LoRes.LoginStatus = LoginStatus.Login;
            Bis.LoRes.UpdateDataFromJson(apiResult2.Data);
            ...
        }
        ...
    }
    catch (Exception ex2)
    {
       ...
    }
}

1. 修改UID

这样才能开启"打开网页-热门站点"\“系统-会员”等多个页面

  1. 找到获取UID的方法
    image
  2. 反编译方法 & 修改代码 & 编译
    image
    image
    public static string UID
    {
        get
        {
-           if (Bis.uid == null)
-           {
-               Bis.uid = DataProcess.GetKey("Sys", "UID");
-           }
-           return Bis.uid;
+          return "52钓鱼崽";
        }
        set
        {
        }
    }

2. 创建虚假登录res

  1. 创建虚拟登录状态
    设置 apiResult2.Status 为 200
  2. 修改apiResult2.Data, 即修改登录结果

不过修改apiResult2.Data过于麻烦,所以还是直接修改UpdateDataFromJson函数

public void UpdateDataFromJson(JToken data)
{
	this.UserName = data["user_name"].ToString();
	...
}

都是通过传入的内容解析获取的
构建一个虚假登录内容用于解析

JObject jsonObject = new JObject
{
    ["user_name"] = "52钓鱼崽",
    ["user_create_time"] = DateTime.Now.ToString(),
    ["phone"] = "1234567890",
    ["nick_name"] = "52钓鱼崽",
    ["nick_flag"] = 0,
    ["sex"] = 0,
    ["head_img"] = "http://read.home133.com/img/icon/picture.svg",
    ["status"] = 1,
    ["active_id"] = "A123",
    ["last_version"] = "123",
    ["update_version"] = "456",
    ["expire_date"] = DateTime.Now.AddDays(30.0).ToString(),
    ["qq_group"] = "123456",
    ["channel"] = "Web",
    ["chapter_ai_url"] = "https://acg-q.github.io/new_blog/post/12.html",
    ["member_share_cnt"] = 5,
    ["point_day"] = 50,
    // 更多 选项
    ["append"] = new JArray
    {
        new JObject
        {
            ["url"] = "",
            ["title"] = "52钓鱼崽 破解"
        }
    },
    // 这里应该是插件
    ["site"] = new JArray
    {
        new JObject
        {
            ["url"] = "",
            ["title"] = "",
            ["plug_uid"] = ""
        }
    },
    ["site"] = new JArray
    {
        new JObject
        {
            ["url"] = "",
            ["title"] = "",
            ["plug_uid"] = ""
        }
    },
    // 购买了哪些APP
    // 这里的参数都是 和 应用中心 的应用信息一一对应
    ["app"] = new JArray
    {
        new JObject
        {
            ["id"] = "",
            ["name"] = "",
            ["status"] = "1", // 这里必须存在且是数字
            ["enabled"] = "1", // 这里必须存在且是数字
            ["type"] = "1", // 这里必须存在且是数字
            ["path"] = "",
            ["imgUrl"] = "",
            ["remark"] = "",
            ["helpUrl"] = "",
            ["downloadUrl"] = "",
            ["updateUrl"] = "",
            ["className"] = "",
            ["version"] = "",
            ["price"] = "999", // 这里必须存在且是数字
            ["freeDay"] = "1", // 这里必须存在且是数字
            ["size"] = ""
        }
    },
    // 公告
    // url 存在,软件运行,打开网页
    // msg 存在,软件运行,打开弹窗
    // close 等于 true,软件运行后自动关闭
    // cap 不清楚,忘了
    ["msg"] = new JObject
    {
        ["msg"] = "",
        ["cap"] = "",
        ["url"] = "",
        ["close"] = false
    }
};

data = jsonObject;
  1. 保持软件更新(不过这里没有测试过...)

AutoLogin函数里的ApiResult apiResult = Util.GetApiResult(Constants.API_PreRegInfo, 10);复制一份
将获取到的内容通过Data传递下去

  ApiResult apiResult2 = Util.GetApiResult(Constants.API_AutoLogin, 10);
+ ApiResult apiResult = Util.GetApiResult(Constants.API_PreRegInfo, 10);
+ apiResult2.Data = apiResult.Data;
+ apiResult2.Status = 200;
  if (apiResult2.Status == 200)

UpdateDataFromJson里面提取出last_versionupdate_version

string text = data["last_version"].ToString();
string text2 = data["update_version"].ToString();
- ["last_version"] = "123",
- ["update_version"] = "456",
+ ["last_version"] = text,
+ ["update_version"]  = text2,
完整的代码
string text = data["last_version"].ToString();
string text2 = data["update_version"].ToString();

JObject jsonObject = new JObject
{
    ["user_name"] = "52钓鱼崽",
    ["user_create_time"] = DateTime.Now.ToString(),
    ["phone"] = "1234567890",
    ["nick_name"] = "52钓鱼崽",
    ["nick_flag"] = 0,
    ["sex"] = 0,
    ["head_img"] = "http://read.home133.com/img/icon/picture.svg",
    ["status"] = 1,
    ["active_id"] = "A123",
    ["last_version"] = text,
    ["update_version"]  = text2,
    ["expire_date"] = DateTime.Now.AddDays(30.0).ToString(),
    ["qq_group"] = "123456",
    ["channel"] = "Web",
    ["chapter_ai_url"] = "https://acg-q.github.io/new_blog/post/12.html",
    ["member_share_cnt"] = 5,
    ["point_day"] = 50,
    // 更多 选项
    ["append"] = new JArray
    {
        new JObject
        {
            ["url"] = "https://acg-q.github.io/new_blog/post/12.html",
            ["title"] = "52钓鱼崽 破解"
        }
    },
    // 这里应该是插件
    ["site"] = new JArray
    {
        new JObject
        {
            ["url"] = "",
            ["title"] = "",
            ["plug_uid"] = ""
        }
    },
    // 购买了哪些APP
    // 这里的参数都是 和 应用中心 的应用信息一一对应
    ["app"] = new JArray
    {
        new JObject
        {
            ["id"] = "",
            ["name"] = "",
            ["status"] = "1", // 这里必须存在且是数字
            ["enabled"] = "1", // 这里必须存在且是数字
            ["type"] = "1", // 这里必须存在且是数字
            ["path"] = "",
            ["imgUrl"] = "",
            ["remark"] = "",
            ["helpUrl"] = "",
            ["downloadUrl"] = "",
            ["updateUrl"] = "",
            ["className"] = "",
            ["version"] = "",
            ["price"] = "999", // 这里必须存在且是数字
            ["freeDay"] = "1", // 这里必须存在且是数字
            ["size"] = ""
        }
    },
    // 公告
    // url 存在,软件运行,打开网页
    // msg 存在,软件运行,打开弹窗
    // close 等于 true,软件运行后自动关闭
    // cap 不清楚,忘了
    ["msg"] = new JObject
    {
        ["msg"] = "",
        ["cap"] = "",
        ["url"] = "",
        ["close"] = false
    }
};

data = jsonObject;

3. 应用免费下载

  1. 找到DownloadApp这个函数
private void DownloadApp(params object[] objs)
{
	try
	{
		if (objs.Length != 0)
		{
			ReApp rApp = objs[0] as ReApp;
			if (rApp != null)
			{
				if (rApp.Status == 0)
				{
					ApiResult apiResult = Util.GetApiResult(Constants.API_GetApp + "?id=" + rApp.ID, 3);
+					apiResult.Status = 200;
					if (apiResult.Status != 200)
					{
						this.loadingW.ShowMsg(apiResult.Msg, 2);
						return;
					}
					rApp.Status = 1;
				}
				rApp.Status = 1;
				this.cApp = rApp;
				ProgressBar pb = this.barDics[rApp.ID];
				Grid grid = this.gridDics[rApp.ID];
				Button btn = this.btnDics[rApp.ID];
				string appPath = Util.GetAppPath("/app");
				if (!Directory.Exists(appPath))
				{
					Directory.CreateDirectory(appPath);
				}
				string text = appPath + "/" + rApp.Path + ".zip";
				base.Dispatcher.Invoke(delegate
				{
					btn.Content = "下载中";
					pb.Visibility = Visibility.Visible;
				});
				Util.DownLoadFile(text, rApp.DownloadUrl, new TimerDispatcherDelegate(this.SetProgressMax), new TimerDispatcherDelegate(this.SetProgress));
				if (File.Exists(text))
				{
					base.Dispatcher.Invoke(delegate
					{
						btn.Content = "安装中";
						pb.Visibility = Visibility.Visible;
					});
					ZipHelper.UnZipFile(text, appPath);
					if (rApp.IsSetup)
					{
						this.IsChange = true;
						this.btnActions[rApp.ID] = AppAction.Start;
						if (rApp.LocalInfo == null)
						{
							AppInfo appInfo = new AppInfo(rApp);
							appInfo.IsEnabled = true;
							DataProcess.InsertApp(appInfo);
							rApp.LocalInfo = appInfo;
						}
						base.Dispatcher.Invoke(delegate
						{
							pb.Visibility = Visibility.Collapsed;
							this.SetActionStyle(rApp);
						});
					}
				}
			}
		}
	}
	catch (Exception ex)
	{
		Util.AddLog("DownloadApp Error:" + ex.Message);
		throw ex;
	}
}
  1. 允许打开应用

找到AppController
找到AppController下的CheckAppEnable方法

public ApiResult CheckAppEnable()
{
-    return Util.GetApiResult(string.Concat(new string[]
+    ApiResult apiResult = Util.GetApiResult(string.Concat(new string[]
    {
        Constants.API_CheckAppEnabled,
        "?appId=",
        this.app.AppID,
        "&appVer=",
        this.app.Version
     )), 3);
+    apiResult.Status = 200;
+    return apiResult;
}

4. 修改会员信息

  1. 找到RegResult

image

  1. 修改UpdateDataFromJson方法
  public void UpdateDataFromJson(JToken data)
  {
	// 剩余可用积分
- 	this.SharePoint = (int)data["share"];
+   this.SharePoint = 9999;
	this.ExpireDate = data["expire_date"].ToString();
	// 积分总数
- 	this.TotalSharePoint = (int)data["total_share"];
+   this.TotalSharePoint = 9999;
	// 分享数量
- 	this.ShareUserCnt = (int)data["share_ucnt"];
+   this.ShareUserCnt = 456;
	// 不清楚
- 	this.PayPoint = ((data["pay_point"] == null) ? 5 : ((int)data["pay_point"]));
+   this.PayPoint = 999;
	// 用户状态
- 	this.Status = (UserStatus)(int)data["status"];
+	this.Status = UserStatus.Member;
  }

image

5. 插件免费下载(目前无法破解)

Tip

主要关键还是在DownPlug方法中
即便通过给apiResult.Status赋值200,但是apiResult.Data["parse_info"]apiResult.Data["append_info"]的缺失,会导致程序无法往下推进

private void DownPlug(object[] objs)
{
	ApiResult apiResult = Util.GetApiResult(Constants.API_PlugDownloadUrl + "?plugID=" + this.plug.UID, 3);
	if (apiResult.Status == 200)
	{
		this.plug.LocalFlag = 1;
		this.plug.ParseInfo = apiResult.Data["parse_info"].ToString();
		this.plug.AppendInfo = apiResult.Data["append_info"].ToString();
		DataProcess.UpdateUrlPlug(this.plug);
		base.Dispatcher.Invoke(delegate
		{
			this.IsChanged = true;
			base.Close();
		});
		return;
	}
	this.loadingW.ShowMsg(apiResult.Msg, 3);
}

或许只有研究一下,如何刷分享值了

相关资源

Note

在线版: v1.2.0.5
离线版: v1.2.0.5

C#反编译工具: https://github.com/dnSpyEx/dnSpy
dnSpyEx/dnSpy - GitHub

Read133_Offline.zip

read133_pro.zip

转载请注明出处