电脑系统检查方案编写规范,电脑系统检查方案编写规范最新
教你查杀DLL木马
从DLL技术说起
要了解DLL木马,就必须知道这个“DLL”是什么意思,所以,让我们追溯到几年前,DOS系统大行其道的日子里。在那时候,写程序是一件繁琐的事情,因为每个程序的代码都是独立的,有时候为了实现一个功能,就要为此写很多代码,后来随着编程技术发展,程序员们把很多常用的代码集合(通用代码)放进一个独立的文件里,并把这个文件称为“库”(Library),在写程序的时候,把这个库文件加入编译器,就能使用这个库包含的所有功能而不必自己再去写一大堆代码,这个技术被称为“静态链接”(Static Link)。静态链接技术让劳累的程序员松了口气,一切似乎都很美好。可是事实证明,美好的事物不会存在太久,因为静态链接就像一个粗鲁的推销员,不管你想不想要宣传单,他都全部塞到你的手上来。写一个程序只想用到一个库文件包含的某个图形效果,就因为这个,你不得不把这个库文件携带的所有的图形效果都加入程序,留着它们当花瓶摆设,这倒没什么重要,可是这些花瓶却把道路都阻塞了——静态链接技术让最终的程序成了大块头,因为编译器把整个库文件也算进去了。
时代在发展,静态链接技术由于天生的弊端,不能满足程序员的愿望,人们开始寻找一种更好的方法来解决代码重复的难题。后来,Windows系统出现了,时代的分水岭终于出现。Windows系统使用一种新的链接技术,这种被称为“动态链接”(Dynamic Link)的新技术同样也是使用库文件,微软称它们为“动态链接库”——Dynamic Link Library,DLL的名字就是这样来的。动态链接本身和静态链接没什么区别,也是把通用代码写进一些独立文件里,但是在编译方面,微软绕了个圈子,并没有采取把库文件加进程序的方法,而是把库文件做成已经编译好的程序文件,给它们开个交换数据的接口,程序员写程序的时候,一旦要使用某个库文件的一个功能函数,系统就把这个库文件调入内存,连接上这个程序占有的任务进程,然后执行程序要用的功能函数,并把结果返回给程序显示出来,在我们看来,就像是程序自己带有的功能一样。完成需要的功能后,这个DLL停止运行,整个调用过程结束。微软让这些库文件能被多个程序调用,实现了比较完美的共享,程序员无论要写什么程序,只要在代码里加入对相关DLL的调用声明就能使用它的全部功能。最重要的是,DLL绝对不会让你多拿一个花瓶,你要什么它就给你什么,你不要的东西它才不会给你。这样,写出来的程序就不能再携带一大堆垃圾了——绝对不会让你把吃剩的东西带回家,否则罚款,这是自助餐。(静态链接与动态链接)
DLL技术的诞生,使编写程序变成一件简单的事情,Windows为我们提供了几千个函数接口,足以满足大多数程序员的需要。而且,Windows系统自身就是由几千个DLL文件组成,这些DLL相互扶持,组成了强大的Windows系统。如果Windows使用静态链接技术,它的体积会有多大?我不敢想。
应用程序接口API
上面我们对DLL技术做了个大概分析,在里面我提到了“接口”,这又是什么呢?因为DLL不能像静态库文件那样塞进程序里,所以,如何让程序知道实现功能的代码和文件成了问题,微软就为DLL技术做了标准规范,让一个DLL文件像奶酪一样开了许多小洞,每个洞口都注明里面存放的功能的名字,程序只要根据标准规范找到相关洞口就可以取得它要的美味了,这个洞口就是“应用程序接口”(Application Programming Interface),每个DLL带的接口都不相同,尽最大可能的减少了代码的重复。
用Steven的一句话:API就是一个工具箱,你根据需要取出螺丝刀、扳手,用完后再把它们放回原处。
在Windows里,最基本的3个DLL文件是kernel32.dll、user32.dll、gdi32.dll。它们共同构成了基本的系统框架。
DLL与木马
DLL是编译好的代码,与一般程序没什么大差别,只是它不能独立运行,需要程序调用。那么,DLL与木马能扯上什么关系呢?如果你学过编程并且写过DLL,就会发现,其实DLL的代码和其他程序几乎没什么两样,仅仅是接口和启动模式不同,只要改动一下代码入口,DLL就变成一个独立的程序了。当然,DLL文件是没有程序逻辑的,这里并不是说DLL=EXE,不过,依然可以把DLL看做缺少了main入口的EXE,DLL带的各个功能函数可以看作一个程序的几个函数模块。DLL木马就是把一个实现了木马功能的代码,加上一些特殊代码写成DLL文件,导出相关的API,在别人看来,这只是一个普通的DLL,但是这个DLL却携带了完整的木马功能,这就是DLL木马的概念。也许有人会问,既然同样的代码就可以实现木马功能,那么直接做程序就可以,为什么还要多此一举写成DLL呢?这是为了隐藏,因为DLL运行时是直接挂在调用它的程序的进程里的,并不会另外产生进程,所以相对于传统EXE木马来说,它很难被查到。
DLL的运行
虽然DLL不能自己运行,可是Windows在加载DLL的时候,需要一个入口函数,就如同EXE的main一样,否则系统无法引用DLL。所以根据编写规范,Windows必须查找并执行DLL里的一个函数DllMain作为加载DLL的依据,这个函数不作为API导出,而是内部函数。DllMain函数使DLL得以保留在内存里,有的DLL里面没有DllMain函数,可是依然能使用,这是因为Windows在找不到DllMain的时候,会从其它运行库中找一个不做任何操作的缺省DllMain函数启动这个DLL使它能被载入,并不是说DLL可以放弃DllMain函数。
DLL木马技术分析
到了这里,您也许会想,既然DLL木马有那么多好处,以后写木马都采用DLL方式不就好了吗?话虽然是这么说没错,但是DLL木马并不是一些人想象的那么容易写的。要写一个能用的DLL木马,你需要了解更多知识。
1.木马的主体
千万别把木马模块写得真的像个API库一样,这不是开发WINAPI。DLL木马可以导出几个辅助函数,但是必须有一个过程负责主要执行代码,否则这个DLL只能是一堆零碎API函数,别提工作了。
如果涉及一些通用代码,可以在DLL里写一些内部函数,供自己的代码使用,而不是把所有代码都开放成接口,这样它自己本身都难调用了,更不可能发挥作用。
DLL木马的标准执行入口为DllMain,所以必须在DllMain里写好DLL木马运行的代码,或者指向DLL木马的执行模块。
2.动态嵌入技术
Windows中,每个进程都有自己的私有内存空间,别的进程是不允许对这个私人领地进行操作的,但是,实际上我们仍然可以利用种种方法进入并操作进程的私有内存,这就是动态嵌入,它是将自己的代码嵌入正在运行的进程中的技术。动态嵌入有很多种,最常见的是钩子、API以及远程线程技术,现在的大多数DLL木马都采用远程线程技术把自己挂在一个正常系统进程中。其实动态嵌入并不少见,罗技的MouseWare驱动就挂着每一个系统进程-_-
远程线程技术就是通过在另一个进程中创建远程线程(RemoteThread)的方法进入那个进程的内存地址空间。在DLL木马的范畴里,这个技术也叫做“注入”,当载体在那个被注入的进程里创建了远程线程并命令它加载DLL时,木马就挂上去执行了,没有新进程产生,要想让木马停止惟有让挂接这个木马DLL的进程退出运行。但是,很多时候我们只能束手无策——它和Explorer.exe挂在一起了,你确定要关闭Windows吗?
3.木马的启动
有人也许会迫不及待的说,直接把这个DLL加入系统启动项目不就可以了。答案是NO,前面说过,DLL不能独立运行,所以无法在启动项目里直接启动它。要想让木马跑起来,就需要一个EXE使用动态嵌入技术让DLL搭上其他正常进程的车,让被嵌入的进程调用这个DLL的DllMain函数,激发木马运行,最后启动木马的EXE结束运行,木马启动完毕。
启动DLL木马的EXE是个重要角色,它被称为Loader,如果没有Loader,DLL木马就是破烂一堆,因此,一个算得上成熟的DLL木马会想办法保护它的Loader不会那么容易被毁灭。记得狼狈为奸的故事吗?DLL木马就是爬在狼Loader上的狈。
Loader可以是多种多样的,Windows的rundll32.exe也被一些DLL木马用来做了Loader,这种木马一般不带动态嵌入技术,它直接挂着rundll32进程运行,用rundll32的方法(rundll32.exe [DLL名],[函数] [参数])像调用API一样去引用这个DLL的启动函数激发木马模块开始执行,即使你杀了rundll32,木马本体还是在的,一个最常见的例子就是3721中文实名,虽然它不是木马。(图3--启动项)
注册表的AppInit_DLLs键也被一些木马用来启动自己,如求职信病毒。利用注册表启动,就是让系统执行DllMain来达到启动木马的目的。因为它是kernel调入的,对这个DLL的稳定性有很大要求,稍有错误就会导致系统崩溃,所以很少看到这种木马。
有一些更复杂点的DLL木马通过svchost.exe启动,这种DLL木马必须写成NT-Service,入口函数是ServiceMain,一般很少见,但是这种木马的隐蔽性也不错,而且Loader有保障。
4.其它
到这里大家也应该对DLL木马有个了解了,是不是很想写一个?别急,不知道大家想过没有,既然DLL木马这么好,为什么到现在能找到的DLL木马寥寥无几?现在让我来泼冷水,最重要的原因只有一个:由于DLL木马挂着系统进程运行,如果它本身写得不好,例如没有防止运行错误的代码或者没有严格规范用户的输入,DLL就会出错崩溃。别紧张,一般的EXE也是这样完蛋的,但是DLL崩溃会导致它挂着的程序跟着遭殃,别忘记它挂接的是系统进程哦,结局就是……惨不忍睹。所以写一个能公布的DLL木马,在排错检查方面做的工作要比一般的EXE木马多,写得多了自己都烦躁……
DLL木马的发现和查杀
经常看看启动项有没有多出莫名其妙的项目,这是Loader的所在,只要杀了狼,狈就不能再狂了。而DLL木马本体比较难发现,需要你有一定编程知识和分析能力,在Loader里查找DLL名称,或者从进程里看多挂接了什么陌生的DLL,可是对新手来说……总之就是比较难啊比较难,所以,最简单的方法:杀毒软件和防火墙(不是万能药,切忌长期服用)。
DLL木马检测与清除实例
守护者(NOIR—QUEEN)是一个典型的DLL木马程序,其服务端以DLL文件的形式插入到系统的Lsass.exe进程中。Lsass.exe进程是一个本地的安全授权服务,并且它会为使用Winlogon服务的授权用户生成一个进程,如果授权是成功的,Lsass就会产生用户的进入令牌。由于Lsass.exe是系统的关键进程,不能被终止,那么我们该如何清除这样的木马呢?
守护者木马入侵系统后,会在服务中添加一项名为“QoSserver”的服务,并将“QoSserver.dll”文件插入到Lsass进程中,使其可以隐藏进程并自动启动。我们利用“进程猎手”这样的工具查看Lsass进程所调用的DLL文件,并与木马入侵前的信息比较,可以发现Lsass进程中增加了“QoSserver.dll”文件。记录下该文件的具体位置,本例中为“C:\Windows\system32\QoSserver.dll”。
打开WindowsXP任务管理器,切换到“进程”选项卡中,结束“QoSserver.exe”进程,同时将系统目录下的“QoSserver.exe”文件删除。然后运行Regedit,在注册表编辑器中依次展开[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\QoSserver],直接删除“QoSserver”项,重启计算机。重启之后,再将系统目录下的“QoSserver.dll”文件删除。需要注意的是,如果前面未删除“QoSserver.exe”文件,而只删除了QoSserver服务并重启之后,插入到Lsass进程当中的“QoSserver.dll”又会生成另外一个名为“AppCPI”的服务。这时再次打开注册表编辑器,展开[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\AppCPI],删除AppCPI项。如果QoSserver服务同时复活,则要将该服务的启动类型改为“禁用”。重新启动计算机后,再删除系统目录下的木马文件。
防范DLL木马
1.安装木马查杀工具。对于多数人而言,要想通过手工查杀DLL木马是不太现实的,因此安装一款可以查杀此类木马的反病毒软件,是非常有必要的。这里还要提醒读者的是,应及时升级病毒数据库,这样才能保证有效地查杀绝大部分木马病毒。当然,我们也可以在计算机中安装那些专门针对木马的查杀工具,例如木马克星。
2.查看是否有不明端口开放以及对端口通信进行监控。只要木马进行连接,接受/发送数据则必然会打开端口,DLL木马也不例外,我们可以通过“Netstat-ano”命令来查看TCP/UDP端口的连接,以及开放端口的进程标识符,也可以直接使用进程端口查看工具Fport.exe来查看与端口对应的进程,以发现是否有不明的连接和端口开放。另外,有些DLL木马通过端口劫持或者端口重用的方法来进行通信,所以仅是查看端口还是不够的,有必要的话,我们可使用嗅探器来了解打开的端口到底在传输些什么数据。
3.检查系统目录下是否有可疑的DLL文件。安装好系统和所有应用程序之后,可对系统目录下System32文件夹中的EXE和DLL文件作一记录:在命令提示符下执行“dir*.exe>bak1.txt&dir*.dll>bak2.txt”,将所有的EXE和DLL文件信息导出成TXT文件保存。当日后发现异常时,可以使用相同的命令再次备份,并使用FC命令比较两次的EXE文件和DLL文件。通过这种方法,我们可以发现可疑的EXE和DLL文件,同时通过文件的大小、创建时间来判断是否为DLL木马。
4.查看系统进程调用的DLL文件。当我们怀疑有DLL木马插入到系统进程,可以使用一些第三方进程工具来查看进程所调用的DLL文件,然后进一步确认是否中了DLL木马。此类查看工具有进程猎手、进程间谍等等。另外,我们也可以使用XP系统自带的命令行工具TaskList,来显示进程调用的DLL文件,并将这些信息导出成TXT文件保存,以便随时进行比较。
但我们就要利用这种木马 因为他比较难查杀 所以~~~~~~~~~~~~~
DLL注入木马如是说
DLL库链接文件,是Windows系统中许多驱动和程序运行时必需的文件。一般来说,这类文件无法单独运行,必须通过某个EXE文件调用该DLL文件,从而执行相应的功能。同时,当该EXE文件正在执行时,调用的DLL文件无法被删除。正因为由于DLL文件具有隐蔽性,并且很难删除,因此目前许多流行的木马程序都采用了DLL文件方式进行安装,将木马DLL文件加载到某个正常的系统进程中,从而达到隐藏木马进程和保护木马文件的目的——这就是所谓的DLL注入式木马。
木马是如何将DLL文件进行加载的呢?这里我们以一个黑客常用的DLL木马“上兴远程控制木马”为例进行讲解。
运行“上兴木马”后,点击界面中“配置服务端”按钮,打开服务端生成程序。在“DNS域名解析更新IP”中输入自己的IP地址或者动态DNS域名,在安装名称中输入生成的服务端DLL文件名。木马运行后,该DLL文件将被注入到下面“宿主进程名”中指定的系统进程中,默认为“explorer.exe”。最后点击生成按钮,即可生成木马文件“rejoice_06.exe”。
将生成的木马文件传播,当其他用户运行后,就可以通过上兴木马远控客户端进行控制了。
警报,病毒无法清除
如果系统中被植入了DLL木马,将会出现什么情况呢?
首先,系统被黑客远程控制,出现数据丢失等情况;其次,杀毒软件会报警系统中有病毒,但是却无法进行清除。例如,在电脑中运行了上面制作的上兴远控木马后,笔者电脑上安装的杀毒软件提示发现病毒,但是在删除DLL病毒文件时却失败了。即使我们手工删除病毒文件,也会因为DLL文件正在使用中,所以也无法彻底删除。即使进入安全模式,得到的也是同样的结果。
另外,由于DLL木马是插入到系统进程中的,因此通过任务管理器等进程工具,也无法发现任何木马进程,这给木马的清除带来了很大的困难!
无法删除病毒文件,无法查找到木马进程,那么到底该如何清除DLL注入式木马呢?
无所遁形,揪出木马藏身之所
虽然木马没有自己的进程,但是有一个宿主进程,只要结束宿主进程,停止DLL文件的调用,就梢陨境鼶LL文件,进而清除木马。因此,清除DLL木马的第一步,就是找到木马注入的宿主进程。那么,如何才能找到木马注入的宿主进程呢?且让我们细细看来。
以清除“上兴远控木马”为例,从杀毒软件的报警提示中已经知道木马DLL文件名为“rejoice.dll”。因此,就可以通过一些查看进程调用DLL文件的进程管理工具,找到该文件的宿主进程,此类工具很多,比如大名鼎鼎的ICESword。
运行IceSword后,点击左侧边栏“查看→进程”,就可以在其右侧窗口中看到所有进程列表。右键点击某进程,在弹出菜单中选择“模块信息”命令,即可看到该进程调用的所有DLL文件。
提示:DLL注入式木马通常是将DLL文件,加载到explorer.exe、svchost.exe、winlogon.exe、iexplore.exe等系统进程中的。因此在查找DLL宿主文件时,可以关闭其它无关的程序,然后依次检查这几个进程中的DLL文件。
不过一个一个的检查系统进程,确实有些麻烦,如何才能快速的定位木马的宿主进程呢?可以使用一款名为“procexp”的进程管理工具。运行procexp后,在程序界面中间显示的是树状进程关系列表,下方是每个进程的详细信息。点击菜单“Find→Find DLL”命令,打开DLL文件查找对话框,在“DLL Substring”中输入要查找的关键词,这里输入刚才杀毒软件扫描出的DLL文件名“rejoice.dll”。然后点击“Search”按钮,在下方的列表中就可以看到该DLL文件是被哪个进程调用的了。 牛刀小试,清除普通进程DLL注入木马
对于大部分DLL注入木马,其注入到“iexplore.exe”和“explorer.exe”这两个进程。对于这类普通进程的DLL木马,清除将是非常方便的。
如果DLL文件是注入到“iexplore.exe”进程中,由于此进程就是IE浏览器进程,因此就需要先关掉所有IE窗口和相关程序,然后直接找到DLL文件进行删除就可以了。
如果DLL文件是注入到“explorer.exe”进程中,那么就略显麻烦一些。由于此进程用于显示桌面和资源管理器,因此,当通过任务管理器结束掉“explorer.exe”进程时,桌面无法看到,桌面上所有图标消失掉,"我的电脑"、"网上邻居"等所有图标都不见了,同时,也无法打开资源管理器找到木马文件进行删除。怎么办呢?
实际上,解决的方法也很简单。在任务管理器中点击菜单“文件→新任务运行”,打开“创建新任务”对话框,点击“浏览”按钮,通过浏览对话框就可以打开DLL文件所在的路径。然后选择“文件类型”为“所有文件”,即可显示并删除DLL文件了。
在浏览对话框中删除DLL文件
除恶务尽,清除特殊DLL注入木马
除了以上所说的注入普通进程的DLL木马之外,还有许多木马注入到系统里关键进程中,比如svchost.exe、smss.exe、winlogon.exe进程。这些进程使用普通方式无法结束,使用特殊工具结束掉进程后,却又很可能造成系统崩溃无法正常运行的情况。对于这些木马,我们可以通过以下两种方法进行清除。
1.使用IceSword卸载DLL文件
IceSword的功能十分强大,我们曾在以前作过介绍,在这里,就可以利用它卸载掉已经插入到正在运行的系统进程中的DLL文件。在IceSword的进程列表显示窗口中,右键点击DLL木马宿主进程,选择弹出命令“模块信息”。在进程模块信息对话框中找到DLL木马文件,选择文件后点击“强制解除”命令,即可将系统进程中的DLL木马文件卸载掉了
卸载系统进程中的DLL木马
2.SSM终结所有DLL木马
使用IceSword可以卸载大部分的DLL木马文件,但还有某些特殊木马在卸载时,却会造成系统崩溃重启。例如一款著名的木马PCShare采用了注入“winlogon.exe”进程的方式运行,由于该进程是掌握Windows登录的,因此在使用IceSword卸载时,系统将会立即异常重启,根本来不及清除掉DLL文件,在重启后DLL木马又被再次加载。对于这类DLL木马,必须在进程运行之前阻止DLL文件的加载。接下来,我们又要用到一款用于阻止DLL文件加载的安全工具——“System Safety Monitor”(简称SSM)。
提示:SSM是一款俄罗斯出品的系统监控软件,通过监视系统特定的文件(如注册表等)及应用程序,达到保护系统安全的目的。这款软件功能非常强大,可以辅助防火墙和杀毒软件更好的保护系统安全。
运行SSM,在程序界面中选择“规则”选项卡,右键点击中间规则列表空白处,选择“新增”命令,弹出文件浏览窗口,选择浏览文件类型为“DLL files”,在其中选择指定文件路径“C:\Windows\system32\rejoice.dll”。点击“确定”按钮后,即可把“rejoice.dll”文件添加到规则列表中,然后在界面下方的“规则”下拉列表中选择“阻止(F2)”。完成添加规则设置后,点击“应用设置”按钮,后重启系统。
阻止DLL文件加载到进程
提示:在重启系统前请检查SSM的设置,确保SSM随系统启动而加载运行。
当系统重启时,SSM就会自动阻止相关进程调用“rejoice.dll”木马文件。这样,该木马文件便不会被任何程序使用,在硬盘中找到它,直接删除即可。
雁过无声,清除木马残留垃圾
DLL注入型木马并不会感染其它文件,只要结束木马进程并删除掉病毒文件木马,木马就没有任何危害性了。剩下的工作就是清除掉木马在注册表和其它启动文件中留下的项目。方法很简单,点击“开始→运行”,输入“regedit”命令,就会打开“注册表编辑器”,利用搜索功能,便可以清除木马在注册表中留下的垃圾;输入“mscnofig”命令,就可以打开系统配置实用程序,清除木马在启动文件中的踪影。
编后:木马选择注入的系统进程也不尽相同。在碰到此类木马时,我们可以首先考虑用procexp之类的工具,查找出DLL文件的宿主进程。找到宿主进程后,如果是注入到普通可结束的进程中,可以直接将宿主进程终止后删除DLL木马文件即可。如果DLL文件是注入到系统关键进程中的话,可以考虑用IceSword卸载DLL文件;如若失败,那么直接用SSM建立规则,阻止DLL文件的加载就可以了。
个人强烈建议:你也可以利用一些软件的 “粉碎文件” 工具也可以达到预期杀毒的效果.
---
回答比较长,希望你能解决问题。
一. 应用实例的分析与开发
---- 我们以学籍管理系统为背景,基于Windows DNA的思想,开发了一套应用系统。在该系统中,有关教务学籍的事务逻辑都是由定制COM组件来处理的,动态Web页面通过ASP脚本调用这些组件。系统在开发速度和软件质量等方面都优于不用COM组件而仅用ASP脚本的方案。为说明问题,我们通过一个定制组件和ASP脚本的主要代码简单介绍局部功能的实现过程。
---- 在displayscore.asp页面中接受、辨别用户的查询请求,做出不同的查询处理。当客户的身份为教师或教务时,可以查询所有学生的成绩;当客户的身份为学生时,只能查询该生本人的成绩。
---- 定制COM组件Score.dll进行查询处理。首先设计该组件的接口,为组件设置四个属性: Subj(课程)、Term(课程所属学期)、Class(查询的班级)和Stu_No(查询学生的学号);定义两个方法:RequeryScores和RequeryAllScores,分别对教师、教务部门和学生的请求做出相应的处理,并将查询结果集返回给用户。
---- 以下是实现该组件Score.dll的部分关键代码。从中我们可以看到组件的接口是如何实现的:
Option Explicit
Private m_StuNo As Variant
Private m_Subj As String
Private m_Term As String
Private m_Class As String
' 设置属性为可写入的
Public Property Let StuNo(ByVal vNewValue As Variant)
m_StuNo = vNewValue
End Property
Public Property Let Subj(ByVal vNewValue As Variant)
m_Subj = vNewValue
End Property
......
' 学生查询成绩请求处理
Public Function RequeryScores() As Object
Dim objContext As MTxAS.ObjectContext
Set objContext = GetObjectContext()
' 建立事务性组件
Dim ObjConn As ADODB.Connection
' 利用ADO访问数据库
Dim ObjRecordset As ADODB.Recordset
Set ObjConn = New ADODB.Connection
ObjConn.Open "xia", "sa", ""
Set ObjRecordset = New ADODB.Recordset
Dim query As String
' 根据查询要求(查询所有课程、查询特定学期的所有课程、
查询指定课程、查询特定学期的某一课程)进行不同的查询操作
If (m_Subj = "all" And m_Term <> "all") Then
query="select Client_Name,Client.Client_No,Courses.subject,
stu_score.score,stu_score.term,sub_type"
query = query & " from client,stu_score,courses"
query=query&"where client.client_no=stu_score.client_no
and stu_score.subject=courses.subject
and courses.term=stu_score.term
and courses.term='" & m_Term & "'
and Client.Client_no='" & m_StuNo & "'"
End If
......
ObjRecordset.Open query, ObjConn
' 进行数据库查询
ObjContext.SetComplte
' 若事务成功完成,则提交该事务
RequeryScoresExit:
Set RequeryScores = ObjRecordset
' 返回查询结果集
Exit Function
RequeryScoresErr:
Set RequeryScores=Nothing
' 事务失败处理
End Function
' 教师、教务查询成绩请求处理
Public Function RequeryAllScores() As Object
......
End Function
---- 在ASP页面displayscore.asp中引用组件,ASP代码如下(其中加粗的部分便是对该组件的调用):
< %@ LANGUAGE="VBSCRIPT" % >
< HTML >
< HEAD >
< META NAME="GENERATOR" Content="Microsoft
Visual InterDev 1.0" >
< META HTTP-EQUIV="Content-Type"
content="text/html; charset=gb_2312-80" >
< TITLE >Show To Teacher< /TITLE >
< /HEAD >
< BODY background="images/bk.GIF" >
< %
dim objResult
set objResult=Server.CreateObject("Display.Score")
dim Term,Subject
Term=Cstr(Request.Form("Term"))
Subject=Cstr(Request.Form("Subject"))
objResult.term=Request.Form("term")
objResult.Subj=RequestForm("Subject")
objresult.class=Request.Form("Class")
dim Scores
set Scores=objResult.RequeryAllScores
% >
' 以下代码为显示处理的结果
< div align="center" >< center >
......
< table border="0" cellpadding="0"
cellspacing="1" width="100" >< tr >
< %For I = 0 To Scores.Fields.Count - 1% >
< td bgcolor="#004080" >
< strong >< font color="#FFFFFF" > < small >?
< %=scores(I).Name% >< /font > < /strong >?< /td >
< %NEXT
Do While (Not Scores.EOF)% >
< /tr >< tr >
< % For I = 0 To Scores.Fields.Count - 1% >
< td bgcolor="#ACE8F9" >< p align="center" >
?< %= Scores(I).Value% >< /td >
< %Next
Scores.MoveNext% >< /tr >
< %Loop% >
< %Scores.close
' 关闭数据库连接
set Scores=Nothing
set objResult=Nothing % >
' 释放对象
< /table >< /center >< /div >
< /BODY >
< /HTML >
---- 可以想象,如果仅使用ASP脚本进行业务处理就会使ASP页面中代码十分臃肿、晦涩。而使用组件的方案也较单纯的ASP脚本执行速度速度快。并且可以将整个查询处理作为一个事务,保证数据库信息的安全、完整。将该组件在MTS中注册,又可避免多用户访问该主页时可能造成的网络拥塞。实际应用中,学生和教师的使用权限是不同的。在学生查询成绩的页面中,可重用该组件,只是调用其不同的接口而已。仅使用ASP脚本进行业务处理,则需重新编写与displayscore.asp类似的、同样烦琐的代码。在开发过程中,不同的开发人员可各尽所能,同时进行组件和ASP页面的设计,缩短了软件开发周期。
---- 以下两图显示的是教师(教务)查询成绩和显示查询结果的页面:
二. 开发过程中辅助工具的使用
---- 传统的软件工程进行的需求分析、数据库设计等都是人们“纯手工”完成的,缺乏严谨性和规范性。而在以组件为中心的系统分析和软件开发过程中,应力争使用有效的计算机辅助工具,以适应快速建模和组件方法新形势的需要,提高分析的质量及精度。
---- 有很多辅助工具可以利用。由于以组件为中心的系统分析过程仍保留着传统软件工程方法的脉络痕迹,北大青鸟的CASE工具对传统的软件工程方法比较有效,我们采用了这一工具。在数据库建模方面,我们选用了SYBASE 公司的S-Designer,可将数据库概念模型自动转化为物理模型。
---- 1. 利用青鸟CASE工具编写需求分析文档
---- 长久以来,人们已习惯于“纯手工”地进行需求分析。开发人员对现有系统和用户要求进行调查后,需要设计系统的数据流图(DFD图),编写小说明,设计系统的结构图(SC图)。但这种分析方法是不严谨的,由于种种原因,可能会发生加工、数据流、文件的语法定义错误;数据流图上下各层不一致;数据流图分解后的数据不平衡,或文件等重名及文档不完备等各种问题,影响了我们对用户需求的分析和理解,防碍了今后的工作。尤其是对组件的分析失当,后果不堪设想。
---- 青鸟CASE工具提供的即是一套支持软件工程中采用传统的结构化方法进行需求分析、软件设计的工具。由工具生成的每个文件即一个项目,每个项目均包括数据流图和模块结构图两部分:
数据流图部分辅助系统分析员完成对软件系统的需求分析、建立目标系统的需求模型、生成一份正确、完整的关于目标系统的说明文档;同时,提供对需求文档的查询、列表、分片、影响范围等分析功能,辅助软件设计人员对需求分析的结果文档进行深入、细致的分析和理解,以利于软件设计工作。
模块结构图部分辅助程序设计人员在需求分析阶段完成后对软件系统进行设计,支持模块的逐层细化,建立系统的软件体系结构,最后得到一份正确、完整的软件设计文档。同时,提供对设计文档进行查询、列表、分片、影响范围等分析功能,完成对设计的结果文档进行深入、细致的分析理解,以利于软件开发及维护工作。在SC图中组件的规划方案已见端倪,继续细化将得出每个组件的概要设计方案。
---- 在教务系统的实例中,利用青鸟CASE工具生成的DFD图和SC图如下图所示:
---- 系统1层DFD图 系统0层SC图
---- 2. 利用S-Designer进行数据库设计
---- 当完成系统的详细设计后,接下来便是数据库设计。数据库设计在整个软件工程中占有举足轻重的地位。数据库设计不合理,数据得不到合理、有效的存储,数据存在潜在的不一致性、不完整性或有大量冗余,都会降低系统性能,甚至使系统崩溃。
---- 手工的数据库设计完全依赖于设计者的设计水平。设计者首先必须根据实际需要建立若干个逻辑上存在的数据库表,并使其满足第三范式;而后根据它们之间的联系建立特定数据库表将其联系起来。这是一件相当烦琐的事。数据库设计者既要进行数据库的逻辑设计,又要将逻辑模型转成物理模型,而且设计出的数据库不一定能满足第三范式。合理的库表结构决定了访库组件接口的设计质量,所以原先数据库设计方式不适用于以组件对象为中心的软工设计。
---- 在教务系统的实例中,S-Designer使数据库设计变得轻松、简单起来。设计者只须根据现实需要,设计出数据库的E-R图,S-Designer会将逻辑模型转化为物理模型,为数据库表间的联系建立新表,指明表的主码、外码,并自动对数据库表进行一致性、冗余性、完整性检查,使数据库表满足第三范式。
---- 例:可首先设计出数据库表课程(Courses)和学生(Client)的逻辑模型:
---- 接下来,为表Courses和Client间建立联系。由S-Designer自动生成的物理模型,如下图所示,它们为访库组件的接口设计提供了准确的依据。
---- 可以相信,随着软件工程学的进一步成熟,将出现更多的计算机辅助工具,帮助软件开发人员构建出更完善的应用系统。许多辅助软件工具可以完成相似的工作,到底选用何种辅助工具取决于这些工具的性能以及使用者的习惯。
---- 以组件对象为中心的动态Web方法和DNA思想并不高深莫测,开发技术也愈加规范化。应当说,这套方法更适合客观信息结构的现实,也更接近于人们的思维方式,其技术有如行云流水般自然,很适合在中小型企业环境中推广和普及。
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。