5.4.2 编码C程序

老师说道:“这里用的方法,是将ShellCode的每个字符‘ShellCode[i]’先和Key作异或得到temp,如果合法,就直接将temp保存在‘enShellCode[i]’当中;如果不合法,则将‘enShellCode[i]’存为‘0’,而把enShellCode[i+1]存为temp+‘0’。算法示意图如图5-10。”

“那么,‘0’是个标志?”宇强问道。

“对,当然,我们也可把‘0’换成其他的合法字符。解码时遇到标志字符时(这里是‘0’)就知道后面一位才是真正的ShellCode,要作一定变换才可恢复原来的值。”

“我们来看看程序DirectExchange.cpp吧(光盘有收录)!懂得了思路,也比较简单。”

#include <string.h>
#include <stdio.h>
#define KEY 0x97
unsigned char ShellCode[] = "\x41\x00\x42";
int main()
{
    int i, k;
    int nLen;
    unsigned char temp;
    unsigned char enShellCode[500]; //编码后的enShellCode
    nLen = sizeof(ShellCode)-1; //获得ShellCode的长度
    k = 0;
    for(i=0;i<nLen;++i)
    {
    temp = ShellCode[i]^KEY; //先异或KEY
        //对一些可能造成shellcode失效的字符进行替换
        if(temp<=0x1f|| temp=='.'|| temp=='/'|| temp=='0'|| temp=='?')
        {
            enShellCode[k]='0';
            ++k;
            temp+=0x31;
        }
        enShellCode[k]=temp; //保存在enShellCode中
        ++k;
    }
    //格式化打印enShellCode
    printf("\"");
    for(i=0; i<k; i++)
    {
        if(i%10 == 0 && i!=0)
        printf("\"\n\"");
        printf("\\x%x",enShellCode[i]); //将编码后的enShellCode打印出来
    }
    printf("\"\n");
    return 0;
}