2018年3月31日星期六

文字数据统计分析-QQ空间短语

     在上一篇博文当中我们抓取了一些QQ空间的说说数据。这里是说说的字频等的简单分析。
     相关文件在Github:https://github.com/WangHexie/getQQzoneText
     以下我们对分析进行一定的说明,展示一些结果。
     首先是简单的字数统计,字频统计的效果:

    可以看到,在这一万六千多字的数据中,用到的字和字符仅为一千五百多个。这只是单个人的数据,我们可以看一下全部文字数据的结果。

    在这里可以看到,文字数量增加了二十多倍,而字典数只增加了一倍多。高频字大概是相符的,但也有一些差异。我们可以再看一个单个人的数据。

   可以看到其中关于字频,有一些统计结果的差异。这也是通过文字来判断作者的一个基础。
  对第一个字典数为1565的人中,我们另外做了一个统计。


  图中可以看到,大部分字都只出现了一次,出现一次的字达到了将近一千三百多个,占了总字数的83%,只有少数多次出现。
  这意味着什么?我们由此画出了一张分布图(不小心用了另一个人的数据,但是影响不大)
    可以看到,前1%的字占了总出现次数的50%。前50个字符和后面的四千多个字的贡献率是差不多的。在后续的机器学习当中我们就可以适当地舍去一些字符,减少字典大小。

2018年3月20日星期二

使用 selenium 爬取QQ空间内容

     由于要进行机器学习,进行数据分析。于是有了抓取空间说说数据的需求。
     由于qq空间代码量过于庞大,不好进行分析,于是直接使用headless Chrome 来进行数据的抓取。这里使用python的selenium库来完成。
     qq空间的数据使用动态加载的形式。而且不同空间的样式区别较大,经常需要进行代码的调试,我在这里推荐使用Ipython来进行代码的构建。发现无法选择元素的时候能及时介入,保存环境,进行调试。同时也推荐调试的时候把headless选项去掉,能够直观地看到网页加载等状态。
     由于selenium相对js原生的环境,还是有一些奇怪的问题发生。功能也相对较少。我们可以先直接在浏览器中初步地调试,使用js写出大概的代码。以下的代码能初步地实现了切换页面的功能。接下来我们将这几行代码转移到python中去。

#引用库 var jqry = document.createElement('script'); jqry.src='https://code.jquery.com/jquery-3.3.1.js'; head = document.getElementsByTagName('head'); head[0].appendChild(jqry); #转到说说页面 var shuoshuo = $('[title="说说"]'); shuoshuo.get(0).click(); var textContent = document.getElementsByTagName('pre'); var page = document.getElementById('pager_num_0_2'); var page = document.getElementById('pager_next_3'); page.click() page = $('[title="下一页"]'); page.get(0).click();
     首先进行qq的登陆,我们在网页中先自行登陆一次,并且复制下cookies,留作python的登陆用,减少代码量。cookies可以用chrome控制台轻松取得。


     复制后,使用代码转换成selenium能够接受的形式
def convertCookies(cookie_before):
    cookiesS = []  # 初始化cookies字典变量
    for line in cookie_before.split(';'):  # 按照字符:进行划分读取        # 其设置为1就会把字符串拆分成2份        cookies = {'name':'','value':''}
        cookies['name'], cookies['value'] = line.strip().split('=', 1)
        cookiesS.append(cookies)
    print(cookiesS)
    return cookiesS
     进入登陆页面,加入cookies,登上电脑上的qq之类的,使登陆页面出现快捷登陆的头像,

切换frame,模拟点击,成功进入空间。 在这里记得要time.sleep(一段时间),不然网页没加载好无法选择元素,导致程序出错。这个问题后面也经常会出现,也使调试有一定难度,程序出错,调试却正常。
     接下来进入说说标签页,查看文件结构,并进行选择,这里也要进行等待。

    以下代码就能轻松解决了。
    try:
        shuoshuo = driver.find_element_by_xpath("//a[@accesskey='6']").click()
    except:
        time.sleep(20)
        driver.find_element_by_xpath("//a[@title='说说']").click()
     跳转到下一页的时候也是同理,但是要加一行滚动页面的代码,不然切换页面的按钮不会加载。我们使用selenium的js引擎直接执行js代码。
driver.execute_script("window.scrollTo(0,document.body.scrollHeight)")
     接下来都是大同小异的过程。
     代码真正要运用执行的时候,可以关闭图像的加载,使得sleep()时间可以相应的缩短,加快加载速度。以下是对应的代码:
prefs = {"profile.managed_default_content_settings.images" : 2}
chrome_opt.add_experimental_option("prefs", prefs)
      元素不可见,frame造成困扰的时候 ,进入defalt frame,再重新进入所需frame也能解决一些其他代码无意中干扰的问题,提高程序的鲁棒性。
       具体的完整代码,请见我的GitHub。
Github:https://github.com/WangHexie/getQQzoneText


2018年3月16日星期五

app 破解记录--MD5salt 寻找过程

     遇到的这个app是通过360加固的,直接从apk还原到jar文件是不可行的。直接还原可以看到里面全是空的方法。
未拖壳代码
   所以要先脱壳,这里用的是https://android.googlesource.com/platform/art/+/kitkat-release/dex2oat/dex2oat.cc。生成新的一个dex
拖壳后代码

    接着阅读代码寻找salt。我们可以看到加密对应的salt是getstring(number)函数
,我们直接搜索apk解包之后的资源文件,然而并没有找到。我们在程序之中再次搜索,发现这个number对应的string
,再次进行搜索,成功找到对应的key
      然后获取用户id,验证找到的key的正确性。我们通过抓包获取用户id。把手机连接到电脑的热点上,并用fiddler拦截所有流量。搜索后成功发现所需id
       代入程序验证。然而结果并不能和数据包上的tokensign对应。重新检查程序,发现app还有一层混淆。使用jadx开反混淆功能,真正的代码出现了。
示例代码,真正代码由于安全问题在这不放出
重新查看,拖出正确的代码,输入数据,结果和我们预期的相同,程序的破解就此结束了。

   总结:
           md5计算的salt不能简单的放在文件里。至少要加密,动态获取。https也应该启用。然而这些只能延迟应用被破解的时间,数据由本地客户端产生,服务端还是难以验证的。