偷梁换柱之计算机二级C语言掌上通注册机编写教程
今天在逛安智的时候看到一个软件,我对注册码验证的程序比较感兴趣哈,- -{:17_1062:}那个帖子的软件是通过爆破法实现破解的,之前我在这个帖子讲过http://www.52pojie.cn/thread-376802-1-1.html爆破法虽然直截了当,不过不利于之后的升级,那我们有没有更好的方法来干掉这个软件,方法当然是有的,也就是我们今天的主题。
原软件地址:http://www.eoemarket.com/soft/232473.html
0x1 爆破软件观察注册机制
打开软件,找到注册处,点击获取按钮后有几种支付模式,我当然是选择最熟悉的支付宝模式
我们直接爆破支付,搜索关键词 9000 的十六进制,即0x2328,找到
在方法开始处添加一行,
回编译,打开支付宝后直接返回上一级,提示支付成功,注册码也出来了,很明显的md5加密模式
0x2 寻找加密算法
我们搜索toast提示的文本信息,注意是unicode编码,找到关键点,打开java代码,
很明显的看到,注册码是调用了cc类的b方法,并将k方法的数据传入,我们点开k方法
不难发现,该方法通过调用系统设备信息,获取到设备号后在数据前添加“L”,在末尾添加了“8H6”,返回该值,传入到cc类的b方法中,我们点开cc类,我擦
此处被作者混淆了,jd-gui无法识别,那我们就无法进行下一步了吗,答案当然是否定的,这也是本主题重点,投机取巧偷取加密算法
0x3 编写“假”注册机
打开eclipse,新建一个Android项目,包名最好和原软件相似,方便修改
其它一切默认即可,
我们在包下新建一个cc类,写上一个方法,定义一个全局的String方法,直接返回即可,不添加任何代码
在方法中将该软件获取设备号的方法写入,然后在Oncreate方法中进行调用,并显示在textview上,需要注意的是,我们需要在AndroidManifest文件中添加一个读取设备信息的权限,不然软件是无法获取的
好了,“假”注册机已经编写好了,我们直接导出为apk文件,这个注册机是什么用都没有的,但截下来我们把它变成真的注册机
0x4 偷梁换柱之真注册机
我们找到导出的apk文件,用改之理反编译,然后将二级考试原软件的cc类复制到我们的反编译工程中替换我们编写的cc类,需要注意的是,我们在最上方需要将包名修改为我们自己设置的包名,保存,回编译
运行软件,看到了吗
我们将这段数据复制到软件的注册框中,
大功告成。。
淡然出尘 发表于 2015-6-25 00:20
这个方法大赞啊
再遇到Jd-Jui反编译不了的 你可以试试Jeb呀;
小白哪会用那些高大上的东西 本帖最后由 taintitly 于 2015-7-11 12:32 编辑
.method public static b(Ljava/lang/String;)Ljava/lang/String;
.locals 5
:try_start_0
const-string v0, "MD5" //加密模式为MD5
invoke-static {v0}, Ljava/security/MessageDigest;->getInstance(Ljava/lang/String;)Ljava/security/MessageDigest;
move-result-object v0
new-instance v1, Ljava/lang/StringBuilder;
const-string v2, "niatxqh"
invoke-direct {v1, v2}, Ljava/lang/StringBuilder;-><init>(Ljava/lang/String;)V
invoke-virtual {v1, p0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1 //在Lxxxxxxxxxxx8H6 在这段字符前加入"niatxqh"字符串,变成"niatxqhLxxxxxxxxxxx8H6"形式
const-string v2, "c2exam86"
invoke-virtual {v1, v2}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v1 //在“niatxqhLxxxxxxxxxxx8H6” 在这段字符后加入"c2exam86"字符串,变成"niatxqhLxxxxxxxxxxx8H6c2exam86"形式
invoke-virtual {v1}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v1
invoke-virtual {v1}, Ljava/lang/String;->getBytes()[B
move-result-object v1
invoke-virtual {v0, v1}, Ljava/security/MessageDigest;->update([B)V
invoke-virtual {v0}, Ljava/security/MessageDigest;->digest()[B
move-result-object v2
new-instance v3, Ljava/lang/StringBuffer;//对字符串进行MD5加密,整个加密后的字符串大写压入v3中
const-string v0, ""
invoke-direct {v3, v0}, Ljava/lang/StringBuffer;-><init>(Ljava/lang/String;)V
const/4 v0, 0x0
move v1, v0
:goto_0
array-length v0, v2
if-lt v1, v0, :cond_0
invoke-virtual {v3}, Ljava/lang/StringBuffer;->toString()Ljava/lang/String;
move-result-object v0
const/4 v1, 0x4 // 取加密字符串的第5位作为开始
const/16 v2, 0x18 // 取加密字符串的第24位作为结束
invoke-virtual {v0, v1, v2}, Ljava/lang/String;->substring(II)Ljava/lang/String;
move-result-object v0
invoke-virtual {v0}, Ljava/lang/String;->toUpperCase()Ljava/lang/String;
move-result-object v0
return-object v0 //将20位注册码返回
==================================================================
这个软件的注册算法很简单:
MD5加密"niatxqhL"+IMEI+"8H6c2exam86"组成的字符串
然后取第5位-24位的20个大写字符作为注册码
完了....
==================================================================
将上述smali代码(部分)还原了一下:
public static string b(string s)
{
int i;
int j;
object obj;
try
{
obj = messagedigest.getInstance("MD5");
((messagedigest) (obj)).update((new StringBuilder("niatxqh")).append(s).append("c2exam86").toString().getBytes());
s = ((messagedigest) (obj)).digest();
obj = new stringbuffer("");
}
catch(string s)
i = 0;
if(i >= s.length)
return ((stringbuffer) (obj)).toString().substring(4, 24).toUpperCase(); }
@Hmily @淡然出尘 {:17_1067:}好不容易写一篇,过来骗分了 好贴,,学习了。。这方法真心管用 。 很好 啊 我的距离还很遥远 本帖最后由 cz5420 于 2015-6-24 18:56 编辑
繁华大神,虎奔等考破一下呗http://www.52pojie.cn/thread-376805-1-1.html
我禁止IMEI真的能用,不过还是期待破解爱加密的~ 不错啊,支持楼主 支持下!谢谢分享!!! 世事繁华皆成空 发表于 2015-6-24 18:40
@Hmily @淡然出尘 好不容易写一篇,过来骗分了
我准备给你加 -15分 谢谢你的分享! 大神 厉害~~