You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:向父进程发送Signal无效,MD5解密程序开发遇阻

Hey there! Let's figure out why your signal-based approach isn't working and get your MD5 cracker up and running properly with pipes.

First off: signals are not meant for passing complex data like strings or match results. Signals only carry a single integer value, they're unreliable (can be lost if multiple are sent quickly), and they're designed for event notifications (like "process got interrupted")—not for sending actual data between processes. Pipes are the right tool here, and I'll show you how to set them up correctly.

Here's the step-by-step fix for your setup:

We'll use two pipes: one for the parent to send words to the child, and another for the child to send match results back to the parent. This keeps data flows separate and avoids blocking issues.

Example Working Code

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <openssl/md5.h>
#include <sys/wait.h>

// Replace this with your target MD5 hash
#define TARGET_MD5 "5d41402abc4b2a76b9719d911017c592" // MD5 of "hello"

// Helper function to compute MD5 hash of a string
void compute_md5(const char *str, char *result) {
    unsigned char digest[MD5_DIGEST_LENGTH];
    MD5((unsigned char*)str, strlen(str), digest);
    
    // Convert binary digest to hex string
    for(int i = 0; i < MD5_DIGEST_LENGTH; i++) {
        sprintf(result + (i*2), "%02x", digest[i]);
    }
    result[32] = '\0'; // Null-terminate the 32-character hex string
}

int main() {
    int word_pipe[2];   // Parent writes words here, child reads from it
    int result_pipe[2]; // Child writes results here, parent reads from it

    // Create both pipes before forking (so both processes inherit them)
    if(pipe(word_pipe) == -1 || pipe(result_pipe) == -1) {
        perror("Failed to create pipe");
        exit(EXIT_FAILURE);
    }

    pid_t pid = fork();
    if(pid == -1) {
        perror("Fork failed");
        exit(EXIT_FAILURE);
    }

    if(pid == 0) {
        // ---------------- CHILD PROCESS ----------------
        // Close the pipe ends we don't need
        close(word_pipe[1]);  // Child doesn't write to the word pipe
        close(result_pipe[0]); // Child doesn't read from the result pipe

        char buffer[256];
        ssize_t bytes_read;

        // Read words from the parent until the pipe is closed
        while((bytes_read = read(word_pipe[0], buffer, sizeof(buffer)-1)) > 0) {
            buffer[bytes_read] = '\0';
            // Strip newline characters (from fgets in parent)
            buffer[strcspn(buffer, "\n")] = '\0';

            char computed_md5[33];
            compute_md5(buffer, computed_md5);

            // Check if we found a match
            if(strcmp(computed_md5, TARGET_MD5) == 0) {
                // Send the matching word back to parent (include null terminator)
                write(result_pipe[1], buffer, strlen(buffer)+1);
                break; // Exit early once we find a match
            }
        }

        // Clean up child's pipe ends
        close(word_pipe[0]);
        close(result_pipe[1]);
        exit(EXIT_SUCCESS);
    } else {
        // ---------------- PARENT PROCESS ----------------
        // Close unused pipe ends
        close(word_pipe[0]);  // Parent doesn't read from the word pipe
        close(result_pipe[1]); // Parent doesn't write to the result pipe

        // Open your dictionary file
        FILE *dict_file = fopen("dictionary.txt", "r");
        if(!dict_file) {
            perror("Failed to open dictionary file");
            exit(EXIT_FAILURE);
        }

        char word[256];
        // Read each word from the file and send to child
        while(fgets(word, sizeof(word), dict_file) != NULL) {
            write(word_pipe[1], word, strlen(word));
        }

        // Close the write end of the word pipe to signal child no more data
        close(word_pipe[1]);

        // Read result from child
        char match_result[256];
        ssize_t result_bytes = read(result_pipe[0], match_result, sizeof(match_result)-1);
        if(result_bytes > 0) {
            match_result[result_bytes] = '\0';
            printf("Success! Found matching word: %s\n", match_result);
        } else {
            printf("No matching word found in the dictionary.\n");
        }

        // Wait for child process to finish cleanly
        wait(NULL);

        // Clean up parent's resources
        close(result_pipe[0]);
        fclose(dict_file);
    }

    return 0;
}

Key Things to Note:

  • Dual Pipes: Using two separate pipes prevents read/write blocking issues. Each process only uses the pipe ends it needs.
  • Proper Pipe Closure: Closing unused pipe ends is critical—if you leave a write end open, read() will block forever waiting for more data.
  • Signal Limitations: As I mentioned earlier, signals can't reliably pass strings. Even if you tried to use a signal to notify the parent "a match was found", you'd still need a pipe to send the actual word. Pipes solve both problems in one go.
  • MD5 Handling: The helper function converts the binary MD5 digest to a hex string, which matches the format of typical MD5 hashes we compare against.

Compilation Note:

You'll need to link the OpenSSL library when compiling:

gcc md5_cracker.c -o md5_cracker -lcrypto

内容的提问来源于stack exchange,提问作者Jose Lopez Rodriguez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 07:25:09