当前位置:网站首页 > 黑客培训 > 正文

详解pwn-内核相关知识(2)

freebuffreebuf 2021-06-02 499 0

本文来源:星云博创

0x00:前言

本篇文章接着内核中断(1)来进行源码的分析,文章难度较大,需要一定的汇编基础。中断分为两种:有错误码中断和无错误码中断,接下来我们来看正文部分。

0x01:源码

/* linux/kernel/asm.s */ .globl _divide_error,_debug,_nmi,_int3,_overflow,_bounds,_invalid_op .globl _double_fault,_coprocessor_segment_overrun .globl _invalid_TSS,_segment_not_present,_stack_segment .globl _general_protection,_coprocessor_error,_irq13,_reserved  _divide_error:   pushl $_do_divide_error  no_error_code:   xchgl %eax,(%esp)   pushl %ebx   pushl %ecx   pushl %edx   pushl %edi   pushl %esi   pushl %ebp   push %ds   push %es   push %fs   pushl $0    # "error code"   lea 44(%esp),%edx   pushl %edx   movl $0x10,%edx   mov %dx,%ds   mov %dx,%es   mov %dx,%fs   call *%eax   addl $8,%esp   pop %fs   pop %es   pop %ds   popl %ebp   popl %esi   popl %edi   popl %edx   popl %ecx   popl %ebx   popl %eax   iret  _debug:   pushl $_do_int3    # _do_debug   jmp no_error_code  _nmi:   pushl $_do_nmi   jmp no_error_code  _int3:   pushl $_do_int3   jmp no_error_code  _overflow:   pushl $_do_overflow   jmp no_error_code  _bounds:   pushl $_do_bounds   jmp no_error_code  _invalid_op:   pushl $_do_invalid_op   jmp no_error_code  _coprocessor_segment_overrun:   pushl $_do_coprocessor_segment_overrun   jmp no_error_code  _reserved:   pushl $_do_reserved   jmp no_error_code  _irq13:   pushl %eax   xorb %al,%al   outb %al,$0xF0   movb $0x20,%al   outb %al,$0x20   jmp 1f 1:  jmp 1f 1:  outb %al,$0xA0   popl %eax   jmp _coprocessor_error  _double_fault:   pushl $_do_double_fault  error_code:   xchgl %eax,4(%esp)    # error code -> %eax   xchgl %ebx,(%esp)    # -> %ebx   pushl %ecx   pushl %edx   pushl %edi   pushl %esi   pushl %ebp   push %ds   push %es   push %fs   pushl %eax      # error code   lea 44(%esp),%eax    # offset   pushl %eax   movl $0x10,%eax   mov %ax,%ds   mov %ax,%es   mov %ax,%fs   call *%ebx   addl $8,%esp   pop %fs   pop %es   pop %ds   popl %ebp   popl %esi   popl %edi   popl %edx   popl %ecx   popl %ebx   popl %eax   iret _invalid_TSS:   pushl $_do_invalid_TSS   jmp error_code _segment_not_present:   pushl $_do_segment_not_present   jmp error_code _stack_segment:   pushl $_do_stack_segment   jmp error_code _general_protection:   pushl $_do_general_protection   jmp error_code

0x02:分析

该文件主要是定义了CPU异常产生的中断函数的调用。

分成2类:

带返回错误码的中断调用

不带返回错误码的中断调用

v2-5cf8047241a2a2c13aa2863ffa3a6355_720w.png

v2-9a1c5dd357e24cb31a592ca014af8068_720w.png

将所有的寄存器值入栈

SS:存放栈顶的段地址
SP:存放栈顶的偏移地址

一个栈也就是一块内存区域,我们必须要有基地址(也就是段地址左移4位)和偏移地址。

要在一个栈中寻址的话,也需要段地址和偏移地址。

-------------------------------------------------------------------------------------------------------------------

CS:代码段寄存器
IP:指令段寄存器

CS:IP 指向可执行程序的起始地址

此后CPU从这个起始地址开始读取内存中的指令,并且执行。

CS:IP指向

1.你想让 CPU 执行哪行指令,你就让 CS:IP 指向保存有指令的那块内存即可。

2.任何时候,CS:IP 指向的地址中的内容都是 CPU 当前执行的指令。

-------------------------------------------------------------------------------------------------

前四步:

v2-854cdd4985a1b91351243924de887403_720w.png

===================================================

xchgl %eax,(%esp)

将eax的值保存在栈上,将中断处理函数的地址保存在eax寄存器中

xchg 交换eax 和esp的值

ESP 专门用作堆栈指针,被形象地称为栈顶指针

EAX是累加器,AX是算术的主要寄存器

asm.s包含着CPU探测到故障异常的底层代码程序,与traps.c关系密切,调用traps.c的程序打印出错信息,并退出。

v2-24be3b8fde9d7123d39e4ce88aae4b34_720w.png

对于不带出错号的中断过程,堆栈指针位置变化情况请参照图(a)。

在开始执行相应中断服务程序之前,堆栈指针esp指在中断返回地址一栏(图中 esp0处)。

当把将要调用的C函数do_ _divide_ error()或其他C函数地址入栈后,指针位置是esp1处,此时程序使用交换指令把该函数的地址放入eax寄存器中,而原来eax的值则被保存到堆栈上。

此后程序在把一些寄存器入栈后,堆栈指针位置处于esp2处。

当正式调用do_ divide_ error()之前, 程序会将开始执行中断程序时的原eip 保存位置(即堆栈指针esp0值)压入堆栈,放到esp3位置处,并在中断返回弹出入栈的寄存器之前指针通过加上8又回到esp2处。

对于CPU会产生错误号的中断过程,堆栈指针位置变化情况请参照图(b)。

在刚开始执行中断服务程序之前,堆栈指针指向图中esp0处。

在把将要调用的C函数do_ double_ fault()或其 他C函数地址入栈后,栈指针位置是esp1处。

此时程序通过使用两个交换指令分别把eax、ebx寄存器的值保存在esp0、esp1位置处,而把出错号交换到eax寄存器中:函数地址交换到了ebx寄存器中。随后的处理过程则和无错误号一样。

----------------------------------------------------------------------------------------

一般寄存器:AX、BX、CX、DX

AX:累积暂存器,BX:基底暂存器,CX:计数暂存器,DX:资料暂存器

索引暂存器:SI、DI

SI:来源索引暂存器,DI:目的索引暂存器

堆叠、基底暂存器:SP、BP

SP:堆叠指标暂存器,BP:基底指标暂存器

cs是代码段寄存器

ds是数据段寄存器

ss是堆栈段寄存器

es是扩展段寄存器

fs是标志段寄存器

gs是全局段寄存器

----------------------------------------------------------------------------------------

把这些寄存器入栈保护

pushl %ebx

pushl %ecx

pushl %edx

pushl %edi

pushl %esi

pushl %ebp

push %ds

push %es

push %fs

v2-698ed2aca088fe2fe0d381cccb314074_720w.png

-----------------------------------------------------------------------------------------------

无错误号的代码:

核心代码:xchg1  %eax,(%esp)  交换ax和sp                   push  $0     0作为错误号压栈                   lea 44(%esp), %edx  把中断的地方压栈                   call  *%eax   调用中断打印函数                   add1 $8  %esp   函数的参数出栈

v2-ece3dbd783b28fd75f0ae9278ea91837_720w.png

----------------------------------------------------------------------------------------

有错误号的代码:

error_code:

0x03:小结

此篇文章主要讲解了中断的工作原理,下篇文章我们一起来看8086 PC机的8259A中断原理。

转载请注明来自网盾网络安全培训,本文标题:《详解pwn-内核相关知识(2)》

标签:pwn

关于我

欢迎关注微信公众号

关于我们

网络安全培训,黑客培训,渗透培训,ctf,攻防

标签列表

Powered By Z-BlogPHP 1.7.3