阿杰 发表于 2010-1-27 20:56:06

ICO资源提取

DWORD GetRawOfFile(char *pImage, DWORD dwRVA)
{
PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER )pImage;
PIMAGE_NT_HEADERS pNtHeads = (PIMAGE_NT_HEADERS)((DWORD)pDos + pDos->e_lfanew);

DWORD NumOfSection = pNtHeads->FileHeader.NumberOfSections;
PIMAGE_SECTION_HEADER pSectionHead = (PIMAGE_SECTION_HEADER )(sizeof(IMAGE_FILE_HEADER) + 4 + pNtHeads->FileHeader.SizeOfOptionalHeader + (DWORD)pNtHeads);
DWORD RawOfEntryPoint = 0;
DWORD RawinSection = 0;
WORD count=0;
while(count<NumOfSection)
{
if((dwRVA >= pSectionHead->VirtualAddress)
&&(dwRVA < pSectionHead->VirtualAddress+pSectionHead->Misc.VirtualSize))
{
RawinSection=dwRVA-pSectionHead->VirtualAddress;
RawOfEntryPoint=pSectionHead->PointerToRawData+RawinSection;
break;
}
pSectionHead++;
count++;
}

if (RawOfEntryPoint == 0)
{
::MessageBox(NULL, "PE file is a error file", NULL, NULL);
return 0;
}
return RawOfEntryPoint;

}


//2字节对齐
#pragma pack (2)

typedef struct _ICONDIRENTRY
{
BYTE bWidth; //宽 16或32
BYTE bHeight; //高 16或32
BYTE bColorCount; //Number of colors in image (0 if >=8bpp)
BYTE bReserved; //保留,必须是0
WORD wPlanes; //图片的位面数
WORD wBitCount; //每个象素的位数
DWORD dwBytesInRes; //图像字节长度
DWORD dwImageOffset; //图像文件偏移
} ICONDIRENTRY;
//ICON文件头,22字节

typedef struct _ICONDIR
{
WORD idReserved; //保留,必须是00 00
WORD idType; //文件类型,1表示icon即01 00
WORD idCount; //图片个数,1个即01 00

//in fact data blow is a struct named ICONDIRENTRY
BYTE bWidth; //宽 16或32
BYTE bHeight; //高 16或32
BYTE bColorCount; //Number of colors in image (0 if >=8bpp)
BYTE bReserved; //保留,必须是0
WORD wPlanes; //图片的位面数
WORD wBitCount; //每个象素的位数
DWORD dwBytesInRes; //图像字节长度
DWORD dwImageOffset; //图像文件偏移
} ICONDIR;


void CGetICODlg::OnOK()
{
HANDLE hFile = ::CreateFile("a.exe", GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
AfxMessageBox("Open error");
return ;
}
DWORD dwFileSize = ::GetFileSize(hFile, NULL);
if (dwFileSize == 0)
{
AfxMessageBox("Error file!");
return ;
}
char *pImage = new char;
if (pImage == NULL)
{
return ;
}
memset(pImage, 0, dwFileSize);
DWORD dwBeRead = 0;
ReadFile(hFile, pImage, dwFileSize, &dwBeRead, NULL);
if (dwBeRead != dwFileSize)
{
AfxMessageBox("Read Error!");
return ;
}

PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER )pImage;
PIMAGE_NT_HEADERS pNtHeads = (PIMAGE_NT_HEADERS)((DWORD)pDos + pDos->e_lfanew);

if (pDos->e_magic != 0x5A4d)
{
return ;
}
if (pNtHeads->Signature != 0x00004550)
{
return ;
}


//DataDirectory的第二项是资源表
if ( pNtHeads->OptionalHeader.DataDirectory.VirtualAddress == 0 &&
pNtHeads->OptionalHeader.DataDirectory.Size == 0 )
{//资源表为空
return;
}

//资源开始的RVA
DWORD dwOffset = GetRawOfFile(pImage, pNtHeads->OptionalHeader.DataDirectory.VirtualAddress);

PIMAGE_RESOURCE_DIRECTORY pFirstDir = (PIMAGE_RESOURCE_DIRECTORY )(dwOffset + pImage);
PIMAGE_RESOURCE_DIRECTORY_ENTRY pFirstDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY )(pFirstDir + 1);

PIMAGE_RESOURCE_DIRECTORY pSecondDir = NULL;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pSecondDirEntry = NULL;

PIMAGE_RESOURCE_DIRECTORY pThirdDir = NULL;
PIMAGE_RESOURCE_DIRECTORY_ENTRY pThirdDirEntry = NULL;

PIMAGE_RESOURCE_DIRECTORY_ENTRY pTempDirEntry = NULL;
PIMAGE_RESOURCE_DATA_ENTRY pSourceData = NULL;
UINT uNum1 = pFirstDir->NumberOfIdEntries + pFirstDir->NumberOfNamedEntries ;
//第一层
for (UINT i=0 ;i<uNum1; i++)
{
pTempDirEntry = pFirstDirEntry + i;
if (pTempDirEntry->Id != 3)
{
continue;
}
//id == 3 图标资源
pSecondDir = (PIMAGE_RESOURCE_DIRECTORY)(pTempDirEntry->OffsetToDirectory + (DWORD)pFirstDir);
pSecondDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pSecondDir + 1);
UINT uNum2 = pSecondDir->NumberOfIdEntries + pSecondDir->NumberOfNamedEntries;
//第二层
for (UINT j=0; j<uNum2; j++)
{
pTempDirEntry = pSecondDirEntry + j;
if (pTempDirEntry->DataIsDirectory == 0x01)
{//第三层
pThirdDir = (PIMAGE_RESOURCE_DIRECTORY)(pTempDirEntry->OffsetToDirectory + (DWORD)pFirstDir);
pThirdDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pThirdDir + 1);
ASSERT(pThirdDir->NumberOfIdEntries + pThirdDir->NumberOfNamedEntries == 1);
pSourceData = (PIMAGE_RESOURCE_DATA_ENTRY)(pThirdDirEntry->OffsetToDirectory + (DWORD)pFirstDir);
char szText = {0};
sprintf(szText, "RVA:%.8X FileOffset:%.8X Size:%.8X", pSourceData->OffsetToData, GetRawOfFile(pImage, pSourceData->OffsetToData), pSourceData->Size);
m_list.AddString(szText);
static int iName = 0;
sprintf(szText, "ICOFILE_%d.ico", ++iName);
HANDLE hFileico = ::CreateFile(szText, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, NULL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
::MessageBox(NULL, "Open error", NULL, NULL);
return ;
}
ICONDIR tempiCon;
tempiCon.idReserved = 0;
tempiCon.idCount = 1;
tempiCon.idType = 1;
tempiCon.bWidth = 0x10;
tempiCon.bHeight = 0x10;
tempiCon.wPlanes = 0x0010;
tempiCon.dwImageOffset = 22;
tempiCon.dwBytesInRes = pSourceData->Size;

DWORD dwWrite = 0;
WriteFile(hFileico, &tempiCon, sizeof(tempiCon), &dwWrite, NULL);
if (dwWrite != sizeof(tempiCon))
{
::MessageBox(NULL, "write error", NULL, NULL);
return ;
}

WriteFile(hFileico, (void *)(GetRawOfFile(pImage, pSourceData->OffsetToData) + (DWORD)pImage), pSourceData->Size, &dwWrite, NULL);
if (dwWrite != pSourceData->Size)
{
::MessageBox(NULL, "write error", NULL, NULL);
return ;
}
CloseHandle(hFileico);
}
}

}
CloseHandle(hFile);
}
页: [1]
查看完整版本: ICO资源提取