Skip to content

Swap Swap Attack

Andrew Udvare edited this page Jun 4, 2018 · 4 revisions

Note: this may no longer be relevant.

This page describes the basics of the swap swap attack used in iOS application cracking.

The swap swap attack allows you to crack architectures compiled for a older instruction set, the basics of the attack is as follows:

- (BOOL)swapArchitecture:(cpu_subtype_t)swap_subtype
{
    if (self.local_cpu_subtype == swap_subtype)
    {
        /* Arch doesn't need to be swapped... */
        return YES;
    }
    
    char swap_buffer[4096];
    
    ...
    Generation of paths, etc
    ...
    
    FILE *swap_binary = fopen(swapBinaryPath.UTF8String, "r+");
    
    fseek(swap_binary, 0, SEEK_SET);
    fread(&swap_buffer, sizeof(swap_buffer), 1, swap_binary);
    
    /* Get the header */
    struct fat_header *swap_fat_header = (struct fat_header *)(swap_buffer);
    struct fat_arch *arch = (struct fat_arch *)&swap_fat_header[1];
    
    cpu_type_t cpu_type_to_swap = 0;
    cpu_subtype_t largest_cpu_subtype = 0;
    
    /* Interate the archs in the header, hopefully we find a swap */
    for (int i = 0; i < CFSwapInt32(swap_fat_header->nfat_arch); i++)
    {
        if (arch->cpusubtype == swap_subtype)
        {
            NSLog(@"found cpu type to swap to: %@\n", [self readableSubtypeName:swap_subtype]);
            cpu_type_to_swap = arch->cputype;
        }
        
        if (arch->cpusubtype > largest_cpu_subtype)
        {
            largest_cpu_subtype = arch->cpusubtype;
        }
        
        arch++;
    }
    
    /* Reset our arch structure */
    arch = (struct fat_arch *)&swap_fat_header[1];
    
    
    /* Actually perform the swap swap attack */
    for (int i = 0; i < CFSwapInt32(swap_fat_header->nfat_arch); i++)
    {
        if (arch->cpusubtype == largest_cpu_subtype)
        {
            if (cpu_type_to_swap != arch->cputype)
            {
                NSLog(@"ERROR: cpu types are incompatible.");
                return FALSE;
            }
            
            arch->cpusubtype = swap_subtype;
        }
        else if (arch->cpusubtype == swap_subtype)
        {
            arch->cpusubtype = largest_cpu_subtype;
            NSLog(@"Replaced %@'s cpu subtype with %@", [self readableSubtypeName:CFSwapInt32(arch->cpusubtype)], [self readableSubtypeName:CFSwapInt32(largest_cpu_subtype)]);
        }
        
        arch++;
    }
    
    /* Write new header to binary */
    fseek(swap_binary, 0, SEEK_SET);
    fwrite(swap_buffer, sizeof(swap_buffer), 1, swap_binary);
    fclose(swap_binary);
    
    /* Move the SC_Info keys, this is because caching will make the OS load up the old arch */
   ...
   return TRUE;
}

We swap out the cpu_subtype of the current architecture with the cpu_subtype of architecture we want to crack. This forces the OS to load the 'swapped' architecture thereby making it crackable.

Clone this wiki locally