int check(int pid, void *address, int set) { Addresses *aptr = address_list; while (aptr != NULL) { if (aptr->address == address) break; aptr = aptr->next; } if (aptr != NULL && set == 0) return 0; if (set && aptr == NULL) { aptr = (Addresses *)calloc(1,sizeof(Addresses)); if (aptr == NULL) return -1; aptr->address = address; if (MapFind((void *)address) == NULL) { rva_to_offset(pid, address); } aptr->next = address_list; address_list = aptr; } return 1; }
static HRESULT parse_clr_metadata(ASSEMBLY *assembly) { METADATASTREAMHDR *streamhdr; ULONG rva, i, ofs; LPSTR stream; HRESULT hr; DWORD hdrsz; BYTE *ptr; hr = parse_metadata_header(assembly, &hdrsz); if (FAILED(hr)) return hr; rva = assembly->corhdr->MetaData.VirtualAddress; ptr = ImageRvaToVa(assembly->nthdr, assembly->data, rva + hdrsz, NULL); if (!ptr) return E_FAIL; for (i = 0; i < assembly->metadatahdr->Streams; i++) { streamhdr = (METADATASTREAMHDR *)ptr; ofs = rva_to_offset(assembly->nthdr, rva + streamhdr->Offset); ptr += sizeof(METADATASTREAMHDR); stream = (LPSTR)ptr; if (!lstrcmpA(stream, "#~")) { hr = parse_clr_tables(assembly, ofs); if (FAILED(hr)) return hr; } else if (!lstrcmpA(stream, "#Strings") || !lstrcmpA(stream, "Strings")) assembly->strings = assembly_data_offset(assembly, ofs); else if (!lstrcmpA(stream, "#Blob") || !lstrcmpA(stream, "Blob")) assembly->blobs = assembly_data_offset(assembly, ofs); ptr += lstrlenA(stream) + 1; ptr = (BYTE *)(((UINT_PTR)ptr + 3) & ~3); /* align on DWORD boundary */ } return S_OK; }
void parse_dll(std::vector<uint8_t> const& buffer) { // parse MZ header MZ_HEADER mz_header; mz_header.parse(&buffer[0]); if(mz_header.e_magic != 0x5A4D) throw std::runtime_error("MZ parse error."); PE_HEADER pe_header; pe_header.parse(&buffer[mz_header.e_lfanew]); if(pe_header.Magic != 0x4550) throw std::runtime_error("PE parse error."); PE_OPT_HEADER pe_opt_header; pe_opt_header.parse(&buffer[mz_header.e_lfanew+PE_HEADER::size()]); if(pe_opt_header.Magic != 0x010B) throw std::runtime_error("PE optional parse error."); std::vector<IMAGE_DATA_DIRECTORY> DataDirectory; uint8_t const* pDataDirectory = &buffer[mz_header.e_lfanew+PE_HEADER::size()+PE_OPT_HEADER::size()]; for(int i=0;i < pe_opt_header.NumberOfRvaAndSizes;++i) { IMAGE_DATA_DIRECTORY entry; entry.parse(&pDataDirectory[i*IMAGE_DATA_DIRECTORY::size()]); DataDirectory.push_back(entry); } std::vector<PE_SECTION_HEADER> SectionHeaders; uint8_t const* pSections = pDataDirectory + pe_opt_header.NumberOfRvaAndSizes * IMAGE_DATA_DIRECTORY::size(); for(int i=0;i < pe_header.NumberOfSections;++i) { PE_SECTION_HEADER sh; sh.parse(&pSections[i*PE_SECTION_HEADER::size()]); SectionHeaders.push_back(sh); } // find the section who contains the export directory int iExportDirectoryVA = DataDirectory[0].VirtualAddress; int iExportDirectorySectionIndex = -1; //std::cout << "Looking for " << offset(iExportDirectoryVA) << std::endl; for(size_t i=0;i < SectionHeaders.size();++i) { PE_SECTION_HEADER const& sh = SectionHeaders[i]; if(iExportDirectoryVA >= sh.VirtualAddress && iExportDirectoryVA < sh.VirtualAddress + sh.VirtualSize) { iExportDirectorySectionIndex = i; } } if(iExportDirectorySectionIndex == -1) throw std::runtime_error("Could not find section for export-directory"); PE_SECTION_HEADER const& sh = SectionHeaders[iExportDirectorySectionIndex]; int iExportDirectoryPA = rva_to_offset(sh, iExportDirectoryVA); IMAGE_EXPORT_DIRECTORY export_directory; export_directory.parse(&buffer[iExportDirectoryPA]); export_directory.print(); int iNameArrayPA = rva_to_offset(sh, export_directory.AddressOfNames); for(int i=0;i < export_directory.NumberOfFunctions;++i) { int iFunctionNameRVA = read_uint(&buffer[iNameArrayPA+4*i]); int iFunctionNamePA = rva_to_offset(sh, iFunctionNameRVA); std::string sFunctionName = read_string(&buffer[iFunctionNamePA]); g_ExportedNames.push_back(sFunctionName); } }