Проблема с ошибкой доступа к памяти в C с символом * - PullRequest
1 голос
/ 26 июня 2019

Я могу без проблем запустить программу переменного тока в своей системе Linux Mint в другой системе Linux. Я получаю сообщение об ошибке доступа к памяти.

void digest_message(const unsigned char *message, size_t message_len, unsigned char **digest, unsigned int *digest_len)
{
    EVP_MD_CTX *mdctx;

    if((mdctx = EVP_MD_CTX_create()) == NULL)
        handleErrors();
    if(1 != EVP_DigestInit_ex(mdctx, EVP_sha1(), NULL))
        handleErrors();
    if(1 != EVP_DigestUpdate(mdctx, message, message_len))
        handleErrors();
    if((*digest = (unsigned char *)OPENSSL_malloc(EVP_MD_size(EVP_sha1()))) == NULL)
        handleErrors();
    if(1 != EVP_DigestFinal_ex(mdctx, *digest, digest_len))
        handleErrors();

    EVP_MD_CTX_destroy(mdctx);
}

void main ()

{
...
    const unsigned char *message= (const unsigned char*) decryptedtext;
    size_t mlen=x;
    unsigned char *digest;
    unsigned int dlen;
    digest_message(message,mlen,&digest,&dlen);

    // if i printf in a for loop i get this memmory access error 
    for(int i=0;i<dlen;i++)
        printf("%x ",digest[i]);
    }

Я пробовал:

printf("%x ",digest[0]);
printf("%x ",digest[1]);
printf("%x ",digest[2]);
...

и не получил ошибку

Почему это происходит?Как я могу это изменить?

Заранее спасибо

Ответы [ 2 ]

0 голосов
/ 26 июня 2019

У вас неопределенное поведение при использовании printf("%x ", digest[i]).

Как упоминалось в , этот ответ с использованием неверного спецификатора формата приводит к неопределенному поведению. Вероятно, поэтому поведение вашей программы зависит от ОС, на которой вы работаете (это может также зависеть от вашего оборудования и компилятора).

Поскольку у меня нет сообщения об ошибке, трудно понять, что происходит в вашем случае, но поскольку спецификатор формата "% x" обычно работает с unsigned int, он должен прочитать 4 байта в памяти. Поскольку disgest[i] является unsigned char, оно записано только в 1 байт, и, вероятно, именно поэтому вы получаете ошибку доступа к памяти.

Преобразование вашей unsigned char переменной digest[i] в unsigned int перед использованием printf должно решить вашу проблему.

Также эта тема должна помочь вам в печати шестнадцатеричных символов

0 голосов
/ 26 июня 2019

Я могу определить следующие (потенциальные) проблемы.


Я могу без проблем запускать программу на моем Linux Mint

Я думаю, что этопросто счастливое совпадение, что вы не видите проблем.


const unsigned char *message= (const unsigned char*) decryptedtext;

Если decryptedtext является просто указателем, то дальнейший доступ к нему с помощью message вполнеплохая идеяОбычно для доступа к ней должна быть выделена память.


size_t mlen=x;

В идеале mlen должно быть связано с длиной message.Если mlen больше реальной длины message, у вас возникли проблемы (переполнение буфера, повреждение памяти ...).


unsigned int dlen;

Как убедиться, что dlen не больше количества записей, доступных в digest?


printf("%x ",digest[i]);

Почему вы хотите printf строку (digest) в виде шестнадцатеричного числа?

---------------------

if(decryptedtext[0]==0x25 &&   //%
    decryptedtext[1]==0x50 &&  //P
    decryptedtext[2]==0x44 &&  //D
    decryptedtext[3]==0x46)    //F
{ printf("%s",decryptedtext);
  break;
}

Это безобразно.decryptedtext не является строкой с нулевым символом в конце, поэтому printf() не будет печатать только 4 символа.


int x;
f = fopen("test.pdf", "w+b");
if(f == NULL) {
printf("Datei konnte nicht geoeffnet werden.\n");
}else {

while(x<decryptedtext_len)  {
    putc(decryptedtext[x],f);
    x++;
}

x не инициализируется перед использованием.


unsigned char hasharrayone[20];
unsigned char hasharraytwo[20];
unsigned char hasharraythree[20];

Вы могли бы использовать:

unsigned char hasharray[3][20];

int xc;
file = fopen("sxxxxx-dest-cipher.bin", "w+b");
if(file == NULL) {
printf("Datei konnte nicht geoeffnet werden.\n");
}else {
while(xc<cpl)  {
    putc(cfbciphertext[xc],file);
    xc++;
}

xc не инициализировано.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...