private unsafe bool processImageResourceDirectoryEntry(IMAGE_RESOURCE_DIRECTORY *pIrd, IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde, uint baserva, string sResType, IMAGE_SECTION_HEADER *pIsh, byte *pData) { //string sResName; UInt16 nEntries; uint i; /* * if (Convert.ToBoolean((pIrde->Name & 0x80000000) >> 31)) // pIrde->Name ==> NameIsString? see Winnt.h * { * IMAGE_RESOURCE_DIR_STRING_U* pDirStringUnicode = (IMAGE_RESOURCE_DIR_STRING_U*)(pIrd + pIrde->OffsetToData); * sResName = MakeStringFromUTF8((byte*)&pDirStringUnicode->NameString); * } */ if (!Convert.ToBoolean((pIrde->OffsetToData & 0x80000000) >> 31)) // pIrde->OffsetToData ==> DataIsDirectory? see Winnt.h { throw new Exception("A resource directory was expected but parsing failed"); } IMAGE_RESOURCE_DIRECTORY * pIrdLevel_2 = (IMAGE_RESOURCE_DIRECTORY *)((baserva + pIrde->OffsetToData & 0x7fffffff)); IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrdeLevel_2 = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrdLevel_2 + 1); nEntries = (UInt16)(pIrdLevel_2->NumberOfIdEntries + pIrdLevel_2->NumberOfNamedEntries); for (i = 0; i < nEntries; i++) { IMAGE_RESOURCE_DATA_ENTRY *irdata = (IMAGE_RESOURCE_DATA_ENTRY *)(baserva + pIrdeLevel_2->OffsetToData); if (sResType == ResourceType.RT_VERSION.ToString()) { if (!processVersion_Information(irdata, baserva, pIsh, pData)) { return(false); } } if (sResType == ResourceType.RT_GROUP_ICON.ToString()) { if (!processVersion_Icon(irdata, baserva, pIsh, pData)) { return(false); } } pIrdeLevel_2++; } return(true); }
private static IMAGE_RESOURCE_DIRECTORY_ENTRY *_MemorySearchResourceEntry(void *root, IMAGE_RESOURCE_DIRECTORY *resources, byte *key, bool unicode) { const uint MAX_LOCAL_KEY_LENGTH = 2048; IMAGE_RESOURCE_DIRECTORY_ENTRY *entries = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(resources + 1); IMAGE_RESOURCE_DIRECTORY_ENTRY *result = null; uint start; uint end; uint middle; if (!IS_INTRESOURCE(key) && key[0] == (byte)'#') { // special case: resource id given as string byte *endpos = null; int tmpkey = (ushort)_tcstol(&key[1], (void **)&endpos, 10, unicode); if (tmpkey <= 0xffff && lstrlen(endpos, unicode) == 0) { key = (byte *)MAKEINTRESOURCE((uint)tmpkey); } } // entries are stored as ordered list of named entries, // followed by an ordered list of id entries - we can do // a binary search to find faster... if (IS_INTRESOURCE(key)) { ushort check = (ushort)(void *)key; start = resources->NumberOfNamedEntries; end = start + resources->NumberOfIdEntries; while (end > start) { ushort entryName; middle = (start + end) >> 1; entryName = (ushort)entries[middle].Name; if (check < entryName) { end = (end != middle ? middle : middle - 1); } else if (check > entryName) { start = (start != middle ? middle : middle + 1); } else { result = &entries[middle]; break; } } } else { char *searchKey; uint searchKeyLen = (uint)_tcslen(key, unicode); char *_searchKey = null; if (unicode) { searchKey = (char *)key; } else { // Resource names are always stored using 16bit characters, need to // convert string we search for. // In most cases resource names are short, so optimize for that by // using a pre-allocated array. char *_searchKeySpace; fixed(char *p = new char[MAX_LOCAL_KEY_LENGTH + 1]) _searchKeySpace = p; if ((ulong)searchKeyLen > MAX_LOCAL_KEY_LENGTH) { void *_searchKeySize = (void *)(((ulong)searchKeyLen + 1) * sizeof(char)); _searchKey = (char *)malloc(_searchKeySize); if (_searchKey == null) { return(null); } } else { _searchKey = _searchKeySpace; } mbstowcs(_searchKey, key, (void *)searchKeyLen); _searchKey[searchKeyLen] = (char)0; searchKey = _searchKey; } start = 0; end = resources->NumberOfNamedEntries; while (end > start) { int cmp; IMAGE_RESOURCE_DIR_STRING_U *resourceString; middle = (start + end) >> 1; resourceString = (IMAGE_RESOURCE_DIR_STRING_U *)OffsetPointer(root, (void *)(entries[middle].Name & 0x7FFFFFFF)); cmp = _wcsnicmp(searchKey, resourceString->NameString, (void *)resourceString->Length); if (cmp == 0) { // Handle partial match if (searchKeyLen > resourceString->Length) { cmp = 1; } else if (searchKeyLen < resourceString->Length) { cmp = -1; } } if (cmp < 0) { end = (middle != end ? middle : middle - 1); } else if (cmp > 0) { start = (middle != start ? middle : middle + 1); } else { result = &entries[middle]; break; } } if (!unicode) { if (searchKeyLen > MAX_LOCAL_KEY_LENGTH) { free(_searchKey); } } } return(result); }
internal unsafe Win32ResourceName(byte *pRoot, IMAGE_RESOURCE_DIRECTORY_ENTRY *pEntry) { _name = (pEntry->Name & 0x80000000) == 0 ? (object)(ushort)pEntry->Name : ReadString(pRoot, (int)(pEntry->Name & 0x7FFFFFFF));
public PEFile(FileStream Fin, int BufferLength) { this.fin = Fin; this.BufferLength = BufferLength; this.bData = ReadFile(fin, BufferLength); bool b64 = false; unsafe { fixed(byte *pData = this.bData) { IMAGE_DOS_HEADER * pIdh = (IMAGE_DOS_HEADER *)pData; IMAGE_NT_HEADERS32 *pInhs32 = (IMAGE_NT_HEADERS32 *)(pIdh->e_lfanew + pData); IMAGE_NT_HEADERS64 *pInhs64 = (IMAGE_NT_HEADERS64 *)(pIdh->e_lfanew + pData); if (pInhs32->FileHeader.SizeOfOptionalHeader > 0) // check for non object file { if (pInhs32->OptionalHeader.Magic == 0x10b) { // 32 Bit } if (pInhs32->OptionalHeader.Magic == 0x20b) { // 64 Bit b64 = true; } if (pInhs32->OptionalHeader.CLRDataDirectory.Size > 0) { m_IsManaged = true; } else { m_IsManaged = false; } if ((this.bData.Length < 9192) && (pInhs32->OptionalHeader.BaseOfCode > 2048)) { iEntryPoint = 2048; } else { if (b64) { iEntryPoint = pInhs64->OptionalHeader.BaseOfCode; } else { iEntryPoint = pInhs32->OptionalHeader.BaseOfCode; } } m_BinImprint = viGetFullImprint_ByteArray(bData, iEntryPoint); iNTHeaderOffset = pIdh->e_lfanew; iOptionalHeaderOffset = iNTHeaderOffset + 4 + (int)sizeof(IMAGE_FILE_HEADER); iSectionOffset = iOptionalHeaderOffset + (int)pInhs32->FileHeader.SizeOfOptionalHeader; iOffset = iSectionOffset + (int)pData; for (int i = 0; i < pInhs32->FileHeader.NumberOfSections; i++) { IMAGE_SECTION_HEADER *pIsh = (IMAGE_SECTION_HEADER *)(iOffset + (int)(sizeof(IMAGE_SECTION_HEADER) * i)); iBaseRVA = pIsh->PointerToRawData + (uint)pData; if (MakeStringFromUTF8((byte *)&pIsh->Name) == ".rsrc") { if (pIsh->VirtualSize > 0) { iImageSectionHeaderSize = pIsh->VirtualSize; } else { iImageSectionHeaderSize = pIsh->SizeOfRawData; } if (b64) { if (pInhs64->OptionalHeader.ResourceDataDirectory.VirtualAddress >= pIsh->VirtualAddress && pInhs64->OptionalHeader.ResourceDataDirectory.VirtualAddress < pIsh->VirtualAddress + iImageSectionHeaderSize) { IMAGE_RESOURCE_DIRECTORY * pIrd = (IMAGE_RESOURCE_DIRECTORY *)(pIsh->PointerToRawData + (uint)pData); IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrd + 1); nEntries = (UInt16)(pIrd->NumberOfIdEntries + pIrd->NumberOfNamedEntries); for (int j = 0; j < nEntries; j++) { if (!processImageResourceDirectory(pIrd, pIrde, iBaseRVA, pIsh, pData)) { throw new Exception("Error during resource directory parsing."); } pIrde++; } } } else { if (pInhs32->OptionalHeader.ResourceDataDirectory.VirtualAddress >= pIsh->VirtualAddress && pInhs32->OptionalHeader.ResourceDataDirectory.VirtualAddress < pIsh->VirtualAddress + iImageSectionHeaderSize) { IMAGE_RESOURCE_DIRECTORY * pIrd = (IMAGE_RESOURCE_DIRECTORY *)(pIsh->PointerToRawData + (uint)pData); IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrd + 1); nEntries = (UInt16)(pIrd->NumberOfIdEntries + pIrd->NumberOfNamedEntries); for (int j = 0; j < nEntries; j++) { if (!processImageResourceDirectory(pIrd, pIrde, iBaseRVA, pIsh, pData)) { throw new Exception("Error during resource directory parsing."); } pIrde++; } } } } if (iOffset >= iOptionalHeaderOffset + (int)sizeof(IMAGE_OPTIONAL_HEADER32) + 8 * 16 + (int)pData) // just for savety reasons { break; } } } } } }
private unsafe bool processImageResourceDirectory(IMAGE_RESOURCE_DIRECTORY *pIrd, IMAGE_RESOURCE_DIRECTORY_ENTRY *pIrde, uint baserva, IMAGE_SECTION_HEADER *pIsh, byte *pData) { string sResType; UInt16 nEntries; uint i; if (Convert.ToBoolean((pIrde->Name & 0x80000000) >> 31)) // pIrde->Name ==> NameIsString? see Winnt.h { return(true); IMAGE_RESOURCE_DIR_STRING_U *pDirStringUnicode = (IMAGE_RESOURCE_DIR_STRING_U *)(pIrd + pIrde->OffsetToData); sResType = MakeStringFromUTF8((byte *)&pDirStringUnicode->NameString); } else { ResourceType eRT = (ResourceType)pIrde->Name; switch (eRT) { case ResourceType.RT_VERSION: sResType = ResourceType.RT_VERSION.ToString(); break; case ResourceType.RT_ICON: sResType = ResourceType.RT_ICON.ToString(); break; case ResourceType.RT_GROUP_ICON: sResType = ResourceType.RT_GROUP_ICON.ToString(); break; default: sResType = "Unknown"; break; } } if (!Convert.ToBoolean((pIrde->OffsetToData & 0x80000000) >> 31)) // pIrde->OffsetToData ==> DataIsDirectory? see Winnt.h { throw new Exception("A resource directory was expected but parsing failed"); } IMAGE_RESOURCE_DIRECTORY *pIrdLevel_1 = (IMAGE_RESOURCE_DIRECTORY *)((baserva + pIrde->OffsetToData & 0x7fffffff)); pIrde = (IMAGE_RESOURCE_DIRECTORY_ENTRY *)(pIrdLevel_1 + 1); nEntries = (UInt16)(pIrdLevel_1->NumberOfIdEntries + pIrdLevel_1->NumberOfNamedEntries); for (i = 0; i < nEntries; i++) { if (!processImageResourceDirectoryEntry(pIrdLevel_1, pIrde, baserva, sResType, pIsh, pData)) { throw new Exception("Error during image resource directory entry parsing."); } pIrde++; } return(true); }