安卓逆向之华山杯ctf第二题:寻找密码

题目下载:http://download.csdn.net/detail/darmao/9873200
安装后打开是这样的:
这里写图片描述
输入用户名和密码登陆

扔进jeb里看看:
这里写图片描述
加壳了,看看是如何动态加载的:
这里写图片描述
**依次调用了readDexFileFromApk()–>splitPayLoadFromDex()
第一个函数先将apk解压,将里边的dex文件读入到一个byte[]里,重点在splitPayLoadFromDex()函数:**
这里写图片描述

        int v5 = arg25.length;  //apk中dex文件的长度
        byte[] v8 = new byte[4];
        System.arraycopy(arg25, v5 - 4, v8, 0, 4);//将dex文件中的最后四个字节读取到v8
        int v19 = new DataInputStream(new ByteArrayInputStream(v8)).readInt();//将四个
                                                  byte转成一个int,也就是未加壳的apk的长度
        System.out.println(Integer.toHexString(v19));
        byte[] v18 = new byte[v19];
        System.arraycopy(arg25, v5 - 4 - v19, v18, 0, v19);//这里是从legth-4-v19开始copy
        v18 = this.decrypt(v18);//解密
        File v9 = new File(this.apkFileName);

通过以上分析,我们可以得到加壳了以后的apk的结构应该是:
+——-+———–|——————+
+ 壳子 | 原始apk | 原始apk的长度 |
+ ——+———–+——————+

我们需要做的就是将原始apk读取出来,然后解密,看看解密算法:

这里写图片描述
**直接和0xff或一下即可
java代码如下:**

public static byte[]newByte(String path) throws IOException 
    {//path是apk中的dex文件的路径
        File file=new File(path);
        byte[] srcLen=new byte[(int) file.length()];
        byte[] temp=new byte[1024];
        int tempLen=0;
        int i=0;
        BufferedInputStream bis=new BufferedInputStream(new FileInputStream(file));
        while(-1!=(tempLen=bis.read(temp)))
        {
            System.arraycopy(temp, 0, srcLen, i, tempLen);
            i+=tempLen;
        }
        byte[] decryptLenByte=new byte[4];
        System.arraycopy(srcLen, srcLen.length-4, decryptLenByte, 0, 4);
        ByteArrayInputStream byteInput=new ByteArrayInputStream(decryptLenByte);
        DataInputStream dataOutput=new DataInputStream(byteInput);
        int decryptLen=dataOutput.readInt();

        System.out.println("长度是:"+Integer.toHexString(decryptLen));

        byte[]newDexByte=new byte[decryptLen];
        System.arraycopy(srcLen, srcLen.length-4-decryptLen, newDexByte, 0, decryptLen);
        for(int j=0;j<decryptLen;j++)
        {
            newDexByte[j]=(byte) ((newDexByte[j]^255)&0x0ff);
        }
        BufferedOutputStream bos=new BufferedOutputStream(new FileOutputStream(new File("D:\\test\\new_write_dex.apk")));
        bos.write(newDexByte);

        return newDexByte;
    }

**将这个读取出来的新apk拖到jeb里:
onClick函数:**
这里写图片描述
这里调用了checkNameAndPassword这个函数,其中第一个参数是:用户名,第二个是密码,还有另外一个参数,我们看看这个函数:
这里写图片描述
**首先对用户名做了使用sha-1进行了哈希,然后读取前16个字节
进行判断的部分:密码要等于这前十六个字节,同时用户名等于其传进去的第三个参数,第三个参数是什么呢?**

这里写图片描述
U2hlMTFfTjZSYw== 这个字符串的解码

总结:用户名:base64.decode(“U2hlMTFfTjZSYw==”);
密码:sha1(“用户名”).subString(0,16);
用户名:She11_N6Rc
密码:6acbbca78fdca0c5
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值