金山保险●箱 探秘金山隐私保险恐怖實力箱 - 天涯资讯此時此刻网

内容标题25

  • <tr id='8osv7l'><strong id='8osv7l'></strong><small id='8osv7l'></small><button id='8osv7l'></button><li id='8osv7l'><noscript id='8osv7l'><big id='8osv7l'></big><dt id='8osv7l'></dt></noscript></li></tr><ol id='8osv7l'><option id='8osv7l'><table id='8osv7l'><blockquote id='8osv7l'><tbody id='8osv7l'></tbody></blockquote></table></option></ol><u id='8osv7l'></u><kbd id='8osv7l'><kbd id='8osv7l'></kbd></kbd>

    <code id='8osv7l'><strong id='8osv7l'></strong></code>

    <fieldset id='8osv7l'></fieldset>
          <span id='8osv7l'></span>

              <ins id='8osv7l'></ins>
              <acronym id='8osv7l'><em id='8osv7l'></em><td id='8osv7l'><div id='8osv7l'></div></td></acronym><address id='8osv7l'><big id='8osv7l'><big id='8osv7l'></big><legend id='8osv7l'></legend></big></address>

              <i id='8osv7l'><div id='8osv7l'><ins id='8osv7l'></ins></div></i>
              <i id='8osv7l'></i>
            1. <dl id='8osv7l'></dl>
              1. <blockquote id='8osv7l'><q id='8osv7l'><noscript id='8osv7l'></noscript><dt id='8osv7l'></dt></q></blockquote><noframes id='8osv7l'><i id='8osv7l'></i>
                您当前的三大圣者和三皇都雙目通紅位置:众乐彩票网 > 财经

                金∩山保险箱 探秘金山隐私你找死保险箱

                2019-06-11 04:02:21 来源: 众乐彩票网责任编辑:小s0条评论

                    信息化时代的快速发展。同一时候也孕育了很多其它的网络攻击。网银被盗、隐私信息泄露而后緩緩嘆了口氣等

                无疑成为了广大网民最为⊙关注的问题。

                几年前,“艳照门”事件的曝光。更是引发了互联网的一阵恐慌。

                         现在。移动互联网的迅速▅普及,手机相机的像素也越来越高,我们能够非常方便就是最后的使用手机拍摄自己感兴趣的东西并上传到朋友圈、微博等。

                可是,这同一第二殿主和冷光也是滿臉錯愕时候也引入了另外一个问题。拍了这么多东西,总有自己的一些隐私数据是不想对外公开的。于是,各大互联网安全厂商纷纷推出了能在移动设备對付冷光上加密照片、音乐、视频等文件的应用程序。

                可是。这些应用真的能有效的保护好用户的隐私数据吗?他们的实對现原理又是什么呢?带着这些疑问,今天我们就来分析下“金山隐私保险箱”的实现原理。

                測试环境

                红米TD版

                百度云ROM 正式版V6

                金山隐私保险箱1.3Beta2

                程序分析

                金山隐私保险箱安装完身上也同樣是一陣陣黑光爆閃之后。加密一张自己拍的照片。此时,程序会将加密好的文件保存到sd卡的.ksbox文件夹下,如图1所看到的。

                图1

                         将.ksbox文件夹导出到本地。使用sqliteexpert工具打开db.sqlite文件,表结构入等人震驚图2所看到的。

                图2

                         依据表结构我们大致能够知道。原始黑袍使者看著三號貴賓室文件名称、文件大小、被加密后的文件名〓称等信息。知道了这些基本信息。我们接下来使用APK IDE解包程序。发现金山隐私保险箱自己实现了一个ImageInputStream的类。该派生自InputStream,详细的实现文件为com/ijinshan/mPrivacy/c/j.smali。如图3所看到的。

                图3

                使用APK IDE搜索Lcom/ijinshan/mPrivacy/c/j,结果如图4所看到的。

                图4

                定位到第一手中个new-instance的地方,代码例如以下所看到的。仅仅截取我们所关注的部分。

                # 解码一个inputstream到Bitmap

                .method private statica(Ljava/lang/String;I)Landroid/graphics/Bitmap;

                    .locals 11

                    .prologue

                    const/4 v3, 0x1

                    const/4 v9, -0x1

                    const/high16 v6,0x3f800000

                    const/4 v8, 0x0

                    .line 197

                    .line 200

                    :try_start_0

                         # 新建一个自己定义的InputStream对象

                    new-instance v0,Lcom/ijinshan/mPrivacy/c/j;

                         # 使用文件初始化InputStream

                    invoke-direct {v0, p0},Lcom/ijinshan/mPrivacy/c/j;-><init>(Ljava/lang/String;)V

                    .line 201

                    invoke-virtual {v0},Lcom/ijinshan/mPrivacy/c/j;->available()I

                    move-result v1

                    if-ne v1, v9, :cond_0

                    move-object v0, v8

                    .line 264

                    :goto_0

                    return-object v0

                    .line 205

                    :cond_0

                         # 新建一个BitmapFactory对象

                    new-instance v1,Landroid/graphics/BitmapFactory$Options;

                    invoke-direct {v1},Landroid/graphics/BitmapFactory$Options;-><init>()V

                    .line 208

                    const/4 v2, 0x1

                    iput-boolean v2, v1,Landroid/graphics/BitmapFactory$Options;->inJustDecodeBounds:Z

                    .line 209

                    const/4 v2, 0x0

                         # 调用BitmapFactory的decodeStream方法,解码input stream到Bitmap

                invoke-static {v0, v2, v1}, Landroid/graphics/BitmapFactory;->decodeStream(Ljava/io/InputStream;Landroid/graphics/Rect;Landroid/graphics/BitmapFactory$Options;)Landroid/graphics/Bitmap;

                调用decodeStream函数之后,就会进入我们派生的ImageInputStream类中。该类重写了read方法,主要用来自己定义解码算法。

                我们来看下主要代码:

                .method public final read([BII)I

                    .locals 7

                    .prologue

                    const/4 v6, 0x0

                    const/16 v5, 0x400

                    .line 61

                    iget-object v0, p0,Lcom/ijinshan/mPrivacy/c/j;->a:Ljava/io/FileInputStream;

                         # p2(byteOffset),p3(byteCount)=0x10000

                    invoke-virtual {v0, p1,p2, p3}, Ljava/io/FileInputStream;->read([BII)I

                    move-result v0

                    .line 63

                    const/4 v1, -0x1

                         # 推断返回值是否为-1,-1即读到■文件末尾

                    if-ne v0, v1, :cond_0

                    .line 103

                    :goto_0

                    return v0

                    .line 70

                    :cond_0

                         # f保存了已读的字节数

                    iget-wide v1, p0, Lcom/ijinshan/mPrivacy/c/j;->f:J

                    const-wide/16 v3, 0x400

                    cmp-long v1, v1, v3

                         # 推断已读的字节数是否大于或等于0x400字节

                    if-gtz v1, :cond_5

                         # 第一次读的话,运行例如神色以下代码

                    .line 73

                         # e是个bool值,推断是否已经解密了前面的0x400字节

                    iget-boolean v1, p0, Lcom/ijinshan/mPrivacy/c/j;->e:Z

                    if-nez v1, :cond_1

                         # 第一次读漆黑色刀芒直接轟到了符箓之上取。未解密,运行例如以下代码

                    .line 75

                    iget-object v1, p0,Lcom/ijinshan/mPrivacy/c/j;->c:Lcom/ijinshan/mPrivacy/c/g;

                         # b是个String类型的变量,当中保存了加密后文件的路径,比如/storage/sdcard0/.ksbox/6b2c357d      

                    iget-object v1, p0,Lcom/ijinshan/mPrivacy/c/j;->b:Ljava/lang/String;

                         # 调用g;->b方法,解密前面0x400字节

                    invoke-static {v1},Lcom/ijinshan/mPrivacy/c/g;->b(Ljava/lang/String;)[B

                    move-result-object v1

                         # 将可是解密出来的字节数组保存到d变量中

                    iput-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

                    .line 76

                    iget-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

                         # 推断字节数组是否为空

                    if-eqz v1, :cond_1

                    .line 77

                    const/4 v1, 0x1

                         # 返回不为空。那他一下子就要朝歸墟秘境么设置变量e为true。即解密成功

                    iput-boolean v1, p0, Lcom/ijinshan/mPrivacy/c/j;->e:Z

                    .line 80

                    :cond_1

                         # v0寄存器保存了实际读取到的字节数,p3是想要读取的字节数。即0x10000

                    if-ge v0, p3, :cond_3

                    move v1, v0

                    .line 82

                    :goto_1

                         # v2 = byteOffset + 实际读到的字节数

                    add-int v2, p2, v1

                         # 假设v2大于0x400,就跳到cond_4

                    if-gt v2, v5, :cond_4

                    .line 84

                    iget-object v2, p0,Lcom/ijinshan/mPrivacy/c/j;->d:[B

                    if-eqz v2, :cond_2

                    .line 85

                         # 将前面解密的数据赋给v2寄存器

                    iget-object v2, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

                         # v2复制到p1。p2为srcOffset,v6是desOffset。v1为拷贝大小何林眼睛一亮

                    invoke-static {v2, p2, p1,v6, v1}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V

                    .line 100

                    :cond_2

                    :goto_2

                         # 已经读取的字节数

                    iget-wide v1, p0, Lcom/ijinshan/mPrivacy/c/j;->f:J

                         # v0为实际读血紅色光芒爆閃到的字节数,转成long,保存到v3

                    int-to-long v3, v0

                    add-long/2addr v1, v3

                         # 本次实际读到的字节数 + 曾经已经读取的字节数,保存到f变量

                    iput-wide v1, p0, Lcom/ijinshan/mPrivacy/c/j;->f:J

                    goto :goto_0

                    :cond_3

                    move v1, p3

                    .line 80

                    goto :goto_1

                    .line 89

                    :cond_4

                    if-ge p2, v5, :cond_2

                    .line 91

                    iget-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

                    if-eqz v1, :cond_2

                    .line 92

                    iget-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

                    sub-int v2, v5, p2

                         # 后面的数据不什么主意用解密。直接拷贝就可以

                    invoke-static {v1, p2, p1,v6, v2}, Ljava/lang/System;->arraycopy(Ljava/lang/Object;ILjava/lang/Object;II)V

                    goto :goto_2

                    .line 98

                         # 假设已读的字节数大于0x400,就跳到这里他运行

                    :cond_5

                    const/4 v1, 0x0

                         # 清空d变量

                    iput-object v1, p0, Lcom/ijinshan/mPrivacy/c/j;->d:[B

                    goto :goto_2

                .end method

                上面这段smali代码中比較关键的一个调用是invoke-static {v1},Lcom/ijinshan/mPrivacy/c/g;->b(Ljava/lang/String;)[B。我们跟进去看一下。

                # 解密文件

                # p0: 加密后文件的路径,比如/storage/sdcard0/.ksbox/6b2c357d

                .method public static b(Ljava/lang/String;)[B

                    .locals 2

                    .prologue

                    const/4 v1, 0x0

                    .line 456

                    :try_start_0

                         # 推断是否是我们的加密文件,推断文件开头特征等甚至更強等

                    invoke-static {p0},Lcom/ijinshan/mPrivacy/c/g;->h(Ljava/lang/String;)[B

                    move-result-object v0

                    .line 457

                    if-nez v0, :cond_0

                    move-object v0, v1

                    .line 472

                    :goto_0

                    return-object v0

                    .line 461

                    :cond_0

                         # 调用b(Ljava/lang/String;I)[B。读取_e文件的我們還是先趕緊追下去内容

                    invoke-static {p0},Lcom/ijinshan/mPrivacy/c/g;->i(Ljava/lang/String;)[B

                         # v0即为_e文件的内容

                    move-result-object v0

                    .line 462

                    if-eqz v0, :cond_1

                    .line 464

                         # 调用解密函数什么大事不好了,解密v0

                    invoke-static {v0},Lcom/ijinshan/mPrivacy/c/g;->a([B)[B

                    :try_end_0

                    .catchLjava/io/IOException; {:try_start_0 .. :try_end_0} :catch_0

                    move-result-object v0

                    goto :goto_0

                    .line 467

                    :catch_0

                    move-exception v0

                    invoke-virtual {v0},Ljava/io/IOException;->printStackTrace()V

                    :cond_1

                    move-object v0, v1

                    .line 472

                    goto :goto_0

                .end method

                这里最为关键的是invoke-static{v0}, Lcom/ijinshan/mPrivacy/c/g;->a([B)[B这个调用。a([B)[B这个函数是专门用来解密byte数组的,代码例如以下所看到的。

                # 解密算法

                # buffer[i] = buffer[i] ^ 0x6b;

                .method public static a([B)[B

                    .locals 3

                    .prologue

                    .line 264

                    array-length v0, p0

                         # 推断血肉传入參数的buffer是不是大于0

                    .line 266

                    const/4 v1, 0x0

                         # 推断v1是否大于buffer的大小

                    :goto_0

                    if-ge v1, v0, :cond_0

                         # 取一个既然叫他小心字节保存到v2

                    .line 267

                    aget-byte v2, p0, v1

                         # 与0x6b异或

                    xor-int/lit8 v2, v2, 0x6b

                    int-to-byte v2, v2

                         # 把异或得到的值写回原来的buffer中

                    aput-byte v2, p0, v1

                         # v1 + 1

                    .line 266

                    add-int/lit8 v1, v1, 0x1

                         # 继续循环

                    goto :goto_0

                    .line 270

                    :cond_0

                    return-object p0

                .end method

                程序分析到这里。我们大致知道了金山隐私保险箱的解密步骤:

                1.       从InputStream类中╱派生自己的类,调用BitmapFactory的decodeStream函数解码文件输入流;

                2.       重写InputStream类的read函数,用来实现自己的解密算第二件神物沒有拍到法;

                3.       解密的时候推断假设是前面最開始的0x400字节,那么读取filename_e文件,每一个字节异或0x6B,假设是大于0x400字节,那么直接读取filename文件。

                4.       依照上面的步骤解密,最后输出的文件即为原始文件。

                编写解密程序

                既然知道了金山隐私保险箱的解惡魔之主說密算法,那么自己实现一个解密程序也就非常easy了,大致代码例如以下所看到的。

                #include "stdafx.h"

                #include <Windows.h>

                // szName - 加密文件的文件名称

                // szOriginName - 原始文件名称

                BOOL DecodeStream(WCHAR *szName, WCHAR *szOriginName)

                {

                         BOOL bRet = FALSE;

                         if (!szName ||!szOriginName)

                         {

                                   return bRet;

                         }

                         HANDLE hFile =CreateFile(szName,

                                   FILE_ALL_ACCESS,

                                   FILE_SHARE_READ| FILE_SHARE_WRITE,

                                   NULL,

                                   OPEN_EXISTING,

                                   FILE_ATTRIBUTE_NORMAL,

                                   NULL);

                         if (hFile ==INVALID_HANDLE_VALUE)

                         {

                                   return bRet;

                         }

                         DWORD dwHigh = 0;

                         DWORD dwSize =GetFileSize(hFile, &dwHigh);

                         if (dwSize < 0x400)

                         {

                                   CloseHandle(hFile);

                                   return bRet;

                         }

                         PBYTE pBuffer =(PBYTE)malloc(dwSize);

                         if (pBuffer == NULL)

                         {

                                   CloseHandle(hFile);

                                   return bRet;

                         }

                         memset(pBuffer, 0,dwSize);

                         HANDLE hSaveFile =CreateFile(szOriginName,

                                   FILE_ALL_ACCESS,

                                   FILE_SHARE_READ| FILE_SHARE_WRITE,

                                   NULL,

                                   CREATE_ALWAYS,

                                   FILE_ATTRIBUTE_NORMAL,

                                   NULL);

                         if (hSaveFile ==INVALID_HANDLE_VALUE)

                         {

                                   CloseHandle(hFile);

                                   free(pBuffer);

                                   return bRet;

                         }

                         WCHAR szPath[MAX_PATH]= {0};

                         wsprintf(szPath,L"%s%s", szName, L"_e");

                         HANDLE hFile_e =CreateFile(szPath,

                                   FILE_ALL_ACCESS,

                                   FILE_SHARE_READ| FILE_SHARE_WRITE,

                                   NULL,

                                   OPEN_EXISTING,

                                   FILE_ATTRIBUTE_NORMAL,

                                   NULL);

                         if (hFile_e ==INVALID_HANDLE_VALUE)

                         {

                                   CloseHandle(hFile);

                                   CloseHandle(hSaveFile);

                                   free(pBuffer);

                                   return bRet;

                         }

                         DWORD dwRet = 0;

                         bRet =ReadFile(hFile_e, pBuffer, 0x400, &dwRet, NULL);

                         if (!bRet)

                         {

                                   CloseHandle(hFile);

                                   CloseHandle(hSaveFile);

                                   CloseHandle(hFile_e);

                                   free(pBuffer);

                                   return bRet;

                         }

                         SetFilePointer(hFile,0x400, NULL, FILE_BEGIN);

                         bRet = ReadFile(hFile,pBuffer+0x400, dwSize-0x400, &dwRet, NULL);

                         if (!bRet)

                         {

                                   CloseHandle(hFile);

                                   CloseHandle(hSaveFile);

                                   CloseHandle(hFile_e);

                                   free(pBuffer);

                                   return bRet;

                         }

                         for (int i = 0; i <0x400; i++)

                         {

                                   pBuffer[i] =pBuffer[i] ^ 0x6b;

                         }

                         WriteFile(hSaveFile,pBuffer, dwSize, &dwRet, NULL);

                         CloseHandle(hFile);

                         CloseHandle(hSaveFile);

                         CloseHandle(hFile_e);

                         free(pBuffer);

                         return bRet;

                }

                int _tmain(int argc, _TCHAR* argv[])

                {

                         DecodeStream(L"C:\\Users\\Administrator\\Desktop\\98fca88",

                                   L"C:\\Users\\Administrator\\Desktop\\1.jpg");

                         return 0;

                }

                运行完如上代码之后。图片被解應該不會再繼續變老了才對密出来,而且能正常打开。自此,金山隐私并不是這火靈根保险箱就被我们轻易的攻破了。

                如图5所看到的:

                图5

                后记

                         分析完金山隐私保险箱之后。我后来又去看了下360隐私保险箱和腾讯手机管家的隐私保险箱,大致的加解密流就算如此程都差点儿相同,都仅仅加解密文件开头的0x400字节。仅仅是各自的加密算法不同等下回去罢了,可是回过头那是仙器之魂来想想,既然它们都能把文件还原回去,也就是说这个过程一定是可逆的。

                         经过上面的分析,眼下移动端的隐私保护软件基本上也就仅奇怪仅是个心里安慰罢了。在日常生活中,我们还是要自珍自爱,尽量不要把私密的文件保存在移动设备上,也不要去下载来历不明的软件、外挂等。


                Copyright © 2006-2016 www.awmnr.com All rights reserved.京ICP备13053018号-1
                郑重申明:未经授权禁止转载、摘编、复制或建立镜像.如有违反,追究法律责任。