See More

// PeLoad.cpp : Defines the entry point for the console application. // /* ʱ¼ä£º2011Äê2ÔÂ12ÈÕ ×÷Õߣºangelkiss º¯Êý¹¦ÄÜ£ºReload And Run³ÌÐòĿ¼ÏµÄtest.exe³ÌÐò */ #include "stdafx.h" #include #include //#include "ntimage.h" #include "PeLoad.h" using namespace std; int main(int argc, char* argv[]) { MessageBox( NULL, "Angelkiss", NULL, MB_OK ); //´ò¿ªtest.exeÎļþ£¬²¢¶ÁÈ¡ÎļþÄÚÈÝ char pFilePath[256] = {0}; GetModuleFileName(NULL,pFilePath,_countof(pFilePath)); #ifdef _DEBUG strcpy(&strrchr(pFilePath,'\\')[1],"dllD.dll"); #else strcpy(&strrchr(pFilePath,'\\')[1],"dll.dll"); #endif HANDLE hFile = CreateFile( pFilePath, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL ); DWORD dwErr = GetLastError(); if( hFile == INVALID_HANDLE_VALUE ) { cout<<"´ò¿ªÎļþʧ°Ü"<e_lfanew + (DWORD)pImageBuffer))->OptionalHeader.AddressOfEntryPoint; //DWORD dwFuncStart = (DWORD)pImageBuffer + 0x1080; cout<e_lfanew ); //»ñÈ¡RtlImageDirectoryEntryToDataº¯ÊýµØÖ· HMODULE hNtDll = LoadLibrary( "ntdll.dll" ); PRTLIMAGEDIRECTORYENTRYTODATA pRtlImageDirectoryEntryToData = (PRTLIMAGEDIRECTORYENTRYTODATA)GetProcAddress( hNtDll, "RtlImageDirectoryEntryToData" ); if( pRtlImageDirectoryEntryToData == NULL ) { cout<<"»ñÈ¡RtlImageDirectoryEntryToDataº¯ÊýµØÖ·Ê§°Ü"<Name != 0 ) { PIMAGE_THUNK_DATA32 pFirstThunkData = (PIMAGE_THUNK_DATA32)( (ULONG)pBaseAddr + pImportDescriptor->FirstThunk); PIMAGE_THUNK_DATA32 pOriginalThunkData = (PIMAGE_THUNK_DATA32)( (ULONG)pBaseAddr + pImportDescriptor->OriginalFirstThunk); //»ñÈ¡dllÃû char *pDllName = (char*)( (ULONG)pBaseAddr + pImportDescriptor->Name ); cout<<"´¦ÀíÊäÈë±í£¬DLLÃû:"<u1.Ordinal != 0 ) && !( pOriginalThunkData->u1.Ordinal&0x80000000) ) { PIMAGE_IMPORT_BY_NAME pImageImportByName = (PIMAGE_IMPORT_BY_NAME)( (ULONG)pBaseAddr + (ULONG)(pOriginalThunkData->u1.AddressOfData) ); char *pFuncName = (char*)(&pImageImportByName->Name); DWORD dwFuncAddr = GetFuncAddrFromModule( pDllName, pFuncName ); cout<<"\t\tº¯ÊýÃû:"<AddressOfNames); PUSHORT pNameOrdinalTableBase = (PUSHORT)(dwModuleBase + pExportDescriptor->AddressOfNameOrdinals); DWORD dwLow = 0; DWORD dwHigh = pExportDescriptor->NumberOfNames - 1; DWORD dwMid = 0; while( dwLow <= dwHigh ) { dwMid = (dwLow + dwHigh) >> 1; LONG lRes = strcmp( (char*)(dwModuleBase+pNameTableBase[dwMid]), pFuncName ); if( lRes > 0 ) dwHigh = dwMid - 1; else if(lRes < 0 ) dwLow = dwMid + 1; else break; } if( dwLow > dwHigh ) { cout<<"²éÕÒº¯Êýʧ°Ü"< pExportDescriptor->NumberOfFunctions ) { cout<<"»ñÈ¡µÄº¯ÊýÐòºÅ´íÎó"<AddressOfFunctions); DWORD dwFuncAddr = dwModuleBase + pAddressTableBase[dwOridinalName]; return dwFuncAddr; } /* º¯ÊýÃèÊö£º½«¶Á³öµÄÎļþÄÚÈݰ´ÄÚ´æ¶ÔÆë¸ñʽ¶ÔÆë ²ÎÊý£º pFileBuffer:ÎļþÄÚÈÝ»º³å ·µ»ØÖµ£ºÄÚ´æ¶ÔÆëºóµÄÎļþ»º³å */ PVOID AlignFileToMem( PVOID pFileBuffer, DWORD dwFileSize ) { //ÕâÀïÓÐÁ½ÖÖ·½·¨¿ÉÒÔ¼ÆËã¶ÔÆëºóµÄÎļþ´óС£º±£´æÔÚ_IMAGE_NT_HEADERS½á¹¹ÖУ¬È»ºó±éÀúÿ¸ö½ÚÍ·£¬¸ù¾Ý½ÚÍ·ÖеĽÚÄÚ´æÆ«ÒÆ¿½±´ÎļþÄÚÈÝ //µ«ÓÐʱ½Ú±íÖÐµÄ½ÚÆ«ÒƲ»×¼È·£¬ËùÒÔÎÒÃÇÕâÀï¸ù¾ÝPEÎļþ¸ñʽ×Ô¼º¼ÆËã //¼ÆËãÎļþÄÚ´æ¶ÔÆëºóµÄ´óС DWORD dwSize = GetTotalImageSize( pFileBuffer, dwFileSize ); if( dwSize == 0 ) { cout<<"¼ÆËãÎļþ¶ÔÆëºó´óСʧ°Ü"<e_lfanew ); PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)( (ULONG)pNtHeaders + sizeof(IMAGE_NT_HEADERS) ); DWORD dwCpySize = pNtHeaders->OptionalHeader.SizeOfHeaders; for( DWORD dwIndex = 0; dwIndex < pNtHeaders->FileHeader.NumberOfSections; dwIndex++ ) { if( (pSectionHeader[dwIndex].PointerToRawData) != 0 && (pSectionHeader[dwIndex].PointerToRawDataOptionalHeader.SizeOfHeaders, pNtHeaders->OptionalHeader.SectionAlignment )); for( DWORD dwIndex = 0; dwIndex < pNtHeaders->FileHeader.NumberOfSections; dwIndex++ ) { if( pSectionHeader[dwIndex].VirtualAddress != 0 ) pt = (PVOID)( (DWORD)pImageBuffer + pSectionHeader[dwIndex].VirtualAddress); if( pSectionHeader[dwIndex].SizeOfRawData != 0 ) { memcpy( pt, (PVOID)( (DWORD)pFileBuffer + pSectionHeader[dwIndex].PointerToRawData), pSectionHeader[dwIndex].SizeOfRawData ); if( pSectionHeader[dwIndex].SizeOfRawData > pSectionHeader[dwIndex].Misc.VirtualSize ) pt = (PVOID)( (ULONG)pt + GetAlignSize(pSectionHeader[dwIndex].SizeOfRawData, pNtHeaders->OptionalHeader.SectionAlignment ) ); else pt = (PVOID)( (ULONG)pt + GetAlignSize(pSectionHeader[dwIndex].Misc.VirtualSize, pNtHeaders->OptionalHeader.SectionAlignment ) ); } else pt = (PVOID)( (ULONG)pt + GetAlignSize(pSectionHeader[dwIndex].Misc.VirtualSize, pNtHeaders->OptionalHeader.SectionAlignment ) ); } return pImageBuffer; } /* º¯Êý˵Ã÷£º¼ÆËãÎļþÄÚ´æ¶ÔÆëºóµÄ´óС,Ê×ÏȼÆËãÎļþÍ·¶ÔÆëÖµ´óС£¬ÔÙ¼ÆËãÿ½ÚµÄ¶ÔÆëÖµ´óС£ºÈç¹û½Ú±íÖеÄVirtualAddress·Ç¿Õ£¬VirtualSize·Ç0£¬Ôò°´VirtualSizeÖµ¼ÆËã¶ÔÆëÖµ //Èç¹ûΪ0£¬Ôò°´SizeOfRawData¼ÆËã¶ÔÆëÖµ£»·´Ö®£¬Èç¹ûVirtualAddressΪ¿Õ£¬Ë­´ó¾Í°´Ë­¼ÆËã¶ÔÆëÖµ ²ÎÊý£º pFileBuffer:ÎļþÄÚÈÝÆðʼµØÖ· ·µ»ØÖµ£º·µ»ØÎļþÄÚÈݰ´ÄÚ´æ¶ÔÆëºóµÄ´óС */ DWORD GetTotalImageSize( PVOID pFileBuffer, DWORD dwFileSize ) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pFileBuffer; PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)( (ULONG)pFileBuffer + pDosHeader->e_lfanew ); DWORD dwTotalSize = GetAlignSize( pNtHeaders->OptionalHeader.SizeOfHeaders, pNtHeaders->OptionalHeader.SectionAlignment ); PIMAGE_SECTION_HEADER pSectionHeader = (PIMAGE_SECTION_HEADER)( (ULONG)pNtHeaders + sizeof(IMAGE_NT_HEADERS) ); DWORD dwSectionCnt = pNtHeaders->FileHeader.NumberOfSections; for( DWORD dwIndex = 0; dwIndex < dwSectionCnt; dwIndex++ ) { if( (pSectionHeader[dwIndex].PointerToRawData + pSectionHeader[dwIndex].SizeOfRawData) > dwFileSize ) { cout<<"Îļþ½Ú±íÐÅÏ¢ÓÉÎÊÌâ"<OptionalHeader.SectionAlignment ); else dwTotalSize += GetAlignSize( pSectionHeader[dwIndex].SizeOfRawData, pNtHeaders->OptionalHeader.SectionAlignment ); } else { if( pSectionHeader[dwIndex].SizeOfRawData > pSectionHeader[dwIndex].Misc.VirtualSize ) dwTotalSize += GetAlignSize( pSectionHeader[dwIndex].SizeOfRawData, pNtHeaders->OptionalHeader.SectionAlignment ); else dwTotalSize += GetAlignSize( pSectionHeader[dwIndex].Misc.VirtualSize, pNtHeaders->OptionalHeader.SectionAlignment ); } } return dwTotalSize; } DWORD GetAlignSize( DWORD dwSize, DWORD dwAlignSize ) { return (dwSize+dwAlignSize-1)/dwAlignSize*dwAlignSize; } /* º¯Êý˵Ã÷£º´¦Àí½ÚÄÚ´æ¶ÔÆëºóÎļþµÄÖØ¶¨Î»±í ²ÎÊý£º pImageBuffer:¶ÔÆëºóµÄÎļþ»ùÖ· */ bool ProcessRelocTable( PVOID pImageBuffer ) { PIMAGE_DOS_HEADER pDosHeader = (PIMAGE_DOS_HEADER)pImageBuffer; PIMAGE_NT_HEADERS pNtHeaders = (PIMAGE_NT_HEADERS)( (ULONG)pDosHeader + pDosHeader->e_lfanew ); //»ñÈ¡RtlImageDirectoryEntryToDataº¯ÊýµØÖ· HMODULE hNtDll = LoadLibrary( "ntdll.dll" ); PRTLIMAGEDIRECTORYENTRYTODATA pRtlImageDirectoryEntryToData = (PRTLIMAGEDIRECTORYENTRYTODATA)GetProcAddress( hNtDll, "RtlImageDirectoryEntryToData" ); if( pRtlImageDirectoryEntryToData == NULL ) { cout<<"»ñÈ¡RtlImageDirectoryEntryToDataº¯ÊýµØÖ·Ê§°Ü"<OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size; DWORD dwDelta = (DWORD)pImageBuffer - pNtHeaders->OptionalHeader.ImageBase; while( dwRelocaSize > 0 ) { PUSHORT pFixup = (PUSHORT)((ULONG)pRelocDescriptor + sizeof(IMAGE_BASE_RELOCATION)); for( DWORD dwIndex = 0; dwIndex< ( (pRelocDescriptor->SizeOfBlock-sizeof(IMAGE_BASE_RELOCATION))/2 ); dwIndex++ ) { if( (pFixup[dwIndex]>>12) == IMAGE_REL_BASED_HIGHLOW ) { DWORD dwAddr = (DWORD)pImageBuffer + pRelocDescriptor->VirtualAddress + (pFixup[dwIndex]&0xfff); *(PULONG)dwAddr += dwDelta; } //DWORD dwAddr = (DWORD)pImageBuffer + pRelocDescriptor->VirtualAddress + (pFixup[dwIndex]&0xfff); // *(PULONG)dwAddr += dwDelta; } dwRelocaSize -= pRelocDescriptor->SizeOfBlock; pRelocDescriptor = (PIMAGE_BASE_RELOCATION)((ULONG)pRelocDescriptor + pRelocDescriptor->SizeOfBlock); } return true; }