Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

449 lines
11 KiB

  1. #include "pch.h"
  2. #pragma hdrstop
  3. #include <delayimp.h>
  4. #include "peimage.h"
  5. #include "persist.h"
  6. //-------------------------------------------------------------------------
  7. // Purpose:
  8. // Returns true if the current state of the passed in
  9. // WIN32_FIND_DATA structure represents a child directory.
  10. //
  11. BOOL
  12. IsChildDir (
  13. IN const WIN32_FIND_DATAA* pFindData)
  14. {
  15. return (pFindData->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) &&
  16. (*pFindData->cFileName != '.');
  17. }
  18. BOOL
  19. FFindNextChildDir (
  20. IN HANDLE hFind,
  21. IN OUT WIN32_FIND_DATAA* pFindData)
  22. {
  23. BOOL fFound;
  24. do
  25. {
  26. fFound = !!FindNextFileA (hFind, pFindData);
  27. }
  28. while (fFound && !IsChildDir (pFindData));
  29. return fFound;
  30. }
  31. HANDLE
  32. FFindFirstChildDir (
  33. IN PCSTR pszFileSpec,
  34. OUT WIN32_FIND_DATAA* pFindData)
  35. {
  36. HANDLE hFind;
  37. hFind = FindFirstFileA (pszFileSpec, pFindData);
  38. if (INVALID_HANDLE_VALUE != hFind)
  39. {
  40. BOOL fFound = IsChildDir (pFindData);
  41. if (!fFound)
  42. {
  43. fFound = FFindNextChildDir (hFind, pFindData);
  44. }
  45. if (!fFound)
  46. {
  47. FindClose (hFind);
  48. hFind = INVALID_HANDLE_VALUE;
  49. }
  50. }
  51. return hFind;
  52. }
  53. // pszFilePath must be at least MAX_PATH characters
  54. //
  55. VOID
  56. GetIndexFilePath (
  57. OUT PWSTR pszFilePath,
  58. IN UINT cchFilePath)
  59. {
  60. GetSystemWindowsDirectory (pszFilePath, cchFilePath);
  61. wcscat (pszFilePath, L"dllquery.dat");
  62. }
  63. HRESULT
  64. HrLoadModuleTree (
  65. OUT CModuleTree* pTree)
  66. {
  67. HRESULT hr;
  68. WCHAR szIndexFile [MAX_PATH];
  69. HANDLE hFile;
  70. hr = E_UNEXPECTED;
  71. pTree->Modules.m_Granularity = 2048;
  72. // Open the index file if it exists.
  73. //
  74. GetIndexFilePath (szIndexFile, celems(szIndexFile));
  75. hFile = CreateFile (szIndexFile, GENERIC_READ, FILE_SHARE_READ,
  76. NULL, OPEN_EXISTING,
  77. FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN,
  78. NULL);
  79. if (INVALID_HANDLE_VALUE != hFile)
  80. {
  81. HANDLE hMapping;
  82. hMapping = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL);
  83. if (hMapping)
  84. {
  85. BYTE* pbBuf;
  86. UINT cbBuf;
  87. DWORD cbSizeHi;
  88. pbBuf = (BYTE*)MapViewOfFile (hMapping, FILE_MAP_READ, 0, 0, 0);
  89. if (pbBuf)
  90. {
  91. cbBuf = GetFileSize (hFile, &cbSizeHi);
  92. hr = HrLoadModuleTreeFromBuffer (pbBuf, cbBuf, pTree);
  93. UnmapViewOfFile (pbBuf);
  94. }
  95. CloseHandle (hMapping);
  96. }
  97. CloseHandle (hFile);
  98. }
  99. else
  100. {
  101. hr = HrLoadModuleTreeFromFileSystem (pTree);
  102. }
  103. return hr;
  104. }
  105. HRESULT
  106. HrLoadModuleTreeFromBuffer (
  107. IN const BYTE* pbBuf,
  108. IN ULONG cbBuf,
  109. OUT CModuleTree* pTree)
  110. {
  111. HRESULT hr = S_OK;
  112. return hr;
  113. }
  114. HRESULT
  115. HrLoadImportsForModule (
  116. IN CModule* pMod,
  117. IN CModuleTree* pTree,
  118. IN PVOID pvImage)
  119. {
  120. HRESULT hr;
  121. PIMAGE_NT_HEADERS pNtHeaders;
  122. PIMAGE_SECTION_HEADER pNtSection = NULL;
  123. PIMAGE_IMPORT_DESCRIPTOR pImportDescriptor;
  124. PIMAGE_THUNK_DATA pThunk;
  125. ULONG cbImportDescriptor;
  126. PCSTR pszImportFileName;
  127. CModule* pImportMod;
  128. hr = S_OK;
  129. pNtHeaders = RtlImageNtHeader(pvImage);
  130. Assert (pNtHeaders);
  131. pImportDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)
  132. RtlImageDirectoryEntryToData (
  133. pvImage,
  134. FALSE,
  135. IMAGE_DIRECTORY_ENTRY_IMPORT,
  136. &cbImportDescriptor);
  137. if (pImportDescriptor)
  138. {
  139. // Characteristics is zero for the terminating descriptor.
  140. //
  141. while (pImportDescriptor->Characteristics &&
  142. pImportDescriptor->FirstThunk)
  143. {
  144. Assert ((ULONG_PTR)pImportDescriptor <
  145. (ULONG_PTR)pImportDescriptor + cbImportDescriptor);
  146. Assert (pImportDescriptor->Name);
  147. pszImportFileName = (PCSTR)RtlImageRvaToVa (pNtHeaders,
  148. pvImage,
  149. pImportDescriptor->Name,
  150. &pNtSection);
  151. Assert(*pszImportFileName);
  152. // Add this import to the list if we don't already have it
  153. // present.
  154. //
  155. hr = pTree->Modules.HrInsertNewModule (
  156. pszImportFileName,
  157. 0,
  158. INS_IGNORE_IF_DUP | INS_SORTED,
  159. &pImportMod);
  160. if (S_OK == hr)
  161. {
  162. PSZ Function = NULL;
  163. hr = pTree->HrAddEntry (pMod, pImportMod, MTE_DEFAULT);
  164. if (S_OK != hr)
  165. {
  166. break;
  167. }
  168. pThunk = (PIMAGE_THUNK_DATA)RtlImageRvaToVa (pNtHeaders,
  169. pvImage,
  170. pImportDescriptor->OriginalFirstThunk,
  171. &pNtSection);
  172. if (!IMAGE_SNAP_BY_ORDINAL(pThunk->u1.Ordinal))
  173. {
  174. PIMAGE_IMPORT_BY_NAME ImportName =
  175. (PIMAGE_IMPORT_BY_NAME)RtlImageRvaToVa (pNtHeaders,
  176. pvImage,
  177. pThunk->u1.AddressOfData,
  178. &pNtSection);
  179. Function = (PSZ)ImportName->Name;
  180. }
  181. pThunk++;
  182. if (!pThunk->u1.AddressOfData)
  183. {
  184. printf("%-16s only imports 1 function from %s (%s)\n",
  185. pMod->m_pszFileName,
  186. pImportMod->m_pszFileName,
  187. Function);
  188. }
  189. }
  190. pImportDescriptor++;
  191. }
  192. }
  193. return hr;
  194. }
  195. HRESULT
  196. HrLoadDelayImportsForModule (
  197. IN CModule* pMod,
  198. IN CModuleTree* pTree,
  199. IN PVOID pvImage)
  200. {
  201. HRESULT hr;
  202. PIMAGE_NT_HEADERS pNtHeaders;
  203. PIMAGE_SECTION_HEADER pNtSection = NULL;
  204. PImgDelayDescr pDelayDescriptor;
  205. ULONG cbDelayDescriptor;
  206. PCSTR pszImportFileName;
  207. CModule* pImportMod;
  208. hr = S_OK;
  209. pNtHeaders = RtlImageNtHeader(pvImage);
  210. Assert (pNtHeaders);
  211. pDelayDescriptor = (PImgDelayDescr)
  212. RtlImageDirectoryEntryToData (
  213. pvImage,
  214. FALSE,
  215. IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT,
  216. &cbDelayDescriptor);
  217. if (pDelayDescriptor)
  218. {
  219. Assert (pNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT].Size);
  220. ULONG_PTR ImageBase = pNtHeaders->OptionalHeader.ImageBase;
  221. // Characteristics is zero for the terminating descriptor.
  222. //
  223. while (pDelayDescriptor->pIAT &&
  224. pDelayDescriptor->pINT &&
  225. pDelayDescriptor->phmod)
  226. {
  227. Assert ((ULONG_PTR)pDelayDescriptor <
  228. (ULONG_PTR)pDelayDescriptor + cbDelayDescriptor);
  229. Assert (pDelayDescriptor->szName);
  230. pNtSection = IMAGE_FIRST_SECTION (pNtHeaders);
  231. ULONG_PTR Rva = (ULONG_PTR)pDelayDescriptor->szName;
  232. ULONG_PTR Base = 0;
  233. for (INT i = 0; i < pNtHeaders->FileHeader.NumberOfSections; i++)
  234. {
  235. if ((Rva >= (ImageBase + pNtSection->VirtualAddress)) &&
  236. (Rva < (ImageBase + pNtSection->VirtualAddress + pNtSection->SizeOfRawData)))
  237. {
  238. Base = (ULONG_PTR)pvImage
  239. + pNtSection->PointerToRawData
  240. - pNtSection->VirtualAddress - ImageBase;
  241. break;
  242. }
  243. pNtSection++;
  244. }
  245. if (0 == Base)
  246. {
  247. break;
  248. }
  249. pszImportFileName = (PCSTR)(Base + Rva);
  250. Assert(*pszImportFileName);
  251. // Add this import to the list if we don't already have it
  252. // present.
  253. //
  254. hr = pTree->Modules.HrInsertNewModule (
  255. pszImportFileName,
  256. 0,
  257. INS_IGNORE_IF_DUP | INS_SORTED,
  258. &pImportMod);
  259. if (S_OK == hr)
  260. {
  261. hr = pTree->HrAddEntry (pMod, pImportMod, MTE_DELAY_LOADED);
  262. if (S_OK != hr)
  263. {
  264. break;
  265. }
  266. }
  267. pDelayDescriptor++;
  268. }
  269. }
  270. return hr;
  271. }
  272. HRESULT
  273. HrLoadModuleTreeFromCurrentDirectory (
  274. OUT CModuleTree* pTree)
  275. {
  276. HRESULT hr;
  277. HANDLE hFind;
  278. WIN32_FIND_DATAA FindData;
  279. hr = S_OK;
  280. // Enumerate all of the files in the current directory.
  281. //
  282. hFind = FindFirstFileA ("*", &FindData);
  283. if (INVALID_HANDLE_VALUE != hFind)
  284. {
  285. CPeImage PeImage;
  286. ZeroMemory (&PeImage, sizeof(PeImage));
  287. do
  288. {
  289. CModule* pMod;
  290. // Don't process directories.
  291. //
  292. if (FindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
  293. {
  294. continue;
  295. }
  296. hr = PeImage.HrOpenFile (FindData.cFileName);
  297. if (S_OK == hr)
  298. {
  299. // Add this module to the list if we don't already have it
  300. // present. (We can already have it if, while procesing the
  301. // imports of an earlier module, this module was one of those
  302. // imports.)
  303. //
  304. hr = pTree->Modules.HrInsertNewModule (
  305. FindData.cFileName,
  306. FindData.nFileSizeLow,
  307. INS_IGNORE_IF_DUP | INS_SORTED,
  308. &pMod);
  309. if (S_OK == hr)
  310. {
  311. (VOID) HrLoadImportsForModule (
  312. pMod, pTree, PeImage.m_pvImage);
  313. (VOID) HrLoadDelayImportsForModule (
  314. pMod, pTree, PeImage.m_pvImage);
  315. }
  316. PeImage.CloseFile ();
  317. }
  318. }
  319. while (FindNextFileA (hFind, &FindData));
  320. FindClose (hFind);
  321. }
  322. // Now recurse into subdirectories.
  323. //
  324. hFind = FFindFirstChildDir("*", &FindData);
  325. if (INVALID_HANDLE_VALUE != hFind)
  326. {
  327. do
  328. {
  329. fprintf(stderr, "Processing %s...\n", FindData.cFileName);
  330. if (SetCurrentDirectoryA (FindData.cFileName))
  331. {
  332. (VOID) HrLoadModuleTreeFromCurrentDirectory (pTree);
  333. SetCurrentDirectoryA ("..");
  334. }
  335. }
  336. while (FFindNextChildDir (hFind, &FindData));
  337. FindClose (hFind);
  338. }
  339. return hr;
  340. }
  341. HRESULT
  342. HrLoadModuleTreeFromFileSystem (
  343. OUT CModuleTree* pTree)
  344. {
  345. HRESULT hr;
  346. WCHAR szCurrentDir [MAX_PATH];
  347. WCHAR szSystemDir [MAX_PATH];
  348. // Save the current directory because we will be changing it.
  349. //
  350. GetCurrentDirectory (celems(szCurrentDir), szCurrentDir);
  351. GetSystemWindowsDirectory (szSystemDir, celems(szSystemDir));
  352. //wcscat (szSystemDir, L"\\system32");
  353. SetCurrentDirectory (szSystemDir);
  354. hr = HrLoadModuleTreeFromCurrentDirectory (pTree);
  355. SetCurrentDirectory (szCurrentDir);
  356. fprintf(stderr, "Processed %d PE modules. (%d total imports)\n",
  357. pTree->Modules.size(),
  358. pTree->size());
  359. return hr;
  360. }