1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
|
#include "reloc.h"
RelocMatch *reloc_match(char *haystack, const char *needle) {
char *data = haystack;
size_t needle_size = strlen(needle);
RelocMatch *match = NULL;
// Search the needle in the data
if (!(memcmp(data, needle, needle_size))) {
if (!(match = calloc(1, sizeof(RelocMatch)))) {
fprintf(stderr,"Failed to allocate RelocMatch structure: %s\n", strerror(errno));
exit(1);
}
size_t data_end = strlen(data);
match->begin = data;
match->end = match->begin + needle_size;
match->length = match->end - match->begin;
match->post = match->end;
match->post_length = strlen(match->post);
match->total_length = data_end;
}
return match;
}
RelocData *reloc_read(const char *filename) {
char *data = NULL;
FILE *fp = NULL;
size_t size = 0;
RelocData *result;
// Open file for reading in binary mode
if (!(fp = fopen(filename, "rb"))) {
fprintf(stderr, "Cannot open %s: %s\n", filename, strerror(errno));
exit(1);
}
// Determine file size
fseek(fp, 0, SEEK_END);
size = ftell(fp);
rewind(fp);
if (!(data = calloc(sizeof(char), size + 1))) {
fprintf(stderr, "Failed to allocate data array: %s\n", strerror(errno));
exit(1);
}
// Read data into array
fread(data, sizeof(char), size, fp);
if (!(result = (RelocData *)malloc(sizeof(RelocData)))) {
fprintf(stderr, "Failed to allocate RelocData structure: %s\n", strerror(errno));
exit(1);
}
result->size = size;
result->data = data;
result->path = strdup(filename);
return result;
}
size_t reloc_write(RelocData *finfo, const char *filename) {
FILE *fp;
// Open file for writing in binary mode
if (!(fp = fopen(filename, "w+b"))) {
fprintf(stderr,"Cannot open %s for writing: %s\n", filename, strerror(errno));
exit(1);
}
// Write data
return fwrite(finfo->data, sizeof(char), finfo->size, fp);
}
void reloc_deinit_data(RelocData *finfo) {
if (finfo) {
if (finfo->path) {
free(finfo->path);
}
free(finfo);
}
}
void reloc_replace(RelocMatch *match, const char *rstr) {
size_t rstr_length = strlen(rstr);
if (rstr_length > match->length) {
fprintf(stderr, "Replacement string is too long ("SIZE_T_FMT " > " SIZE_T_FMT ")\n", rstr_length, match->length);
return;
}
char *data = match->begin;
size_t i = 0;
// Overwrite data with replacement string
while (i < rstr_length) {
*data = *rstr;
data++;
rstr++;
i++;
}
i = 0;
// Append remaining bytes not part of the original match to the replaced string
char *post = match->post;
while (i < match->post_length) {
*data = *post;
data++;
post++;
i++;
}
// Destroy bytes between the end of the original data and the end of the replaced string
memset(data, '\0', post - data);
}
int main(int argc, char *argv[]) {
const char *program = strrchr(argv[0], DIRSEP) + 1;
if (argc < 5) {
printf("%s <str1> <str2> <input_file> <output_file>\n"
"\n"
"Arguments:\n"
"str1 - Pattern to search for\n"
"str2 - Replace str1 with contents of str2\n"
"input_file - Path to input file\n"
"output_file - Path to output file\n"
"\n"
"Example:\n"
"%s /original/path /new/path input.bin output.bin\n"
"\n", program, program);
exit(1);
}
char *needle = argv[1];
char *replacement = argv[2];
char *input_file = strdup(argv[3]);
char *output_file = strdup(argv[4]);
RelocData *info = reloc_read(input_file);
size_t records = 0;
for (size_t i = 0; i < info->size; i++) {
RelocMatch *match = NULL;
if (!(match = reloc_match(&info->data[i], needle))) {
// No match found
continue;
}
// Replace string
reloc_replace(match, replacement);
free(match);
records++;
}
reloc_write(info, output_file);
printf(SIZE_T_FMT"\n", records);
reloc_deinit_data(info);
return 0;
}
|