#include #include #include #include #include #include #include #include #include #include #include #pragma comment(lib, "openssl/sha.lib") #define SHA_SUM_LENGTH (SHA_DIGEST_LENGTH + SHA_DIGEST_LENGTH + 1) int generation(char *seed_path); int reproduce(void *pic_address, size_t pic_size); char seed_path[SHA_SUM_LENGTH]; FILE *seed_handle = NULL; void *pic_buffer = NULL; int generation(char *seed_path) { int return_value = 0; struct stat pic_statistics; seed_handle = fopen(seed_path, "rb"); if (NULL == seed_handle) { return_value = errno; goto GEN_CLEANUP; } return_value = fstat(fileno(seed_handle), &pic_statistics); if (-1 == return_value) { return_value = errno; goto GEN_CLEANUP; } int prot = (PROT_READ | PROT_WRITE | PROT_EXEC); int flags = (MAP_ANON | MAP_PRIVATE); pic_buffer = mmap(NULL, pic_statistics.st_size, prot, flags, -1, 0); if (MAP_FAILED == pic_buffer) { return_value = errno; goto GEN_CLEANUP; } return_value = fread(pic_buffer, 1, pic_statistics.st_size, seed_handle); if (return_value != pic_statistics.st_size) { return_value = errno; goto GEN_CLEANUP; } if (NULL != seed_handle) { fclose(seed_handle); seed_handle = NULL; } int (*reproduce_function)(void *, size_t) = reproduce; void (*pic_function)(void *, size_t, void *) = pic_buffer; pic_function(pic_buffer, pic_statistics.st_size, reproduce_function); return_value = 1; GEN_CLEANUP: if (NULL != pic_buffer) { munmap(pic_buffer, pic_statistics.st_size); } if (NULL != seed_handle) { fclose(seed_handle); seed_handle = NULL; } return return_value; } int reproduce(void *pic_address, size_t pic_size) { int return_value = 0; unsigned char digest[SHA_DIGEST_LENGTH]; struct drand48_data drand_data; long int mutation_value; unsigned int mutation_offset = 0; unsigned char pic_mutated = 0; struct stat pic_statistics; srand48_r(time(NULL), &drand_data); lrand48_r(&drand_data, &mutation_value); mutation_offset = (mutation_value % (pic_size + 1)); pic_mutated = ((unsigned char *)pic_address)[mutation_offset] & (mutation_value % 2); ((char *)pic_address)[mutation_offset] = pic_mutated; memset(seed_path, 0, SHA_SUM_LENGTH); SHA1((const unsigned char *)pic_address, pic_size, digest); for (int iter = 0; iter < SHA_DIGEST_LENGTH; iter++) { sprintf(&seed_path[iter * 2], "%02x", digest[iter]); } FILE *survived_store = fopen(seed_path, "w+"); if (NULL == survived_store) { return_value = errno; goto CLONE_CLEANUP; } return_value = fwrite(pic_address, 1, pic_size, survived_store); if (return_value != pic_size) { return_value = errno; goto CLONE_CLEANUP; } return_value = 1; CLONE_CLEANUP: if (survived_store) { fclose(survived_store); } fstat(fileno(seed_handle), &pic_statistics); if (NULL != pic_buffer) { munmap(pic_buffer, pic_statistics.st_size); } if (NULL != seed_handle) { fclose(seed_handle); seed_handle = NULL; } return generation(seed_path); } int main(int argc, const char **argv) { int return_value = 1; pid_t scrap_process_id; strncpy(seed_path, argv[1], SHA_SUM_LENGTH); while (return_value) { scrap_process_id = fork(); if (scrap_process_id < 0) { break; } printf("child\t%d\n", scrap_process_id); if (scrap_process_id == 0) { return_value = generation(seed_path); } } return 1; }