xsscx / xnuimagefuzzer

XNU Image Fuzzer - iOS App for Fuzzing Images with Objective-C Code covering 12 CGCreateBitmap & CGColorSpace Functions working with Raw Data and String Injection.
https://srd.cx/xnu-image-fuzzer/
GNU General Public License v3.0
35 stars 2 forks source link

Crash in signature() function due to missing #define for COMM_PAGE for X86_64 #4

Closed xsscx closed 6 months ago

xsscx commented 7 months ago

X86_64 Crash in signature() function

Why

This function directly accesses memory and should be used with caution, ensuring that COMM_PAGE64_BASE_ADDRESS points to a valid, accessible memory address to prevent undefined behavior.

pragma mark - Signature

#define COMM_PAGE64_BASE_ADDRESS (0x0000000FFFFFC000ULL)
#define COMM_PAGE_CPU_CAPABILITIES64 (COMM_PAGE64_BASE_ADDRESS + 0x010)
...
#pragma mark - Signature

/**
 Retrieves a signature from a predefined memory address.

 This function allocates memory and copies a 16-byte signature from a specified base address in memory, commonly used for retrieving system or application-specific signatures stored in a secure memory region.

 The memory is allocated with calloc, ensuring all bytes are initialized to zero, including the byte following the signature, effectively null-terminating the string.

 @return A pointer to a null-terminated string containing the signature. The caller is responsible for freeing this memory using free(). Returns NULL if memory allocation fails.

 @note This function directly accesses memory and should be used with caution, ensuring that COMM_PAGE64_BASE_ADDRESS points to a valid, accessible memory address to prevent undefined behavior.

 Example usage:
 char *sig = signature();
 if (sig) {
     printf("Signature: %s\n", sig);
     free(sig);
 } else {
     fprintf(stderr, "Failed to retrieve signature.\n");
 }
*/
char *signature(void) {
    // Allocate memory using calloc; +1 for null terminator, initializing all bits to zero
    char *signature = calloc(1, 0x10 + 1); // Replaces malloc(0x10 + 1) and initializes memory
    if (!signature) {
        fprintf(stderr, "Error: Failed to allocate memory for signature.\n");
        return NULL;
    }
    memcpy(signature, (const char *)COMM_PAGE64_BASE_ADDRESS, 0x10);
    // No need to explicitly set the null terminator since calloc initializes the memory to zero
    return signature;](xnuimagefuzzer.m:237)

LLDB Output - X86_64 2020 Mac Mini i7

(lldb) re read
General Purpose Registers:
       rbx = 0x0000000105202210
       rbp = 0x00007ff7bb2dfec0
       rsp = 0x00007ff7bb2dfeb0
       r12 = 0x00007ff7bb2e00a0
       r13 = 0x0000000000000000
       r14 = 0x0000000104c23730  XNU Image Fuzzer`main at xnuimagefuzzer.m:1294
       r15 = 0x00007ff7bb2e0220
       rip = 0x0000000104c216fa  XNU Image Fuzzer`signature + 106 at xnuimagefuzzer.m:268:12
13 registers were unavailable.
(lldb) dis -f
XNU Image Fuzzer`signature:
    0x104c21690 <+0>:   pushq  %rbp
    0x104c21691 <+1>:   movq   %rsp, %rbp
    0x104c21694 <+4>:   subq   $0x10, %rsp
    0x104c21698 <+8>:   movl   $0x1, %edi
    0x104c2169d <+13>:  movl   $0x11, %esi
    0x104c216a2 <+18>:  callq  0x104c263f8               ; symbol stub for: calloc
    0x104c216a7 <+23>:  movq   %rax, -0x10(%rbp)
    0x104c216ab <+27>:  cmpq   $0x0, -0x10(%rbp)
    0x104c216b0 <+32>:  jne    0x104c216db               ; <+75> at xnuimagefuzzer.m:266:5
    0x104c216b6 <+38>:  movq   0xaa5b(%rip), %rax        ; (void *)0x00007ff8511439b0: __stderrp
    0x104c216bd <+45>:  movq   (%rax), %rdi
    0x104c216c0 <+48>:  leaq   0x716f(%rip), %rsi        ; "Error: Failed to allocate memory for signature.\n"
    0x104c216c7 <+55>:  movb   $0x0, %al
    0x104c216c9 <+57>:  callq  0x104c263e6               ; symbol stub for: fprintf
    0x104c216ce <+62>:  movq   $0x0, -0x8(%rbp)
    0x104c216d6 <+70>:  jmp    0x104c21702               ; <+114> at xnuimagefuzzer.m:269:1
    0x104c216db <+75>:  movq   -0x10(%rbp), %rdi
    0x104c216df <+79>:  movabsq $0xfffffc000, %rsi        ; imm = 0xFFFFFC000 
    0x104c216e9 <+89>:  movl   $0x10, %edx
    0x104c216ee <+94>:  movq   $-0x1, %rcx
    0x104c216f5 <+101>: callq  0x104c263d4               ; symbol stub for: __memcpy_chk
->  0x104c216fa <+106>: movq   -0x10(%rbp), %rax
    0x104c216fe <+110>: movq   %rax, -0x8(%rbp)
    0x104c21702 <+114>: movq   -0x8(%rbp), %rax
    0x104c21706 <+118>: addq   $0x10, %rsp
    0x104c2170a <+122>: popq   %rbp
    0x104c2170b <+123>: retq   
(lldb) bt
* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0xfffffc000)
    frame #0: 0x00007ff80f981689 libsystem_platform.dylib`_platform_memmove$VARIANT$Haswell + 169
  * frame #1: 0x0000000104c216fa XNU Image Fuzzer`signature at xnuimagefuzzer.m:266:5
    frame #2: 0x0000000104c21afd XNU Image Fuzzer`dump_comm_page at xnuimagefuzzer.m:446:17
    frame #3: 0x0000000104c238d5 XNU Image Fuzzer`main(argc=5, argv=0x00007ff7bb2e02b0) at xnuimagefuzzer.m:1327:13
    frame #4: 0x00007ff80f5c9366 dyld`start + 1942
Message from debugger: killed
xsscx commented 7 months ago

// Reduced Fix

pragma mark - Headers

include

include

include

include

pragma mark - Constants

ifdef arm64

define COMM_PAGE64_BASE_ADDRESS (0x0000000FFFFFC000ULL)

elif defined(__x86_64__)

// Adjust this base address for x86_64 architectures as necessary

define COMM_PAGE64_BASE_ADDRESS (0x00007fffffe00000ULL)

endif

define COMM_PAGE_VERSION (COMM_PAGE64_BASE_ADDRESS + 0x01E)

...

define COMM_PAGE_CPU_CAPABILITIES64 (COMM_PAGE64_BASE_ADDRESS + 0x010)

const char *cpu_cap_strings[] = { "MMX", // Bit 0 ... "SGX", // Bit 37 };

pragma mark - Signature

char signature(void) { // Allocate memory using calloc; +1 for null terminator, initializing all bits to zero char signature = calloc(1, 0x10 + 1); // Replaces malloc(0x10 + 1) and initializes memory if (!signature) { fprintf(stderr, "Error: Failed to allocate memory for signature.\n"); return NULL; } memcpy(signature, (const char *)COMM_PAGE64_BASE_ADDRESS, 0x10); // No need to explicitly set the null terminator since calloc initializes the memory to zero return signature; }

pragma mark - Memory Reading Utilities

uint8_t read_uint8(uint64_t address) { uint8_t value = ((uint8_t )address); return value; }

uint16_t read_uint16(uint64_t address) { uint16_t value = ((uint16_t )address); return value; }

uint32_t read_uint32(uint64_t address) { uint32_t value = ((uint32_t )address); return value; }

uint64_t read_uint64(uint64_t address) { uint64_t value = ((uint64_t )address); return value; }

pragma mark - Comm Page Dump Function

void dump_comm_page(void) { printf("[] COMM_PAGE_SIGNATURE: %s\n", signature()); ... printf("[] COMM_PAGE_CPU_CAPABILITIES64:\n");

uint64_t cpu_caps = read_uint64(COMM_PAGE_CPU_CAPABILITIES64);
for (int i = 0, shift = 0; i < sizeof(cpu_cap_strings) / sizeof(void *); i++) {
    printf("\t%s: ", cpu_cap_strings[i]);
    if (shift == 16) {
        // Number of CPUs
        printf("%d\n", (int)(cpu_caps & 0x00FF0000) >> 16);
        // Jump to next relevant bits
        shift = 24;
        continue;
    }
    if (cpu_caps & (1ULL << shift)) {
        printf("true\n");
    } else {
        printf("false\n");
    }
    shift++;
}
printf("[*] Done dumping comm page.\n");

}

pragma mark - Main Function

int main(int argc, const char * argv[]) {

if !defined(arm64) && !defined(__x86_64__)

printf("Unsupported architecture.\n");
return -1;

endif

dump_comm_page();
return 0;

}

xsscx commented 6 months ago

Closing Note: The Issue has been resolved by creating Dead Code by adding Comments:

// dump_comm_page(); // dumpDeviceInfo(); // dumpMacDeviceInfo();

The Commit: https://github.com/xsscx/xnuimagefuzzer/commit/511f99b3a3ecaf392d86588b4d3d5fb26361b4c5

This Code is more appropriate for the iOS On Mac Interposing Code at URL https://github.com/xsscx/macos-research/tree/main/code/iOSOnMac