June 2008 - Posts
[原文地址]:June 27th, 2008
[原文发表时间]:Friday, June 27, 2008 2:25 PM
今天是很特别的一天——至少对我们这些在微软的人来说是这样。
全世界都知道了这个消息,今天是Bill Gates作为微软全职雇员的最后一天。
在这里请允许我分享一些我的观点和想法。
作为微软的一部分,投身于伟大的产品和技术,提供给世界各地的人使用……我经历了非常美好的时光。与Bill Gates领导的微软高层共事,对我来说获益良多。过去的这些年来,我有很多机会与Bill接触,并从中学习。Bill是我非常欣赏和尊敬的人。
我从Bill那里学到的事情中,最重要的方面是以下几点:
- 全局思考,有宏伟的梦想
- 从长期发展的角度进行思考和优化
- 软件的力量是很强大的,在我们的工作下,软件已经前进了很多,但还有很大的成长空间
Bill通过软件、计算技术和微软,在世界各地创造了空前的影响力。现在他决定将更多时间和精力转移到基金会方面的工作。我想要感谢Bill所做的一切,并祝他的未来一切顺利。
这里是一个Channel 9视频,您将看到微软人分享与Bill的故事。
Namaste !
前几天老婆找我要一个可以抓取网页图片的软件,我推荐了HyperSnap,但是自己使用后发现即使滚屏方式,也是抓不全的,又在网上找了找,没有发现合适的,那干脆写一个吧!
原理也很简单,基于.net winform的WebBrowser,首先让WebBrowser去加载要抓取的网页,然后对WebBrowser进行拷屏,生成图片就OK了。原本用的Control类的DrawToBitmap方法,但是经常出现空白网页,后来采用
萧寒的方法解决。
下载地址:
http://www.openlab.net.cn/forums/threads/1207936.aspx#1207936
截图如下:

本文概述
StreamWriter 在产生UTF-8编码的内容时候,会在产生的这个UTF-8内容中增加BOM的信息,而这个BOM的信息,会干扰我们在一些情况的使用。
本文描述的情况,就是这种干扰让我们无法正常工作的一种情况。
何为BOM?
BOM(Byte Order Mark),BOM签名。
BOM的内容就可以表示unicode文件是何种编码。BOM签名的意思就是告诉编辑器当前文件采用何种编码,方便编辑器识别。
对于UTF-8 , BOM 信息为 EF BB BF。 我们如果在Google搜索 UTF-8 BOM 就会搜索到很多文章, BOM 在不少情况下,都会给我们添乱子。
下面是我碰到这个问题的描述
我碰到这个问题的场景:在书写一段模拟HTTP Post 请求的时候, 代码如下,但是却无法模拟Post请求:
private void do2()
{
string url = "http://localhost:39749/Default.aspx";
string indata = "__VIEWSTATE=%2FwEPDwUKMTQ2OTkzNDMyMWRkyGd";
indata += "iqWjBKr5rIKmHzSdD9AaojKw%3D&Button1=Button&__EVENTVALIDATION=%";
indata += "2FwEWAgLohfrVDQKM54rGBu49QLoa7JmG9cEfUpTccMrUmJfD";
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(url);
req.ContentType = "application/x-www-form-urlencoded";
req.Method = "Post";
Stream myRequestStream = req.GetRequestStream();
StreamWriter myStreamWriter = new StreamWriter(myRequestStream, Encoding.UTF8);
myStreamWriter.Write(indata);
myStreamWriter.Close();
myRequestStream.Close();
myStreamWriter.Dispose();
myRequestStream.Dispose();
HttpWebResponse res = (HttpWebResponse)req.GetResponse();
StreamReader reader = new StreamReader(res.GetResponseStream(), Encoding.UTF8);
string info = reader.ReadToEnd();
reader.Close();
res.Close();
reader.Dispose();
MessageBox.Show(info);
}
而文中中间的代码修改成下面代码则可以成功模拟。
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(indata);
req.ContentLength = bytes.Length;
Stream myRequestStream = req.GetRequestStream();
myRequestStream.Write(bytes, 0, bytes.Length);
myRequestStream.Close();
为何会这样呢?分析原因,竟然是 UTF-8 BOM 在作怪。
StreamWriter 在产生UTF-8编码的内容时候,会在产生的这个UTF-8内容中增加BOM的信息, 这样他发送的Post信息就比正常多了三个字节 EF BB BF。 就是因为这三个字节导致服务器端无法处理正常的Post请求。
解决方法:
1、自己重写UTF-8类,参看 http://www.19870202.com/?tid=381 。在调用的时候用这个自己写的类。
重写代码:
public class UTF8EncodingNoPreamble : System.Text.UTF8Encoding
{
public override byte[] GetPreamble()
{
return new byte[0];
}
}
2、不要用 StreamWriter ,参看我上面的替代方案。
参考资料:
System.IO.StreamWriter写UTF-8文件不写BOM
http://www.19870202.com/?tid=381
UTF-8, UTF-16, UTF-32 & BOM
http://unicode.org/faq/utf_bom.html#BOM
utf-8 保存文件的 bom 问题
http://www.uuzone.com/blog/tom/101761.htm
先从SQL注入攻击说起吧。
前一段时间的SQL注入攻击可以说让国内以及国外大量网站沦陷,几个攻击变种中幸好是update而不是delete,否则众多网站损失更大,不过从犯罪的角度来说,并不是这些攻击者心慈手软,而是update才能置入网页木马,也才能在置入成功后获得预期的利润。
在很多所谓的开发高手来看,SQL注入只是菜鸟才会犯的低级错误,其实不然。一个中大型的网站,在他不断发展的过程中,网站门户的程序都是Patch模式的逐步叠加,随着页面的增加以及版本的螺旋上升,SQL注入的危险百分比也会指数增长,尤其是国内各个网站开发的模式而言。当一个中大型网站的页面达到几万甚至几十万的时候,当这个网站的程序不断叠加积累,诸多历史页面已经处于失控的时候,如何避免SQL Inject攻击将会是一件令人非常头疼的事情,因为你此时是不可能完全重写整个网站或者完全对所有页面做代码安全审核的。
在这众多的历史页面代码中,一个微小的疏漏就导致你的DB完全向攻击者敞开,甚至威胁到服务器磁盘数据。
我以SQL Inject为例就是为了说明其实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 Inject攻击。对于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攻击和防御(..... ) - ..........
[原文发表地址]: ¡Bienvenido!
[原文发表时间]: Tuesday, June 17, 2008 8:49 AM
看着世界各地的软件开发都在迅速增长,是如此令人陶醉和兴奋。去年,十分荣幸的有人(来自Microsoft内部以及外部社区)将我的网络日志翻译成中文和日文,以方便更广泛的读者群体阅读。有不少人请求将我的网络日志翻译成西班牙文。这件事我已经考虑了一段时间了,终于在开发工具部内部找到了几个志愿者帮我做翻译。
现在,我的网络日志有英文、 中文、 日文和西班牙文等不同版本,这让我能接触到更多的热爱编写软件的人。
Namaste !
好久没有些东西了,好像大家最近都很忙,写东西的人不多。最近事情真的很多,国家大事多,体育赛事多,。。。。
SQL Server 2008 RC0已经发布了,但是我还没有去download呢,因为再等新机器,T61P,装了x64的系统,装SQL当然也要x64的,所以要等等。SQL Server 2008很多人都还没有用过,Webcast上倒是已经有很多课程了,大家可以去学学,很多新的功能还是不错的。我最近一直在做关于FileStream的东西,好多人也会有这种疑惑,为什么要把Blob数据,通俗的讲就是文件为什么要存储到数据库里,存到文件系统不是也很好吗?So.......美国人说话总是说So,大家可以想一个问题,如果你的文件很多,比如有N TB数据怎么办?还放到文件系统里吗?当然可以,放到哪里有你决定,但是文件很多的时候管理成本就会增加,而且存储成本也将不断的增加,客户需要一种文件管理的系统。Windows的文件管理并不是十分的好,如果你的一个文件夹中有数百万文件,估计这个文件夹也没办法展开了。多年前,我们还在用Windows XP&Windows Server 2003时,MS给了我们一个Idea-WinFS,新的文件管理平台,用数据库去管理文件系统,几百万条记录的检索在数据库中并不是很慢,至少不会像explorer一样死掉。但是遗憾的是在Vista中并没有发布这个东西。
在SQL Server 2008中的FileStream特性给我们提供了这样一个可能,就是WinFS,换个马甲我还认得,哈哈哈。我们可以把Blob数据存储到SQL Server中,当然数据空间并不是在传统的MDF中,还是在文件系统里,只不过我们可以通过SQL Server来进行管理,这样检索数据就会相对简单很多了。我们的这个客户Blob数据量估计在60T左右,按每个文件2MB,3千万个文件。千万级数据的查询应该不会太慢,因为我们没有什么关联的表。
但是MS的想法更大,一个大想法,RBS,Remote Blob Storage,也就是远程Blob存储系统,这个比WinFS的概念可就大多了,这个RBS就是希望通过利用更多小型的存储系统去替代那种昂贵的大型存储系统。当然这个RBS是一个Provider的模式,可以通过自己开发Provider来去实现各种存储的方式,可以存储到磁盘、磁带、数据库中,我们现在就是要做一个RBS Provider for SQL Database并且带有NLB的功能。这个大想法给用户带来的好处就是他们可以用统一的应用程序接口来去访问文件,而并不用关系文件存储的位置和存储系统,我们可以将数据存储在Near Line系统中当然这样的系统动不动就几个Million的$,也可以有一种选择放到数据库里面,当然通过RBS Client中我们就不用去知道后面这些东西怎么处理了,只要我们传一个StoreBlobId给RBS就可以了,我们通过自己实现的Provide算法去返回给客户端。RBS这个东西的目的很明显用SQL Server实现文件管理,当然这个是MS的目标,database这个词开始的时候就是做管理文件的,当然用RBS去连接其他的存储系统也是可以的,因为Provider的模式还是比较灵活的。这个东西还不知道是不是在SQL Server RC0中包含,但是RBS Client的代码是已经Completed。
以前我都很少研究Storage这个东西,毕竟好像和应用开发和数据库还有些距离,但是RBS这个就是介于Storage和App之间的一个桥梁,对于很多特殊的用户来说是非常有意义的,毕竟存储这个东西还是很贵的。
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
;
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
;
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
= ((uint) pPageoff
) * 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
= (uint) pPageoff
;
}
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
) + "\u2029");
this.iChapStr.Add((string) aChapStr
);
}
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
= (uint) (random.Next(1, 0xfffffff) * -1);
writer.Write('$');
writer.Write(numArray
);
writer.Write((uint) (9 + this.iZippedSeg
.Length));
writer.Write(this.iZippedSeg
);
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
;
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
= ((string) this.iChapter
).Replace("\r\n", "\u2029");
this.iContent = this.iContent + ((string) this.iChapter
);
this.iChapOff
= this.iTotalen;
this.iTotalen += ((string) this.iChapter
).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;
}
}
}
在2007年6月美国政府问责办公室(GAO)的一份报告中,是这样描述网络犯罪的:“具有显著的经济影响并危及美国国家安全利益”,并且参照了2005年FBI的一份调查报告,报告中估计了美国企业由于网络犯罪损失达 672亿美元,预计在2006年与盗窃身份资料有关的损失将达到493亿美元。
我们都知道网络犯罪是多么的严重,但是并不是每个人都了解软件最脆弱的部分在哪里。
据2007年7月微软安全情报报告,至2007年7月为止,小于10%的安全漏洞来自对于操作系统的攻击。但是大于90% 的安全漏洞来自于应用层,所有软件开发组织都需要认真地思考与之相关的安全问题。
在6437个2007年新发现的安全漏洞中,只有13.6%属于5个最大的软件供应商(微软,Oracle,IBM,苹果和思科)。
在此背景下,有必要问一个问题:“微软采取了什么行动来帮助开发者开发更加安全的应用软件?”