还不满足,还有功能不爽,看看附件里面的图,再对照自己的比较一下,差距啊:)
厚道的放出链接:
http://www.wholetomato.com/index.html
破解都找到了,我太好了T T
Telnet your heart…
还不满足,还有功能不爽,看看附件里面的图,再对照自己的比较一下,差距啊:)
厚道的放出链接:
http://www.wholetomato.com/index.html
破解都找到了,我太好了T T
那天有个信息安全实验室的博士生叫我们做IE插件,主要用于拦截IE浏览器的各项消息,从而做出我们自己的处理。
实现方法,当然千奇百怪,全局钩子函数,进程注入,消息拦截等等都可以,不过我最终选择了全局钩子函数,感觉应该好做一点。
由于最近比较多接触C#,第一反映当然还是.net framework。
MSDN->Filter:c#->“全局钩子”一找,郁闷死人:
在 .NET 框架中不支持全局挂钩
您无法在 Microsoft .NET 框架中实现全局挂钩。若要安装全局挂钩,挂钩必须有一个本机动态链接库 (DLL) 导出以便将其本身插入到另一个需要调入一个有效而且一致的函数的进程中。这需要一个 DLL 导出,而 .NET 框架不支持这一点。托管代码没有让函数指针具有统一的值这一概念,因为这些函数是动态构建的代理。
[http://support.microsoft.com/kb/318804]
当然,其实这段文字本身有点问题,先不说网上有人说好像并不是所有的全局挂钩都不能加载,但就.net支持对非受控代码的访问这点,就可以通过在中间增加一层Managed Code->UnManaged Code->Managed Code实现调用。
但是这样的实现难度陡增,很是麻烦。不过在搜索结果中看到一个比较乖的咚咚:Browser Helper Object,看起来感觉比较象。
记得以前有篇写Office Doc Object架构的文章很有名(好像小排发过吧),不过记忆中,当时看了一点就放弃了,感觉挺麻烦的。特别是针对COM组件的调用部分,看着就头大。
话说回来,调用COM组件在.net环境下,还是C++来得方便快捷,毕竟都是非受控的代码,不用处理太多受控、非受控对象之间的交互问题。不过C++.net依然还是VC++6.0的模样,看着都恶心,于是乎放弃:P
粗粗看了看Browser Helper Object(BHO)的机理,这个咚咚主要用于下面的场景:
想实现一个浏览器,提供一些自己的功能,但是如果用IE Control来写的话,还要自己写很多很多很多诸如:前进、后退、历史记录等等IE已经提供的功能,所以更简便的方法是给扩展、修改IE的功能,直接使用IE来实现。这方面,当然不能不提很多人深恶痛绝的3721,他提供了一个个性化的浏览器,却只写了很少的代码,其余的都是IE自带的内容。
打开一个IE,打开Spy++,再结合Internet Explorer 4.0 Architecture的图看看
举个例子,如果想要获取IE地址栏的内容:
IEExplorer->IEFrame->WorkerW->ReBarWindow32->ComboBoxEx32->ComboBox->Edit
这就是他的层次结构
IE和Explorer在启动新线程的时候(Explorer要看看选项里面是否选择了在新的线程中打开窗口),会检查注册表项:
[HKLMSOFTWAREMicrosoftWindowsCurrentVersionExplorerBrowser Helper Objects]
他下面有很多子项,每一个子项就是一个GUID
例如:
{06849E9F-C8D7-4D59-B87D-784B7D6BE0B3}
这个GUID对应一个BHO组件(其实就是一个COM组件)
这个组件在[HKLMSOFTWAREClassesCLSID]下面进行描述,包括dll路径,签名等等信息
IE或Explorer在每个线程里会依次实例化每个在上述路径注册的BHO对象,从而BHO对象实际上运行在IE或Explorer的地址空间内,并且能够访问IE的几乎所有资源,拦截几乎所有事件,挂载自己的事件处理函数,而不需要跨进程调用和传消息。
看来完全符合最初的应用要求并且是最简单的方法了。
接下来的问题,就只剩下COM组件的使用了。.NET对COM组件的调用提供了很方便的100% pure 受控的访问方式 – Interop, Marshal。查错过程比较艰辛,因为每次重新生成都要重启Explorer.exe T T并且调试的时候,要先开IE,再下断点,再将VS .NET附加到IE进程,再点新建IE窗口…
COM组件的使用:
首先,当然是用Create GUID工具生成我们自己BHO组件的GUID({B29E305D-BC4D-4a80-B522-B0ABC9EBDFFC}),然后添加对 Microsoft Internet Controls COM组件(%systemroot%ShDocVw.dll)的引用。VS.NET会自动Wrapper之为 Interop.SHDocVw.dll,值得注意的是,这里由于最后要使用BHO注册,所以要求这个COM组件必须用私钥签名,从而使用强名机制。具体步骤如下:
1、sn -k BHO.key生成Bho.key文件,也就是我们的私钥。
2、设置项目属性,ActiveX/COM对象的包装程序集->包装程序集密钥文件,指向Bho.key
3、添加COM引用(此时查看相关信息就可以看到强名选项已设为true)
4、设置AssemblyInfo.cs填写key字段,指向Bho.key
然后,就可以声明我们要继承的各项接口:
using SHDocVw;
#region 引入IObjectWithSite接口
[ComImport(), Guid("fc4801a3-2ba9-11cf-a229-00aa003d7352")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IObjectWithSite
{
void SetSite([In ,MarshalAs(UnmanagedType.IUnknown)] object site);
void GetSite(ref Guid guid, [MarshalAs(UnmanagedType.IUnknown)] out object site);
}
#endregion
#region 定义默认BHO COM接口
[GuidAttribute("181C179B-7CC9-4457-8C1D-4B45E7C8589D")]
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsDual)]
public interface IObserver
{
}
#endregion
然后定义我们自己的BHO类:
/// <summary>
///定义BHO类,此类由浏览器实例化
/// </summary>
[ClassInterfaceAttribute(ClassInterfaceType.None)]
[GuidAttribute("B29E305D-BC4D-4a80-B522-B0ABC9EBDFFC")]//由CreateGUID程序生成
[ProgIdAttribute("Observer.BrowserMonitor")]
public class BrowserMonitor : IObserver, IObjectWithSite
{}
这个类里面如下引入定义:
protected IWebBrowser2 browser; //浏览器对象
protected DWebBrowserEvents2_Event browserEvents;//浏览器事件
并且实现IObjectWithSite接口:
#region IObjectWithSite 成员
/// <summary>
/// IE调用此方法,并传递指向容器Site的IUnknown指针,由此我们可以获得IWebBrowser2接口
/// 并挂载DWebBrowserEvents2事件
/// </summary>
/// <param name="site">容器Site的IUnknown指针</param>
public void SetSite(object site)
{
// TODO: 添加 BrowserMonitor.SetSite 实现
#region 取得 IWebBrowser2 引用
if (browser != null)
Release();
if (site == null)
return;
browser = site as IWebBrowser2;
#endregion
#region 检查名称,当且仅当为IEXPLORE.EXE时加载
string hostName = browser.FullName;
if (!(hostName.ToUpper().EndsWith("IEXPLORE.EXE")))
{
Release();
return;
}
#endregion
#region 挂载浏览器事件
browserEvents = browser as DWebBrowserEvents2_Event ;
if (browserEvents != null)
{
browserEvents.DocumentComplete += new DWebBrowserEvents2_DocumentCompleteEventHandler(this.OnDocumentComplete);
}
else
{
Release();
return;
}
#endregion
}
/// <summary>
/// 调用者调用此方法以获得前面浏览器发送给SetSite()方法的浏览器对象
/// </summary>
/// <param name="guid">请求Site接口对象的GUID</param>
/// <param name="site">返回的Site接口对象</param>
public void GetSite(ref System.Guid guid, out object site)
{
// TODO: 添加 BrowserMonitor.GetSite 实现
site = null;
if (browser != null)
{
IntPtr pSite = IntPtr.Zero;
IntPtr pUnk = Marshal.GetIUnknownForObject(browser); //引用计数增加
Marshal.QueryInterface(pUnk, ref guid, out pSite); //引用计数增加
Marshal.Release(pUnk); //引用计数减少
Marshal.Release(pUnk); //引用计数减少
if (!pSite.Equals(IntPtr.Zero))
{
site = pSite;
}
else
{
// 若找不到请求的接口,将返回E_NOINTERFACE
Release();
Marshal.ThrowExceptionForHR(E_NOINTERFACE);
}
}
else
{
// 若找不到请求的接口对象,将返回E_FAIL
Release();
Marshal.ThrowExceptionForHR(E_FAIL);
}
}
#endregion
这里挂载了我们自己的事件处理函数,处理DocumentComplete事件,此外还有很多事件可以使用,例如:
DownloadBegin
DownloadComplete
BeforeNavigate2
CommandStateChange
FileDownload
NavigateComplete
NewWindow
FullScreen
MenuBar
Quit
FrameBeforeNavigate
FrameNavigateComplete
FrameNewWindow
ProgressChange
PropertyChange
StatusTextChange
TitleChange
WindowActivate
WindowMove
WindowResize
using System.IO;
#region 用于挂载的自定义函数
protected void OnDocumentComplete(object display, ref object url)
{
try
{
if (Marshal.Equals(browser, display))
{
StreamWriter sw = new StreamWriter(@"C:Test.txt", true);
sw.WriteLine(url.ToString());
sw.Close();
}
}
catch
{
Release();
Marshal.ThrowExceptionForHR(E_FAIL);
}
}
#endregion
此外,关于错误处理,由于涉及包裹为受控组件的非受控组件,所以需要使用以下方式抛出异常:
#region 定义HRESULT值 : 预定义的COMException值
//在未检查的上下文中,如果表达式产生目标类型范围之外的值,则结果被截断
const int E_FAIL = unchecked((int)0x80004005);//失败
const int E_NOINTERFACE = unchecked((int)0x80004002);//QueryInterface时,接口不存在
#endregion
Marshal.ThrowExceptionForHR(E_FAIL);
Marshal.ThrowExceptionForHR(E_NOINTERFACE);
使用一下方式,释放对象:
#region Release操作
protected void Release()
{
if (browserEvents != null)
{
Marshal.ReleaseComObject(browserEvents);
browserEvents = null;
}
if (browser != null)
{
Marshal.ReleaseComObject(browser);
browser = null;
}
}
#endregion
至此已基本完成,但是要想自动注册BHO组件,还需要做几件事情:
#region 挂载注册/注销操作
/// <summary>
/// 在注册COM组件时,由运行时调用
/// </summary>
[ComRegisterFunctionAttribute]
public static void Register(Type type)
{
// 注册BHO组件
string guid = type.GUID.ToString("B");
RegistryKey rkey =
Registry.LocalMachine.CreateSubKey(@"SOFTWAREMicrosoftWindowsCurrentVersionExplorerBrowser Helper Objects");
RegistryKey rkeyBHO = rkey.CreateSubKey(guid);
}
/// <summary>
/// 在注销COM组件时,由运行时调用
/// </summary>
[ComUnregisterFunctionAttribute]
public static void Unregister(Type type)
{
// 注销BHO组件
string guid = type.GUID.ToString("B");
RegistryKey rkey =
Registry.LocalMachine.CreateSubKey(@"SOFTWAREMicrosoftWindowsCurrentVersionExplorerBrowser Helper Objects");
rkey.DeleteSubKey(guid,false);
}
#endregion
由这些可见.NET平台对于COM组件的调用支持还是相当强大的,可以在受控环境下实现100% pure的COM访问能力。
PS:
结尾怎么写成这样了,写一写的就有点偏题了- –
其实因为C#语言自身的一些特点,和FlyWeight的实现方式不太一样- –
初学,不足之处见谅:)
详细叙述见附件
======2005-12-13======
作了一些修改,使用方式不变,不过加入了对任何单参数构造函数的支持。
有人问,为什么不支持任何多参数构造函数, 因为实际上参数就是缓存时用于查找的Key,多参数生成Key的时候较麻烦而已:)
最后,说明一点,本FlyWeight在Scavenging的时候,会根据使用的情况,删除最不常使用的Key
======2006-1-19=======
VS2005发布后,更新版本
人之初,性本善,世间本没恶魔,有的只是迷失的心智,爵爷有罪,按罪当诛,但其并非恶魔,他只是一个普普通通的学生。他坚强,他坚持,套用《朋友》的歌词,他能够划船不用桨,他能够扬帆没有风向, 但任其三头六臂,也不能能够离开“好朋友”却不感伤。
然而正是这些所谓的好朋友,给了他最后的一击,当然他的选择是极其错误的,但是他的选择以他的背景来看,却并非完全不能理解。
总之,黑夜给了我黑色的眼睛,我却用它来寻找光明;命运给了我们苦难,我们不应该去苦难别人。
希望他们一个寝室的5兄弟,能够再次团聚, 一起开心的玩牌,一起开心的歌唱。
附:
遗书
春城的春天下着雨
有着一丝凄寒的风
我望着生锈的铁窗
我想起了我可怜的父母
为了供子女读书
他二老起早摸黑在田里干活
还点着蜡烛为人烫衣服
5毛钱一件
那次我母亲掉了一百块钱
她心疼的说那是烫了两百件衣服赚来的钱呀
我看着母亲伤心的样子
就把自己做苦力赚来的一百块钱丢到地上
对母亲说:妈妈你的一百块钱在这里!
妈妈露出了一丝苦笑
其实妈妈知道是我丢的
我不怕一个人独自吃苦
我不忍心父母看到我吃苦
读大学几年我没问家里要一分钱
我总希望父母不要为我操劳
他们年纪大了
辛苦了一辈子
怎么忍心增添他们的负担呢
但学费是高昂的
我必须自己去卖苦力
耽误学习也是没办法的事情
我一个人默默的做苦工
我一个人偷偷一天只吃两个馒头
冬天其实我更怕冷
因为我是南方人
但是为了节省洗热水澡的几块钱
我整个冬天坚持洗冷水澡
我冷的直打哆嗦
我微笑着对同学说
我们年轻人需要锻炼身体
那天我没鞋子穿
我不好意思去上课
直到学校发了点救济
我才买了双便宜的拖鞋走进了课堂
我家一直很穷苦
我在穷苦中长大
我从小就体味到家庭的艰辛
幼小的我便心疼父母的辛苦
只想通过小手减轻父母一点点负担
我说:爸妈你们辛苦了,我做好了饭,你们快吃吧!
我一直努力读书
村里的邻居以及中学老师
都知道我是个吃苦好学、斯文老实的学生
我中学拿过全国奥林匹克物理大赛二等奖
我上了高中受过歧视而闷闷不乐
可是在接近高考的那几个月
我顶住各方面的压力奋发苦读
就这样我一个穷困的学生考出了优异的成绩
我高考的成绩超过我们广西省当年重点线50多分
完全可以上名牌大学武汉大学 、哈工大之类
可是我考虑到那离家远费用更大
所以选择地域较近并且消费水平比较低的云南大学
我充盈着希冀
一个农家的孩子
蕴涵着淳朴老实本分
来到了云南大学
当我看到毛主席书写的四个大字
“云南大学”
我的心激起一阵阳光的涟漪
我立志一定好好继续努力
学好专业找个好工作
可以好好报答父母,
改变穷苦的命运也好好用自己的知识
来为社会为国家努力工作
认真做个受人尊重的人
做个对社会有贡献的人
进入大学以后我怎么发现
大部分人不爱读书
每天晚上谈女孩子
哪个女孩子性感漂亮
和哪个女孩子做爱更爽
有钱的同学则大胆的找起女朋友来
大摇大摆的在学校旁边租房子同居
大家都爱玩电脑游戏
大家都嘲笑我是个土包子
这个不会那个也不会
于是我为了和同学打好关系
我也学会了玩电脑游戏
并且由于我的天生智商还可以
玩游戏比他们更厉害
我以后更乐衷于玩电脑了
我还自己用打工的钱以及借了部分钱
买了台旧电脑
我很大方
我的电脑同学们随时都可以玩
我很希望和同学们和睦相处
时间很快
大学过了几年
我暑假寒假基本都不回家
都在昆明做苦工赚钱
我还慰藉父母
爸爸妈妈我在云大过的很好
老师还经常约请我到他们家去做客呢
其实我每次说这样的话心里都是虚的
我有时候没钱就打一份饭吃上两天
经常一天吃两个馒头就过去了
我从不怕苦也不怨恨谁
我更没因为没钱而想到去偷去抢
我很坚强
我为自己骄傲
我对的起父母
我对的起自己
我对的起同学
我对的起社会
可是总有那么些同学总有意无意的歧视我
有时候说些话很伤我的心
他们觉得我的穿着打扮很怪
他们觉得我的举止很怪
我开始悄悄的打工
我不想被人家看成异类
好在我自以为有几个好老乡、好同学
这样我才能不去理会那些同学的歧视与人格蔑视
大学很多男生都在大胆的追求自己喜欢的女孩子
很多男生都谈恋爱了
我在这种氛围下加上几个同学的怂恿
也大胆的写了一封情书
交给了我暗恋许久的一个女孩子
由于我的模样不好看
加上又没钱
人显的很土气内向
那女生毫不留情的当着许多人的面
把我那封用真心诚挚锩刻成的信
撕个粉碎
我只是内心痛苦了下
我也并没有怨恨谁
我只觉得自己确实条件不行配不上她
我对父母也是这么说的
我有自知之明,我不谈恋爱
况且大学生应该以学业为重
时间过了很快
快到大学毕业了只剩一个学期就毕业了
最后一个寒假
我依旧没有回家
依旧在昆明做苦力
离开学还有几天
有些同学提前来学校了
大家可能都是为了找工作所以提前回学校
我很开心
因为整个寒假我一个人多么孤寂
我不怕吃苦
但是人是很怕寂寞的
当我看到同学们时我很热情
他们为了打发时间约我打牌
我很乐意的接受了
其实我们原来也经常玩牌的
其实无须掩饰
我智商真的比较高
所以打牌经常赢
几个同学都怀疑我作弊
我坚持说没有
谁知道那三个我自以为平时没有歧视过我的同学
以为一直平等对我的同学
竟然恶语伤我,蹂躏我的人格,
还揭露了我以前的许多伤疤,
包括那女生撕毁我情书的事情
什么苦楚什么贫苦什么艰辛的生活
我可以忍受
其他人歧视蔑视我
我也可以忍受
可是我这几个平时稍微好点的同学竟然
这样残酷无情的践踏、蹂躏我的人格尊严
原来每个人长期以来一直这样
凶悍的歧视我
残忍的嘲笑我
我的心很痛
我的泪悄悄的落下了
我是一个坚强的人
我不曾被艰辛贫苦生活打败
可是当我的人格尊严被人糟蹋的不成样子的时候
当我的过去的伤痛被人再次拿出来嘲讽的时候
我的心滴血了
践踏我竟然还是平时关系稍微好点的同学以及老乡!
我在这种氛围下再也难以立足了
是他们残忍的对我
是他们不给我活路
他们没有给我留后路
他们淋漓尽致地侮辱完我后
居然还那样嚣张与快乐
因为他们生活条件还是比较好的
他们还有资本去玩女孩子
我伤痛的心找不到归处!
总浮现出他们淋漓尽致侮辱我的样子
我没有退路了
我决定玉石俱毁
我决定给那些歧视穷苦人、蔑视穷苦人的人
一个教训
我决定给那些无情践踏、残忍蹂躏穷苦人人格尊严的人
一个教训
我本来习惯被人歧视、被人蔑视的
可是这次他们表现的实在是太淋漓尽致了
他们嘲讽时刻的无情
他们侮辱时刻的面孔可恶
让我下定了决心
终于我买了一把石锤
结束了他们几个人的生命
于是我逃跑
我想没抓到我以后到一个
没有歧视侮辱的地方重新做人
万一抓到就一死百了
我是不怕死的我只想死刑
我不愿意被判无期徒刑
因为那样会给我父母带来压力!许多人现在都说我是杀人恶魔
都说我杀红了眼
其实说心理话
我只想杀那些无情蹂躏糟蹋别人人格的人
我并不想伤及无辜
当我另一个同学来找我的时候
我并没有杀他
因为在我最穷困的时候并没有歧视我
反而打饭给我吃
我深刻懂得人间真情的可贵
我曾对自己说:滴水之恩,涌泉相报
我一定会报答这位同学
可是我现在留下了一个永远的遗憾
我没有机会报答这位同学了!
但我最后想送一句话给我那位同学:
好人自有好报!
我听到到飘曳进来的歌声了
好象是〈梦驮铃〉
多么熟悉的旋律呀
我想起了经常帮助我家的十四叔、十四婶来了
我们那个家虽然很穷
但是大家都很互相关怀
大家都感到很快乐
没有歧视与蔑视
从来不知道什么是人格践踏
我很想和陶渊明那样
就永远生活在我那个村子里
天天看着清澈的流水
望着袅袅的炊烟
写着清新的诗歌
呵 那多美好呀
可是现在—–
只好等来生了
爸爸妈妈,对不起了
儿子不孝
儿子来生一定让你过上好日子
警察又来提审我了
我总听到外面摩托车的声音
为什么总是那么飞扬跋扈
我怀念十哥开的摩托修理店
在我印象中那是很赚钱的
十哥骑摩托车很英姿飒爽
那摩托车的声音是
那样的婉转清脆!
我仿佛又坐在十哥的摩托车上了
慢悠悠的行走在
我可爱、纯朴、亲切的家乡
PS:几个生命就这么消失了
青春其实可以用另一种方式去诠释的
我也很穷
我也很丑
我也经常被抛弃
别太在意别人对你说些什么
也不要去委曲求全
找到和你真心相印的朋友
一路走好