本帖最后由 淡然出尘 于 2015-2-3 18:43 编辑
我读书少,大家不要骗我,看看就好。求大牛轻虐。
http://www.52pojie.cn/thread-232658-1-1.html crackme 包在这个帖子里有
首先解压apk得到dex,再用dex2jar转成jar.用jd-gui.exe打开jar.查看算法:
private boolean checkSN(StringparamString1, String paramString2)//用户名,输入的注册码 { if (paramString1 != null) try { if (paramString1.length() == 0) return false; //如果用户名长度为0,返回false if ((paramString2 != null) && (paramString2.length() == 16))//如果注册码不为空,且长度为16则进行下一步 { MessageDigest localMessageDigest =MessageDigest.getInstance("MD5");//MD5加密 localMessageDigest.reset(); localMessageDigest.update(paramString1.getBytes()); String str = toHexString(localMessageDigest.digest(), "");//字符串处理 StringBuilder localStringBuilder = new StringBuilder(); for (int i = 0; ; i += 2)//此函数作用是取32位MD5中的16单数字符组成注册码 { if (i >= str.length()) { if(!localStringBuilder.toString().equalsIgnoreCase(paramString2)) break; return true; } localStringBuilder.append(str.charAt(i)); } } } catch (NoSuchAlgorithmException localNoSuchAlgorithmException) { localNoSuchAlgorithmException.printStackTrace(); } return false; }
private static String toHexString(byte[] paramArrayOfByte, StringparamString) { StringBuilder localStringBuilder = new StringBuilder(); int i = paramArrayOfByte.length; for (int j = 0; ; j++) { if (j >= i) return localStringBuilder.toString(); String str = Integer.toHexString(0xFF & paramArrayOfByte[j]); if (str.length() == 1) localStringBuilder.append('0'); localStringBuilder.append(str).append(paramString); } }
利用vb6.0还原算法: Private Sub Command1_Click() Dim pin As String Dim key As String Dim i As Integer pin = Text1.Text pin = DigestStrToHexStr(pin) For i = 1 To 32 Step 2 key = key + Mid(pin, i, 1) Next i Text2.Text = key End Sub
注册机效果:
=====================================================================================
Crackme03 还原出来的代码如下 public void onClick(ViewparamAnonymousView) { String str1 =((EditText)HelloAndroid.this.findViewById(2131034116)).getText().toString(); int i = str1.length();//输入的用户名长度 String str2 = ""; String str3 =((EditText)HelloAndroid.this.findViewById(2131034118)).getText().toString(); if (i < 4);//判别输入的注册码是否小于4 while (true) { try { Toast.makeText(HelloAndroid.this.getApplicationContext(), "Min 4chars", 1).show(); return; int k = str1.length(); if (j >= k) { String str4 = String.valueOf(0x6B016 ^Integer.parseInt(str2.substring(0, 5)));//用户名ascii码前五位数和16进制数6b016做xor运算 TelephonyManager localTelephonyManager = (TelephonyManager)HelloAndroid.this.getSystemService("phone"); String str5 = localTelephonyManager.getDeviceId(); String str6 = localTelephonyManager.getSimSerialNumber(); String str7 = str5.substring(0, 6);//hardid01第1到第6位 String str8 = str6.substring(0, 6); //hardid02第1到第6位 long l = Integer.parseInt(str7) ^ Integer.parseInt(str8);//将hardid01与hardid02 xor运算 if (!(str4 + "-" + String.valueOf(l) + "-" +str7).equals(str3)) //判别注册码格式:str4-l-str7 break label285; Toast.makeText(HelloAndroid.this.getApplicationContext(), "Godboy", 1).show(); return; } } catch (Exception localException) { Toast.makeText(HelloAndroid.this.getApplicationContext(), "AnotherError Ocurred :(", 1).show(); return; } int m = str1.charAt(j); str2 = str2 + m; j++; continue; label285: Toast.makeText(HelloAndroid.this.getApplicationContext(),"Bad boy ", 1).show(); return; int j = 0; } }
VB源代码: Private SubCommand1_Click() Dim hid1 AsString Dim hid2 AsString Dim name AsString Dim namestr AsString Dim nnum AsDouble Dim num2 AsDouble Dim i As Integer hid1 =Mid(Text1.Text, 1, 6) hid2 =Mid(Text2.Text, 1, 6) name =Text3.Text num2 = Val(hid1)Xor Val(hid2) If Len(Text3.Text)< 4 Then Text4.Text ="Name长度最小为4" Else For i = 1 ToLen(name) namestr =namestr & Asc(Mid(name, i, 1)) Next i nnum =Val(Mid(namestr, 1, 5)) Xor 438294 Text4.Text =nnum & "-" & num2 & "-" & hid1 End If End Sub
===============================================================================
CrackMe-F1F2 public class LisenceCheck extends Activity { inta; private View.OnClickListener appButtonOnClickListener = newView.OnClickListener() { public void onClick(View paramAnonymousView) { if ((Button)paramAnonymousView == LisenceCheck.this.mbutton) { new String(""); String str1 = LisenceCheck.this.meditun.getText().toString(); new String(""); String str2 = LisenceCheck.this.meditsn.getText().toString(); int i = 0; int j = 0; label82: int m; int n; if (j >= str1.length())//如果用户名为空,则m=I xor0x5678 { m = i ^ 0x5678; n = 0; } for (int i1 = 0; ; i1++) { if (i1 >= str2.length()) { if (m != (n ^ 0x1234))//如果m=n xor 0x1234则注册成功 break label202; Toast.makeText(LisenceCheck.this.getApplicationContext(), "LisenceCorrect!", 0).show(); return; int k = str1.charAt(j); if (k < 65) break label82; if (k > 90) k = (char)(k - 32); i += k; j++; break; } n = (char)(str2.charAt(i1) - '0') + n * 10; } label202: Toast.makeText(LisenceCheck.this.getApplicationContext(),"Lisence Uncorrect!", 0).show(); return; } LisenceCheck.this.meditun.setText(""); LisenceCheck.this.meditsn.setText(""); } };
注册算法过于坑爹:经过分析,用户名留空,注册码为“17484”即可通过验证。 PS:17484=0x1234 xor 0x5678
F1、F2函数//F1函数部分,s1为输入的用户名
1 int i = 0,k1 = 0;;
2 char ch;
3 for (i = 0; i<s1.length();i++)
4 {
5 ch = s1.charAt(i);
6 if (ch < 'A') break;
7 if (ch > 'Z') ch -= 32;
8 k1 = k1 + ch;
9 }
10 k1 = k1 ^ 0x5678;
//F2函数部分,s2为输入的序列号
1 int k2 = 0;
2 for (i = 0;i < s2.length(); i++)
3 {
4 ch = s2.charAt(i);
5 ch –= 48;
6 k2 = k2 * 10 + ch;
7 }
8 k2 = k2 ^ 0x1234;
原apk就是这样,若k1==k2,那么验证成功,否则验证失败。 可以看出 F2函数的循环部分,仅仅是把序列号s2从字符串转换为整型,存于k2中,此处的k2我们成为k2[序列号]。最后做异或运算,从而得出密文,覆盖于k2中,此处的k2成为k2[密文]。在异或运算中,若存在 c = a xor b (对应到F2函数中的最后一步,即 k2[密文] = k2[序列号] xor 0x1234) 则a=c xor b (对应着k2[序列号] = k2[密文] xor 0x1234) 也就是说通过 密文 xor 0x1234 就能得到序列号 在F1函数的结果也就是密文。所以,注册机的写法也就出来了:把F1的结果 xor 0x1234就是对应用户名的正确的序列号。 注册机的核心代码
1 int i = 0;
2 int k3 = 0;
3 char ch;
4 for (i = 0; i < s1.length(); i++)
5 {
6 ch = s1.charAt(i);
7 if (ch < 'A') break;
8 if (ch > 'Z')
9 ch -= 32;
10 k3 = k3 + ch;
11 }
12 k3 = k3 ^ 0x5678 ^ 0x1234;
//s1为用户名,k3为根据s1算出来的正确的序列号,单独写一个注册机,然后通过注册机计算
================================================================================= 最后一个EX05_01_:
public void onCreate(Bundle paramBundle) { super.onCreate(paramBundle); setContentView(2130903040); this.mTextView01 = ((TextView)findViewById(2131034112)); this.mEditText01 = ((EditText)findViewById(2131034114)); this.mEditText01.setOnKeyListener(new View.OnKeyListener() { public boolean onKey(View paramAnonymousView, int paramAnonymousInt,KeyEvent paramAnonymousKeyEvent) { if ("gogo".equals("11"))////这个等式不可能成立….改 { EX05_01.this.mTextView01.setText("gogo"); Toast.makeText(EX05_01.this, "right++", 1).show(); } while (true) { Linkify.addLinks(EX05_01.this.mTextView01, 7); return false; EX05_01.this.mTextView01.setText("gogo"); Toast.makeText(EX05_01.this, "error--", 1).show(); } } }); }
!@#¥%……%@#¥!#¥%……¥#@!@#¥%……%……#@!#¥%……%& 改smali文件,把”11”改成”gogo”. 修改后的smali代码如下: .method publiconKey(Landroid/view/View;ILandroid/view/KeyEvent;)Z .locals 4 .param p1, "arg0" #Landroid/view/View; .param p2, "arg1" # I .param p3, "arg2" #Landroid/view/KeyEvent;
.prologue const/4 v3, 0x1
.line 28 const-string v0, "gogo"
.line 30 .local v0, "str":Ljava/lang/String; const-string v1, "gogo" //修改这里…
invoke-virtual {v0, v1},Ljava/lang/String;->equals(Ljava/lang/Object;)Z
move-result v1
if-eqz v1, :cond_0
.line 31 iget-object v1, p0,Lirdc/ex05_01/EX05_01$1;->this$0:Lirdc/ex05_01/EX05_01;
#getter for: Lirdc/ex05_01/EX05_01;->mTextView01:Landroid/widget/TextView; invoke-static {v1},Lirdc/ex05_01/EX05_01;->access$0(Lirdc/ex05_01/EX05_01;)Landroid/widget/TextView;
move-result-object v1
invoke-virtual {v1, v0}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
.line 32 iget-object v1, p0,Lirdc/ex05_01/EX05_01$1;->this$0:Lirdc/ex05_01/EX05_01;
const-string v2, "right++"
invoke-static {v1, v2, v3},Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V
.line 40 :goto_0 iget-object v1, p0,Lirdc/ex05_01/EX05_01$1;->this$0:Lirdc/ex05_01/EX05_01;
#getter for: Lirdc/ex05_01/EX05_01;->mTextView01:Landroid/widget/TextView; invoke-static {v1},Lirdc/ex05_01/EX05_01;->access$0(Lirdc/ex05_01/EX05_01;)Landroid/widget/TextView;
move-result-object v1
const/4 v2, 0x7
invoke-static {v1, v2},Landroid/text/util/Linkify;->addLinks(Landroid/widget/TextView;I)Z
.line 41 const/4 v1, 0x0
return v1
.line 35 :cond_0 iget-object v1, p0,Lirdc/ex05_01/EX05_01$1;->this$0:Lirdc/ex05_01/EX05_01;
#getter for: Lirdc/ex05_01/EX05_01;->mTextView01:Landroid/widget/TextView; invoke-static {v1},Lirdc/ex05_01/EX05_01;->access$0(Lirdc/ex05_01/EX05_01;)Landroid/widget/TextView;
move-result-object v1
invoke-virtual {v1, v0}, Landroid/widget/TextView;->setText(Ljava/lang/CharSequence;)V
.line 36 iget-object v1, p0,Lirdc/ex05_01/EX05_01$1;->this$0:Lirdc/ex05_01/EX05_01;
const-string v2, "error--"
invoke-static {v1, v2, v3},Landroid/widget/Toast;->makeText(Landroid/content/Context;Ljava/lang/CharSequence;I)Landroid/widget/Toast;
move-result-object v1
invoke-virtual {v1}, Landroid/widget/Toast;->show()V
goto :goto_0 .end method
注册机和修改过的最后一个软件
|