MCPcopy Create free account
hub / github.com/GJDuck/e9patch / targetAnalysis

Function targetAnalysis

src/e9patch/e9CFR.cpp:98–459  ·  view source on GitHub ↗

* Target analysis. Find instructions that can be reached by a * control-flow-transfer, including returns. This can be a "safe" * overapproximation, even if the general case is undecidable. */

Source from the content-addressed store, hash-verified

96 * overapproximation, even if the general case is undecidable.
97 */
98void targetAnalysis(Binary *B)
99{
100 // Step (1): Basic checks
101 if (B->targets != nullptr || !option_OCFR)
102 return;
103 switch (B->mode)
104 {
105 case MODE_ELF_EXE: case MODE_ELF_DSO:
106 break;
107 default:
108 warning("target analysis for Windows PE binaries is "
109 "not-yet-implemented; `-OCFR' will be ignored");
110 option_OCFR = false;
111 return; // Windows PE is NYI
112 }
113 bool cet = false;
114 if (B->elf.features == nullptr ||
115 (*B->elf.features & GNU_PROPERTY_X86_FEATURE_1_IBT) == 0 ||
116 (*B->elf.features & GNU_PROPERTY_X86_FEATURE_1_SHSTK) == 0)
117 cet = true;
118 bool pic = B->pic;
119 const uint8_t *data = B->original.bytes;
120 const Elf64_Phdr *phdrs = (Elf64_Phdr *)(data + B->elf.ehdr->e_phoff);
121 size_t phnum = B->elf.ehdr->e_phnum;
122 const Elf64_Phdr *phdr_dynamic = nullptr;
123 for (unsigned i = 0; i < phnum; i++)
124 {
125 const Elf64_Phdr *phdr = phdrs + i;
126 if (phdr->p_type == PT_DYNAMIC)
127 phdr_dynamic = phdr;
128 if (phdr->p_type != PT_LOAD || (phdr->p_flags & PF_X) == 0)
129 continue;
130 if ((phdr->p_flags & PF_W) != 0)
131 {
132 warning("target analysis does not support writable code segments");
133 return; // Not read-only
134 }
135 }
136
137 // Step (2): Create the target map:
138 void *ptr = mmap(nullptr, (B->size + PAGE_SIZE) / 8,
139 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE,
140 -1, 0);
141 if (ptr == MAP_FAILED)
142 error("failed to allocate target map: %s", strerror(errno));
143 uint8_t *targets = (uint8_t *)ptr;
144 B->targets = targets;
145
146 // Step (3): Find all direct jump targets.
147 //
148 // Note: This is a basic overapproximation that assumes *all* executable
149 // byte patterns resembling direct calls/jumps *are* direct
150 // calls/jumps. This analysis does not assume the binary can be
151 // disassembled, and safely handles data-in-code, etc.
152 //
153 std::set<intptr_t> tables;
154 for (unsigned i = 0; i < phnum; i++)
155 {

Callers 2

parseOptionsFunction · 0.85
parseBinaryFunction · 0.85

Calls 10

warningFunction · 0.85
mmapFunction · 0.85
errorFunction · 0.85
strerrorFunction · 0.85
memcpyFunction · 0.85
getModRMSizeFunction · 0.85
setTargetFunction · 0.85
addrToOffsetFunction · 0.70
findMethod · 0.45
endMethod · 0.45

Tested by

no test coverage detected