首页
论坛
课程
招聘
[求助].net算法
2009-10-8 10:33 9014

[求助].net算法

2009-10-8 10:33
9014
被混淆了……

用软件反混淆后发现后用switch做的流程混淆,看了半天没看懂它的算法

玩.net的有兴趣的话看下

关键代码在

Public Class Class_7_Form
Private Sub Procedure_6(ByVal A_0 As Object, ByVal A_1 As System.EventArgs)

[招生]科锐逆向工程师培训46期预科班将于 2023年02月09日 正式开班

收藏
点赞0
打赏
分享
最新回复 (23)
雪    币: 26
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zlws 活跃值 2009-10-9 12:44
2
0
下来
看看

好冷清啊
雪    币: 290
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
芳草碧连 活跃值 2009-10-10 13:39
3
0
额 看来有难度?
雪    币: 83
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
atrm 活跃值 2009-10-10 19:48
4
0
转存到vs项目分析源码试试
雪    币: 5002
活跃值: 活跃值 (182)
能力值: (RANK:1170 )
在线值:
发帖
回帖
粉丝
tankaiha 活跃值 29 2009-10-10 20:24
5
0
贴子中,关键方法的名称与附件提供的程序中的名称不一样,估计你是指class b 中的private void d(object A_0_1, EventArgs A_1_2)

反混淆了一下
private void d(object A_0_1, EventArgs A_1_2)
{
    string str = this.e.Text.Trim() + "-" + this.n.Text.Trim() + "-" + this.o.Text.Trim() + "-" + this.p.Text.Trim();
    string str2 = this.f.Text.Trim().ToUpper() + this.h.Text.Trim().ToUpper();
    int num = this.b.a(str, str2);
    this.a = num;
    if (num != 0)
    {
        if (num != -2)
        {
            MessageBox.Show("序列号不正确!", "提示");
        }
        else
        {
            MessageBox.Show("序列号与注册码错误!", "提示");
        }
    }
    else
    {
        str = this.b.g(str);
        byte[] bytes = Encoding.Default.GetBytes(str.ToUpper());
        this.b.a("MaplotusSerials", bytes);
        str2 = this.b.f(str2);
        byte[] buffer2 = Encoding.Default.GetBytes(str2.ToUpper());
        this.b.a("MaplotusKeys", buffer2);
        this.e.Enabled = false;
        this.f.Enabled = false;
        this.h.Enabled = false;
        this.n.Enabled = false;
        this.o.Enabled = false;
        this.p.Enabled = false;
        this.i.Enabled = false;
        this.j.Enabled = false;
        base.Close();
    }
}

这个版本 的switch混淆不是最强的,很多加密软件的switch算法厉害的多。反混淆工具原来发过了,http://bbs.pediy.com/showthread.php?t=90356&highlight=

快一年没玩.net了,不知道现在怎么样了。
雪    币: 5002
活跃值: 活跃值 (182)
能力值: (RANK:1170 )
在线值:
发帖
回帖
粉丝
tankaiha 活跃值 29 2009-10-10 20:27
6
0
接着来,注册码比较出来了,算法是什么,应该在
int num = this.b.a(str, str2);的a方法中
我反混淆后,出现错误,不能直接反成C#。简单调整了下,代码如下,虽然还是错的,但大体可以看出模式

public int a(string A_0_1, string A_1_2)
{
    // This item is obfuscated and can not be translated.
    string[] strArray = A_0_1.Split(new char[] { '-' });
    int[] numArray = new int[8];
    int[] numArray2 = new int[8];
    string str = "";
    if (((strArray.Length == 4) && (strArray[0].Length == 8)) && ((strArray[1].Length == 8) && (strArray[2].Length == 8)))
    {
        goto Label_051D;
    }
    if (true)
    {
        return -1;
    }
    char ch = strArray[0][2];
    ch = strArray[3][0];
    numArray[0] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[0][4];
    ch = strArray[3][1];
    numArray[1] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[0][7];
    ch = strArray[3][2];
    numArray[2] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[0][6];
    ch = strArray[3][3];
    numArray[3] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[0][0];
    ch = strArray[3][4];
    numArray[4] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[0][5];
    ch = strArray[3][5];
    numArray[5] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[0][1];
    ch = strArray[3][6];
    numArray[6] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[0][3];
    ch = strArray[3][7];
    numArray[7] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[1][6];
    ch = strArray[2][0];
    numArray2[0] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[1][7];
    ch = strArray[2][1];
    numArray2[1] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[1][2];
    ch = strArray[2][2];
    numArray2[2] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[1][0];
    ch = strArray[2][3];
    numArray2[3] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[1][1];
    ch = strArray[2][4];
    numArray2[4] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[1][4];
    ch = strArray[2][5];
    numArray2[5] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[1][3];
    ch = strArray[2][6];
    numArray2[6] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    ch = strArray[1][5];
    ch = strArray[2][7];
    numArray2[7] = (Convert.ToInt32(ch.ToString(), 0x10) + Convert.ToInt32(ch.ToString(), 0x10)) % 0x10;
    str = (((Convert.ToString((int) ((numArray[0] + numArray2[5]) % 0x10), 0x10) + Convert.ToString((int) ((numArray[1] + numArray2[3]) % 0x10), 0x10)) + Convert.ToString((int) ((numArray[2] + numArray2[0]) % 0x10), 0x10) + Convert.ToString((int) ((numArray[3] + numArray2[1]) % 0x10), 0x10)) + Convert.ToString((int) ((numArray[4] + numArray2[7]) % 0x10), 0x10) + Convert.ToString((int) ((numArray[5] + numArray2[6]) % 0x10), 0x10)) + Convert.ToString((int) ((numArray[6] + numArray2[4]) % 0x10), 0x10) + Convert.ToString((int) ((numArray[7] + numArray2[2]) % 0x10), 0x10);
    if (!(A_1_2 == str.ToUpper()))
    {
        return -2;
    }
    return 0;
}

供参考...
雪    币: 83
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
atrm 活跃值 2009-10-10 22:12
7
0
就是说返回0,什么注册码都可以
雪    币: 290
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
芳草碧连 活跃值 2009-10-10 23:10
8
0
好久不见大侠……

先学习

我说的那个 是我用软件反混淆后的方法名
雪    币: 290
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
芳草碧连 活跃值 2009-10-10 23:14
9
0
按照5楼tankaiha大侠的代码 貌似是这样……返回0就注册成功了
雪    币: 290
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
芳草碧连 活跃值 2009-10-10 23:31
10
0
貌似算法已经出来了
strArray数组就是保存的各框中的机器码 A_1_2就是我们输入的假码
下面就是一堆转换……
明天上机调试下^_

多谢tankaiha
雪    币: 26
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
zlws 活跃值 2009-10-11 09:17
11
0
我编译试了试,生成的注册码貌似不能注册成功
   
char ch = strArray[0][2];
    ch = strArray[3][0];

每次都是连续两次给字符 ch 赋值,那第一次赋值岂不是没意义了?

strArry一维数组中保存的是机器码的4个部分,strArray[0][2]是指第一部分的第三个字符?
雪    币: 290
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
芳草碧连 活跃值 2009-10-11 11:57
12
0
ldc.i4.s   0
ret

直接让它返回0,爆破成功

算法好像不太对劲,算出的号注册不成功
雪    币: 86
活跃值: 活跃值 (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
tease 活跃值 2009-10-12 14:59
13
0
最近生病进了三次医院,好久没来,看到这贴连Tankaiha大牛都来了。真是够火啊。
我也来凑热闹。
雪    币: 83
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
atrm 活跃值 2009-10-12 15:34
14
0
@tease
大师保重,不要加班了,身体重要
雪    币: 86
活跃值: 活跃值 (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
tease 活跃值 2009-10-12 15:42
15
0
唉,别提了,我这个病就是由于精神压力过大引起的,并有抑郁症的迹象,这下是真的郁闷了。
雪    币: 83
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
atrm 活跃值 2009-10-12 15:53
16
0
和女朋友去旅游一下吧,工作是做不完的,祝你身体健康
雪    币: 312
活跃值: 活跃值 (29)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
grassdrago 活跃值 3 2009-10-12 17:25
17
0
这么多牛人啊?
跟着混,别见笑.对了,tease好!版主好!

class g 为验证及注册表中注册码判断类.
class f.a()为[STAThread]
class b为注册窗口
class h 为主功能窗口.
混淆方式为switch还带嵌套,晕

f.a()大致如下:(没完全反混淆了,但能看明白了)
[STAThread]
private static void a()
{
    // This item is obfuscated and can not be translated.
    b b;
    bool flag;
    //Application.Run(new h());//爆
    //return;//爆
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    g g = new g();
    string str = "";
    string str2 = "";
    string str3 = "";
    int num = 0x1b;
Label_003B:
    switch (num)
    {
        case 1:
        case 4:
            Application.Run(new h());
            num = 2;
            goto Label_003B;

        case 2:
        case 11:
        case 0x25:
        case 0x27:
            return;

        case 3:
            flag = !g.e("MaplotusSerials");
            num = 0;
            goto Label_003B;

        case 5:
            break;

        case 6:
            flag = !(str2 == str3);
            num = 0x1c;
            goto Label_003B;

        case 7:
            MessageBox.Show("未注册,只可访问20个博客!", "提示");
            num = 0x1a;
            goto Label_003B;

        case 8:
            flag = b.b() != -10;
            num = 0x12;
            goto Label_003B;

        case 9:
            num = 40;
            goto Label_003B;

        case 10:
        case 0x24:
            num = 4;
            goto Label_003B;

        case 12:
            b = new b();
            b.Text = "用户注册";
            b.ShowDialog();
            flag = b.b() == 0;
            num = 0x11;
            goto Label_003B;

        case 13:
            if (1 != 0)
            {
            }
            goto Label_023E;

        case 14:
            MessageBox.Show("未注册,只可访问20个博客!", "提示");
            num = 0x10;
            goto Label_003B;

        case 15:
            flag = b.b() != -10;
            num = 0x15;
            goto Label_003B;

        case 0x10:
            num = 13;
            goto Label_003B;

        case 0x11:
            if (flag)
            {
                goto Label_02AE;
            }
            num = 0x23;
            goto Label_003B;

        case 0x12:
            if (flag)
            {
                num = 0x25;
            }
            else
            {
                num = 14;
            }
            goto Label_003B;

        case 0x13:
            goto Label_0164;

        case 20:
            goto Label_02E6;

        case 0x15:
            if (!flag)
            {
                num = 7;
            }
            else
            {
                num = 11;
            }
            goto Label_003B;

        case 0x16:
            goto Label_0192;

        case 0x17:
            if (str.Length == 8)
            {
                num = 9;
                goto Label_003B;
            }
            goto Label_0338;

        case 0x18:
            if (flag)
            {
                goto Label_02E6;
            }
            num = 15;
            goto Label_003B;

        case 0x19:
            str = g.c(Encoding.Default.GetString(g.d("MaplotusKeys")));
            str2 = g.b().ToUpper();
            str3 = g.a(Encoding.Default.GetString(g.d("MaplotusSerials"))).Replace("-", "").ToUpper();
            num = 0x17;
            goto Label_003B;

        case 0x1a:
            num = 20;
            goto Label_003B;

        case 0x1b:
            if (!g.e("MaplotusKeys"))
            {
                num = 0x13;
            }
            else
            {
                num = 0x1d;
            }
            goto Label_003B;

        case 0x1c:
            if (flag)
            {
                b = new b();
                b.Text = "用户注册";
                b.ShowDialog();
                flag = b.b() == 0;
                num = 0x18;
            }
            else
            {
                num = 0x20;
            }
            goto Label_003B;

        case 0x1d:
            num = 3;
            goto Label_003B;

        case 30:
            if (flag)
            {
                goto Label_023E;
            }
            num = 8;
            goto Label_003B;

        case 0x1f:
            goto Label_02AE;

        case 0x20:
            str2 = str2.Insert(8, "-").Insert(0x11, "-").Insert(0x1a, "-");
            flag = g.a(str2.ToUpper(), str.ToUpper()) == 0;
            num = 0x29;
            goto Label_003B;

        case 0x21:
            if (!flag)
            {
                num = 0x22;
            }
            else
            {
                num = 0x27;
            }
            goto Label_003B;

        case 0x22:
            MessageBox.Show("未注册,只可访问20个博客!", "提示");
            num = 0x2a;
            goto Label_003B;

        case 0x23:
            flag = b.b() != -10;
            num = 0x21;
            goto Label_003B;

        case 0x26:
            num = 6;
            goto Label_003B;

        case 40:
            if (str2.Length != 0x20)
            {
                goto Label_0338;
            }
            num = 0x26;
            goto Label_003B;

        case 0x29:
            if (flag)
            {
                break;
            }
            num = 12;
            goto Label_003B;

        case 0x2a:
            num = 0x1f;
            goto Label_003B;

        default:
            if (!flag)
            {
                num = 0x19;
            }
            else
            {
                b = new b();
                b.Text = "用户注册";
                b.ShowDialog();
                flag = b.b() == 0;
                num = 30;
            }
            goto Label_003B;
    }
    num = 0x24;
    goto Label_003B;
Label_023E:
    num = 1;
    goto Label_003B;
Label_02AE:
    num = 5;
    goto Label_003B;
Label_02E6:
    num = 10;
    goto Label_003B;
Label_0338:
    num = 0x16;
    goto Label_003B;
}

这个软件从f.a()爆破,并没发现有什么限制:

L_0000: newobj instance void h::.ctor()
    L_0005: call void [System.Windows.Forms]System.Windows.Forms.Application::Run(class [System.Windows.Forms]System.Windows.Forms.Form)
    L_000a: nop
    L_000b: ret

除了g.c(string):string很麻烦外,其它g类方法还是可以转过来的.有兴趣的朋友可以试一下反g.c(string):string.
它的第二层switch得动态算,没去碰它了.
雪    币: 290
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
芳草碧连 活跃值 2009-10-12 18:29
18
0
额 保重身体喔 tease大哥

算法部分直接用了原程序的IL代码?这样也行

看了Tankaiha的分析代码,我自己也调试了下,但算出的注册码不行 不知为何……

看了下你的keygen,GetKey这个函数是把public int a(string A_0_1, string A_1_2)里的相关代码直接复制过去就OK?

PS:我的笔记本才60G硬盘 装个vs2005都捉襟见肘(还是没装……)
雪    币: 86
活跃值: 活跃值 (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
tease 活跃值 2009-10-12 20:55
19
0
复制当然要复制,关键要看怎么复制。完全复制是肯定不行的。
代码还是稍微修改了一点点,没看见函数的返回值改成String了么。你可以自己对比一下我的KeyGen和原程序的IL代码。

Tankaiha老大自己已经说了那并不是完全的反编译结果,他的目的是为了便于大家分析算法,而不是让你抄那些代码就能算出来结果的。或多或少还是要自己分析并修改一下的。我就是在他的基础上分析的。
雪    币: 5002
活跃值: 活跃值 (182)
能力值: (RANK:1170 )
在线值:
发帖
回帖
粉丝
tankaiha 活跃值 29 2009-10-12 21:35
20
0
建议tease搞个反混淆工具出来
雪    币: 86
活跃值: 活跃值 (11)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
tease 活跃值 2009-10-12 23:38
21
0
我正在看老大您的开源代码,可是貌似我的功力还不够啊。惭愧,惭愧 等我修炼一些内功后,再来看看能不能写出来。

我在脱每个方法保护强度的壳的实战中经常遇到问题。例如,在《微软.NET程序的加密解密》一书的第226页,注入到进程后,通过反射枚举调用每一个方法,解密后dump,那么这里的是不是意味着此时可以用Netunpack软件来dump,还是用Task Explorer来dump。

在对付Intellilock加的程序时候,我dump后的文件和原文件对比发现少了好多东西,有些地方不能改,根本就不知道怎么修复。老大能不能指点一二。

老大支持你再多写一些精华文章阿,现在DONET加密越来越强大了,没有你的指引,我无法跟上时代阿。
雪    币: 290
活跃值: 活跃值 (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
芳草碧连 活跃值 2009-10-14 22:53
22
0
等组长来解决
雪    币: 225
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
hezhichun 活跃值 2009-10-15 13:21
23
0
没看到下载点啊,我也玩玩
雪    币: 214
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
claudedb 活跃值 1 2009-10-20 10:10
24
0
似乎这种工作量比较大
呵呵
我自己也弄过一个
不过是IL文本纯分析的
规则太多,很麻烦
总达不到好效果

前阵子破的一个控件
居然是用switch代替goto做跳转判断
折腾死人

还是发现手工分析的好处,呵呵
游客
登录 | 注册 方可回帖
返回