某屏幕录像大师注册流程分析笔记(C#调用C++DLL RSA)
先上个图片吧.重启验证系列,,网站就不发了.需要练手的,可以私聊我,获取下载地址经过查壳,
发现是 Microsoft Visual C# / Basic .NET [覆盖] 编写的,心想这下可以直接做注册机了!
毕竟可以反编译,但结果并没我想的那么顺利
dnSpy-x86载入程序,dnSpy-x86可以到爱盘下载
载入之后,优先选择跟注册相关的窗口类进入
大致一看,貌似函数被进行过处理吧.我对C#的反编译操作不多.反正一脸蒙,附带上代码
FormRegister 代码如下
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
using ScreenRecorder5.Properties;
namespace ScreenRecorder5
{
// Token: 0x0200003C RID: 60
public class FormRegister : Form
{
// Token: 0x06000244 RID: 580 RVA: 0x0000CFEA File Offset: 0x0000B1EA
public FormRegister()
{
this.a();
}
// Token: 0x06000245 RID: 581 RVA: 0x0000CFF8 File Offset: 0x0000B1F8
private void e(object A_0, EventArgs A_1)
{
this.b();
}
// Token: 0x06000246 RID: 582 RVA: 0x0000D000 File Offset: 0x0000B200
private void d(object A_0, EventArgs A_1)
{
base.Close();
}
// Token: 0x06000247 RID: 583 RVA: 0x0000D008 File Offset: 0x0000B208
private void c(object A_0, EventArgs A_1)
{
}
// Token: 0x06000248 RID: 584 RVA: 0x0000D00C File Offset: 0x0000B20C
private void b(object A_0, EventArgs A_1)
{
if (q.c())
{
q.h("");
q.g("");
q.f("");
q.e("");
string caption = q.c("APP_Caption");
MessageBox.Show(q.c("Msg_UnReg_Successful"), caption, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
this.b();
return;
}
string text = this.g.Text;
string text2 = this.f.Text;
text = text.Trim();
text2 = text2.Trim();
int num = 0;
if (!ab.a(text, text2, out num))
{
string caption2 = q.c("APP_Caption");
MessageBox.Show(q.c("Msg_ErrorRegCode"), caption2, MessageBoxButtons.OK, MessageBoxIcon.Hand);
return;
}
int a_;
if (num == q.d)
{
a_ = 29;
}
else if (num == q.e)
{
a_ = 30;
}
else if (num == q.e)
{
a_ = 31;
}
else
{
a_ = 29;
}
q.a(a_);
q.b(text);
if (!false)
{
q.h(text);
q.g(text2);
string caption3 = q.c("APP_Caption");
MessageBox.Show(q.c("Msg_RegistrationSuccessful"), caption3, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
this.b();
return;
}
}
// Token: 0x06000249 RID: 585 RVA: 0x0000D140 File Offset: 0x0000B340
private void a(object A_0, EventArgs A_1)
{
if (!q.c())
{
global::p.j();
return;
}
global::p.i();
}
// Token: 0x0600024A RID: 586 RVA: 0x0000D158 File Offset: 0x0000B358
private void b()
{
if (q.c())
{
string text = q.p();
string text2 = q.o();
this.g.Text = text;
this.f.Text = text2;
this.g.Enabled = false;
this.f.Enabled = false;
string text3 = q.c("ButtonText_Renew");
string text4 = q.c("ButtonText_UnReg");
this.k.Text = text3;
this.e.Text = text4;
this.k.Enabled = false;
return;
}
this.g.Text = "";
this.f.Text = "";
this.g.Enabled = true;
this.f.Enabled = true;
this.k.Enabled = true;
string text5 = q.c("ButtonText_BuyNow");
string text6 = q.c("ButtonText_Register");
this.k.Text = text5;
this.e.Text = text6;
string text7 = "Please copy and paste your registration name and registration code";
this.m.Text = text7;
}
// Token: 0x0600024B RID: 587 RVA: 0x0000D26D File Offset: 0x0000B46D
protected override void Dispose(bool disposing)
{
if (disposing && this.a != null)
{
this.a.Dispose();
}
base.Dispose(disposing);
}
// Token: 0x0600024C RID: 588 RVA: 0x0000D28C File Offset: 0x0000B48C
private void a()
{
ComponentResourceManager componentResourceManager = new ComponentResourceManager(typeof(FormRegister));
this.b = new Label();
this.c = new GroupBox();
this.m = new Label();
this.d = new Button();
this.e = new Button();
this.f = new TextBox();
this.g = new TextBox();
this.h = new Label();
this.i = new Label();
this.j = new GroupBox();
this.p = new Label();
this.o = new Label();
this.n = new Label();
this.k = new Button();
this.l = new Label();
this.c.SuspendLayout();
this.j.SuspendLayout();
base.SuspendLayout();
this.b.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right);
this.b.Font = new Font("宋体", 17.5f, FontStyle.Bold, GraphicsUnit.Point, 134);
this.b.Location = new Point(16, 24);
this.b.Name = "labelTitle";
this.b.Size = new Size(452, 30);
this.b.TabIndex = 0;
this.b.Text = "TVT Screen Recorder";
this.b.TextAlign = ContentAlignment.MiddleCenter;
this.c.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right);
this.c.Controls.Add(this.m);
this.c.Controls.Add(this.d);
this.c.Controls.Add(this.e);
this.c.Controls.Add(this.f);
this.c.Controls.Add(this.g);
this.c.Controls.Add(this.h);
this.c.Controls.Add(this.i);
this.c.Location = new Point(16, 310);
this.c.Margin = new Padding(3, 2, 3, 2);
this.c.Name = "groupBoxRegister";
this.c.Padding = new Padding(3, 2, 3, 2);
this.c.Size = new Size(452, 149);
this.c.TabIndex = 2;
this.c.TabStop = false;
this.m.Location = new Point(16, 16);
this.m.Name = "labelExprirationInfo";
this.m.Size = new Size(420, 19);
this.m.TabIndex = 0;
this.m.Text = "Please copy and paste your registration name and registration code";
this.m.TextAlign = ContentAlignment.MiddleCenter;
this.d.Location = new Point(240, 107);
this.d.Margin = new Padding(3, 2, 3, 2);
this.d.Name = "buttonLater";
this.d.Size = new Size(120, 30);
this.d.TabIndex = 6;
this.d.Text = "&Cancel";
this.d.UseVisualStyleBackColor = true;
this.d.Click += this.d;
this.e.Location = new Point(91, 107);
this.e.Margin = new Padding(3, 2, 3, 2);
this.e.Name = "buttonRegister";
this.e.Size = new Size(120, 30);
this.e.TabIndex = 5;
this.e.Text = "&Register";
this.e.UseVisualStyleBackColor = true;
this.e.Click += this.b;
this.f.Location = new Point(148, 75);
this.f.Margin = new Padding(3, 2, 3, 2);
this.f.Name = "textBoxRegistrationCode";
this.f.Size = new Size(288, 21);
this.f.TabIndex = 4;
this.g.Location = new Point(148, 43);
this.g.Margin = new Padding(3, 2, 3, 2);
this.g.Name = "textBoxRegistrationName";
this.g.Size = new Size(288, 21);
this.g.TabIndex = 2;
this.h.AutoSize = true;
this.h.Location = new Point(16, 79);
this.h.Name = "labelRegistrationCode";
this.h.Size = new Size(107, 12);
this.h.TabIndex = 3;
this.h.Text = "Registration Code";
this.i.AutoSize = true;
this.i.Location = new Point(16, 47);
this.i.Name = "labelRegistrationName";
this.i.Size = new Size(107, 12);
this.i.TabIndex = 1;
this.i.Text = "Registration Name";
this.j.Anchor = (AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right);
this.j.Controls.Add(this.p);
this.j.Controls.Add(this.o);
this.j.Controls.Add(this.n);
this.j.Controls.Add(this.k);
this.j.Controls.Add(this.l);
this.j.Location = new Point(16, 62);
this.j.Margin = new Padding(3, 2, 3, 2);
this.j.Name = "groupBoxTalk";
this.j.Padding = new Padding(3, 2, 3, 2);
this.j.Size = new Size(452, 240);
this.j.TabIndex = 1;
this.j.TabStop = false;
this.p.Location = new Point(16, 54);
this.p.Name = "labelTalk2";
this.p.Size = new Size(420, 30);
this.p.TabIndex = 4;
this.p.Text = "Our goal is to build high quality software and provide excellent customer service for you.";
this.p.TextAlign = ContentAlignment.MiddleLeft;
this.o.Font = new Font("宋体", 9f, FontStyle.Bold, GraphicsUnit.Point, 134);
this.o.ForeColor = SystemColors.MenuText;
this.o.Location = new Point(15, 92);
this.o.Name = "labelLimitation";
this.o.Size = new Size(420, 30);
this.o.TabIndex = 3;
this.o.Text = "The limitation of this copy is the recording length is limited to 120 seconds.";
this.o.TextAlign = ContentAlignment.MiddleLeft;
this.n.Location = new Point(17, 130);
this.n.Name = "labelLove";
this.n.Size = new Size(420, 45);
this.n.TabIndex = 2;
this.n.Text = "Would you like to purchase a full-featured license to remove all limitations in this copy? We promise you can use and update this software for life.\r\n";
this.n.TextAlign = ContentAlignment.MiddleLeft;
this.k.Font = new Font("宋体", 9f, FontStyle.Bold, GraphicsUnit.Point, 134);
this.k.ForeColor = SystemColors.InfoText;
this.k.Image = Resources.coffe32x32;
this.k.ImageAlign = ContentAlignment.MiddleRight;
this.k.Location = new Point(136, 183);
this.k.Margin = new Padding(3, 2, 3, 2);
this.k.Name = "buttonLove";
this.k.Size = new Size(180, 45);
this.k.TabIndex = 0;
this.k.Text = "Yes, I'd like to.";
this.k.TextImageRelation = TextImageRelation.ImageBeforeText;
this.k.UseVisualStyleBackColor = true;
this.k.Click += this.a;
this.l.Location = new Point(16, 16);
this.l.Name = "labelTalk1";
this.l.Size = new Size(420, 30);
this.l.TabIndex = 0;
this.l.Text = "The first version of the TVT Screen Recorder was released in 2010. In past years, we are constantly updating and improving our software.";
this.l.TextAlign = ContentAlignment.MiddleLeft;
base.AcceptButton = this.k;
base.AutoScaleDimensions = new SizeF(6f, 12f);
base.AutoScaleMode = AutoScaleMode.Font;
this.AutoScroll = true;
this.AutoSize = true;
base.ClientSize = new Size(484, 475);
base.Controls.Add(this.j);
base.Controls.Add(this.c);
base.Controls.Add(this.b);
base.FormBorderStyle = FormBorderStyle.FixedDialog;
base.Icon = (Icon)componentResourceManager.GetObject("$this.Icon");
base.Margin = new Padding(3, 2, 3, 2);
base.MaximizeBox = false;
base.MinimizeBox = false;
base.Name = "FormRegister";
base.StartPosition = FormStartPosition.CenterScreen;
this.Text = "Registration Now";
base.Load += this.e;
this.c.ResumeLayout(false);
this.c.PerformLayout();
this.j.ResumeLayout(false);
base.ResumeLayout(false);
}
// Token: 0x040001FB RID: 507
private IContainer a;
// Token: 0x040001FC RID: 508
private Label b;
// Token: 0x040001FD RID: 509
private GroupBox c;
// Token: 0x040001FE RID: 510
private Button d;
// Token: 0x040001FF RID: 511
private Button e;
// Token: 0x04000200 RID: 512
private TextBox f;
// Token: 0x04000201 RID: 513
private TextBox g;
// Token: 0x04000202 RID: 514
private Label h;
// Token: 0x04000203 RID: 515
private Label i;
// Token: 0x04000204 RID: 516
private GroupBox j;
// Token: 0x04000205 RID: 517
private Button k;
// Token: 0x04000206 RID: 518
private Label l;
// Token: 0x04000207 RID: 519
private Label m;
// Token: 0x04000208 RID: 520
private Label n;
// Token: 0x04000209 RID: 521
private Label o;
// Token: 0x0400020A RID: 522
private Label p;
}
}
关键代码是这样一段 我已备注 从代码可以看出,我们继续跟进 ab这个类即可.
private void b(object A_0, EventArgs A_1)
{
if (q.c())
{
q.h("");
q.g("");
q.f("");
q.e("");
string caption = q.c("APP_Caption");
MessageBox.Show(q.c("Msg_UnReg_Successful"), caption, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
this.b();
return;
}
string text = this.g.Text;//输入的用户名
string text2 = this.f.Text;//输入的密码
text = text.Trim();
text2 = text2.Trim();
int num = 0;
if (!ab.a(text, text2, out num))//ab.a (代码在下面 已备注) 调用函数 如果返回0 则提示错误
{
string caption2 = q.c("APP_Caption");
MessageBox.Show(q.c("Msg_ErrorRegCode"), caption2, MessageBoxButtons.OK, MessageBoxIcon.Hand);//弹出错误的注册码提示
return;
}
int a_;
if (num == q.d)
{
a_ = 29;
}
else if (num == q.e)
{
a_ = 30;
}
else if (num == q.e)
{
a_ = 31;
}
else
{
a_ = 29;
}
q.a(a_);
q.b(text);
if (!false)
{
q.h(text);
q.g(text2);
string caption3 = q.c("APP_Caption");
MessageBox.Show(q.c("Msg_RegistrationSuccessful"), caption3, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
//弹出正确的提示
this.b();
return;
}
}using System;
using System.Text;
// Token: 0x0200002B RID: 43
internal class ab
{
// Token: 0x0600013E RID: 318 RVA: 0x00005778 File Offset: 0x00003978
private static int c(string A_0, string A_1)
{
string text = "-----BEGIN PUBLIC KEY-----\nMDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhALQbAuvV+BWW+xtspfWhIaxgOxWT8hrM\n11yfOxgFqNMrAgMBAAE=\n-----END PUBLIC KEY-----";
StringBuilder stringBuilder = new StringBuilder(512);
stringBuilder.Clear();
if (i.a(text, text.Length, A_1, A_1.Length, stringBuilder, 512) == 0)
{
string b = stringBuilder.ToString();
if (A_0 == b && A_0 != "")
{
return 100;
}
}
return -1;
}
// Token: 0x0600013F RID: 319 RVA: 0x000057D8 File Offset: 0x000039D8
private static int b(string A_0, string A_1)
{
string text = "-----BEGIN PUBLIC KEY-----\nMDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAONkGAMKMfWW8H9pMajrbniEDtUuhY5T\n8xMIeFTl5kJpAgMBAAE=\n-----END PUBLIC KEY-----\n";
StringBuilder stringBuilder = new StringBuilder(512);
stringBuilder.Clear();
if (i.a(text, text.Length, A_1, A_1.Length, stringBuilder, 512) == 0)
{
string b = stringBuilder.ToString();
if (A_0 == b && A_0 != "")
{
return 100;
}
}
return -1;
}
// Token: 0x06000140 RID: 320 RVA: 0x00005838 File Offset: 0x00003A38
private static int a(string A_0, string A_1)
{
string text = "-----BEGIN PUBLIC KEY-----\nMDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAJxo01j0uANaQkNCnrK+028I1J6wvJNS\nzXgELMbiF7eXAgMBAAE=\n-----END PUBLIC KEY-----\n";
StringBuilder stringBuilder = new StringBuilder(512);
stringBuilder.Clear();
if (i.a(text, text.Length, A_1, A_1.Length, stringBuilder, 512) == 0)
{
string b = stringBuilder.ToString();
if (A_0 == b && A_0 != "")
{
return 100;
}
}
return -1;
}
// Token: 0x06000141 RID: 321 RVA: 0x00005898 File Offset: 0x00003A98
public static bool a(string A_0, string A_1, out int A_2)
{
A_2 = -1;
if (A_0 == null)
{
return false;
}
if (A_1 == null)
{
return false;
}
if (A_0.CompareTo("") == 0)
{
return false;
}
if (A_1.CompareTo("") == 0)
{
return false;
}
if (A_0.CompareTo("sr5_user000") == 0)
{
return false;
}
if (ab.c(A_0, A_1) == 100)
{
A_2 = q.d;
return true;
}
if (ab.b(A_0, A_1) == 100)
{
A_2 = q.e;
return true;
}
if (ab.a(A_0, A_1) == 100)
{
A_2 = q.f;
return true;
}
return false;
}
// Token: 0x06000142 RID: 322 RVA: 0x0000591C File Offset: 0x00003B1C
public static int a()
{
return 0;
}
}
代码每个颜色对应的.流程控制的命令
不难发现 这是一串RSA加密的操作找到共同的
if (i.a(text, text.Length, A_1, A_1.Length, stringBuilder, 512) == 0)
跟进入
public static int a(string A_0, int A_1, string A_2, int A_3, StringBuilder A_4, int A_5)
{
return i.DLL_GTRSADecode_NoPadding(A_0, A_1, A_2, A_3, A_4, A_5);
}继续跟,发现最终调用的是 GTRSADll.dll 的导出函数 GTRSADecode_NoPadding 从名字看出 貌似是个解密函数
private static extern int DLL_GTRSADecode_NoPadding(string A_0, int A_1, string A_2, int A_3, StringBuilder A_4, int A_5);从传参来看 调用的是 公钥解密 那么存在的可能,也许是私钥加密,或其他.
private static extern int DLL_GTRSAEncode_NoPadding(string A_0, int A_1, string A_2, int A_3, StringBuilder A_4, int A_5);本以为是内置的私钥,却发现 无法定位到,虽然软件内有几个私钥,但是,我怎么用,都没办法顺利完成验证.所以,我打算对DLL分析一下
对DLL 查壳Microsoft Visual C++ 6.0~7.10是VC++写的.IDA导入定位到 GTRSADecode_NoPadding 看看
int __cdecl GTRSADecode_NoPadding(int a1, int a2, int a3, int a4, void *a5, int a6)
{
int v6; // eax
int v7; // esi
int v8; // edi
int v9; // esi
void *v10; // ebx
void *v11; // eax
void *v12; // esi
signed int v13; // eax
int v15; //
int v16; //
SSL_library_init();
SSL_load_error_strings();
v6 = BIO_new_mem_buf(a1, -1);
v7 = v6;
if ( !v6 )
return -1;
v8 = PEM_read_bio_RSA_PUBKEY(v6, 0, 0, 0);
if ( !v8 )
return -1;
BIO_free_all(v7);
v9 = RSA_size(v8);
v10 = malloc((v9 + 1) | -__CFADD__(v9, 1));
if ( !v10 )
{
LABEL_11:
RSA_free(v8);
return -1;
}
v16 = v9 + 1;
sub_10002900(v10, 0, v9 + 1);
v15 = sub_10001010(v10, a3);
v11 = malloc((v9 + 1) | -__CFADD__(v9, 1));
v12 = v11;
if ( !v11 || (sub_10002900(v11, 0, v16), v13 = RSA_public_decrypt(v15, v10, v12, v8, 3), v13 < 0) )
{
sub_10003CD9(v10);
if ( v12 )
sub_10003CD9(v12);
goto LABEL_11;
}
if ( a6 > v16 )
sub_10001940(a5, v12, v13);
sub_10003CD9(v10);
sub_10003CD9(v12);
RSA_free(v8);
return 0;
}
好吧,这个DLL 就是一个RSA解密的.也就是说,可能是在服务器算的注册码,到本地解密. 如果解密成功,返回0 否则返回 -1
回到 dnspy 查看这个代码
private static int c(string A_0, string A_1)
{
string text = "-----BEGIN PUBLIC KEY-----\nMDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhALQbAuvV+BWW+xtspfWhIaxgOxWT8hrM\n11yfOxgFqNMrAgMBAAE=\n-----END PUBLIC KEY-----";
StringBuilder stringBuilder = new StringBuilder(512);
stringBuilder.Clear();
if (i.a(text, text.Length, A_1, A_1.Length, stringBuilder, 512) == 0)//i.a就是DLL解密函数,解密出来的结果 是stringBuilder
{
string b = stringBuilder.ToString();// 解密结果 保存到变量b 并且
if (A_0 == b && A_0 != "")//和 A_0进行对比.也就是说.
{
return 100;//解密出来等于用户名,那就说明注册成功
}
}
return -1;// ,否则注册失败
}继续看上层代码
if (ab.c(A_0, A_1) == 100)//返回100
{
A_2 = q.d;//把q.d给A_2 这个q.d 下面的q.e q.f 应该是决定版本的
return true; //返回true 回到上一层 会提示注册成功请重新启动,
}
if (ab.b(A_0, A_1) == 100)
{
A_2 = q.e;
return true;
}
if (ab.a(A_0, A_1) == 100)
{
A_2 = q.f;
return true;
}到这里完成一半了.为什么说一半,因为还有代码编写部分.
我打算采用劫持的替换 GTRSADll.dll 的方法 达到伪造的目的.
所以, GTRSADecode_NoPadding首先要返回0 其次,还要返回我们输入用户名.
GTRSADecode_NoPadding 只要处理这个函数即可!其他的函数完全没必要处理.
备份软件的GTRSADll.dll用写好的替换
启动软件 输入 代码中内置的 用户名 52PoJie.cn 注册码随意 不要中文即可
重新启动查看效果
目前来说 是标准版, 回到刚才说的. A_2 = q.d;//把q.d给A_2 这个q.d 下面的q.e q.f 应该是决定版本的
根据逻辑走一下当注册的时候 会调用3次 GTRSADecode_NoPadding 全部不符合,就提示失败
那么,我们可以根据RSA密钥来区分是什么版本.
进入DLL进行判断,.如果密钥等于指定的,我们可以返回对应的版本
string text = "-----BEGIN PUBLIC KEY-----\nMDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAJxo01j0uANaQkNCnrK+028I1J6wvJNS\nzXgELMbiF7eXAgMBAAE=\n-----END PUBLIC KEY-----\n";修改易语言代码 对Key进行判断
编译出来后 替换DLL 打开软件 提示企业版,限制全部通过 .
本文仅供学习交流,不提供任何下载地址,如有侵权或违规,请直接删除 本帖最后由 wtujoxk 于 2020-7-7 12:50 编辑
因式分解得到的RSA密钥对,有了它注册机编写就不远了!密钥测试网址:http://tool.chacuo.net/cryptrsakeyvalid
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhALQbAuvV+BWW+xtspfWhIaxgOxWT8hrM
11yfOxgFqNMrAgMBAAE=
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIGdAgEAAiEAtBsC69X4FZb7G2yl9aEhrGA7FZPyGszXXJ87GAWo0ysCAwEAAQIg
TTp/6CyZ8ngJONs/1rG/Q/fWNmtaA5jn1mgIHgO44xECEQDBDUTyhZHJLs5WWC93
bN0VAhEA7tUQ8uWcwXRYbfU8la1/PwIMAN8cmeLwmJ1vMwXNAgwDJ0hLu1ex3MQQ
e7ECDAC/MRO8jHbKkD4Gyw==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAONkGAMKMfWW8H9pMajrbniEDtUuhY5T
8xMIeFTl5kJpAgMBAAE=
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIGdAgEAAiEA42QYAwox9Zbwf2kxqOtueIQO1S6FjlPzEwh4VOXmQmkCAwEAAQIg
O2dtwnWKYa9h+tcfaxK+U+1jfA+ROX+O9Mq2n2AvG5ECEQDkZ0/Ld2v7vlX1oXXc
apLtAhEA/t12azcHKhIxe6JujZSR7QIMAN8cmeLwmJ1vMwXNAgwDJ0hLu1ex3MQQ
e7ECDAC/MRO8jHbKkD4Gyw==
-----END RSA PRIVATE KEY-----
-----BEGIN PUBLIC KEY-----
MDwwDQYJKoZIhvcNAQEBBQADKwAwKAIhAJxo01j0uANaQkNCnrK+028I1J6wvJNS
zXgELMbiF7eXAgMBAAE=
-----END PUBLIC KEY-----
-----BEGIN RSA PRIVATE KEY-----
MIGdAgEAAiEAnGjTWPS4A1pCQ0Kesr7TbwjUnrC8k1LNeAQsxuIXt5cCAwEAAQIg
cFMTnKm6UKYMOjNotuM2AULX4sqW2Gv1HT122AeM54ECEQDPNBwEbf59zbmCqt/g
G6bXAhEAwT5xLYC7RcTQWVqqhrQdQQIMAN8cmeLwmJ1vMwXNAgwDJ0hLu1ex3MQQ
e7ECDAC/MRO8jHbKkD4Gyw==
-----END RSA PRIVATE KEY-----
本帖最后由 jixun66 于 2020-7-7 19:40 编辑
分享三组注册码:
版 本: 标准版
注册名: sr5_user101
注册码: EUcRiweMmDcHvUyIKxjP+EMBia718bcdC2fYSMgdOMk=
版 本: 专业版
注册名: sr5_pro_user101
注册码: DSzDdLk1Ty4MYMc6m+69RfxdTtQrA6Xfs1E+F7dfEQg=
版 本: 企业版
注册名: sr5_ent_user101
注册码: dvw5UZD62qFAguDK9N3rQfWq8iHD75hcj/oIzEnibLs=
这几个好像是不会进行机器验证的特别用户名。 本帖最后由 jixun66 于 2020-7-8 18:47 编辑
wtujoxk 发表于 2020-7-8 06:27
大佬能分析一下正常的注册码被怎样移位或者异或得到最终注册码么?我看得一脸懵逼!求教???
直接调用 `GTRSAEncode_NoPadding` 就好,不过要做一点小处理。
首先要补丁掉输入长度限制:
```csharp
class LibraryPatcher
{
static extern IntPtr GetCurrentProcess();
static extern bool VirtualProtect(IntPtr lpAddress, uint dwSize, Protection flNewProtect, out Protection lpflOldProtect);
static extern IntPtr LoadLibrary( string lpFileName);
static extern IntPtr GetProcAddress(IntPtr hModule, string procName);
public static extern bool WriteProcessMemory(IntPtr hProcess, IntPtr lpBaseAddress, byte[] lpBuffer, int nSize, int lpNumberOfBytesWritten);
public enum Protection: uint
{
PAGE_NOACCESS = 0x01,
PAGE_READONLY = 0x02,
PAGE_READWRITE = 0x04,
PAGE_WRITECOPY = 0x08,
PAGE_EXECUTE = 0x10,
PAGE_EXECUTE_READ = 0x20,
PAGE_EXECUTE_READWRITE = 0x40,
PAGE_EXECUTE_WRITECOPY = 0x80,
PAGE_GUARD = 0x100,
PAGE_NOCACHE = 0x200,
PAGE_WRITECOMBINE = 0x400
}
internal static void PatchSizeLimit()
{
var hDll = LoadLibrary("GTRSADll.dll");
if (hDll == IntPtr.Zero)
{
throw new FileLoadException("Could not load GTRSADll.dll");
}
var fnGTRSAEncode_NoPadding = GetProcAddress(hDll, "GTRSAEncode_NoPadding");
if (fnGTRSAEncode_NoPadding == IntPtr.Zero)
{
throw new FileLoadException("Could not find export: GTRSAEncode_NoPadding");
}
// 7A9815D0 | 55 | push ebp |
// ........
// 7A98166D | 83C4 08 | add esp,8 |
// 7A981670 | 8D42 F5 | lea eax,dword ptr ds:|
// ^^ 原来的 F5 改成 01
// 7A981670 | 8D42 01 | lea eax,dword ptr ds:|
var offset = 0x7A981670 + 2 - 0x7A9815D0;
var patchAddress = fnGTRSAEncode_NoPadding + offset;
Protection oldProtection;
if (!VirtualProtect(patchAddress, 1, Protection.PAGE_EXECUTE_READWRITE, out oldProtection))
{
throw new Exception("could not change memoey type");
}
WriteProcessMemory(GetCurrentProcess(), patchAddress, new byte[] { 0x01 }, 1, 0);
VirtualProtect(patchAddress, 1, oldProtection, out oldProtection);
}
}
```
其次要填充用户名到 32 字节:
```csharp
class Keygen
{
public static string PrivKeyProfessional = @"-----BEGIN RSA PRIVATE KEY-----
MIGdAgEAAiEA42QYAwox9Zbwf2kxqOtueIQO1S6FjlPzEwh4VOXmQmkCAwEAAQIg
O2dtwnWKYa9h+tcfaxK+U+1jfA+ROX+O9Mq2n2AvG5ECEQDkZ0/Ld2v7vlX1oXXc
apLtAhEA/t12azcHKhIxe6JujZSR7QIMAN8cmeLwmJ1vMwXNAgwDJ0hLu1ex3MQQ
e7ECDAC/MRO8jHbKkD4Gyw==
-----END RSA PRIVATE KEY-----";
public static string PrivKeyEnterprise = @"-----BEGIN RSA PRIVATE KEY-----
MIGdAgEAAiEAnGjTWPS4A1pCQ0Kesr7TbwjUnrC8k1LNeAQsxuIXt5cCAwEAAQIg
cFMTnKm6UKYMOjNotuM2AULX4sqW2Gv1HT122AeM54ECEQDPNBwEbf59zbmCqt/g
G6bXAhEAwT5xLYC7RcTQWVqqhrQdQQIMAN8cmeLwmJ1vMwXNAgwDJ0hLu1ex3MQQ
e7ECDAC/MRO8jHbKkD4Gyw==
-----END RSA PRIVATE KEY-----";
public static string PrivKeyStandard = @"-----BEGIN RSA PRIVATE KEY-----
MIGdAgEAAiEAtBsC69X4FZb7G2yl9aEhrGA7FZPyGszXXJ87GAWo0ysCAwEAAQIg
TTp/6CyZ8ngJONs/1rG/Q/fWNmtaA5jn1mgIHgO44xECEQDBDUTyhZHJLs5WWC93
bN0VAhEA7tUQ8uWcwXRYbfU8la1/PwIMAN8cmeLwmJ1vMwXNAgwDJ0hLu1ex3MQQ
e7ECDAC/MRO8jHbKkD4Gyw==
-----END RSA PRIVATE KEY-----";
static Keygen()
{
try
{
LibraryPatcher.PatchSizeLimit();
}
catch (Exception ex)
{
MessageBox.Show("动态补丁 GTRSADll.dll 发生错误:\n" + ex.Message);
}
}
public static string EncodePassword(string name, string privKey)
{
var sb = new StringBuilder();
sb.Append(name);
sb.Append('\x00', 32 - name.Length);
var enc = RSA.RSAEncode_NoPadding(privKey, sb.ToString());
// Console.WriteLine("error: " + RSA.GetError().Trim());
// Console.WriteLine("enc: " + enc);
return enc;
}
}
```
其它代码写的太烂就不放出来了 {:301_978:}
直接拿反编译工具看就行,反正没混淆。
大佬们是不是不用花钱呀?感觉你们看见一个软件,步骤都一样:
OD,摆进去看看
劫持,拦截返回的一些信息
修改数值,以达到目的
最后,成功“学习”
{:301_1003:} 优秀~~~~~~~~~~~~ waltzofjack 发表于 2020-7-6 17:24
大佬们是不是不用花钱呀?感觉你们看见一个软件,步骤都一样:
OD,摆进去看看
劫持,拦截返回的一些信息 ...
{:301_993:}主要是学习,其他的都是其次{:301_1004:} 揰掵佲 发表于 2020-7-6 17:32
主要是学习,其他的都是其次
我本来也想弄弄OD,结果必须下载360管家,我去他个360管家,看见这个还是放弃OD了 你是真人,还是模仿的呀?特别喜欢乐易的课。 密钥等于指定的 感谢分享,0{:301_998:} 感谢分享教程
waltzofjack 发表于 2020-7-6 17:32
我本来也想弄弄OD,结果必须下载360管家,我去他个360管家,看见这个还是放弃OD了
OD和360管家有什么关系?OD直接可以爱盘下载。