20 if (!this->pe_rawf.empty())
return cobf_error::COBF_PE_LOADED;
23 cobf_error ret_err = cobf_error::COBF_NO_ERROR;
24 HANDLE h_file = CreateFileA(
25 this->pe_path.c_str(),
30 FILE_ATTRIBUTE_NORMAL,
35 if (h_file == INVALID_HANDLE_VALUE)
38 return cobf_error::COBF_CANNOT_OPEN_FILE;
42 PIMAGE_DOS_HEADER dos_hdr;
43 PIMAGE_NT_HEADERS nt_hdrs;
44 PIMAGE_IMPORT_DESCRIPTOR p_imports;
49 if (!GetFileSizeEx(h_file, &f_size))
52 ret_err = cobf_error::COBF_CANNOT_GET_SIZE;
57 this->pe_rawf.resize((
size_t)f_size.QuadPart);
64 (DWORD)this->pe_rawf.size(),
70 ret_err = cobf_error::COBF_CANNOT_READ_FILE;
75 if (!this->get_dos_header(dos_hdr))
78 ret_err = cobf_error::COBF_INVALID_DOS_HDR;
83 if (!this->get_nt_headers(dos_hdr, nt_hdrs))
86 ret_err = cobf_error::COBF_INVALID_NT_HDRS;
91 if (!this->verify_machine(nt_hdrs))
94 ret_err = cobf_error::COBF_UNSUPPORTED_PE;
99 if (!this->verify_sections(dos_hdr, nt_hdrs))
102 ret_err = cobf_error::COBF_INVALID_SECTION_HDR;
107 if (!this->get_data_table(IMAGE_DIRECTORY_ENTRY_IMPORT, (PVOID*)&p_imports, imports_size))
110 ret_err = cobf_error::COBF_INVALID_IMPORTS_DIR;
115 if (p_imports && !this->parse_imports(p_imports, imports_size))
118 ret_err = cobf_error::COBF_CANNOT_PARSE_IMPORTS;
125 if (ret_err != cobf_error::COBF_NO_ERROR)
128 this->pe_rawf.clear();
129 this->pe_mods.clear();
133 if (!CloseHandle(h_file))
return cobf_error::COBF_CANNOT_CLEAR;
141 if (this->pe_rawf.empty())
return cobf_error::COBF_PE_UNLOADED;
144 this->pe_rawf.clear();
145 this->pe_mods.clear();
146 return cobf_error::COBF_NO_ERROR;
150 BOOL cobf::get_data_table(
size_t data_entry, PVOID* p_table_ptr,
size_t& table_size)
153 PIMAGE_DOS_HEADER dos_hdr = (PIMAGE_DOS_HEADER)this->pe_rawf.data();
154 PIMAGE_NT_HEADERS nt_hdrs = (PIMAGE_NT_HEADERS)&this->pe_rawf[dos_hdr->e_lfanew];
157 if (data_entry >= nt_hdrs->OptionalHeader.NumberOfRvaAndSizes)
return FALSE;
160 DWORD table_rva = nt_hdrs->OptionalHeader.DataDirectory[data_entry].VirtualAddress;
161 table_size = nt_hdrs->OptionalHeader.DataDirectory[data_entry].Size;
174 if (!this->rva_to_offset(table_rva, table_offset))
return FALSE;
175 if (table_offset + table_size > this->pe_rawf.size())
return FALSE;
178 *p_table_ptr = (PVOID)&this->pe_rawf[table_offset];
183 BOOL cobf::section_of_rva(DWORD rva, PIMAGE_SECTION_HEADER& sec)
186 PIMAGE_DOS_HEADER dos_hdr = (PIMAGE_DOS_HEADER)this->pe_rawf.data();
187 PIMAGE_NT_HEADERS nt_hdrs = (PIMAGE_NT_HEADERS)&this->pe_rawf[dos_hdr->e_lfanew];
188 PIMAGE_SECTION_HEADER c_sec = (PIMAGE_SECTION_HEADER)&this->pe_rawf[dos_hdr->e_lfanew +
189 sizeof(nt_hdrs->Signature) +
sizeof(nt_hdrs->FileHeader) +
190 nt_hdrs->FileHeader.SizeOfOptionalHeader];
193 WORD n_secs = nt_hdrs->FileHeader.NumberOfSections;
197 if (rva < (
size_t)c_sec->VirtualAddress || rva >= (size_t)c_sec->VirtualAddress +
198 c_sec->Misc.VirtualSize)
215 BOOL cobf::get_dos_header(PIMAGE_DOS_HEADER& dos_hdr)
218 dos_hdr = (PIMAGE_DOS_HEADER)this->pe_rawf.data();
219 if (
sizeof(*dos_hdr) > this->pe_rawf.size() ||
220 dos_hdr->e_magic != IMAGE_DOS_SIGNATURE)
return FALSE;
225 BOOL cobf::get_nt_headers(PIMAGE_DOS_HEADER dos_hdr, PIMAGE_NT_HEADERS& nt_hdrs)
228 nt_hdrs = (PIMAGE_NT_HEADERS)&this->pe_rawf[dos_hdr->e_lfanew];
229 if (
sizeof(*nt_hdrs) + dos_hdr->e_lfanew > this->pe_rawf.size() ||
230 nt_hdrs->Signature != IMAGE_NT_SIGNATURE)
return FALSE;
235 BOOL cobf::verify_machine(PIMAGE_NT_HEADERS nt_hdrs)
239 return nt_hdrs->FileHeader.Machine == IMAGE_FILE_MACHINE_I386;
241 return nt_hdrs->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 ||
242 nt_hdrs->FileHeader.Machine == IMAGE_FILE_MACHINE_IA64;
247 BOOL cobf::verify_sections(PIMAGE_DOS_HEADER dos_hdr, PIMAGE_NT_HEADERS nt_hdrs)
250 return dos_hdr->e_lfanew +
sizeof(*nt_hdrs) + nt_hdrs->FileHeader.NumberOfSections
251 *
sizeof(IMAGE_SECTION_HEADER) <= this->pe_rawf.size() &&
252 nt_hdrs->FileHeader.NumberOfSections;
256 BOOL cobf::parse_imports(PIMAGE_IMPORT_DESCRIPTOR p_imports,
size_t imports_size)
259 while (imports_size >=
sizeof(IMAGE_IMPORT_DESCRIPTOR) && p_imports->Name)
262 DWORD dll_name = p_imports->Name;
263 DWORD orig_th = p_imports->OriginalFirstThunk;
264 DWORD first_th = p_imports->FirstThunk;
265 PSIZE_T p_orig_th, p_first_th;
266 PCHAR p_dll_name;
size_t sym_idx = 0;
269 if ((orig_th && !this->rva_to_ptr(orig_th, (PVOID*)&p_orig_th))
270 || !this->rva_to_ptr(first_th, (PVOID*)&p_first_th)
271 || !this->rva_to_ptr(dll_name, (PVOID*)&p_dll_name))
278 this->pe_mods.push_back({ p_dll_name });
279 auto& dll_mod = this->pe_mods.back();
280 transform(dll_mod.dll_name.begin(), dll_mod.dll_name.end(),
281 dll_mod.dll_name.begin(), ::toupper);
284 PSIZE_T p_thunk = orig_th ? p_orig_th : p_first_th;
288 DWORD fth_rva = first_th + (DWORD)sym_idx *
sizeof(
size_t);
289 DWORD oth_off = (DWORD)((PBYTE)p_thunk - this->pe_rawf.data());
292 if (!this->insert_import(this->pe_mods.back(), dll_name, *p_thunk, fth_rva, oth_off))
301 imports_size -=
sizeof(IMAGE_IMPORT_DESCRIPTOR);
310 BOOL cobf::insert_import(cmod& dll_mod, DWORD dll_off,
size_t th_sym, DWORD fth_rva, DWORD oth_off)
313 if (IMAGE_SNAP_BY_ORDINAL(th_sym))
316 dll_mod.mod_syms.push_back(csym(IMAGE_ORDINAL(th_sym), dll_off, fth_rva, oth_off));
322 if (!this->rva_to_ptr((DWORD)th_sym, (PVOID*)&p_name))
329 p_name +=
sizeof(IMAGE_IMPORT_BY_NAME::Hint);
332 dll_mod.mod_syms.push_back(csym(p_name, dll_off, fth_rva, oth_off,
333 (DWORD)((PBYTE)p_name - this->pe_rawf.data())));
338 BOOL cobf::rva_to_ptr(DWORD ptr_rva, PVOID* p_ptr)
340 if (!this->rva_to_offset(ptr_rva, ptr_rva) ||
341 ptr_rva >= this->pe_rawf.size())
return FALSE;
342 *p_ptr = (PVOID)&this->pe_rawf[ptr_rva];
347 BOOL cobf::rva_to_offset(DWORD rva, DWORD& offset)
350 PIMAGE_SECTION_HEADER sec;
351 if (this->section_of_rva(rva, sec))
354 offset = sec->PointerToRawData + (rva - sec->VirtualAddress);
366 srand((DWORD)time(NULL));