Skip to content

Instantly share code, notes, and snippets.

@w4kfu
Created February 5, 2016 10:47
Show Gist options
  • Save w4kfu/c1701cfb1d06f1b45520 to your computer and use it in GitHub Desktop.
Save w4kfu/c1701cfb1d06f1b45520 to your computer and use it in GitHub Desktop.
POC for reading PCRs and TCG log
#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