Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: syzygy/pe/pe_file_writer.cc

Issue 2535563002: Added all code for integrity check transform (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « syzygy/pe/pe_file_writer.h ('k') | syzygy/pe/pe_relinker.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 Google Inc. All Rights Reserved. 1 // Copyright 2012 Google Inc. All Rights Reserved.
2 // 2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License. 4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at 5 // You may obtain a copy of the License at
6 // 6 //
7 // http://www.apache.org/licenses/LICENSE-2.0 7 // http://www.apache.org/licenses/LICENSE-2.0
8 // 8 //
9 // Unless required by applicable law or agreed to in writing, software 9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, 10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and 12 // See the License for the specific language governing permissions and
13 // limitations under the License. 13 // limitations under the License.
14 14
15 #include "syzygy/pe/pe_file_writer.h" 15 #include "syzygy/pe/pe_file_writer.h"
16 16
17 #include <windows.h> 17 #include <windows.h>
18 #include <winnt.h> 18 #include <winnt.h>
19 #include <imagehlp.h> // NOLINT 19 #include <imagehlp.h> // NOLINT
20 20
21 #include "base/logging.h" 21 #include "base/logging.h"
22 #include "base/files/file_util.h" 22 #include "base/files/file_util.h"
23 #include "base/win/scoped_handle.h" 23 #include "base/win/scoped_handle.h"
24 #include "syzygy/common/buffer_parser.h"
25 #include "syzygy/common/com_utils.h" 24 #include "syzygy/common/com_utils.h"
26 #include "syzygy/pe/pe_utils.h" 25 #include "syzygy/pe/pe_utils.h"
27 26
28 namespace pe { 27 namespace pe {
29 28
30 using block_graph::BlockGraph; 29 using block_graph::BlockGraph;
31 using common::BinaryBufferParser; 30 using common::BinaryBufferParser;
32 using core::AbsoluteAddress; 31 using core::AbsoluteAddress;
33 using core::FileOffsetAddress; 32 using core::FileOffsetAddress;
34 using core::RelativeAddress; 33 using core::RelativeAddress;
35 using pe::ImageLayout; 34 using pe::ImageLayout;
36 35
37 namespace { 36 namespace {
38 37
39 template <class Type>
40 bool UpdateReference(size_t start, Type new_value, std::vector<uint8_t>* data) {
41 BinaryBufferParser parser(&data->at(0), data->size());
42
43 Type* ref_ptr = NULL;
44 if (!parser.GetAtIgnoreAlignment(start,
45 const_cast<const Type**>(&ref_ptr))) {
46 LOG(ERROR) << "Reference data not in block";
47 return false;
48 }
49 *ref_ptr = new_value;
50
51 return true;
52 }
53
54 // Returns the type of padding byte to use for a given section. Int3s will be 38 // Returns the type of padding byte to use for a given section. Int3s will be
55 // used for executable sections, nulls for everything else. 39 // used for executable sections, nulls for everything else.
56 uint8_t GetSectionPaddingByte(const ImageLayout& image_layout, 40 uint8_t GetSectionPaddingByte(const ImageLayout& image_layout,
57 size_t section_index) { 41 size_t section_index) {
58 const uint8_t kZero = 0; 42 const uint8_t kZero = 0;
59 const uint8_t kInt3 = 0xCC; 43 const uint8_t kInt3 = 0xCC;
60 44
61 if (section_index == BlockGraph::kInvalidSectionId) 45 if (section_index == BlockGraph::kInvalidSectionId)
62 return kZero; 46 return kZero;
63 DCHECK_GT(image_layout.sections.size(), section_index); 47 DCHECK_GT(image_layout.sections.size(), section_index);
(...skipping 254 matching lines...) Expand 10 before | Expand all | Expand 10 after
318 return false; 302 return false;
319 } 303 }
320 304
321 previous_section_end = section_start + section_size; 305 previous_section_end = section_start + section_size;
322 previous_section_file_end = section_file_start + section_file_size; 306 previous_section_file_end = section_file_start + section_file_size;
323 } 307 }
324 308
325 return true; 309 return true;
326 } 310 }
327 311
312 AbsoluteAddress* PEFileWriter::GetImageBase() {
313 DCHECK(nt_headers_ != nullptr);
314 AbsoluteAddress *addr =
315 new AbsoluteAddress(nt_headers_->OptionalHeader.ImageBase);
316 return addr;
317 }
318
319 const size_t PEFileWriter::GetImageSize() {
320 uint32_t last_section_addr = image_layout_.sections.back().addr.value();
321 size_t last_section_size = image_layout_.sections.back().size;
322 return last_section_addr + last_section_size;
323 }
324
328 bool PEFileWriter::WriteBlocks(FILE* file) { 325 bool PEFileWriter::WriteBlocks(FILE* file) {
329 DCHECK(file != NULL); 326 DCHECK(file != NULL);
330 327
331 AbsoluteAddress image_base(nt_headers_->OptionalHeader.ImageBase); 328 AbsoluteAddress image_base(nt_headers_->OptionalHeader.ImageBase);
332 329
333 // Create the output buffer, reserving enough room for the whole file. 330 // Create the output buffer, reserving enough room for the whole file.
334 DCHECK(!image_layout_.sections.empty()); 331 DCHECK(!image_layout_.sections.empty());
335 size_t last_section_index = image_layout_.sections.size() - 1; 332 size_t last_section_index = image_layout_.sections.size() - 1;
336 size_t image_size = section_file_range_map_[last_section_index].end().value(); 333 size_t image_size = section_file_range_map_[last_section_index].end().value();
337 std::vector<uint8_t> buffer; 334 std::vector<uint8_t> buffer;
(...skipping 16 matching lines...) Expand all
354 BlockGraph::Block* block = const_cast<BlockGraph::Block*>(block_it->second); 351 BlockGraph::Block* block = const_cast<BlockGraph::Block*>(block_it->second);
355 352
356 // If we're jumping to a new section output the necessary padding. 353 // If we're jumping to a new section output the necessary padding.
357 if (block->section() != section_id) { 354 if (block->section() != section_id) {
358 FlushSection(section_index, &buffer); 355 FlushSection(section_index, &buffer);
359 section_id = block->section(); 356 section_id = block->section();
360 section_index++; 357 section_index++;
361 DCHECK_GT(image_layout_.sections.size(), section_index); 358 DCHECK_GT(image_layout_.sections.size(), section_index);
362 } 359 }
363 360
364 if (!WriteOneBlock(image_base, section_index, block, &buffer)) { 361 if (!WriteOneBlock(image_base, section_index, block, &buffer, nullptr)) {
365 LOG(ERROR) << "Failed to write block \"" << block->name() << "\"."; 362 LOG(ERROR) << "Failed to write block \"" << block->name() << "\".";
366 return false; 363 return false;
367 } 364 }
368 } 365 }
369 366
370 FlushSection(last_section_index, &buffer); 367 FlushSection(last_section_index, &buffer);
371 DCHECK_EQ(image_size, buffer.size()); 368 DCHECK_EQ(image_size, buffer.size());
372 369
373 // Write the whole image to disk in one go. 370 // Write the whole image to disk in one go.
374 if (::fwrite(&buffer[0], sizeof(buffer[0]), buffer.size(), file) != 371 if (::fwrite(&buffer[0], sizeof(buffer[0]), buffer.size(), file) !=
(...skipping 20 matching lines...) Expand all
395 392
396 uint8_t padding_byte = GetSectionPaddingByte(image_layout_, section_index); 393 uint8_t padding_byte = GetSectionPaddingByte(image_layout_, section_index);
397 buffer->resize(section_file_end, padding_byte); 394 buffer->resize(section_file_end, padding_byte);
398 395
399 return; 396 return;
400 } 397 }
401 398
402 bool PEFileWriter::WriteOneBlock(AbsoluteAddress image_base, 399 bool PEFileWriter::WriteOneBlock(AbsoluteAddress image_base,
403 size_t section_index, 400 size_t section_index,
404 const BlockGraph::Block* block, 401 const BlockGraph::Block* block,
405 std::vector<uint8_t>* buffer) { 402 std::vector<uint8_t>* buffer,
403 FileOffsetAddress* offset_block) {
406 // This function walks through the data referred by the input block, and 404 // This function walks through the data referred by the input block, and
407 // patches it to reflect the addresses and offsets of the blocks 405 // patches it to reflect the addresses and offsets of the blocks
408 // referenced before writing the block's data to the file. 406 // referenced before writing the block's data to the file.
409 DCHECK(block != NULL); 407 DCHECK(block != NULL);
410 DCHECK(buffer != NULL); 408 DCHECK(buffer != NULL);
411 409
412 RelativeAddress addr; 410 RelativeAddress addr;
413 if (!image_layout_.blocks.GetAddressOf(block, &addr)) { 411 if (!image_layout_.blocks.GetAddressOf(block, &addr)) {
414 LOG(ERROR) << "All blocks must have an address."; 412 LOG(ERROR) << "All blocks must have an address.";
415 return false; 413 return false;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
463 // and the explicit block data). 461 // and the explicit block data).
464 if (file_offs + inited_data_size > section_file_range.end()) { 462 if (file_offs + inited_data_size > section_file_range.end()) {
465 LOG(ERROR) << "Initialized portion of block data lies outside of section."; 463 LOG(ERROR) << "Initialized portion of block data lies outside of section.";
466 return false; 464 return false;
467 } 465 }
468 466
469 // Add any necessary padding to get us to the block offset. 467 // Add any necessary padding to get us to the block offset.
470 if (buffer->size() < file_offs.value()) 468 if (buffer->size() < file_offs.value())
471 buffer->resize(file_offs.value(), padding_byte); 469 buffer->resize(file_offs.value(), padding_byte);
472 470
471 if (offset_block != nullptr)
472 offset_block->set_value(buffer->size());
473
473 // Copy the block data into the buffer. 474 // Copy the block data into the buffer.
474 buffer->insert(buffer->end(), 475 buffer->insert(buffer->end(),
475 block->data(), 476 block->data(),
476 block->data() + block->data_size()); 477 block->data() + block->data_size());
477 478
478 // We now want to append zeros for the implicit portion of the block data. 479 // We now want to append zeros for the implicit portion of the block data.
479 size_t trailing_zeros = block->size() - block->data_size(); 480 size_t trailing_zeros = block->size() - block->data_size();
480 if (trailing_zeros > 0) { 481 if (trailing_zeros > 0) {
481 // It is possible for a block to be laid out at the end of a section such 482 // It is possible for a block to be laid out at the end of a section such
482 // that part of its data lies within the virtual portion of the section. 483 // that part of its data lies within the virtual portion of the section.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
581 default: 582 default:
582 LOG(ERROR) << "Unsupported reference size."; 583 LOG(ERROR) << "Unsupported reference size.";
583 return false; 584 return false;
584 } 585 }
585 } 586 }
586 587
587 return true; 588 return true;
588 } 589 }
589 590
590 } // namespace pe 591 } // namespace pe
OLDNEW
« no previous file with comments | « syzygy/pe/pe_file_writer.h ('k') | syzygy/pe/pe_relinker.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698