ULONG BtrCopyCodeViewRecord( __in PVOID Base, __out PCV_INFO_PDB70 CvRecord, __out PULONG NameLength ) { PIMAGE_NT_HEADERS NtHeader; PIMAGE_DATA_DIRECTORY Directory; PIMAGE_DEBUG_DIRECTORY Debug; ULONG Count; PCV_INFO_PDB70 Info; ULONG i; NtHeader = ImageNtHeader(Base); Directory = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; Debug = (PIMAGE_DEBUG_DIRECTORY)PtrFromRva(Base, Directory->VirtualAddress); Count = Directory->Size / sizeof(IMAGE_DEBUG_DIRECTORY); for (i = 0; i < Count; i += 1) { if (Debug[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW) { Info = (PCV_INFO_PDB70)PtrFromRva(Base, Debug[i].AddressOfRawData); CvRecord->CvSignature = Info->CvSignature; CvRecord->Signature = Info->Signature; CvRecord->Age = Info->Age; StringCchCopyA(CvRecord->PdbName, MAX_PATH, Info->PdbName); *NameLength = (ULONG)strlen(Info->PdbName) + 1; return S_OK; } } return S_FALSE; }
void ImageSectionsReader::Next(void) { if(Eof()) return; m_SectionsLeft--; m_Section = (PIMAGE_SECTION_HEADER) PtrFromRva( m_Section, sizeof(IMAGE_SECTION_HEADER) ); }
ImageSectionsReader::ImageSectionsReader(HMODULE hModule) { PIMAGE_DOS_HEADER DosHeader = ( PIMAGE_DOS_HEADER ) hModule; PIMAGE_NT_HEADERS NtHeader; m_hModule = hModule; m_SectionsLeft = 0; NtHeader = (PIMAGE_NT_HEADERS) PtrFromRva( DosHeader, DosHeader->e_lfanew ); if( IMAGE_NT_SIGNATURE != NtHeader->Signature ) { return; } m_SectionsLeft = NtHeader->FileHeader.NumberOfSections; m_Section = (PIMAGE_SECTION_HEADER) PtrFromRva( NtHeader, sizeof(IMAGE_NT_HEADERS) ); }
ULONG BtrCreateCvRecord( __in ULONG_PTR Base, __in ULONG Size, __in ULONG Timestamp, __out PBTR_CV_RECORD CvRecord ) { PIMAGE_NT_HEADERS NtHeader; PIMAGE_DATA_DIRECTORY Directory; PIMAGE_DEBUG_DIRECTORY Debug; ULONG Count; PCV_INFO_PDB70 Info; CHAR Name[64]; CHAR Pdb[16]; ULONG Length; ULONG i; NtHeader = ImageNtHeader((PVOID)Base); Directory = &NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DEBUG]; Debug = (PIMAGE_DEBUG_DIRECTORY)PtrFromRva(Base, Directory->VirtualAddress); Count = Directory->Size / sizeof(IMAGE_DEBUG_DIRECTORY); for (i = 0; i < Count; i += 1) { if (Debug[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW) { Info = (PCV_INFO_PDB70)PtrFromRva(Base, Debug[i].AddressOfRawData); CvRecord->CvSignature = Info->CvSignature; CvRecord->Signature = Info->Signature; CvRecord->Age = Info->Age; // // N.B. Some pdb string include a full path, we only reserved its // short name, it's ok without problem. // _splitpath_s(Info->PdbName, NULL, 0, NULL, 0, Name, 64, Pdb, 16); StringCchPrintfA(CvRecord->PdbName, 64, "%s%s", Name, Pdb); // // Compute CV_INFO_PDB70 offset // CvRecord->CvRecordOffset = FIELD_OFFSET(BTR_CV_RECORD, CvSignature); // // Compute size of CV_INFO_PDB70 // Length = (ULONG)strlen(CvRecord->PdbName) + 1; Length = FIELD_OFFSET(BTR_CV_RECORD, PdbName[Length]); CvRecord->SizeOfCvRecord = Length - CvRecord->CvRecordOffset; CvRecord->Reserved0 = 0; CvRecord->Reserved1 = 0; CvRecord->Timestamp = Timestamp; CvRecord->SizeOfImage = Size; return S_OK; } } return S_FALSE; }
DWORD ImageSectionsReader::GetStartAddress(void) { return (DWORD)PtrFromRva(m_hModule, m_Section->VirtualAddress); }
/*++ Routine Description: Replace the function pointer in a module's IAT. Parameters: Module - Module to use IAT from. ImportedModuleName - Name of imported DLL from which function is imported. ImportedProcName - Name of imported function. AlternateProc - Function to be written to IAT. OldProc - Original function. Return Value: S_OK on success. (any HRESULT) on failure. --*/ HRESULT PatchIat(HMODULE Module, PSTR ImportedModuleName, PSTR ImportedProcName, PVOID AlternateProc, PVOID *OldProc) { PIMAGE_DOS_HEADER DosHeader = ( PIMAGE_DOS_HEADER ) Module; PIMAGE_NT_HEADERS NtHeader; PIMAGE_IMPORT_DESCRIPTOR ImportDescriptor; UINT Index; // _ASSERTE( Module ); // _ASSERTE( ImportedModuleName ); // _ASSERTE( ImportedProcName ); // _ASSERTE( AlternateProc ); NtHeader = ( PIMAGE_NT_HEADERS ) PtrFromRva( DosHeader, DosHeader->e_lfanew ); if( IMAGE_NT_SIGNATURE != NtHeader->Signature ) { return HRESULT_FROM_WIN32( ERROR_BAD_EXE_FORMAT ); } ImportDescriptor = ( PIMAGE_IMPORT_DESCRIPTOR ) PtrFromRva( DosHeader, NtHeader->OptionalHeader.DataDirectory [ IMAGE_DIRECTORY_ENTRY_IMPORT ].VirtualAddress ); // // Iterate over import descriptors/DLLs. // for ( Index = 0; ImportDescriptor[ Index ].Characteristics != 0; Index++ ) { PSTR dllName = ( PSTR ) PtrFromRva( DosHeader, ImportDescriptor[ Index ].Name ); if ( 0 == _strcmpi( dllName, ImportedModuleName ) ) { // // This the DLL we are after. // PIMAGE_THUNK_DATA Thunk; PIMAGE_THUNK_DATA OrigThunk; if ( ! ImportDescriptor[ Index ].FirstThunk || ! ImportDescriptor[ Index ].OriginalFirstThunk ) { return E_INVALIDARG; } Thunk = ( PIMAGE_THUNK_DATA ) PtrFromRva( DosHeader, ImportDescriptor[ Index ].FirstThunk ); OrigThunk = ( PIMAGE_THUNK_DATA ) PtrFromRva( DosHeader, ImportDescriptor[ Index ].OriginalFirstThunk ); for ( ; OrigThunk->u1.Function != NULL; OrigThunk++, Thunk++ ) { if ( OrigThunk->u1.Ordinal & IMAGE_ORDINAL_FLAG ) { // // Ordinal import - we can handle named imports // ony, so skip it. // continue; } PIMAGE_IMPORT_BY_NAME import = ( PIMAGE_IMPORT_BY_NAME ) PtrFromRva( DosHeader, OrigThunk->u1.AddressOfData ); if ( 0 == strcmp( ImportedProcName, ( char* ) import->Name ) ) { // // Proc found, patch it. // DWORD junk; MEMORY_BASIC_INFORMATION thunkMemInfo; // // Make page writable. // VirtualQuery( Thunk, &thunkMemInfo, sizeof( MEMORY_BASIC_INFORMATION ) ); if ( ! VirtualProtect( thunkMemInfo.BaseAddress, thunkMemInfo.RegionSize, PAGE_EXECUTE_READWRITE, &thunkMemInfo.Protect ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } // // Replace function pointers (non-atomically). // if ( OldProc ) { *OldProc = ( PVOID ) ( DWORD_PTR ) Thunk->u1.Function; } #ifdef _WIN64 Thunk->u1.Function = ( ULONGLONG ) ( DWORD_PTR ) AlternateProc; #else Thunk->u1.Function = ( DWORD ) ( DWORD_PTR ) AlternateProc; #endif // // Restore page protection. // if ( ! VirtualProtect( thunkMemInfo.BaseAddress, thunkMemInfo.RegionSize, thunkMemInfo.Protect, &junk ) ) { return HRESULT_FROM_WIN32( GetLastError() ); } return S_OK; } } // // Import not found. // return HRESULT_FROM_WIN32( ERROR_PROC_NOT_FOUND ); } } // // DLL not found. // return HRESULT_FROM_WIN32( ERROR_MOD_NOT_FOUND ); }