2016-07-30 100 views
-2

我一直悬而未决与C和一点密码学,无论如何我试图动态分配一个字符串输入一个纯文本和一个密钥,我用它来获取密码文本。程序工作,直到我决定释放分配的内存。然后产生一个错误,说明:HEAP CORRUPTION DETECTED:在这个和这个地址处的普通块(#73)之后;检查了所有其他帖子,没有,我很困惑,请帮助。这里的代码:堆腐败检测C

int main(int argc, char *argv[]) 
{ 
    int plainSize = 0; 
    int keySize = 0; 

    InputInteger(keySize,"key size"); 
    InputInteger(plainSize,"plaintext size"); 

    char *plaintext = (char*)malloc((plainSize + 1) * sizeof(char)); 
    char *key = (char*)malloc((keySize + 1) * sizeof(char)); 
    char *cypher = (char*)malloc((plainSize + 1) * sizeof(char)); 

    InputString(plaintext, "plaintext"); 
    InputString(key, "key"); 


    cypher=ViginereEncrypt(plaintext, key); 
    printf("\n%s encypted with Viginere key %s is %s", plaintext, key, cypher); 
    printf("\n\n"); 

    free(plaintext); 
    free(key); 
    free(cypher); 
} 

char *ViginereEncrypt(char *plaintext,char *key) 
{ 
    int i = 0; 
    char *cypherText = (char*)malloc((strlen(plaintext) + 1)*sizeof(char)); 
    printf("\n%d\n", strlen(plaintext) + 1); 
    for (i = 0;i < strlen(plaintext);i++) 
    *cypherText++ =(*plaintext++ - 'A' + *key++ - 'A' -1) % ('Z' - 'A') + 'A'; 
    cypherText[i] = '\0'; 
    return cypherText; 
} 
void InputInteger(int myInteger,char name [100]) 
{ 
    printf("Input a number for %s : ",name); 
    scanf("%d", &myInteger); 
} 
void InputString(char myString[],char name[100]) 
{ 
    printf("Input a string for %s : ",name); 
    scanf("%s", myString); 
} 

是在函数内部分配的问题?认为它不应该是因为我“复制”密码到函数返回然后释放它。提前致谢!

+0

使用[valgrind](http://valgrind.org/) –

+0

关于@Weather Wane的良好答案并指出安全问题,您的程序中的内存管理还有几个问题尚未涉及。请编译这个程序,提供更正建议,打开所有警告,并有一个良好的学习时间调试。 – user3078414

回答

1

函数调用InputInteger(keySize,"key size");不能将值设置为keySizekeySizeplainSize将保持为0。所以你为每个字符串分配了1个字节的内存,仅仅足够用于结束符。电脑融化。

,我建议这些变化,首先传回的输入值

void InputInteger(int *myInteger, char name [100])  // add the * 
{ 
    printf("Input a number for %s : ", name); 
    scanf("%d", myInteger);        // remove the & 
} 

然后改变你怎么称呼它的方式。

InputInteger(&keySize, "key size");     // add the & 
InputInteger(&plainSize, "plaintext size");   // add the & 

这样你就可以传递你希望改变的变量的地址。

编辑:这并不是说在代码中没有其他漏洞。字符串长度可能是一个负数,你应该做一些输入验证。此外,InputString函数可用于恶意攻击或意外故障,用户可以说该字符串长度为2,然后破坏堆栈,并带有一些好奇的大型输入来接管机器,因为它是perp在那里放置的可执行代码偷你的豆子。