SQL Server 2008 SP以及累计更新包之间的关系还真的有点乱。
SQL Server 2008 SP1刚刚发布,现在没几天出来一个CU1 for SP1。
目前的这个CU1是将之前SQL Server 2008 CU4的Hotfix补漏到了SQL Server 2008 SP1当中,因为在SQL Server 2008 SP1中并不包含SQL Server 2008 CU4的所有Hotfix。
因为按照微软的说法,SQL Server 2008 SP1与CU4 for SQL Server 2008 RTM只重叠6个hotfix ,参见http://blogs.msdn.com/psssql/archive/2009/04/09/sql-server-2008-sp1-and-cumulative-updates-explained.aspx。
962900
(http://support.microsoft.com/kb/962900/ )
FIX: Error message when you run a query that involves an outer join operation in SQL Server 2008: "Attempting to set a non-NULL-able column's value to NULL"
968693
(http://support.microsoft.com/kb/968693/ )
FIX: A query that uses parameters and the RECOMPILE option returns incorrect result when it is run in multiple connections concurrently in SQL Server 2008
963070
(http://support.microsoft.com/kb/963070/ )
FIX: You cannot edit or debug a SSIS package in BIDS when SQL Server 2008 Enterprise Edition, Standard Edition, Developer Edition or Evaluation edition is installed without the SSIS feature.
961633
(http://support.microsoft.com/kb/961633/ )
FIX: A SQL Server 2008 Reporting Services report is displayed incorrectly in Mozilla Firefox if the report is displayed by using the ReportViewer control
963658
(http://support.microsoft.com/kb/963658/ )
FIX: PAGE compression is removed from a SQL Server 2008 data table after you shrink the database
967470
(http://support.microsoft.com/kb/967470/ )
FIX: Error message when you perform an update or a delete operation on the table that does not have a clustered index created in SQL Server 2008: "The operating system returned error 1450"
也就是说,如果你更新到CU4 for SQL Server 2008 RTM是为了解决上面6个问题中的某个,那么你更新SQL Server 2008 SP1之后,这些hotfix仍然有效,但如果你更新CU4 for SQL 2008 RTM是因为其他的hotfix,那么请不要更新SP1。
是不是有点绕,简单点来说,微软这么做是为了那些一直持续进行SQL Server 2008 CU1 / CU2 / CU3 / CU 4更新上来的那些同志们服务的。
SQL Server 2008 SP1就是包含了SQL Server 2008 CU1/CU2/CU3的Hotfix(也包含6个CU4 hotfix)。
SQL Server 2008 SP1:
http://www.microsoft.com/downloads/details.aspx?FamilyID=66ab3dbb-bf3e-4f46-9559-ccc6a4f9dc19&displaylang=en
SQL Server 2008 Service Pack 1 Cumulative Update 1下载地址:
http://support.microsoft.com/kb/969099/en-us
SQL Server 2008 RTM之后的Build版本变化:
http://support.microsoft.com/kb/956909/en-us
更清晰点可以看这幅图:

(点击上图可以看大图)
很不错的一份演示PPT,详细介绍了如何在IIS7下利用HttpModule来实现一个完整的WAF产品,其中很多特性值得借鉴和学习,不妨仔细看看。
IIS7是一个充分借鉴了Apache的优秀模块化设计思想的产物,虽然在ASP.NET设计之初就有HttpModule/HttpHandle的概念,但是那时候的.NET HttpModule/HttpHandle只能捕获以及处理ASP.NET的请求,而针对于同样将IIS作为宿主的其他Http Request则只能干瞪眼,比如PHP/ASP。
在以前的IIS5.x/IIS 6下面,如果要开发一个完整的Web Application Firewall子集,则必须写ISAPI Filter。而ISAPI在不同的IIS版本下都有诸多限制。比如说:在IIS 5.x下,ISAPI Filter可以轻松捕获以及处理GET和POST数据,但是到了IIS6下面则很难捕获到POST数据,当然在IIS6下是同样可以捕获处理POST数据的,只是难度要远大于IIS5.x,需要利用通配符ISAPI Extend来迂回处理,或者启用IIS6的向下兼容模式(这也完全失去了IIS6的优势所在了)。
而在IIS5.x /IIS6下编写ISAPI Filter则在很长一段时间内都没有C#的份儿,原因很简单,C#之类的IL语言是不能直接来编写ISAPI Filter的,只能用VC/Delphi之类的来写ISAPI。不过使用C#还是可以开发ISAPI的,只是同样适用迂回策略即可,:) 。 这一点就连微软IIS Team竟然也在blog上不可行,不过后面我来告诉大家如何用C#来实现ISAPI Filter。
现在IIS7则完全提供了对于.NET的原生支持,也就是说我们可以用.NET Httpmodule/HttpHandle来捕获处理所有进站/出站的Request/Response,从而得以可以使用.NET完整控制整个Web Server的请求过程。
同时IIS7也提供了重写的原生C++支持。
从上面可以总结出来,IIS7.0下的Module/Handle可以通过.NET以及C++两种方式来编写,如果说两者之间有什么差异的话,那当然是原生的C++能处理的粒度更细微以及性能更好,总体上来说,差异并不大。
微软也建议在IIS7下不要再编写ISAPI,因为Module/Handle设计的架构更完备,他就是用来取代历史的ISAPI Filter以及ISAPI Extend的。不过有意思的是,URLScan 3.x版本竟然还是一个ISAPI,:) 。
Protecting Vulnerable Applications with IIS7
• Overview
• IIS7 Integrated Mode
• IIS7 Modules
– Request Filtering Module
– Add-on Modules (from Microsoft)
– Custom Modules
– Case Study: SPF
点击这里可以下载PDF格式的演示稿
WAF中的一个特性就是要阻止各类的XSS攻击以及CSRF攻击,尤其是后者,一般的WAF解决方案是针对GET以及POST插入随机身份令牌的做法,这样做的目的就是辨别出来经过伪造的跨站请求提交。
对于GET而言,WAF需要在受保护的URL连接后面动态插入随机令牌,比如这两个对比站点:http://trade-spf.gdsdemo.com/ 以及 http://trade-no-spf.gdsdemo.com/ ,前者是受保护的测试站点,后者则没有收到任何保护。
对于POST而言,也是类似的做法,WAF通过合理的令牌构造,可以比较有效的保护表单数据以及ASP.NET VIEWSTATE数据。
设计一个完备的令牌机制,可以有效的做到保护如下几个方面:
- 保护URL数据 (/ShowArticle.aspx?ArticleId=123&UrlToken=182734:A7A9369D50B2E185F54A)
- 保护HTML FORM表单数据 (<input type ="hidden" name="FormToken" value="3F2504E0-4F89-11D3-9A0C-0305E82C3301">)
- 抵御CRSF (/ShowArticle.aspx?ArticleId=123&UrlToken=182734:A7A9369D50B2E185F54A)
- 保护Javascript
<a href="javascript:__doPostBack('ctl00$MainContent$gvwThreads'
,'Sort$LastPostDate')">
进化为
<a href="javascript:__doPostBack('b/xEVUeEDOCnhiKu0jS5USUs6N
4Qu1VH5OqHOwF146wSPlA87g==:1829384:61D26FD0849FF93D67B8489C4Qu1VH5OqHOwF146wSPlA87g==:61D26FD0849FF93D67B8489CF
A76','b/xEVUeEDOBfdZR3UM0Ds212HDDwHY3KoYyc/+/JULiDcjQ=:1829384:
83BF9D18B5C34CE2FC0541F954C093B43F0C3EA5')">
有关这方面的东西,后面再慢慢讨论.
下面这篇blog是讨论如何通过ASP.NET MVC的AntiForgeryToken helpers来保护POST数据,可以参考下。
Prevent Cross-Site Request Forgery (CSRF) using ASP.NET MVC’s AntiForgeryToken() helper
http://blog.codeville.net/2008/09/01/prevent-cross-site-request-forgery-csrf-using-aspnet-mvcs-antiforgerytoken-helper/
Update: Since the Release Candidate of ASP.NET MVC, these anti-forgery helpers have been promoted to be included in the core ASP.NET MVC package (and not in the Futures assembly).
Cross-site scripting (XSS) is widely regarded as the number one security issue on the web. But since XSS gets all the limelight, few developers pay much attention to another form of attack that’s equally destructive and potentially far easier to exploit. Your application can be vulnerable to cross-site request forgery (CSRF) attacks not because you the developer did something wrong (as in, failing to encode outputs leads to XSS), but simply because of how the whole Web is designed to work. Scary!
How CSRF works
So, what’s it all about? All web application platforms are potentially vulnerable to CSRF, but in this post I’ll focus on ASP.NET MVC. Imagine you have a controller class as follows:
public class UserProfileController : Controller
{
public ViewResult Edit() { return View(); } public ViewResult SubmitUpdate()
{
// Get the user's existing profile data (implementation omitted)
ProfileData profile = GetLoggedInUserProfile(); // Update the user object
profile.EmailAddress = Request.Form["email"];
profile.FavoriteHobby = Request.Form["hobby"];
SaveUserProfile(profile); ViewData["message"] = "Your profile was updated.";
return View();
}
}
This is all very normal. First, the visitor goes to Edit(), which renders some form to let them change their user profile details. Secondly, they post that form to SubmitUpdate(), which saves the changes to their profile record in the database. There’s no XSS vulnerability here. Everything’s fine, right? We implement this sort of thing all the time…
Unfortunately, this innocent controller is an easy target for CSRF. Imagine that an attacker sets up the following HTML page and hosts it on some server of their own:
<body onload="document.getElementById('fm1').submit()">
<form id="fm1" action="http://yoursite/UserProfile/SubmitUpdate" method="post">
<input name="email" value="hacker@somewhere.evil" />
<input name="hobby" value="Defacing websites" />
</form>
</body>
Next, they somehow persuade a victim to visit this page (basic social engineering, look it up). When this HTML page loads, it submits a valid form post to /UserProfile/SubmitUpdate on your server.
Assuming you’re using Windows authentication or some kind of cookie-based authentication system such as Forms Authentication, the automated form post will be processed within the victim’s established authentication context, and will successfully update the victim’s email address to something under the attacker’s control. All the attacker has to do now is use your “forgotten password” facility, and they’re taken control of the victim’s account.
Of course, instead of changing an victim’s email address, they can perform any action that the victim can perform with a single POST request. For example, they might be able to grant administrative permissions to another account, or post something defamatory to a CMS.
Ways to stop CSRF
There are two main ways to block CSRF:
- Check that incoming requests have a Referer header referencing your domain. This will stop requests unwittingly submitted from a third-party domain. However, some people disable their browser’s Referer header for privacy reasons, and attackers can sometimes spoof that header if the victim has certain versions of Adobe Flash installed. This is a weak solution.
- Put a user-specific token as a hidden field in legitimate forms, and check that the right value was submitted. If, for example, this token is the user’s password, then a third-party can’t forge a valid form post, because they don’t know each user’s password. However, don’t expose the user’s password this way: Instead, it’s better to use some random value (such as a GUID) which you’ve stored in the visitor’s Session collection or into a Cookie.
Using the AntiForgeryToken helpers
With Preview 5, Microsoft has added a set of helpers to the “futures” assembly, Microsoft.Web.Mvc.dll,The core ASP.NET MVC package includes a set of helpers that give you a means to detect and block CSRF using the “user-specific tokens” technique.
To use these helpers to protect a particular form, put an Html.AntiForgeryToken() into the form, e.g.,
<% using(Html.Form("UserProfile", "SubmitUpdate")) { %>
<%= Html.AntiForgeryToken() %>
<!-- rest of form goes here -->
<% } %>
This will output something like the following:
<form action="/UserProfile/SubmitUpdate" method="post">
<input name="__RequestVerificationToken" type="hidden" value="saTFWpkKN0BYazFtN6c4YbZAmsEwG0srqlUqqloi/fVgeV2ciIFVmelvzwRZpArs" />
<!-- rest of form goes here -->
</form>
At the same time, Html.AntiForgeryToken() will give the visitor a cookie called __RequestVerificationToken, with the same value as the random hidden value shown above.
Next, to validate an incoming form post, add the [ValidateAntiForgeryToken] filter to your target action method. For example,
[ValidateAntiForgeryToken]
public ViewResult SubmitUpdate()
{
// ... etc
}
This is an authorization filter that checks that:
- The incoming request has a cookie called __RequestVerificationToken
- The incoming request has a Request.Form entry called __RequestVerificationToken
- These cookie and Request.Form values match
Assuming all is well, the request goes through as normal. But if not, boom!, there’s an authorization failure with message “A required anti-forgery token was not supplied or was invalid”.
This prevents CSRF because even if a potential victim has an __RequestVerificationToken cookie, an attacker can’t find out its value, so they can’t forge a valid form post with the same value in Request.Form. But legitimate users aren’t inconvenienced at all; the mechanism is totally silent.
Using salt
Salt? What? In case you want to protect multiple forms in your application independently of each other, you can use a “salt” value when you call Html.AntiForgeryToken(), e.g.,
<%= Html.AntiForgeryToken("someArbitraryString") %>
… and also in [ValidateAntiForgeryToken], e.g.,
[ValidateAntiForgeryToken(Salt="someArbitraryString")]
public ViewResult SubmitUpdate()
{
// ... etc
}
Salt is just an arbitrary string. A different salt value means a different anti-forgery token will be generated. This means that even if an attacker manages to get hold of a valid token somehow, they can’t reuse it in other parts of the application where a different salt value is required. (If anyone can suggest other use cases for salt, please let me know.)
Limitations of the Anti-Forgery helpers
ASP.NET MVC’s anti-CSRF helpers work very nicely, but you should be aware of a few limitations:
- All legitimate visitors must accept cookies (otherwise, [ValidateAntiForgeryToken] will deny their form posts). Arguably this isn’t a limitation, because unless visitors allow cookies, you probably don’t have anything to protect anyway.
- It only works with POST requests, not GET requests. Arguably this isn’t a limitation, because under the normal HTTP conventions, you shouldn’t be using GET requests for anything other than read-only operations.
- It’s easily bypassed if you have any XSS holes on your domain. An XSS hole would allow an attacker to read a victim’s anti-forgery token value, then use it to forge valid posts. So, don’t have XSS holes!
- It relies on the potential victim’s browser implementing cross-domain boundaries solidly. Browsers are supposed to stop foreign domains from reading your app’s response text and cookies, and are supposed to stop foreign domains from writing cookies to your domain. If an attacker manages to find a way around this, they can bypass [ValidateAntiForgeryToken]. Of course that’s not supposed to be possible. For the most part, modern browsers block this line of attack.
In conclusion, ASP.NET MVC’s anti-CSRF helpers are easy to use, and work very nicely thank you!
AppScan是一款很不错的Web安全扫描工具,对于检测网站安全,进行安全稽核审计有很大帮助,从WatchFire Appscan 7.0就开始使用了,一直到现在。
不过任何一款安全扫描工具都存在一些误判,AppScan同样如此。最近在对一家证券公司进行安全评估时候,appscan就出现较多误判,如何剔除误判的条目,就需要你仔细分析appscan给出的Request/Response内容了。
这一次的7.8.1终于提供了多国语言支持,其中也包含了简体中文,的确是一个很好的选择。在商业安全扫描工具中,提供简体中文支持的,目前也只有AppScan一个。之所以比较关心appscan的简体中文,是因为appscan在每次扫描到漏洞后,会给出相应的java/.net/php等的解决方案,洋洋洒洒一大片,虽然英文不是太大问题,不过都给出来中文当然最好了。
另外2个比较好的Web安全审计工具分别是Acunetix Web Vulnerability Scanner以及HP Webinspect,同样可以在其主页上下载到相关版本。

目前能够下载到的为Test版本,Standard版本,Developer版本,以及Build版本。IBM网站没有提供Enterprise版本的下载
Build版本是可以与Rational Application Developer以及Eclipse进行集成的。

安装过程中需要注意的,初始启动安装的时候,要检查IBM Installtion Manager的最新版本,安装包里面的是1.2.1,需要更新到最新版本,否则安装失败(我在Windows Server 2008上是如此)。

一路按照需求进行选择,即可:




IBM Rational AppScan Developer/Build Edition V7.8.1 安装包
IBM Rational AppScan Developer Edition 7.8 for Rational Application Developer 7.0/Eclipse 3.2 Windows Evaluation Multilingual Part 1
CZ122ML.zip (592 MB)
http://www15.software.ibm.com/sdfdl/v2/fulfill/CZ122ML/Xa.2/Xb.aq9Tc4a86B22iy0SonsK7xETExEVsWlsdCJ8xY8/Xc.CZ122ML/CZ122ML.zip/Xd./Xf.LPr.A6VN/Xg.4876199/Xi.RATLe-APPSCANDE-EVAL/XY.regsrvs/XZ.9WheiV-ai_5HsH5goLk8KutFYx0/CZ122ML.zip
IBM Rational AppScan Developer Edition 7.8 for Rational Application Developer 7.0/Eclipse 3.2 Windows Evaluation Multilingual Part 2
CZ123ML.zip (20 MB)
http://www15.software.ibm.com/sdfdl/v2/fulfill/CZ123ML/Xa.2/Xb.aq9Tc4a86B22iy0SonsK7xETExEVsWlsdCJ8xY8/Xc.CZ123ML/CZ123ML.zip/Xd./Xf.LPr.A6VN/Xg.4876199/Xi.RATLe-APPSCANDE-EVAL/XY.regsrvs/XZ.j3X1NMrz7yQySOco_0qbe1d725w/CZ123ML.zip
IBM Rational AppScan Developer Edition 7.8 for Rational Application Developer 7.5/Eclipse 3.4 Windows Evaluation Multilingual Part 1
CZ124ML.zip (496 MB)
http://www15.software.ibm.com/sdfdl/v2/fulfill/CZ124ML/Xa.2/Xb.aq9Tc4a86B224a3C6AODtb3q-gwRosaPn3uTIRo/Xc.CZ124ML/CZ124ML.zip/Xd./Xf.LPr.A6VN/Xg.4875928/Xi.RATLe-APPSCANDE-EVAL/XY.regsrvs/XZ.c0PFnNWHiOjyASAT4Vi8LhPzgV0/CZ124ML.zip
IBM Rational AppScan Developer Edition 7.8 for Rational Application Developer 7.5/Eclipse 3.4 Windows Evaluation Multilingual Part 2
CZ125ML.zip (249 MB)
http://www15.software.ibm.com/sdfdl/v2/fulfill/CZ125ML/Xa.2/Xb.aq9Tc4a86B224a3C6AODtb3q-gwRosaPn3uTIRo/Xc.CZ125ML/CZ125ML.zip/Xd./Xf.LPr.A6VN/Xg.4875928/Xi.RATLe-APPSCANDE-EVAL/XY.regsrvs/XZ.hSIf5Pyz287S-qOG0Ja64TYJsMc/CZ125ML.zip
IBM Rational License Server Windows V7.1 Multilingual English Eval
C1ST1ML.zip (88 MB)
http://www15.software.ibm.com/sdfdl/v2/fulfill/C1ST1ML/Xa.2/Xb.aq9Tc4a86B22iy0SonsK7xETExEVsWlsdIGTLR4/Xc.C1ST1ML/C1ST1ML.zip/Xd./Xf.LPr.D1VK/Xg.4876199/Xi.RATLe-APPSCANDE-EVAL/XY.regsrvs/XZ.aMiwSY2lWh6BQprQolM6lMA6f_4/C1ST1ML.zip
IBM Rational AppScan Standard Edition V7.8.1 安装包
http://www15.software.ibm.com/sdfdl/v2/fulfill/CZ126ML/Xa.2/Xb.aK60yfwVKe9-iJmuzGDuCRsxx-oAWVpam67J_p4/Xc.CZ126ML/CZ126ML.exe/Xd./Xf.LPr.A6VN/Xg.4878821/Xi.RATLe-APPSCANSE-EVAL/XY.regsrvs/XZ.o208egMTeBbesVvttV9sBXWlC4A/CZ126ML.exe
备注:如果要扫描Web Services,则必须安装AppScan的Web Services组件 :


IBM Rational Web Services Explorer (add-on to AppScan Standard Edition 7.8)
CZ25ZML.exe (263 MB)
http://www15.software.ibm.com/sdfdl/v2/fulfill/CZ25ZML/Xa.2/Xb.aK60yfwVKe9M34olDWX569EBUk8zEoQKSEdzgQo/Xc.CZ25ZML/CZ25ZML.exe/Xd./Xf.LPr.A6VN/Xg.4876284/Xi.RATLe-APPSCANSE-EVAL/XY.regsrvs/XZ.0cz6a8um-3jeBQIc0go3jJ7-VIo/CZ25ZML.exe
SQL注入算是一个极为普通的问题了,解决方案也多如牛毛,但是新的注入方式仍然层出不穷。
目前很多IIS防火墙其实质就是一个ISAPI Filter,针对SQL注入攻击的防御实质就是关键字过滤,这一点在我以前的随笔中提到的在开发的Web Server Guard中也是这样操作的。但目前大部分的IIS防火墙都存在一个漏洞:如果关键字包含未转义百分比符号 (%) ,那么将会绕过这些IIS防火墙的请求过滤和拦截,包含IIS 7.0的Request Filter。
因为这类防火墙都是查找位于URL/Form/Cookie中的关键字,比如Exec。但是如果你传入E%xec,那么将不会被过滤,这个问题在目前已知的大部分IIS防火墙(具体的就不介绍了,以免存在广告之嫌,Google搜索即可知道)中都存在,很容易被轻易穿透。包含微软为ASP提供的一组安全过滤函数里面同样存在这个问题。
URLScan同样存在这个问题,但是URLScan 3.0beta我还没有测试过。所以大家在开发ISAPI Request Filter中要注意这一点。
http://www.ietf.org/rfc/rfc2396.txt
IIS 7.0修补程序:
http://www.microsoft.com/downloads/details.aspx?FamilyID=9bf0adf3-20ce-4772-8304-83b68983c1fa&DisplayLang=zh-cn
http://support.microsoft.com/kb/957508/en-us
用过Reporting service (后面都用RS代替)的人对sum这个函数都不会陌生,这个函数的使用率极高并且非常好用,下面我们就来谈谈使用这个函数可能会遇到的一个问题。
我们先假设报表使用的dataset传过来的数据如下
Supplier Revenue
A 0.00
B 0.00
报表的需求是要算出每个Supplier的Revenue所占的比率。我们在报表中新建一个table,table中新建一个group,group绑定的值为Fields!SupplierName.Value,group的名字为SupplierGroup,该Dataset的名字为Dssup。报表如下:

可以看到比率的计算公式为:
=FormatPercent(Sum(Fields!Revenue.Value,"SupplierGroup")/Sum(Fields!Revenue.Value,"Dssup"),2)
但事实上,由这个计算公式得到的值却是这样:

这个很好理解,是因为我们的计算公式的分母为0,所以出现了NaN这种值,这个时候,按照正常的逻辑,我们都会选择先判断一下分母,改后的计算公式是这样(为了便于查看,先去掉函数FormatPercent):
iif(Sum(Fields!Revenue.Value,"Dssup") = 0, 0.00%, Sum(Fields!Revenue.Value,"SupplierGroup")/Sum(Fields!Revenue.Value,"Dssup"))
这个是说如果分母为0,那么传回0.00%,反之通过公式计算。从这个公式来看,没有问题,但是不幸的是,结果依然是NaN。
那么怎么办呢,继续尝试下去,改计算公式为
iif(Sum(Fields!Revenue.Value,"SupplierGroup")/Sum(Fields!Revenue.Value,"Dssup")=’NaN’, 0.00%, Sum(Fields!Revenue.Value,"SupplierGroup")/Sum(Fields!Revenue.Value,"Dssup"))
结果证明,改成这样,还是不行。
这个时候,考虑到当Sum(Fields!Revenue.Value,"Dssup") = 0 时,Sum(Fields!Revenue.Value,"SupplierGroup")一定也为0,所以改计算公式为:
Sum(Fields!Revenue.Value,"SupplierGroup")/iif(Sum(Fields!Revenue.Value,"Dssup")=0,1,Sum(Fields!Revenue.Value,"Dssup"))
既如果分母为0,那么强制将分母变为1,最后结果为

这是我们想要的结果。最终计算公式是:
=FormatPercent(Sum(Fields!Revenue.Value,"SupplierGroup")/iif(Sum(Fields!Revenue.Value,"Dssup")=0,1,Sum(Fields!Revenue.Value,"Dssup")),2)
留言请访问如下链接: Reporting Service Tips 101(#2) - 关于使用Sum函数会遇到的问题(1)
Reporting Service有三种报表发布方式:
一、是在报表管理器上直接上传报表,创建数据源,这种方式很麻烦,只适用于少量的报表。
二、是在VS.net里的project里面直接发布,这种只适用于开发环境。
三、就是使用RSS脚本进行自动发布。下面我们就来初步了解一下RSS这种发布方式。
默认情况下,安装完Reporting Service,我们可以在Microsoft SQL Server\90\Samples\Reporting Services\Script Samples目录下找到一个名为PublishSampleReports.rss的文件,同时在联机文件中,我们也可以找到该文件。这个RSS文件就是自动发布的脚本,但是内容比较基础简单,下面我们在这个文件基础上进行一些扩展。
1. 这个是一个比较重要的问题,提供的RSS脚本,要求默认windows认证或者允许匿名访问,但是在实际的生产环境中,一般是用的域认证,且出于安全考虑,禁止匿名访问。所以这一块,我们要改变RSS的认证方式。
已有的代码是:
rs.Credentials = System.Net.CredentialCache.DefaultCredentials
改为:
rs.Credentials = new System.Net.NetworkCredential(User_Name,User_Password,User_domin)
然后在命令行里面加上这三个参数即可:
rs -i PublishSampleReports.rss -s http://ReportServerName/reportserver -u UserName -p UserPassword\Userdomin
在指定的服务器上进行发布时,有关权限问题这一块,我们还应当考虑是否拥有报表服务器的访问权限,以及是否对对要访问的报表服务器的根文件夹具有相应的权限。在实际操作中,权限问题是报得最多的error。
2.该脚本必须用Visual Studio VB.NET语言编写,因此也可以用VB.NET进行一些额外的操作,例如判断报表是否已经被发布。
留言请访问:Reporting Service Tips 101(#1) - 使用RSS在指定的服务器上自动进行ReportingService报表发布
先从SQL注入攻击说起吧。
前一段时间的SQL注入攻击可以说让国内以及国外大量网站沦陷,几个攻击变种中幸好是update而不是delete,否则众多网站损失更大,不过从犯罪的角度来说,并不是这些攻击者心慈手软,而是update才能置入网页木马,也才能在置入成功后获得预期的利润。此次大规模的SQL Injection是使用一个叫做Asprox的自动化工具来借助Google搜索引擎寻找目标网站并自动实施SQL注入的,就连趋势科技网站也未能幸免,惨被注入。此次SQL注入攻击风潮从3月份开始,进入6月份后被攻击的网站仍在大量沦陷。
在很多所谓的开发高手来看,SQL注入只是菜鸟才会犯的低级错误,其实不然。一个中大型的网站,在他不断发展的过程中,网站门户的程序都是Patch模式的逐步叠加,随着页面的增加以及版本的螺旋上升,SQL注入的危险百分比也会指数增长,尤其是国内各个网站开发的模式而言。当一个中大型网站的页面达到几万甚至几十万的时候,当这个网站的程序不断叠加积累,诸多历史页面已经处于失控的时候,如何避免SQL Inject攻击将会是一件令人非常头疼的事情,因为你此时是不可能完全重写整个网站或者完全对所有页面做代码安全审核的。
在这众多的历史页面代码中,一个微小的疏漏就导致你的DB完全向攻击者敞开,甚至威胁到服务器磁盘数据。不要侥幸的认为,你的漏洞页面有可能隐藏的很深,现在对于Google而言,什么都不是隐藏的,再加上SQL注入的自动化操作,你的历史页面越多,你的危险就越大。
我以SQL Injection为例就是为了说明其实Web威胁攻击并不是说需要多么高深的技术才可以进行实施,这些攻击往往是你在认为很简单就可以抵御的时候来进行实施的。另外一个极端就是,所谓的社会工程学攻击,各位可以Google一下就会了解。可以说 ,目前的各类攻击已经不再像很早以前那样为了显示自身技术而进行的有意或无意的攻击破坏了,现在大量的Web攻击都是带有利益驱使性的,也更具危害性。
这些Web攻击都是非常危险的,因为不论你的硬件防火墙或者入侵检测系统如何强大,是无法判断这类Web攻击的,因为它们都是合法的HTTP请求。所以根据统计,目前的Web攻击除了操作系统以及各类服务器端应用软件的漏洞外,绝大部分(70%以上)都是此类“合法的”Web攻击。
因此,抵御此类攻击一是需要检测你的应用程序代码,二是可以采用服务器端的针对访问请求以及内容的检测过滤。
针对第一类,目前业界有非常多的安全检测工具,比如HP WebInspect,NStalker-WAS(NStalker-Web Application Security Scanner),IBM Rational AppScan(Watchfire AppScan),Acunetix Web Vulnerability Scanner等等,当然这里我列举的都是商业软件,而没有包含相应的开源软件,在这方面而言,商业软件用来做安全威胁评估的优势更明显,也更合适。
这类模拟攻击检测软件有庞大的规则库以及模拟场景库,可以代替繁杂易错的人工检测。
针对第二类,则可以通过服务器端的过滤和监测机制来最大程度上保证IIS Web服务器的安全,比如微软的IIS Lock。在IIS 7推出后,做此类过滤更加简单和便捷了。国内外也有针对此类的软件产品,比如Port80 ServerDefender。这类产品可以在服务器端对于HTTP Request / POST / Cookie等做过滤和检测,抵御此类Web攻击。
(此图片转自于IBM网站,特注明)
排名前两位的是XSS攻击以及SQL Injection攻击。对于XSS攻击,很多开发者想必会嗤之以鼻的,因为目前而言XSS攻击都很少能破坏掉服务器端的数据,但是XSS最大危害在于钓鱼式攻击,这对于一个成功的网站而言,对其信誉的打击将是致命的,因为展现在用户面前的是合法的网站URL地址,只是XSS攻击部分被编码了。一旦用户遭受此类攻击,对于你网站的信任将会大大降低,现在有什么比得罪你的忠实用户的危害性更大呢?
上面我们提到了很多安全检测工具,其中提到的那四种工具我都有过一定使用(Trial或者Test),其中的AppScan是我印象最为深刻的,也是效果较好的一个。Rational家族随着IBM的不断收购,已经越来越庞大,通过收购Watchfire从而获得了这款企业级安全检测产品,并被Rational产品系列所整合,使之符合Rational的完整涵盖软件生命周期的目的。
Rational AppScan开发版本会有针对于Visual Studio 的AddIn,来在程序开发过程中就能进行代码安全审计和检测;同时也有QA版本;当然我们使用更多的是产品发布后定期的安全审计以及检测了。各版本的比较可以参见:http://www-142.ibm.com/software/dre/hmc/compare.wss?HMC02=C126096V43460Q17
Rational AppScan 7.7全功能测试版本在IBM网站可以免费下载到(http://www14.software.ibm.com/webapp/download/search.jsp?pn=Rational+AppScan),目前CSDN好像也在进行AppScan的市场活动,有兴趣可以去CSDN找一下即可。
下一个post会详细讲述一下如何针对一个真实网站进行安全审计。
---
可能的大概目录
Web攻击和防御(一) - 安全检测工具(1)介绍
Web攻击和防御(二) - 安全检测工具(2)AppScan详解
Web攻击和防御(三) - 安全检测工具(3)AppScan数据分析
Web攻击和防御(四) - IIS安全防护,IIS Filter介绍
Web攻击和防御(五) - IIS安全防护,IIS Extend介绍
Web攻击和防御(六) - IIS安全防护,IIS 5.x 、6、7区别对待
Web攻击和防御(七) - Web Server Guard介绍
Web攻击和防御(八) - Web Server Guard安全防护使用详解
Web攻击和防御(九) - Web Server Guard性能调优使用详解
Web攻击和防御(十) - Web Server Guard服务器监测使用详解
Web攻击和防御(十一) - 完成不可能的事情:使用C#编写IIS Filter(IIS 5.x/6.0)
Web攻击和防御(十二) - IIS 7.0 Filter
Web攻击和防御(十三) - IIS 7.0 安全防护
Web攻击和防御(..... ) - ..........
UMD格式是国内手机阅读中使用较多的一种格式,但其公司却并没有将UMD数据格式公开,但是却用另外一种方式将其公开,你去访问一下他们的站点然后下载他的制作工具就知道。
下面的是文本的UMD相关处理代码,图形的下一篇post出来。
namespace Ikari
{
using ICSharpCode.SharpZipLib.Zip.Compression;
using System;
using System.Collections;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
public class UMD_GENEGINE
{
private const int A_32K_BYTE = 0x8000;
private byte ACTUAL_WIDTH_S60_HORI = 0xcc;
private byte ACTUAL_WIDTH_S60_VERT = 0xac;
private byte ACTUAL_WIDTH_SP = 0xa6;
private const uint BASE_REFN_CHAP_OFF = 0x3000;
private const uint BASE_REFN_CHAP_STR = 0x4000;
private const uint BASE_REFN_CONTENT = 0x2000;
private const uint BASE_REFN_COVER = 0x1000;
private const uint BASE_REFN_PAGE_OFFSET = 0x7000;
private const string BEYOND_END_FLAG = "\0";
private const int BYTE_LEN = 1;
private const byte COVER_TYPE_BMP = 0;
private const byte COVER_TYPE_GIF = 2;
private const byte COVER_TYPE_JPG = 1;
private const int CURR_VERSION = 1;
private const short DCTS_CMD_ID_AUTHOR = 3;
private const short DCTS_CMD_ID_CDS_KEY = 240;
private const short DCTS_CMD_ID_CHAP_OFF = 0x83;
private const short DCTS_CMD_ID_CHAP_STR = 0x84;
private const short DCTS_CMD_ID_CONTENT_ID = 10;
private const short DCTS_CMD_ID_COVER_PAGE = 130;
private const short DCTS_CMD_ID_DAY = 6;
private const short DCTS_CMD_ID_FILE_LENGTH = 11;
private const short DCTS_CMD_ID_FIXED_LEN = 12;
private const short DCTS_CMD_ID_GENDER = 7;
private const short DCTS_CMD_ID_LICENSE_KEY = 0xf1;
private const short DCTS_CMD_ID_MONTH = 5;
private const short DCTS_CMD_ID_PAGE_OFFSET = 0x87;
private const short DCTS_CMD_ID_PUBLISHER = 8;
private const short DCTS_CMD_ID_REF_CONTENT = 0x81;
private const short DCTS_CMD_ID_TITLE = 2;
private const short DCTS_CMD_ID_VENDOR = 9;
private const short DCTS_CMD_ID_VERSION = 1;
private const short DCTS_CMD_ID_YEAR = 4;
private const byte FIXED_LINE_PER_PAGE_S60 = 50;
private const byte FIXED_LINE_PER_PAGE_SP = 0x19;
private string iAuthor;
private byte[] ibContent;
private int[] iChapOff;
private ArrayList iChapStr = new ArrayList();
private ArrayList iChapter = new ArrayList();
private int iCID;
private string iContent;
private string iCoverFile;
private string iDay;
private string iGender;
private string iMonth;
private const int INT_LEN = 4;
private short iPGKSeed = 0;
private string iPublisher;
private string iSaveTo;
private string iTitle;
private int iTotalen;
private string iVendor;
private ArrayList iWidthData_S60 = new ArrayList();
private ArrayList iWidthData_SP = new ArrayList();
private string iYear;
private byte[][] iZippedSeg;
private const string KEY_CODE_TAB = "\t";
private const byte S60_FONT_SIZE_BIG = 0x10;
private const byte S60_FONT_SIZE_SMALL = 12;
private const byte SEREIS60_FONTS_COUNT = 2;
private const int SHORT_LEN = 2;
private const byte SP_FONT_SIZE_10 = 10;
private const byte SP_FONT_SIZE_MAX = 0x10;
private const byte SP_FONT_SIZE_MIN = 6;
private const string SYMBIAN_RETURN = "\u2029";
private const string SYMBIAN_SPACE = " ";
private const byte UMD_DCTD_HEAD_LEN = 9;
private const byte UMD_DCTS_HEAD_LEN = 5;
private const int UMD_FREE_CID_MIN = 0x5f5e100;
private const int UMD_FREE_PGK_SEED_MIN = 0x400;
private const int UMD_LICENSEKEY_LEN = 0x10;
private const int UMD_MAX_BOOKMARK_STR_LEN = 40;
private const byte UMD_PLATFORM_ID_NONE = 0;
private const byte UMD_PLATFORM_ID_S60 = 1;
private const byte UMD_PLATFORM_ID_SP = 5;
private const int UMD_SEGMENT_LENGTH = 0x8000;
private const byte VER_PKG_LEN = 3;
private const string WINDOWS_RETURN = "\r\n";
private const int ZIP_LEVEL = 9;
private byte CharWidth_S60(string Char, byte pFontSize)
{
ushort num = Char[0];
for (int i = 0; i < this.iWidthData_S60.Count; i++)
{
SWidthData data = (SWidthData) this.iWidthData_S60[i];
if (((data.FontSize == pFontSize) && (num >= data.rngFrom)) && (num <= data.rngTo))
{
if (data.vCount == 1)
{
return data.Value[0];
}
return data.Value[num - data.rngFrom];
}
}
return pFontSize;
}
private byte CharWidth_SP(string Char, byte pFontSize)
{
ushort num = Char[0];
for (int i = 0; i < this.iWidthData_SP.Count; i++)
{
SWidthData data = (SWidthData) this.iWidthData_SP[i];
if (((data.FontSize == pFontSize) && (num >= data.rngFrom)) && (num <= data.rngTo))
{
if (data.vCount == 1)
{
return data.Value[0];
}
return data.Value[num - data.rngFrom];
}
}
return pFontSize;
}
private bool GetPageOffsetS60(byte size, uint actual_width, ref ProgressBar pbar, out uint[] result)
{
ArrayList pPageoff = new ArrayList();
if ((size != 0x10) && (size != 12))
{
result = new uint[0];
return false;
}
this.GetWidthData_S60();
pPageoff.Add(0);
int num = pbar.Value;
while (((int) pPageoff[pPageoff.Count - 1]) < this.iContent.Length)
{
this.ParseOnePage((uint) (pPageoff.Count - 1), size, actual_width, ref pPageoff, 1);
pbar.Value = num + ((int) ((uint) pPageoff[pPageoff.Count - 1]));
}
result = new uint[pPageoff.Count];
for (int i = 0; i < pPageoff.Count; i++)
{
result[i] = ((uint) pPageoff[i]) * 2;
}
return true;
}
private bool GetPageOffsetSP(byte size, uint actual_width, ref ProgressBar pbar, out uint[] result)
{
ArrayList pPageoff = new ArrayList();
if ((size < 6) || (size > 0x10))
{
result = new uint[0];
return false;
}
this.GetWidthData_SP();
pPageoff.Add(0);
int num = pbar.Value;
while (((uint) pPageoff[pPageoff.Count - 1]) < this.iContent.Length)
{
this.ParseOnePage((uint) (pPageoff.Count - 1), size, actual_width, ref pPageoff, 5);
if ((num + ((int) ((uint) pPageoff[pPageoff.Count - 1]))) < pbar.Maximum)
{
pbar.Value = num + ((int) ((uint) pPageoff[pPageoff.Count - 1]));
}
}
result = new uint[pPageoff.Count];
for (int i = 0; i < pPageoff.Count; i++)
{
result[i] = (uint) pPageoff[i];
}
return true;
}
private void GetWidthData_S60()
{
this.iWidthData_S60.Clear();
for (int i = 0; i < 2; i++)
{
string path = "";
switch (i)
{
case 0:
path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase.Remove(0, 8)) + @"\FontWidthData\S60CHS.S16.wdt";
break;
case 1:
path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase.Remove(0, 8)) + @"\FontWidthData\S60CHS.S12.wdt";
break;
}
if (File.Exists(path))
{
FileStream input = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(input);
while (reader.BaseStream.Position < reader.BaseStream.Length)
{
ushort num2 = reader.ReadUInt16();
ushort num3 = reader.ReadUInt16();
uint num4 = reader.ReadUInt16();
byte[] buffer = new byte[num4];
for (uint j = 0; j < num4; j++)
{
buffer[j] = reader.ReadByte();
}
SWidthData data = new SWidthData();
switch (i)
{
case 0:
data.FontSize = 0x10;
break;
case 1:
data.FontSize = 12;
break;
}
data.rngFrom = num2;
data.rngTo = num3;
data.vCount = num4;
data.Value = buffer;
this.iWidthData_S60.Add(data);
}
reader.Close();
input.Close();
}
}
}
private void GetWidthData_SP()
{
this.iWidthData_SP.Clear();
for (int i = 0x10; i < 0x11; i++)
{
string path = (Assembly.GetExecutingAssembly().CodeBase.Remove(0, 8) + @"\FontWidthData\sunfon.s") + i.ToString() + ".wdt";
if (File.Exists(path))
{
FileStream input = new FileStream(path, FileMode.Open, FileAccess.Read);
BinaryReader reader = new BinaryReader(input);
while (reader.BaseStream.Position < reader.BaseStream.Length)
{
ushort num2 = reader.ReadUInt16();
ushort num3 = reader.ReadUInt16();
uint num4 = reader.ReadUInt16();
byte[] buffer = new byte[num4];
for (uint j = 0; j < num4; j++)
{
buffer[j] = reader.ReadByte();
}
SWidthData data = new SWidthData();
data.FontSize = (byte) i;
data.rngFrom = num2;
data.rngTo = num3;
data.vCount = num4;
data.Value = buffer;
this.iWidthData_SP.Add(data);
}
reader.Close();
input.Close();
}
}
}
public bool Initialize(string aTitle, string aAuthor, string aYear, string aMonth, string aDay, string aGender, string aPublisher, string aVendor, string aCoverFile, int aContentID, string aSaveTo, ref ArrayList aChapter, ref ArrayList aChapStr, out string aResult)
{
aResult = "true";
if (aTitle.Length <= 0)
{
aResult = "标题不能为空";
return false;
}
if (aAuthor.Length <= 0)
{
aResult = "作者不能为空";
return false;
}
if (((aYear.Length > 4) || (aMonth.Length > 2)) || (aDay.Length > 2))
{
aResult = "日期非法";
return false;
}
if (aChapter.Count <= 0)
{
aResult = "内容数量不能小于0";
return false;
}
if (aChapter.Count != aChapStr.Count)
{
aResult = "章节标题数量和章节内容数量不符";
return false;
}
if (!Directory.Exists(aSaveTo))
{
aResult = "保存文件的路径不存在";
return false;
}
this.iTitle = aTitle;
this.iAuthor = aAuthor;
this.iYear = aYear;
this.iMonth = aMonth;
this.iDay = aDay;
this.iGender = aGender;
this.iPublisher = aPublisher;
this.iVendor = aVendor;
this.iCID = aContentID;
this.iCoverFile = aCoverFile;
this.iSaveTo = aSaveTo;
File.Copy(this.iCoverFile + ".tmp", this.iSaveTo + @"\" + this.iTitle + ".jpg");
for (int i = 0; i < aChapter.Count; i++)
{
this.iChapter.Add(((string) aChapter[i]) + "\u2029");
this.iChapStr.Add((string) aChapStr[i]);
}
this.iChapOff = new int[this.iChapter.Count];
return true;
}
public bool Make(ref ProgressBar pbar, out string result)
{
uint[] numArray2;
this.Prepare();
Random random = new Random();
uint num = 0;
if (this.iSaveTo.EndsWith(@"\"))
{
this.iSaveTo.Remove(this.iSaveTo.Length - 1, 1);
}
string path = this.iSaveTo + @"\" + this.iTitle + ".umd";
if (File.Exists(path))
{
if (MessageBox.Show("您要保存的文件已经存在,是否覆盖?", "mBook制作工具 版本:1.0", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes)
{
result = "生成文件操作被用户取消";
return false;
}
File.Delete(path);
}
FileStream output = new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write);
BinaryWriter writer = new BinaryWriter(output);
byte num1 = Encoding.Unicode.GetBytes((string) this.iChapter[0])[0];
writer.Write((uint) 0xde9a9b89);
writer.Write('#');
writer.Write((short) 1);
writer.Write((byte) 0);
writer.Write((byte) 8);
writer.Write((byte) 1);
writer.Write(this.iPGKSeed);
writer.Write('#');
writer.Write((short) 2);
writer.Write((byte) 0);
writer.Write((byte) (5 + (this.iTitle.Length * 2)));
writer.Write(Encoding.Unicode.GetBytes(this.iTitle));
writer.Write('#');
writer.Write((short) 3);
writer.Write((byte) 0);
writer.Write((byte) (5 + (this.iAuthor.Length * 2)));
writer.Write(Encoding.Unicode.GetBytes(this.iAuthor));
if (this.iYear.Length > 0)
{
writer.Write('#');
writer.Write((short) 4);
writer.Write((byte) 0);
writer.Write((byte) (5 + (this.iYear.Length * 2)));
writer.Write(Encoding.Unicode.GetBytes(this.iYear));
}
if (this.iMonth.Length > 0)
{
writer.Write('#');
writer.Write((short) 5);
writer.Write((byte) 0);
writer.Write((byte) (5 + (this.iMonth.Length * 2)));
writer.Write(Encoding.Unicode.GetBytes(this.iMonth));
}
if (this.iDay.Length > 0)
{
writer.Write('#');
writer.Write((short) 6);
writer.Write((byte) 0);
writer.Write((byte) (5 + (this.iDay.Length * 2)));
writer.Write(Encoding.Unicode.GetBytes(this.iDay));
}
if (this.iGender.Length > 0)
{
writer.Write('#');
writer.Write((short) 7);
writer.Write((byte) 0);
writer.Write((byte) (5 + (this.iGender.Length * 2)));
writer.Write(Encoding.Unicode.GetBytes(this.iGender));
}
if (this.iPublisher.Length > 0)
{
writer.Write('#');
writer.Write((short) 8);
writer.Write((byte) 0);
writer.Write((byte) (5 + (this.iPublisher.Length * 2)));
writer.Write(Encoding.Unicode.GetBytes(this.iPublisher));
}
if (this.iVendor.Length > 0)
{
writer.Write('#');
writer.Write((short) 9);
writer.Write((byte) 0);
writer.Write((byte) (5 + (this.iVendor.Length * 2)));
writer.Write(Encoding.Unicode.GetBytes(this.iVendor));
}
writer.Write('#');
writer.Write((short) 11);
writer.Write((byte) 0);
writer.Write((byte) 9);
writer.Write(this.ibContent.Length);
num = (uint) (0x3000L + random.Next(0xfff));
writer.Write('#');
writer.Write((short) 0x83);
writer.Write((byte) 1);
writer.Write((byte) 9);
writer.Write(num);
writer.Write('$');
writer.Write(num);
writer.Write((uint) (9 + (this.iChapOff.Length * 4)));
foreach (int num2 in this.iChapOff)
{
writer.Write(num2);
}
num = (uint) (0x4000L + random.Next(0xfff));
writer.Write('#');
writer.Write((short) 0x84);
writer.Write((byte) 1);
writer.Write((byte) 9);
writer.Write(num);
int num3 = 0;
foreach (object obj2 in this.iChapStr)
{
num3 += (((string) obj2).Length * 2) + 1;
}
writer.Write('$');
writer.Write(num);
writer.Write((uint) (9 + num3));
foreach (object obj3 in this.iChapStr)
{
writer.Write((byte) (((string) obj3).Length * 2));
writer.Write(Encoding.Unicode.GetBytes((string) obj3));
}
int num4 = 0;
int num5 = 0;
uint[] numArray = new uint[this.iZippedSeg.Length];
if (this.iZippedSeg.Length > 1)
{
num4 = random.Next(0, this.iZippedSeg.Length - 1);
num5 = random.Next(0, this.iZippedSeg.Length - 1);
}
for (int i = 0; i < this.iZippedSeg.Length; i++)
{
numArray[i] = (uint) (random.Next(1, 0xfffffff) * -1);
writer.Write('$');
writer.Write(numArray[i]);
writer.Write((uint) (9 + this.iZippedSeg[i].Length));
writer.Write(this.iZippedSeg[i]);
if (i == num4)
{
writer.Write('#');
writer.Write((short) 0xf1);
writer.Write((byte) 0);
writer.Write((byte) 0x15);
writer.Write(Encoding.ASCII.GetBytes("\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"));
}
if (i == num5)
{
writer.Write('#');
writer.Write((short) 10);
writer.Write((byte) 0);
writer.Write((byte) 9);
writer.Write(this.iCID);
}
}
num = (uint) (0x2000L + random.Next(0xfff));
writer.Write('#');
writer.Write((short) 0x81);
writer.Write((byte) 1);
writer.Write((byte) 9);
writer.Write(num);
writer.Write('$');
writer.Write(num);
writer.Write((uint) (9 + (numArray.Length * 4)));
foreach (uint num7 in numArray)
{
writer.Write(num7);
}
if (File.Exists(this.iCoverFile))
{
FileStream stream2 = new FileStream(this.iCoverFile + ".tmp", FileMode.Open);
byte[] buffer = new byte[stream2.Length];
stream2.Read(buffer, 0, (int) stream2.Length);
stream2.Close();
num = (uint) (0x1000L + random.Next(0xfff));
writer.Write('#');
writer.Write((short) 130);
writer.Write((byte) 1);
writer.Write((byte) 10);
writer.Write((byte) 1);
writer.Write(num);
writer.Write('$');
writer.Write(num);
writer.Write((uint) (9 + buffer.Length));
writer.Write(buffer);
}
pbar.Maximum = this.iContent.Length * 5;
pbar.Value = 0;
this.GetPageOffsetS60(0x10, this.ACTUAL_WIDTH_S60_HORI, ref pbar, out numArray2);
this.WritePageOffset(0x10, (byte) (this.ACTUAL_WIDTH_S60_HORI + 4), ref numArray2, ref writer, 1);
numArray2.Initialize();
this.GetPageOffsetS60(0x10, this.ACTUAL_WIDTH_S60_VERT, ref pbar, out numArray2);
this.WritePageOffset(0x10, (byte) (this.ACTUAL_WIDTH_S60_VERT + 4), ref numArray2, ref writer, 1);
numArray2.Initialize();
this.GetPageOffsetS60(12, this.ACTUAL_WIDTH_S60_HORI, ref pbar, out numArray2);
this.WritePageOffset(12, (byte) (this.ACTUAL_WIDTH_S60_HORI + 4), ref numArray2, ref writer, 1);
numArray2.Initialize();
this.GetPageOffsetS60(12, this.ACTUAL_WIDTH_S60_VERT, ref pbar, out numArray2);
this.WritePageOffset(12, (byte) (this.ACTUAL_WIDTH_S60_VERT + 4), ref numArray2, ref writer, 1);
numArray2.Initialize();
this.GetPageOffsetSP(10, this.ACTUAL_WIDTH_SP, ref pbar, out numArray2);
this.WritePageOffset(10, this.ACTUAL_WIDTH_SP, ref numArray2, ref writer, 5);
writer.Write('#');
writer.Write((short) 12);
writer.Write((byte) 1);
writer.Write((byte) 9);
writer.Write((uint) (((uint) writer.BaseStream.Position) + 4));
writer.Close();
output.Close();
result = "true";
return true;
}
private void ParseOnePage(uint pPageNumber, byte pFontSize, uint pScreenWidth, ref ArrayList pPageoff, byte PID)
{
if (pPageNumber < pPageoff.Count)
{
string str = "";
int num = 0;
uint num2 = (uint) pPageoff[(int) pPageNumber];
ArrayList list = new ArrayList();
byte num3 = 0;
if (PID == 1)
{
num3 = 50;
}
if (PID == 5)
{
num3 = 0x19;
}
for (byte i = 0; i < num3; i = (byte) (i + 1))
{
str = str.Remove(0, str.Length);
string str2 = "";
byte num5 = 0;
Label_0061:
if (num2 < this.iContent.Length)
{
str2 = this.iContent.Substring((int) num2, 1);
}
else
{
str2 = "\0";
}
switch (str2)
{
case "\t":
case "\0":
str2 = " ";
break;
}
byte num6 = this.CharWidth_S60(str2, pFontSize);
if (str2 == "\u2029")
{
num6 = 0;
}
if ((num6 + num5) <= pScreenWidth)
{
num5 = (byte) (num5 + num6);
num2++;
if (!(str2 == "\u2029"))
{
str = str + str2;
goto Label_0061;
}
}
if (str2 != "\u2029")
{
list.Add(str.Length);
}
else
{
list.Add(str.Length + 1);
}
num += (int) list[i];
if (i == ((byte) (num3 - 1)))
{
if ((num2 < this.iContent.Length) && (num2 > ((uint) pPageoff[pPageoff.Count - 1])))
{
pPageoff.Add(((uint) pPageoff[pPageoff.Count - 1]) + ((uint) num));
}
if (num2 >= this.iContent.Length)
{
pPageoff.Add((uint) this.iContent.Length);
}
}
}
}
}
private void Prepare()
{
Random random = new Random();
this.iPGKSeed = (short) (random.Next(0x401, 0x7fff) % 0xffff);
this.iTotalen = 0;
for (int i = 0; i < this.iChapter.Count; i++)
{
this.iChapter[i] = ((string) this.iChapter[i]).Replace("\r\n", "\u2029");
this.iContent = this.iContent + ((string) this.iChapter[i]);
this.iChapOff[i] = this.iTotalen;
this.iTotalen += ((string) this.iChapter[i]).Length * 2;
}
this.ibContent = new byte[this.iTotalen];
int index = 0;
for (int j = 0; j < this.iChapter.Count; j++)
{
byte[] bytes = new byte[((string) this.iChapter[j]).Length * 2];
bytes = Encoding.Unicode.GetBytes((string) this.iChapter[j]);
bytes.CopyTo(this.ibContent, index);
index += bytes.Length;
}
int num4 = 0;
if ((this.iTotalen % 0x8000) == 0)
{
num4 = this.iTotalen / 0x8000;
}
else
{
num4 = (this.iTotalen / 0x8000) + 1;
}
this.iZippedSeg = new byte[num4][];
byte[] input = new byte[0x8000];
int num5 = 0;
int num6 = 0;
for (int k = 0; k < this.ibContent.Length; k++)
{
input[num5] = this.ibContent[k];
if ((num5 == 0x7fff) || (k == (this.ibContent.Length - 1)))
{
byte[] output = new byte[0x8000];
num5 = 0;
Deflater deflater = new Deflater(Deflater.BEST_COMPRESSION, false);
if (deflater.IsNeedingInput)
{
deflater.SetInput(input, 0, input.Length);
}
deflater.Finish();
deflater.Deflate(output);
this.iZippedSeg[num6] = new byte[deflater.TotalOut];
Deflater deflater2 = new Deflater(Deflater.BEST_COMPRESSION, false);
if (deflater2.IsNeedingInput)
{
deflater2.SetInput(input, 0, input.Length);
}
deflater2.Finish();
deflater2.Deflate(this.iZippedSeg[num6]);
num6++;
input = Encoding.Unicode.GetBytes("");
input = new byte[0x8000];
}
else
{
num5++;
}
}
}
private void WritePageOffset(byte fontSize, byte screenWidth, ref uint[] data, ref BinaryWriter writer, byte PID)
{
Random random = new Random();
uint num = (uint) (0x7000L + random.Next(0xfff));
writer.Write('#');
writer.Write((short) 0x87);
writer.Write(PID);
writer.Write((byte) 11);
writer.Write(fontSize);
writer.Write(screenWidth);
writer.Write(num);
writer.Write('$');
writer.Write(num);
writer.Write((uint) (9 + (data.Length * 4)));
foreach (uint num2 in data)
{
writer.Write(num2);
}
}
[StructLayout(LayoutKind.Sequential)]
private struct SWidthData
{
public byte FontSize;
public ushort rngFrom;
public ushort rngTo;
public uint vCount;
public byte[] Value;
}
}
}
今天发现电脑有些不正常,svchost.exe进程频繁和外界通讯,关闭网络就会开始不断出现 svchost.exe 错误对话框,提示远端地址被中断或者ICMP无效,经常一下子出来40多个对话框,不胜其烦,如果你连接网络,则直接打开 奇虎MP3搜索 mp3.qihoo.com , 我已经无语了。
我没有使用过任何和奇虎相关的软件或者服务,当然不排除无意中中招了。
Windows Defender 和 一起其他反流氓软件完全检测也没有任何结果。
大家都知道 奇虎360一直标榜着自己是反流氓软件的卫士,但是这次呢?当然不排除竞争对手恶意针对奇虎栽赃的。。。不过可能性比较低。
经过分析发现,流氓软件来自 Windows\Media\ClickMe.exe以及Windows\Media\svchost.exe 这两个文件,利用Unlocker删除这两个文件就天下太平了。
不知道奇虎MP3搜索 是不是还在用老路子(类似3721那样的手段)来推广?如果是的话,那自己竟然还出奇虎360,那岂不是 笑掉大牙? 谁敢用?
当然,如果不是,那也给奇虎360 一个改进建议,因为我使用它也没有查出这个流氓软件(我最后还下载了奇虎360来查了查),如果这个流氓软件恶意给奇虎栽赃话,奇虎360更要第一时间杀了,人家都给你扣黑帽子了,你竟然还查不出来。。。
这段时间一直在翻译两本比较新的外文技术书籍,也顺便分享给大家几本好的书籍英文版,有时间的话,可以找来看看。
《Pro SQL Server 2005 Database Design and Optimization》
ISBN: 1590595297
Title: Pro SQL Server 2005 Database Design and Optimization
Author: Louis Davidson Kevin Kline Kurt Windisch
Publisher: Apress
Publication Date: 2006-05-01
Number Of Pages: 672
Average Amazon Rating: 5.0

介绍:Pro SQL Server 2005 Database Design and Optimization will teach you effective strategies for designing proper databases. It covers everything from how to gather business requirements to logical data modeling and normalization. It then shows you how to implement your design on SQL Server 2005.
The authors also describe how to optimize and secure access to this data, covering indexing strategies, SQL design and optimization, and strategies for increased scalability to support large numbers of concurrent users. They provide in-depth advice on optimal code distribution in SQL Server 2005 applications, in the wake of innovations to be able to use .NET code in the database itself. This essential book will ensure that projects have a well-designed database and secure, optimized data access strategies right from the start.
《Microsoft Visual Studio 2005 Unleashed》 - 正在翻译中文版本中
介绍:
Microsoft Visual Studio 2005 Unleashed is a deep dive into the Visual Studio 2005 tool. Specifically, it will provide you with solid guidance and education that will allow you to squeeze the ultimate productivity and use out of the Visual Studio 2005 development environment. This book folds in real-world development experience with detailed information about the IDE to make you more productive and ease transition from other development environments (including prior versions of Visual Studio). This book will also help you increase team collaboration and project visibility with Visual Studio Team Systems and it will give you straight, to-the-point answers to common developer questions about the IDE.
《Pro ASP.NET 2.0 in C# 2005》 - 中文版本翻译完毕,出版中
介绍:
The book will teach you ASP.NET 2.0 in five clear steps. You will learn:
- Core concepts of ASP.NET 2.0. Why it抯 special. What its fundamental principals are. The basics of Visual Studio. How ASP.NET 2.0 controls are created, and how they fit into ASP.NET 2.0 pages, ultimately creating full applications
- Data access details. The intricacies of ADO.NET 2.0 and how to perform data binding to many sources梖rom databases, to file-streams, to XML
- Security. Once considered the Achilles heel of all Windows web applications, security has been completely revamped in ASP.NET 2.0. This section explains the various forms of available security, and how to best apply them
- Taking things further using Advanced User Interface Techniques. This includes User Controls, Customer Server Controls, client-side JavaScript and GDI+. This is where the real strength of ASP.NET 2.0 lies
- Web Services. In an increasingly connected world, working with web services grows in importance. This book will show you how to work with them
微软已经提供了IE7 Beta 2的下载。
Internet Explorer 7 Beta 2 for Windows XP SP2
但是这个Beta 2我在使用的过程中仍然遇到一个和之前CTP版本同样的问题,就是如果你在Tools里面设置了你的HTTP代理的话,即便你钩选掉这个选项了,IE同样还是去尝试连接这个代理服务器,然后告诉你无法连接。
这次本来以为在Beta 2内能修复这个Bug,但是又上当了,我把注册表里面所有和Proxy相关的地方都删除了,重启动IE后,仍然发现他创建了这个代理,并且让他有效。
甚至我在卸载了IE7之后,发现IE6也同样发生了这个问题,在之前所有的CTP版本都有这个问题,没想到正式的Beta 2还是这样。
实在没有办法,就只好又开始用FF了,我两次被迫使用FF都是因为IE7的这个缘故。。。
又由于 博客堂的Blog不支持FF,甚至也不支持IE7,我写的文字就全成一团了,不能换行,不能使用格式,我只能直接使用HTML来自己格式化这片Blog ...
Team Foundation Server 1.0如期的发布了。
http://blogs.msdn.com/jeffbe/archive/2006/03/17/553858.aspx
http://blogs.msdn.com/johnlawr/archive/2006/03/17/553864.aspx
但是目前VST - Suite版本的MSDN订阅只能下载到Workgroup版本以及试用版本,不知道啥级别才能下载完整的正式版本?
Workgroup Edition只有5个用户。
TFS的文档也同步更新到了正式版本
http://msdn2.microsoft.com/en-US/library/ms181232(VS.80).aspx
补充一下:
虽然WorkGroup版本限制了5个用户,但是可以通过购买TFS的CAL许可,来增加用户上限。这个模式类似于SQL Server。
如果购买了VS 2005的四个版本之一,那么自动包含一份TFS CAL.
http://msdn.microsoft.com/vstudio/teamsystem/team/tfs_plan/default.aspx
昨天在安装SQL 2005 RTM的时候碰到了这样一个错误:
TITLE: Microsoft SQL Server 2005 Setup
------------------------------
The SQL Server System Configuration Checker cannot be executed due to WMI configuration on the machine XXXX Error:2147749896 (0x80041008).
For help, click: http://go.microsoft.com/fwlink?LinkID=20476&ProdName=Microsoft+SQL+Server&ProdVer=9.00.1399.06&EvtSrc=setup.rll&EvtID=70342
------------------------------
BUTTONS:
OK
------------------------------
之前安装了N次都没有碰到,而机器也是干净的,新安装的英文Windows Server 2003 with lastest Patchs。错误信息里面的Link也没有提供任何可利用的信息。
从错误信息来看好像是WMI损坏了,于是Google一下,发现有一个解决方法:Re-installing WMI ,里面提到是因为更新2K3最新补丁造成的这个错误:The cause of this error is a corrupt install of WMI, caused by upgrading Windows Server 2003 to SP1 build 1277,虽然他针对的是CTP版本。但是发现根本不能运行。
我的2K3是SP1 build 1447,仍然出现这个错误。
幸运的是终于找到了一个Fix WMI的Script脚本,运行之后就好了:
FIXWMI.CMD
------------------------
@echo on
cd /d c:\temp
if not exist %windir%\system32\wbem goto TryInstall
cd /d %windir%\system32\wbem
net stop winmgmt
winmgmt /kill
if exist Rep_bak rd Rep_bak /s /q
rename Repository Rep_bak
for %%i in (*.dll) do RegSvr32 -s %%i
for %%i in (*.exe) do call :FixSrv %%i
for %%i in (*.mof,*.mfl) do Mofcomp %%i
net start winmgmt
goto End
:FixSrv
if /I (%1) == (wbemcntl.exe) goto SkipSrv
if /I (%1) == (wbemtest.exe) goto SkipSrv
if /I (%1) == (mofcomp.exe) goto SkipSrv
%1 /RegServer
:SkipSrv
goto End
:TryInstall
if not exist wmicore.exe goto End
wmicore /s
net start winmgmt
:End
如果你碰巧也遇到了这个问题,不妨看看能否解决?