📄 signcsp.cpp
字号:
/////////////////////////////////////////////////////////////////////////////
// FILE : client.cxx //
// DESCRIPTION : Crypto API interface //
// AUTHOR : //
// HISTORY : //
// Mar 8 1996 larrys New //
// dbarlow //
// //
// Copyright (C) 1996 Microsoft Corporation All Rights Reserved //
/////////////////////////////////////////////////////////////////////////////
#include <windows.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdio.h>
#include "mainrpc.h" // header file generated by the MIDL compiler
#include <imagehlp.h>
#include "des.h"
#include "modes.h"
#include "skrpc.h"
extern "C" {
#include "md5.h"
};
// designatred resource for in file signatures
#define CRYPT_SIG_RESOURCE_NUMBER "#666"
// MAC in file
#define MAC_RESOURCE_NUMBER "#667"
static DWORD dwMACInFileVersion = 0x100;
BYTE rgbDESKey[] = {0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
BOOL HashTheFile(
LPCSTR pszFile,
DWORD dwCRCOffset,
BYTE *pbHash,
DWORD *pcbHash,
DWORD cbImage
);
DWORD GetCRCOffset(
LPCSTR szFile,
DWORD cbImage,
DWORD *pdwCRCOffset
);
static DWORD dwSigInFileVersion = 0x100;
DWORD SetCryptSignatureResource(
LPCSTR szFile,
DWORD dwSigVersion,
DWORD dwCRCOffset,
PBYTE pbNewSig,
DWORD cbNewSig,
DWORD cbImage
);
void ShowHelp();
BOOL DumpFile(LPCTSTR szFile, const BYTE *pb, UINT cb);
void CallServer(void);
BYTE pbSignature[256];
BYTE pbDigest[80];
DWORD cbDigestLen = sizeof(pbDigest);
DWORD cbSignatureLen = sizeof(pbSignature);
// The function MACs the given bytes.
void MACBytes(
IN DESTable *pDESKeyTable,
IN BYTE *pbData,
IN DWORD cbData,
IN OUT BYTE *pbTmp,
IN OUT DWORD *pcbTmp,
IN OUT BYTE *pbMAC,
IN BOOL fFinal
)
{
DWORD cb = cbData;
DWORD cbMACed = 0;
while (cb)
{
if ((cb + *pcbTmp) < DES_BLOCKLEN)
{
memcpy(pbTmp + *pcbTmp, pbData + cbMACed, cb);
*pcbTmp += cb;
break;
}
else
{
memcpy(pbTmp + *pcbTmp, pbData + cbMACed, DES_BLOCKLEN - *pcbTmp);
CBC(des, DES_BLOCKLEN, pbMAC, pbTmp, pDESKeyTable,
ENCRYPT, pbMAC);
cbMACed = cbMACed + (DES_BLOCKLEN - *pcbTmp);
cb = cb - (DES_BLOCKLEN - *pcbTmp);
*pcbTmp = 0;
}
}
}
// Given hInst, allocs and returns pointers to MAC pulled from
// resource
BOOL GetResourcePtr(
IN HMODULE hInst,
IN LPSTR pszRsrcName,
OUT BYTE **ppbRsrcMAC,
OUT DWORD *pcbRsrcMAC
)
{
HRSRC hRsrc;
BOOL fRet = FALSE;
// Nab resource handle for our signature
if (NULL == (hRsrc = FindResourceA(hInst, pszRsrcName,
RT_RCDATA)))
goto Ret;
// get a pointer to the actual signature data
if (NULL == (*ppbRsrcMAC = (PBYTE)LoadResource(hInst, hRsrc)))
goto Ret;
// determine the size of the resource
if (0 == (*pcbRsrcMAC = SizeofResource(hInst, hRsrc)))
goto Ret;
fRet = TRUE;
Ret:
return fRet;
}
#define CSP_TO_BE_MACED_CHUNK 4096
// Given hFile, reads the specified number of bytes (cbToBeMACed) from the file
// and MACs these bytes. The function does this in chunks.
BOOL MACBytesOfFile(
IN HANDLE hFile,
IN DWORD cbToBeMACed,
IN DESTable *pDESKeyTable,
IN BYTE *pbTmp,
IN DWORD *pcbTmp,
IN BYTE *pbMAC,
IN BYTE fFinal
)
{
BYTE rgbChunk[CSP_TO_BE_MACED_CHUNK];
DWORD cbRemaining = cbToBeMACed;
DWORD cbToRead;
DWORD dwBytesRead;
BOOL fRet = FALSE;
//
// loop over the file for the specified number of bytes
// updating the hash as we go.
//
while (cbRemaining > 0)
{
if (cbRemaining < CSP_TO_BE_MACED_CHUNK)
cbToRead = cbRemaining;
else
cbToRead = CSP_TO_BE_MACED_CHUNK;
if(!ReadFile(hFile, rgbChunk, cbToRead, &dwBytesRead, NULL))
goto Ret;
if (dwBytesRead != cbToRead)
goto Ret;
MACBytes(pDESKeyTable, rgbChunk, dwBytesRead, pbTmp, pcbTmp,
pbMAC, fFinal);
cbRemaining -= cbToRead;
}
fRet = TRUE;
Ret:
return fRet;
}
BOOL MACTheFileWithSig(
LPCSTR pszImage,
DWORD cbImage,
IN DWORD dwMACVersion,
IN DWORD dwCRCOffset,
OUT BYTE *pbMAC
)
{
HMODULE hInst = 0;
MEMORY_BASIC_INFORMATION MemInfo;
BYTE *pbRsrcMAC;
DWORD cbRsrcMAC;
BYTE *pbRsrcSig;
DWORD cbRsrcSig;
BYTE *pbStart;
BYTE rgbMAC[DES_BLOCKLEN];
BYTE rgbZeroMAC[DES_BLOCKLEN + sizeof(DWORD) * 2];
BYTE rgbZeroSig[144];
BYTE *pbPostCRC; // pointer to just after CRC
DWORD cbCRCToRsrc1; // number of bytes from CRC to first rsrc
DWORD cbRsrc1ToRsrc2; // number of bytes from first rsrc to second
DWORD cbPostRsrc; // size - (already hashed + signature size)
BYTE *pbRsrc1ToRsrc2;
BYTE *pbPostRsrc;
BYTE *pbZeroRsrc1;
BYTE *pbZeroRsrc2;
DWORD cbZeroRsrc1;
DWORD cbZeroRsrc2;
DWORD dwZeroCRC = 0;
DWORD dwBytesRead = 0;
OFSTRUCT ImageInfoBuf;
HFILE hFile = HFILE_ERROR;
HANDLE hMapping = NULL;
DESTable DESKeyTable;
BYTE rgbTmp[DES_BLOCKLEN];
DWORD cbTmp = 0;
BOOL fRet = FALSE;
memset(&MemInfo, 0, sizeof(MemInfo));
memset(rgbMAC, 0, sizeof(rgbMAC));
memset(rgbTmp, 0, sizeof(rgbTmp));
// Load the file
if (HFILE_ERROR == (hFile = OpenFile(pszImage, &ImageInfoBuf,
OF_READ)))
{
goto Ret;
}
hMapping = CreateFileMapping((HANDLE)IntToPtr(hFile),
NULL,
PAGE_READONLY,
0,
0,
NULL);
if(hMapping == NULL)
{
goto Ret;
}
hInst = (HMODULE)MapViewOfFile(hMapping,
FILE_MAP_READ,
0,
0,
0);
if(hInst == NULL)
{
goto Ret;
}
pbStart = (BYTE*)hInst;
// Convert pointer to HMODULE, using the same scheme as
// LoadLibrary (windows\base\client\module.c).
*((ULONG_PTR*)&hInst) |= 0x00000001;
// the MAC resource
if (!GetResourcePtr(hInst, MAC_RESOURCE_NUMBER, &pbRsrcMAC, &cbRsrcMAC))
goto Ret;
// the MAC resource
if (!GetResourcePtr(hInst, CRYPT_SIG_RESOURCE_NUMBER, &pbRsrcSig, &cbRsrcSig))
goto Ret;
if (cbRsrcMAC < (sizeof(DWORD) * 2))
goto Ret;
// create a zero byte MAC
memset(rgbZeroMAC, 0, sizeof(rgbZeroMAC));
// create a zero byte Sig
memset(rgbZeroSig, 0, sizeof(rgbZeroSig));
// set up the pointers
pbPostCRC = pbStart + dwCRCOffset + sizeof(DWORD);
if (pbRsrcSig > pbRsrcMAC) // MAC is first Rsrc
{
cbCRCToRsrc1 = (DWORD)(pbRsrcMAC - pbPostCRC);
pbRsrc1ToRsrc2 = pbRsrcMAC + cbRsrcMAC;
cbRsrc1ToRsrc2 = (DWORD)(pbRsrcSig - pbRsrc1ToRsrc2);
pbPostRsrc = pbRsrcSig + cbRsrcSig;
cbPostRsrc = (cbImage - (DWORD)(pbPostRsrc - pbStart));
// zero pointers
pbZeroRsrc1 = rgbZeroMAC;
cbZeroRsrc1 = cbRsrcMAC;
pbZeroRsrc2 = rgbZeroSig;
cbZeroRsrc2 = cbRsrcSig;
}
else // Sig is first Rsrc
{
cbCRCToRsrc1 = (DWORD)(pbRsrcSig - pbPostCRC);
pbRsrc1ToRsrc2 = pbRsrcSig + cbRsrcSig;
cbRsrc1ToRsrc2 = (DWORD)(pbRsrcMAC - pbRsrc1ToRsrc2);
pbPostRsrc = pbRsrcMAC + cbRsrcMAC;
cbPostRsrc = (cbImage - (DWORD)(pbPostRsrc - pbStart));
// zero pointers
pbZeroRsrc1 = rgbZeroSig;
cbZeroRsrc1 = cbRsrcSig;
pbZeroRsrc2 = rgbZeroMAC;
cbZeroRsrc2 = cbRsrcMAC;
}
// init the key table
deskey(&DESKeyTable, rgbDESKey);
// MAC up to the CRC
if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), dwCRCOffset, &DESKeyTable, rgbTmp,
&cbTmp, rgbMAC, FALSE))
{
goto Ret;
}
// pretend CRC is zeroed
MACBytes(&DESKeyTable, (BYTE*)&dwZeroCRC, sizeof(DWORD), rgbTmp, &cbTmp,
rgbMAC, FALSE);
if (!SetFilePointer((HANDLE)IntToPtr(hFile), sizeof(DWORD), NULL, FILE_CURRENT))
{
goto Ret;
}
// MAC from CRC to first resource
if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), cbCRCToRsrc1, &DESKeyTable, rgbTmp,
&cbTmp, rgbMAC, FALSE))
{
goto Ret;
}
// pretend image has zeroed first resource
MACBytes(&DESKeyTable, (BYTE*)pbZeroRsrc1, cbZeroRsrc1, rgbTmp, &cbTmp,
rgbMAC, FALSE);
if (!SetFilePointer((HANDLE)IntToPtr(hFile), cbZeroRsrc1, NULL, FILE_CURRENT))
{
goto Ret;
}
// MAC from first resource to second
if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), cbRsrc1ToRsrc2, &DESKeyTable, rgbTmp,
&cbTmp, rgbMAC, FALSE))
{
goto Ret;
}
// pretend image has zeroed second Resource
MACBytes(&DESKeyTable, (BYTE*)pbZeroRsrc2, cbZeroRsrc2, rgbTmp, &cbTmp,
rgbMAC, FALSE);
if (!SetFilePointer((HANDLE)IntToPtr(hFile), cbZeroRsrc2, NULL, FILE_CURRENT))
{
goto Ret;
}
// MAC after the resource
if (!MACBytesOfFile((HANDLE)IntToPtr(hFile), cbPostRsrc, &DESKeyTable, rgbTmp, &cbTmp,
rgbMAC, TRUE))
{
goto Ret;
}
memcpy(pbMAC, rgbMAC, DES_BLOCKLEN);
fRet = TRUE;
Ret:
if(hInst)
UnmapViewOfFile(hInst);
if(hMapping)
CloseHandle(hMapping);
if (HFILE_ERROR != hFile)
_lclose(hFile);
return fRet;
}
// SetCryptMACResource
//
// slams MAC resource in file with the new MAC
//
DWORD SetCryptMACResource(
IN LPCSTR szFile,
IN DWORD dwMACVersion,
IN DWORD dwCRCOffset,
IN PBYTE pbNewMAC,
IN DWORD cbImage
)
{
DWORD dwErr = 0x1;
HANDLE hFileProv = NULL;
HMODULE hInst = NULL;
PBYTE pbFilePtr = NULL;
DWORD cbImageSize, cbMACOffset;
PBYTE pbMAC;
DWORD cbMAC;
MEMORY_BASIC_INFORMATION MemInfo;
BYTE *pbStart;
DWORD OldCheckSum;
DWORD NewCheckSum;
PIMAGE_NT_HEADERS pImageNTHdrs;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -