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

Side by Side Diff: syzygy/pe/pe_utils.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_utils.h ('k') | no next file » | 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,
(...skipping 529 matching lines...) Expand 10 before | Expand all | Expand 10 after
540 ref.size(), 540 ref.size(),
541 it->second.first, 541 it->second.first,
542 it->second.second, 542 it->second.second,
543 it->second.second + delta); 543 it->second.second + delta);
544 referrer->SetReference(reference_it->first, new_reference); 544 referrer->SetReference(reference_it->first, new_reference);
545 } 545 }
546 } 546 }
547 } 547 }
548 } 548 }
549 549
550 size_t GetSectionOffset(const ImageLayout& image_layout,
551 const RelativeAddress rel_addr,
552 size_t section_index) {
553 if (section_index == BlockGraph::kInvalidSectionId)
554 return rel_addr.value();
555
556 DCHECK_GT(image_layout.sections.size(), section_index);
557 const ImageLayout::SectionInfo& section_info =
558 image_layout.sections[section_index];
559
560 DCHECK_GE(rel_addr, section_info.addr);
561 return rel_addr - section_info.addr;
562 }
563
564 template <class Type>
565 bool UpdateReference(size_t start, Type new_value, std::vector<uint8_t>* data) {
566 common::BinaryBufferParser parser(&data->at(0), data->size());
567
568 Type* ref_ptr = NULL;
569 if (!parser.GetAtIgnoreAlignment(start,
570 const_cast<const Type**>(&ref_ptr))) {
571 LOG(ERROR) << "Reference data not in block";
572 return false;
573 }
574 * ref_ptr = new_value;
575
576 return true;
577 }
578
579 bool ResolveReferences2(core::AbsoluteAddress image_base,
580 core::RelativeAddress addr,
581 BlockGraph::Block::ReferenceMap::const_iterator ref_it,
582 const ImageLayout& image_layout) {
583 BlockGraph::Offset start = ref_it->first;
584 const BlockGraph::Reference& ref = ref_it->second;
585 BlockGraph::Block* dst = ref.referenced();
586
587 RelativeAddress src_addr(addr + start);
588 RelativeAddress dst_addr;
589 if (!image_layout.blocks.GetAddressOf(dst, &dst_addr)) {
590 LOG(ERROR) << "All blocks must have an address.";
591 return false;
592 }
593 dst_addr += ref.offset();
594
595 // Compute the new value of the reference.
596 uint32_t value = 0;
597 switch (ref.type()) {
598 case BlockGraph::ABSOLUTE_REF:
599 value = image_base.value() + dst_addr.value();
600 break;
601
602 case BlockGraph::PC_RELATIVE_REF:
603 value = dst_addr - (src_addr + ref.size());
604 break;
605
606 case BlockGraph::RELATIVE_REF:
607 value = dst_addr.value();
608 break;
609 }
610
611 return true;
612 }
613
614 bool ResolveReferences(core::AbsoluteAddress image_base,
615 const block_graph::BlockGraph::Block* block,
616 core::RelativeAddress addr,
617 const core::FileOffsetAddress file_offs,
618 SectionIndexFileRangeMap section_file_range_map,
619 SectionIndexSpace section_index_space,
620 bool write_references_in_place,
621 std::vector<uint8_t>* buffer,
622 const ImageLayout& image_layout) {
623 BlockGraph::Block::ReferenceMap::const_iterator ref_it(
624 block->references().begin());
625 BlockGraph::Block::ReferenceMap::const_iterator ref_end(
626 block->references().end());
627 for (; ref_it != ref_end; ++ref_it) {
628 BlockGraph::Offset start = ref_it->first;
629 const BlockGraph::Reference& ref = ref_it->second;
630 BlockGraph::Block* dst = ref.referenced();
631
632 RelativeAddress src_addr(addr + start);
633 RelativeAddress dst_addr;
634 if (!image_layout.blocks.GetAddressOf(dst, &dst_addr)) {
635 LOG(ERROR) << "All blocks must have an address.";
636 return false;
637 }
638 dst_addr += ref.offset();
639
640 // Compute the new value of the reference.
641 uint32_t value = 0;
642 switch (ref.type()) {
643 case BlockGraph::ABSOLUTE_REF:
644 value = image_base.value() + dst_addr.value();
645 break;
646
647 case BlockGraph::PC_RELATIVE_REF:
648 value = dst_addr - (src_addr + ref.size());
649 break;
650
651 case BlockGraph::RELATIVE_REF:
652 value = dst_addr.value();
653 break;
654
655 case BlockGraph::FILE_OFFSET_REF: {
656 // Get the index of the section containing the destination block.
657 SectionIndexSpace::const_iterator section_index_space_it =
658 section_index_space.FindContaining(
659 SectionIndexSpace::Range(dst_addr, 1));
660 DCHECK(section_index_space_it != section_index_space.end());
661 size_t dst_section_index = section_index_space_it->second;
662
663 // Get the offset of the block in its section, as well as the range of
664 // the section on disk. Validate that the referred location is
665 // actually directly represented on disk (not in implicit virtual data).
666 const FileRange& file_range =
667 section_file_range_map[dst_section_index];
668 size_t section_offset = GetSectionOffset(image_layout,
669 dst_addr,
670 dst_section_index);
671 if (section_offset >= file_range.size()) {
672 LOG(ERROR) << "Encountered file offset reference that refers to "
673 << "a location outside of the explicit section data.";
674 return false;
675 }
676
677 // Finally, calculate the value of the file offset.
678 value = file_range.start().value() + section_offset;
679 break;
680 }
681
682 default:
683 LOG(ERROR) << "Impossible reference type";
684 return false;
685 }
686
687 if (!write_references_in_place)
688 return true;
689
690 // Now store the new value.
691 BlockGraph::Offset ref_offset = file_offs.value() + start;
692 switch (ref.size()) {
693 case sizeof(uint8_t) :
694 if (!UpdateReference(ref_offset, static_cast<uint8_t>(value), buffer))
695 return false;
696 break;
697
698 case sizeof(uint16_t) :
699 if (!UpdateReference(ref_offset, static_cast<uint16_t>(value), buffer))
700 return false;
701 break;
702
703 case sizeof(uint32_t) :
704 if (!UpdateReference(ref_offset, static_cast<uint32_t>(value), buffer))
705 return false;
706 break;
707
708 default:
709 LOG(ERROR) << "Unsupported reference size.";
710 return false;
711 }
712 }
713 return true;
714 }
550 } // namespace pe 715 } // namespace pe
OLDNEW
« no previous file with comments | « syzygy/pe/pe_utils.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698