Shellcode on AIX 7.x PPC64 vs AIX 5.x/6.x PPC32 1. Function Descriptors (The Biggest Challenge) On 32-bit AIX, function pointers directly point to executable code. You can just jump to an address and start running. On 64-bit AIX 7.x, functions use a 3-part descriptor structure: - Entry point (where the code actually is) - TOC pointer (Table of Contents register r2 - points to global data) - Environment pointer On 64-bit AIX 7.x, shellcode can't just call system() by address anymore. You must: 1. Load the descriptor address 2. Extract the entry point from offset 0 3. Extract the TOC from offset 8 4. Load TOC into register r2 5. THEN call the function This adds ~20 extra bytes and complexity to every function call. 2. 64-bit Addresses Are Harder to Load 32-bit: Loading an address takes 2 instructions: lis r9, 0x1234 # Load upper 16 bits ori r9, r9, 0x5678 # Add lower 16 bits 64-bit: Loading an address takes 5 instructions: lis r9, hw1 # Bits 48-63 ori r9, r9, hw2 # Bits 32-47 rldicr r9, r9, 32 # Shift left 32 bits oris r9, r9, hw3 # Bits 16-31 ori r9, r9, hw4 # Bits 0-15 This makes shellcode 2-3x larger for the same functionality. 3. The TOC Register Problem The TOC (Table of Contents) register r2 must be set correctly or your program crashes. On 32-bit, there was no TOC. On 64-bit: - Every function expects r2 to point to the right data area - If you call a library function with the wrong TOC, it crashes - Shellcode must either preserve the current TOC or load the correct one for each function call - This requires saving r2 on the stack and restoring it after calls 4. Bigger Stack Frames 32-bit: Stack slots are 4 bytes, minimum frame ~32 bytes 64-bit: Stack slots are 8 bytes, minimum frame 128+ bytes: - Link register save at offset 16 (not 8) - TOC save area at offset 40 - Parameter area starts at offset 48 - Local variables need more space 5. Hardcoded Addresses Don't Work Across Systems On 64-bit AIX 7.x, library addresses change between: - Different AIX versions (7.2 vs 7.3) - Different patch levels - Different service packs 6. NX/DEP Protection Modern AIX 7.x has non-executable stack by default: - You can't just put shellcode on the stack and jump to it - Need ROP (Return-Oriented Programming) chains - Must reuse existing code snippets ("gadgets") - Way more complex than direct shellcode injection 7. Shellcode size comparison For spawning /bin/sh using system(): - 32-bit AIX: ~40-50 bytes - 64-bit AIX 7.x: 104 bytes The 64-bit version is over twice as large due to: - Function descriptor handling (20 bytes) - 64-bit address loading (40+ bytes) - Stack frame setup/teardown (24 bytes) - TOC save/restore (8 bytes) AIX 7.3 PPC64 shellcoding is fundamentally harder because every function call requires understanding and manipulating a 3-level indirection system (descriptors + TOC), addresses are twice as long, and modern protections like NX make direct code injection impossible without ROP chains.