// 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;
}