C内存编程

href="file:///C:%5CDOCUME%7E1%5CADMINI%7E1%5CLOCALS%7E1%5CTemp%5Cmsohtml1%5C01%5Cclip_filelist.xml" rel="File-List">

假设你截获了截获了一段编码信息,这些密文是一系列的二进制代码,用16进制的形式表示如下:

 

6363636363636363724646636F6D 6F 72

466D 203A 65693A 7243646E 206F 54540A

5920453A 54756F 0A 6F 6F 470A 21643A 6F  

594E 2020206F 776F 797275744563200A

6F 786F 686E 6963736C 206765796C 656B

2C 3365737420346E 20216F 74726F 5966

7565636F 202061206C 61676374206C 6F

20206F 74747865656561727632727463

6E 617920680A 64746F 69766120646E69

21687467630020656C 6C 786178742078

6578206F 727478787863617800783174

虽然你并不知道怎样进行译码以获取其表达的信息含义,但是能否将信息内容破译决定了你的成绩。所以你会尽一切努力进行代码的破译。幸好一个007特工获取到了一部分解码的程序,并将程序放在文件secret.cpp文件中。

阅读这个源程序你可以发现这个译码程序运行时需要输入四个整数参数,如果任意输入一些整数运行,程序或者会异常中断,或者会输出一些莫名其妙的乱码。看来如果输入正确的四个参数就可以得到正确的解码信息,所以这四个整数又叫做“密钥”。虽然007特工没有拿到这四个密钥,但是他在一个桌子上发现了程序解密后的前5个原文,它们是:“From:”。

你的任务就是:

(1)       破译这段密文;

(2)       确定四个整数构成的密钥。

PS:在VC6.0编译环境下,且输入的四个参数在Projiect -> Setting -> Debug -> Program arguments: 中设置,每个key之间有一个空格即可;

 

secret.cpp 源代码:

#include <stdio.h>

#include <stdlib.h>

int data [] = {
          0x63636363, 0x63636363, 0x72464663, 0x6F6D6F72,
          0x466D203A, 0x65693A72, 0x43646E20, 0x6F54540A,
          0x5920453A, 0x54756F0A, 0x6F6F470A, 0x21643A6F,
          0x594E2020, 0x206F776F, 0x79727574, 0x4563200A,
          0x6F786F68, 0x6E696373, 0x6C206765, 0x796C656B,
          0x2C336573, 0x7420346E, 0x20216F74, 0x726F5966,
          0x7565636F, 0x20206120, 0x6C616763, 0x74206C6F,
          0x20206F74, 0x74786565, 0x65617276, 0x32727463,
          0x6E617920, 0x680A6474, 0x6F697661, 0x20646E69,
          0x21687467, 0x63002065, 0x6C6C7861, 0x78742078,
          0x6578206F, 0x72747878, 0x78636178, 0x00783174
};


char message[100];

void usage_and_exit(char * program_name) {
    fprintf(stderr, "USAGE: %s key1 key2 key3 key4/n", program_name);
    exit(1);
}

void process_keys12 (int * key1, int * key2) {
   
    *((int *) (key1 + *key1)) = *key2;
}

void process_keys34 (int * key3, int * key4) {

    *(((int *)&key3) + *key3) += *key4;
}

char * extract_message1(int start, int stride) {
    int i, j, k;
    int done = 0;

    for (i = 0, j = start + 1; ! done; j++) {
        for (k = 1; k < stride; k++, j++, i++) {

            if (*(((char *) data) + j) == '/0') {
                done = 1;
                break;
            }
                             
            message[i] = *(((char *) data) + j);
        }
    }
    message[i] = '/0';
    return message;
}


char * extract_message2(int start, int stride) {
    int i, j;

    for (i = 0, j = start;
         *(((char *) data) + j) != '/0';
         i++, j += stride)
         {
             message[i] = *(((char *) data) + j);
         }
    message[i] = '/0';
    return message;
}

int main (int argc, char *argv[])
{
    int dummy = 1;
    int start, stride;
    int key1, key2, key3, key4;
    char * msg1, * msg2;

    key3 = key4 = 0;
    if (argc < 3) {
        usage_and_exit(argv[0]);
    }
    key1 = strtol(argv[1], NULL, 0);
    key2 = strtol(argv[2], NULL, 0);
    if (argc > 3) key3 = strtol(argv[3], NULL, 0);
    if (argc > 4) key4 = strtol(argv[4], NULL, 0);

    process_keys12(&key1, &key2);

    start = (int)(*(((char *) &dummy)));
    stride = (int)(*(((char *) &dummy) + 1));

    if (key3 != 0 && key4 != 0) {
        process_keys34(&key3, &key4);
    }

    msg1 = extract_message1(start, stride);

    if (*msg1 == '/0') {
        process_keys34(&key3, &key4);
        msg2 = extract_message2(start, stride);
        printf("%s/n", msg2);
    }
    else {
        printf("%s/n", msg1);
    }

    return 0;
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值