• ptrace 人人小站


    学了一周的ptrace,很多细节没有研究到。勉强交个自己打及格分的报告吧。希望高手轻喷~

        Ptracelinux提供的系统函数。具体可以在子进程处设置断点。当子进程到达断点时,暂停并通知父进程。此时,父进程可以看到子进程所有内存状态。并且可以直接获取或者修改寄存器等数据。甚至可以插入代码到子进程中。

        网上有很多利用ptrace漏洞的。大概思路是说,可以调试超级权限的进程,插入代码到其中,使普通用户具备超级权限。具体感兴趣的同学可以上网学习。

        插入代码有两个思路。一个思路是,直接将代码指令插入到子进程eip指向的内存空间。这里需要注意的是,peektextpoketext都是以4个字节为单位,对内存进行读写。所以,如果需要对原来的代码段指令进行备份,应该以4个字节为单位进行备份。不然,可能会在代码中出现乱码。这些乱码对应的指令代码可能会访问没有权限的位置。就会出现段错误。

        另一个思路是,将代码指令插入到子进程对应的自由空间中。并且将eip设置到对应的位置,使子进程可以执行替代后的指令。进程被分配的空间,可以在/proc/pid/maps文件里面看到。这里需要注意,如果插入指令,最好找代码段,并且对源代码进行备份。我看到一份资料里面,作者将指令插入到bss段里面,然后将eip设为bss段的起始位置。因为bss段可读可写不可执行,当指令执行到这个线性地址空间,当然因为访问权限不够出现段错误。

    下面是一些参数和基本用法。

    PTRACE_ME

    ptrace(PTRACE_ME,0,0,0)

    子进程进入调试模式。

     

    PTRACE_CONT

    ptrace(PTRACE_CONT,pid,0,0)

    让子进程继续执行,子进程不再进入调试模式。

     

    PTRACE_SYSCALL

    ptrace(PTRACE_SYSCALL,pid,0,0)

    1、进入系统功能调用之前

    2、退出系统功能调用之后

    3、子进程结束

    PTRACE_SINGLESTEP

    Ptrace(PTRACE_SINGLESTEP,pid,0,0)

    子进程单步执行

    PTRACE_ATTACH

    ptrace(PTRACE_ATTACH,pid,0,0)

    设置子进程为调试模式。

    具体:设置pid对应的子进程为当前进程的子进程。设置子进程为调试模式。

     

    PTRACE_DETACH

    解除子进程的调试

     

    PTRACE_PEEKTEXT

    PTRACE_POKETEXT

    long  ptrace(PTRACE_PEEKTEXT, int pid , long offset , 0);

    从代码段的offset处取得数据。数据大小是4个字节。

    ptrace(PTRACE_POKETEXT, int pid , long offset , long data);

    将数据data写入到代码段的offset处。数据大小是4个字节。

     

    PTRACE_PEEKDATA

    PTRACE_POKEDATA

    long  ptrace(PTRACE_PEEKDATA, int pid , long offset , 0);

    从数据段的offset处取得数据。数据大小是4个字节。

    ptrace(PTRACE_POKEDATA, int pid , long offset , long data);

    将数据data写入到数据段的offset处。数据大小是4个字节。

     

     

    PTRACE_PEEKUSER

    PTRACE_POKEUSER

    从用户区域取得数据,返回值在offset处取4个字节

    long reg = ptrace(PTRACE_PEEKUSER , int pid , long offset  ,NULL);

    将数据写入到user区。写入的是4个字节。

    ptrace(PTRACE_POKEUSER, int pid , long offset , long data);

    其中,data是写入的long型数据。

    Offset/4可以取EAX(如下)等。

    #define EBX 0

    #define ECX 1

    #define EDX 2

    #define ESI 3

    #define EDI 4

    #define EBP 5

    #define EAX 6

    #define DS 7

    #define ES 8

    #define FS 9

    #define GS 10

    #define ORIG_EAX 11

    #define EIP 12

    #define CS  13

    #define EFL 14

    #define UESP 15

    #define SS   16

    用户区的结构体:

    struct user32 {

      struct user_regs_struct32 regs; /* Where the registers are actually stored */

      int u_fpvalid;            /* True if math co-processor being used. */

                                /* for this mess. Not yet used. */

      struct user_i387_ia32_struct i387;      /* Math Co-processor registers. */

    /* The rest of this junk is to help gdb figure out what goes where */

      __u32 u_tsize;  /* Text segment size (pages). */

      __u32 u_dsize; /* Data segment size (pages). */

      __u32 u_ssize; /* Stack segment size (pages). */

      __u32 start_code;     /* Starting virtual address of text. */

      __u32 start_stack;  /* Starting virtual address of stack area.

                                   This is actually the bottom of the stack,

                                   the top of the stack is always found in the

                                   esp register.  */

      __u32 signal;              /* Signal that caused the core dump. */

      int reserved;                   /* No __u32er used */

      __u32 u_ar0;   /* Used by gdb to help find the values for */

                                /* the registers. */

      __u32 u_fpstate;     /* Math Co-processor pointer. */

      __u32 magic;          /* To uniquely identify a core file */

      char u_comm[32];          /* User command that was responsible */

      int u_debugreg[8];

    };

     

     

     

    PTRACE_GETREGS

    PTRACE_SETREGS

    取得寄存器的值

    struct user_regs_struct regs

    ptrace(PTRACE_GETREGS , int pid , NULL , & regs);

    设置寄存器的值

    struct user_regs_struct regs

    ptrace(PTRACE_SETREGS , int pid , NULL , & regs);

     

    struct user_regs_struct {

           unsigned long      bx;

           unsigned long      cx;

           unsigned long      dx;

           unsigned long      si;

           unsigned long      di;

           unsigned long      bp;

           unsigned long      ax;

           unsigned long      ds;

           unsigned long      es;

           unsigned long      fs;

           unsigned long      gs;

           unsigned long      orig_ax;

           unsigned long      ip;

           unsigned long      cs;

           unsigned long      flags;

           unsigned long      sp;

           unsigned long      ss;

    };

    PTRACE_GETFPREGS,

    PTRACE_SETFPREGS


  • 相关阅读:
    推荐大家使用的CSS书写规范、顺序
    只能输入数字的文本框
    js和jQuery 获取屏幕高度、宽度
    jquery插件开发规范
    ie下使用firebug
    equals和==的使用
    引用数据类型的赋值
    数组工具Arrays的基本使用
    冒泡排序
    使用数组对杨辉三角练习
  • 原文地址:https://www.cnblogs.com/robbychan/p/3786620.html
Copyright © 2020-2023  润新知