在Firefox里用光大网银

// WIP,光大网银很多javascript代码貌似在ff下就有问题,这里只是说ActiveX的问题 光大网银用了ActiveX,于是看上去很难在别的系统/浏览器下用。 但其实就结果来说,那个ActiveX控件没啥用…… 页面上有三个<object>,其中一个啥sign貌似啥都没干,另外俩负责加密密码/提交。 提交登录表单的时候,多数域都是空的。根据观察,控件就填了一个域:Password 为了观察那个控件都调了啥加密函数,找了个很好用的工具,叫WinAPIOverride。粗粗一看调了若干Crypt* API,于是缩小范围到各个Crypt*函数上。分析记录在 http://wiki.henryhu.net/wiki/CEB。 最后发现这个控件很匮乏,在用公钥加密了密码之后(公钥在JS里……),它蛋疼的生成了一个随机数加密了一下,之后有解密了一把,最后完全没用…… 而那个Password域,内容其实就是密码加密结果反过来之后base64一把…… 分析的时候有个地方很奇怪。看上去CryptEncrypt()的输入每次都一样,但是结果每次不同…… 后来自己写了个程序试试发现的确每次不同…… 再次看见网上说,加密时候会随机pad到block长度,才理解…… 接下来嘛,写个Greasemonkey脚本来帮助登录。第一步就是把那几个控件替换成我们的对象。替换完之后,可以登录过第一步了,之后手机短信验证还是不成。看console里有个错说HiddenSubmitArea不存在,于是插入一个进去…… 这货找遍各个地方都没找到,貌似也没啥用。 这样就可以过短信验证了…… 进去之后貌似还是有一些js错误,慢慢来…… 反正可以登录了。 作为库调用跟踪工具,WinAPIOverride还是挺好用的,功能上类似于ltrace,还有调试器的一部分功能,可以在库函数调用前后断下来,观察内存/寄存器等。IEinspector作为分析IE数据包的工具也不错,看上去比HttpFox功能更多…… 只是要收钱。 Greasemonkey代码: // ==UserScript== // @name cebbank // @namespace net.henryhu // @description ceb bank // @include https://www.cebbank.com/per/perlogin* // @include https://www.cebbank.com/per/prePerlogin.do?_locale=zh_CN // @version 1 // @grant none // ==/UserScript==   function reset() { console.log(’reset’); }   …

Continue reading ‘在Firefox里用光大网银’ »

在FreeBSD的Flash里输入中文

对其他系统用户这大概都不是什么问题,但是在BSD系统上有一堆问题…… 环境:FreeBSD 11, 打了个patch所以用的centos 6作为linux_base。 首先是glibc是否支持locale的问题。貌似linux_base-c6没有产生locale数据库,所以要跑build-locale-archive。 之后跑linux的locale应该就不会报错了。 其次看gtk的xim输入法模块是否启用了。找个gtk2-devel的包,从里面可以找到gtk-demo,跑他可以检验。 默认貌似只装了gtk2包,没装immodule…… 找到gtk2-immodules-xim包,把里面的im-xim.so装到/compat/linux/usr/lib/gtk-2.0/2.10.0/immodules里。这还没完,还要更新immodules列表。跑linux的gtk-query-immodules-2.0,把结果写到/compat/linux/etc/gtk-2.0/i386-redhat-linux-gnu/gtk.immodules里。之后开gtk-demo,找个文本框,右键菜单->输入法里应该有XIM了。 这时可能还是无法激活输入法。我写了个小程序检查XIM的情况: #include <X11/Xlib.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> int main() { Display *dpy = XOpenDisplay(NULL); if (!dpy) { printf("fail to open display\n"); exit(1); } if (XSupportsLocale()) { printf("Xlib supports current locale\n"); } char *p = XSetLocaleModifiers(""); printf("current locale modifier: %s\n", p); XIM im = …

Continue reading ‘在FreeBSD的Flash里输入中文’ »

用Python Descriptor弱智了一把

Python Descriptor是个有意思的功能,类似于c++里面的重载operator=和operator T,可以在你访问这个对象的时候,调你定义的__get__(),把返回值作为访问结果,在你给对象赋值的时候,调你的__set__()。 昨晚大约是在搞这么一个类: class Field(object): def __get__(self, obj, objtype): …. def __set__(self, obj, val): ….   class Data: x = Field()   d = Data()class Field(object): def __get__(self, obj, objtype): …. def __set__(self, obj, val): …. class Data: x = Field() d = Data() 然后在访问d.x的时候,没啥问题,__get__被调用了;但是给d.x赋值的时候,__set__没被调用,只是貌似给d搞上了一个域叫x,之后再访问d.x也不会调__get__了…… 在折腾了若干时间之后,最后发现问题特别弱智:Data不是new-style class。只要改成Data(object)就好了……   虽然是我弱智吧,这个语言方面也有问题吧…… 既然old-style class不支持Descriptor,为啥__get__能用__set__却不行…… 而且也没个警告之类……

关于错误信息和bug报告

有时候如果你什么错误信息都不输出,那碰到bug的人会去找相关原因;但是如果你输出了一些错误信息,人们可能会误以为那就是bug的原因。 具体来说,例如这个bug rep: https://bugzilla.mozilla.org/show_bug.cgi?id=833117 简单来说就是很多人碰见了firefox/thunderbird crash。并且他们看见了那么一个错误信息: GLib-CRITICAL **: void g_slice_set_config(GSliceConfig, gint64): assertion `sys_page_size == 0′ failed 然后他们就认为crash是因为这个错误信息引起的。 但其实那个信息只是一个warning,具体来说就是初始化某个组件的时候检查是不是已经初始化过了,如果初始化过了就给个warning并且返回。 所以这些人crash的原因可能各不相同。但是因为看见了一个公共的warning,好多人就跑来”confirm”这个bug了。 如果你啥都不说,或者说这是个warning而不是CRITICAL错误,那多半人们会意识到有别的问题,然后贴stack trace之类,而不是都觉得“我也有这个问题”……

DTrace

这两天搞了一把DTrace,貌似还挺有意思的。 DTrace是个动态跟踪工具,可以在动态环境下向内核/程序中插入探头(probe),收集处理以及显示一些信息。 其实本来搞DTrace是为了一个FreeBSD的bug。搞chromecast的时候发现,IP multicast的目标mac不对。不过后来分析代码大致定位到了出问题的文件,然后在最新代码里发现这个bug已经修了(PR 185395),于是纯粹就是学习DTrace了。 一开始在我的机子上DTrace还跑不起来,后来发现是因为我跑的UEFI分支里的内核路径有些特别,于是DTrace找不到符号。打了个补丁(dt_kernel_path.patch)之后,dtrace终于能用了。 DTrace脚本的主体是一堆事件处理函数。跑DTrace脚本的时候,系统碰到某个符合的事件,就调用对应的函数。这些函数用D语言(不是那个D语言,是DTrace自己的一种语言)写成,语法和C差不多。基本的赋值/比较都能干,不过没有循环,也没有if/then/else。能控制流程的,基本上就是每个事件自带的条件,和三元操作符,也就是?:。 虽然前面那个bug是修了,我还是搞了个简单脚本来试DTrace。我希望观察arpresolve函数的参数和返回结果,也就是那个返回IP对应mac地址的函数。 arpresolve的原型是 int arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, const struct sockaddr *dst, u_char *desten, struct llentry **lle)int arpresolve(struct ifnet *ifp, struct rtentry *rt0, struct mbuf *m, const struct sockaddr *dst, u_char *desten, struct llentry **lle) 我希望查看dst里的ip地址,和desten里返回的mac地址。 DTrace脚本如下: fbt::arpresolve:entry /execname == "ping" && arg4 != …

Continue reading ‘DTrace’ »