PoRE: Lab 4

哇比起Lab3可以说是很痛苦了…
康康Smali转Java叭~


Task 1

这里是写了一个check输入字符串的类

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;
    }
}

其实很容易看懂的
输入一个字符串,长度在12~16之间,分成两个子串分别check:
(1)(0~0xa)用checkStr1
开头0,结尾9,中间有两个x中间间隔3个字符,第一个x之前含"key"
eg.0keyxabcx9
(2)(0xa~结尾)用count() & func()
需要含有k个1(k满足k==k!)
eg.11abc

输出:
在这里插入图片描述

ps:写的时候有几个小错误没注意,debug了挺久的…
第一个是first和last的值没有更新对,其实是在不等于x的时候也进行判断(悔恨的泪水( •̥́ ˍ •̀ू ))
在这里插入图片描述
(强行smali输出debug)
第二个是我写的0和0!是相等的…(又粗心( •̥́ ˍ •̀ू )
在这里插入图片描述
在这里插入图片描述

看反汇编要仔细仔细仔细!!


Task 2

第二关相对复杂,先输入ID,生成hash值并encode
会给出一个Encoded msg
然后需要把这个msg作为参数运行,再输入ID判断是否合法

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
}

还蛮好理解的,就是在加密时用了一些Java的自动加密方法
idea带参数的方法:
https://blog.csdn.net/u013713294/article/details/53020293
以及发现了很有意思的事情,传入byte参数<0时会&0xff
在这里插入图片描述
查了一下资料:
https://blog.csdn.net/ido1ok/article/details/85235955
大概就是之后作为int运算时byte自动补符号位吧,&一下保证得到正数

当中的一些加密方法:(hash)
MessageDigest.getInstance(algorithm);生成实现指定摘要算法的 MessageDigest 对象
digest(byte[] input) 使用指定的字节数组对摘要进行最后更新,然后完成摘要计算

其实这些都是之后要学的加密方法啦~
输出:
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Rachel_IS/article/details/105315250