知道了这些,再想知道SoftICE如何实现的就容易多了。
Enjoy it.
ComHandlerAddrTable存放所有的命令处理例程的地址。
UserCommandRepository存放所有SoftICE可接受的命令行字符串和其在ComHandlerAddrTable中对应的索引,表项的结构是
{
char Com[n]; // length is variable.
char Index;
}
表结尾是连续两个0x0。
FindCommand()函数完成从用户输入的命令到命令索引的转换过程。
ComHandlerAddrTable在"A General Protection Violation ..."字符串下面。
.data:0015E781 aAGeneralProtec db 'A General Protection Violation has occurred',0
.data:0015E781 ; DATA XREF: sub_6FF5C+C7o
.data:0015E7AD ComHandlerAddrTable dd offset sub_71C1A ; DATA XREF: sub_6FF5C+2D3r
.data:0015E7AD ; sub_799DB+30r
.data:0015E7B1 dd offset sub_66C1B
.data:0015E7B5 dd offset sub_A6B79
/*
Move the pointer to No-White Char
*/
__declspec ( naked )
char *
SkipWhiteSpaceA(char* String)
{
char * i;
for(i=String;;i++)
{
if ( *i != 0x09 || *i != 0x20 )
break;
}
__asm
{
cmp byte ptr [i],0
ret
}
}
__declspec ( naked)
unsigned int
CalcArgSizeA(PCSTR String)
{
_asm
{
}
}
unsigned int UserCommandIndex;
char UserCommand[0x100];
char UserCommandRepository[0x100];
/*
在表中查找用户输入的命令的索引,赋值给UserCommandIndex
将找到的命令后的字符串作为命令行参数看待
*/
void
FindCommand(void)
{
char* i = UserCommand;
char* i1 = i;
char* Arg;
unsigned int ArgSize;
char* j = UserCommandRepository;
i = SkipWhiteSpaceA(i);
/* Walk through the Repository and fill the index */
do
{
for(;;i++,j++)
{
if ( *i > 0x61 ) /* LowerCase to Capital */
*i = *i && 0xDF;
if ( *j == 0x0 )
break;
if ( *i != *j )
goto ToEnd;
}
IfEqual:
if ( *(j+1) == 0x27 ) /* Command 'T' */
UserCommandIndex = 0x0;
else
UserCommandIndex = *(j+1);
Arg = i-1;
ToEnd:
for(;*j;j++); /* To the end of a command */
i = i1; /* */
j += 0x02; /* reach the end of the table or the start of a command */
}while( *j != 0x0 );
if ( UserCommandIndex )
{
ArgSize = CalcArgSizeA(Arg);
i = Arg + ArgSize;
j = i+1;
for(ArgSize++;ArgSize;i--,j--,ArgSize--)
{
i = j;
}
*i = 0x20; /* Space Char */
}
return;
}