This source file includes following definitions.
- open_input_file
- open_output_file
- open_inout_file
- close_file_data
- get_unrounded_section_size
- find_section
- rva_to_section
- offset_to_section
- relocate_offset
- copy_executable_and_move_sections
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #define DEFER_MS_W32_H
25 #include <config.h>
26
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <fcntl.h>
30 #include <time.h>
31 #if defined(__GNUC__) && !defined(MINGW_W64)
32 #define _ANONYMOUS_UNION
33 #define _ANONYMOUS_STRUCT
34 #endif
35 #include <windows.h>
36
37
38
39
40 PIMAGE_NT_HEADERS (__stdcall * pfnCheckSumMappedFile) (LPVOID BaseAddress,
41 DWORD_PTR FileLength,
42 PDWORD_PTR HeaderSum,
43 PDWORD_PTR CheckSum);
44
45 #undef min
46 #undef max
47 #define min(x, y) (((x) < (y)) ? (x) : (y))
48 #define max(x, y) (((x) > (y)) ? (x) : (y))
49
50
51
52
53 typedef struct file_data {
54 const char *name;
55 unsigned long size;
56 HANDLE file;
57 HANDLE file_mapping;
58 unsigned char *file_base;
59 } file_data;
60
61 int
62 open_input_file (file_data *p_file, const char *filename)
63 {
64 HANDLE file;
65 HANDLE file_mapping;
66 void *file_base;
67 unsigned long size, upper_size;
68
69 file = CreateFile (filename, GENERIC_READ, FILE_SHARE_READ, NULL,
70 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
71 if (file == INVALID_HANDLE_VALUE)
72 return FALSE;
73
74 size = GetFileSize (file, &upper_size);
75 file_mapping = CreateFileMapping (file, NULL, PAGE_READONLY,
76 0, size, NULL);
77 if (!file_mapping)
78 return FALSE;
79
80 file_base = MapViewOfFile (file_mapping, FILE_MAP_READ, 0, 0, size);
81 if (file_base == 0)
82 return FALSE;
83
84 p_file->name = filename;
85 p_file->size = size;
86 p_file->file = file;
87 p_file->file_mapping = file_mapping;
88 p_file->file_base = file_base;
89
90 return TRUE;
91 }
92
93 int
94 open_output_file (file_data *p_file, const char *filename, unsigned long size)
95 {
96 HANDLE file;
97 HANDLE file_mapping;
98 void *file_base;
99
100 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
101 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
102 if (file == INVALID_HANDLE_VALUE)
103 return FALSE;
104
105 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE,
106 0, size, NULL);
107 if (!file_mapping)
108 return FALSE;
109
110 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
111 if (file_base == 0)
112 return FALSE;
113
114 p_file->name = filename;
115 p_file->size = size;
116 p_file->file = file;
117 p_file->file_mapping = file_mapping;
118 p_file->file_base = file_base;
119
120 return TRUE;
121 }
122
123 int
124 open_inout_file (file_data *p_file, const char *filename)
125 {
126 HANDLE file;
127 HANDLE file_mapping;
128 void *file_base;
129 unsigned long size, upper_size;
130
131 file = CreateFile (filename, GENERIC_READ | GENERIC_WRITE, 0, NULL,
132 OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
133 if (file == INVALID_HANDLE_VALUE)
134 return FALSE;
135
136 size = GetFileSize (file, &upper_size);
137 file_mapping = CreateFileMapping (file, NULL, PAGE_READWRITE,
138 0, size, NULL);
139 if (!file_mapping)
140 return FALSE;
141
142 file_base = MapViewOfFile (file_mapping, FILE_MAP_WRITE, 0, 0, size);
143 if (file_base == 0)
144 return FALSE;
145
146 p_file->name = filename;
147 p_file->size = size;
148 p_file->file = file;
149 p_file->file_mapping = file_mapping;
150 p_file->file_base = file_base;
151
152 return TRUE;
153 }
154
155
156 void
157 close_file_data (file_data *p_file)
158 {
159 UnmapViewOfFile (p_file->file_base);
160 CloseHandle (p_file->file_mapping);
161
162 SetFilePointer (p_file->file, p_file->size, NULL, FILE_BEGIN);
163 SetEndOfFile (p_file->file);
164 CloseHandle (p_file->file);
165 }
166
167
168
169
170 unsigned long
171 get_unrounded_section_size (PIMAGE_SECTION_HEADER p_section)
172 {
173
174
175
176 return min (p_section->SizeOfRawData,
177 p_section->Misc.VirtualSize);
178 }
179
180
181 IMAGE_SECTION_HEADER *
182 find_section (const char *name, IMAGE_NT_HEADERS *nt_header)
183 {
184 PIMAGE_SECTION_HEADER section;
185 int i;
186
187 section = IMAGE_FIRST_SECTION (nt_header);
188
189 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
190 {
191 if (strcmp (section->Name, name) == 0)
192 return section;
193 section++;
194 }
195 return NULL;
196 }
197
198
199
200 IMAGE_SECTION_HEADER *
201 rva_to_section (DWORD_PTR rva, IMAGE_NT_HEADERS * nt_header)
202 {
203 PIMAGE_SECTION_HEADER section;
204 int i;
205
206 section = IMAGE_FIRST_SECTION (nt_header);
207
208 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
209 {
210
211
212
213
214
215
216 DWORD_PTR real_size = max (section->SizeOfRawData,
217 section->Misc.VirtualSize);
218 if (rva >= section->VirtualAddress
219 && rva < section->VirtualAddress + real_size)
220 return section;
221 section++;
222 }
223 return NULL;
224 }
225
226
227
228 IMAGE_SECTION_HEADER *
229 offset_to_section (DWORD_PTR offset, IMAGE_NT_HEADERS * nt_header)
230 {
231 PIMAGE_SECTION_HEADER section;
232 int i;
233
234 section = IMAGE_FIRST_SECTION (nt_header);
235
236 for (i = 0; i < nt_header->FileHeader.NumberOfSections; i++)
237 {
238 if (offset >= section->PointerToRawData
239 && offset < section->PointerToRawData + section->SizeOfRawData)
240 return section;
241 section++;
242 }
243 return NULL;
244 }
245
246
247
248
249 static DWORD_PTR
250 relocate_offset (DWORD_PTR offset,
251 IMAGE_NT_HEADERS * src_nt_header,
252 IMAGE_NT_HEADERS * dst_nt_header)
253 {
254 PIMAGE_SECTION_HEADER src_section = IMAGE_FIRST_SECTION (src_nt_header);
255 PIMAGE_SECTION_HEADER dst_section = IMAGE_FIRST_SECTION (dst_nt_header);
256 int i = 0;
257
258 while (offset >= src_section->PointerToRawData)
259 {
260 if (offset < src_section->PointerToRawData + src_section->SizeOfRawData)
261 break;
262 i++;
263 if (i == src_nt_header->FileHeader.NumberOfSections)
264 {
265
266 dst_section = IMAGE_FIRST_SECTION (dst_nt_header);
267 dst_section += dst_nt_header->FileHeader.NumberOfSections - 1;
268 while (dst_section->PointerToRawData == 0)
269 dst_section--;
270 while (src_section->PointerToRawData == 0)
271 src_section--;
272 return offset
273 + (dst_section->PointerToRawData + dst_section->SizeOfRawData)
274 - (src_section->PointerToRawData + src_section->SizeOfRawData);
275 }
276 src_section++;
277 dst_section++;
278 }
279 return offset +
280 (dst_section->PointerToRawData - src_section->PointerToRawData);
281 }
282
283 #define OFFSET_TO_RVA(offset, section) \
284 ((section)->VirtualAddress + ((DWORD_PTR)(offset) - (section)->PointerToRawData))
285
286 #define RVA_TO_OFFSET(rva, section) \
287 ((section)->PointerToRawData + ((DWORD_PTR)(rva) - (section)->VirtualAddress))
288
289 #define RVA_TO_SECTION_OFFSET(rva, section) \
290 ((DWORD_PTR)(rva) - (section)->VirtualAddress)
291
292 #define RVA_TO_PTR(var,section,filedata) \
293 ((void *)((unsigned char *)(RVA_TO_OFFSET(var,section) + (filedata)->file_base)))
294
295
296 #define PTR_TO_RVA(ptr) ((DWORD_PTR)(ptr) - (DWORD_PTR) GetModuleHandle (NULL))
297
298 #define PTR_TO_OFFSET(ptr, pfile_data) \
299 ((unsigned const char *)(ptr) - (pfile_data)->file_base)
300
301 #define OFFSET_TO_PTR(offset, pfile_data) \
302 ((pfile_data)->file_base + (DWORD_PTR)(offset))
303
304 #define ROUND_UP(p, align) \
305 (((DWORD_PTR)(p) + (align)-1) & ~((DWORD_PTR)(align)-1))
306 #define ROUND_DOWN(p, align) ((DWORD_PTR)(p) & ~((DWORD_PTR)(align)-1))
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345 static void
346 copy_executable_and_move_sections (file_data *p_infile,
347 file_data *p_outfile)
348 {
349 unsigned char *dst;
350 PIMAGE_DOS_HEADER dos_header;
351 PIMAGE_NT_HEADERS nt_header;
352 PIMAGE_NT_HEADERS dst_nt_header;
353 PIMAGE_SECTION_HEADER section;
354 PIMAGE_SECTION_HEADER dst_section;
355 PIMAGE_SECTION_HEADER import_section;
356 PIMAGE_SECTION_HEADER reloc_section;
357 PIMAGE_DATA_DIRECTORY import_dir;
358 PIMAGE_DATA_DIRECTORY reloc_dir;
359 DWORD_PTR import_delta_rva;
360 DWORD_PTR reloc_delta_rva;
361 DWORD_PTR offset;
362 int i;
363
364 #define COPY_CHUNK(message, src, size) \
365 do { \
366 unsigned const char *s = (void *)(src); \
367 unsigned long count = (size); \
368 printf ("%s\n", (message)); \
369 printf ("\t0x%08x Offset in input file.\n", s - p_infile->file_base); \
370 printf ("\t0x%08x Offset in output file.\n", dst - p_outfile->file_base); \
371 printf ("\t0x%08x Size in bytes.\n", count); \
372 memcpy (dst, s, count); \
373 dst += count; \
374 } while (0)
375
376 #define DST_TO_OFFSET() PTR_TO_OFFSET (dst, p_outfile)
377 #define ROUND_UP_DST_AND_ZERO(align) \
378 do { \
379 unsigned char *newdst = p_outfile->file_base \
380 + ROUND_UP (DST_TO_OFFSET (), (align)); \
381 \
382 memset (dst, 0, newdst - dst); \
383 dst = newdst; \
384 } while (0)
385
386
387
388
389
390
391
392
393 dos_header = (PIMAGE_DOS_HEADER) p_infile->file_base;
394 nt_header = (PIMAGE_NT_HEADERS) (((unsigned char *) dos_header) +
395 dos_header->e_lfanew);
396 section = IMAGE_FIRST_SECTION (nt_header);
397
398 import_dir = &nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
399 import_section = rva_to_section (import_dir->VirtualAddress, nt_header);
400
401 reloc_dir = &nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
402 reloc_section = rva_to_section (reloc_dir->VirtualAddress, nt_header);
403 if (!reloc_section)
404 {
405 printf ("No relocation data, cannot prepare for profile prepping.\n");
406 exit (1);
407 }
408
409 dst = (unsigned char *) p_outfile->file_base;
410
411 COPY_CHUNK ("Copying DOS header...", dos_header,
412 (DWORD_PTR) nt_header - (DWORD_PTR) dos_header);
413 dst_nt_header = (PIMAGE_NT_HEADERS) dst;
414 COPY_CHUNK ("Copying NT header...", nt_header,
415 (DWORD_PTR) section - (DWORD_PTR) nt_header);
416 dst_section = (PIMAGE_SECTION_HEADER) dst;
417 COPY_CHUNK ("Copying section table...", section,
418 nt_header->FileHeader.NumberOfSections * sizeof (*section));
419
420
421 dst += 2 * sizeof (*section);
422
423
424
425 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
426 dst_nt_header->OptionalHeader.SizeOfHeaders = DST_TO_OFFSET ();
427
428 for (i = 0; i < nt_header->FileHeader.NumberOfSections;
429 i++, section++, dst_section++)
430 {
431 char msg[100];
432 sprintf (msg, "Copying raw data for %s...", section->Name);
433
434
435 if (section == import_section || section == reloc_section)
436 {
437 dst_section->Name[0] = 'X';
438 dst_section->Misc.VirtualSize =
439 ROUND_UP (dst_section->Misc.VirtualSize,
440 dst_nt_header->OptionalHeader.SectionAlignment);
441 dst_section->PointerToRawData = 0;
442 dst_section->SizeOfRawData = 0;
443 dst_section->Characteristics &= ~IMAGE_SCN_CNT_INITIALIZED_DATA;
444 dst_section->Characteristics |= IMAGE_SCN_CNT_UNINITIALIZED_DATA;
445 dst_section->Characteristics &= ~IMAGE_SCN_MEM_WRITE;
446 continue;
447 }
448
449
450
451
452 if (dst_section->PointerToRawData)
453 dst_section->PointerToRawData = DST_TO_OFFSET ();
454
455
456 COPY_CHUNK
457 (msg, OFFSET_TO_PTR (section->PointerToRawData, p_infile),
458 section->SizeOfRawData);
459
460
461 dst_section->SizeOfRawData =
462 ROUND_UP (dst_section->SizeOfRawData,
463 dst_nt_header->OptionalHeader.FileAlignment);
464
465
466 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
467 }
468
469
470
471 if (import_section != NULL)
472 {
473 dst_nt_header->FileHeader.NumberOfSections++;
474 dst_nt_header->OptionalHeader.SizeOfImage +=
475 ROUND_UP (import_section->Misc.VirtualSize,
476 dst_nt_header->OptionalHeader.SectionAlignment);
477 *dst_section = *import_section;
478 dst_section->VirtualAddress =
479 dst_section[-1].VirtualAddress
480 + ROUND_UP (dst_section[-1].Misc.VirtualSize,
481 dst_nt_header->OptionalHeader.SectionAlignment);
482 dst_section->PointerToRawData = DST_TO_OFFSET ();
483
484 import_delta_rva = dst_section->VirtualAddress - import_section->VirtualAddress;
485 COPY_CHUNK
486 ("Relocating import directory",
487 OFFSET_TO_PTR (import_section->PointerToRawData, p_infile),
488 import_section->SizeOfRawData);
489 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
490 dst_section++;
491 }
492 if (reloc_section != NULL)
493 {
494 dst_nt_header->FileHeader.NumberOfSections++;
495 dst_nt_header->OptionalHeader.SizeOfImage +=
496 ROUND_UP (reloc_section->Misc.VirtualSize,
497 dst_nt_header->OptionalHeader.SectionAlignment);
498 *dst_section = *reloc_section;
499 dst_section->VirtualAddress =
500 dst_section[-1].VirtualAddress
501 + ROUND_UP (dst_section[-1].Misc.VirtualSize,
502 dst_nt_header->OptionalHeader.SectionAlignment);
503 dst_section->PointerToRawData = DST_TO_OFFSET ();
504
505 reloc_delta_rva = dst_section->VirtualAddress - reloc_section->VirtualAddress;
506 COPY_CHUNK
507 ("Relocating base relocations directory",
508 OFFSET_TO_PTR (reloc_section->PointerToRawData, p_infile),
509 reloc_section->SizeOfRawData);
510 ROUND_UP_DST_AND_ZERO (dst_nt_header->OptionalHeader.FileAlignment);
511 reloc_dir = &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
512 reloc_dir->VirtualAddress += reloc_delta_rva;
513 dst_section++;
514 }
515
516
517 section--;
518 offset = ROUND_UP (section->PointerToRawData + section->SizeOfRawData,
519 nt_header->OptionalHeader.FileAlignment);
520 COPY_CHUNK
521 ("Copying remainder of executable...",
522 OFFSET_TO_PTR (offset, p_infile),
523 p_infile->size - offset);
524
525
526 p_outfile->size = DST_TO_OFFSET ();
527
528
529 printf ("Patching up raw data offsets...\n");
530
531 section = IMAGE_FIRST_SECTION (nt_header);
532 dst_section = IMAGE_FIRST_SECTION (dst_nt_header);
533
534 #define ADJUST_OFFSET(var) \
535 do { \
536 if ((var) != 0) \
537 (var) = relocate_offset ((var), nt_header, dst_nt_header); \
538 } while (0)
539
540 #define ADJUST_IMPORT_RVA(var) \
541 do { \
542 if ((var) != 0) \
543 *((DWORD_PTR *)&(var)) += import_delta_rva; \
544 } while (0)
545
546 dst_nt_header->OptionalHeader.SizeOfInitializedData = 0;
547 dst_nt_header->OptionalHeader.SizeOfUninitializedData = 0;
548 for (i = 0; i < dst_nt_header->FileHeader.NumberOfSections; i++)
549 {
550
551 if (dst_section[i].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
552 dst_nt_header->OptionalHeader.SizeOfInitializedData +=
553 ROUND_UP (dst_section[i].Misc.VirtualSize, dst_nt_header->OptionalHeader.FileAlignment);
554 else if (dst_section[i].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
555 dst_nt_header->OptionalHeader.SizeOfUninitializedData +=
556 ROUND_UP (dst_section[i].Misc.VirtualSize, dst_nt_header->OptionalHeader.FileAlignment);
557
558 ADJUST_OFFSET (dst_section[i].PointerToLinenumbers);
559 }
560
561 ADJUST_OFFSET (dst_nt_header->FileHeader.PointerToSymbolTable);
562
563
564
565
566 {
567 PIMAGE_DATA_DIRECTORY debug_dir =
568 &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG];
569 PIMAGE_DEBUG_DIRECTORY debug_entry;
570
571
572 if (rva_to_section (debug_dir->VirtualAddress, nt_header) == import_section)
573 debug_dir->VirtualAddress += import_delta_rva;
574
575 section = rva_to_section (debug_dir->VirtualAddress, dst_nt_header);
576 if (section)
577 {
578 int size;
579
580 debug_entry = RVA_TO_PTR (debug_dir->VirtualAddress, section, p_outfile);
581 size = debug_dir->Size / sizeof (IMAGE_DEBUG_DIRECTORY);
582
583 for (i = 0; i < size; i++, debug_entry++)
584 {
585
586
587
588 ADJUST_OFFSET (debug_entry->PointerToRawData);
589 ADJUST_IMPORT_RVA (debug_entry->AddressOfRawData);
590 }
591 }
592 }
593
594
595 {
596 PIMAGE_IMPORT_DESCRIPTOR imports;
597 PIMAGE_THUNK_DATA import_thunks;
598
599 import_dir = &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
600 import_dir->VirtualAddress += import_delta_rva;
601
602 section = rva_to_section (import_dir->VirtualAddress, dst_nt_header);
603 imports = RVA_TO_PTR (import_dir->VirtualAddress, section, p_outfile);
604
605 for ( ; imports->Name != 0; imports++)
606 {
607 ADJUST_IMPORT_RVA (imports->OriginalFirstThunk);
608 ADJUST_IMPORT_RVA (imports->FirstThunk);
609 ADJUST_IMPORT_RVA (imports->Name);
610
611 for (import_thunks = RVA_TO_PTR (imports->OriginalFirstThunk, section, p_outfile);
612 import_thunks->u1.Function != 0;
613 import_thunks++)
614 if ((import_thunks->u1.Ordinal >> 31) == 0)
615 ADJUST_IMPORT_RVA (import_thunks->u1.Ordinal);
616
617 for (import_thunks = RVA_TO_PTR (imports->FirstThunk, section, p_outfile);
618 import_thunks->u1.Function != 0;
619 import_thunks++)
620 if ((import_thunks->u1.Ordinal >> 31) == 0)
621 ADJUST_IMPORT_RVA (import_thunks->u1.Ordinal);
622 }
623
624 import_dir = &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT];
625 import_dir->VirtualAddress += import_delta_rva;
626 }
627
628
629 printf ("Applying fixups to import references...\n");
630
631 {
632 IMAGE_BASE_RELOCATION *relocs, *block, *start_block, *end_block;
633 DWORD_PTR import_start = import_section->VirtualAddress + dst_nt_header->OptionalHeader.ImageBase;
634 DWORD_PTR import_end = import_start + import_section->Misc.VirtualSize;
635 DWORD_PTR len_import_relocs;
636 DWORD_PTR len_remaining_relocs;
637 int seen_high = 0;
638 WORD * high_word;
639 void * holder;
640
641 reloc_dir = &dst_nt_header->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
642 reloc_section = rva_to_section (reloc_dir->VirtualAddress, dst_nt_header);
643 relocs = RVA_TO_PTR (reloc_dir->VirtualAddress, reloc_section, p_outfile);
644
645
646
647
648 for (block = relocs, start_block = 0;
649 (DWORD_PTR) block - (DWORD_PTR) relocs < reloc_dir->Size;
650 block = (void *)((DWORD_PTR) block + block->SizeOfBlock))
651 {
652 if (block->VirtualAddress >= import_section->VirtualAddress + import_section->Misc.VirtualSize)
653 {
654 end_block = block;
655 break;
656 }
657 if (block->VirtualAddress >= import_section->VirtualAddress)
658 {
659 if (start_block == 0)
660 start_block = block;
661 block->VirtualAddress += import_delta_rva;
662 }
663 }
664 if (start_block)
665 {
666 len_import_relocs = (DWORD_PTR) end_block - (DWORD_PTR) start_block;
667 len_remaining_relocs = (DWORD_PTR) relocs + reloc_dir->Size - (DWORD_PTR) end_block;
668 holder = malloc (len_import_relocs);
669 if (holder == 0)
670 abort ();
671 memcpy (holder, start_block, len_import_relocs);
672 memcpy (start_block, end_block, len_remaining_relocs);
673 memcpy ((char *) start_block + len_remaining_relocs, holder, len_import_relocs);
674 free (holder);
675 }
676
677
678
679
680 for (block = relocs;
681 (DWORD_PTR) block - (DWORD_PTR) relocs < reloc_dir->Size;
682 block = (void *)((DWORD_PTR) block + block->SizeOfBlock))
683 {
684 DWORD_PTR page_rva = block->VirtualAddress;
685 DWORD_PTR page_offset;
686 union {
687 WORD word;
688 DWORD_PTR dword;
689 } * ploc;
690 WORD *fixup;
691
692 section = rva_to_section (page_rva, dst_nt_header);
693
694 if (section->Name[0] == 'X')
695 continue;
696
697 for (fixup = (WORD *) &block[1];
698 (DWORD_PTR) fixup - (DWORD_PTR) block < block->SizeOfBlock;
699 fixup++)
700 {
701 page_offset = (*fixup) & 0xfff;
702 ploc = RVA_TO_PTR (page_rva + page_offset, section, p_outfile);
703
704
705
706 if (seen_high && ((*fixup) >> 12) != IMAGE_REL_BASED_LOW)
707 abort ();
708
709 switch ((*fixup) >> 12)
710 {
711 case IMAGE_REL_BASED_ABSOLUTE:
712 break;
713 case IMAGE_REL_BASED_HIGH:
714
715
716
717
718
719
720 seen_high = 1;
721 high_word = &ploc->word;
722 break;
723 case IMAGE_REL_BASED_LOW:
724 offset = (*high_word << 16) + ploc->word;
725 if (offset >= import_start && offset < import_end)
726 {
727 (*high_word) += import_delta_rva >> 16;
728 ploc->dword += import_delta_rva & 0xffff;
729 }
730 seen_high = 0;
731 break;
732 case IMAGE_REL_BASED_HIGHLOW:
733
734
735
736 if (ploc->dword >= import_start && ploc->dword < import_end)
737 ploc->dword += import_delta_rva;
738 break;
739 case IMAGE_REL_BASED_HIGHADJ:
740
741
742 if (ploc->dword >= import_start && ploc->dword < import_end)
743 ploc->dword += import_delta_rva;
744 break;
745 case IMAGE_REL_BASED_MIPS_JMPADDR:
746
747
748 abort ();
749 break;
750 #ifdef IMAGE_REL_BASED_SECTION
751 case IMAGE_REL_BASED_SECTION:
752 case IMAGE_REL_BASED_REL32:
753
754 #endif
755 default:
756 abort ();
757 }
758 }
759 }
760 }
761 }
762
763
764 int
765 main (int argc, char **argv)
766 {
767 PIMAGE_DOS_HEADER dos_header;
768 PIMAGE_NT_HEADERS nt_header;
769 file_data in_file, out_file;
770 char out_filename[MAX_PATH], in_filename[MAX_PATH];
771
772 strcpy (in_filename, argv[1]);
773 strcpy (out_filename, argv[2]);
774
775 printf ("Preparing %s for profile prepping\n", out_filename);
776
777
778 if (!open_input_file (&in_file, in_filename))
779 {
780 printf ("Failed to open %s (%d)...bailing.\n",
781 in_filename, GetLastError ());
782 exit (1);
783 }
784
785
786
787
788 if (!open_output_file (&out_file, out_filename, in_file.size))
789 {
790 printf ("Failed to open %s (%d)...bailing.\n",
791 out_filename, GetLastError ());
792 exit (1);
793 }
794
795 copy_executable_and_move_sections (&in_file, &out_file);
796
797
798 {
799 HANDLE hImagehelp = LoadLibrary ("imagehlp.dll");
800 DWORD_PTR headersum;
801 DWORD_PTR checksum;
802
803 dos_header = (PIMAGE_DOS_HEADER) out_file.file_base;
804 nt_header = (PIMAGE_NT_HEADERS) ((char *) dos_header + dos_header->e_lfanew);
805
806 nt_header->OptionalHeader.CheckSum = 0;
807
808
809
810
811 pfnCheckSumMappedFile = (void *) GetProcAddress (hImagehelp, "CheckSumMappedFile");
812 if (pfnCheckSumMappedFile)
813 {
814
815 pfnCheckSumMappedFile (out_file.file_base,
816 out_file.size,
817 &headersum,
818 &checksum);
819 nt_header->OptionalHeader.CheckSum = checksum;
820 }
821 FreeLibrary (hImagehelp);
822 }
823
824 close_file_data (&out_file);
825 close_file_data (&in_file);
826
827 return 0;
828 }
829
830