/* rinia1.c - Don Yang (uguu.org) 01/10/04 */ #include #include #include int t_table[256], t_embed_offset[256]; int o_freq[256], o_patch_offset[9]; int p_partial[9]; int q_counter[9]; int s_filesize; int c_input, c_crc, c_mod_char, c_partial; int i; int j_offset_count, j_run_length; int k_last_char, k_max_freq, k_embed_offset; int x_patch_char, x_ripple, x_bit; int l_last_block; FILE *f_file; unsigned char *d_data; unsigned char b_rchar[9][128], b_buffer[9]; unsigned char *w; int Checksum(int crc, int start, int end); int Embed(void); void GenerateCRCTable(void); int LoadFile(char *name); int LoadLayout(char *name); int main(int argc, char **argv) { if( argc < 4 ) return printf("%s \n", *argv); if( LoadFile(argv[1]) != 0 ) return printf("Error loading file: %s\n", argv[1]); if( LoadLayout(argv[2]) != 0 ) { free(d_data); return printf("Error loading layout: %s\n", argv[2]); } GenerateCRCTable(); if( Embed() == 0 ) { if( (f_file = fopen(argv[3], "wb+")) == NULL ) { printf("Error writing %s\n", argv[3]); } else { fwrite(d_data, s_filesize, 1, f_file); fclose(f_file); puts("\nsuccess"); } } else { puts("\nfail"); } free(d_data); return 0; } int Checksum(int crc, int start, int end) { while( start < end ) { crc = ((crc >> 8) & 0xffffff) ^ t_table[(crc ^ d_data[start++]) & 0xff]; } return crc; } int Embed(void) { l_last_block = o_patch_offset[j_offset_count - 1]; if( l_last_block < k_embed_offset ) o_patch_offset[j_offset_count] = l_last_block = k_embed_offset + 8; else o_patch_offset[j_offset_count] = ++l_last_block; c_partial = time(NULL); sprintf((char*)b_buffer, "%08x", Checksum(c_partial, l_last_block, s_filesize) ^ ~0); for(i = 0; i < 8; i++) d_data[k_embed_offset + i] = *(b_buffer + i); for(i = 0; i < j_offset_count; q_counter[i++] = 0) { w = b_rchar[i] + 1; for(c_mod_char = 33; c_mod_char < 127; c_mod_char++) { if( c_mod_char == 47 || c_mod_char == 92 || c_mod_char == (int)b_rchar[i][0] ) continue; *(w++) = (unsigned char)c_mod_char; } *w = 0; } p_partial[0] = Checksum(~0, 0, o_patch_offset[0]); for(i = 0; i >= 0;) { for(x_patch_char = i; x_patch_char < j_offset_count; x_patch_char++) { d_data[o_patch_offset[x_patch_char]] = b_rchar[x_patch_char][q_counter[x_patch_char]]; p_partial[x_patch_char + 1] = Checksum(p_partial[x_patch_char], o_patch_offset[x_patch_char], o_patch_offset[x_patch_char + 1]); } if( p_partial[j_offset_count] == c_partial ) return 0; for(i = j_offset_count - 1; i >= 0; i--) { if( b_rchar[i][++q_counter[i]] != 0 ) break; for(x_ripple = i; x_ripple < j_offset_count; q_counter[x_ripple++] = 0); } if( i < j_offset_count - 4 ) { putchar('.'); fflush(stdout); } } return -1; } void GenerateCRCTable(void) { for(i = 0; i < 256; i++) { c_crc = i; for(x_bit = 8; x_bit > 0; x_bit--) { if( (c_crc & 1) != 0 ) c_crc = ((unsigned)c_crc >> 1) ^ 0xedb88320; else c_crc = (unsigned)c_crc >> 1; } t_table[i] = c_crc; } } int LoadFile(char *name) { if( (f_file = fopen(name, "rb")) == NULL ) return -1; fseek(f_file, 0, SEEK_END); if( (s_filesize = ftell(f_file)) < 9 ) { fclose(f_file); return -1; } if( (d_data = (unsigned char*)malloc(s_filesize)) == NULL ) { fclose(f_file); return -1; } fseek(f_file, 0, SEEK_SET); fread(d_data, s_filesize, 1, f_file); fclose(f_file); return 0; } int LoadLayout(char *name) { if( (f_file = fopen(name, "rb")) == NULL ) return -1; for(i = 0; i < 256; t_embed_offset[i++] = -1) o_freq[i] = 0; k_last_char = -1; for(i = j_run_length = 0; i < s_filesize; i++) { if( (c_input = fgetc(f_file)) == EOF ) break; o_freq[c_input]++; if( c_input == k_last_char ) { if( ++j_run_length >= 8 ) { if( t_embed_offset[k_last_char] == -1 ) t_embed_offset[k_last_char] = i - 7; } } else { k_last_char = c_input; j_run_length = 1; } } x_patch_char = -1; k_max_freq = s_filesize + 1; for(i = 33; i < 127; i++) { if( t_embed_offset[i] == -1 ) continue; if( k_max_freq > o_freq[i] ) { k_max_freq = o_freq[i]; x_patch_char = i; } } if( x_patch_char == -1 ) { fclose(f_file); return -1; } k_embed_offset = t_embed_offset[x_patch_char]; fseek(f_file, 0, SEEK_SET); for(i = j_offset_count = 0; i < s_filesize && j_offset_count < 8; i++) { if( (c_input = fgetc(f_file)) == EOF ) break; if( i < k_embed_offset || i > k_embed_offset + 7 ) { if( c_input == x_patch_char ) { if( (b_rchar[j_offset_count][0] = d_data[i]) == 0 ) b_rchar[j_offset_count][0] = '.'; o_patch_offset[j_offset_count++] = i; } } } fclose(f_file); return (j_offset_count > 0) ? 0 : -1; }