随笔 - 123, 文章 - 0, 评论 - 62, 引用 - 0
数据加载中……

置顶随笔

[置顶]安全伞IIS防火墙 v5.0.0.6

关于软件:

   
  

 “Safe3 Web Protector"是国内知名安全组织保护伞网络基于新一代Web安全技术开发的全方位企业Web信息安全产品。不仅能有效扫描各种WebShell,而且可以抵御各种Web攻击。

 

运行环境:

  • 该软件能运行在 Windows 2000/2003 下,支持 IIS5/IIS6
软件主要功能:
  • 流量控制。当前网络P2P软件泛滥成灾,多线程下载(如迅雷等)造成网站仅有的带宽 资源严重枯竭,不仅影响了网站的正常浏览,还得为额外的流量支付大批费用。Safe3 IIS Firewall能有效解决多线程下载带来的流量损失,帮助站长赢得网络先机。
     
  • SQL注入。如今各种SQL注入工具充斥着Internet,更甚者自动化蠕虫的Mass SQL Injection 一天就可以给成千上万的网站挂马,严重的损害了企业形象和数据安全。 Safe3 IIS Firewall采用注入模拟技术,有效拦截各种变种注入,帮助企业在互联网 中力挽狂澜,博得生存空间。 
     
  • CC攻击。在互联网竞争日益激烈的今天,不正当的竞争关系造成一方对另一方网站进 行严重的CC攻击,随之而来的是网站瘫痪和访问量急剧下降。Safe3 IIS Firewall能 强力阻止因CC造成的DDOS攻击,彻底解决非法的不正当的竞争关系。 
     
  • 资源盗链。当今网站间相互复制资源(图片和下载链接)已习以为常,不仅浪费带宽 资源,而且也是一种侵权行为。Safe3 IIS Firewall可以对网站资源进行高度保护, 防止盗链,保障原创网站的合法权益。   
       
  • XSS跨站。OWASP将XSS列为2007年WEB安全威胁第一位。黑客往Web页面里插 入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行, 从而达到恶意用户的特殊目的。Safe3 IIS Firewall可以有效检测包含XSS的恶意 URL并拦截。
     
  • 影音保护。只允许影音在线播放而不能直接下载,有力的保护了视频网站的带宽资源 和服务质量。
     
  • 网页防篡改。实时监控Web目录的变化情况并报警,强力阻止网页被篡改。    
       
  • Webshell扫描。通过分析可以扫描出99%的隐藏WebShell,保障web安全。   
       
  • 文件篡改检查。提取重要文件的特征,当网页代码被修改后可迅速从大量代码文件中
  • 找出隐藏的后门或木马的页面。   
       
  • 特殊后门检测。主要用于检测Win2003存在着一个文件解析路径的漏洞,当文件夹 名为类似hack.asp的时候(即文件夹名看起来像一个ASP文件的文件名),此时此文 件夹下的文本类型的文件都可以在IIS中被当做ASP程序来执行。另外比如像xxx..\ 这样的特殊文件夹会被黑客利用。这样的文件夹既普通删不掉也不能修改,放在里面 的木马一些杀毒软件视而不见。而此功能能有效找出这样的文件夹。   
       
  • 挂马清除助手。网上批量挂马的程序随处可见,给管理员手工清除造成了很大的困 难,此功能可轻松解决管理员的困境。   
       
  • Arp免疫。防止ARP挂马和敏感信息被监听截获。当黑客入侵同一网段的主机后如 果你的主机没做任何ARP防御措施,虽然你的主机没被黑但客户访问你的网站时网 页被插入恶意代码即ARP挂马。同时黑客可以嗅探到此网段下所以主机的ftp、http 等用户密码。著名黑客网站安全焦点就曾遭到这样的攻击。虽然基本解决了arp对 本地的威胁。但是arp还可以欺骗网关,会造成本地通讯中断,所以希望有条件的 朋友最好在网关上绑定本地ip和mac地址。
软件特点:
  • 防火墙采用C语言编写,运行效率极高。在每秒 100兆比特数据传输的大型服务器
  • 上运行良好,占用 CPU 很少。
  • 不写注册表,不捆绑任何插件,纯绿色无污染软件。
  • 超强安全防护:彻底防 SQL 注入攻击等攻击。
  • 彻底防迅雷、FlashGet等。
  • 无需重启 IIS,配置数据即刻生效。
  • 汇集保护伞网络多年安全经验,强大可靠。
  • 安装容易,配置简单,丰富的帮助文档指导安装,专门的配置工具实现轻松配置。
配置界面:
    V5.0.0.6版本的图形化的配置管理工具。     
        

下载地址:http://www.safe3.com.cn/safe3.rar

posted @ 2009-05-31 13:03 Safe3| 编辑

[置顶]Safe3SG安全网关

1. 产品简介
    Safe3SG安全网关系统(简称:Safe3SG)是Safe3 Network Center结合多年应用安全的攻防理论和应急响应实际经验积累的基础

上自主研发完成安全产品。传统的防火墙及入侵检测产品简单地通过WEB等应用的流量,Safe3SG是一种无缝地、透明地嵌入网络的嵌

入式设备。当数据包通过IPS时,它们能被完全检测出来以判断它们是合法的还是恶意的。这种实时防护是最有效的防止有任何目的的攻

击的方法。该产品致力于解决应用及业务逻辑层面的安全问题,广泛适用于“政府、运营商、金融、公安、教育、税务、电力、电子商务

”等所有涉及应用的各个行业。

2. 主要功能 
    Safe3SG安全网关系统,包括WEB应用防火墙及应用安全网关,提供网站应用各类的安全防护,如SQL注入攻击(SQL injections)

、跨站脚本攻击(cross-site scripting attacks)、会话窃取(session tampering)及缓存溢出( buffer overflows)等各类。
几乎所有的应用都易于被以上各类攻击方式攻击,因为大多数应用程序开发人员并没有开发过程中严格执行各类安全编程规范。Safe3SG

安全网关设计的理念就是抵御各类攻击和威胁行为:

• 最新网络蠕虫/Net Worm
• 跨站脚本攻击/Cross Site Scripting (XSS)
• SQL注入攻击/SQL injection flaws
• OS命令注入攻击/OS command injections
• 网站侦测攻击/Site reconnaissance
• 会话劫持攻击/Session hijacking
• 应用拒绝服务攻击、Application denial of service
• 恶意爬行攻击/Malicious probes/crawlers
• Cookie/会话窃取攻击/ Cookie/session tampering
• 路径模式发掘攻击/Path traversal
• 头信息窃取攻击/Header tampering
• 信息泄漏攻击/Information leakage
 
3. 产品部署 

Safe3SG安全网关系统设计理念是简单及串联接入任何既有的数据中心环境,快速保护。不需要对前端及后端服务器修改任何IP地址。

Safe3SG本身是透明的,所以不容易遭到攻击。
 
 

     Safe3SG解决方案的完整部分是数字疫苗® 服务。由Safe3 Network Center开发的数字疫苗服务为Safe3SG安全网关系统提供综

合的安全过滤,以提前防护新的zero-day攻击漏洞的被利用。这些过滤用来阻挡不同的针对一个漏洞的攻击,并在不影响网络性能的基

础上提供准确的攻击识别。数字疫苗每周自动升级,或是当有重要的漏洞和威胁出现时立即升级。

posted @ 2009-05-04 12:27 Safe3| 编辑

2009年7月3日

Editor漏洞问题总结

    该文被密码保护。

posted @ 2009-07-03 11:51 Safe3| 编辑

2009年7月1日

Safe3 网页防篡改 网络版(WProtector 1.1)

特点:

1、          现有网上流行的是第三代网页防篡改技术,本软件率先使用第四代网页防篡改技术。

2、          如第三代技术相比,本软件采用系统内核驱动直接拦截篡改,实现网页防篡改零延时,真正保证了网页篡改不被外界发现。

3、          采用服务端和客户端分离,不需要登录服务器,便可进行保护配置。

 

点击试用可以免费试用10天

下载地址:/Files/Safe3/WProtector.rar

posted @ 2009-07-01 11:14 Safe3 阅读(152) | 评论 (0)编辑

2009年6月29日

驱动研究日记-内核同步

    自旋锁
------------------------------------------------------
    自旋锁是专为防止多处理器并发而引入的一种锁,它在内核中大量应用于中断处理等部分(对于单处理器来说,防止中断处理中的并发可简单采用关闭中断的方式,不需要自旋锁)。

    如果被保护的共享资源只在进程上下文访问,使用信号量保护该共享资源非常合适,如果对共巷资源的访问时间非常短,自旋锁也可以。但是如果被保护的共享资源需要在中断上下文访问(包括底半部即中断处理句柄和顶半部即软中断),就必须使用自旋锁
    自旋锁最多只能被一个内核任务持有,如果一个内核任务试图请求一个已被争用(已经被持有)的自旋锁,那么这个任务就会一直进行忙循环——旋转——等待锁重新可用。要是锁未被争用,请求它的内核任务便能立刻得到它并且继续进行。自旋锁可以在任何时刻防止多于一个的内核任务同时进入临界区,因此这种锁可有效地避免多处理器上并发运行的内核任务竞争共享资源。
    事实上,自旋锁的初衷就是:在短期间内进行轻量级的锁定。一个被争用的自旋锁使得请求它的线程在等待锁重新可用的期间进行自旋(特别浪费处理器时间),所以自旋锁不应该被持有时间过长。如果需要长时间锁定的话, 最好使用信号量。
自旋锁的基本形式如下:
    spin_lock(&mr_lock);
    //临界区
    spin_unlock(&mr_lock);
    因为自旋锁在同一时刻只能被最多一个内核任务持有,所以一个时刻只有一个线程允许存在于临界区中。这点很好地满足了对称多处理机器需要的锁定服务。在单处理器上,自旋锁仅仅当作一个设置内核抢占的开关。如果内核抢占也不存在,那么自旋锁会在编译时被完全剔除出内核。
    简单的说,自旋锁在内核中主要用来防止多处理器中并发访问临界区,防止内核抢占造成的竞争。另外自旋锁不允许任务睡眠(持有自旋锁的任务睡眠会造成自死锁——因为睡眠有可能造成持有锁的内核任务被重新调度,而再次申请自己已持有的锁),它能够在中断上下文中使用。

      快速互斥对象

      有利的一面,快速互斥在没有实际竞争的情况下可以快速获取和释放。不利的一面,你不能递归获取一个快速互斥对象。即如果你拥有快速互斥对象你就不能发出APC,这意味着你将处于APC_LEVEL或更高的IRQL,在这一级上,线程优先级将失效,但你的代码将不受干扰地执行,除非有硬件中断发生。

表. 内核互斥和快速互斥的比较

内核互斥 快速互斥
可以被单线程递归获取(系统为其维护一个请求计数器) 不能被递归获取
速度慢 速度快
所有者只能收到“特殊的”内核APC 所有者不能收到任何APC
所有者不能被换出内存 不自动提升被阻塞线程的优先级(如果运行在大于或等于APC_LEVEL级),除非你使用XxxUnsafe函数并且执行在PASSIVE_LEVEL级上
可以是多对象等待的一部分 不能作为KeWaitForMultipleObjects的参数使用

 

表. 快速互斥服务函数

服务函数 描述
ExAcquireFastMutex 获取快速互斥,如果必要则等待
ExAcquireFastMutexUnsafe 获取快速互斥,如果必要则等待,调用者必须先停止接收APC
ExInitializeFastMutex 初始化快速互斥对象
ExReleaseFastMutex 释放快速互斥
ExReleaseFastMutexUnsafe 释放快速互斥,不解除APC提交禁止
ExTryToAcquireFastMutex 获取快速互斥,如果可能,立即获取不等待

 

ExAcquireFastMutex等待互斥变成有效状态,然后再把所有权赋给调用线程,最后把处理器当前的IRQL提升到APC_LEVEL。IRQL提升的结果是阻止所有APC的提交。ExAcquireFastMutexUnsafe不改变IRQL。在使用这个“不安全”的函数获取快速互斥前你需要考虑潜在的死锁可能。必须避免运行在同一线程上下文下的APC例程获取同一个互斥或任何其它不能被递归锁定的对象。否则你将冒随时死锁那个线程的风险。

如果你不想在互斥没立即有效的情况下等待,使用“尝试获取”函数:

ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
BOOLEAN acquired = ExTryToAcquireFastMutex(FastMutex);

如果返回值为TRUE,则你已经拥有了该互斥。如果为FALSE,表明该互斥已经被别人占有,你不能获取。

为了释放一个快速互斥并允许其它线程请求它,调用适当的释放函数:

ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
ExReleaseFastMutex(FastMutex);

ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL);
ExReleaseFastMutexUnsafe(FastMutex);

快速互斥之所以快速是因为互斥的获取和释放步骤都为没有竞争的情况做了优化。获取互斥的关键步骤是自动减和测试一个整数计数器,该计数器指出有多少线程占有或等待该互斥。如果测试表明没有其它线程占有该互斥,则没有额外的工作需要做。如果测试表明有其它线程拥有该互斥,则当前线程将阻塞在一个同步事件上,该同步事件是fastmutext对象的一部分。释放互斥时必须自动增并测试计数器。如果测试表明当前没有等待线程,则没有额外的工作要做。如果还有线程在等待,则互斥所有者需调用KeSetEvent函数释放一个等待线程。

     互锁运算
在WDM驱动程序能调用的函数中,有一些函数可以以线程安全和多处理器安全的方式执行算术运算。这些例程有两种形式,第一种形式以Interlocked为名字开头,它们可以执行原子操作,其它线程或CPU不能干扰它们的执行。另一种形式以ExInterlocked为名字开头,它们使用自旋锁。

表 互锁运算服务函数

服务函数 描述
InterlockedCompareExchange 比较并有条件地交换两个值
InterlockedDecrement 整数减1
InterlockedExchange 交换两个值
InterlockedExchangeAdd 加两个值并返回和
InterlockedIncrement 整数加1
ExInterlockedAddLargeInteger 向64位整数加
ExInterlockedAddLargeStatistic 向ULONG加
ExInterlockedAddUlong 向ULONG加并返回原始值
ExInterlockedCompareExchange64 交换两个64位值

InterlockedXxx函数可以在任意IRQL上调用;由于该函数不需要自旋锁,所以它们还可以在PASSIVE_LEVEL级上处理分页数据尽管ExInterlockedXxx函数也可以在任意IRQL上调用,但它们需要在大于或等于DISPATCH_LEVEL级上操作目标数据,所以它们的参数需要在非分页内存中。使用ExInterlockedXxx的唯一原因是,如果你有一个数据变量,且需要增减该变量的值,并且有时还需要用其它指令序列直接访问该变量。你可以在对该变量的多条访问代码周围明确声明自旋锁,然后仅用ExInterlockedXxx函数执行简单的增减操作。

InterlockedXxx函数
InterlockedIncrement向内存中的长整型变量加1,并返回加1后的值:

LONG result = InterlockedIncrement(pLong);
 

pLong是类型为LONG的变量的地址,概念上,该函数的操作等价于C语句:return *pLong,但它与简单的C语句的不同地方是提供了线程安全和多处理器安全。InterlockedIncrement可以保证整数变量被成功地增1,即使其它CPU上的线程或同一CPU上的其它线程同时尝试改变这个整数的值。就操作本身来说,它不能保证所返回的值仍是该变量当前的值,甚至即使仅仅过了一个机器指令周期,因为一旦这个增1原子操作完成,其它线程或CPU就可能立即修改这个变量。

InterlockedDecrement除了执行减1操作外,其它方面同上。

LONG result = InterlockedDecrement(pLong);
 

InterlockedCompareExchange函数可以这样调用:

LONG target;
LONG result = InterlockedCompareExchange(&target, newval, oldval);
 

target是一个类型为LONG的整数,既可以用于函数的输入也可以用于函数的输出,oldval是你对target变量的猜测值,如果这个猜测正确,则newval被装入target。该函数的内部操作与下面C代码类似,但它是以原子方式执行整个操作,即它是线程安全和多处理器安全的:

LONG CompareExchange(PLONG ptarget, LONG newval, LONG oldval)
{
  LONG value = *ptarget;
  if (value == oldval)
    *ptarget = newval;
  return value;
}
 

换句话说,该函数总是返回target变量的历史值给你。此外,如果这个历史值等于oldval,那么它把target的值设置为newval。该函数用原子操作实现比较和交换,而交换仅在历史值猜测正确的情况下才发生。

你还可以调用InterlockedCompareExchangePointer函数来执行类似的比较和交换操作,但该函数使用指针参数。该函数或者定义为编译器内部的内联函数,或者是一个真实的函数,取决于你编译时平台的指针宽度,以及编译器生成内联代码的能力。下面例子中使用了这个指针版本的比较交换函数,它把一个结构加到一个单链表的头部,而不用使用自旋锁或提升IRQL:

typedef struct _SOMESTRUCTURE {
  struct _SOMESTRUCTURE* next;
  ...
} SOMESTRUCTURE, *PSOMESTRUCTURE;
...
void InsertElement(PSOMESTRUCTURE p, PSOMESTRUCTURE* anchor)
{
  PSOMESTRUCTURE next, first;
  do
  {
    p->next = first = *anchor;
    next = InterlockedCompareExchangePointer(anchor, p, first);
  }
  while (next != first);
}
 

每一次循环中,我们都假设新元素将连接到链表的当前头部,即变量first中的地址。然后我们调用InterlockedCompareExchangePointer函数来查看anchor是否仍指向first,即使在过了几纳秒之后。如果是这样,InterlockedCompareExchangePointer将设置anchor,使其指向新元素p。并且如果InterlockedCompareExchangePointer的返回值也与我们的假设一致,则循环终止。如果由于某种原因,anchor不再指向那个first元素(可能被其它并发线程或CPU修改过),我们将发现这个事实并重复循环。

最后一个函数是InterlockedExchange,它使用原子操作替换整数变量的值并返回该变量的历史值:

LONG value;
LONG oldval = InterlockedExchange(&value, newval);
 

正如你猜到的,还有一个InterlockedExchangePointer函数,它交换指针值(64位或32位,取决于具体平台)。

ExInterlockedXxx函数
每一个ExInterlockedXxx函数都需要在调用前创建并初始化一个自旋锁。注意,这些函数的操作数必须存在于非分页内存中,因为这些函数在提升的IRQL上操作数据。

ExInterlockedAddLargeInteger加两个64位整数并返回被加数的历史值:

LARGE_INTEGER value, increment;
KSPIN_LOCK spinlock;
LARGE_INTEGER prev = ExInterlockedAddLargeInteger(&value, increment, &spinlock);
 

value是被加数。increment是加数。spinlock是一个已经初始化过的自旋锁。返回值是被加数的历史值。该函数的操作过程与下面代码类似,但除了自旋锁的保护:

__int64 AddLargeInteger(__int64* pvalue, __int64 increment)
{
  __int64 prev = *pvalue;
  *pvalue = increment;
  return prev;
}
 

注意,并不是所有编译器都支持__int64整型类型,并且不是所有计算机都能用原子指令方式执行64位加操作。

ExInterlockedAddUlong与ExInterlockedAddLargeInteger类似,但它的操作数是32位无符号整数:

ULONG value, increment;
KSPIN_LOCK spinlock;
ULONG prev = ExInterlockedAddUlong(&value, increment, &spinlock);
 

该函数同样返回被加数的加前值。

ExInterlockedAddLargeStatistic与ExInterlockedAddUlong类似,但它把32位值加到64位值上。该函数在本书出版时还没有在DDK中公开,所以我在这里仅给出它的原型:

VOID ExInterlockedAddLargeStatistic(PLARGE_INTEGER Addend, ULONG Increment);
 

该函数要比ExInterlockedAddUlong函数快,因为它不需要返回被加数的加前值。因此,它也不需要使用自旋锁来同步。该函数的操作也是原子性的,但仅限于调用同一函数的其它调用者。换句话说,如果你在一个CPU上调用ExInterlockedAddLargeStatistic函数,而同时另一个CPU上的代码正访问Addend变量,那么你将得到不一致的结果。我将用该函数在Intel x86上的执行代码(并不是实际的源代码)来解释这个原因:

mov eax, Addend
mov ecx, Increment
lock add [eax], ecx
lock adc [eax 4], 0
 

这个代码在低32位没有进位的情况下可以正常工作,但如果存在着进位,那么在ADD和ADC指令之间其它CPU可能进入,如果那个CPU调用的ExInterlockedCompareExchange64函数复制了这个时刻的64位变量值,那么它得到值将是不正确的。即使每个加法指令前都有lock前缀保护其操作的原子性(多CPU之间),但多个这样的指令组成的代码块将无法保持原子性。

链表的互锁访问
Windows NT的executive部件提供了三组特殊的链表访问函数,它们可以提供线程安全的和多处理器安全的链表访问。这些函数支持双链表、单链表,和一种称为S链表(S-List)的特殊单链表。我在前面章中已经讨论过单链表和双链表的非互锁访问。在这里,我将解释这些链表的互锁访问。

如果你需要一个FIFO队列,你应该使用双链表。如果你需要一个线程安全的和多处理器安全的下推栈,你应该使用S链表。为了以线程安全和多处理器安全的方式使用这些链表,你必须为它们分配并初始化一个自旋锁。但S链表并没有真正使用自旋锁。S链表中存在顺序号,内核利用它可以实现比较-交换操作的原子性。

用于互锁访问各种链表对象的函数都十分相似,所以我将以函数的功能来组织这些段。我将解释如何初始化这三种链表,如何向这三种链表中插入元素,如何从这三种链表中删除元素。

初始化
你可以象下面这样初始化这些链表:

LIST_ENTRY DoubleHead;
SINGLE_LIST_ENTRY SingleHead;
SLIST_HEADER SListHead;

InitializeListHead(&DoubleHead);

SingleHead.Next = NULL;

ExInitializeSListHead(&SListHead);
 

不要忘记为每种链表分配并初始化一个自旋锁。另外,链表头和所有链表元素的存储都必须来自非分页内存,因为支持例程需要在提升的IRQL上访问这些链表。注意,在链表头的初始化过程中不需要使用自旋锁,因为此时不存在竞争。

插入元素
双链表可以在头部或尾部插入元素,但单链表和S链表仅能在头部插入元素:

PLIST_ENTRY pdElement, pdPrevHead, pdPrevTail;
PSINGLE_LIST_ENTRY psElement, psPrevHead;
PKSPIN_LOCK spinlock;

pdPrevHead = ExInterlockedInsertHeadList(&DoubleHead, pdElement, spinlock);
pdPrevTail = ExInterlockedInsertTailList(&DoubleHead, pdElement, spinlock);

psPrevHead = ExInterlockedPushEntryList(&SingleHead, psElement, spinlock);

psPrevHead = ExInterlockedPushEntrySList(&SListHead, psElement, spinlock);
 

返回值是插入前链表头(或尾)的地址。注意,被插入的链表元素地址是一个链表表项结构的地址,这个地址通常要嵌入到更大的应用结构中,调用CONTAINING_RECORD宏可以获得外围应用结构的地址。

删除元素
你可以从这些链表的头部删除元素:

pdElement = ExInterlockedRemoveHeadList(&DoubleHead, spinlock);

psElement = ExInterlockedPopEntryList(&SingleHead, spinlock);

psElement = ExInterlockedPopEntrySList(&SListHead, spinlock);
 

如果链表为空则函数的返回值为NULL。你应该先测试返回值是否为NULL,然后再用CONTAINING_RECORD宏取外围应用结构的指针。

IRQL的限制
你只能在低于或等于DISPATCH_LEVEL级上调用S链表函数。只要所有对链表的引用都使用ExInterlockedXxx函数,那么访问双链表和单链表的ExInterlockedXxx函数可以在任何IRQL上调用。这些函数没有IRQL限制的原因是因为它们在执行时都禁止了中断,这就等于把IRQL提升到最高可能的级别。一旦中断被禁止,这些函数就获取你指定的自旋锁。因为此时在同一CPU上没有其它代码能获得控制,并且其它CPU上的代码也不能获取那个自旋锁,所以你的链表是安全的。

注意
--------------------------------------------------------------------------------
DDK文档中关于这条规则的陈述过于严格,它认为所有调用者必须运行在低于或等于你的中断对象DIRQL之下的某个IRQL上。实际上,并不需要所有调用者都在同一IRQL上,同样也不必限制IRQL必须小于或等于DIRQL。
最好在代码的一个部分使用ExInterlockedXxx互锁函数访问单链表或双链表(不包括S链表),在另一部分使用非互锁函数(InsertHeadList等等)。在使用一个非互锁原语前,应该提前获取调用使用的自旋锁。另外,应该低于或等于DISPATCH_LEVEL级访问链表。因为自旋锁不可以递归获得。例如:

// Access list using noninterlocked calls:

VOID Function1()
{
  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
  KIRQL oldirql;
  KeAcquireSpinLock(spinlock, &oldirql);
  InsertHeadList(...);
  RemoveTailList(...);
  ...
  KeReleaseSpinLock(spinlock, oldirql);
}

// Access list using interlocked calls:

VOID Function2()
{
  ASSERT(KeGetCurrentIrql() <= DISPATCH_LEVEL);
  ExInterlockedInsertTailList(..., spinlock);
}
 

第一个函数必须运行在低于或等于DISPATCH_LEVEL上,因为这里需要调用KeAcquireSpinLock函数。第二个函数的IRQL限定原因是这样的:假定Function1在准备访问链表阶段获取了自旋锁,而获取自旋锁时需要把IRQL暂时提升到DISPATCH_LEVEL级,现在再假定在同一CPU上有一个中断发生在更高级的IRQL上,然后Function2获得了控制,而它又调用了一个ExInterlockedXxx函数,而此时内核正要获取同一个自旋锁,因此CPU将死锁。导致这个问题的原因是允许用同一个自旋锁的代码运行在两个不同的IRQL上:Function1在DISPATCH_LEVEL级上,而Function2在HIGH_LEVEL级上。

共享数据的非互锁访问
如果你要提取一个对齐的数据,那么调用任何一个InterlockedXxx函数就可以正确地做到。支持NT的CPU必然保证你能获得一个首尾一致的值,即使互锁操作发生在数据被提取前后的短暂时间内。然而,如果数据没有对齐,当前的互锁访问也会禁止其它的互锁访问,不至于造成并发访问而取到不一致的值。想象一下,如果有一个整数,其大小跨过了物理内存中的缓冲边界,此时,CPU A想提取这个整数,而CPU B在同一时间要在这个值上执行一个互锁加1操作。那么即将发生的一系列事情可能是:(a) CPU A提取了含有该值高位部分的缓冲线,(b) CPU B执行了一个互锁增1操作并向该值高位部分产生了一个进位,(c) CPU A接着提取了包含该值低位部分的缓冲线。确保这个值不跨过一个缓冲界限可以避免这个问题,但最容易的解决办法是确保该值按其数据类型的自然边界对齐,如ULONG类型按4字节对齐。

posted @ 2009-06-29 09:08 Safe3| 编辑

驱动研究日记-链表+后备链表

链表的使用:

①     定义一个链表头,单链表为SINGLE_LIST_ENTRY,双链表为LIST_ENTRY。然后要对链表头进行初始化。单链表链表头初始化要将它的Next域设为NULL,双链表直接调用InitializeListHead。

②     往链表中插入元素:

对于单链表使用PushEntryList双链表可以从链表头也可以从链表尾插入:InsertHeadList,InsertTailList。这三个函数都有两个参数,第一个参数为指向链表头的指针,第二个参数为要插入的元素的链接域。

③     从链表中删除元素:

与插入元素类似,单链表使用PtryList,双链表使用RemoveEntryList,RemoveHeadList,RemoveTailList。他们的参数都是指向链表头的指针。

④     为了得到链表中的元素,我们使用CONTAINING_RECORD宏。

 

 后备链表        

         如果你需要固定尺寸的内存块,但是你事先并不知道它的大小和使用频率,这样的话为了性能的原因,你还是使用后备列表(Lookaside Lists)吧,后备列表是只有内核模式才有的。
          后备列表是一组事先分配的相同尺寸的内存块。这些块有些在使用,有些没被使用。当有内存分配请求的时候,系统会遍历这个列表寻找最近的未分配的块。如果未分配的块找到了,分配请求就很快被满足了。否则系统必须从分页或不分页内存池去分配。根据列表中分配行为发生的频率,系统会自动调整未分配块的数量来满足分配请求,分配的频率越高,会有越多的块被存储在后备列表中。后备列表如果总是不被使用,也会自动减少空间大小。

       

        使用后备链表:

①     为一个PAGED_LOOKASIDE_LIST或NPAGED_LOOKASIDE_LIST对象保留非分页内存。

         这里这两种对象都是用来管理后备链表,它本身只能位于非分页内存,因为系统需要在提升的IRQL级上访问它。这两个对象十分相似,但分页类型的链表使用FAST_MUTEX来同步,而非分页类型的链表要使用自旋锁。

②     调用相应的初始化函数对Lookaside链表进行初始化。

③     从Lookaside链表上面分配存储,使用AllocateFrom()函数。

④     使用完之后,将从Lookaside上面申请的存储空间返回Lookaside。

⑤     调用Delete函数删除链表。

服务函数

描述

ExInitializeNPagedLookasideList
ExInitializePagedLookasideList

初始化lookaside链表

ExAllocateFromNPagedLookasideList
ExAllocateFromPagedLookasideList

分配一个固定大小的内存块

ExFreeToNPagedLookasideList
ExFreeToPagedLookasideList

将一个内存块释放回lookaside链表

ExDeleteNPagedLookasideList
ExDeletePagedLookasideList

删除lookaside链表

posted @ 2009-06-29 09:01 Safe3| 编辑

Windows NT 驱动程序开发人员提示

下面是开发人员在使用 Windows NT 设备驱动程序时应当避免的事项列表:

  1. 一定不要在没有标注 I/O 请求数据包 (IRP) 挂起 (IoMarkIrpPending) 的情况下通过调度例程返回 STATUS_PENDING。
  2. 一定不要通过中断服务例程 (ISR) 调用 KeSynchronizeExecution。 它会使系统死锁。
  3. 一定不要将 DeviceObject->Flags 设置为 DO_BUFFERED_IO 和 DO_DIRECT_IO。 它会扰乱系统并最终导致致命错误。 而且,一定不要在 DeviceObject->Flags 中设置 METHOD_BUFFERED、METHOD_NEITHER、METHOD_IN_DIRECT 或 METHOD_OUT_DIRECT,因为这些值只在定义 IOCTL 时使用。
  4. 一定不要通过页面缓冲池分配调度程序对象。 如果这样做,将会偶尔导致系统故障检测 (Bugcheck)。
  5. 当运行于 IRQL >= DISPATCH_LEVEL 时,一定不要通过页面缓冲池分配内存,或访问页面缓冲池中的内存。 这是一个致命错误。
  6. 一定不要在 IRQL >= DISPATCH_LEVEL 上等候核心调度程序对象出现非零间隔。 这是一个致命错误。
  7. 在 IRQL >= DISPATCH_LEVEL 上执行时,一定不要调用任何导致调用线程发生直接或间接等待的函数。 这是一个致命错误。
  8. 一定不要把中断请求级别 (IRQL) 降低到低于您的顶级例程被调用的级别。
  9. 如果没有调用过 KeRaiseIrql(),则一定不要调用 KeLowerIrql()。
  10. 一定不要使处理器 (KeStallExecutionProcessor) 停止运转的时间超过 50 微秒。
  11. 一定不要使旋转锁 (Spin Lock) 保持锁定状态的时间超过您的需要。 要使系统获得更好的总体性能,请不要使任何系统范围内有效的旋转锁的锁定时间超过 25 微秒。
  12. 当 IRQL 大于 DISPATCH_LEVEL 时,一定不要调用 KeAcquireSpinLock 和 KeReleaseSpinLock,或 KeAcquireSpinLockAtDpcLevel 和 KeReleaseSpinLockFromDpcLevel。
  13. 一定不要通过调用 KeReleaseSpinLockFromDpcLevel 来释放 KeAcquireSpinLock 所获取的旋转锁,因为这会使原始 IRQL 无法被还原。
  14. 一定不要在 ISR 或 SynchCritSection 例程中调用 KeAcquireSpinLock 和 KeReleaseSpinLock 或者其它任何使用可执行旋转锁的例程。
  15. 当您在例程中而不是在 DriverEntry 中创建设备对象时,一定不要忘记清除 DO_DEVICE_INITIALIZING 标记。
  16. 一定不要同时在不同处理器的多个线程中将延时过程调用 (DPC) 对象添加到队列中(使用 KeInsertQueueDpc)。 这会导致致命错误。
  17. 一定不要通过 CutomerTimerDPC 例程释放周期定时器。 您可以通过 DPC 例程释放非周期定时器。
  18. 一定不要将相同的 DPC 指针传递给 KeSetTimer,或者 KeSetTimerEx (CustomTimerDpc) 和 KeInsertQueueDpc (CustomDpc),因为这将导致竞争。
  19. 旋转锁锁定时,一定不要调用 IoStartNextPacket。 这将使系统死锁。
  20. 旋转锁锁定时,一定不要调用 IoCompleteRequest。 这将使系统死锁。
  21. 如果您的驱动程序设置了完成例程,那么一定不要在没有把完成例程设置为 NULL 的情况下调用 IoCompleteRequest。
  22. 调用 IoCompleteRequest 之前,一定不要忘记设置 IRP 中的 I/O 状态区。
  23. 在将 IRP 添加到队列中或将它发送到另一个驱动程序 (IoCallDriver) 之后,一定不要调用 IoMarkPending。 在驱动程序调用 IoMarkPending 之前,IRP 可能已经完成,由此可能发生故障检测。 对于包含完成例程的驱动程序,如果设置了 Irp->PendingReturned,则完成例程必须调用 IoMarkPending。
  24. 一定不要在已经对某个 IRP 调用 IoCompleteRequest 之后再去访问该 IRP。
  25. 一定不要对不属于您的驱动程序的 IRP 调用 IoCancelIrp,除非您知道该 IRP 还没有完成。
  26. 在您的调度例程返回到调用者之前,一定不要对您的调度例程正在处理的 IRP 调用 IoCancelIrp。
  27. 一定不要从中间驱动程序调用 IoMakeAssociatedIrp 来为较低的驱动程序创建 IRP。 在中间驱动程序中所获得的 IRP 可能是已被关联的 IRP,而您不能将其它 IRP 关联到已经被关联的 IRP。
  28. 一定不要对使用缓冲 I/O 而设置的 IRP 调用 IoMakeAssociatedIrp。
  29. 一定不要简单地将指向设备 I/O 寄存器的虚拟指针解除引用并访问这些指针。 始终使用正确的硬件抽象层 (HAL) 函数来访问设备。
  30. 如果 IRP 或设备对象可能在 DISPATCH 级别被修改,那么一定不要通过 ISR 来访问 它。 在对称多处理器系统中,这会造成数据损坏。
  31. 正在高级 IRQL 中运行时,如果数据可能被低级 IROL 代码写入,那么一定不要修改该数据。 应当使用 KeSynchronizeExecution 例程。
  32. 在获取系统范围的取消旋转锁 (IoAcquireCancelSpinLock) 之前,一定不要在您的 DispatchCleanup 例程中获取驱动程序自己的旋转锁(如果有的话)。 要避免可能出现的死锁,一定要在驱动程序中遵循一致的锁定获取层次结构。
  33. 一定不要在取消例程中调用 IoAcquireCancelSpinLock,因为该例程被调用时已经获取了系统级的取消旋转锁。
  34. 在从取消例程返回之前,一定不要忘记调用 IoReleaseCancelSpinLock。
  35. 一定不要使用基于 IRQL 的同步,因为它只对单处理器系统有效。 提高单处理器上的 IRQL 将不会掩蔽在其它处理器上的中断。
  36. 一定不要对重叠的内存地址范围使用 RtlCopyMemory。 应当使用 RtlMoveMemory。
  37. 一定不要假定页面大小是常量,即使是用于给定的 CPU。 为了保持可移植性,应当使用 PAGE_SIZE 以及在头文件中所定义的其它页面相关常量。
  38. 一定不要从引导\系统初始化阶段加载的驱动程序的 DriverEntry 例程中访问除 Registry\Machine\Hardware 和 Registry\Machine\System 以外的任何注册表项。
  39. 一定不要为了加载驱动程序而在驱动程序的注册表项 (Registry\Machine\System\CurrentControlSet\Services) 下创建 Enum 项。 系统将动态地创建该项。
  40. 如果没有先在注册表中申请必需的与总线相关的 I/O 端口、内存范围、中断或直接内存访问 (DMA) 通道/端口等硬件资源,一定不要初始化物理设备。
  41. 一定不要在您的 DriverEntry 例程调用 IoRegisterDriverReinitialization,除非重初始化例程返回了 STATUS_SUCCESS。
  42. IRQL 为 PASSIVE_LEVEL 时,一定不要从被页面调度的线程或驱动程序例程中在 Wait 参数被设置为 TRUE 的情况下调用 KeSetEvent。 如果碰巧在调用 KeSetEvent 和 KeWait..Object(s) 之间您的例程被页面调度出去,这类调用就会导致致命的页面错误。
  43. 与上例相同的条件下,同样不能调用 KeReleaseSemaphore 。
  44. 与上例相同的条件下,同样不能调用 KeReleaseMutex 。
  45. 一定不要通过零售的 Windows NT 驱动程序调用 KeBugCheckEx 或 KeBugCheck 来停止系统的运行,除非您遇到的是破坏系统内存并最终导致系统进入故障检测的重要错误。 应当始终巧妙地处理错误条件。
  46. 一定不要假定 IoTimer 例程将会准确地在一秒边界处被调用,因为任何特定 IoTimer 例程的调用间隔最终取决于系统时钟。
  47. 一定不要从核心模式的设备驱动程序调用 Win32 应用程序编程接口 (API)。
  48. 一定不要使用会导致堆栈溢出的递归函数,因为调用线程的核心模式堆栈不能动态增长。
  49. 在处理多个中断的 ISR 例程中,一定不要使用中断对象指针 (PKINTERRUPT) 来标识中断,因为您在 ISR 中所获得的中断对象地址不会始终与您通过 IoConnectInterrupt 所获得的地址相同。 要想识别当前发生中断的设备,应当仅使用您在 IoConnectInterrupt 中所指定的 ServiceContext 值。
  50. 如果没有清零 CustomTimerDpc (KeCancelTimer),一定不要卸载驱动程序。 如果在卸载驱动程序后启动 DPC,它可能调用不存在的代码,并导致系统进入故障检测查。
  51. 如果 IRP 中设置了某个驱动程序的 I/O CompletionRoutine,那么一定要等到所有这些 IRP 完成之后,才能卸载该驱动程序。 如果卸载驱动程序后,IRP 被更低级的驱动程序完成,那么系统会试图执行不存在的代码,并导致系统崩溃。
  52. 一定要等到驱动程序准备好要处理某个设备中断时,才能启用该设备中断。 应当只在完成驱动程序初始化之后才启用它,执行 ISR 和 DPC 时,系统才能安全的访问设备对象的若干私有成员。
  53. 在旋转锁锁定时,一定不要调用驱动程序以外的代码,因为这会引起死锁。
  54. 如果您的驱动程序通过 IoBuildAsynchronousFsdRequest/IoAllocateIrp 创建了一个 IRP,那么,一定不要从您的 I/O CompletionRoutine 为这个 IRP 返回 STATUS_MORE_PROCESSING_REQUIRED 以外的任何状态,因为该 IRP 没有为与完成有关的 I/O 管理器的处理后工作做好准备。 这样的 IRP 应当被驱动程序显式地释放 (IoFreeIrp)。 如果本来没有打算重用 IRP,可以在返回状态 STATUS_MORE_PROCESSING_REQUIRED 之前,在 CompletionRoutine 中将它释放。
  55. 一定不要在任意的线程上下文中使用 IoBuildSynchronousFsdRequest/IoBuildDeviceIoControlRequest 来分配 IRP,因为该 IRP 依然与该线程保持关联 (Irp->ThreadListEntry),直到它被释放。
  56. 如果已经使用 IoAllocateIrp 在 ChargeQuota 参数被设置为 TRUE 的情况下分配了某个 IRP,那么一定不要对该 IRP 调用 IoInitializeIrp。 如果在 ChargeQuota 设置为 TRUE 的情况下分配 IRP,则 I/O 管理器将把它为该 IRP 分配内存时所用的缓冲池的相关信息保存在该 IRP 的内部标记中。

    如果对这样的 IRP 调用 IoInitializeIrp,那么,当该函数盲目地清零整个 IRP 时,分配池信息将会丢失。 当您释放 IRP 时,这将导致内存被破坏。 同时,一定不要重用来自 IO 管理器的 IRP。 如果要重用 IRP,应当使用 IoAllocateIrp 分配您自己的 IRP。
  57. 如果在调用线程的堆栈中分配了对象,就一定不要在 KeWaitForSingleObject/KeWaitForMultipleObjects 中将 WaitMode 指定为 UserMode。 这样做的结果是,如果被等候的对象是在函数堆栈中创建的,那么您必须将 WaitMode 指定为 KernelMode 才能防止线程被页面调度出去。
  58. 在没有对关键节中的代码加以保护的情况下,一定不要在用户模式线程的上下文中获取诸如 ERESOURCES 和 FastMutex(Unsafe) 这类资源。

    因为获取这些资源不会使 IRQL 提高到 APC_LEVEL,所以,如果线程在已获取资源后被挂起(通过将 APC 加入队列实现),它可能导致死锁,并使系统安全性降低。 因此,应当通过显式地将 IRQL 提高到 APC_LEVEL,或者调用 KeEnterCriticalRegion 来进入关键段,然后可以获取这些资源。
 

posted @ 2009-06-29 08:57 Safe3| 编辑

2009年6月24日

Hook IofCallDriver 代码收集

     摘要: Inline Hook IofCallDriver 截获所有IRP首先声明这个是菜鸟—我的学习日记,不是什么高深文章,高手们慎看.前段时间搞了一些Inline HOOK API的demo,例如对NtQueryDirectoryFile Inline HOOK 进行文件的隐藏,(恰好NtQueryDirectoryFile 在SSDT有导出,也可以采用改SSDT来实现HOOK.,只不过I... 阅读全文

posted @ 2009-06-24 13:04 Safe3| 编辑

2009年6月18日

Socket Server with .NET 3.5 using pooled buffers and SocketAsyncEventArgs

In a previous post I talked about the System.Net.Sockets enhancements in .NET 3.5, and if you haven't read it I suggest you do before tucking in to this as some of that code is important to understand what's happening here. Before I start, in essence this is just a result of my experimentation and while it seems it does a pretty good job, I'm not going to claim it's bullerproof or that it's a good example of how to write a socket server all it does is demonstrate the techniques of working with the new classes and methods.

The sample solution you can see on the right there contains three projects. FlawlessCode contains all the classes we'll need to build ourselves a socket server. TestLoadGenerator is a console application which generates load for us by connecting lots of sockets to our server and sending it random data. TestSocketServer is a small socket server implementation using the classes in FlawlessCode.

TcpSocketListener

We'll begin by looking at the FlawlessCode project and in particular, the TcpSocketListener. It should be fairly obvious from the name what this class is meant to achieve, it sits in a loop listening for socket connections and lets us know when one arrives. The public interface is very simple and looks like this:

public void Start();

public void Stop();

public event EventHandler<SocketEventArgs> SocketConnected;

The only thing we'll take a closer look at here is the internal loop which accepts the client sockets. Here you can see the first usage of the new SocketAsyncEventArgs and we're calling AcceptAsync, in our callback we check the SocketError property to see if we had any errors.

private void ListenForConnection(SocketAsyncEventArgs args)

{

    args.AcceptSocket = null;

 

    listenerSocket.InvokeAsyncMethod(

        new SocketAsyncMethod(listenerSocket.AcceptAsync)

        , SocketAccepted, args);

}

private void SocketAccepted(object sender, SocketAsyncEventArgs e)

{

    SocketError error = e.SocketError;

    if (e.SocketError == SocketError.OperationAborted)

        return; //Server was stopped

 

    if (e.SocketError == SocketError.Success)

    {

        Socket handler = e.AcceptSocket;

        OnSocketConnected(handler);

    }

 

    lock (this)

    {

        ListenForConnection(e);

    }

}

ServerConnection 

Next we're going to take a look at the ServerConnection class, this class encapsulates the concept of a connected client. Depending on what you wanted to do with your server you may decide to extend this class, rewrite it or maybe completely replace it with something derived from NetworkStream. For our purposes today, this class when created will begin listening for data from the network, it has two public methods, one to disconnect the client and one to send data synchronously back to the client. ServerConnection also fires two callbacks, one when data is received and one when the client is disconnected. Here is a rundown of the interesting parts:

public void Disconnect()

{

    lock (this)

    {

        CloseConnection(eventArgs);

    }

}

 

public void SendData(Byte[] data, Int32 offset, Int32 count)

{

    lock (this)

    {

        State state = eventArgs.UserToken as State;

        Socket socket = state.socket;

        if (socket.Connected)

            socket.Send(data, offset, count, SocketFlags.None);

    }

}

 

private void ListenForData(SocketAsyncEventArgs args)

{

    lock (this)

    {

        Socket socket = (args.UserToken as State).socket;

        if (socket.Connected)

        {

            socket.InvokeAsyncMethod(socket.ReceiveAsync,

                ReceivedCompleted, args);

        }

    }

}

 

private void ReceivedCompleted(Object sender,

    SocketAsyncEventArgs args)

{

    if (args.BytesTransferred == 0)

    {

        CloseConnection(args); //Graceful disconnect

        return;

    }

    if (args.SocketError != SocketError.Success)

    {

        CloseConnection(args); //NOT graceful disconnect

        return;

    }

 

    State state = args.UserToken as State;

 

    Byte[] data = new Byte[args.BytesTransferred];

    Array.Copy(args.Buffer, args.Offset, data, 0, data.Length);

    OnDataReceived(data, args.RemoteEndPoint as IPEndPoint,

        state.dataReceived);

 

    ListenForData(args);

}

 

private void CloseConnection(SocketAsyncEventArgs args)

{

    State state = args.UserToken as State;

    Socket socket = state.socket;

    try

    {

        socket.Shutdown(SocketShutdown.Both);

    }

    catch { } // throws if client process has already closed

    socket.Close();

    socket = null;

 

    args.Completed -= ReceivedCompleted; //MUST Remember This!

    OnDisconnected(args, state.disconnectedCallback);

}

Taking it from the top, we can see the public Disconnect method, this simply calls our internal CloseConnection method which shuts down the socket and fires our disconnected callback. An interesting point to note here is that when this class is instanciated we subscribe to the SocketAsyncEventArgs.Completed event, when a client disconnects we need to remember to unhook this event because when we're reusing objects and pooling resources like this it's a bad idea to leave these references hanging around. Moving down we have the public SendData method, nothing interesting here really, just a standard synchrounous call. Next we get to the internal loop which listens for data from the client, notice how we check SocketAsyncEventArgs.BytesTransferred, if this is zero, the client has closed the connection and disconnected gracefully. We check the value of SocketError here also to make sure there was no error anywhere, after that we make a copy of the bytes we received and inform any interested parties we have new data.

BufferPool and SocketArgsPool 

These two classes help us with pooling our resources and are not really very interesting, they're also almost identical to the MSDN examples so you can either look there or just check out the code.

BufferPool: http://msdn2.microsoft.com/en-us/library/bb517542.aspx

SocketArgsPool: http://msdn2.microsoft.com/en-us/library/bb551675.aspx

TestSocketServer

Now that we've sen to main functionality in the FlawlessCode project we're going to look at a simple socket server implementation using these classes.

TcpSocketListener socketListener = new TcpSocketListener(IPAddress.Any, 12345, 10);

socketListener.SocketConnected += socketListener_SocketConnected;

socketListener.Start();

Fairly straight forward, we fire up out listener on port 12345 and give the listening socket an allowed connection backlog of 10.

static void socketListener_SocketConnected(object sender, SocketEventArgs e)

{

    SocketAsyncEventArgs args = socketArgsPool.CheckOut();

    bufferManager.CheckOut(args);

 

    ServerConnection connection = new ServerConnection(e.Socket, args,

        new DataReceivedCallback(DataReceived),

        new DisconnectedCallback(Disconnected));

}

When a client connects we get an SocketAsyncEventArgs and some free buffer space for our client and then we create an instance of ServerConnection. Note that we are passing delegates into the constructor, this is because the ServerConnection begins listening for data immediately and we have to have the callbacks hooked up before hand. If we let the call to the constructor complete and the we hooked to standard events we may have already missed the first batch of data!

static void DataReceived(ServerConnection sender, DataEventArgs e)

{

    //Do whatever we want here...

}

 

static void Disconnected(ServerConnection sender, SocketAsyncEventArgs e)

{

    bufferManager.CheckIn(e);

    socketArgsPool.CheckIn(e);

}

Here we do whatever processing is necessary when a client sends us data. When a client disconnects we just check our buffer space and SocketAsyncEventArgs back into their respective pools to fight another day.

TestLoadGenerator

I'm not going to go into how the load generation works for now, the code is all very straight forward if you've managed to follow the post this far I would imagine. One thing to note is that if you want to test this code and open thousands of connections you need to tweak a registry setting or windows wont give you enough ports. You will need to add the DWORD MaxUserPort to HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters and give it a high enough value that windows won't run out of ports (reboot required, sorry)! Here is a quick examaple of how the load generation classes are used:

static void Main(string[] args)

{

    LoadGenerator generator = new LoadGenerator(15000);

    generator.BytesPerDelivery = 2048;

    generator.DeliveriesPerSecond = 2;

    generator.SocketCount = 15000;

    generator.SocketDelay = 5;

    generator.SocketsPerDelivery = 3;

 

    generator.Start(IPAddress.Parse("127.0.0.1"), 12345);

 

    Console.ReadLine();

 

    generator.Stop();

}

Pretty easy to use, right? We create an instance of the LoadGenerator class, telling it we'd like 15,000 connections maximum. Then we set some properties saying that we'd like each connected socket to deliver 2K of data twice per second. We'd like 15,000 sockets and we'd like them to connect 5ms apart and that we want on average 3% of sockets to send data in each delivery. Then we just aim and fire! Check it out:



When this was taken, the server executable was using 109MB or RAM and 1% CPU on my desktop machine so I think at 15,000 connections we've got some pretty damned good performance out of this thing! Obviously when we start implementing the server logic and actually processing each packet this will go up, but for a bare socket server, I'm pretty pleased.

Net35SocketServer.zip (24.77 kb)

posted @ 2009-06-18 21:47 Safe3| 编辑

2009年6月12日

Safe3 Web Protector 2009 Enterprise Edition V5.0.0.1

About the software:

"Safe3 Web Protector" is a new generation of Web security technology based and on the full range of enterprise Web development of information security product produced by the well-known security organization Safe3 network .  Not only can effectively scan a variety of WebShell, but also can withstand a variety of Web attacks.

Operating Environment:

 The software can run on Windows 2000/2003 supporting IIS5/IIS6 .

Software main functions:

Flow control.  Swamped with P2P network software, multi-threaded download (such as the Thunder, etc.) resulted in the only website bandwidth resources are severely depleted, not only affected the site normal browsing, but also for a large number of extra payment of the cost of the flow. Safe3 IIS Firewall can effectively solve the multi-threaded download traffic brought about by the loss, to help win the network station opportunities.

SQL injection. Today, a variety of SQL injection tools full of Internet, what is more automation of Mass SQL Injection Worm on the day can give tens of thousands of sites  linked to trojan, serious damage to the corporate image and data security. Safe3 IIS Firewall into the simulation technology used to effectively block all kinds of variants of implantation, to help enterprises in the Internet Network to turn the tide and win living space.


CC attack. An increasingly competitive on the Internet today, unfair competition caused by the other side of the grave site of the CC attack, followed by net freight terminal and a sharp decline in traffic. Strong Safe3 IIS Firewall to stop DDOS attacks CC caused a thorough solution to illegal improper competition.


Resources leech. Copy of today's inter-site resources (picture and download link) has been used, not only a waste of bandwidth resources, but also a tort. Safe3 IIS Firewall Web resources can be a high degree of protection while navigating  to prevent, protect the original site of the legitimate rights and interests.


XSS Cross Site. OWASP will XSS as a security threat in 2007 the first WEB. Hackers to insert malicious Web page in html code, when a user views at the time of the page embedded inside the Web which will be the implementation of html code in order to achieve the specific purpose of a malicious user. Safe3 IIS Firewall testing can effectively contain the evil XSS URL and intended to intercept.

AV protection. Only allowed to play audio and video online and can not be directly downloaded from the protection of powerful video site bandwidth resources and quality of service.

Tamper-resistant. Web directory of real-time monitoring of changes and alarm, power to stop the page has been tampered with.

Webshell scan. Analysis can be scanned through the 99% of the hidden WebShell, the protection of web security.

Tampering inspection. Extract the characteristics of important documents, when the web page code can be changed rapidly from a large number of code files to find hidden in the back door or Trojan horse page.

Backdoor detection. Mainly used to detect the existence of a file Win2003 path vulnerability analysis, when hack.asp folder named similar to the time (that is, the folder who looks like an ASP file name), at this point in the text folder type of file can be in the IIS as ASP procedures to implement. Similar to the xxx .. \ such a special folder will be hackers to use. This folder can not have both the common deletion can not be changed, on the inside of some anti-virus software as Trojan horse and this feature can effectively find such a folder.


Mal-script cleaner. Online procedure volume of horses hanging everywhere, and to the administrator caused by hand to remove a lot of difficulties, this feature makes it easy to solve the plight of the administrator.

 

Arp immune.  ARP linked to trojan and to prevent sensitive information being intercepted by eavesdropping. When hacking the same network segment of the host after the host if you did not make any defensive measures ARP, while your hosts are not black but customers visit your site by inserting malicious code page that is linked to Ma ARP. At the same time, hackers can sniff this network segment so the next host ftp, http, such as user passwords. Well-known hacker site security has been the focus of such attacks. Although the basic solution to the arp on the local threat. But also Gateway by deception, this will result in disruption of local communications, so I hope the best friend of conditional binding at the gateway on the local ip and mac address.

Software features:

Firewall using C language, a high operating efficiency 100 megabits per second data transmission good running on large servers, taking up very little CPU.

Do not write the registry, not tied to any plug-in, pure green pollution-free software.

Super security: anti-radical attacks SQL injection attacks.

Thoroughly anti-Thunderbolt, FlashGet and so on.

Without restarting IIS, configuration data, effective immediately.

Safe3 network security together for many years of experience, a strong and reliable.

Easy to install, configure, simple and rich guide to help document the installation, a dedicated configuration tool for easy configuration.

 

Download:http://121.207.254.246/safe3.zip


 Technical Support: s0_6@hotmail.com 
 Contact: http://www.safe3.com.cn/

 

posted @ 2009-06-12 13:32 Safe3 阅读(41) | 评论 (0)编辑

2009年5月31日

安全伞IIS防火墙 v5.0.0.6

关于软件:

   
  

 “Safe3 Web Protector"是国内知名安全组织保护伞网络基于新一代Web安全技术开发的全方位企业Web信息安全产品。不仅能有效扫描各种WebShell,而且可以抵御各种Web攻击。

 

运行环境:

  • 该软件能运行在 Windows 2000/2003 下,支持 IIS5/IIS6
软件主要功能:
  • 流量控制。当前网络P2P软件泛滥成灾,多线程下载(如迅雷等)造成网站仅有的带宽 资源严重枯竭,不仅影响了网站的正常浏览,还得为额外的流量支付大批费用。Safe3 IIS Firewall能有效解决多线程下载带来的流量损失,帮助站长赢得网络先机。
     
  • SQL注入。如今各种SQL注入工具充斥着Internet,更甚者自动化蠕虫的Mass SQL Injection 一天就可以给成千上万的网站挂马,严重的损害了企业形象和数据安全。 Safe3 IIS Firewall采用注入模拟技术,有效拦截各种变种注入,帮助企业在互联网 中力挽狂澜,博得生存空间。 
     
  • CC攻击。在互联网竞争日益激烈的今天,不正当的竞争关系造成一方对另一方网站进 行严重的CC攻击,随之而来的是网站瘫痪和访问量急剧下降。Safe3 IIS Firewall能 强力阻止因CC造成的DDOS攻击,彻底解决非法的不正当的竞争关系。 
     
  • 资源盗链。当今网站间相互复制资源(图片和下载链接)已习以为常,不仅浪费带宽 资源,而且也是一种侵权行为。Safe3 IIS Firewall可以对网站资源进行高度保护, 防止盗链,保障原创网站的合法权益。   
       
  • XSS跨站。OWASP将XSS列为2007年WEB安全威胁第一位。黑客往Web页面里插 入恶意html代码,当用户浏览该页之时,嵌入其中Web里面的html代码会被执行, 从而达到恶意用户的特殊目的。Safe3 IIS Firewall可以有效检测包含XSS的恶意 URL并拦截。
     
  • 影音保护。只允许影音在线播放而不能直接下载,有力的保护了视频网站的带宽资源 和服务质量。
     
  • 网页防篡改。实时监控Web目录的变化情况并报警,强力阻止网页被篡改。    
       
  • Webshell扫描。通过分析可以扫描出99%的隐藏WebShell,保障web安全。   
       
  • 文件篡改检查。提取重要文件的特征,当网页代码被修改后可迅速从大量代码文件中
  • 找出隐藏的后门或木马的页面。   
       
  • 特殊后门检测。主要用于检测Win2003存在着一个文件解析路径的漏洞,当文件夹 名为类似hack.asp的时候(即文件夹名看起来像一个ASP文件的文件名),此时此文 件夹下的文本类型的文件都可以在IIS中被当做ASP程序来执行。另外比如像xxx..\ 这样的特殊文件夹会被黑客利用。这样的文件夹既普通删不掉也不能修改,放在里面 的木马一些杀毒软件视而不见。而此功能能有效找出这样的文件夹。   
       
  • 挂马清除助手。网上批量挂马的程序随处可见,给管理员手工清除造成了很大的困 难,此功能可轻松解决管理员的困境。   
       
  • Arp免疫。防止ARP挂马和敏感信息被监听截获。当黑客入侵同一网段的主机后如 果你的主机没做任何ARP防御措施,虽然你的主机没被黑但客户访问你的网站时网 页被插入恶意代码即ARP挂马。同时黑客可以嗅探到此网段下所以主机的ftp、http 等用户密码。著名黑客网站安全焦点就曾遭到这样的攻击。虽然基本解决了arp对 本地的威胁。但是arp还可以欺骗网关,会造成本地通讯中断,所以希望有条件的 朋友最好在网关上绑定本地ip和mac地址。
软件特点:
  • 防火墙采用C语言编写,运行效率极高。在每秒 100兆比特数据传输的大型服务器
  • 上运行良好,占用 CPU 很少。
  • 不写注册表,不捆绑任何插件,纯绿色无污染软件。
  • 超强安全防护:彻底防 SQL 注入攻击等攻击。
  • 彻底防迅雷、FlashGet等。
  • 无需重启 IIS,配置数据即刻生效。
  • 汇集保护伞网络多年安全经验,强大可靠。
  • 安装容易,配置简单,丰富的帮助文档指导安装,专门的配置工具实现轻松配置。
配置界面:
    V5.0.0.6版本的图形化的配置管理工具。     
        

下载地址:http://www.safe3.com.cn/safe3.rar

posted @ 2009-05-31 13:03 Safe3| 编辑

2009年5月26日

左腦思考還是右腦思考

試試看---你看到的美女是順時針還是逆時針轉動?---(說明在後)

 

每個人看來都是不一樣的
順時針轉的話屬於是用右腦較多的類型
逆時針轉屬於使用左腦較多的類型
大部分人的眼裡裡是逆時針方向轉動
但也有人看來是順時針方向轉動的
順時針的情況女性比男性多~

 

有圖有真相(給一些直接說我騙人的莽夫)

左圖:舉左手、頭往左偏
右圖:舉右手、頭往右偏
我做的事情只有用白線明顯告訴你那是左腳還是右腳

科學人雜誌--天才的特殊思維
作者﹕巫石吉

頂葉負責掌管腦中的數學和邏輯,這也是愛因斯坦成為天才的秘密。但不可否認的,愛因斯坦豐富的想像力與創造力,是使他的右腦不斷激發出潛在能力的重要因素之一。

左腦因為是以語言處理訊息,控制知識、判斷力、思考力因此被稱為「知性腦」﹔右腦則控制著自律神經與字宙波動共振,由於是圖像腦,因此造型能力優越,被稱為「藝術腦」。

有關右腦的神奇功能研究,是始於1981年加州理工學院羅傑'史貝利博士研究右腦獲得諾貝爾獎以後,人們才開始對右腦有所認識,在此之前,人們並不認為左 腦與右腦的功能有那麼大的差別。史貝利在分割腦的實驗中發現,左腦與右腦這兩個半球完全以不同的方式在進行思考,他發現左腦用語言進行思考,右腦則是以圖 像進行思考﹔左腦偏向語言、邏輯性的思考,右腦則是影像和心像的思考。

根據七田真博士的研究,原來人在誕生之初,右腦的能力還很發達,右腦具備了超越常識那種幾乎可稱為全然未知的天才似的能力,這種能力自古以來就隱藏在人們 腦海裡,是一種超越時間、空間,與無限境界相連結的能力,但是因為人類世界是以教導、開啟左腦為主,讓小孩子努力學習語言以及往後生存所必需的知識,久而 久之,左腦越來越發達,右腦卻因為少用而日形退化。

至於什麼樣的成人比較容易打開右腦,七田真博士認為,心思專注、純真沒有成見的人,比較容易進入神奇的右腦世界。你相信超能力嗎?如果你有看過(雨人)這 部電影,一定對片中達斯汀霍夫曼飾演的哥哥印象深刻,他不但能正確快速數出散落一地的火柴數目,而且飾演他弟弟的湯姆克魯斯還利用他天賦異稟的「透視」能 力,上賭場找人玩撲克牌,結果對手的牌在達斯汀霍夫曼的「全神貫注」下,被透視得一覽無疑,湯姆克魯斯因此贏了一大筆錢。

或許你會認為那是電影誇張其事,現實世界中,人不可能具備那樣的能力。如果你這麼想,你就是犯了習慣左腦思考的錯誤,其實,人類大腦的另一半-右腦,擁有的能力是左腦思考者很難想像的。

 

posted @ 2009-05-26 15:41 Safe3| 编辑