205 lines
5.4 KiB
C

/** @file
Copyright (c) 2018, vit9696. All rights reserved.
SPDX-License-Identifier: BSD-3-Clause
**/
#include <Library/OcAppleChunklistLib.h>
#include <Library/OcAppleDiskImageLib.h>
#include <Library/OcAppleRamDiskLib.h>
#include <Library/OcAppleKeysLib.h>
#include <Library/OcCompressionLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <UserFile.h>
#include <UserMemory.h>
#define NUM_EXTENTS 20
int
ENTRY_POINT (
int argc,
char *argv[]
)
{
int Index;
BOOLEAN DmgContextValid;
UINT8 *Dmg;
UINT32 DmgSize;
UINT8 *Chunklist;
UINT32 ChunklistSize;
UINT8 *UncompDmg;
UINT32 UncompSize;
BOOLEAN Result;
OC_APPLE_DISK_IMAGE_CONTEXT DmgContext;
APPLE_RAM_DISK_EXTENT_TABLE ExtentTable;
UINT32 Index2;
OC_APPLE_CHUNKLIST_CONTEXT ChunklistContext;
//
// Limit pool allocation size to 3072 MB
//
SetPoolAllocationSizeLimit (BASE_1GB | BASE_2GB);
if (argc < 2) {
DEBUG ((DEBUG_ERROR, "Please provide a valid Disk Image path\n"));
return -1;
}
if ((argc % 2) != 1) {
DEBUG ((DEBUG_ERROR, "Please provide a chunklist file for each DMG, enter \'n\' to skip\n"));
}
for (Index = 1; Index < (argc - 1); Index += 2) {
DmgContextValid = FALSE;
Dmg = NULL;
Chunklist = NULL;
UncompDmg = NULL;
if ((Dmg = UserReadFile (argv[Index], &DmgSize)) == NULL) {
DEBUG ((DEBUG_ERROR, "Read fail\n"));
goto ContinueDmgLoop;
}
ExtentTable.Signature = APPLE_RAM_DISK_EXTENT_SIGNATURE;
ExtentTable.Version = APPLE_RAM_DISK_EXTENT_VERSION;
ExtentTable.Reserved = 0;
ExtentTable.Signature2 = APPLE_RAM_DISK_EXTENT_SIGNATURE;
ExtentTable.ExtentCount = MIN (NUM_EXTENTS, ARRAY_SIZE (ExtentTable.Extents));
for (Index2 = 0; Index2 < ExtentTable.ExtentCount; ++Index2) {
ExtentTable.Extents[Index2].Start = (UINTN)Dmg + (Index2 * (DmgSize / ExtentTable.ExtentCount));
ExtentTable.Extents[Index2].Length = (DmgSize / ExtentTable.ExtentCount);
}
if (Index2 != 0) {
ExtentTable.Extents[Index2 - 1].Length += (DmgSize - (Index2 * (DmgSize / ExtentTable.ExtentCount)));
}
Result = OcAppleDiskImageInitializeContext (&DmgContext, &ExtentTable, DmgSize);
if (!Result) {
DEBUG ((DEBUG_ERROR, "DMG Context initialization error\n"));
goto ContinueDmgLoop;
}
DmgContextValid = TRUE;
if (AsciiStrCmp (argv[Index + 1], "n") != 0) {
if ((Chunklist = UserReadFile (argv[Index + 1], &ChunklistSize)) == NULL) {
DEBUG ((DEBUG_ERROR, "Read fail\n"));
goto ContinueDmgLoop;
}
Result = OcAppleChunklistInitializeContext (&ChunklistContext, Chunklist, ChunklistSize);
if (!Result) {
DEBUG ((DEBUG_ERROR, "Chunklist Context initialization error\n"));
goto ContinueDmgLoop;
}
Result = OcAppleChunklistVerifySignature (&ChunklistContext, PkDataBase[0].PublicKey);
if (!Result) {
DEBUG ((DEBUG_ERROR, "Chunklist signature verification error\n"));
goto ContinueDmgLoop;
}
Result = OcAppleDiskImageVerifyData (&DmgContext, &ChunklistContext);
if (!Result) {
DEBUG ((DEBUG_ERROR, "Chunklist chunk verification error\n"));
goto ContinueDmgLoop;
}
}
UncompSize = (DmgContext.SectorCount * APPLE_DISK_IMAGE_SECTOR_SIZE);
UncompDmg = AllocatePool (UncompSize);
if (UncompDmg == NULL) {
DEBUG ((DEBUG_ERROR, "DMG data allocation failed\n"));
goto ContinueDmgLoop;
}
Result = OcAppleDiskImageRead (&DmgContext, 0, UncompSize, UncompDmg);
if (!Result) {
DEBUG ((DEBUG_ERROR, "DMG read error\n"));
goto ContinueDmgLoop;
}
DEBUG ((DEBUG_ERROR, "Decompressed the entire DMG...\n"));
#if 0
UserWriteFile ("out.bin", UncompDmg, UncompSize);
#endif
#if 0
UINT8 Digest[CC_MD5_DIGEST_LENGTH];
CC_MD5_CTX Context;
UINTN Index3;
CC_MD5_Init (&Context);
CC_MD5_Update (&Context, UncompDmg, UncompSize);
CC_MD5_Final (Digest, &Context);
for (Index3 = 0; Index3 < CC_MD5_DIGEST_LENGTH; ++Index3) {
DEBUG ((DEBUG_ERROR, "%02x", (UINT32)Digest[Index3]));
}
DEBUG ((DEBUG_ERROR, "\n"));
#endif
DEBUG ((DEBUG_ERROR, "Success...\n"));
ContinueDmgLoop:
if (DmgContextValid) {
OcAppleDiskImageFreeContext (&DmgContext);
}
if (Dmg != NULL) {
FreePool (Dmg);
}
if (Chunklist != NULL) {
FreePool (Chunklist);
}
if (UncompDmg != NULL) {
FreePool (UncompDmg);
}
}
return 0;
}
int
LLVMFuzzerTestOneInput (
const uint8_t *Data,
size_t Size
)
{
#define MAX_INPUT 256
#define MAX_OUTPUT 4096
UINT8 *Test;
UINTN Index;
UINT32 CurrentLength;
if (Size > MAX_INPUT) {
return 0;
}
Test = AllocateZeroPool (MAX_OUTPUT);
if (Test == NULL) {
return 0;
}
for (Index = 0; Index < 4096; ++Index) {
ASAN_POISON_MEMORY_REGION (Test + Index, MAX_OUTPUT - Index);
CurrentLength = DecompressZLIB (
Test,
Index,
Data,
Size
);
ASAN_UNPOISON_MEMORY_REGION (Test + Index, MAX_OUTPUT - Index);
ASSERT (CurrentLength <= Index);
}
return 0;
}