Informative Information for the Uninformed | ||||||||||||||
|
||||||||||||||
Index RegistersOn the PowerPC platform, immediate values are encoded using all 16 bits. If the assembled value of your immediate contains a NULL, you will need to find another way to load it into the target register. The most common technique is to first load a NULL-free value into a register, then substract that value minus the difference to your immediate.
;; ;; Demonstrate index register usage ;; main: li r7, 1999 ; place a NULL-free value into the index subi r5, r7, 1999-1 ; substract our value minus the target ; the r5 register is now set to 1 If you have a rough idea of the immediate values you will need in your shellcode, you can take this a step further. Set your initial index register to a value, that when decremented by the immediate value, actually results in a character of your choice. If you have two distant ranges (1-10 and 50-60), then consider using two index registers. The example below demonstrates an index register that works for the system call number as well as the arguments, leaving the assembled bytes NULL-free. As you can see, besides the four bytes required to set the index register, this method does not significantly increase the size of the code.
;; ;; Create a TCP socket without NULL bytes ;; main: li r7, 0x3330 ; 0x38e03330 = NULL-free index value subi r0, r7, 0x3330-97 ; 0x3807cd31 = system call for sys_socket subi r3, r7, 0x3330-2 ; 0x3867ccd2 = socket domain subi r4, r7, 0x3330-1 ; 0x3887ccd1 = socket type subi r5, r7, 0x3330-6 ; 0x38a7ccd6 = socket protocol .long 0x45585037 ; patched 'sc' instruction
|