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.

852 lines
24 KiB

  1. /////////////////////////////////////////////////////////////////////////////
  2. // FILE : client.cxx //
  3. // DESCRIPTION : Crypto API interface //
  4. // AUTHOR : //
  5. // HISTORY : //
  6. // Mar 8 1996 larrys New //
  7. // dbarlow //
  8. // //
  9. // Copyright (C) 1996 Microsoft Corporation All Rights Reserved //
  10. /////////////////////////////////////////////////////////////////////////////
  11. #include <windows.h>
  12. #include <stdlib.h>
  13. #include <stddef.h>
  14. #include <stdio.h>
  15. #include <imagehlp.h>
  16. #include "des.h"
  17. #include "modes.h"
  18. // SIG in file
  19. #define SIG_RESOURCE_NAME "#666"
  20. // MAC in file
  21. #define MAC_RESOURCE_NAME "#667"
  22. static DWORD dwMACInFileVersion = 0x100;
  23. BYTE rgbDESKey[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
  24. // The function MACs the given bytes.
  25. void MACBytes(
  26. IN DESTable *pDESKeyTable,
  27. IN BYTE *pbData,
  28. IN DWORD cbData,
  29. IN OUT BYTE *pbTmp,
  30. IN OUT DWORD *pcbTmp,
  31. IN OUT BYTE *pbMAC,
  32. IN BOOL fFinal
  33. )
  34. {
  35. DWORD cb = cbData;
  36. DWORD cbMACed = 0;
  37. while (cb)
  38. {
  39. if ((cb + *pcbTmp) < DES_BLOCKLEN)
  40. {
  41. memcpy(pbTmp + *pcbTmp, pbData + cbMACed, cb);
  42. *pcbTmp += cb;
  43. break;
  44. }
  45. else
  46. {
  47. memcpy(pbTmp + *pcbTmp, pbData + cbMACed, DES_BLOCKLEN - *pcbTmp);
  48. CBC(des, DES_BLOCKLEN, pbMAC, pbTmp, pDESKeyTable,
  49. ENCRYPT, pbMAC);
  50. cbMACed = cbMACed + (DES_BLOCKLEN - *pcbTmp);
  51. cb = cb - (DES_BLOCKLEN - *pcbTmp);
  52. *pcbTmp = 0;
  53. }
  54. }
  55. }
  56. /*
  57. void QuickTest()
  58. {
  59. BYTE rgbTmp[DES_BLOCKLEN];
  60. DWORD cbTmp = 0;
  61. BYTE rgbMAC[DES_BLOCKLEN] =
  62. {
  63. 0x12, 0x34, 0x56, 0x78, 0x90, 0xab, 0xcd, 0xef
  64. };
  65. DESTable DESKeyTable;
  66. DWORD i;
  67. BYTE rgbData[] =
  68. {
  69. 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, 0x31, 0x20,
  70. 0x4e, 0x6f, 0x77, 0x20, 0x69, 0x73, 0x20, 0x74,
  71. 0x68, 0x65, 0x20, 0x74, 0x69, 0x6d, 0x65, 0x20,
  72. 0x66, 0x6f, 0x72, 0x20, 0x00, 0x00, 0x00, 0x00
  73. };
  74. memset(&DESKeyTable, 0, sizeof(DESKeyTable));
  75. memset(rgbTmp, 0, sizeof(rgbTmp));
  76. // init the key table
  77. deskey(&DESKeyTable, rgbDESKey);
  78. MACBytes(&DESKeyTable, rgbData, sizeof(rgbData), rgbTmp,
  79. &cbTmp, rgbMAC, TRUE);
  80. printf("MAC - ");
  81. for (i = 0; i < DES_BLOCKLEN; i++)
  82. {
  83. printf("%02X", rgbMAC[i]);
  84. }
  85. printf("\n");
  86. }
  87. */
  88. // Given hInst, allocs and returns pointers to MAC pulled from
  89. // resource
  90. BOOL GetResourcePtr(
  91. IN HMODULE hInst,
  92. IN LPSTR pszRsrcName,
  93. OUT BYTE **ppbRsrcMAC,
  94. OUT DWORD *pcbRsrcMAC
  95. )
  96. {
  97. HRSRC hRsrc;
  98. BOOL fRet = FALSE;
  99. // Nab resource handle for our signature
  100. if (NULL == (hRsrc = FindResourceA(hInst, pszRsrcName,
  101. RT_RCDATA)))
  102. goto Ret;
  103. // get a pointer to the actual signature data
  104. if (NULL == (*ppbRsrcMAC = (PBYTE)LoadResource(hInst, hRsrc)))
  105. goto Ret;
  106. // determine the size of the resource
  107. if (0 == (*pcbRsrcMAC = SizeofResource(hInst, hRsrc)))
  108. goto Ret;
  109. fRet = TRUE;
  110. Ret:
  111. return fRet;
  112. }
  113. #define CSP_TO_BE_MACED_CHUNK 4096
  114. // Given hFile, reads the specified number of bytes (cbToBeMACed) from the file
  115. // and MACs these bytes. The function does this in chunks.
  116. BOOL MACBytesOfFile(
  117. IN HANDLE hFile,
  118. IN DWORD cbToBeMACed,
  119. IN DESTable *pDESKeyTable,
  120. IN BYTE *pbTmp,
  121. IN DWORD *pcbTmp,
  122. IN BYTE *pbMAC,
  123. IN BYTE fFinal
  124. )
  125. {
  126. BYTE rgbChunk[CSP_TO_BE_MACED_CHUNK];
  127. DWORD cbRemaining = cbToBeMACed;
  128. DWORD cbToRead;
  129. DWORD dwBytesRead;
  130. BOOL fRet = FALSE;
  131. //
  132. // loop over the file for the specified number of bytes
  133. // updating the hash as we go.
  134. //
  135. while (cbRemaining > 0)
  136. {
  137. if (cbRemaining < CSP_TO_BE_MACED_CHUNK)
  138. cbToRead = cbRemaining;
  139. else
  140. cbToRead = CSP_TO_BE_MACED_CHUNK;
  141. if(!ReadFile(hFile, rgbChunk, cbToRead, &dwBytesRead, NULL))
  142. goto Ret;
  143. if (dwBytesRead != cbToRead)
  144. goto Ret;
  145. MACBytes(pDESKeyTable, rgbChunk, dwBytesRead, pbTmp, pcbTmp,
  146. pbMAC, fFinal);
  147. cbRemaining -= cbToRead;
  148. }
  149. fRet = TRUE;
  150. Ret:
  151. return fRet;
  152. }
  153. BOOL MACTheFileNoSig(
  154. IN LPCSTR pszImage,
  155. IN DWORD cbImage,
  156. IN DWORD dwMACVersion,
  157. IN DWORD dwCRCOffset,
  158. OUT BYTE *pbMAC
  159. )
  160. {
  161. HMODULE hInst = 0;
  162. MEMORY_BASIC_INFORMATION MemInfo;
  163. BYTE *pbStart;
  164. BYTE rgbMAC[DES_BLOCKLEN];
  165. BYTE rgbZeroMAC[DES_BLOCKLEN + sizeof(DWORD) * 2];
  166. BYTE *pbPostCRC; // pointer to just after CRC
  167. DWORD cbCRCToMAC; // number of bytes from CRC to sig
  168. DWORD cbPostMAC; // size - (already hashed + signature size)
  169. BYTE *pbPostMAC;
  170. DWORD dwZeroCRC = 0;
  171. DWORD dwBytesRead = 0;
  172. OFSTRUCT ImageInfoBuf;
  173. HFILE hFile = HFILE_ERROR;
  174. HANDLE hMapping = NULL;
  175. DESTable DESKeyTable;
  176. BYTE rgbTmp[DES_BLOCKLEN];
  177. DWORD cbTmp = 0;
  178. BYTE *pbRsrcMAC = NULL;
  179. DWORD cbRsrcMAC;
  180. BOOL fRet = FALSE;
  181. memset(&MemInfo, 0, sizeof(MemInfo));
  182. memset(rgbMAC, 0, sizeof(rgbMAC));
  183. memset(rgbTmp, 0, sizeof(rgbTmp));
  184. // Load the file
  185. if (HFILE_ERROR == (hFile = OpenFile(pszImage, &ImageInfoBuf,
  186. OF_READ)))
  187. {
  188. goto Ret;
  189. }
  190. hMapping = CreateFileMapping((HANDLE)IntToPtr(hFile),
  191. NULL,
  192. PAGE_READONLY,
  193. 0,
  194. 0,
  195. NULL);
  196. if(hMapping == NULL)
  197. {
  198. goto Ret;
  199. }
  200. hInst = MapViewOfFile(hMapping,
  201. FILE_MAP_READ,
  202. 0,
  203. 0,
  204. 0);
  205. if(hInst == NULL)
  206. {
  207. goto Ret;
  208. }
  209. pbStart = (BYTE*)hInst;
  210. // Convert pointer to HMODULE, using the same scheme as
  211. // LoadLibrary (windows\base\client\module.c).
  212. *((ULONG_PTR*)&hInst) |= 0x00000001;
  213. // create a zero byte MAC
  214. memset(rgbZeroMAC, 0, sizeof(rgbZeroMAC));
  215. if (!GetResourcePtr(hInst, MAC_RESOURCE_NAME, &pbRsrcMAC, &cbRsrcMAC))
  216. {
  217. printf("Couldn't find MAC placeholder\n");
  218. goto Ret;
  219. }
  220. pbPostCRC = pbStart + dwCRCOffset + sizeof(DWORD);
  221. cbCRCToMAC = (DWORD)(pbRsrcMAC - pbPostCRC);
  222. pbPostMAC = pbRsrcMAC + (DES_BLOCKLEN + sizeof(DWORD) * 2);
  223. cbPostMAC = (cbImage - (DWORD)(pbPostMAC - pbStart));
  224. // copy the resource MAC
  225. if (DES_BLOCKLEN != (cbRsrcMAC - (sizeof(DWORD) * 2)))
  226. {
  227. goto Ret;
  228. }
  229. // init the key table
  230. deskey(&DESKeyTable, rgbDESKey);
  231. // MAC up to the CRC
  232. if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), dwCRCOffset, &DESKeyTable, rgbTmp,
  233. &cbTmp, rgbMAC, FALSE))
  234. {
  235. goto Ret;
  236. }
  237. // pretend CRC is zeroed
  238. MACBytes(&DESKeyTable, (BYTE*)&dwZeroCRC, sizeof(DWORD), rgbTmp, &cbTmp,
  239. rgbMAC, FALSE);
  240. if (!SetFilePointer((HANDLE)IntToPtr(hFile), sizeof(DWORD), NULL, FILE_CURRENT))
  241. {
  242. goto Ret;
  243. }
  244. // MAC from CRC to MAC resource
  245. if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), cbCRCToMAC, &DESKeyTable, rgbTmp,
  246. &cbTmp, rgbMAC, FALSE))
  247. {
  248. goto Ret;
  249. }
  250. // pretend image has zeroed MAC
  251. MACBytes(&DESKeyTable, (BYTE*)rgbZeroMAC, cbRsrcMAC, rgbTmp, &cbTmp,
  252. rgbMAC, FALSE);
  253. if (!SetFilePointer((HANDLE)IntToPtr(hFile), cbRsrcMAC, NULL, FILE_CURRENT))
  254. {
  255. goto Ret;
  256. }
  257. // MAC after the resource
  258. if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), cbPostMAC, &DESKeyTable, rgbTmp, &cbTmp,
  259. rgbMAC, TRUE))
  260. {
  261. goto Ret;
  262. }
  263. memcpy(pbMAC, rgbMAC, DES_BLOCKLEN);
  264. fRet = TRUE;
  265. Ret:
  266. if (pbRsrcMAC)
  267. FreeResource(pbRsrcMAC);
  268. if(hInst)
  269. UnmapViewOfFile(hInst);
  270. if(hMapping)
  271. CloseHandle(hMapping);
  272. if (HFILE_ERROR != hFile)
  273. _lclose(hFile);
  274. return fRet;
  275. }
  276. BOOL MACTheFileWithSig(
  277. LPCSTR pszImage,
  278. DWORD cbImage,
  279. IN DWORD dwMACVersion,
  280. IN DWORD dwCRCOffset,
  281. OUT BYTE *pbMAC
  282. )
  283. {
  284. HMODULE hInst = 0;
  285. MEMORY_BASIC_INFORMATION MemInfo;
  286. BYTE *pbRsrcMAC = NULL;
  287. DWORD cbRsrcMAC;
  288. BYTE *pbRsrcSig = NULL;
  289. DWORD cbRsrcSig;
  290. BYTE *pbStart;
  291. BYTE rgbMAC[DES_BLOCKLEN];
  292. BYTE rgbZeroMAC[DES_BLOCKLEN + sizeof(DWORD) * 2];
  293. BYTE rgbZeroSig[144];
  294. BYTE *pbPostCRC; // pointer to just after CRC
  295. DWORD cbCRCToRsrc1; // number of bytes from CRC to first rsrc
  296. DWORD cbRsrc1ToRsrc2; // number of bytes from first rsrc to second
  297. DWORD cbPostRsrc; // size - (already hashed + signature size)
  298. BYTE *pbRsrc1ToRsrc2;
  299. BYTE *pbPostRsrc;
  300. BYTE *pbZeroRsrc1;
  301. BYTE *pbZeroRsrc2;
  302. DWORD cbZeroRsrc1;
  303. DWORD cbZeroRsrc2;
  304. DWORD dwZeroCRC = 0;
  305. DWORD dwBytesRead = 0;
  306. OFSTRUCT ImageInfoBuf;
  307. HFILE hFile = HFILE_ERROR;
  308. HANDLE hMapping = NULL;
  309. DESTable DESKeyTable;
  310. BYTE rgbTmp[DES_BLOCKLEN];
  311. DWORD cbTmp = 0;
  312. BOOL fRet = FALSE;
  313. memset(&MemInfo, 0, sizeof(MemInfo));
  314. memset(rgbMAC, 0, sizeof(rgbMAC));
  315. memset(rgbTmp, 0, sizeof(rgbTmp));
  316. // Load the file
  317. if (HFILE_ERROR == (hFile = OpenFile(pszImage, &ImageInfoBuf,
  318. OF_READ)))
  319. {
  320. goto Ret;
  321. }
  322. hMapping = CreateFileMapping((HANDLE)IntToPtr(hFile),
  323. NULL,
  324. PAGE_READONLY,
  325. 0,
  326. 0,
  327. NULL);
  328. if(hMapping == NULL)
  329. {
  330. goto Ret;
  331. }
  332. hInst = MapViewOfFile(hMapping,
  333. FILE_MAP_READ,
  334. 0,
  335. 0,
  336. 0);
  337. if(hInst == NULL)
  338. {
  339. goto Ret;
  340. }
  341. pbStart = (BYTE*)hInst;
  342. // Convert pointer to HMODULE, using the same scheme as
  343. // LoadLibrary (windows\base\client\module.c).
  344. *((ULONG_PTR*)&hInst) |= 0x00000001;
  345. // the MAC resource
  346. if (!GetResourcePtr(hInst, MAC_RESOURCE_NAME, &pbRsrcMAC, &cbRsrcMAC))
  347. goto Ret;
  348. // the MAC resource
  349. if (!GetResourcePtr(hInst, SIG_RESOURCE_NAME, &pbRsrcSig, &cbRsrcSig))
  350. goto Ret;
  351. if (cbRsrcMAC < (sizeof(DWORD) * 2))
  352. goto Ret;
  353. // create a zero byte MAC
  354. memset(rgbZeroMAC, 0, sizeof(rgbZeroMAC));
  355. // create a zero byte Sig
  356. memset(rgbZeroSig, 0, sizeof(rgbZeroSig));
  357. // set up the pointers
  358. pbPostCRC = pbStart + dwCRCOffset + sizeof(DWORD);
  359. if (pbRsrcSig > pbRsrcMAC) // MAC is first Rsrc
  360. {
  361. cbCRCToRsrc1 = (DWORD)(pbRsrcMAC - pbPostCRC);
  362. pbRsrc1ToRsrc2 = pbRsrcMAC + cbRsrcMAC;
  363. cbRsrc1ToRsrc2 = (DWORD)(pbRsrcSig - pbRsrc1ToRsrc2);
  364. pbPostRsrc = pbRsrcSig + cbRsrcSig;
  365. cbPostRsrc = (cbImage - (DWORD)(pbPostRsrc - pbStart));
  366. // zero pointers
  367. pbZeroRsrc1 = rgbZeroMAC;
  368. cbZeroRsrc1 = cbRsrcMAC;
  369. pbZeroRsrc2 = rgbZeroSig;
  370. cbZeroRsrc2 = cbRsrcSig;
  371. }
  372. else // Sig is first Rsrc
  373. {
  374. cbCRCToRsrc1 = (DWORD)(pbRsrcSig - pbPostCRC);
  375. pbRsrc1ToRsrc2 = pbRsrcSig + cbRsrcSig;
  376. cbRsrc1ToRsrc2 = (DWORD)(pbRsrcMAC - pbRsrc1ToRsrc2);
  377. pbPostRsrc = pbRsrcMAC + cbRsrcMAC;
  378. cbPostRsrc = (cbImage - (DWORD)(pbPostRsrc - pbStart));
  379. // zero pointers
  380. pbZeroRsrc1 = rgbZeroSig;
  381. cbZeroRsrc1 = cbRsrcSig;
  382. pbZeroRsrc2 = rgbZeroMAC;
  383. cbZeroRsrc2 = cbRsrcMAC;
  384. }
  385. // init the key table
  386. deskey(&DESKeyTable, rgbDESKey);
  387. // MAC up to the CRC
  388. if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), dwCRCOffset, &DESKeyTable, rgbTmp,
  389. &cbTmp, rgbMAC, FALSE))
  390. {
  391. goto Ret;
  392. }
  393. // pretend CRC is zeroed
  394. MACBytes(&DESKeyTable, (BYTE*)&dwZeroCRC, sizeof(DWORD), rgbTmp, &cbTmp,
  395. rgbMAC, FALSE);
  396. if (!SetFilePointer((HANDLE)IntToPtr(hFile), sizeof(DWORD), NULL, FILE_CURRENT))
  397. {
  398. goto Ret;
  399. }
  400. // MAC from CRC to first resource
  401. if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), cbCRCToRsrc1, &DESKeyTable, rgbTmp,
  402. &cbTmp, rgbMAC, FALSE))
  403. {
  404. goto Ret;
  405. }
  406. // pretend image has zeroed first resource
  407. MACBytes(&DESKeyTable, (BYTE*)pbZeroRsrc1, cbZeroRsrc1, rgbTmp, &cbTmp,
  408. rgbMAC, FALSE);
  409. if (!SetFilePointer((HANDLE)IntToPtr(hFile), cbZeroRsrc1, NULL, FILE_CURRENT))
  410. {
  411. goto Ret;
  412. }
  413. // MAC from first resource to second
  414. if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), cbRsrc1ToRsrc2, &DESKeyTable, rgbTmp,
  415. &cbTmp, rgbMAC, FALSE))
  416. {
  417. goto Ret;
  418. }
  419. // pretend image has zeroed second Resource
  420. MACBytes(&DESKeyTable, (BYTE*)pbZeroRsrc2, cbZeroRsrc2, rgbTmp, &cbTmp,
  421. rgbMAC, FALSE);
  422. if (!SetFilePointer((HANDLE)IntToPtr(hFile), cbZeroRsrc2, NULL, FILE_CURRENT))
  423. {
  424. goto Ret;
  425. }
  426. // MAC after the resource
  427. if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), cbPostRsrc, &DESKeyTable, rgbTmp, &cbTmp,
  428. rgbMAC, TRUE))
  429. {
  430. goto Ret;
  431. }
  432. memcpy(pbMAC, rgbMAC, DES_BLOCKLEN);
  433. fRet = TRUE;
  434. Ret:
  435. if (pbRsrcMAC)
  436. FreeResource(pbRsrcMAC);
  437. if (pbRsrcSig)
  438. FreeResource(pbRsrcSig);
  439. if(hInst)
  440. UnmapViewOfFile(hInst);
  441. if(hMapping)
  442. CloseHandle(hMapping);
  443. if (HFILE_ERROR != hFile)
  444. _lclose(hFile);
  445. return fRet;
  446. }
  447. DWORD GetCRCOffset(
  448. LPCSTR szFile,
  449. DWORD cbImage,
  450. DWORD *pdwCRCOffset
  451. )
  452. {
  453. DWORD dwErr = 0x1;
  454. HANDLE hFileProv = NULL;
  455. PBYTE pbFilePtr = NULL;
  456. DWORD OldCheckSum;
  457. DWORD NewCheckSum;
  458. PIMAGE_NT_HEADERS pImageNTHdrs;
  459. HANDLE hFileMap = NULL;
  460. if (INVALID_HANDLE_VALUE == (hFileProv = CreateFile(szFile,
  461. GENERIC_READ | GENERIC_WRITE,
  462. 0, // don't share
  463. NULL,
  464. OPEN_EXISTING,
  465. FILE_ATTRIBUTE_NORMAL,
  466. 0)))
  467. {
  468. printf("Couldn't CreateFile: 0x%x\n", GetLastError());
  469. goto Ret;
  470. }
  471. if (NULL == (hFileMap = CreateFileMapping(
  472. hFileProv,
  473. NULL,
  474. PAGE_READWRITE,
  475. 0,
  476. 0,
  477. NULL)))
  478. {
  479. printf("Couldn't map file\n");
  480. goto Ret;
  481. }
  482. if (NULL == (pbFilePtr = (PBYTE)MapViewOfFile(
  483. hFileMap,
  484. FILE_MAP_ALL_ACCESS,
  485. 0,
  486. 0,
  487. 0)))
  488. {
  489. printf("Couldn't create view\n");
  490. goto Ret;
  491. }
  492. // compute a new checksum
  493. if (NULL == (pImageNTHdrs = CheckSumMappedFile(pbFilePtr, cbImage,
  494. &OldCheckSum, &NewCheckSum)))
  495. goto Ret;
  496. *pdwCRCOffset = (DWORD)((BYTE*)&pImageNTHdrs->OptionalHeader.CheckSum - pbFilePtr);
  497. dwErr = ERROR_SUCCESS;
  498. Ret:
  499. if (pbFilePtr)
  500. UnmapViewOfFile(pbFilePtr);
  501. if (hFileMap)
  502. CloseHandle(hFileMap);
  503. if (hFileProv)
  504. CloseHandle(hFileProv);
  505. return dwErr;
  506. }
  507. // SetCryptMACResource
  508. //
  509. // slams MAC resource in file with the new MAC
  510. //
  511. DWORD SetCryptMACResource(
  512. IN LPCSTR szFile,
  513. IN DWORD dwMACVersion,
  514. IN DWORD dwCRCOffset,
  515. IN PBYTE pbNewMAC,
  516. IN DWORD cbImage
  517. )
  518. {
  519. DWORD dwErr = 0x1;
  520. HANDLE hFileProv = NULL;
  521. HMODULE hInst = NULL;
  522. PBYTE pbFilePtr = NULL;
  523. DWORD cbMACOffset;
  524. PBYTE pbMAC;
  525. DWORD cbMAC;
  526. MEMORY_BASIC_INFORMATION MemInfo;
  527. BYTE *pbStart;
  528. DWORD OldCheckSum;
  529. DWORD NewCheckSum;
  530. PIMAGE_NT_HEADERS pImageNTHdrs;
  531. HANDLE hFileMap = NULL;
  532. memset(&MemInfo, 0, sizeof(MemInfo));
  533. // Load the file as a datafile
  534. if (NULL == (hInst = LoadLibraryEx(szFile, NULL, LOAD_LIBRARY_AS_DATAFILE)))
  535. {
  536. printf("Couldn't load file\n");
  537. goto Ret;
  538. }
  539. if (!GetResourcePtr(hInst, MAC_RESOURCE_NAME, &pbMAC, &cbMAC))
  540. {
  541. printf("Couldn't find MAC placeholder\n");
  542. goto Ret;
  543. }
  544. // get image start address
  545. VirtualQuery(hInst, &MemInfo, sizeof(MemInfo));
  546. pbStart = (BYTE*)MemInfo.BaseAddress;
  547. FreeLibrary(hInst); hInst = NULL;
  548. cbMACOffset = (DWORD)(pbMAC - pbStart);
  549. if (cbMAC != (DES_BLOCKLEN + sizeof(DWORD) * 2))
  550. {
  551. printf("Attempt to replace %d zeros with new MAC!\n", cbMAC);
  552. goto Ret;
  553. }
  554. if (INVALID_HANDLE_VALUE == (hFileProv = CreateFile(szFile,
  555. GENERIC_READ | GENERIC_WRITE,
  556. 0, // don't share
  557. NULL,
  558. OPEN_EXISTING,
  559. FILE_ATTRIBUTE_NORMAL,
  560. 0)))
  561. {
  562. printf("Couldn't CreateFile: 0x%x\n", GetLastError());
  563. goto Ret;
  564. }
  565. if (NULL == (hFileMap = CreateFileMapping(
  566. hFileProv,
  567. NULL,
  568. PAGE_READWRITE,
  569. 0,
  570. 0,
  571. NULL)))
  572. {
  573. printf("Couldn't map file\n");
  574. goto Ret;
  575. }
  576. if (NULL == (pbFilePtr = (PBYTE)MapViewOfFile(
  577. hFileMap,
  578. FILE_MAP_ALL_ACCESS,
  579. 0,
  580. 0,
  581. 0)))
  582. {
  583. printf("Couldn't create view\n");
  584. goto Ret;
  585. }
  586. // copy version, CRC offset and new sig
  587. CopyMemory(pbFilePtr+cbMACOffset, &dwMACVersion, sizeof(dwMACVersion));
  588. cbMACOffset += sizeof(dwMACVersion);
  589. CopyMemory(pbFilePtr+cbMACOffset, &dwCRCOffset, sizeof(dwCRCOffset));
  590. cbMACOffset += sizeof(dwCRCOffset);
  591. CopyMemory(pbFilePtr+cbMACOffset, pbNewMAC, DES_BLOCKLEN);
  592. // compute a new checksum
  593. if (NULL == (pImageNTHdrs = CheckSumMappedFile(pbFilePtr, cbImage,
  594. &OldCheckSum, &NewCheckSum)))
  595. goto Ret;
  596. CopyMemory(&pImageNTHdrs->OptionalHeader.CheckSum, &NewCheckSum, sizeof(DWORD));
  597. if (NULL == (pImageNTHdrs = CheckSumMappedFile(pbFilePtr, cbImage,
  598. &OldCheckSum, &NewCheckSum)))
  599. goto Ret;
  600. if (OldCheckSum != NewCheckSum)
  601. goto Ret;
  602. dwErr = ERROR_SUCCESS;
  603. Ret:
  604. if (pbFilePtr)
  605. UnmapViewOfFile(pbFilePtr);
  606. if (hFileMap)
  607. CloseHandle(hFileMap);
  608. if (hInst)
  609. FreeLibrary(hInst);
  610. if (hFileProv)
  611. CloseHandle(hFileProv);
  612. return dwErr;
  613. }
  614. void ShowHelp()
  615. {
  616. printf("CryptoAPI Internal CSP MACing Utility\n");
  617. printf("maccsp <option> <filename>\n");
  618. printf(" options\n");
  619. printf(" m MAC with no sig resource\n");
  620. printf(" s MAC with sig resource\n");
  621. printf(" ? Show this message\n");
  622. }
  623. void __cdecl main( int argc, char *argv[])
  624. {
  625. LPCSTR szInFile = NULL;
  626. DWORD cbImage;
  627. DWORD dwCRCOffset;
  628. HANDLE hFileProv = 0;
  629. BYTE rgbMAC[DES_BLOCKLEN];
  630. BOOL fSigInFile = FALSE;
  631. DWORD dwRet = 1;
  632. memset(rgbMAC, 0, sizeof(rgbMAC));
  633. //
  634. // Parse the command line.
  635. //
  636. if ((argc != 3) || (argv[1][0] == '?'))
  637. {
  638. ShowHelp();
  639. goto Ret;
  640. }
  641. else if ('s' == argv[1][0])
  642. {
  643. fSigInFile = TRUE;
  644. }
  645. else if ('m' == argv[1][0])
  646. {
  647. fSigInFile = FALSE;
  648. }
  649. else
  650. {
  651. ShowHelp();
  652. goto Ret;
  653. }
  654. szInFile = &argv[2][0];
  655. //
  656. // Command consistency checks.
  657. //
  658. if (NULL == szInFile)
  659. {
  660. printf("No input file specified.\n");
  661. goto Ret;
  662. }
  663. // get the file size
  664. if ((hFileProv = CreateFile(szInFile,
  665. GENERIC_READ,
  666. FILE_SHARE_READ,
  667. NULL,
  668. OPEN_EXISTING,
  669. FILE_ATTRIBUTE_NORMAL,
  670. 0)) == INVALID_HANDLE_VALUE)
  671. {
  672. printf("CSP specified was not found!\n");
  673. goto Ret;
  674. }
  675. if (0xffffffff == (cbImage = GetFileSize(hFileProv, NULL)))
  676. {
  677. printf("CSP specified was not found!\n");
  678. goto Ret;
  679. }
  680. CloseHandle(hFileProv);
  681. hFileProv = NULL;
  682. if (0 != GetCRCOffset(szInFile, cbImage, &dwCRCOffset))
  683. {
  684. printf("Unable to get CRC!\n");
  685. goto Ret;
  686. }
  687. // calculate the MAC
  688. if (fSigInFile)
  689. {
  690. if (!MACTheFileWithSig(szInFile, cbImage, dwMACInFileVersion,
  691. dwCRCOffset, rgbMAC))
  692. {
  693. printf("MAC failed!\n");
  694. goto Ret;
  695. }
  696. }
  697. else
  698. {
  699. if (!MACTheFileNoSig(szInFile, cbImage, dwMACInFileVersion,
  700. dwCRCOffset, rgbMAC))
  701. {
  702. printf("MAC failed!\n");
  703. goto Ret;
  704. }
  705. }
  706. //
  707. // Place the MAC into the resource in the file
  708. //
  709. if (ERROR_SUCCESS != SetCryptMACResource(szInFile, dwMACInFileVersion,
  710. dwCRCOffset, rgbMAC, cbImage))
  711. {
  712. printf("Unable to set the MAC into the file resource!\n");
  713. goto Ret;
  714. }
  715. //
  716. // Clean up and return.
  717. //
  718. dwRet = 0;
  719. Ret:
  720. exit(dwRet);
  721. }