zoukankan      html  css  js  c++  java
  • Android反编译实战(5)

    在com/dangdang/reader/e/a目录下有个叫a.smali的文件,里面有个叫a的方法,我把代码全都贴出来

     1 .method public static a([B[B)[B
     2     .locals 5
     3 
     4     new-instance v0, Lorg/bouncycastle/jce/provider/BouncyCastleProvider;
     5 
     6     invoke-direct {v0}, Lorg/bouncycastle/jce/provider/BouncyCastleProvider;-><init>()V
     7 
     8     invoke-static {v0}, Ljava/security/Security;->addProvider(Ljava/security/Provider;)I
     9 
    10     new-instance v0, Ljavax/crypto/spec/SecretKeySpec;
    11 
    12     const-string v1, "AES"
    13 
    14     invoke-direct {v0, p0, v1}, Ljavax/crypto/spec/SecretKeySpec;-><init>([BLjava/lang/String;)V
    15 
    16     const-string v1, "AES/CBC/PKCS7Padding"
    17 
    18     const-string v2, "BC"
    19 
    20     invoke-static {v1, v2}, Ljavax/crypto/Cipher;->getInstance(Ljava/lang/String;Ljava/lang/String;)Ljavax/crypto/Cipher;
    21 
    22     move-result-object v1
    23 
    24     const/4 v2, 0x2
    25 
    26     new-instance v3, Ljavax/crypto/spec/IvParameterSpec;
    27 
    28     sget-object v4, Lcom/dangdang/reader/e/a/a;->a:[B
    29 
    30     invoke-direct {v3, v4}, Ljavax/crypto/spec/IvParameterSpec;-><init>([B)V
    31 
    32     invoke-virtual {v1, v2, v0, v3}, Ljavax/crypto/Cipher;->init(ILjava/security/Key;Ljava/security/spec/AlgorithmParameterSpec;)V
    33 
    34     invoke-virtual {v1, p1}, Ljavax/crypto/Cipher;->doFinal([B)[B
    35 
    36     move-result-object v0
    37 
    38     return-object v0
    39 .end method

    上述smali代码翻译成源代码大致上是这样的:

    1 public static byte[] a(byte[] p1, byte[] p2)
    2   {
    3     Security.addProvider(new BouncyCastleProvider());
    4     SecretKeySpec localSecretKeySpec = new SecretKeySpec(p1, "AES");
    5     Cipher localCipher = Cipher.getInstance("AES/CBC/PKCS7Padding", "BC");
    6     localCipher.init(2, localSecretKeySpec, new IvParameterSpec(a));
    7     return localCipher.doFinal(p2);
    8   }

    其中第6行有个数字2,经过查资料,得知

    也就是说2代表DECRY_MODE,即采用AES算法解密。其中两个参数p1代表对称秘钥,p2代表要解密的密文。

    我们可以试着动态调试,用Log的方式,将秘钥打印出来。

    修改上面的com/dangdang/reader/e/a下的a.smali文件,在第3行附近加入以下代码:

    1     const-string v0, "bupt"
    2     new-instance v1, Ljava/lang/String;
    3     const-string v2, "UTF-8"
    4     invoke-direct {v1,p0,v2}, Ljava/lang/String;-><init>([BLjava/lang/String;)V
    5     invoke-static {v0, v1}, Landroid/util/Log;->e(Ljava/lang/String;Ljava/lang/String;)I

     稍微解释一下:将byte[]数组转为String,然后调用Log.e()方法将秘钥打印出来。在logcat里查看显示的是乱码,如下图

    导出来发现只有104位,开头的空格和结尾的回车去掉了。

    疯了,不知道哪边错了。

    接下来,我们用grep 命令查找哪个地方调用了上述a方法,发现com/dangdang/reader/epubreader/b/ 目录下有个1.smali。

     1 private byte[] loadResource(String paramString, boolean paramBoolean, byte[] paramArrayOfByte)
     2   {
     3     if (!this.mEncrypted)
     4       paramBoolean = false;
    5 com.dangdang.reader.c.a.c("loadResource().." + paramString + "(" + paramBoolean + ")"); 6 byte[] arrayOfByte1; 7 //省略了try catch等代码 8 FileInputStream localFileInputStream = new FileInputStream(paramString); 9 ByteArrayOutputStream localByteArrayOutputStream = new ByteArrayOutputStream(); 10 byte[] arrayOfByte3 = new byte[1024]; 11 for (int i = localFileInputStream.read(arrayOfByte3); i != -1; i = localFileInputStream.read(arrayOfByte3)) 12 localByteArrayOutputStream.write(arrayOfByte3, 0, i); 13 localFileInputStream.close(); 14 localByteArrayOutputStream.flush(); 15 localByteArrayOutputStream.close(); 16 byte[] arrayOfByte4 = localByteArrayOutputStream.toByteArray(); 17 arrayOfByte1 = arrayOfByte4; 18 if (arrayOfByte1 == null) 19 return arrayOfByte1;
    。。。。。。。

              byte[] arrayOfByte2 = com.dangdang.reader.e.a.a.a(paramArrayOfByte, arrayOfByte1);
              return arrayOfByte2;

    }

    再结合我们上节破解出的log日志,对照着看

    loadResource()../mnt/sdcard/dangdang/undefine/readbook/1900284177/1900284177/OPS/Preface3.xhtml(true
    • 第一个参数paramString 是sd卡上的电子书路径
    • 第二个参数paramBoolean为true表明这是解密
    • 第三个参数paramArrayOfByte代表对称秘钥

     ======================

    参考破解"当当"DRM版权保护的电子书中的介绍,找到sd目录里的book_decode_key文件,对其进行Base64解码,得到128位AES秘钥。

    1     String str = readFileToString(new File("book_decode_key"), "UTF-8");
    2     byte[] aesKey = Base64.decode(str);
    3     StringBuffer sb = new StringBuffer();
    4     for(byte b: aesKey){
    5         sb.append(String.format("%x ", b));
    6     }
    7     System.out.println(sb);
    a0 e8 59 55 32 61 13 98 cd 20 bf b2 97 e2 a0 4a 

    下一步呢??

  • 相关阅读:
    每日日报
    HTML相关
    60-Shiro功能扩展(记住我)
    60--Shiro安全框架
    服务器项目部署简单操作
    61--DB项目--修改密码模块设计
    59-SpringAOP --Cache操作(注解)
    58-Spring AOP 异步操作
    58-Spring-AOP事务管理
    Terminal 执行 java 命令
  • 原文地址:https://www.cnblogs.com/feiyunruyue/p/3128612.html
Copyright © 2011-2022 走看看