mirror of
https://github.com/acidanthera/OpenCorePkg.git
synced 2025-12-08 19:25:01 +00:00
110 lines
3.6 KiB
C
110 lines
3.6 KiB
C
/** @file
|
|
Copyright (C) 2018, vit9696. All rights reserved.
|
|
|
|
All rights reserved.
|
|
|
|
This program and the accompanying materials
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
**/
|
|
|
|
#include <Library/BaseMemoryLib.h>
|
|
#include <Library/MemoryAllocationLib.h>
|
|
#include <Library/OcMachoLib.h>
|
|
#include <Library/OcMiscLib.h>
|
|
#include <Library/DebugLib.h>
|
|
|
|
#include <string.h>
|
|
#include <sys/time.h>
|
|
#include <stdint.h>
|
|
#include <stdio.h>
|
|
|
|
#include <File.h>
|
|
|
|
/*
|
|
for fuzzing (TODO):
|
|
clang-mp-7.0 -Dmain=__main -g -fsanitize=undefined,address,fuzzer -I../Include -I../../Include -I../../../MdePkg/Include/ -include ../Include/Base.h -I../../../EfiPkg/Include/ Macho.c ../../Library/OcMiscLib/Base64Decode.c ../../Library/OcStringLib/OcAsciiLib.c ../../Library/OcMachoLib/CxxSymbols.c ../../Library/OcMachoLib/Header.c ../../Library/OcMachoLib/Relocations.c ../../Library/OcMachoLib/Symbols.c -o Macho
|
|
rm -rf DICT fuzz*.log ; mkdir DICT ; cp /System/Library/Kernels/kernel DICT ; ./Macho -rss_limit_mb=4096M -jobs=4 DICT
|
|
|
|
rm -rf fuzz*.log ; mkdir -p DICT ; cp /System/Library/Kernels/kernel DICT/kernel ; ./Macho -jobs=4 -rss_limit_mb=4096M DICT
|
|
|
|
rm -rf Macho.dSYM DICT fuzz*.log Macho
|
|
*/
|
|
|
|
static int FeedMacho(void *file, uint32_t size) {
|
|
OC_MACHO_CONTEXT Context;
|
|
if (!MachoInitializeContext (&Context, file, size)) {
|
|
DEBUG ((DEBUG_WARN, "MachoInitializeContext failure\n"));
|
|
return -1;
|
|
}
|
|
|
|
/*
|
|
For MH_FILELIST Mach-O as determined by checking Mach-O header:
|
|
|
|
1. Save original Mach-O header.
|
|
2. Find __TEXT segment:
|
|
- make sure its offset is 0.
|
|
- make sure its memory size and file size equal.
|
|
3. Calculate DIFF = NEW_SIZE - file size.
|
|
4. Write NEW_SIZE to memory size and file size of __TEXT.
|
|
5. For each segment, that is not text:
|
|
- Increase file_offset by DIFF.
|
|
- Increase vm_offset by DIFF.
|
|
6. For each dyld fixup:
|
|
- Increase target by DIFF, becuase the offset will not change for anything.
|
|
7. Insert DIFF bytes between __TEXT and other segments.
|
|
|
|
VRAM FILE FILE NEW VRAM
|
|
|
|
__HIB __TEXT __TEXT (bigger)
|
|
__TEXT __TEXT_EXEC __TEXT_EXEC (lower)
|
|
__TEXT_EXEC __DATA_CONST __DATA_CONST (lower)
|
|
__DATA_CONST __PRELINK_INFO <empty space>
|
|
__PRELINK_INFO __DATA __DATA (same off)
|
|
__DATA __HIB __HIB (same off)
|
|
__REGION0 __REGION0 __REGION0 (same off)
|
|
... ... ...
|
|
__LINKEDIT __LINKEDIT __REGIONX (new kext)
|
|
__PRELINK_INFO (bigger)
|
|
__LINKEDIT (bigger?)
|
|
|
|
*/
|
|
|
|
|
|
BOOLEAN shr = MachoMergeSegments64 (&Context, "__REGION");
|
|
DEBUG ((DEBUG_WARN, "Shrinking __REGION is %d\n", shr));
|
|
|
|
writeFile("out.bin", file, size);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int main(int argc, char** argv) {
|
|
uint32_t f;
|
|
uint8_t *b;
|
|
if ((b = readFile(argc > 1 ? argv[1] : "/System/Library/KernelCollections/BootKernelExtensions.kc", &f)) == NULL) {
|
|
printf("Read fail\n");
|
|
return -1;
|
|
}
|
|
|
|
FeedMacho (b, f);
|
|
free(b);
|
|
return 0;
|
|
}
|
|
|
|
INT32 LLVMFuzzerTestOneInput(CONST UINT8 *Data, UINTN Size) {
|
|
if (Size > 0) {
|
|
VOID *NewData = AllocatePool (Size);
|
|
if (NewData) {
|
|
CopyMem (NewData, Data, Size);
|
|
FeedMacho (NewData, (UINT32) Size);
|
|
FreePool (NewData);
|
|
}
|
|
}
|
|
return 0;
|
|
}
|