找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 6502|回复: 0

[分享] ICO资源提取

[复制链接]

1214

主题

352

回帖

11

精华

管理员

菜鸟

积分
93755

贡献奖关注奖人气王精英奖乐于助人勋章

发表于 2010-1-27 20:56:06 | 显示全部楼层 |阅读模式
  1. DWORD GetRawOfFile(char *pImage, DWORD dwRVA)
  2. {
  3. PIMAGE_DOS_HEADER pDos = (PIMAGE_DOS_HEADER )pImage;
  4. PIMAGE_NT_HEADERS pNtHeads = (PIMAGE_NT_HEADERS)((DWORD)pDos + pDos->e_lfanew);

  5. DWORD NumOfSection = pNtHeads->FileHeader.NumberOfSections;
  6. PIMAGE_SECTION_HEADER pSectionHead = (PIMAGE_SECTION_HEADER )(sizeof(IMAGE_FILE_HEADER) + 4 + pNtHeads->FileHeader.SizeOfOptionalHeader + (DWORD)pNtHeads);
  7. DWORD RawOfEntryPoint = 0;
  8. DWORD RawinSection = 0;
  9. WORD count=0;
  10. while(count<NumOfSection)
  11. {
  12. if((dwRVA >= pSectionHead->VirtualAddress)
  13. &&(dwRVA < pSectionHead->VirtualAddress+pSectionHead->Misc.VirtualSize))
  14. {
  15. RawinSection=dwRVA-pSectionHead->VirtualAddress;
  16. RawOfEntryPoint=pSectionHead->PointerToRawData+RawinSection;
  17. break;
  18. }
  19. pSectionHead++;
  20. count++;
  21. }

  22. if (RawOfEntryPoint == 0)
  23. {
  24. ::MessageBox(NULL, "PE file is a error file", NULL, NULL);
  25. return 0;
  26. }
  27. return RawOfEntryPoint;

  28. }


  29. //2字节对齐
  30. #pragma pack (2)

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

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

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


  58. void CGetICODlg::OnOK()
  59. {
  60. HANDLE hFile = ::CreateFile("a.exe", GENERIC_READ, NULL, NULL, OPEN_EXISTING, NULL, NULL);
  61. if (hFile == INVALID_HANDLE_VALUE)
  62. {
  63. AfxMessageBox("Open error");
  64. return ;
  65. }
  66. DWORD dwFileSize = ::GetFileSize(hFile, NULL);
  67. if (dwFileSize == 0)
  68. {
  69. AfxMessageBox("Error file!");
  70. return ;
  71. }
  72. char *pImage = new char[dwFileSize];
  73. if (pImage == NULL)
  74. {
  75. return ;
  76. }
  77. memset(pImage, 0, dwFileSize);
  78. DWORD dwBeRead = 0;
  79. ReadFile(hFile, pImage, dwFileSize, &dwBeRead, NULL);
  80. if (dwBeRead != dwFileSize)
  81. {
  82. AfxMessageBox("Read Error!");
  83. return ;
  84. }

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

  87. if (pDos->e_magic != 0x5A4d)
  88. {
  89. return ;
  90. }
  91. if (pNtHeads->Signature != 0x00004550)
  92. {
  93. return ;
  94. }


  95. //DataDirectory的第二项是资源表
  96. if ( pNtHeads->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].VirtualAddress == 0 &&
  97. pNtHeads->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE].Size == 0 )
  98. {//资源表为空
  99. return;
  100. }

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

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

  105. PIMAGE_RESOURCE_DIRECTORY pSecondDir = NULL;
  106. PIMAGE_RESOURCE_DIRECTORY_ENTRY pSecondDirEntry = NULL;

  107. PIMAGE_RESOURCE_DIRECTORY pThirdDir = NULL;
  108. PIMAGE_RESOURCE_DIRECTORY_ENTRY pThirdDirEntry = NULL;

  109. PIMAGE_RESOURCE_DIRECTORY_ENTRY pTempDirEntry = NULL;
  110. PIMAGE_RESOURCE_DATA_ENTRY pSourceData = NULL;
  111. UINT uNum1 = pFirstDir->NumberOfIdEntries + pFirstDir->NumberOfNamedEntries ;
  112. //第一层
  113. for (UINT i=0 ;i<uNum1; i++)
  114. {
  115. pTempDirEntry = pFirstDirEntry + i;
  116. if (pTempDirEntry->Id != 3)
  117. {
  118. continue;
  119. }
  120. //id == 3 图标资源
  121. pSecondDir = (PIMAGE_RESOURCE_DIRECTORY)(pTempDirEntry->OffsetToDirectory + (DWORD)pFirstDir);
  122. pSecondDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pSecondDir + 1);
  123. UINT uNum2 = pSecondDir->NumberOfIdEntries + pSecondDir->NumberOfNamedEntries;
  124. //第二层
  125. for (UINT j=0; j<uNum2; j++)
  126. {
  127. pTempDirEntry = pSecondDirEntry + j;
  128. if (pTempDirEntry->DataIsDirectory == 0x01)
  129. {//第三层
  130. pThirdDir = (PIMAGE_RESOURCE_DIRECTORY)(pTempDirEntry->OffsetToDirectory + (DWORD)pFirstDir);
  131. pThirdDirEntry = (PIMAGE_RESOURCE_DIRECTORY_ENTRY)(pThirdDir + 1);
  132. ASSERT(pThirdDir->NumberOfIdEntries + pThirdDir->NumberOfNamedEntries == 1);
  133. pSourceData = (PIMAGE_RESOURCE_DATA_ENTRY)(pThirdDirEntry->OffsetToDirectory + (DWORD)pFirstDir);
  134. char szText[100] = {0};
  135. sprintf(szText, "RVA:%.8X FileOffset:%.8X Size:%.8X", pSourceData->OffsetToData, GetRawOfFile(pImage, pSourceData->OffsetToData), pSourceData->Size);
  136. m_list.AddString(szText);
  137. static int iName = 0;
  138. sprintf(szText, "ICOFILE_%d.ico", ++iName);
  139. HANDLE hFileico = ::CreateFile(szText, GENERIC_WRITE, NULL, NULL, CREATE_ALWAYS, NULL, NULL);
  140. if (hFile == INVALID_HANDLE_VALUE)
  141. {
  142. ::MessageBox(NULL, "Open error", NULL, NULL);
  143. return ;
  144. }
  145. ICONDIR tempiCon;
  146. tempiCon.idReserved = 0;
  147. tempiCon.idCount = 1;
  148. tempiCon.idType = 1;
  149. tempiCon.bWidth = 0x10;
  150. tempiCon.bHeight = 0x10;
  151. tempiCon.wPlanes = 0x0010;
  152. tempiCon.dwImageOffset = 22;
  153. tempiCon.dwBytesInRes = pSourceData->Size;

  154. DWORD dwWrite = 0;
  155. WriteFile(hFileico, &tempiCon, sizeof(tempiCon), &dwWrite, NULL);
  156. if (dwWrite != sizeof(tempiCon))
  157. {
  158. ::MessageBox(NULL, "write error", NULL, NULL);
  159. return ;
  160. }

  161. WriteFile(hFileico, (void *)(GetRawOfFile(pImage, pSourceData->OffsetToData) + (DWORD)pImage), pSourceData->Size, &dwWrite, NULL);
  162. if (dwWrite != pSourceData->Size)
  163. {
  164. ::MessageBox(NULL, "write error", NULL, NULL);
  165. return ;
  166. }
  167. CloseHandle(hFileico);
  168. }
  169. }

  170. }
  171. CloseHandle(hFile);
  172. }
复制代码
【VB】QQ群:1422505加的请打上VB好友
【易语言】QQ群:9531809  或 177048
【FOXPRO】QQ群:6580324  或 33659603
【C/C++/VC】QQ群:3777552
【NiceBasic】QQ群:3703755
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表