Created
February 5, 2016 10:47
-
-
Save w4kfu/c1701cfb1d06f1b45520 to your computer and use it in GitHub Desktop.
POC for reading PCRs and TCG log
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <stdio.h> | |
#include <tbs.h> | |
#pragma comment(lib, "Tbs.lib") | |
#pragma comment(lib, "Ws2_32.lib") | |
#define TPM_DIGEST_SIZE 20 | |
#define TPM_TAG_RQU_COMMAND ((UINT16)0x00C1) | |
#define TPM_TAG_RSP_COMMAND ((UINT16)0x00C4) | |
#define TPM_ORD_PcrRead ((UINT32)0x00000015) | |
#define TPM_BASE 0x00000000 | |
#define TPM_SUCCESS TPM_BASE | |
typedef UINT32 TCG_EVENTTYPE; | |
typedef UINT32 TPM_PCRINDEX; | |
typedef TPM_PCRINDEX TCG_PCRINDEX; | |
#pragma pack(push,1) | |
typedef struct { | |
TCG_PCRINDEX PCRIndex; | |
TCG_EVENTTYPE EventType; | |
UINT8 Digest[TPM_DIGEST_SIZE]; | |
UINT32 EventSize; | |
UINT8 Event[1]; | |
} TCG_PCR_EVENT2; | |
#pragma pack(pop) | |
VOID PrintHex(PBYTE pBuffer, INT iSize); | |
VOID HexDump(VOID *pData, INT iSize); | |
BOOL ReadPCR(TBS_HCONTEXT hContext, UINT32 Index, PBYTE pDigest) | |
{ | |
BYTE BufferIn[0x10]; | |
BYTE BufferOut[0x200]; | |
UINT32 BufOutLen; | |
BufOutLen = sizeof (BufferOut); | |
memset(pDigest, 0, TPM_DIGEST_SIZE); | |
memset(BufferIn, 0, sizeof (BufferIn)); | |
memset(BufferOut, 0, sizeof (BufferOut)); | |
*(WORD*)(BufferIn) = htons(TPM_TAG_RQU_COMMAND); | |
*(DWORD*)(BufferIn + 0x02) = htonl(0x0E); // Length | |
*(DWORD*)(BufferIn + 0x06) = htonl(TPM_ORD_PcrRead); | |
*(DWORD*)(BufferIn + 0x0A) = htonl(Index); | |
Tbsip_Submit_Command(hContext, 0, TBS_COMMAND_PRIORITY_NORMAL, BufferIn, 0x0E, BufferOut, &BufOutLen); | |
if (*(WORD*)(BufferOut + 0x00) != htons(TPM_TAG_RSP_COMMAND)) { | |
printf("[-] not TPM_TAG_RSP_COMMAND\n"); | |
return FALSE; | |
} | |
if (*(DWORD*)(BufferOut + 0x06) != TPM_SUCCESS) { | |
printf("[-] ERROR : 0x%08X\n", htonl(*(DWORD*)(BufferOut + 0x02))); | |
return FALSE; | |
} | |
memcpy(pDigest, BufferOut + 0x0A, TPM_DIGEST_SIZE); | |
return TRUE; | |
} | |
VOID ReadPCRs(TBS_HCONTEXT hContext) | |
{ | |
BYTE Digest[TPM_DIGEST_SIZE]; | |
for (int i = 0; i < 23; i++) { | |
if (ReadPCR(hContext, i, Digest) == TRUE) { | |
printf("PCR[%02d] : ", i); | |
PrintHex(Digest, TPM_DIGEST_SIZE); | |
printf("\n"); | |
} | |
} | |
} | |
VOID ParseTCGLog(PBYTE pLogBuffer, UINT32 iLogSize) | |
{ | |
TCG_PCR_EVENT2 *pEvent = NULL; | |
PBYTE pFinalSize = NULL; | |
pEvent = (TCG_PCR_EVENT2*)pLogBuffer; | |
pFinalSize = pLogBuffer + iLogSize; | |
while (pLogBuffer < pFinalSize) { | |
printf("[+] PCR : %02d (0x%08X)\n", pEvent->PCRIndex, pEvent->PCRIndex); | |
printf("[+] EventType : %d (0x%08X)\n", pEvent->EventType, pEvent->EventType); | |
printf("[+] Digest : "); | |
PrintHex(pEvent->Digest, 20); | |
printf("\n"); | |
HexDump(pEvent->Event, pEvent->EventSize); | |
pLogBuffer = pLogBuffer + 4 + 4 + 20 + 4 + pEvent->EventSize; | |
pEvent = (TCG_PCR_EVENT2*)pLogBuffer; | |
} | |
} | |
int main(int argc, char *argv[]) | |
{ | |
TBS_RESULT res; | |
TBS_HCONTEXT hContext; | |
TBS_CONTEXT_PARAMS ContextParams; | |
UINT32 iLogSize = TBS_IN_OUT_BUF_SIZE_MAX; | |
BYTE* pTCGLogBuffer = NULL; | |
UNREFERENCED_PARAMETER(argc); | |
UNREFERENCED_PARAMETER(argv); | |
ContextParams.version = TBS_CONTEXT_VERSION_ONE; | |
res = Tbsi_Context_Create(&ContextParams, &hContext); | |
if (res == TBS_SUCCESS) { | |
ReadPCRs(hContext); | |
pTCGLogBuffer = (BYTE*)malloc(sizeof (CHAR) * iLogSize); | |
if (pTCGLogBuffer == NULL) { | |
printf("[-] malloc failed\n"); | |
} | |
else { | |
memset(pTCGLogBuffer, 0, iLogSize); | |
res = Tbsi_Get_TCG_Log(hContext, pTCGLogBuffer, &iLogSize); | |
if (res == TBS_SUCCESS) { | |
ParseTCGLog(pTCGLogBuffer, iLogSize); | |
} | |
else { | |
printf("[-] Tbsi_Get_TCG_Log failed : 0x%08X\n", res); | |
} | |
free(pTCGLogBuffer); | |
} | |
Tbsip_Context_Close(hContext); | |
} | |
else { | |
printf("[-] Tbsi_Context_Create failed : 0x%08X\n", res); | |
} | |
return 0; | |
} | |
VOID PrintHex(PBYTE pBuffer, INT iSize) | |
{ | |
for (int i = 0; i < iSize; i++) { | |
printf("%02X", pBuffer[i]); | |
} | |
} | |
VOID HexDump(VOID *pData, INT iSize) | |
{ | |
PBYTE p = (PBYTE)pData; | |
BYTE c; | |
int n; | |
CHAR bytestr[4] = {0}; | |
CHAR addrstr[10] = {0}; | |
CHAR hexstr[16 * 3 + 5] = {0}; | |
CHAR charstr[16 * 1 + 5] = {0}; | |
for (n = 1; n <= iSize; n++) { | |
if (n % 16 == 1) { | |
sprintf_s(addrstr, sizeof(addrstr), "%.4x", ((ULONG_PTR)p - (ULONG_PTR)pData)); | |
} | |
c = *p; | |
if (isalnum(c) == 0) { | |
c = '.'; | |
} | |
sprintf_s(bytestr, sizeof(bytestr), "%02X ", *p); | |
strncat_s(hexstr, sizeof(hexstr), bytestr, sizeof(hexstr) - strlen(hexstr) - 1); | |
sprintf_s(bytestr, sizeof(bytestr), "%c", c); | |
strncat_s(charstr, sizeof(charstr), bytestr, sizeof(charstr) - strlen(charstr) - 1); | |
if (n % 16 == 0) { | |
printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); | |
hexstr[0] = 0; | |
charstr[0] = 0; | |
} | |
else if (n % 8 == 0) { | |
strncat_s(hexstr, sizeof(hexstr), " ", sizeof(hexstr) - strlen(hexstr) - 1); | |
} | |
p++; | |
} | |
if (strlen(hexstr) > 0) { | |
printf("[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment