BOOL ImageFile(BYTE *FileBuffer,BYTE **ImageModuleBase) { PIMAGE_DOS_HEADER ImageDosHeader; PIMAGE_NT_HEADERS ImageNtHeaders; PIMAGE_SECTION_HEADER ImageSectionHeader; DWORD FileAlignment,SectionAlignment,NumberOfSections,SizeOfImage,SizeOfHeaders; DWORD Index; BYTE *ImageBase; DWORD SizeOfNtHeaders; ImageDosHeader=(PIMAGE_DOS_HEADER)FileBuffer; if (ImageDosHeader->e_magic!=IMAGE_DOS_SIGNATURE) { return FALSE; } ImageNtHeaders=(PIMAGE_NT_HEADERS)(FileBuffer+ImageDosHeader->e_lfanew); if (ImageNtHeaders->Signature!=IMAGE_NT_SIGNATURE) { return FALSE; } FileAlignment=ImageNtHeaders->OptionalHeader.FileAlignment; SectionAlignment=ImageNtHeaders->OptionalHeader.SectionAlignment; NumberOfSections=ImageNtHeaders->FileHeader.NumberOfSections; SizeOfImage=ImageNtHeaders->OptionalHeader.SizeOfImage; SizeOfHeaders=ImageNtHeaders->OptionalHeader.SizeOfHeaders; SizeOfImage=AlignSize(SizeOfImage,SectionAlignment); ImageBase=ExAllocatePool(NonPagedPool,SizeOfImage); if (ImageBase==NULL) { return FALSE; } RtlZeroMemory(ImageBase,SizeOfImage); SizeOfNtHeaders=sizeof(ImageNtHeaders->FileHeader) + sizeof(ImageNtHeaders->Signature)+ImageNtHeaders->FileHeader.SizeOfOptionalHeader; ImageSectionHeader=(PIMAGE_SECTION_HEADER)((DWORD)ImageNtHeaders+SizeOfNtHeaders); for (Index=0;Index<NumberOfSections;Index++) { ImageSectionHeader[Index].SizeOfRawData=AlignSize(ImageSectionHeader[Index].SizeOfRawData,FileAlignment); ImageSectionHeader[Index].Misc.VirtualSize=AlignSize(ImageSectionHeader[Index].Misc.VirtualSize,SectionAlignment); } if (ImageSectionHeader[NumberOfSections-1].VirtualAddress+ImageSectionHeader[NumberOfSections-1].SizeOfRawData>SizeOfImage) { ImageSectionHeader[NumberOfSections-1].SizeOfRawData = SizeOfImage-ImageSectionHeader[NumberOfSections-1].VirtualAddress; } RtlCopyMemory(ImageBase,FileBuffer,SizeOfHeaders); for (Index=0;Index<NumberOfSections;Index++) { DWORD FileOffset=ImageSectionHeader[Index].PointerToRawData; DWORD Length=ImageSectionHeader[Index].SizeOfRawData; DWORD ImageOffset=ImageSectionHeader[Index].VirtualAddress; RtlCopyMemory(&ImageBase[ImageOffset],&FileBuffer[FileOffset],Length); } *ImageModuleBase=ImageBase; return TRUE; }
VOID GetITSectionSizeRVA(ULONG_PTR ImageBase, PULONG_PTR SizeNewSection, PULONG_PTR RVAIT) { PIMAGE_DOS_HEADER pDos; PIMAGE_NT_HEADERS pNT; PIMAGE_SECTION_HEADER pSection; pDos = (PIMAGE_DOS_HEADER)ImageBase; pNT = (PIMAGE_NT_HEADERS)(ImageBase + pDos->e_lfanew); pSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)pNT + sizeof(IMAGE_NT_HEADERS)); *SizeNewSection = AlignSize(pinfo.Importer.TotalSizeIT, pNT->OptionalHeader.SectionAlignment); *RVAIT = AlignSize(pSection[pNT->FileHeader.NumberOfSections - 1].VirtualAddress + pSection[pNT->FileHeader.NumberOfSections - 1].Misc.VirtualSize, pNT->OptionalHeader.SectionAlignment); }
/* This method will fix the Raw Size and Offset of Sections FileAlignment = pNT->OptionalHeader.SectionAlignment; */ BOOL PrepareDumpPE(ULONG_PTR ImageBase, PBYTE *pDump, PULONG_PTR AllocSize) { PIMAGE_DOS_HEADER pDos; ULONG_PTR FinalSize = 0; DWORD NumberOfSections = 0; DWORD FileAlignment = 0; ULONG_PTR Align = 0; PIMAGE_NT_HEADERS pNT; PIMAGE_SECTION_HEADER pSection; *pDump = AllocDumpedPE(ImageBase, AllocSize); if (*pDump == NULL) { DbgMsg("[-] AllocDumpedPE failed\n"); return FALSE; } /* Copy DOS HEADER */ memcpy(*pDump, (LPVOID)ImageBase, sizeof (IMAGE_DOS_HEADER)); FinalSize += sizeof (IMAGE_DOS_HEADER); pDos = (PIMAGE_DOS_HEADER)ImageBase; pNT = (PIMAGE_NT_HEADERS)(ImageBase + pDos->e_lfanew); pSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)pNT + sizeof(IMAGE_NT_HEADERS)); /* Copy PADDING */ memcpy(*pDump + FinalSize, (LPVOID)(ImageBase + FinalSize), (ULONG_PTR)pNT - (ULONG_PTR)((ULONG_PTR)pDos + sizeof (IMAGE_DOS_HEADER))); FinalSize += (DWORD)((ULONG_PTR)pNT - (ULONG_PTR)((ULONG_PTR)pDos + sizeof (IMAGE_DOS_HEADER))); /* Copy NT HEADER */ memcpy(*pDump + FinalSize, (LPVOID)pNT, sizeof (IMAGE_FILE_HEADER) + pNT->FileHeader.SizeOfOptionalHeader + sizeof(DWORD)); FinalSize += sizeof (IMAGE_FILE_HEADER) + pNT->FileHeader.SizeOfOptionalHeader + sizeof(DWORD); NumberOfSections = pNT->FileHeader.NumberOfSections; FileAlignment = pNT->OptionalHeader.FileAlignment; FileAlignment = pNT->OptionalHeader.SectionAlignment; /* Copy Sections */ memcpy(*pDump + FinalSize, (LPVOID)pSection, sizeof (IMAGE_SECTION_HEADER) * NumberOfSections); FinalSize += sizeof (IMAGE_SECTION_HEADER) * NumberOfSections; Align = AlignSize(FinalSize, FileAlignment); for (; FinalSize < Align; FinalSize++) *(*pDump + FinalSize) = 0; for (DWORD i = 0; i < NumberOfSections; i++) { memcpy(*pDump + FinalSize, (LPVOID)(ImageBase + pSection[i].VirtualAddress), pSection[i].Misc.VirtualSize); FinalSize += pSection[i].Misc.VirtualSize; Align = AlignSize(FinalSize, FileAlignment); for (; FinalSize < Align; FinalSize++) *(*pDump + FinalSize) = 0; } return TRUE; }
CStream::CStream(UINT32 cap) { m_capacity = AlignSize(cap); m_size = 0; m_pos = 0; m_stream = new UINT8[m_capacity]; }
uint32_t CalculateObjectSize(const VMValue object, uint8_t *memoryArea) { auto typeField = GetTypeField(object, memoryArea); if (IsArray(typeField)) { return AlignSize(GetArrayLengthUnchecked(object, memoryArea)*TypeSize(GetArrayValueType(typeField)) + ArrayHeaderSize()); } else { throw std::logic_error("Size calculation not implemented for non-arrays"); } }
// hint是一个提示值,用于在某些情况下减少重新分配的次数 void CStream::ReAlloc(UINT32 hint) { UINT32 inc = AlignSize(hint); UINT8 *temp = new UINT8[m_capacity+inc]; // 扩展buffer if (m_stream) { memcpy(temp, m_stream, m_size); // 进行深拷贝 delete[] m_stream; } m_stream = temp; // 更新消息流 m_capacity += inc; return; }
PBYTE AllocDumpedPE(ULONG_PTR ImageBase, PULONG_PTR dwAllocSize) { PIMAGE_DOS_HEADER pDos; PIMAGE_NT_HEADERS pNT; PIMAGE_SECTION_HEADER pSection; PBYTE pDump = NULL; if (ValidateHeader(ImageBase) == FALSE) { return NULL; } pDos = (PIMAGE_DOS_HEADER)ImageBase; pNT = (PIMAGE_NT_HEADERS)(ImageBase + pDos->e_lfanew); pSection = (PIMAGE_SECTION_HEADER)((ULONG_PTR)pNT + sizeof(IMAGE_NT_HEADERS)); *dwAllocSize = pSection[pNT->FileHeader.NumberOfSections - 1].VirtualAddress + pSection[pNT->FileHeader.NumberOfSections - 1].Misc.VirtualSize; *dwAllocSize = AlignSize(*dwAllocSize, pNT->OptionalHeader.SectionAlignment); pDump = (PBYTE)VirtualAlloc(NULL, *dwAllocSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (!pDump) { return NULL; } return pDump; }
BOOL dump(DWORD dwOEP, struct dll *NewDLL, DWORD dwStartIAT) { DWORD dwBase; DWORD dwLen; BYTE modulePath[MAX_PATH + 8]; PBYTE pDump; PIMAGE_DOS_HEADER pDosHeader; PIMAGE_NT_HEADERS pPE; PIMAGE_SECTION_HEADER pSection; PIMAGE_SECTION_HEADER pSectionHeaders; DWORD curseur, i; HANDLE hFile; DWORD NbByteWritten; PBYTE IAT = NULL; DWORD dwAllocSize = 0; DWORD dwRVAIAT = 0; dwBase = (DWORD)GetModuleHandle(NULL); if (((dwLen = GetModuleFileNameA((HMODULE) dwBase, modulePath, MAX_PATH + 1)) >= MAX_PATH) || (!dwLen)) return FALSE; if (!(pDump = AllocAndCopy(dwBase, &dwAllocSize))) return FALSE; pDosHeader = (PIMAGE_DOS_HEADER)pDump; pPE = (PIMAGE_NT_HEADERS)(pDump + pDosHeader->e_lfanew); pSection = (PIMAGE_SECTION_HEADER)((PCHAR)pPE + sizeof(IMAGE_FILE_HEADER) + pPE->FileHeader.SizeOfOptionalHeader + sizeof(DWORD)); pPE->OptionalHeader.FileAlignment = 0x200; for (curseur = AlignSize(pPE->OptionalHeader.SizeOfHeaders, pPE->OptionalHeader.FileAlignment) - 1; ! pDump[curseur]; curseur --); pSectionHeaders = (PIMAGE_SECTION_HEADER)((PBYTE)pPE + sizeof(IMAGE_FILE_HEADER) + pPE->FileHeader.SizeOfOptionalHeader + sizeof(DWORD)); dwRVAIAT = AlignSize(pSectionHeaders[pPE->FileHeader.NumberOfSections - 1].VirtualAddress + pSectionHeaders[pPE->FileHeader.NumberOfSections - 1].Misc.VirtualSize, pPE->OptionalHeader.SectionAlignment); IAT = Reconstruct(dwStartIAT, NewDLL, dwRVAIAT); memcpy(pDump, dwBase, dwAllocSize); curseur = AlignSize(curseur + 1, pPE->OptionalHeader.FileAlignment); pPE->OptionalHeader.SizeOfHeaders = curseur; for (i = 0; i < pPE->FileHeader.NumberOfSections; i++) { memcpy(pDump + curseur, pDump + pSection[i].VirtualAddress, pSection[i].Misc.VirtualSize); pSection[i].PointerToRawData = curseur; curseur += pSection[i].Misc.VirtualSize - 1; //AlignCurseur(pDump, &curseur); while ((pDump[curseur] == 0) && (((int)curseur) >= -1)) curseur--; curseur = AlignSize(curseur + 1, pPE->OptionalHeader.FileAlignment); pSection[i].SizeOfRawData = curseur - pSection[i].PointerToRawData; } strcpy(pSection[pPE->FileHeader.NumberOfSections].Name, ".suce"); pSection[pPE->FileHeader.NumberOfSections].PointerToRawData = curseur; pSection[pPE->FileHeader.NumberOfSections].Misc.VirtualSize = AlignSize(computeSizeIAT(NewDLL), pPE->OptionalHeader.SectionAlignment); pSection[pPE->FileHeader.NumberOfSections].VirtualAddress = dwRVAIAT; pSection[pPE->FileHeader.NumberOfSections].Characteristics = 0xE0000060; memcpy(pDump + curseur, IAT, pSection[pPE->FileHeader.NumberOfSections].Misc.VirtualSize); curseur += pSection[pPE->FileHeader.NumberOfSections].Misc.VirtualSize - 1; while ((pDump[curseur] == 0) && (((int)curseur) >= -1)) curseur--; curseur = AlignSize(curseur + 1, pPE->OptionalHeader.FileAlignment); pSection[pPE->FileHeader.NumberOfSections].SizeOfRawData = curseur - pSection[pPE->FileHeader.NumberOfSections].PointerToRawData; pPE->FileHeader.NumberOfSections += 1; pPE->OptionalHeader.DataDirectory[1].VirtualAddress = dwRVAIAT; pPE->OptionalHeader.DataDirectory[1].Size = computeSizeIAT(NewDLL); pPE->OptionalHeader.AddressOfEntryPoint = dwOEP - (DWORD)GetModuleHandle(0); pPE->OptionalHeader.SizeOfImage += AlignSize(computeSizeIAT(NewDLL), pPE->OptionalHeader.SectionAlignment); modulePath[dwLen - 4] = '-'; modulePath[dwLen - 3] = 'd'; modulePath[dwLen - 2] = 'u'; modulePath[dwLen - 1] = 'm'; modulePath[dwLen] = 'p'; modulePath[dwLen + 1] = 'e'; modulePath[dwLen + 2] = 'd'; modulePath[dwLen + 3] = '.'; modulePath[dwLen + 4] = 'e'; modulePath[dwLen + 5] = 'x'; modulePath[dwLen + 6] = 'e'; modulePath[dwLen + 7] = 0; if ((hFile = CreateFileA(modulePath,(GENERIC_READ | GENERIC_WRITE), FILE_SHARE_READ | FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL)) == INVALID_HANDLE_VALUE) return FALSE; WriteFile(hFile, pDump, curseur, &NbByteWritten, NULL); if (NbByteWritten != curseur) return FALSE; return TRUE; }
BOOL DumpPE(HMODULE hModule, LPCSTR dumpFileName) { PIMAGE_DOS_HEADER pDos; PIMAGE_NT_HEADERS pNT32; PIMAGE_NT_HEADERS64 pNT64; PIMAGE_SECTION_HEADER pSection; PBYTE pDump = NULL; DWORD dwAllocSize = 0; DWORD dwFinalSize = 0; DWORD NumberOfSections = 0; DWORD FileAlignment = 0; DWORD dwAlign = 0; pDump = AllocEnough(hModule, &dwAllocSize); if (!pDump) { fprintf(stderr, "[-] AllocEnough failed\n"); return FALSE; } /* Copy DOS HEADER */ memcpy(pDump, (LPVOID)hModule, sizeof (IMAGE_DOS_HEADER)); dwFinalSize += sizeof (IMAGE_DOS_HEADER); pDos = (PIMAGE_DOS_HEADER)hModule; if (IsPE64Bit(hModule)) { pNT64 = (PIMAGE_NT_HEADERS64)((DWORD)hModule + pDos->e_lfanew); /* Copy PADDING */ memcpy(pDump + dwFinalSize, (LPVOID)((DWORD)hModule + dwFinalSize), (DWORD)pNT64 - (DWORD)((DWORD)pDos + sizeof (IMAGE_DOS_HEADER))); dwFinalSize += (DWORD)pNT64 - (DWORD)((DWORD)pDos + sizeof (IMAGE_DOS_HEADER)); /* Copy NT HEADER */ memcpy(pDump + dwFinalSize, (LPVOID)pNT64, sizeof (IMAGE_FILE_HEADER) + pNT64->FileHeader.SizeOfOptionalHeader + sizeof(DWORD)); dwFinalSize += sizeof (IMAGE_FILE_HEADER) + pNT64->FileHeader.SizeOfOptionalHeader + sizeof(DWORD); NumberOfSections = pNT64->FileHeader.NumberOfSections; FileAlignment = pNT64->OptionalHeader.FileAlignment; pSection = (PIMAGE_SECTION_HEADER)((DWORD)pNT64 + sizeof(IMAGE_NT_HEADERS64)); } else { pNT32 = (PIMAGE_NT_HEADERS)((DWORD)hModule + pDos->e_lfanew); /* Copy PADDING */ memcpy(pDump + dwFinalSize, (LPVOID)((DWORD)hModule + dwFinalSize), (DWORD)pNT32 - (DWORD)((DWORD)pDos + sizeof (IMAGE_DOS_HEADER))); dwFinalSize += (DWORD)pNT32 - (DWORD)((DWORD)pDos + sizeof (IMAGE_DOS_HEADER)); /* Copy NT HEADER */ memcpy(pDump + dwFinalSize, (LPVOID)pNT32, sizeof (IMAGE_FILE_HEADER) + pNT32->FileHeader.SizeOfOptionalHeader + sizeof(DWORD)); dwFinalSize += sizeof (IMAGE_FILE_HEADER) + pNT32->FileHeader.SizeOfOptionalHeader + sizeof(DWORD); NumberOfSections = pNT32->FileHeader.NumberOfSections; FileAlignment = pNT32->OptionalHeader.FileAlignment; pSection = (PIMAGE_SECTION_HEADER)((DWORD)pNT32 + sizeof(IMAGE_NT_HEADERS)); } /* Copy Sections */ memcpy(pDump + dwFinalSize, (LPVOID)pSection, sizeof (IMAGE_SECTION_HEADER) * NumberOfSections); dwFinalSize += sizeof (IMAGE_SECTION_HEADER) * NumberOfSections; dwAlign = AlignSize(dwFinalSize, FileAlignment); for (; dwFinalSize < dwAlign; dwFinalSize++) *(pDump + dwFinalSize) = 0; for (DWORD i = 0; i < NumberOfSections; i++) { printf("%08X\n", pSection[i].VirtualAddress); printf("%08X\n", hModule + pSection[i].VirtualAddress); printf("%08X\n", pSection[i].SizeOfRawData); memcpy(pDump + dwFinalSize, (LPVOID)((DWORD)hModule + pSection[i].VirtualAddress), pSection[i].SizeOfRawData); dwFinalSize += pSection[i].SizeOfRawData; dwAlign = AlignSize(dwFinalSize, FileAlignment); for (; dwFinalSize < dwAlign; dwFinalSize++) *(pDump + dwFinalSize) = 0; } return Write2File(dumpFileName, pDump, dwFinalSize); }
static size_t ComputeStructureSize(const char *signature, const char *&endpos, size_t &alignment) { size_t size = 0; alignment = 1; // Start with one byte alignment. int numelements = *signature++; numelements |= (*signature++) << 8; for(int i = 0; i < numelements; ++i) { int type = *signature; switch(type) { case 'v': break; case 'x': ++size; break; case 'b': case 'B': ++size; break; case 's': case 'S': AlignSize(size, 2); size += 2; alignment = max(alignment, 2); break; case 'i': case 'I': case 'p': case 'P': case 'f': AlignSize(size, 4); size += 4; alignment = max(alignment, 4); break; case 'l': case 'L': case 'F': AlignSize(size, 8); size += 8; alignment = max(alignment, 8); break; case 'D': AlignSize(size, 16); size += 16; alignment = max(alignment, 16); break; case 'V': abort(); break; case 'd': size_t subAlignment; size_t subSize = ComputeStructureSize(signature, signature, subAlignment); AlignSize(size, subAlignment); size += subSize; alignment = max(alignment, subAlignment); break; } } endpos = signature - 1; AlignSize(size, alignment); return size; }