More servicesWindows Live
HomeHotmailSpacesOneCare
 
MSN
Sign in
 
 
Spaces home  信息产业部专业鉴定室PhotosProfileFriendsMore Tools Explore the Spaces community
Updated 4/8/2008
Updated 4/5/2008
Updated 3/20/2008
Updated 11/29/2007
Updated 10/30/2007
Updated 10/14/2007
Updated 10/16/2007
Updated 10/4/2007
Updated 10/11/2007
Updated 6/12/2008
Updated 10/11/2007

信息产业部专业鉴定室

August 05

又被点名了

又被考察团团长点名了,而且问题多达三十八个,真三八啊。

没的说,捧场。

1.当你不高兴的时候,你喜欢做什么?
  开骂然后加仓。

2.最让你迷惘的事情是什么?
  为啥股市跌成这样嗫?

3.2008年最大的心愿是什么?
  风调雨顺国泰民安股市大涨买个破房。

4.你现在住在哪个城市,如果能够选择,你希望住在哪里?
  上海。布拉索夫。

5.如果现在可以让你随心所欲去旅行,你想去哪?
  也想去太空。

6.你相信命运么? 你会为了改变自己的命运抗争么?
  不可知论,也就没抗争的说法了。

7.最不喜欢什么类型的人?
  欠钱不还还大找借口的废话特多的男人。

8.会不会做饭?你希望你的伴侣会做饭吗?
  会。希望。

9.感触最深的一本书或影片的是?为什么?
  红楼梦

10.你会选择你爱的人还是爱你的人?为什么?
  选择两个行不?

11.当你遇到跟你很合不来的同事或者同学时(就是很不服你所做的事情和看法的那
种)而且你们还要经常在一起干活,你会怎样处理?
  一边合作一边鄙视它。

12.你最喜欢你伴侣的什么?如果没有,你希望你的伴侣具有什么品质。
  胸围。

13.给你一种能力去改变(或提升)自己,你选择什么?
  选择能给予提升能力的能力。

14.你会出于什么样的理由结婚? 或者是出于什么样的理由单身?
  八月十八星期八和九月九的酒。

15.和恋人分手了你会把对方的手机,MSN,QQ删掉么,如果删掉为什么?
  不会。

16.喜欢的人是谁?
  美女。

17.说说你童年的梦想和现在的理想。
  玩游戏机。玩模拟器。

18.你觉得,到目前为止,你在多大程度上对生活是满意的?
  除了钱不满意其他都满意。

19.你最欣赏的人是?为什么?
  芙蓉姐姐。她的勇气谁比的上?

20.你有非常非常贴心的朋友吗?
  有。

21.如果可以规划你的人生,你会选择去规划还是顺其自然?
  顺其自然地规划。

22.给你最深感动的一件事是什么?
  公元钟熄灭的那一刻……

23.喜欢孤单的感觉么?为何?
  不喜欢孤单也不喜欢嘈杂。

24.一年四季,你最喜欢哪个季节
  秋天。

25.喜欢养宠物么,如果有条件的话?
  不喜欢养只喜欢玩。

26.有的时候你非常想得到的东西,得不到,怎么想?
  使劲想。

27.对自己的缺点用不超过10个字总结一下
  一二三四五六七八九。

28.你最喜欢的明星是谁?
  现在没了。

29.用一种颜色来代表你现在的生活状态,那么它是哪种颜色呢?
  女色。
  
30.现在你最想做的一件事情是什么?
  马上治好口腔溃疡。

31.对自己的样貌作一个评价吧。
  玉树临疯。

32.喜欢苦的东西么,为什么?
  不喜欢。

33.民已食为天,你最喜欢的水果和菜是什么?
  西瓜。菜太多说不来。

34.最喜欢说的口头禅?它的典故或来源?
  tmd又跌了!来自最近一年的股市。

35.感觉自己最讨人喜欢的地方是?(不可以说你不讨人喜欢)
  BT+猥琐

36.当你心情低落时,是如何做调整的?
  疯狂加仓

37.下辈子想做什么?
  证监会主席

38.外面晴空万里,你想做点什么事情?
  下班回家睡觉。

July 31

乱捏联话之一

国画大师徐悲鸿当年曾在浙江丽水作画顺便寻访故人,后未逢而怅然远游。然故人亦病,后托信于徐,信辗转至藏外大吉岭,彼时大雪封山人难行,且信无地址,回复亦不能,唯无可奈何尔。
当时,好事者曾以“悲鸿绘丽水”出联,后闻大吉岭之事,遂对“喜马拉雅山”,无情流水,严丝合缝,真他妈的牛。
July 25

大饼油条四明治

三个角的是三明治,四个角的自然就是四明治了,但一个自产的四明治吃不饱,又补了一份大饼油条,然而后者吃着总没前者爽。早上七点提早起床折腾面包香肠榨菜黄瓜色拉酱凑成四明治,这样新奇的口味以前是没尝过的。人要会感恩会知足,要提前历练做房奴的穷困日子,早晚这四明治会被磨光棱角变成∞明治的。
June 30

周老虎终于被抓了

一副很牛很粗俗的对联:
 
顶叶纸虎啸山林,
卧槽泥马勒戈壁。
June 20

转贴:歪批《三国》

歪批《三国》

甲: 说相声的谈今论古,《三国演义》、“东、西汉”、“红楼”、“聊斋”。《水浒传》,什么书都看。
乙: 要提起“三国”,我可知道得最彻底。
甲: 你对“三国”有研究?请问你“三国”里头所有的人物,谁最有能耐?
乙: 能耐最大的就是诸葛亮。
甲: 诸葛亮有何能耐?
乙: 诸葛亮仰面知天文,俯察知地理,明阴阳,懂八卦,运筹帏幄之中,决胜千里之外。抱膝危坐,自比管仲、乐毅;笑做风月,未出茅庐就知有三分天下。诸葛亮乃一国军师,可称得起世之奇才!《三国》里就数诸葛亮能耐。
甲: 诸葛亮要是能耐大,七星灯借寿怎么会死到司马懿手里呢?
乙: 这个……那就是司马懿能耐。
甲: 司马懿有什么能耐?
乙: 司马懿乃是领兵大元帅,统带千军万马,执掌生杀之权,攻、杀、战、守,抽、撤、盘、环,无一不晓。就拿取街亭说吧,不用自己去,派张郃一战成功。司马懿多有能耐!
甲: 司马懿要是有能耐,得了街亭,怎么还叫赵云追得满市街乱跑?
乙: 那么这一说是赵云有能耐。
甲: 赵云有什么能耐?
乙: 赵云是常胜将军,百战百胜,长坂坡前一场大战,单枪独马,敌住曹操八十三万人马,闯出重围,救出阿斗。那是多大的能耐!
甲: 赵云要有能耐,到了当阳桥,为什么还让张飞给断后哪?
乙: 那是张飞有能耐。
甲: 张飞要有能耐,虎牢关战吕布,怎么哥儿仨打人家一个?
乙: 那是吕布有能耐。
甲: 吕布要是有能耐,在白门楼怎么会死在曹操手里?
乙: 那是曹操有能耐。
甲: 曹操有能耐,火烧战船,怎么把胡子都烧没啦?
乙: 要照你这么一说……
甲: 谁有能耐?
乙: 你有能耐。
甲: 我有什么能耐?
乙: 你把我问住了,还没有能耐吗?
甲: 你就知道看人家优点,你不知道人家的缺点。
乙: 缺点我也知道,就是不说。
甲: 为什么?
乙: 得罪那个人干什么?
甲: 你说这话不对,做事情要站稳立场,优点应该提出表扬,缺点应该提出批评。
乙: 噢,优点提出表扬,缺点提出批评,话虽然很对,可是我上哪儿找诸葛亮去呀?
甲: 我没让你找诸葛亮,我是说事情应该这样做。如此看来,你对《三国演义》还是没什么研究。请问你《三国演义》是谁作的?
乙: 罗贯中。
甲: 什么人批过?
乙: 有好几位哪,金批——金圣叹;御批——四帝乾隆;毛批——毛宗岗。
甲: 还有。
乙: 还有什么?
甲: 还有侯批!
乙: 什么侯批?是古人吗?
甲: 不,是今人。
乙: 姓什么叫什么?
甲: 侯宝林。
乙: 噢,就是你呀!
甲: 对啦!
乙: 金批,御批,毛批我全看过,您这侯批我可没看见过。
甲: 可以买一本看看。
乙: 书店有吗?
甲: 不好买。
乙: 缺货?
甲: 不,还没出版哪。
乙: 废话!没出版说它干什么!
甲: 我这可不敢说是批“三国”。
乙: 是什么?
甲: 我这叫与读者共同讨论。
乙: 怎么?
甲: 你也爱看“三国”,我也爱看“三国”,我们在“三国”里头提出点问题,互相研究研究,讨论讨论。
乙: 那好哇!“三国”里头有不知道的,你就问我。
甲: 噢!你都知道?我问你为什么叫“三国”?
乙: 北魏,西蜀,东吴,此为三国。
甲: 十八路诸侯讨董卓,为什么不叫十八国哪?
乙: 那个……他们都没成事。
甲: 三分归一统,为什么不叫一国?
乙: 那不是以后吗?我说的不对吗?那你说为什么叫“三国”?
甲: “三国”里带“三”的节目多,故此叫“三国”。
乙: 全有什么哪?
甲: 拿过来“三国”您看,头本第一回那个目录里头就有个三字。
乙: 有什么?
甲: “宴桃园豪杰三结义”,有三没有?
乙: 有啊!还有什么?
甲: 最后一回:“降孙皓三分归一统”,有三没有?
乙: 就两个三呀?
甲: 还有哪:“虎牢关三战吕布”、“屯土山关公约三事”、“刘玄德三顾茅庐”、“陶公祖三让徐州”、“荆州城公子三求计”、“袁曹各起马步三军”、“三江口曹操折兵”、“定三分隆中决策”、“三江口周瑜纵火”、“诸葛亮智取三城”、“三气周瑜”、“三擒孟获”……
乙: 七擒孟获!
甲: 三擒!
乙: 怎么是三擒哪?
甲: 先有三擒,然后才有七擒,你得经过三擒,才能到七擒哪,不能由二擒就蹦到四上去!
乙: 噢!这么个三擒哪?还有什么?
甲: 三出祁山!
乙: 六出祁山!
甲: 二三得六。
乙: 小九九哇!
甲: 三伐中原。
乙: 哎,九伐中原!
甲:、乙 三三见九。
乙: 我就知道嘛。
甲: 这是明三,“三国”里还有暗三。
乙: 什么叫暗三?
甲: “三国”里有三妻,三不明,三不知去向,三头驴,三张断三桥,文官三丑,武将三俊,三个不知道,还有三个做小买卖的。
乙: 你说这是什么呀?这么乱!你说这话我好有一比。
甲: 比从何来?
乙: 蛤蟆跳井——
甲: 怎么讲?
乙: 不懂(扑通)。
甲: 不懂不要紧,我可以给你讲。
乙: 我先问你什么叫三妻?
甲: 妻是夫妻的妻。头一个是猎户刘安杀妻供主。
乙: 第二个?
甲: 刘备抛妻。刘备要不抛妻,没有《回荆州》。
乙: 第三个?
甲: 吕布贪妻。吕布要不贪妻,没有《白门楼》。
乙: 什么叫三不明?
甲: “三国”里有三个人,他们的姓名不明。
乙: 头一个?
甲: 是有姓无名。
乙: 谁?
甲: 乔阁老。
乙: 噢,东吴的,他不是姓乔名阁老吗?
甲: 不对,阁老是皇亲,说白话就是老丈人,他就是有姓没名。
乙: 有名。
甲: 叫什么?
乙: 乔玄。
甲: 你是在“三国”里头看到的?
乙: 不是。
甲: 哪儿学来的?
乙: 听戏听来的,《甘露寺》里头有。
甲: 我早就知道你是听戏听来的。
乙: 怎么?
甲: 唱戏到台口要报名,就是介绍剧中人物。不能报乔阁老,阁老是老丈人。光报姓不报名也不好听,“老夫,乔——”乔什么呀?因此戏剧演员给他编出个名字叫乔玄。
乙: 他为什么叫乔玄哪?
甲: “三国”原文上没有,历史纲鉴上查不着,这个名字还在那悬(玄)着哪。
乙: 噢,这么个乔玄哪。第二个是谁?
甲: 第二个有名无姓——貂蝉。
乙: 哎,貂蝉有姓。
甲: 姓什么?
乙: 姓貂名蝉。
甲: 不对,她是王司徒的一个歌姬,原文上没姓,就叫貂蝉,是有名无姓。
乙: 第三个人是谁?
甲: 就是“张翼德怒鞭督邮”这是督邮无名无姓。
乙: 哎!那不是姓督名邮吗?
甲: 不对,督邮是当时的官衔,就相当于现在的税务局长。督邮是无姓无名,他刚一露头没等报名,就叫张飞给打回去了。以后再不提他了。我看这个人就是为挨打而来的。
乙: 噢,这是三不明。什么叫三不知去向呢?
甲: 对,有三不知去向,貂蝉不知去向,徐庶不知去向,督邮被打完了可也不知去向。
乙: 啊,还有什么三头驴?
甲: 对,“三国”里头有三头驴。
乙: 头一头?
甲: 吕伯奢骑驴沽酒。
乙: 哎,不错,有。第二头?
甲: 诸葛亮的岳父黄承彦有一头驴。
乙: 他哪有驴呀?
甲: 有啊,在三顾茅庐的时候,不是黄承彦骑驴过小桥吗!有一首《梁父吟》,那里就有一头驴。
乙: 在哪有?
甲: 我念念你听:“一夜北风寒,万里彤云厚,长空雪乱飘,改尽江山旧,仰面观太虚,疑是玉龙斗,纷纷鳞甲飞,顷刻遍字宇宙,骑驴过小桥,独叹梅花瘦。”这里边不是有头驴吗?
乙: 第三头?
甲: 诸葛亮有个哥哥诸葛瑾……
乙: 对!东吴的谋士,号叫子瑜。
甲: 他长的是什么相貌?
乙: 他长的是驴脸。
甲: 哎,长脸膛,大下巴,长得跟驴一样。哎,他,他,他就算一头驴。
乙: 啊?拿人比驴,这叫什么话呀!
甲: 哎!他是有一头驴。有一天东吴的孙权大宴群臣,内中就有诸葛子瑜,他是带他的儿子去的。他儿子叫诸葛恪,那年才七岁,一块儿去了。在赴宴的时候,文武百官跟诸葛子瑜开玩笑,一看他那脸长得跟驴脸似的,就拉过来一头驴,在那驴脑门上写了四个字:“诸葛子瑜”,大家一看,哄堂大笑。你说诸葛子瑜急又不能急,这是开玩笑;不急吧,当众受辱。正在难受的时候,他儿子诸葛恪一看,他爸爸面红耳赤,小孩子有办法,拿起笔在驴头上那四个字底下又添了两个字。
乙: 什么字?
甲: “之驴”这样一念就好听了:“诸葛子瑜之驴”,说明这头驴是他们家的。吃完喝完了,还把这头驴拉他们家去啦。
乙: 噢,这是三头驴。那三张断三桥哪?
甲: 第一,张飞喝断当阳桥。
乙: 二?
甲: 张任断过金雁桥。
乙: 三?
甲: 威镇逍遥津,张辽断过小石桥。
乙: 文官三丑?
甲: 夏侯敦是猴相,诸葛瑾是驴相,庞统是七孔朝天,这是文官三丑。
乙: 武将三俊哪?
甲: 吕布、赵云、周瑜,这是武将三俊。
乙: 还有什么?
甲: 还有三个不知道,问谁谁也不知道。
乙: 你不知道问我呀,我全知道。
甲: 你知道?我问你:周瑜他姥姥家姓什么?
乙: 不知道。
甲: 诸葛亮他姥姥家姓什么?
乙: 不知道。
甲: 张飞他姥姥家姓什么?
乙: 也不知道。
甲: 哎,这就是三不知道。你不知道,大家也不知道。
乙: 那你知道吗?
甲: 我当然知道。
乙: 周瑜他姥姥家姓什么?
甲: 姓纪。
乙: 诸葛亮他姥姥家姓什么?
甲: 姓何。
乙: 张飞他姥姥家姓什么?
甲: 姓吴。
乙: “三国”原文没有哇!
甲: 有,周瑜在临死的时候,仰面长叹,说了一句。
乙: 说什么?
甲: 说:“既生瑜而何生亮?”这就是说,纪氏老太太生的周瑜,何氏老太太生的诸葛亮。
乙: 哎,不对,人家是说既然生周瑜何必再生诸葛亮!
甲: 我就这么体会!
乙: 好,那张飞他姥姥家为什么姓吴哪?
甲: 你没看老太太管小孩儿,不是有那么一句话嘛:“你这个孩子,总出去惹祸!真是无(吴)事(氏)生非(飞)!”这就是吴氏老太太生的张飞!
乙: 噢,这么讲啊,像话吗!还有什么?
甲: 还有三个做小买卖的。
乙: 第一个?
甲: 刘备卖过草鞋。
乙: 不错,织席贩履嘛!第二个?
甲: 张飞卖肉。
乙: 对,屠户出身嘛。第三个?
甲: 你没听明白吗?刘备卖草鞋。
乙: 唉!我问你第三个?
甲: 啊!是啊!张飞卖肉。
乙: 哎!你等一等。第一个是刘备卖草鞋,第二个是张飞卖肉,这第三个哪?
甲: 啊,有啊,你别着急呀!
乙: 第三个?
甲: 第三个……哎,赵云……
乙: 赵云卖什么呀?
甲: 赵云卖年糕嘛!
乙: 赵云多会儿卖年糕?
甲: 你看过《天水关》这出戏吗?
乙: 看过呀!
甲: 《天水关》这出戏,姜维在校场一传令,那几句(流水板),就把赵云卖年糕给唱出来啦。
乙: 怎么唱的?
甲: (唱)“这一班五虎将俱都丧了,只剩下赵子龙老迈(卖)年(年)高(糕)。”他老卖年糕!
乙: 去你的吧!

June 02

诡异!

前段时间台式机出毛病了,偶尔跑着跑着就死机,死机的症状一般是硬盘灯持续亮着,然后就蓝屏。开始以为中毒了或者中木马了,杀了一回没见着。后来逐渐感觉到是进行比较大的硬盘操作时死机的概率大些,比如复制一电影等,便怀疑杀软的监视文件的功能有问题,于是卸掉卡巴裸奔,情况果然好些,但仍然会死。接着怀疑是硬盘文件系统坏了,用CHKDSK能查出几个问题,也能修复,但下回仍旧会死机。于是凄凉地怀疑硬盘可能坏了,只有凑合着继续用。终于有一次死机后Windows少了n多系统文件,CHKDSK也找不回来了,只有重装系统。重装后好了很多,但陆续装上一堆应用软件后,死机的概率越来越大,总怀疑有木马病毒,用IceSword查内核,有几个挂接NTDLL的,是DaemonTool虚拟光驱与360安全卫士。尝试着卸掉360再裸奔,果然几天不死机了,以为找到了原因,沾沾自喜的同时还很专业地抱怨360的内核驱动兼容性差。岂料过几天又开始死了,晕!再卸掉DaemonTool,又安静了几天,这回不敢乱抱怨了,还是静观其变为好。果然过了几天老毛病又开始犯,而且越来越厉害,大有又要重装之势。幸亏上回刚重装好一堆东西比较稳定时做了一个几个G的Ghost,花十几分钟恢复回来也不太费事。一恢复又好些,但跑着跑着又有老毛病重犯的趋势,又猜可能天热了CPU过热引发死机,下了个CPU COOL,看温度也不过20多度,不像,不过为保险起见还是拆开机箱拿风扇吹,但仍旧无效。快抓狂时在敞开的机箱里瞎捣腾,发现主板的串口硬盘线略有松动,难道是它???于是插紧了一下,重启,没死机;等了等,还没死;折腾折腾,仍然不死;陆续玩了半个月了,死机蓝屏的迹象一次都没复现。神啊,老子以后要是被查出有啥神经方面的毛病,就是这个硬盘线插头折腾的!
May 23

转贴韩寒的一段话

转贴。
“另外,我还想继续说一个事情,我依然坚持我的向有关部门捐款为0,这是我个人的选择。我也依然非常反对逼捐和搞捐款的排名,很多人在背后冷言冷语,有些个人和公司出于善心,追加了捐款,那些人就自以为是自己的功劳,并把这些钱下意识记在自己的账上。他们都是道德的小人,自己制定道德的准绳。在大家都忙着做善事没空的时候,他们闲着,指指点点,我朋友说,他发现这些人都喜欢重复发言,反复变换马甲,在各个地方说一样的风凉话,足以见得他们是闲到一种什么样的程度。他们体力和脑力都非常充沛活跃,网监部门应该把他们登记在案,以后有灾难的时候派他们上场。
前一阵子盛传的肯德基没捐款,麦当劳没捐款,我当时就和朋友说,首先,他们如果没捐款,也不应该受到指责,这是他们的权利,其次,肯德基可能是以百胜的名义捐的。因为这些我么熟知的国际快餐都属于百胜集团。事实证明,的确是以百胜集团的名义捐款了一千多万,而麦当劳也是。但是,一些丐帮人员居然在某一个城市,去肯德基麦当劳门前闹事,这才是添乱和丢脸。
一旦捐款变味,会让做善事者心里很不舒服。比如这次地震,第一批捐款的人应该是最积极的,但到最后,他们都会因为数额少而被人骂。很多人也会借机对自己不喜欢的人传播谣言,这些都是对好心人的打击。
做善事者,内心一定要得到宽慰,如果做了善事还要备受一些什么都没做的人的指责,好人会越来越少,做事会越来越谨慎。”
May 15

地震

川汶一震罢,烽烟满地愁。
丹景成绝景,泥流伴石流。
天道无刍狗,人伦有方舟。
勉尽些微事,来日祭荒丘。

April 25

Sparc 平台上的 FlexLM 7.0 用户滤波函数分析

Sparc 平台上的 FlexLM 7.0 用户滤波函数分析
 
作为一个比较老旧的保护工具,FlexLM的初级保护已经被分析的差不多了,默认情况下内存中能截到明文的签名,这点很多高手的文章中都有提到。但俺近日在分析一款SunOS Sparc平台下的FlexLM 7.0时遇上了 user_crypt_filter 机制,这种机制会对签名加以变形运算,导致内存中不会出现明文,给破解的捕获增加了一些难度。后来参考Nolan Blender大牛的文章,总算破掉了这个用户滤波函数的保护,在此写出来总结一下供有相同需要的朋友参考与讨论。
本文没有提到到具体的软件名称,也不涉及到Feature、Vendor与版本号的跟踪捕获,甚至也和抓取VendorKey和加密种子等没有关系。另外Sparc平台的汇编可能大伙都不熟悉,这儿尽量多加以解释。
工具:DDD+GDB、IDA
 
一、按传统方法定位明文比较处。
 
参考laoqian的《制作Flexlm license总结》的文章,以及laowanghai的《LabWindows CVI 8.0》中列出来的详尽x86汇编代码,通过在IDA中搜索常数66D8B337,可以定位到几个地方。以下是laowanghai的《LabWindows CVI 8.0》文章中列出的部分x86的代码供参考:
 
105C9CDB      894D F4                    mov dword ptr ss:[ebp-C],ecx
105C9CDE    ^ E9 EEFAFFFF                jmp CVI_1.105C97D1
105C9CE3      817D 18 37B3D866           cmp dword ptr ss:[ebp+18],66D8B337
105C9CEA      0F85 96000000              jnz CVI_1.105C9D86
105C9CF0      33D2                       xor edx,edx
……
105C9D86      C785 78FEFFFF 08000000     mov dword ptr ss:[ebp-188],8
105C9D90      817D 18 37B3D866           cmp dword ptr ss:[ebp+18],66D8B337
105C9D97      75 0F                      jnz short CVI_1.105C9DA8
……
105C9EB0      8B95 30FEFFFF              mov edx,dword ptr ss:[ebp-1D0]
105C9EB6      81E2 FF000000              and edx,0FF
105C9EBC      8B85 7CFEFFFF              mov eax,dword ptr ss:[ebp-184]
105C9EC2      33C9                       xor ecx,ecx
105C9EC4      8A88 98358A10              mov cl,byte ptr ds:[eax+108A3598]
105C9ECA      3BD1                       cmp edx,ecx                     ; 与正确SIGN逐字节的比较
 
这里,比较之处前面一个and edx,0FF比较的显目,可以作为一个小标志。
类似的,在我们对付的SPARC平台下的软件,其比较代码也类似:
 
 loc_3515CC:                             ! CODE XREF: sub_3508E4+6B0j
.text:003515CC                                         ! sub_3508E4+CE0j
.text:003515CC                 ld      [%fp+arg_54], %o5
.text:003515D0                 set     0x66D8B337, %o7 ! 绝对是这儿的常数
.text:003515D8                 cmp     %o5, %o7
.text:003515DC                 be      loc_3515EC
.text:003515E0                 nop
……
 loc_351684:                             ! CODE XREF: sub_3508E4+D00j
.text:00351684                 mov     8, %o7          ! 也是这儿的常数
.text:00351688                 st      %o7, [%fp+var_8]
.text:0035168C                 ld      [%fp+arg_54], %l0
.text:00351690                 set     0x66D8B337, %l1
.text:00351698                 cmp     %l0, %l1
.text:0035169C                 be      loc_3516AC
.text:003516A0                 nop
……
.text:003517F8 loc_3517F8:                             ! CODE XREF: sub_3508E4+EE0j
.text:003517F8                 ld      [%fp+var_4_idx], %o3
.text:003517FC                 set     byte_4DD515, %o4
.text:00351804                 ldub    [%o3+%o4], %o5  ! ldub取一位字节,相当于同时做了上面的and 0xff了
.text:00351808                 ldub    [%fp+var_180_oursign+3], %o7
.text:0035180C                 cmp     %o7, %o5        ! 是这儿的比较
.text:00351810                 bne     loc_351820
.text:00351814                 nop
.text:00351814
 
由x86与Sparc的汇编代码对比可以看出,.text:0035180C处确实是我们传入的伪造签名值(我传的是1234567890AB)与正确签名值的比较之处,byte_4DD515这个地址所指的一片内存区域,应该是我们需要的正确签名。于是在0035180C处下断,第一次来到此处时查看0x4DD515地址的内容,得到六个字节EEB53723B248。想当然地拿它放到license文件里头一试,很不幸,通不过。
于是开始了摸索,在0035180C之前下断,逐步来,发现0035180C之前有一处很关键的代码:
 
.text:003517CC loc_3517CC:                             ! CODE XREF: sub_3508E4+ED8j
.text:003517CC                 ld      [%fp+arg_44_job], %o0
.text:003517D0                 ld      [%o0+0x234], %g1 ! Job偏移234处是啥?原来是user_crypt_filter函数地址。
.text:003517D4                 ld      [%fp+var_4_idx], %o1
.text:003517D8                 set     byte_4DD515, %o2
.text:003517E0                 add     %o1, %o2, %o1   ! char*,指向正确的未filter的内容
.text:003517E4                 ldub    [%fp+var_180_oursign+3], %o3 ! 我们的sign的字符
.text:003517E8                 ld      [%fp+arg_44_job], %o0 ! Job!
.text:003517EC                 ld      [%fp+var_4_idx], %o2 ! Index?
.text:003517F0                 call    %g1             ! 3323a0,user_crypt_filter,结果放在o1指的内容
.text:003517F4                 nop
 
那个call %g1是对解出的明文密码进行的一次变换。刚才抓到的六个字节EEB53723B248,其中EE是已经经过了第一次变换的结果,变换出来的结果和我们传入的伪造签名的第一个字节12不一致,因此出错。如果在003517F0之前下断查看byte_4DD515的内容,则可得到未经变换的第一个字节值。抓出的初始的正确签名值是C1B53723B248,但如果拿这个签名值去license文件里头试的话仍然通不过,因为这串签名值还会经过一次变换,这个变换便是臭名昭著的user_crypt_filter:用户滤波函数。
 
二、分析用户滤波函数
 
查FlexLM的资料得知,user_crypt_filter是对签名字符进行的进一步可逆变换机制,包括生成时的user_crypt_filter解码函数和user_crypt_filter_gen编码函数。我们的任务,是根据user_crypt_filter函数的实现,反推出user_crypt_filter_gen函数来。
从代码中以及从大牛们的破解资料中可得知,user_crypt_filter 附近的调用机制基本上是:
 
for (i = 0; i < j; i++) /* compare user-input and real checksums */
{
  ......
  if (user_crypt_filter)
    (*user_crypt_filter)(job, &x, i, y[i]); // 使用了滤波函数进行进一步的对比!
   
  if (x != y[i])
    return 0;
}
 
而网上查到的很多中文文章中的FlexLM都是没用user_crypt_filter的,也就是user_crypt_filter为false而跳过(*user_crypt_filter)指针所指函数的变换,因此下面的x != y[i]便是正确签名字符与我们输入的伪造签名字符的明文比较。而我们碰到的情况是会调用user_crypt_filter的函数的。
 
user_crypt_filter 的函数原型为:
user_crypt_filter(job, char* KeySign, int index, char OurChar);
 
其中job在函数体内基本无用。KeySign为传入的未变换的签名的地址(下面称为原始签名),index为此字符在密文中的位置,如签名为1234567890AB,则12的index为0,34的为1,以此类推。
 
user_crypt_filter是逐个处理字符的,它根据未变换的原始签名字符、此字符的位置、以及我们传入的伪造签名字符进行一系列的运算返回一个字符,这个字符必须等于我们传入的伪造签名字符。这么说可能有点绕,换种说法就是:未变换的原始签名字符、此字符的位置、以及变换后的签名字符三者必须符合一定的运算法则,user_crypt_filter函数拿我们传入的伪造签名字符作为验证来和原始签名字符参与运算,如果运算通过,则表示伪造的签名字符是正确的变换后的签名字符,那么就将此正确的签名字符返回供上层代码(x != y[i])比较,其实此时已经无需比较了。
 
可以看出,user_crypt_filter函数中不会出现我们需要的正确签名字符,只有当我们传入的伪造签名字符等于正确签名字符时才会验证通过,才会返回正确签名字符。下面我们要搞清楚的是user_crypt_filter函数究竟对未变换的原始签名字符、此字符的位置、以及我们传入的伪造签名字符三者进行了怎样的变换,从而努力反推出来如何根据未变换的原始签名字符以及此字符的位置计算正确的签名字符。
 
user_crypt_filter函数非常长,从.text:003323A0 到.text:003374B8,反汇编代码有七千多行,很是吓人。不过经过大致浏览,可以看出它是根据传入的Idx的范围0到19有比较重复的20大段代码,20大段里头每大段会对字符进行异或并对其8位进行处理,共20加160处变换,搞明白了它做啥就好办了。
 
首先是将传入的字符异或,比如我们传入的Idx是0的话:
 
.text:003324E0                 ld      [$XADqrkBrM9j3y7__num0], %l0
.text:003324E4                 cmp     %l1, %l0
.text:003324E8                 bne     loc_332504
.text:003324EC                 nop
.text:003324EC
.text:003324F0                 ldub    [%fp+var_2_GoodChar_xor], %l2
.text:003324F4                 sethi   %hi(unk_496800), %l0
.text:003324F8                 ldub    [$XADqrkBrM9j3y7__x_0], %l1 !
// 取出num0对应的某常量值(x_0)和GoodChar一异或,存入局部变量 GoodChar_Xor。
.text:003324FC                 xor     %l2, %l1, %l0
.text:00332500                 stb     %l0, [%fp+var_2_GoodChar_xor]
根据传入的Idx的不同,将未变换的原始签名字符和某一值进行异或,得到临时变量GoodChar_xor。
然后启用另外一个Char变量,这里命名为TmpChar,用来挨个检查GoodChar_xor的位,比如这儿是检查其中一位:
 loc_332740:                             ! CODE XREF: user_crypt_filter+384j
.text:00332740                 ld      [%fp+arg_4C_Idx], %l1
.text:00332744                 sethi   %hi(unk_496800), %l0
.text:00332748                 ld      [$XADqrkBrM9j3y7__num8], %l0
.text:0033274C                 cmp     %l1, %l0
.text:00332750                 bne     loc_3327BC // 如果此字符的index是8,那么检查
.text:00332754                 nop
.text:00332754
.text:00332758                 ldub    [%fp+var_2_GoodChar_xor], %l2
.text:0033275C                 sethi   %hi(unk_496800), %l0
.text:00332760                 ld      [$XADqrkBrM9j3y7__bit3], %l1
.text:00332764                 andcc   %l2, %l1, %l0
.text:00332768                 be      loc_332784  // 如果异或后的字符的bit3位是1 则执行下面的,
.text:0033276C                 nop
.text:0033276C
.text:00332770                 ldub    [%fp+var_1_TmpChar], %l2
.text:00332774                 sethi   %hi(unk_496800), %l0
.text:00332778                 ld      [$XADqrkBrM9j3y7__bit4], %l1 
// 如果异或后的字符的bit3位是1,则将临时变量TmpChar的bit4置为1,
.text:0033277C                 or      %l2, %l1, %l0
.text:00332780                 stb     %l0, [%fp+var_1_TmpChar]
.text:00332780
.text:00332784
.text:00332784 loc_332784:                             ! CODE XREF: user_crypt_filter+3C8j
.text:00332784                 ldub    [%fp+var_1_TmpChar], %l1
.text:00332788                 sethi   %hi(unk_496800), %l0
.text:0033278C                 ld      [$XADqrkBrM9j3y7__bit4], %l2
.text:00332790                 and     %l1, %l2, %l1
.text:00332794                 ldub    [%fp+var_3_OurChar], %l0
.text:00332798                 and     %l0, %l2, %l0
.text:0033279C                 cmp     %l1, %l0
.text:003327A0                 be      loc_3327BC // 然后检查我们伪造的签名字符的bit4,和TmpChar的bit4是否相同。
.text:003327A4                 nop
.text:003327A4
.text:003327A8                 ld      [%fp+arg_48_charX], %l1
.text:003327AC                 ldsb    [%l1], %l0
.text:003327B0                 btog    -0x3E, %l0 // 在俩bit不同的情况下,返回垃圾值3E
.text:003327B4                 ba      locret_3374B8
.text:003327B8                 stb     %l0, [%l1]
.text:003327B8
 
以上是对Index为8时的未签名字符bit3位的判断检查过程:如果GoodChar_xor的bit3是1,则TmpChar的bit4也置一,因为TmpChar原始为0,因此bit4原始也为0,所以这一步就是把GoodChar_xor的bit3搬移到了TmpChar的bit4上。
然后TmpChar的bit4和我们传入的伪造签名字符OurChar的bit4进行比较,相同的话这位检查通过,继续检查下一位,否则返回一个垃圾值-0x3E用以迷惑俺们。总的来说,这步就是检查异或后的GoodChar_xor的bit3是否等于伪造签名字符的bit4,等的话才通过。
参考Nolan Blender的文章,这里检查一个bit的过程用C代码描述如下(这里是index为0时检查GoodChar_xor的bit2与TmpChar的bit5是否相等的情况):
 
if (idx == num0)
{
  if (GoodChar_xor & bit2) TmpChar |= bit5;
  // 如果inc_c的2置位,那么把另外一个C的5置位,相当于2位换到5位去
  if ((TmpChar & bit5) != (OurChar & bit5)) { *KeySign = 0xxx; return; // 不等则返回垃圾}
  // 其实就是GoodChar_xor的bit2要和输入签名字符的bit5相等。
}
 
以下还有很多类似的检验,对于每一个index,都要检查GoodChar_xor的8个bit和OurChar的8个bit是否相同,但这8个bit并不是顺序上一一对应,而是乱序(permute)了。比如GoodChar_xor的bit0应该等于OurChar的bit3、GoodChar_xor的bit2必须等于OurChar的bit7,等等。
 
由此可知,只要将GoodChar_xor按user_crypt_filter中特定的index处所指明的bit置换规则,把各个bit换一下,则可得到解密后的明文签名字符。这也就是说,如果我们在代码中找到了针对一个index的字符的八条位置换规则,如GoodChar_xor的bit0应该等于OurChar的bit3、GoodChar_xor的bit2应该等于OurChar的bit7等共八条,那么我们只要新起一个变量TmpChar,将GoodChar_xor的bit0放到变量TmpChar的bit3,GoodChar_xor的bit2换到TmpChar的bit7,换过8个bit后,这个TmpChar的每一位必然等于解密后的明文签名字符OurChar。这就是user_crypt_filter检查运算的逆运算!
 
三、编写逆运算程序
 
逆运算分析出来了,就可以写还原程序了。
这儿参考了Nolan Blender的思想,将0到19个index,每个index所对应的8位bit置换规则写成一个大数组,共一百六十项,从七千多行汇编代码中整理出来相当费力,但所幸只是体力活儿。而且如果是短的签名的话,只要搜集0到5的index所对应的四十八条bit置换规则即可。
 
以下代码用Delphi实现:
 
type
  TShiftVals = array[0..7] of Integer;
  TPermute = packed record
    shiftvals: TShiftVals;
  end;
 
PerTab: array[0..19] of TPermute = // 搜集得到的位置换规则数组
(           // BIT  0 1 2 3 4 5 6 7
       (shiftvals: (0,4,5,3,1,2,6,7)), // idx 00 //
       (shiftvals: (4,0,5,2,1,3,6,7)), // idx 01 //
       (shiftvals: (7,1,3,4,0,5,2,6)), // idx 02 //
       (shiftvals: (4,7,3,6,1,5,2,0)), // idx 03 //
       (shiftvals: (0,3,7,4,2,5,6,1)), // idx 04 //
       (shiftvals: (4,3,5,6,7,0