知道了这些,再想知道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;
}