<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

统计

  • 随笔 - 44
  • 文章 - 0
  • 评论 - 86
  • 引用 - 0

常用链接

留言簿(6)

随笔分类(31)

随笔档案(44)

Mining

最新随笔

搜索

  •  

最新评论

阅读排行榜

评论排行榜

小觑IE 浏览器ActiveX 控件创建过程

1. Activex 控件是怎么安装的
一个HTML 中嵌入控件的例子

<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=7,0,19,0" width="400" height="300">
<param name="movie" value="flash/flash.swf">
<param name="quality" value="high">
<embed src="flash/flash.swf" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" width="400" height="300"></embed>
</object>

当用IE 打开这个页面的时候, IE 首先根据 classid 在注册表中(HKEY_CLASS_ROOT)查找其安装信息, 如果未找到, 则IE 根据codebase 去看是否有对应的控件存在; 如果还是不行, 则会一些控件注册服务器联系(列表在 HKLM\Software\Microsoft\Windows\CurrentVersion\Internet Settings\CodeBaseSearchPath 可以找到 ), 一般是 http://activex.microsoft.com/objects/ocget.dll , http://codecs.microsoft.com/isapi/ocget.dll  , 然后服务器会告诉IE 从哪里去下载. 

FROM : http://oreilly.com/catalog/malmobcode/chapter/ch11.html


2. ActiveX 控件是如何启动的
创建一个控件有很多种方法
CoCreateInstance, CoGetInstanceFromFile, CoGetInstanceFromIStorage
CoCreateInstanceEx
CoGetClassObjectFromURL , CoGetClassObject 
CoGetObject, DllGetClassObject 等
基本调用顺序好像是
(CoGetInstanceFromFile, CoGetInstanceFromIStorage ) -> CoCreateInstance
CoCreateInstanceEx
CoGetClassObjectFromURL -> CoGetClassObject 
其他没有测试过... :9

IE 创建控件的时候会调用 CoGetClassObjectFromURL -> CoGetClassObject 的顺序进行, 而不是直接调用(CoCreateInstance 或者 CoCreateInstanceEx) , 但是免不了控件会自己调用 CoCreateInstanceEx, 比如Real 控件在创建的时候会调用Dx 的组件等.

posted @ 2008-07-30 19:55 泡泡牛 阅读(2198) | 评论 (2)编辑 收藏
获取IE (控件)的所有链接(包括Frameset, iframe)

IE 顶层 body 节点通过IHTMLElement->get_all 方法无法获取iframe 里面的节点列表

CComPtr<IHTMLElement> body;
 
CComPtr
<IDispatch> spDispCollection;
body
->get_all(&spDispCollection);

所以要获取iframe/frame(frameset) 里面的节点列表的话, 则需要根据body/doc 找到frames, 然后从frames -> IHTMLWindow2 -> IHTMLDocument2 . 主要有2个方法, 下面是代码片段
方法一:
IHTMLDocument2 *pDoc = 浏览器的Document(IWebBrowser2->IDispatch->IHTMLDocument2); 
IHTMLWindow2 
*pHTMLWnd = NULL; 
IHTMLDocument2 
*pFrameDoc=NULL; 
IHTMLFramesCollection2 
*pFramesCollection=NULL; 
LPDISPATCH lpDispatch; 

long p; 
VARIANT varindex,varresult; 
varresult.vt
=VT_DISPATCH; 
varindex.vt 
= VT_I4; 
if(pDoc!=NULL) 

    HRESULT hr
=pDoc->get_frames(&pFramesCollection); 
    
if(SUCCEEDED(hr)&&pFramesCollection!=NULL) 
    { 
        hr
=pFramesCollection->get_length(&p); 
        
if(SUCCEEDED(hr)) 
            
for(int i=0; i<p; i++
            { 
                varindex.lVal 
= i; 
                
if(pFramesCollection->item(&varindex, &varresult) ==S_OK) 
                { 
                    lpDispatch
=(LPDISPATCH)varresult.ppdispVal; 
                    
if (SUCCEEDED(lpDispatch->QueryInterface(IID_IHTMLWindow2, (LPVOID *)&pHTMLWnd))) 
                    { 
                        
if(SUCCEEDED(pHTMLWnd->get_document( &pFrameDoc))) 
                        { 
                            
//work with the pFrameDoc 
                        } 
                        pHTMLWnd
->Release(); 
                        pHTMLWnd
=NULL; 
                    } 
                } 
            } 
            pFramesCollection
->Release(); 
    } 
    pDoc
->Release(); 
}

方法二:
CComQIPtr<IHTMLElement> pElem = ; // 可以递归上面的 CComPtr<IDispatch> spDispCollection 来得到
CComBSTR bstrTagName;
pElem
->get_tagName(&bstrTagName);
if ( lstrcmpiW(L"IFRAME", bstrTagName)==0 ||
        lstrcmpiW(L
"FRAME", bstrTagName)==0 )
{
    CComQIPtr
<IHTMLFrameBase2>    _framebase2;
    CComPtr
<IHTMLWindow2>        _framewindow;
    CComPtr
<IHTMLDocument2>        _framedoc;
    
    
if( (_framebase2 = spItem) 
        
&& SUCCEEDED( _framebase2->get_contentWindow(&_framewindow) ) && _framewindow!=NULL 
        
&& SUCCEEDED( _framewindow->get_document(&_framedoc) ) && _framedoc!=NULL )
    {
        
// 对 _framedoc 节点进行处理
    }
}


iframe 跨域访问(cross frame)  zz from : http://codecentrix.blogspot.com/2007/10/when-ihtmlwindow2getdocument-returns.html 
由于安全性限制, 为防止跨域脚本攻击, 当frames 跨域的时候, IHTMLWindow2::get_document 调用将返回 E_ACCESSDENIED .
下面函数 HtmlWindowToHtmlDocument  对于跨域的frame 通过 IHTMLWindow2 -> IID_IWebBrowserApp -> IHTMLWindow2 绕过了限制.

// Converts a IHTMLWindow2 object to a IHTMLDocument2. Returns NULL in case of failure.
// It takes into account accessing the DOM across frames loaded from different domains.
CComQIPtr<IHTMLDocument2> HtmlWindowToHtmlDocument(CComQIPtr<IHTMLWindow2> spWindow)
{
     ATLASSERT(spWindow 
!= NULL);

     CComQIPtr
<IHTMLDocument2> spDocument;
     HRESULT hRes 
= spWindow->get_document(&spDocument);
    
     
if ((S_OK == hRes) && (spDocument != NULL))
     {
          
// The html document was properly retrieved.
          return spDocument;
     }

     
// hRes could be E_ACCESSDENIED that means a security restriction that
     
// prevents scripting across frames that loads documents from different internet domains.
     CComQIPtr<IWebBrowser2>  spBrws = HtmlWindowToHtmlWebBrowser(spWindow);
     
if (spBrws == NULL)
     {
          
return CComQIPtr<IHTMLDocument2>();
     }

     
// Get the document object from the IWebBrowser2 object.
     CComQIPtr<IDispatch> spDisp;
     hRes 
= spBrws->get_Document(&spDisp);
     spDocument 
= spDisp;

     
return spDocument;
}


// Converts a IHTMLWindow2 object to a IWebBrowser2. Returns NULL in case of failure.
CComQIPtr<IWebBrowser2> HtmlWindowToHtmlWebBrowser(CComQIPtr<IHTMLWindow2> spWindow)
{
     ATLASSERT(spWindow 
!= NULL);

     CComQIPtr
<IServiceProvider>  spServiceProvider = spWindow;
     
if (spServiceProvider == NULL)
     {
          
return CComQIPtr<IWebBrowser2>();
     }

     CComQIPtr
<IWebBrowser2> spWebBrws;
     HRESULT hRes 
= spServiceProvider->QueryService(IID_IWebBrowserApp, IID_IWebBrowser2, (void**)&spWebBrws);
     
if (hRes != S_OK)
     {
          
return CComQIPtr<IWebBrowser2>();
     }

     
return spWebBrws;
}


附:
IE(控件/接口)中主要有4个部分, Browser, Document, Frame/IFrame, Element , 其对应接口分别是
Browser         -    IWebBrowser2
Document      -    IHTMLDocument2
Frame/IFrame-    IHTMLWindow2
Element         -    IHTMLElement
可以通过下面方法互相获取
browser      -> document        IWebBrowser2::get_Document
document     -> frame           IHTMLDocument2::get_parentWindow
frame        -> document        IHTMLWindow2::get_document
frame        -> parent frame    IHTMLWindow2::get_parent
frame        -> children frames IHTMLWindow2::get_frames
element     -> Frame             IHTMLElement->QI(IHTMLFrameBase2) -> IHTMLFrameBase2->get_contentWindow -> IHTMLWindow2

ref:
在多Frame的网页中怎么取出各个Frame的IHTMLDocument2的接口!急用.(高分)
在文章 When IHTMLWindow2::get_document returns E_ACCESSDENIED 解决了iframe 跨域访问的问题

posted @ 2008-07-30 19:17 泡泡牛 阅读(7189) | 评论 (3)编辑 收藏
Apache 安装在只读分区上的配置

有时候Apache 程序安装在NFS ,SAMBA, Windows 的共享盘上, 而且可能是只读, 所以需要修改一些配置. 主要有:
# apache 运行时所依赖文件
LockFile /path/to/apache-rproxy.lock
# apache 运行时会修改的相关文件
PidFile /path/to/apache-rproxy.pid
ErrorLog /path/to/apache-rproxy.elog
CustomLog /path/to/apache-rproxy.dlog "%{%v/%T}t %h -> %{SERVER}e URL: %U"

具体说明如下

ServerRoot "/usr/local"
ServerRoot用于指定守护进程httpd的运行目录,httpd在启动之后将自动将进程的当前目录改变为这个目录,因此如果设置文件中指定的文件或目录是相对路径,那么真实路径就位于这个ServerRoot定义的路径之下。

由于httpd会经常进行并发的文件操作,就需要使用加锁的方式来保证文件操作不冲突,由于NFS文件系统在文件加锁方面能力有限,因此这个目录应该是本地磁盘文件系统,而不应该使用NFS文件系统。

LockFile /var/run/httpd.lock
LockFile参数指定了httpd守护进程的加锁文件,一般不需要设置这个参数,Apache服务器将自动在ServerRoot下面的路径中进行操作。但如果ServerRoot为NFS文件系统,便需要使用这个参数指定本地文件系统中的路径。

PidFile /var/run/httpd.pid
PidFile指定的文件将记录httpd守护进程的进程号,由于httpd能自动复制其自身,因此系统中有多个httpd进程,但只有一个进程为最初启动的进程,它为其他进程的父进程,对这个进程发送信号将影响所有的httpd进程。PidFILE定义的文件中就记录httpd父进程的进程号。

posted @ 2008-07-18 18:08 泡泡牛 阅读(633) | 评论 (0)编辑 收藏
C/C++ 的预处理变量,宏 和 预定义宏

== 预处理指令(Preprocessor Directives) ==


== 预处理操作符(Preprocessor Operators) ==
Stringizing operator (#)
Causes the corresponding actual argument to be enclosed in double quotation marks
将参数变成字符串 : #x -> "x"

Charizing operator (#@)
Causes the corresponding argument to be enclosed in single quotation marks and to be treated as a character (Microsoft Specific)
将参数变成字符变量 : #x -> 'x'

Token-pasting operator (##)
Allows tokens used as actual arguments to be concatenated to form other tokens
将参数和前面的符号结合 : token##x -> tokenx


== 预定义宏(Predefined Macros) ==

__FILE__
__LINE__

#define LINE1(x) #x
#define LINE(x) LINE1(x)
#define TODO(msg)   message ( __FILE__ "(" LINE(__LINE__)  "): [TODO] " #msg )
#define NOTE(msg)   message ( __FILE__ "(" LINE(__LINE__)  "): [NOTE] " #msg )

posted @ 2008-06-06 14:10 泡泡牛 阅读(2238) | 评论 (0)编辑 收藏
zz 自定义浏览器控件

同自动化浏览器(http://blog.joycode.com/jiangsheng/archive/2005/10/20/65489.aspx)相比,自动化浏览器控件(WebBrowser Control) 在应用程序中更加常用。从Outlook的预览窗格到Maxthon这样的基于IE引擎的浏览器,从无界面的HTML分析器到Norton Antivirusd的主界面,浏览器控件在众多领域被用作各种各样的用途。这也使得有必要根据具体的用户需求自定义浏览器控件的行为。

在应用程序中加入浏览器控件

集成浏览器控件的最简单的方法是找一个支持ActiveX的集成开发环境,在工具箱中加入Microsoft Web Browser这个控件,往表单上拖一个这个控件就可以完成工作。你甚至可以用集成开发环境添加ActiveX的事件处理函数。如果要直接导入ActiveX的话,建议使用mehrcpp的vbMHWB控件(http://www.codeproject.com/atl/vbmhwb.asp)。这个控件在浏览器控件的基础上进行了扩展,暴露了很多底层接口。

通常导入ActiveX就可以满足大部分需求  ,但是有些类库中也集成了浏览器控件,并且提供了更多的功能,例如MFC的CHTMLView和CDHtmlDialog,ATL的HTML Control,以及.Net 2.0中的Windows.Forms.WebBrowser。如果使用Visual C++来进行非托管编程,那么建议使用MFC或者ATL的封装类,或者使用vbMHWB控件。托管编程中当然首选Windows.Forms.WebBrowser。除非这些类的BUG影响到了应用程序的开发,否则建议使用这些功能更加强大的封装类。

在使用浏览器控件及其封装类的时候要注意一些已知问题

常见任务

在集成浏览器控件之后,可以完成基本的网页浏览,但是对于不同的任务,也需要进一步的处理,例如设置控件的属性、为控件添加事件处理、操作HTML文档等等。

修改浏览器控件的属性

这在集成开发环境中可以很容易地设置,也可以自己实现容器来设置,但是CHTMLView这样的封装类没有这个选项(http://support.microsoft.com/kb/197921)。

  • 链接目标解析。对于用浏览器控件来做浏览器的场合来说,需要将浏览器的RegisterAsBrowser属性设置为true。这使得Internet Explorer在解析HTML链接的target属性指定的目标窗口时可以找到这个窗口。
  • 禁用拖放。对于使用浏览器控件来做预览窗格的场合来说,需要将浏览器的RegisterAsDropTarget属性设置为false。这使得窗口不接受拖进来的文件和链接。
  • 禁用消息框。对于用浏览器控件来做HTML分析器的场合来说,有时需要屏蔽脚本产生的消息框以避免阻塞程序运行。这可以通过设置浏览器的Silent属性来实现,或者实现IDocHostShowUI::ShowMessage。

捕获浏览器控件的事件

集成开发环境中可以也很容易地添加浏览器的事件处理函数。比较常用的事件包括

  • NewWindow2或者NewWindow3事件。默认情况下,浏览器控件中创建的新窗口会是一个Internet Explorer的窗口。这通常不是预期的行为,对于浏览器程序来说更是这样。需要处理浏览器的NewWindow2或者NewWindow3(在Windows XP SP2或者Windows 2003 SP1之后可用)事件来让新的浏览器窗口在应用程序提供的窗口中运行。
  • WindowClosing事件。浏览器控件需要处理WindowClosing事件来在浏览器控件被脚本关闭时关闭浏览器控件的宿主窗口(http://support.microsoft.com/kb/253219)。
  • BeforeNavigate2事件。可以在自己的网页中加入自定义的协议,之后在BeforeNavigate2事件中扫描URL来进行网页和应用程序之间的交互(http://www.microsoft.com/msj/0100/c/c0100.aspx)。当然,自定义的网络协议也可以用Asynchronous Pluggable Protocol来处理(参见http://support.microsoft.com/kb/303740),vbMHWB控件就实现了这个功能。但是更加常用的是在弹出广告过滤器程序中用BeforeNavigate2来判断在NewWindow2事件中创建的窗口是否需要关闭。

操作MSHTML文档

通常HTML分析和浏览器自动化程序都需要分析网页的结构,找到需要操作的元素。这需要对网页的结构进行分析,找到目标元素的标识方法。 一些常用的操作包括:

 在页面包含框架的时候,可能需要跨框架访问HTML文档。可以通过查询框架元素所支持的IWebBrowser2接口或者IHTMLWindow2接口来访问框架中的文档(http://support.microsoft.com/kb/196340),但是也有可能因为安全设置而无法访问(http://support.microsoft.com/kb/167796)。

在浏览器控件中显示其它类型的文档时,可以用IWebBrowser2的document属性来访问ActiveX文档,例如在显示Microsoft Word时,IWebBrowser2的document属性就是Word的文档对象,在显示文件夹的时候,IWebBrowser2的document属性就是文件夹对象等等。

扩展浏览器的宿主

浏览器控件在创建时会查询ActiveX容器的IOleClientSite的实现的如下接口:IDocHostUIHandler, IDocHostUIHandler2 and IDocHostShowUI

虽然在无法自定义ActiveX容器的情况下可以用ICustomDoc::SetUIHandler来挂接IDocHostUIHandler到浏览器控件,但是这样也会造成内存泄漏(http://support.microsoft.com/kb/893629)。一些类库,例如MFC、ATL和.Net类库都实现了IDocHostUIHandler接口。

除了专门用于浏览器用途的程序之外,通常都需要自定义浏览器控件的上下文菜单。这需要实现IDocHostUIHandler::ShowContextMenu。通常的实现包括完全禁用上下文菜单、完全替换上下文菜单、以及修改部分上下文菜单。经常被从上下文菜单中移除的菜单项包含查看源代码、刷新和属性。一种替代的方案是在容器中过滤右键消息(http://support.microsoft.com/kb/231578)。

与浏览器相比,一些Internet Explorer的宿主功能在浏览器控件中并不是默认启用。在某些场合,默认启用的宿主功能可能并非预期。这时需要实现IDocHostUIHandler::GetHostInfo。可以通过实现IDocHostUIHandler::GetHostInfo来自定义的功能包括:

  • 自动完成功能。对于用浏览器控件来做浏览器的场合来说,这个功能是有必要启用的。启用的方法是设置DOCHOSTUIFLAG_ENABLE_FORMS_AUTOCOMPLETE位
  • 如果浏览器中的链接网址包含非ASCII的字符,那么需要实现IDocHostUIHandler::GetHostInfo,并且在返回的DOCHOSTUIINFO结构中设置dwFlags成员的DOCHOSTUIFLAG_URL_ENCODING_ENABLE_UTF8位。这使得网址会在发送之前用UTF-8编码。
  • 3D边框、滚动条,禁用文字选择功能和禁用页面上的脚本。
  • 对于使用浏览器控件来做HTML编辑器的场合来说,有时需要修改默认的页面样式。这都需要实现IDocHostUIHandler::GetHostInfo(http://support.microsoft.com/kb/328803)。注意在有些版本的IE中IDocHostUIHandler::GetHostInfo只在MSHTML被初始化的时候被调用,所以如果你需要在MSHTML被初始化之后使你的修改生效,你需要浏览到一个Word之类的非HTML Active document文档,之后再浏览回来。

在使用浏览器控件来做数据录入界面的场合,需要更改浏览器控件默认的Tab键处理使得用户可以使用Tab键切换到容器中的其他控件。这需要实现IDocHostUIHandler::TranslateAccelerator来自定义浏览器控件的快捷键处理。对于MFC这样用消息钩子来做消息预处理的可自定义容器来说,也可以用PreTranslateMessage来过滤F5键盘消息,而不是实现IDocHostUIHandler::TranslateAccelerator。

在脚本中调用应用程序对浏览器控件的扩展,这需要实现IDocHostUIHandler::GetExternal。使用.Net的WebBrowser控件的话设置ObjectForScripting属性就可以了。

对于用浏览器控件来做HTML分析器的场合来说,有时需要屏蔽脚本产生的消息框。这需要实现IDocHostShowUI::ShowMessage,或者设置浏览器的Silent属性。

另外,浏览器也会查询IOleClientSite来获得其它的服务信息,例如

其他控制

对于用浏览器控件来做HTML分析器的场合来说,有时需要禁用浏览器的脚本、ActiveX或者图片下载。这可以通过在容器中实现IDispatch,处理DISPID_AMBIENT_DLCONTROL来做到(http://msdn.microsoft.com/library/default.asp?url=/workshop/browser/overview/Overview.asp)。

看来离线浏览的控制并不能用这种方法来控制(http://support.microsoft.com/kb/247336)。不过你可以自己编写一个HTTP层传递 BINDF_OFFLINEOPERATION标志 (http://groups-beta.google.com/group/microsoft.public.inetsdk.programming.mshtml_hosting/msg/76bf4910a289d4b3

在浏览器控件中java小程序可能不能正常运行,如果使用Sun JVM1.4之后的版本,可以用SetEnvironmentVariable 来设置JAVA_PLUGIN_WEBCONTROL_ENABLE为1来启用Sun JVM。

默认情况下在页面载入时会有点击声。屏蔽点击声的一个方法是在程序运行时修改注册表键(http://support.microsoft.com/kb/201901),另一个方法是将浏览器控件隐藏,在调用Navigate2之后再显示,但是这也需要锁定控件的更新区域(LockWindowUpdate)以避免闪烁。在IE7中,也可以调用 CoInternetSetFeatureEnabled函数,传递FEATURE_DISABLE_NAVIGATION_SOUNDS来禁用浏览时的声音。

在需要使用代理服务器时,有可能需要在应用程序中使用非默认的代理服务器设置。这可以通过调用UrlMkSetSessionOption来实现。

Overriding IInternetSecurityManager in a CComControl class
CAxWindow implements IObjectWithSite interface (get it with QueryHost
method). Call SetSite passing your implementation of IServiceProvider.
At this point, AxWin will forward all QueryService calls from hosted
WebBrowser to your implementation.

posted @ 2008-04-18 22:29 泡泡牛 阅读(1940) | 评论 (0)编辑 收藏
ie 攻击监测

对ie 的攻击分好几类, 有修改主页, 弹出窗口, 恶意插件, 网页木马等. 其中一些是利用了ie 的脚本的自带功能, 而另外一些要对ie 实施攻击后才能做到, 主要手段有利用第三方软件漏洞, ie 堆喷射等, 文章 [ [JavaScript中的堆风水]|[ http://www.team509.com/download/Heap%20Feng%20Shui%20in%20JavaScript_en_cn.htm ] ] 对堆喷射进行了介绍, 主要是利用覆盖函数返回地址或者对象的虚函数表来执行shellcode, 主要涉及到ie & 系统的内存管理.
一般shellcode 基本只完成攻击动作, 具体的对系统的后续攻击肯定离不了下载执行 exe 文件等动作, 并且在攻击ie 也会有各种症状, 可以根据这些基本实现恶意代码.

1. 根据ie 症状
当ie 访问恶意页面的遭受攻击时, 其重要表现是
a. 内存使用
b. cpu 使用率
所以实时监测这些参数可以基本判断是否有攻击


2. 根据行为
shellcode 如果被执行, 那么肯定会进行木马下载执行等步骤. 一般纯shellcode 里面的内容不会很多, 所以不可能完成很多复杂的攻击.
win32 创建进程的API调用串是:
WinExec/ShellExecuteA/CreateProcessA->CreateProcessInternalA->CreateProcessInternalW->ZwCreateProcessEx

CreateProcessW->CreateProcessInternalW->ZwCreateProcessEx

win32 要执行下载的API 主要是wsock32.dll 的
recv , recvfrom

所以对上述API 进行拦截, 一般可以检测到是否有ie 是否被攻击, 但是这个只能在攻击成功后, shellcode 执行后才能被检测到

3.
拦截一些操作注册表, 创建窗口等API , 可以做到防止被修改主页, 弹出窗口等

 

利用ms 的Detours 可以很容易的实现对系统 API 的hook
http://blog.csdn.net/hu0406/archive/2008/03/05/2150358.aspx
http://blog.csdn.net/hu0406/archive/2008/03/05/2150351.aspx
http://www.moon-soft.com/doc/2288.htm
http://blog.csdn.net/dedodong/archive/2006/10/07/1323925.aspx

[ [JavaScript中的堆风水]|[ http://www.team509.com/download/Heap%20Feng%20Shui%20in%20JavaScript_en_cn.htm ] ] ie 堆喷射

[ [也聊inline-hook]|[ http://blog.tom.com/tigerkings941220/article/9211.html ] ] 介绍了 进程自身保护(通过拦截LoadLibraryW)和IE漏洞防护(通过拦截CreateProcessInternalW)

[ [maxthon2(遨游2) mxsafe.dll对网页木马的防护以及绕过]|[ http://hi.baidu.com/54nop/blog/item/b52cff6e713964d980cb4a9e.html ] ] 讨论了maxthon2 防止网页木马的策略( 拦截 ZwCreateProcessEx/ZwCreateProcess, ZwWriteVirtualMemory, LoadLibraryExW, CreateProcessInternalW )以及对抗策略, 其实这个只是hook & unhook 的游戏了..

[ [小议PE病毒技术]|[ http://blog.vckbase.com/windowssky/archive/2007/04/17.html ] ] 介绍了 pe 病毒 & win32 进程加载内部

[ [360安全卫士程序员志愿者]|[ http://blog.csdn.net/dedodong/archive/2006/10/07/1323925.aspx ] ] 通过拦截 NtCreateProcessEx/NtCreateProcess 实现了"""编写一个程序,在此程序中运行a.exe,并使得a.exe认为是由explorer.exe运行它的"""

[ [阻击恶意软件--清除和保护你的网站的小技巧]|[ http://www.googlechinawebmaster.com/labels/badware.html ] ] google 上的对恶意软件(badware) 的介绍

[ [StopBadware Blog]|[ http://blogs.stopbadware.org/articles/2007/11 ] ]


 

posted @ 2008-04-18 19:49 泡泡牛 阅读(1903) | 评论 (1)编辑 收藏
Windows Winnet 实现HTTP 文件断点续传下载

1. MFC 下载文件

有2种方法:
a)
创建CInternetSession 对象 -> 调用 CInternetSession::OpenURL 该函数解析URL,然后打开与URL指定的服务器连接,同时返回一个只读的CInternetFile对象 -> CInternetFile::Read 读取文件 -> 析构CInternetSession

b)
创建CInternetSession 对象 -> 调用 CInternetSession::GetHttpConnection
返回CHttpConnection 对象 -> 调用CHttpConnection::OpenRequest 创建一个CHttpFile对象 -> CHttpFile::SendRequest 发送连接请求 -> CHttpFile::QueryInfo 获取HTTP 信息(比如文件大小, ETAG等) | CInternetFile::Read 读取文件 ->  析构CInternetSession

在上述过程中, 如果出现错误会抛出 CInternetException 异常
另外在打开链接前, 可以进行如下设置
CInternetSession::SetOption    读取或设置 InternetQuery 选项 (如超时或重试次数)
CInternetSession::EnableStatusCallback 设置回调函数监视session状态
CHttpFile::AddRequestHeaders   设置HTTP 请求头(需要在CHttpFile::SendRequest 前调用)


2. 实现断点续传
断点续传其实是通过在HTTP 请求头中设置要下载的文件区间来实现, 一个典型的HTTP 请求头是

  GEThttp://class/download.microtool.de:80/somedata.exe 
  Host:download.microtool.de
  Accept:*/*
  Pragma:no-cache
  Cache-Control:no-cache
  Referer:http://class/download.microtool.de/
  User-Agent:Mozilla/4.04[en](Win95;I;Nav)
  Range:bytes=554554-
 
注意最后一行:Range:bytes=554554-,格式为:Range: bytes=起始位置 - 终止位置,也就是说,我们可以通过设置Http请求头的设置起始结束位置,来获取HTTP文件的某一部分。


3. Win32 WinInet API 实现
和MFC 的函数对应, 执行下载操作大致需要的函数有:

InternetOpen是最先调用的函数,它返回HINTERNET句柄,习惯定义为hSession,即会话句柄, 相当于CInternetSession
InternetConnect使用hSession句柄,返回的是http连接句柄,定义为hConnect, 相当于 CInternetSession::GetHttpConnection
HttpOpenRequest使用hConnect句柄,返回的句柄是http请求句柄,定义为hRequest, 相当于 CHttpConnection::OpenRequest
HttpSendRequest(相当于 CHttpFile::SendRequest)、HttpQueryInfo、InternetSetFilePointer和InternetReadFile都使用HttpOpenRequest返回的句柄,即hRequest。

CInternetSession::OpenURL 相当于实现了 InternetConnect & HttpOpenRequest & HttpSendRequest 3个函数

当这几个句柄不再使用时,应该用函数InternetCloseHandle把它关闭,以释放其占用的资源。


用WinInet开发Internet客户端应用指南(一)  http://www.vckbase.com/document/viewdoc/?id=545
用WinInet开发Internet客户端应用指南(二) http://www.vckbase.com/document/viewdoc/?id=546
使用 CInternetSession 封装多线程 http 文件下载 http://www.vckbase.com/document/viewdoc/?id=1693
Http下载的断点续传       http://sunyan331.spaces.live.com/blog/cns!89B9F8BF2575E281!947.entry
HTTP服务器上断点下载文件(里面有很不错的源码)      http://www.cnitblog.com/wangk/archive/2007/05/22/5942.html
编写断点续传和多线程下载(有源码)   http://www.bbbh.org/20060427/2620/
WinInet: implementing resuming feature  http://www.clevercomponents.com/articles/article015/resuming.asp
(很详细的一个代码解释)Retrieving a file via. HTTP  http://www.codeproject.com/KB/IP/getwebfile.aspx 

posted @ 2008-04-17 23:01 泡泡牛 阅读(9854) | 评论 (0)编辑 收藏
MSNP协议的通信过程[En]

You have been using MSN for quite some time wondering how it works. Well You need not look any further. This article will not just tell you how MSN works but will also tell you how to make your own version of MSN messenger. You can download a sample application from here MSN Clone .Let's get ready to rumble!!!!

 

We can split up the working of MSN messenger into 2 phases

  • Authentication Phase

  • Instant Messaging Phase

The Authentication Phase involves logging into the MSN messenger server and also (friends) list retrieval in this case.

The Instant Messaging Phase involves sending/accepting requests for an Instant Messaging session and also sending/receiving messages.

 

The MSN messenger protocol is an ASCII based protocol. In other words the commands are in pure English !!!.The first phase involves connecting to an MSN messenger server .In this case we shall connect to the server 64.4.13.58 on port 1863(MSN messenger works through port 1863).

Once the connection is done we need to start the log in process. The first stage in this phase is the versioning stage. In this stage the client (in this case your app) lists/sends the versions that it can support to the server and waits for the server to respond.

VER 0 MSNP7 MSNP6 MSNP5 MSNP4 CVRO

In the MSN messenger protocol a "trial id" is sent along with every command. The trial id starts from 0 and is incremented every time the server responds successfully to the client's commands.

 

The server responds like this

VER 0 MSNP7 MSNP6 MSNP5 MSNP4

The Client and the server have agreed on a version in which they will communicate.

 

Next the client sends a request to the server asking it for the name of the security package it supports for authentication.

INF 1

Unlike Yahoo, Rediff and a few other Messengers MSN does not actually send the password as it is.It encrypts the password while sending it ensuring that your password will not be leaked out easily if somebody monitors your port.

 

The server responds with this

INF 1 MD5

Here MD5 is the name of the security package which the server currently supports.

Next the client sends the userid to the server

 

USR 2  MD5  I  venky_dude@hotmail.com

Here the server does a check whether it contains all the relevant details about the user for authentication .If it does not then it sends the following reply

 XFR 2  NS 64.4.13.55:1863  0

What the server says is that the client should connect to the Notification Server(NS) on 64.4.13.55 on port 1863. We close the current connection and repeat the  steps while being connected to the new server i.e  64.4.13.55

  • (client)   VER 3 MSNP7 MSNP6 MSNP5 MSNP4 CVRO

  • (server) VER 3 MSNP7 MSNP6 MSNP5 MSNP4 

  • (client)   INF  4

  • (server) INF  4  MD5

  • (client)  USR  5  MD5 I venky_dude@hotmail.com

Now the server to which we are connected to has the relevant information about the user trying to log in. The server replies this way

USR 5  MD5  S 989048851.1851137130

 The string which is sent by the server is the " MD5 Hash". It is a hash generated by the server and is used in the authentication process. The client then has to send the password which is encrypted using the MD5 algorithm.In effect the client has to send the unique MD5 equivalent of the MD5 hash i.e 989048851.1851137130 in this case and the password combined .i.e. MD5 equivalent of (hash+pass). In this case it turns out to be 3b7926d277068ec49576a0c40598ff21.

USR 6 MD5 S 3b7926d277068ec49576a0c40598ff21

If the password is right then the server replies with this

USR 6 OK venky_dude@hotmail.com venkat

Here the last word is the nickname/name by which the user is known.

In the new version of the protocol (MSNP7) the server sends additional data like some general information about the user and a authentication code something similar to a cookie which can be used for various other functions.

 

MSG Hotmai Hotmail 362
MIME-Version: 1.0
Content-Type: text/x-msmsgspro file; charset=UT
LoginTime: 1011252477
EmailEnabled: 1
MemberIdHigh: 84736
MemberIdLow: - 1434729391
lang _preference: 103
preferredEmai l: venky_dude@hotmail.com
country: IN
PostalCode:
Gender: M
Kid:0
Age: 22
sid: 517
kv: 2
MSPAuth: 2AAAAAAAADU0p4uxxxJtDJozJSlUTS0i7YpwnC9PUHRv56YKxxxCTWmg$$

Now we are logged into the server but our status is still offline. We need to change our status to online in order to send and receive messages. The client does this in the following way

CHG 7 NLN

The server replies with friends who are online and in various states.

CHG 7 NLN

ILN 7 NLN btxxxe@hotmail.com nick
ILN 7 AWY wmpyxxx@msn.com mike
ILN 7 BSY tehpxxpxx@hotmail.com yeaxxx

MSG Hotmail Hotmail 223
MIME-Version: 1.0
Content-Type: text/x-msmsgsinitialemailnotification; charset=UTF-8

Inbox-Unread: 293
Folders-Unread: 0
Inbox-URL: /cgi-bin/HoTMaiL
Folders-URL: /cgi-bin/folders
Post-URL: http://www.hotmail.com

 

The next command to be sent to the server pertains to the version of the client currently being used.The client send to the server it's version number and also information about the machine like the OS and the build.

CVR 8 0x0409 win 4.10 i386 MSMSGS 4.5.0127 MSMSGS

Here 0x409 win 4.10 i386 specifies that the client is running win98 on a intel microprocessor, and MSMSGS 4.5.0127 MSMSGS here specifies the version and build no of msmsgs.exe (basically the version no of MSN messenger).

The server responds with the url to download the latest version and some other info

CVR 8 4.5.0127 4.5.0127 1.0.0863 http://download.microsoft.com/download/msnmessenger/install/4.5/win98me/en-us/mmssetup.exe http://messenger.microsoft.com

 

It is not necesarry to send the CVR command, the messenger protocol will function properly regardless of this command being sent

 

To get a list of people who are in our friends list we may send this command

LST 9 RL

On sending this command the server will reply by sending the reverse list .The reverse list is basically a list of users who can see you when you are online and send you a message.You could alternatively also request for the forward list by sending LST 9 FL .The forward list contains a list of all users whom the user has added to his/her list.

The server responds this way

LST 9 RL 69 1 19 venky_dude@hotmail.com venkat
LST 9 RL 69 2 19 puxxxxx@hotmail.com PUJA
LST 9 RL 69 3 19 vancxxxxx@hotmail.com ramachandran
LST 9 RL 69 4 19 moxxxxx@hotmail.com chandramouli
LST 9 RL 69 5 19 v_n_xxxxx@hotmail.com Narayanaswamy
LST 9 RL 69 6 19 dexxxxx@hotmail.com Venkatesh
LST 9 RL 69 7 19 lousydxxxxx@hotmail.com deepika%20kalyani%20Vairam                                                  LST 9 RL 69 8 19 hexxxxxr@hotmail.com Hetchar%20Ramachandran
LST 9 RL 69 9 19 ambxxxxx@hotmail.com Aiyer
LST 9 RL 69 10 19 suxxx@hotmail.com Ganesh
LST 9 RL 69 11 19 deexxxxx@hotmail.com Deepak
LST 9 RL 69 12 19 anilxxxxx@hotmail.com anil
LST 9 RL 69 13 19 dixxxxx@hotmail.com <Diamond>
LST 9 RL 69 14 19 nvxxxx@hotmail.com giri
LST 9 RL 69 15 19 shxxx@hotmail.com Hari
LST 9 RL 69 16 19 radhikashuxxxxx@hotmail.com radhika
LST 9 RL 69 17 19 eskaxxxxx@hotmail.com kannan
LST 9 RL 69 18 19 shaxxxxx@hotmail.com Shankar
LST 9 RL 69 19 19 puneetagarxxxxx@hotmail.com puneet

 

 

*Every time a friend comes online the server(NS) sends us the following command

NLN 10NLN deaxxxx@hotmail.com Venkatesh

and when the friend goes offline the server sends us this

FLN 10 FLN deaxxxx@hotmail.com

With the MSNP7 protocol msn has introduced a new challenege authentication mechanism. The MSN server sends t a challenge key which the user has to authenticate succesfully in order for the session to continue.

CHL 0 20881396011366812350

 

The client has to send the md5 equivalent of this string which is formed by appending this hash with the string "Q1P7W2E4J9R8U3S5".So the final string which will be sent to the server will be the md5 equivalent of 20881396011366812350Q1P7W2E4J9R8U3S5

i.e MD5string(20881396011366812350Q1P7W2E4J9R8U3S5 )

So the client response would be something like this

QRY 18 msmsgs@msnmsgr.com 32
0212eaad0876afb8505859ca75d21a78

Here 18 is the trial id .Replace it by the appropriate trial id in your program .

The server will respond in the following way if the authentication is right

QRY 18

We have successfully logged into the MSN Messenger server. The Instant Messaging phase is next.






Instant Messaging in MSN Messenger is session based . The people in between whom the conversation is going to take place have to be in a session mode. We cannot send/receive messages unless we start a chat session with a user. 

There are basically two methods in  which a user can be in a chat session                                                           

  • User sends a chat session request to another user
  • User receives a chat session request from another user

 

User sends a chat session request

 

The client(user) sends a command to the server asking it for the address of the SwitchBoard(SB) server. All instant messaging conversation take place via the switchboard server.

XFR 9 SB

The server(SB) replies back with the ip address of the switchboard server(SB),the port on which to connect and a CKI hash. CKI is a security package and the client has to use the hash to connect to the switchboard server.

 XFR 9 SB 64.4.13.88:1863 CKI 989487642.2070896604     

Now we have to make another  new connection this time to the switchboard server. Our previous connection to the MSN messenger server  must be kept as it is. If we lose connection with that server we would log out.

After we have connected to the switchboard server(SB) we send the following command to the switchboard server.

USR 1 venky_dude@hotmail.com  989487642.2070896604  

If the CKI hash sent by us is right the server(SB) responds back with this

USR 1 OK venky_dude@hotmail.com venkat

After this has been done the user has to "Call" the other user to the chat session. This is done by sending the following command.

CAL 2 deadxxx@hotmail.com 

The server replies back with the a session id which it will pass on to the other user

CAL 2 RINGING 11717653

When the other user replies and is ready for a chat the server(SB) sends us this command

JOI deadlee@hotmail.com Venkatesh

This indicates that the other user has joined in the conversation and we are now ready to send and receive messages.

 

User receives a chat session request

When we are being invited to a chat session by a user the server(NS) send us the following message.

 

RNG 11742066 64.4.13.74:1863 CKI 989495494.750408580 deaxxxx@hotmail.com Venkatesh

Here the server(NS) sends us the session id ,the ip address of the SwitchBoard server to connect to,the port on which to connect to ,the CKI hash and the user trying to start a conversation with us.

Now we have to make another  new connection this time to the switchboard server. Our previous connection to the MSN messenger server  must be kept as it is. If we loose connection with that server we would log out.

We  connect to the switchboard server and send the following command

ANS 1 venky_dude@hotmail.com 989495494.750408580 11742066

Here we send our login name ,the CKI hash that was sent to us and the session Id that was sent to us

The server responds back with 

IRO 1 1 1 deaxxxx@hotmail.com Venkatesh

and

ANS 1 OK

We are now ready to send and receive messages.

 

Before sending/receiving messages let us see how the message is constructed.

When we are sending a message we build the header information  in the following way

MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
X-MMS-IM-Format: FN=Microsoft%20Sans%20Serif; EF=; CO=0; CS=0; PF=22

While sending a message we send it this way

MSG  2  N 137                                                                                                                                                            MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
X-MMS-IM-Format: FN=Microsoft%20Sans%20Serif; EF=; CO=0; CS=0; PF=22

hello

Here 2 is the trial id which has to incremented each time we send a message. 137 is the total length of the message i.e length of the header and length of the actual message that we are sending in this case it is 'hello'.

 While receiving the message it is more or less similar

Here is an example of a message received

MSG deaxxxx@hotmail.com Venkatesh 137
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
X-MMS-IM-Format: FN=Microsoft%20Sans%20Serif; EF=; CO=0; CS=0; PF=22

hello

 

When the other user is typing a message we receive the foll message

MSG deaxxxx@hotmail.com Venkatesh 100
MIME-Version: 1.0
Content-Type: text/x-msmsgscontrol
TypingUser: deaxxxx@hotmail.com

 

I guess now u guys are well on your way to make your own version of  MSN messenger.Post your doubts/comments/message in the Forumn .Do visit my projects page for some cool vb & c++ codes

 I'll keep adding to the protocol ,will try to put in addition functions like add/remove users ,rename user id,file transfer and voice chat, so keep checking back

 

References:

You could take a look at these sites for more information

This is the original protocol published by microsoft.

http://www.tlsecurity.net/Textware/Misc/draft-movva-msn-messenger-protocol-00.txt

This is the MD5 homepage where u can find programs/codes for doing the MD5 encryption

http://userpages.umbc.edu/~mabzug1/cs/md5/md5.html


MSNP10协议分析 01.登录 [by progsoft]
http://blog.csdn.net/progsoft/archive/2004/08/24/82938.aspx

MSN协议中文释义(Zz)
http://blog.csdn.net/fanccYang/archive/2005/03/16/321198.aspx

MSN Protocol Version 8
http://msnpiki.msnfanatic.com/index.php/Main_Page
介绍了MSNP 的整个协议 & 服务器 Notification Server (NS)  & Switchboard (SB)  的功能

MSN Messenger Protocol Version 9
http://zoronax.bot2k3.net/
很详细的介绍, 里面还有原始包例子

MSN Messenger Protocol
http://www.hypothetic.org/docs/msn/client/invitation_types.php
MSNP 的详细命令介绍

Reverse-engineering MSN Messenger's Video Conversation Formats[Ramiro Polla]
http://www.libing.net.cn/read.php/1031.htm

posted @ 2008-03-23 13:13 泡泡牛 阅读(4344) | 评论 (1)编辑 收藏
IE 异步可插入协议扩展

可插入协议扩展(Asynchronous Pluggable Protocols)主要基于异步的URL Moniker技术。 IE的URL Moniker在urlmon.dll 动态库中实现的, 有两种处理机制:
1. 根据URL 协议调用外部程序处理
比如telnet: or news: or mailto:,当访问这些url的时候会打开相应的程序来处理。
比如要添加note:协议(Registering an Application to a URL Protocol), 则只要修改注册表
[HKEY_CLASSES_ROOT]
    [note]
        (Default) = "URL:Note Protocol"
        URL Protocol = ""
        [DefaultIcon]
            (Default) = "notepad.exe"
        [shell]
            [open]
                [command]
                    (Default) = "c:\windows\notepad.exe %1"
在IE 中输入 note://xxx.txt 的时候会自动用notepad 打开xxx.txt 文件

2. 根据URL 协议调用类对象来处理
可以根据URL 协议或者MIME type 注册不同的处理对象
有两种方式:
a) 通过在注册表将URL 协议与COM 对象关联
主要在注册表中的
HKEY_CLASSES_ROOT\PROTOCOLS\Handler # URL 协议
HKEY_CLASSES_ROOT\PROTOCOLS\Filter # Mime Filter

b) 通过临时注册类对象将URL 协议与其关联
// 注册
CComPtr<IInternetSession> spSession;
CComPtr<IClassFactory>   spCFHTTP;
HRESULT hr = CoInternetGetSession(0, &spSession, 0);
hr = FilterFactory::CreateInstance(CLSID_HttpProtocol, &spCFHTTP);
hr = spSession->RegisterNameSpace(spCFHTTP, CLSID_NULL, L"http", 0, 0, 0);

// 反注册
spSession->UnregisterNameSpace(spCFHTTP, L"http");

 

3. FilterFactory 的实现可以参考
Asynchronous Pluggable Protocol Implementation with ATL
http://www.codeguru.com/cpp/com-tech/atl/misc/article.php/c37/

Internet Explorer下载文件的终极过滤
http://blog.csdn.net/111222/archive/2002/02/09/7255.aspx

通过Mime filter技术对网页源码进行过滤(监视下载文件)
http://blog.csdn.net/lion_wing/archive/2006/06/27/839134.aspx

HTML代码过滤技术
http://blog.csdn.net/lion_wing/articles/534716.aspx

About Asynchronous Pluggable Protocols (MSDN)

Internet Explorer 编程简述(九)在自己的浏览器中嵌入Google工具条
http://blog.csdn.net/CathyEagle/archive/2005/12/12/550698.aspx

放1000分,高手进来动手试试:如何提取AJAX里的HTML内容?
http://topic.csdn.net/t/20061214/12/5230161.html
这里主要通过监视IE 的下载从而保存Google Map 的地图数据文件.  通过监视http & text/html & application/javascript 的内容来获取图片文件URL 和 信息.. :)


posted @ 2008-03-23 00:38 泡泡牛 阅读(5205) | 评论 (1)编辑 收藏
const和指针组合的变化

a. char const* p     *p不能变,p能变,不需要初始化
b. const char* p     同a
c. char* const p     *p能变,p不能变,需要初始化
d. const char* const p  *p不能变,p不能变,需要初始化
d. const char const* p  *p不能变,p能变,不需要初始化
e. const char const* const p  错误
f. char const* const p  同d

posted @ 2008-02-27 11:03 泡泡牛 阅读(649) | 评论 (0)编辑 收藏
仅列出标题
共5页: 1 2 3 4 5