· 9 years ago · Dec 26, 2016, 07:38 PM
1/*
2 Source for ida_patcher
3 Copyright (c) 2006 Chris Eagle cseagle at gmail.com
4
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 2 of the License, or (at your option)
8 any later version.
9
10 This program is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 more details.
14
15 You should have received a copy of the GNU General Public License along with
16 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 Place, Suite 330, Boston, MA 02111-1307 USA
18*/
19
20/*
21 * This program reads an Ida Pro generated .dif file and applies
22 * the differences to the original binary to create a patched binary
23 * The program will infer the name of the binary from the content of
24 * the dif file, or take the name as a command line option.
25 * CAUTION: The program transforms the input binary so if you wish
26 * to preserve the original binary make sure you make a copy and
27 * transform the copy.
28 */
29
30#include <stdio.h>
31
32int main(int argc, char **argv) {
33 char line[256];
34 FILE *patch = stdin;
35 FILE *input = NULL;
36 unsigned int offset;
37 int orig;
38 int newval;
39
40 int i;
41
42 for (i = 1; i < argc; i += 2) {
43 if (!strcmp(argv[i], "-p")) {
44 if ((i + 1) < argc) {
45 FILE *f = fopen(argv[i+1], "r");
46 if (f) {
47 patch = f;
48 }
49 else {
50 fprintf(stderr, "Failed to open patch file %s\n", argv[i+1]);
51 exit(0);
52 }
53 }
54 }
55 else if (!strcmp(argv[i], "-i")) {
56 if ((i + 1) < argc) {
57 fprintf(stderr, "Opening %s\n", argv[i+1]);
58 input = fopen(argv[i+1], "rb+");
59 if (input == NULL) {
60 fprintf(stderr, "Failed to open input file %s\n", argv[i+1]);
61 exit(0);
62 }
63 }
64 }
65 else {
66 fprintf(stderr, "usage:\n\t%s [-i <binary>] [-p <dif file>]\n", argv[0]);
67 fprintf(stderr, "\t%s [-p <dif file>]\n", argv[0]);
68 fprintf(stderr, "\t%s [-i <binary>] < <dif file>\n", argv[0]);
69 fprintf(stderr, "\t%s < <dif file>\n", argv[0]);
70 exit(0);
71 }
72 }
73
74 if (patch == stdin) {
75 fprintf(stderr, "Reading patch data from stdin.\n");
76 }
77 fgets(line, sizeof(line), patch); /* eat dif file intro line */
78 fgets(line, sizeof(line), patch); /* eat blank line */
79
80 if (input == NULL) {
81 fprintf(stderr, "Inferring input file name from patch file data.\n");
82 fscanf(patch, "%256s", line);
83 input = fopen(line, "rb+");
84 if (input == NULL) {
85 fprintf(stderr, "Failed to open input file %s\n", line);
86 exit(0);
87 }
88 }
89 else { /* don't need input file name, but need to skip it in dif file */
90 fgets(line, sizeof(line), patch);
91 }
92
93 while (fscanf(patch, "%x: %x %x", &offset, &orig, &newval) == 3) {
94 fseek(input, offset, SEEK_SET);
95 if (fgetc(input) == orig) {
96 fseek(input, offset, SEEK_SET);
97 fputc(newval, input);
98 }
99 else {
100 //original bytes don't match expected?
101 }
102 }
103 fclose(input);
104 if (patch != stdin) {
105 fclose(patch);
106 }
107}