Wow, compared to Lab3, it can be said to be very painful...
Kang Kang Smali turns to Java~
Task 1
Here is the class that wrote a check input string
public class Checker {
private String secret;
public Checker(){
secret="key";};//构造函数
private boolean checkStr1(String str)
{
int i=0,num=0,first=0,last=0;
char[] c=str.toCharArray();
int len=c.length;
while(i<len)
{
if(c[i]==0x78) {
num++;
if(num==1) first=i;
if(num==2) last=i;}
i++;}
if(num!=2 || (last-first)!=4 || c[0]!=0x30 || c[len-1]!=0x39) return false;
String tmp = str.substring(0, first);
if(tmp.contains(secret)) {
return true; }
else return false;
};//检查子串1
private int count(String str)
{
char[] c=str.toCharArray();
int len=c.length;
if(len<=0) return 0;
int i=0,num=0;
while(i<len)
{
if(c[i]==0x31) num++;
i++;
}
return num;
}//子串2中1的数量
private int func(int n)
{
if(n<=1) return 1;
else return func(n-1)*n;
}//阶乘
public boolean check(String str)
{
int len=str.length();
if(len<0xc) return false;
if(len<=0x10)
{
String sub1=str.substring(0,0xa);
String sub2=str.substring(0xa,len);
int m=count(sub2);
int k=func(m);
if(m==k && checkStr1(sub1)==true) return true;
else return false;
}
else return false;
}
}
In fact, it’s easy to understand.
Enter a string with a length between 12 and 16, divided into two substrings to check:
(1) (0~0xa) Use checkStr1 to
start with 0 and end with 9, with two x in the middle and 3 in the middle. Characters, "key" before the first x
eg.0keyxabcx9
(2) (0xa~end) use count() & func()
to contain k 1s (k satisfies k==k!)
eg.11abc
Output:
ps: I didn’t pay attention to a few small mistakes when writing. I have been debugging for a long time... The
first one is that the values of first and last are not updated. In fact, it is judged when it is not equal to x (Tears of regret (• ̥́ ˍ •̀ू ))
(Forced smali output debug) The
second is the 0 and 0 I wrote! Are equal... (and careless (•̥́ ˍ •̀ू)
Look at the disassembly carefully! !
Task 2
The second level is relatively complicated. First enter the ID, generate the hash value and encode
will give an Encoded msg,
then you need to run this msg as a parameter, and then enter the ID to determine whether it is legal
public class Encoder {
private String algorithm;
private String charSet;
private final String[] hexDigits;
public Encoder()
{
hexDigits= new String[]{
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"};
algorithm="MD5";
charSet="utf-8";
}//构造函数
private String byteArrayToHexString(byte[] b)
{
StringBuffer buff = new StringBuffer();
int len=b.length,i=0;
while(i<len)
{
buff.append(byteToHexString(b[i]));
i++;
}
return buff.toString();
}//转换HexString
private String byteToHexString(Byte b)
{
int b1=b&0xff;
int v0=b1/16,v1=b1%16;
StringBuilder build=new StringBuilder();
build.append(hexDigits[v0]).append(hexDigits[v1]);
return build.toString();
}
private String getSalt()
{
Random ran=new Random();
StringBuilder build=new StringBuilder(0x10);
int i=0;
while(i<0x10)
{
if(ran.nextBoolean()==false)
build.append("0");
else build.append("1");
i++;
}
return build.toString();
}//获取盐值
public boolean check(String a,String b)
{
int i=0;
char[] c1=new char[0x20];
char[] c2=new char[0x10];
int b_len=b.length();
if(b_len!=0x30) return false;
else {
while (i<0x30) {
int m=(i/3)*2;
c1[m]=b.charAt(i);
c1[m+1]=b.charAt(i+2);
m=i/3;
c2[m]=b.charAt(i+1);
i+=3;
}
String str = new String(c2);
StringBuilder build1 = new StringBuilder();
build1.append(a).append(str);
String str1 = build1.toString();
try {
MessageDigest dig = MessageDigest.getInstance(algorithm);
StringBuilder build2 = new StringBuilder();
build2.append("");
byte[] res = dig.digest(str1.getBytes(charSet));
build2.append(byteArrayToHexString(res));
String str2 = new String(c1);
return str2.equals(build2.toString());
} catch (Exception e) {
e.printStackTrace();
}
}
return false;
}//用于第二次检查
public String encoding(String str){
String salt=getSalt();
String str2=null;
String str3=null;
StringBuilder build=new StringBuilder();
StringBuilder build2 = new StringBuilder();
build.append(str).append(salt);
String str1=build.toString();
try{
MessageDigest dig = MessageDigest.getInstance(algorithm);
build2.append("");
byte[] res = dig.digest(str1.getBytes(charSet));
build2.append(byteArrayToHexString(res));
str2=build2.toString();
} catch (Exception e) {
e.printStackTrace();}
try{
char[] c=new char[0x30];
int i=0;
while(i<0x30)
{
int m=(i/3)*2;
c[i]=str2.charAt(m);
m=i/3;
c[i+1]=salt.charAt(m);
m=(i/3)*2+1;
c[i+2]=str2.charAt(m);
i+=3;
}
str3=new String(c);} catch (Exception e) {
str3=str2;
e.printStackTrace();
}
return str3;
}//用于第一次生成Encoded msg
}
It is quite easy to understand, that is, some Java automatic encryption method
idea method with parameters is used when encrypting :
https://blog.csdn.net/u013713294/article/details/53020293
and found very interesting things, pass When entering the byte parameter <0, you will
check the information with &0xff :
https://blog.csdn.net/ido1ok/article/details/85235955 is
probably the byte will automatically complement the sign bit when it is used as an int operation, & it is guaranteed to get a positive number
Some of the encryption methods: (hash)
MessageDigest.getInstance(algorithm);
generate a MessageDigest object that implements the specified digest algorithm.
digest(byte[] input)
Use the specified byte array to finally update the digest, and then complete the digest calculation
In fact, these are the encryption methods to learn later~
Output: