-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbflag.c
158 lines (120 loc) · 3 KB
/
bflag.c
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
/* bgrep - A binary grep tool. */
#include "blib.h"
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x20
int flip_pe_la_flag(char* name) {
map_file(name, WRITE_FILE);
if( CH_BUF(0) != 'M' || CH_BUF(1) != 'Z' )
goto invalid_ret; // MZ header missing.
uint32_t pe_loc = U32_BUF(0x3C);
if ( U32_BUF(pe_loc) != 0x4550 )
goto invalid_ret; // No PE header here.
pe_loc += 0x12;
U16_BUF(pe_loc) ^= IMAGE_FILE_LARGE_ADDRESS_AWARE; // Toggle it.
// Succeeded
unmap_file();
return 0;
invalid_ret:
unmap_file();
return 1;
}
int check_pe_la_flag(char* name) {
map_file(name, READ_FILE);
if( CH_BUF(0) != 'M' || CH_BUF(1) != 'Z' )
goto invalid_ret; // MZ header missing.
uint32_t pe_loc = U32_BUF(0x3C);
if ( U32_BUF(pe_loc) != 0x4550 )
goto invalid_ret; // No PE header here.
pe_loc += 0x12;
if( !(U16_BUF(pe_loc) & IMAGE_FILE_LARGE_ADDRESS_AWARE) )
goto no_ret; // Not LA aware, is PE
// LA aware PE image.
unmap_file();
return 0;
no_ret:
unmap_file();
return 1;
invalid_ret:
unmap_file();
return 2;
}
int check_pe(char* name) {
map_file(name, READ_FILE);
if( CH_BUF(0) != 'M' || CH_BUF(1) != 'Z' )
goto invalid_ret; // MZ header missing.
uint32_t pe_loc = U32_BUF(0x3C);
if ( U32_BUF(pe_loc) != 0x4550 )
goto invalid_ret; // No PE header here.
unmap_file();
return 0; // Is PE
invalid_ret:
unmap_file();
return 1; // Not PE
}
void help(char* name) {
printf("%s bflag\n", PACKAGE_STRING);
printf("(C) 2015 Jon Feldman (@chaoskagami) <%s>\n", PACKAGE_BUGREPORT);
printf("Usage:\n");
printf(" %s [args] file ...\n", name);
printf("Options (PE Images):\n");
printf(" -v Show information on file\n");
printf(" -L Flip the large address aware bit\n");
printf("Report bugs to <%s>\n", PACKAGE_URL);
printf("This software is licensed under the MIT license.\n");
}
int main(int argc, char** argv) {
int opt;
int do_op = 0;
while ( (opt = getopt(argc, argv, "hvL")) != -1) {
switch(opt) {
case 'h':
help(argv[0]);
return 0;
break;
case 'v':
do_op = 1; // View
break;
case 'L':
do_op = 2; // Flip LA flag
break;
case '?':
fprintf(stderr, "error: unknown option. Run with -h for more info\n");
return 1;
default:
fprintf(stderr, "error: unknown option. Run with -h for more info\n");
return 1;
}
}
if (optind == argc) {
fprintf(stderr, "error: requires a file argument. Run with -h for more info\n");
return 1;
}
int ret = 0;
switch(do_op) {
case 0:
fprintf(stderr, "error: no operation specified\n");
return 1;
case 1: // View flags
printf("Is PE Image: ");
ret = check_pe(argv[optind]);
if (ret == 0) {
printf("Yes\n");
printf("Large Address Aware: ");
ret = check_pe_la_flag(argv[optind]);
if (ret == 0) {
printf("Yes\n");
} else {
printf("No\n");
}
} else {
printf("No\n");
}
break;
case 2:
ret = flip_pe_la_flag(argv[optind]);
if (ret == 0)
printf("Flipped the LA bit.\n");
else
printf("Failed to flip LA bit.\n");
break;
}
}