首页
社区
课程
招聘
[原创]纯手工Divbrush-V1.8算号器及Java程序拆解过程
发表于: 2013-7-13 18:49 10833

[原创]纯手工Divbrush-V1.8算号器及Java程序拆解过程

2013-7-13 18:49
10833

今日写成Divbrush_v1.8的算号器,算是(部分)完美破解,因为机器码还不能通过程序直接计算出来。
下面是算号器效果图:
            
上图中的机器码是Divbrush软件中注册对话框上显示的机器码,使用该算号器时要填写这个机器码(本程序美中不足的地方)。
Divbrush软件的注册界面如下:
            

下面简单讲一下该软件的拆解过程

    1. 准备工具
    必备工具:jd-gui(因为关键程序是java程序)
    其他工具:PeID, ProtectionID, Spy++(不是必需)

    2. 检查程序
    用PeID和ProtectionId检查该程序都说本程序是MinGW编译的(?),但是用Spy++查看界面时看到是“SunAwtFrame”,所以断定该程序是java程序。
    所以这个时候就不要管exe主程序了,要找它的.jar包(即java可执行程序)!在相同目录下找到“dist”,然后找到out.jar。

    3. 反编译java程序包out.jar
    用jd-gui打开out.jar,在Main目录下找到RegJDialog,单击一下,在右侧会显示RegJDialog包的源程序。往下一翻就会看到“正式个人版”……字符串,这里就是判断验证码的关键代码。
    继续往下翻,找到真正有用的函数:private void jdMethod_if(ActionEvent paramActionEvent)。通过阅读这段函数知道这个函数就是注册对话框上的验证逻辑。
    后面就是顺藤摸瓜,把Divbrush程序的验证逻辑还原回来。

    4. 还原验证逻辑
    仔细研究刚才提到的函数:private void jdMethod_if(ActionEvent paramActionEvent),其中有这两句:

String str = this.txtNum1.getText() + this.txtNum2.getText() + this.txtNum3.getText() + this.txtNum4.getText();
if (this.serialNumber.a().equals(str))
{
    this.registerCompare.jdMethod_try();
    jdMethod_if();
}

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 5
支持
分享
最新回复 (3)
雪    币: 437
活跃值: (78)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
谢谢楼主分享
2013-7-15 11:41
0
雪    币: 237
活跃值: (160)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
3
1、看了下,机器码应该是从这里传来的:jdMethod_if(); 分析下这个内容
2、注册是机器码加 yolan 字符串再MD5的吧?
        MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
        localMessageDigest.update((str1 + "yolan").getBytes("UTF-8"));
        byte[] arrayOfByte = localMessageDigest.digest();

另一个问题,按LZ说的:然后把MD5中的字符做个一个很明确的替换,最后取字符串的前20位。
像:str2 = str2.replace('@', 'G'); 是把@换成G,但MD5里不可能有@的吧...

以上说法如有错误,敬请指正。
2013-7-17 12:21
0
雪    币: 95
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
[QUOTE='XF[BCG];1199755']1、看了下,机器码应该是从这里传来的:jdMethod_if(); 分析下这个内容
2、注册是机器码加 yolan 字符串再MD5的吧?
        MessageDigest localMessageDigest = MessageDigest.getInstance("MD5&...[/QUOTE]

非常荣幸得到您的批评指正

前面两点说的都非常正确:
1. 机器码确实是由 jdMethod_if(); 算出来的,它的实现是这样:
  
public String jdMethod_if()
  {
    DiskID localDiskID = new DiskID();
    return DiskID.DiskID().toUpperCase();
  }

其中DiskID这个类是在一个单独的DLL里面的,由于Divbrush程序是java做的,用C重写一遍会比较麻烦,所以我就偷懒了。
2. 第二条说的很对
3. 关于我说的“一个很明确的替换”也是偷懒了,其实字符串替换有两个地方,除了前面代码中显示出来的,还有一个是这一句:
      MessageDigest localMessageDigest = MessageDigest.getInstance("MD5");
      localMessageDigest.update((str1 + "yolan").getBytes("UTF-8"));
      byte[] arrayOfByte = localMessageDigest.digest();
[B]      k localk = new k();
      String str2 = localk.a(arrayOfByte);[/B]
      str2 = str2.toUpperCase();

    k这个类就是做字符串替换的:
public class k
{
  private static char[] a = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' };

  public String a(byte[] paramArrayOfByte)
  {
    int i = paramArrayOfByte.length * 8;
    int j = i % 6;
    int k = 0;
    StringBuffer localStringBuffer = new StringBuffer();
    while (k < i)
    {
      int m = k / 8;
      int n;
      switch (k % 8)
      {
      case 0:
        localStringBuffer.append(a[((paramArrayOfByte[m] & 0xFC) >> 2)]);
        break;
      case 2:
        localStringBuffer.append(a[(paramArrayOfByte[m] & 0x3F)]);
        break;
      case 4:
        if (m == paramArrayOfByte.length - 1)
        {
          localStringBuffer.append(a[((paramArrayOfByte[m] & 0xF) << 2 & 0x3F)]);
        }
        else
        {
          n = ((paramArrayOfByte[m] & 0xF) << 2 | (paramArrayOfByte[(m + 1)] & 0xC0) >> 6) & 0x3F;
          localStringBuffer.append(a[n]);
        }
        break;
      case 6:
        if (m == paramArrayOfByte.length - 1)
        {
          localStringBuffer.append(a[((paramArrayOfByte[m] & 0x3) << 4 & 0x3F)]);
        }
        else
        {
          n = ((paramArrayOfByte[m] & 0x3) << 4 | (paramArrayOfByte[(m + 1)] & 0xF0) >> 4) & 0x3F;
          localStringBuffer.append(a[n]);
        }
        break;
      case 1:
      case 3:
      case 5:
      }
      k += 6;
    }
    if (j == 2)
      localStringBuffer.append("==");
    else if (j == 4)
      localStringBuffer.append("=");
    return localStringBuffer.toString();
  }
}
2013-7-17 21:40
0
游客
登录 | 注册 方可回帖
返回
//