[Android]开发式注册算法(反编译,dex2jar,算法还原)
文章转载于:http://www.52pojie.cn/thread-282153-1-1.html
大家如果有兴趣,可以自己拿来练练手,编译,还原算法,写注册机。
这个软件集合了反编译,dex2jar,算法还原等几个很值得研究的地方。
本篇只限于探讨算法还原,不涉及第三方反编译和dex转jar的讨论,谢谢
老规矩,反编译进入smali,找到判别注册与否的函数isreg()
.method public staticisReg(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z
.locals 27
.param p0, “arg0” #Ljava/lang/String; //邮箱(大写)
.param p1, “arg1” #Ljava/lang/String; //手机imei最后8位
.param p2, “arg2” #Ljava/lang/String; //输入的注册码注册码
.prologue
.line 451
const-string v23, “”
move-object/from16 v0, v23
move-object/from16 v1, p0
invoke-virtual {v0, v1},Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v23
if-nez v23, :cond_0
if-nez p0, :cond_1
.line452
:cond_0
const/16 v23, 0x0
.line 492
:goto_0
return v23 //判别邮箱是否为空,如果是则返回false
文章内容IIS文字限制,剩下的请下载文本查看下载地址:点击下载
看了头晕吧?肯定头晕,现在把片段再整理下,整理的好一些:
Java代码整段还原如下:
public static boolean isReg(String paramString1, String paramString2,String paramString3)
{
if ((“”.equals(paramString1)) || (paramString1 == null))
return false; //判别邮箱是否为空
if ((“”.equals(paramString2)) || (paramString2 == null))
return false; //判别机器码是否为空
if ((“”.equals(paramString3)) || (paramString3 == null))
return false; //判别注册码是否为空
try
{
int i = paramString3.length(); //i=注册码长度
int j = Integer.parseInt(paramString3.substring(0, 1));//j=注册码首位
int k = Integer.parseInt(paramString3.substring(i – 1));//k=注册码末位
String str1 = paramString3.substring(0, j + 1);//str1=注册码第一位到第j+1位
String str2 = paramString3.substring(j + 1, i – 1);//str2=注册码第j+2位到第i-1位
long l1 = Long.parseLong(str2.substring(0, k)+ str2.substring(k + 1), 16);
int m = Integer.parseInt(str2.substring(k, k + 1));//m=str2第k+1位
long l2 = System.currentTimeMillis();
String str3 = MD5(paramString1 + “0o” + m);//str3=邮箱地址+0o+m字符串MD5加密
String str4 = MD5(paramString2 + “0o” + m); //str4=机器码+0o+m字符串MD5加密
String str5 = j + str3.substring(k, j + k);//str5=注册码首位字符+str3第K+1位到j+k位
String str6 = j + str4.substring(k, j + k); //str6=注册码首位字符+str3第K+1位到j+k位
if (!str5.equals(str1)) //判别:如果str1=str5 注册成功(邮箱)
{
boolean bool = str6.equals(str1); //判别:如果str1=str6 注册成功(机器码)
if (!bool);
}
else
{
if (m == 9)
return true;
if (m == 0)
m = 12;
long l3 = l2 – l1;
long l4 = 2592000000L * m;
if ((l3 > 0L) && (l3 < l4))
return true;
}
}
catch (Exception localException)
{
localException.printStackTrace();
}
return false;
}
看完上面的内容你是不是万念聚灰了?注册码本身居然也作为一个运算参数参与了注册码的计算,而且是MD5运算。
再简化一下吧:
注册码=注册码第一位+MD5(邮箱/机器码+”0o”+(注册码第j+2位到第i-1位字符的第k+1位))的第K+1位到j+k位
所以说,这是一个开放性的注册码,一个邮箱或者机器码能有很多个注册码。
但是,如果我们限定住一个或者两个条件。
因为j和k这两个最主要的参数是注册码的第一位和最后一位。
那么,注册码的判别就没有那么复杂了。
为了让注册码看起来不那么容易被拆解分析,我先将j和k设定成一个固定的数值。
写出来的注册机有时候运算一个注册码也是需要1-3分钟时间。
不过好歹还是可以用了。
PS:我用vb完全按JAVA还原出来的算法写的注册机,跑了8小时没跑出一个能用的注册码来。更囧。
我已经把算法的源码给还原出来了,至于大家用什么方式自己去写注册机啥的,
就看大家自己了,我只会用vb6.0
此软件有后门,会泄露信息,莫用!!
用这个软件发布这篇文章,探讨开放性注册算法罢了。