Posted on Leave a comment

Blink内核相关术语、映射关系

在读Adblock Plus for Chrome插件的源代码时,拦截入口处有几个判断非常重要,这涉及到当前打开Tab的URL、来源、打开方式等概念,对应到Blink中术语有page、main frame、iframe、document等,翻阅一下Blink的README文档,找到官方的介绍在此做一下记录。

  • Page

一个Page对应于一个Tab,当然前提时OOPIF(Out-of-Process iframes)没有开启。每一个渲染进程可能包含多个Tab。

  • Frame

Frame对应于HTML中的frame,可能是主frame或者iframe,每个Page在树形结构中可能包含一个或者多个frame。

  • DOMWindow

一个DOMWindow对应Javascript中的一个window对象,每个Frame有一个DOMWindow。

  • Document

一个Document对应Javascript中的一个window.document,每个Frame有一个Document。

  • ExecutionContext

一个ExecutionContext是一个抽象概念,在渲染进程的主线程中对应于一个Document,在工作者线程中对应于一个WorkerGlobalScope。

解释完这些,那就知道相互之间的对应关系了。

  • 渲染进程:Page=1:N
  • Page:Frame=1:M
  • Frame:DOMWindow:Document(ExecutionContext)=1:1:1,这在某个时刻是成立的,因为某个时间段内涉及到iframe的locatio跳转新建frame以及frame的重用问题。
Posted on Leave a comment

Chromium Android工程迁移编译过程

本文从Chromium编译的中间产物入手深入分析、学习Chromium Android版本的工程化定制流程。初始工作依赖于Chromium的ninja、GYP构建系统,在构建完成后基于编译中间产物,迁入Android Studio作为新的构建工程,测试编译发布的过程。

注:这种编译过程除了资源文件外其他编译中间产物,都不可修改,不具备大规模定制化的可能性,仅作为熟悉编译过程和代码结构的学习、测试使用。

前提

Chromium代码结构、Android开发、Android Studio使用

编译Chromium

编译步骤可以参考Chromium团队的文章,可以选择编译目标为chrome_public_apk、content_shell_apk,本文以chrome_public_apk为例。

编译结果APK

在以chrome_public_apk为编译目标后,在经历一段时间后编译完成,在out/***文件夹内就包含了所有的编译结果和编译中间产物,其中apk在apks文件夹内,可以拉取安装一下,除了包名外其他功能与Chrome基本一致,本文的迁移目标就是在Android Studio工程下同样可以编译出这个APK,再探讨后续的源码迁移和定制工作。

工作目录

在out/***文件夹下,我们主要涉及到的文件分为三类:so、jar、resource,各自又来自不同的Chromium模块。

apks—编译目标文件目录

gen—编译过程中间产物,基本不涉及

lib.java—jar文件的主要来源,将不同模块的java文件编译后汇集在这个目录

locale—国际化的资源文件

resource-zips—资源文件的主要来源,也是Android Studio module化的主要依据

lib.unstripped—so文件目录

建立Android Studio工程

由于Chromium原有模块是基于命名空间来管理的,而且Android的R资源文件定义方式与此关联,所以需要通过Android Application、Library module的方式进行区分,同时还需要将Android Support这一类第三方库通过Gradle依赖的方式进行关联,而不是JAR+资源文件的方式。

所以基于Chromium的模块划分方式分为如下几个子module:

app—org.chromium.chrome,主App Application

ui—org.chromium.ui,Android Library

base—org.chromium.base,Android Library

components—com.chromium.components,Android Library

content—org.chromium.content,Android Library

media—org.chromium.media,Android Library

autofill—org.chromium.components.autofill,Android Library

web_contents_delegate_android—org.chromium.components.web_contents_delegate_android,Android Library

third_party—com.chromium.third_party,Android Library

tools—org.chromium.tools,Android Library

url—org.chromium.url,Android Library

builder—org.chromium.build,Android Library

net—org.chromium.net,Android Library

mojo—org.chromium.mojo,Android Library

device—org.chromium.device,Android Library

gpu—org.chromium.gpu,Android Library

printing—org.chromium.printing,Android Library

services—org.chromium.services,Android Library

skia—org.chromium.skia,Android Library

迁移编译后so

lib.unstripped目录下的所有so文件,迁入主工程的jniLibs文件中,并在CMake文件中配置引入,切记。

add_library(xxx SHARED IMPORTED)
set_target_properties(xxx PROPERTIES IMPORTED_LOCATION src/main/jniLibs/${ANDROID_ABI}/libxxx.so)

迁移编译后Jar

lib.java目录下按照已经建立好的Android Library工程分别放入libs目录下,注意仅放入非interface.jar的文件,否则可能导致duplicate class问题,同时注意JAR文件重名问题,建议以多多级目录重命名的方式导入。

迁移编译后Resource

gen/chrome/android/chrome_public_apk目录下的AndroidManifest.xml 拷贝到主工程中

resource_zips目录下也同样按照Android Library工程分别解压放入res目录下,尤其注意覆盖问题,因为同一模块下可能有同名的资源文件。android_deps、gvr目录下的资源文件不引入,后续将通过Gradle依赖方式引入。

除此之外还需要将额外的资源文件引入主工程assets目录中,并且禁用压缩。文件如下:chrome_100_percent.pak

icudtl.dat

resources.pak

snapshot_blob.bin

locales目录(包含目录这一级)

修正工程参数+Gradle

上述步骤做完以后工程不能如期运行,还需要调整几个地方,因为有些java文件是在编译过程中生成的:

gen/chrome/android/chrome_public_apk__build_config_java下的buildConfig.java

此文件主要定义启动参数等信息,这个文件主要参考信息,由于Gradle编译的过程中最终会覆盖这个文件,所以里面的所有参数需要通过Gradle配置进行定义。

gen/chrome/android/chrome_public_apk__native_libraries_java下的NativeLibraries.java

此文件主要定义了需要引入哪些so文件、版本号等信息。

运行编译

这一系列的步骤,可以通过一步步的运行报错进行修正,最后得到正确运行的编译包。最后还是那句话,这只是探索定制化过程的一小小步,Chromium项目庞大,需要长久的深入。

如果只是想体验一下迁移后的结果工程,文末附Github工程

Posted on Leave a comment

浅析宽带运营商劫持

今天请求公司主站裸域会导致莫名奇妙的跳转到yiqifa.com然后再跳转回www域的诡异问题,清理Cookies、更换DNS均无效,郁闷!在公司群里讨论了一下大概可以锁定为宽带运营商劫持,由于之前安装了Wireshark也没怎么用,正好出现类似问题,使用HTTP抓包工具分析再好不过了。关闭大部分的可能产生网络连接的软件,Start&Action!

去掉正常的请求响应包,锁定到302请求,依次向下查看,果然发现了一些猫腻。截图如下:Screen Shot 2015-04-18 at 16.07.18

96号 百度HM请求包61.135.185.140

URL:http://hm.baidu.com/h.js?ca88bf7b092f300a228b2c153a0a9fc8

97号 百度HM响应包61.135.185.140

HTTP 302 Location=http://122.141.234.60:51234/bdpop.sl.php?http://hm.baidu.com/h.js?ca88bf7b092f300a228b2c153a0a9fc8

当浏览器302跳转上述地址时响应Cookie里面增加了一个DIANSHANG=54

 

100号 跳转URL请求包122.141.234.60

URL:http://122.141.234.60:51234/bdpop.sl.php?http://hm.baidu.com/h.js?ca88bf7b092f300a228b2c153a0a9fc8

 

103号TCP超时快速重传包61.135.185.140

HTTP 304

 

106号跳转URL响应包122.141.234.60

HTTP 200

window.location=’http://p.yiqifa.com/n?k=2mLErn2OWE3lrI6H2mLErI6H6ljqWmLm6lwLWN6HWl3FWNtsrI6HkQLErnWLWlDO39MErBXpgZUfgmL-&e=c&t=http://www.wangjiu.com’;

 

117号浏览器加载上述Location请求包

 

我们所看到的劫持发生在96号请求包和97号响应包之间,大致过程如下:

1)浏览器将/h.js的请求(96号)发送到百度;

2)宽带运营商嗅探到这个请求后,会将百度的302响应进行篡改,然后转发至用户浏览器(97号),与此同时对百度TCP连接的响应直接给予超时处理;

3)此时真正的响应(来自百度)可能还未到达用户。这就导致了百度服务器认为响应没有送达用户浏览器-发起TCP快速重传(103号),但是用户浏览器在这个过程已经确认收到响应(来自宽带运营商);

4)根据响应结果,浏览器触发302跳转,然后就是我们所看到的先跳转yiqifa.com(117号)然后yiqifa将它的CPSID带上再跳转回主站(后续包)。