存档

作者存档

终于通网了

2009年9月5日 3 条评论

北京网通(哦,现在是联通了)拖了我一个星期,ADSL终于装上了。2M包年,¥1680。

网速测试结果:

到网通:
Speed_changchun

到电信:
Speed_yixing

到美国西海岸:
Speed_CA

网速看起来还可以,也许是因为半夜的缘故。

标签:

Twitter Weekly Updates for 2009-08-30

2009年8月30日 没有评论
  • [Blog] Twitter Weekly Updates for 2009-08-23 http://tinyurl.com/l9ctvd #
  • [Blog] Twitter Weekly Updates for 2009-08-23 http://tinyurl.com/kvppdy #
  • RT @iamxhu: 在看精通正则表达式这本书,里面用到的关于汽车驱动的一些原理的类比…结果让我现在更加无法理解作者要表达的意思了。// 老美的书都这样,老美最熟悉的东西之一就是汽车了,这 #
  • 被一个叫“小强–MSN机器人大赛三等奖”的MSN机器人加为好友,这个主要做联系人备份。不知道从什么时候开始,这种机器人开始流行的。 #
  • @ferryzhou "在机器上装了一个svn server" // 你马上就要掉入一个万劫不复的维护svn服务器的深渊了…… in reply to ferryzhou #

Powered by Twitter Tools

标签:

Twitter Weekly Updates for 2009-08-23

2009年8月23日 1 条评论
  • [Blog] Twitter Weekly Updates for 2009-08-16 http://tinyurl.com/n8wm4a #
  • [Blog] Twitter Weekly Updates for 2009-08-16 http://tinyurl.com/nn4h6q #
  • 貌似海缆断了,MSN上不了,众多网站速度极慢,唉。 #
  • @fbzhong @xlvector 嗯,已经到北京了。 in reply to fbzhong #
  • Gmail 向公司邮箱发信失败,报 connection timeout。国内的邮箱可以发。难道是被封了? #

Powered by Twitter Tools

标签:

Twitter Weekly Updates for 2009-08-16

2009年8月16日 没有评论
  • [Blog] Twitter Weekly Updates for 2009-08-09 http://tinyurl.com/neq2bh #
  • [Blog] Twitter Weekly Updates for 2009-08-09 http://tinyurl.com/lzfxat #
  • @ferryzhou "sprintf is not safe…" // Use snprintf 😛 in reply to ferryzhou #
  • 又有一块家里用的硬盘坏掉了,试图使用刷固件的方法软修复未果,送去所谓的数据恢复公司则是漫天要价,报价1k算是非常厚道了,还有人要价5k。硬盘症状:型号、SN都可以探测出来,但是容 #
  • [Blog] WordPress <= 2.8.3 管理员密码远程重置漏洞(及绕过方案) http://tinyurl.com/nyvfwn #
  • RT @holywen: RT: @vincnd: RT @songshinan: RT @secretaryzhang: 下次你还像贱人一样的参与募捐吗?760亿地震捐赠80%流入政府财政专户http://bit.ly/b6E7e #
  • #
  • @ferryzhou vc6 不清楚,snprintf不行换用_snprintf试试? in reply to ferryzhou #
  • [Blog] 要走了 http://tinyurl.com/nxmjq9 #

Powered by Twitter Tools

标签:

要走了

2009年8月14日 5 条评论

明天上午10点40,D32,上海再见。
就要从沪上硬盘男变成北漂了。
Journeyman就要继续去journey了。

标签:

WordPress <= 2.8.3 管理员密码远程重置漏洞(及绕过方案)

2009年8月12日 没有评论

今天刚刚看到的,WordPress 2.8.3版本之前(含)远程重置管理员密码漏洞。

关于该漏洞的信息参见这里。SuperHei的blog上面有一个简单的原理分析。

别拿我的blog做实验,我这个已经修改过了。

这个漏洞的危害不怎么大,只是用来做一些恶作剧。目前WordPress还没有新版,各位用WordPress自建blog的同仁们可以考虑自己修改 wordpress 的代码来绕过该问题:

在$(blog_root)下面,找到wp-login.php,打开,找到function reset_password。找到其中这一行:

function reset_password($key) {
global $wpdb;
$key = preg_replace('/[^a-z0-9]/i', '', $key);
if ( empty( $key ) )
return new WP_Error('invalid_key', __('Invalid key'));

将其改成:

if ( ! is_string($key) || empty( $key ) )

即可。

Twitter Weekly Updates for 2009-08-09

2009年8月9日 没有评论
  • Twitter Weekly Updates for 2009-08-02 http://tinyurl.com/n9et2w #
  • Twitter Weekly Updates for 2009-08-02 http://tinyurl.com/ngha47 #
  • Google生活频道,找租房信息,在下拉框当中选择了过滤条件之后就一直“正在处理”了。换用IE之后没有这个问题,什么时候Google也开始做IE only的东西了。 #
  • Google Reader的快捷键v弹出来的所有页面都是about:blank。还有人遇到相同的问题么? #
  • @JunChen 由嘀咕变火兔想到… // 这样会失去很多用户的,毕竟会翻墙的是少数。 in reply to JunChen #
  • RT @JunChen: RT: @ftofficer: @JunChen 由嘀咕变火兔想到… // 这样会失去很多用户的,毕竟会翻墙的是少数。//也比死了好啊 // 可以考虑Google那种方式,墙内墙外两套服务器。 #
  • 发现一个有用的服务 Read It Later http://tinyurl.com/nnbkbl #
  • 发现Error Console里面很多Permission denied for <https://www.google.com> to call method UnnamedClass.newChannel,估计是GR热键不管用的原因,root cause排查中…… #
  • @Snowprint: firefox 3.5只剩最后一个tab的时候,默认也要占一行标签栏,这个怎么修改? // Options->Tab->Always show tab bar。 #
  • 找到了GR热键v不能用的原因了,还是因为有一个扩展Force-TLS(http://bit.ly/9uFM0 #
  • Text-based sequence diagram editor: http://bit.ly/mdlqA #
  • @JunChen: “旅游行业,被过滤成旅口口业,操!” // 解决这个问题有两种方式:更好的分词或者取消这扯淡的规定。遗憾的是,很多人在做第一个,更多人在想第二个。 #
  • http://www.eeloves.com/garden/memorial/gid/307 512汶川地震遇难学生纪念园 #
  • RT @nanfangzhoumo: “集体户口让我结不了婚”: http://www.infzm.com/content/32535 // 唉,前景堪忧啊…… #
  • 编译了一个OpenInkpot的版本的固件,UI很好很强大,就是core dump多了点,而且偶尔会hang。中文支持还没跟上,评估字体中,要求支持CJK,但是要尽量小。#openinkpot #
  • http://is.gd/25L84 国务院法制办就职业技能培训和鉴定条例征意见 “用人单位应当按照职工工资总额的1.5%-2.5%提取职工教育培训经费,列入成本费用,依法在税前扣除。” // 这个强制规定的动机是 #

Powered by Twitter Tools

标签:

发现一个有用的服务 Read It Later

2009年8月5日 3 条评论

长期以来都有一个习惯,就是在上班的前面半个多小时翻看Google Reader当中的内容,最近还形成了检查Twitter上面的更新的习惯。随着订阅和follow的越来越多,信息量也在逐日上升,信噪比也在降低,有时候难得其中碰到一篇很好的文章想要细细读来,却发现手头的工作一大堆,不得不去处理,然后这篇文章就淹没在了茫茫文海之中了。后来发现Google Reader有收藏的功能,可以将喜欢的文章打上一个星标,Twitter也有收藏,也是打一个星标,浏览器,或者很多的在线收藏夹的网站都可以支持把它们和大量的噪声区分开。但是收藏夹毕竟是收藏夹,而不是要读的列表,把一篇还没有好好读过的文章就放入收藏只会让收藏夹变得越来越无用。

所以我的需求产生了:我需要一个临时的To Read列表,这个列表是动态的,随时有新的东西加入,随时有旧的东西删除。文章进入这个列表之后,会让我在将来的某个时间可以找到它,并在阅读之后将其从中删除。这个列表介于“所有文章”和“收藏文章”中间,是一个待定的状态。并且,所后的操作要尽可能的简单。而且,要可以在手机上访问到,因为,我的最大块的阅读时间是在地铁和公车上,这种时候我能用的只有手机。

然后就去找有没有类似的服务,最后还真找到了很多:一个叫做Read It Later。这是一个典型的Web 2.0的服务型网站,提供REST的API,具有Firefox插件、iPhone的插件和Bookmarklet(小书签程序),可以随时随地加入文章,后面一旦把一篇文章标记为已读,就从中删除。非常单纯也非常好用。它的Firefox插件功能很强,可以支持和Google Reader的集成。

还有一个叫做instapaper,我到现在不知道怎么来断词,inst-a-paper?这个服务也差不多,但是没有Firefox插件,只有Bookmarklet,但是我平时没有在浏览器上显示收藏夹工具栏的习惯,因此Bookmarklet对我来说没有什么意义。虽然有API,但是何必DIY呢……所以暂时不考虑这个了。还有一个Firefox插件,叫做Readeroo,基于delicious,但是没有为Firefox 3.5兼容的版本,只好放弃。

目前Read It Later已经用了两天,感觉良好。

Twitter Weekly Updates for 2009-08-02

2009年8月2日 没有评论
  • RT @myfirsttweet: @ftofficer Your 1st tweet: http://myfirsttweet.com/1st/ftofficer // 我好没有创意… #
  • twitter换IP了?twhirl不能用了,我应该怎么改hosts? #
  • Hello from word press Twitter Tools extension. 🙂 #

Powered by Twitter Tools.

标签:

计算机不存在灵异事件

2009年8月1日 2 条评论

再把这条铁律拉出来一次。

今天碰到了一个bug,服务器在运行时会core dump在一个很灵异的地方,排除这个错误的过程,以及最后发现的错误结果很具有典型性,所牵涉到的技术也很多,拿来作为Linux调试的课程挺好的。:-P

整个里面假设读者已经知道怎么用gdb,如果不知道,请参见GDB Manual

首先,很幸运的是,这个问题是可以很容易重现的,而且更重要的,有core dump。
拿到core dump之后,惯例是查看一下调用栈:(为了避免泄漏商业秘密,所有函数名,文件名什么的都用foo啊,bar啊,foobar啊,blabla啊等等代替)。

(gdb) bt
#0 0x000000eb in ?? ()
#1 0x3aa1d941 in ?? ()
#2 0x000001f8 in ?? ()
#3 0x080cf888 in foo (range=10000) at foo/foo.c:18
#4 0x080c1f29 in bar () at bar/bar.c:423
[....]

(gdb) info f 0
Stack frame at 0xbfc42548:
eip = 0xeb; saved eip 0x3aa1d941
called by frame at 0xbfc4254c
Arglist at 0xbfc42540, args:
Locals at 0xbfc42540, Previous frame's sp is 0xbfc42548
Saved registers:
eip at 0xbfc42544

(gdb) f 3
#3 0x080cf888 in foo (range=10000) at foo/foo.c:18
18 return ((u32)random()) % range;

相当的灵异,栈上的0,1,2都是,一个返回地址怎么可能是0x1f8,而且,core dump的原因是因为eip跑飞到了0xeb。到frame 3的时候看起来正常了,但是出错的地方在random这种简单的库函数上。不过既然frame 3往下的部分都是好的,我们有理由认为栈并没有被搞坏。因为GDB在显示调用栈的时候可能会把一些不正确的调用栈也显示出来,我们干脆直接看内存:

(gdb) x/10w $esp
0xbfc42544: 0x3aa1d941 0x000001f8 0x080cf888 0x09582930
0xbfc42554: 0x0833f038 0xbfc42678 0x080c1f29 0x00002710
0xbfc42564: 0x0823747f 0xb7ca168c

看加粗的部分:这里就是frame 3返回地址,而上面的东西,就是bt显示出来的frame 1和frame 2了,而frame 0就是当前的eip了:它跑飞到了0xeb。

GDB果然在显示栈的时候做了手脚。

OK,我们反汇编看看这个返回地址,到底干了什么:

(gdb) disassemble 0x080cf888
Dump of assembler code for function _Z6foom:
0x080cf85c <_Z6foom+0>: push %ebp
0x080cf85d <_Z6foom+1>: mov %esp,%ebp
0x080cf85f <_Z6foom+3>: push %ebx
0x080cf860 <_Z6foom+4>: sub $0x4,%esp
[…]
0x080cf87a <_Z6foom+30>: movl $0x0,0xfffffff8(%ebp)
0x080cf881 <_Z6foom+37>: jmp 0x80cf893 <_Z6foom+55>
0x080cf883 <_Z6foom+39>: call 0x8051f90
0x080cf888 <_Z6foom+44>: mov $0x0,%edx
[…]
0x080cf899 <_Z6foom+61>: pop %ebx
0x080cf89a <_Z6foom+62>: pop %ebp
0x080cf89b <_Z6foom+63>: ret
End of assembler dump.

看起来也没干啥,继续看调用的地址是啥吧:

(gdb) disassemble 0x8051f90
Dump of assembler code for function random@plt:
0x08051f90 : jmp *0x833f140
0x08051f96 : push $0x1f8
0x08051f9b : jmp 0x8051b90 <_init+24>

有点意思啊,random@plt,PLT是什么?PLT是Linux ELF格式可执行文件当中的一个部分,称为Procedure Linkage Table。PLT是程序为了实现Linux共享库的动态迟绑定(Lazy Binding)而引入的一种机制。关于 ELF格式、PLT,和下面要提到的GOT(Global Offset Table)的资料,可以参见下面这些链接:
The ELF Object File Format: Introduction
http://www.linuxjournal.com/article/1060
UNIX ELF File Format (PPT)

好了,言归正传,就算你不知道PLT,你也可以继续往下看。最土的办法,既然jump到一个地方,就看看这个地方是什么吧。

(gdb) p/x *0x833f140
$6 = 0x8051f96

显然这个重新跳回到了PLT当中,看下面:

(gdb) disassemble 0x8051f96
Dump of assembler code for function random@plt:
0x08051f90 : jmp *0x833f140
0x08051f96 : push $0x1f8 // 这是栈上的 0x1f8
0x08051f9b : jmp 0x8051b90 <_init+24>

又一个jmp,这次jmp到了什么地方呢?

(gdb) disassemble 0x8051b90
No function contains specified address.

这是怎么回事?因为没有对应的符号,或者这一段代码不在.text里面。不过我们还可以用其他的方法看到指令:

(gdb) x/10i 0x8051b90
0x8051b90 <_init+24>: pushl 0x833f03c // 这是栈上的另一个东西的来源
0x8051b96 <_init+30>: jmp *0x833f040
0x8051b9c <_init+36>: add %al,(%eax)
0x8051b9e <_init+38>: add %al,(%eax)

又有一个jmp,继续。

(gdb) p/x *0x833f040
$7 = 0xeb

怎么会这样?这个指针被覆写了,Jump到了0xeb,然后就core了。

看08833f040这个地址,属于GOT(Global Offset Table):

(gdb) x/10w 0x833f040
0x833f040 <_GLOBAL_OFFSET_TABLE_+8>: 0x000000eb 0x00000002 0x00000006 0xb7f4401c
0x833f050 <_GLOBAL_OFFSET_TABLE_+24>: 0x08051bd6 0xb7d8e9b0 0xb7d85260 0x08051c06
0x833f060 <_GLOBAL_OFFSET_TABLE_+40>: 0xb7d32ae0 0xb7da88d0

我们从GOT头上开始看:

(gdb) x/10w 0x833f040-8
0x833f038 <_GLOBAL_OFFSET_TABLE_>: 0x00000000 0x3aa1d941 0x000000eb 0x00000002
0x833f048 <_GLOBAL_OFFSET_TABLE_+16>: 0x00000006 0xb7f4401c 0x08051bd6 0xb7d8e9b0
0x833f058 <_GLOBAL_OFFSET_TABLE_+32>: 0xb7d85260 0x08051c06

仍然说Lazy Binding相关的东西,如果你了解ELF的Lazy Binding,你会知道GOT的前面四个字是特殊的,而其中的GOT+8的地方是_dl_runtime_resolve,而上面的最后一个jmp就是跳到这里。但是,这里却变成了0xeb。

错误的原因找到了,但是,究竟是谁干的?我们知道gdb有一个很好的feature叫做watchpoint,这个在VS当中被叫做Data Breakpoint。它们的本质是一样的,都是通过硬件来实现对某个地址的监控,你可以设定当这块内存被读、写、或者被访问(包括读写)的时候触发该断点。很好,我们就在这里加上一个watchpoint。注意watchpoint的语法,你需要在地址前面加一个*。

我们重新启动服务器,然后attach到这个进程,对出现错误的地址 0x0833f040加了watchpoint。为什么可以这么做?因为GOT在内存当中的位置是固定的,我们知道,无论你第几次启动一个程序,GOT都会被加载到同一个地址。

(gdb) watch *0x0833f040
Hardware watchpoint 2 added

然后继续执行

(gdb) c
Continuing.

然后,坐到一边喝茶去吧,等待你看到gdb被断进去。
然后,终于,等到了。

Hardware watchpoint 2: *137621568

Old value = -1208695104
New value = 235
CFoo::foobar (this=0xb1df5810) at foo/foobar.c:477
477 blablabla_func(0, sth->data.id, tmpData);
Current language: auto; currently c++

好了,我们看看这个时候的GOT:

(gdb) x/w 0x833f040
0x833f040 <_GLOBAL_OFFSET_TABLE_+8>: 0x000000eb

这个值的的确确被修改了,那么,我们看看栈。

(gdb) bt
#0 CFoo::foobar (this=0xb1df5810) at foo/foobar.c:477
#1 0x0812fa69 in CFoo::doSomthing(this=0xb1df5810, action=0xbfb93378, event=0xbfb934d0) at foo/foobar.c:1100
[...]
#10 0x08067a60 in main (argc=0, argv=0x3aa1d95a) at server.c:1289

很好,这是我们的代码,过去看看:

对应代码:
LPSOME_DATA_TYPE tmpData;
u64 some_array[MAX_SOME_ARRAY_SIZE];
size_t array_sz = MAX_SOME_ARRAY_SIZE;
[...]
tmpData->iRet = 0;
tmpData->iField01 = someVar;
tmpData->iField02 = SOME_CONSTRANT; // iField02的offset是8,也就是结构的第三个成员。
tmpData->iId = some->unit_id;
foobar(); // line 477

(gdb) p tmpData
0x833f038

OK,因为代码已经被处理过,所以逻辑可能看的不是很清楚,但是很明显,在这里,问题在tmpData,这是一个指针(请参见类型,但是变量名竟然没有任何的表明这个是个指针),没有初始化就用了。非常非常的巧合,这个变量所在的地方正好是GOT的地址,然后,在对iField02变量赋值的时候,_dl_runtime_resolve的地址被覆盖掉了。

至此,凶手已经找到了,但是这个给我们什么启示呢?

计算机没有灵异事件。

标签: , , ,