在
Zend\Zend Studio - 7.0.0\plugins\com.zend.php.ui_7.0.0.v20090614-1641\com\zend\php\ui\actions从目录看,应该是eclipse的图形化界面的shell接口操作
上一级目录中,有 PHPUIMessages.properties
其中发现有
RegisterAction.3=You will need to restart the workbench for the changes to take effect.\nRestart now? SerialNumberDialog.5=The entered license key is invalid
等字样
使用jd-gui查看RegisterAction.class的代码
发现有
import com.zend.php.core.core.basic.c; import com.zend.php.core.core.basic.d;
导入了两个class文件,这两个文件在一个jar中,直接解压
public void run(IAction paramIAction)中
c localc = c.a(localr.a(), localr.b());这个c就是import进来的basic.c
往下看
if (localc == null) { MessageDialog.openError(this.a.getShell(), PHPUIMessages.a("RegisterAction.4"), PHPUIMessages.a("RegisterAction.0")); return; } try { d.b(localc); if (!(MessageDialog.openQuestion(this.a.getShell(), PHPUIMessages.a("RegisterAction.6"), PHPUIMessages.a("RegisterAction.3")))) return; PlatformUI.getWorkbench().restart(); }查查刚才的PHPUIMessages.properties
确认了一个事实:
可以猜测 localr.a() 和 localr.b() 取出的分别是 username 和 password
那么,首先用 c.a(a, b)进行计算,如果返回不为空,则进行 d.b(c) 的过程
根据返回值确定结果
PHPUIMessages.a()这个函数的参数,对应的那个 properties 文件的内容看,这个推断应该没错
好吧,首先看看 com.zend.php.core.core.basic.c
Zend\Zend Studio - 7.0.0\plugins\com.zend.php.core_7.0.0.v20090607-1658\com\zend\php\core\core\basic用jd-gui打开 c.class
根据重载参数,找到
public static c a(String paramString1, String paramString2) { c localc = null; try { if (localc != null) break label34; int k = Integer.parseInt(paramString2.substring(0, 1), 16); localc = f.a(k).a(paramString1, paramString2); } catch (Exception localException) { } label34: return localc; }
其中,f 是 com.zend.php.core.core.basic.parser.f
打开 Zend\Zend Studio - 7.0.0\plugins\com.zend.php.core_7.0.0.v20090607-1658\com\zend\php\core\core\basic\parser
再看参数
public static b a(int paramInt) { if (3 == paramInt) return new e(); throw new IllegalStateException("Unknown license version"); }也就是说,paramInt必须为3
那么回到前边的代码
localc = f.a(k).a(paramString1, paramString2);k必须为3,这样就会返回一个 e();
于是,Integer.parseInt(paramString2.substring(0, 1), 16) == 3 ………………………………………………………………………………………… p2 第一个字符为3
进入 com.zend.php.core.core.basic.parser.e
看参数和返回值(localc = f.a(k).a(paramString1, paramString2);):
public c a(String paramString1, String paramString2)
这个代码:
int i = Integer.parseInt(paramString2.substring(0, 1), 16); if (i != 3) return null;再次验证了 p2[0] == 3的事实
String str1 = paramString2.substring(1, 3);取出p2 的 [1] [2] 两个字符
String str2 = a(paramString2.substring(3, 16), str1 + paramString2.substring(16));返回值是 String,看函数
private static String a(String paramString1, String paramString2)其中是一个循环
算法的php实现是:
<?php function a($p1, $p2) { $s = ''; $i = 0; do { $j = 0; do { $s .= dechex( hexdec($p1[$i+$j]) ^ hexdec($p2[$j]) ); } while ($j < strlen($p2) && $i+$j < strlen($p1)); $i += strlen($p2); } while( $i < strlen($p1) ); return $s; } ?>根据这个16进制串的返回值,继续往后走,回到刚才的 a()
int j = Integer.parseInt(str2.substring(0, 1), 16); int k = Integer.parseInt(str2.substring(1, 2), 16);j 为 上一个返回 str2 的 [0], k 为 [1],两个都是10进制整数。
int l = Integer.parseInt(str2.substring(2, 4), 16); int i1 = Integer.parseInt(str2.substring(4, 5), 16); int i2 = Integer.parseInt(str2.substring(5, 7), 16);又是三个整数变量 然后根据前边定义的
Date localDate = null;判断:
if ((l != 0) || (i1 != 0) || (i2 != 0)) { Calendar localCalendar = GregorianCalendar.getInstance(); localCalendar.set(5, l); localCalendar.set(2, i1 - 1); localCalendar.set(1, 2000 + i2); localDate = localCalendar.getTime(); }//……………………………………………………………………………………………………………………代码求解释
int i3 = Integer.parseInt(str2.substring(7, 9), 16); long l1 = Long.parseLong(str2.substring(9, 13), 16); long l2 = a(paramString1, i, str1, j, k, localDate, i3, l1).longValue(); long l3 = Long.parseLong(paramString2.substring(16), 16);又是对 str2的运算 其中,又将刚才算出来的localDate代入到另外一个a里边
private static Long a(String paramString1, int paramInt1, String paramString2, int paramInt2, int paramInt3, Date paramDate, int paramInt4, long paramLong)这个函数里边主要做了一些字符串的合并,和时间数据的字符串化(ddMMyy),猜测可能是与expiration有关 补了00000在串后 而后加了一个crc32的计算校验 这个函数的返回值就是 那个 crc32的long值 而其中的那个00000的补全就不知道有何意义了………………莫非函数引用传值? 再次回到最初的a()
if (l3 != l2) break label403;也就是说,l3 == l2 下边又是一个循环
do { if ((()Math.pow(2.0D, i4) & l1) != 0L) { int i5 = 0; if (bool); do { localArrayList.add(d[i4][i5].getId()); ++i5; } while (i5 < d[i4].length); } ++i4; } while (i4 < d.length);这里的 localArrayList 在循环结束后
return new c(i, paramString1, j, k, localDate, i3, (String[])localArrayList.toArray(new String[localArrayList.size()]));送进构造另外一个对象 这个c是 com.zend.php.core.core.basic.c ======================================================================================== 跳出加密验证部分 回到对话框界面的数据获取 还是 RegisterAction.class
r localr = new r(this.a.getShell()); if (localr.open() == 1) return; c localc = c.a(localr.a(), localr.b());看看 r这个类的东西 package com.zend.php.ui.core.dialogs; 看看两个参数的获取:
public String a() { return this.j.getText().trim(); } public String b() { return this.k.getText().trim(); }i和j的定义在:
this.j = new StringDialogField(); this.j.setLabelText(PHPUIMessages.a("SerialNumberDialog.1")); this.j.setDialogFieldListener(new i(this)); this.j.doFillIntoGrid(localComposite, 2); LayoutUtil.setHorizontalGrabbing(this.j.getTextControl(null)); this.j.setFocus(); this.k = new StringDialogField(); this.k.setLabelText(PHPUIMessages.a("SerialNumberDialog.2")); this.k.setDialogFieldListener(new j(this)); this.k.doFillIntoGrid(localComposite, 2); LayoutUtil.setHorizontalGrabbing(this.k.getTextControl(null));对应的串:
SerialNumberDialog.1=User Name / Order #: SerialNumberDialog.2=License Key:断定数据肯定是在这儿了 但是刚才看了看6版的注册机,license首字节不是限制在1,2,-1之间(虽然6.1代码里只有这三个判断数据) 所以,我觉得这里肯定会有一些数据的预处理过程 继续找
Zend\Zend Studio - 7.0.0\plugins\com.zend.php.ui_7.0.0.v20090614-1641\com\zend\php\ui\core\dialogs r.class i.class现在先尝试按照ui的流程将验证过程实现
然后再做keygen
但是有些初始值怎么定还是个问题
No comments:
Post a Comment