Skip to content

Instantly share code, notes, and snippets.

@digetx
Created March 5, 2020 11:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save digetx/576a4ec9859e85e1beb8d03c1b97aa40 to your computer and use it in GitHub Desktop.
Save digetx/576a4ec9859e85e1beb8d03c1b97aa40 to your computer and use it in GitHub Desktop.
parse_tegrapt
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <openssl/sha.h>
#include <stdbool.h>
#include <stdint-gcc.h>
#define _GNU_SOURCE
typedef struct NvFsMountInfoRec
{
uint32_t DeviceId; // 4
uint32_t DeviceInstance; // 4
uint32_t DeviceAttr; // 4
char MountPath[4]; // 4
uint32_t FileSystemType; // 4
uint32_t FileSystemAttr; // 4
} NvFsMountInfo;
typedef struct NvPartInfoRec
{
uint32_t PartitionAttr; // 4 4
uint32_t Padding1; // 4 8
uint64_t LogicalSectorAddress; // 8 16
uint64_t NumLogicalSectors; // 8 24
uint64_t StartPhysicalSectorAddress; // 8 32
uint64_t EndPhysicalSectorAddress; // 8 40
uint32_t PartitionType; // 4 44
uint32_t Padding2; // 4 48
} NvPartInfo;
typedef struct NvPartTableHeaderInsecureRec
{
uint64_t Magic;
uint32_t InsecureVersion;
uint32_t InsecureLength;
uint8_t Signature[16];
} NvPartTableHeaderInsecure;
typedef struct NvPartTableHeaderSecureRec
{
uint8_t RandomData[16];
uint64_t SecureMagic;
uint32_t SecureVersion;
uint32_t SecureLength;
uint32_t NumPartitions;
uint8_t padding[4];
} NvPartTableHeaderSecure;
typedef struct NvPartitionTableEntryRec
{
uint32_t PartitionId; // 4
char PartitionName[4]; // 4
NvFsMountInfo MountInfo; // 38
NvPartInfo PartInfo; // 52
} NvPartitionTableEntry;
typedef struct NvPartitionTableRec
{
NvPartTableHeaderInsecure InsecureHeader;
NvPartTableHeaderSecure SecureHeader;
NvPartitionTableEntry TableEntry[18];
} NvPartitionTable;
int parse_table(char *table)
{
int i=0, b=0;
NvPartitionTable *tegra = (NvPartitionTable *)table;
printf("(Insecure Header)\n");
printf("Insecure Magic: %08llX\n", tegra->InsecureHeader.Magic);
printf("Insecure Version: %04X\n", tegra->InsecureHeader.InsecureVersion);
printf("Insecure Length: 0x%X\n", tegra->InsecureHeader.InsecureLength);
printf("Hash: ");
for (i=0; i<16; i++)
{
printf("%02x", tegra->InsecureHeader.Signature[i]);
};
printf("\n\n");
printf("(Secure Header)\n");
printf("Random Data: ");
for (i=0; i<16; i++)
{
printf("%02X", tegra->SecureHeader.RandomData[i]);
}
printf("\n");
printf("Secure Magic: %08llX\n", tegra->SecureHeader.SecureMagic);
printf("Secure Version: %04X\n", tegra->SecureHeader.SecureVersion);
printf("Secure Length: 0x%X\n", tegra->SecureHeader.SecureLength);
printf("Partitions: %d\n", tegra->SecureHeader.NumPartitions);
printf("\n\n");
printf("[Partition Table Entries]\n\n");
for (i=0; i<18; i++)
{
if (tegra->TableEntry[i].PartitionId >= 128) break;
printf("(%s)\n\n", tegra->TableEntry[i].PartitionName);
printf("Partition ID: [0x%X]\n", tegra->TableEntry[i].PartitionId);
printf("Device ID: [%X]\n", tegra->TableEntry[i].MountInfo.DeviceId);
printf("Device Instance: [%X]\n", tegra->TableEntry[i].MountInfo.DeviceInstance);
printf("Device Attributes: [%X]\n", tegra->TableEntry[i].MountInfo.DeviceAttr);
printf("Mount Path: [%s]\n", tegra->TableEntry[i].MountInfo.MountPath);
printf("Filesystem Type: [%X]\n", tegra->TableEntry[i].MountInfo.FileSystemType);
printf("Filesystem Attributes: [%X]\n", tegra->TableEntry[i].MountInfo.FileSystemAttr);
printf("Partition Attributes: [%X]\n", tegra->TableEntry[i].PartInfo.PartitionAttr);
printf("Logical Sector Address: [0x%016llX]\n", tegra->TableEntry[i].PartInfo.LogicalSectorAddress);
printf("Number of Logical Sectors: [0x%016llX]\n", tegra->TableEntry[i].PartInfo.NumLogicalSectors);
printf("Start Physical Sector Address: [0x%016llX]\n", tegra->TableEntry[i].PartInfo.StartPhysicalSectorAddress);
printf("End Physical Sector Address: [0x%016llX]\n", tegra->TableEntry[i].PartInfo.EndPhysicalSectorAddress);
printf("Partition Type: [0x%X]\n", tegra->TableEntry[i].PartInfo.PartitionType);
printf("\n\n");
}
return 0;
}
int parse_header(char* image)
{
FILE* inf;
int i = 0;
uint32_t size, result;
char* data;
inf = fopen(image, "rb");
if (!inf)
{
printf("Error opening image %s\n", image);
return 1;
}
fseek(inf, 0, SEEK_END);
size = ftell(inf);
rewind(inf);
data = (char*)malloc(sizeof(char)*(size));
if (!data)
{
printf("Failed to allocate buffer!\n");
return 1;
}
result = fread((data), 1, size, inf);
if (result != size)
{
printf("Error reading image %s\n\r", image);
return 1;
}
fclose(inf);
result = *(uint32_t*)data;
if (result == 0x8F9E8D8B)
{
printf("Detected Nvidia Tegra partition table!\n\n");
parse_table(data);
}
else
{
printf("Image could not be identified!\n\n");
}
free(data);
return 0;
}
int main(int argc, char* argv[])
{
char image[200] = {0};
if (argc < 2 || argc > 2)
{
printf("No partition file specified!\n");
}
else
{
sscanf(argv[1], "%s", image);
printf("Processing...\n\n");
parse_header(image);
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment