Linux中基于ptrace的外挂程序设计

所谓的外挂程序就是在某个进程执行的过程中,其他进程可以动态的修改进程中的数据或代码,从而影响程序的执行路径,并最终影响程序的运行结果。在windows上我们有系统库函数writeprocess()可以直接完成该项功能。而在linux上没有相同功能的函数可以使用,不过使用ptrace也可以完成类似的功能。

首先,Ptrace的使用形式如下:

#include <sys/ptrace.h>

int ptrace(int request, int pid, int addr, int data);

Ptrace 提供了一种父进程可以控制子进程运行,并可以检查和改变它的核心image的方式。它主要用于实现断点调试。一个被跟踪的进程在运行中,发生一个信号的时候进程被中止,并且通知其父进程。在进程中止的状态下,进程的内存空间可以被读写。父进程还可以使子进程继续执行,并选择是否是否忽略引起中止的信号。

#include <sys/ptrace.h>

#include <sys/types.h>

#include <sys/wait.h>

#include <unistd.h>

#include <sys/syscall.h>

#include <sys/reg.h>

const int int_size = sizeof(int);

void putdata(pid_t child, int addr,   //向进程号为child的进程的addr这个地址空间写入str

char *str, int len)

{

char *laddr;

int i, j;

union u {

int val;

char chars[int_size];

}data;

i = 0;

j = len / int_size;

laddr = str;

while(i < j) {

memcpy(data.chars, laddr, int_size);

ptrace(PTRACE_POKEDATA, child,   //每次写入长度为int_size的数据

addr + i * 4, data.val);

++i;

laddr += int_size;

}

j = len % int_size;

if(j != 0) {

memcpy(data.chars, laddr, j);

ptrace(PTRACE_POKEDATA, child,

addr + i * 4, data.val);

}

}

int main()

{

pid_t child;

child = fork();

if(child == 0) {

ptrace(PTRACE_TRACEME, 0, NULL, NULL);  //设置自进程由父进程监控

execl("./test", "test", NULL);  //由父进程启动自进程

}

else

{

int orig_eax;

int params[3];

int status;

char *str, *laddr;

int toggle = 0;

while(1) {

wait(&status);  //阻塞自己,等待子进程信号

if(WIFEXITED(status))  // 子进程结束

break;

orig_eax = ptrace(PTRACE_PEEKUSER,   //获取寄存器信息

child, 4 * ORIG_EAX,

NULL);

if(orig_eax == SYS_write) {  //如果是写系统调用,修改细节具体参见系统write调用

params[0] = ptrace(PTRACE_PEEKUSER,

child, 4 * EBX,

NULL);

params[1] = ptrace(PTRACE_PEEKUSER,

child, 4 * ECX,

NULL);

params[2] = ptrace(PTRACE_PEEKUSER,

child, 4 * EDX,

NULL);

char* writedata =  "The winner of 100 billion dollars is:gagaga\n";

putdata(child, params[1],writedata,

params[2]);

}

ptrace(PTRACE_SYSCALL, child, NULL, NULL);  //设置子进程系统调用或者终止时暂停

}

}

return 0;

}

子进程代码:

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

int main()

{

srand((unsigned)(time(NULL)));

int i = 0;

for(i=0;i<120;i++)

{

int choose = rand()%4;

char* name="gagaga";

switch(choose)

{

case 0: name="hahaha";break;

case 1: name="papapa";break;

case 2: name="lalala";break;

}

printf("The winner of 100 billion dollars is:%s\n",name);

}

return 0;

}

这样在子进程系统调用write的时候,父进程就可以修改write的参数值,并进一步影响了信息的输出。

时间: 2024-10-08 04:52:07

Linux中基于ptrace的外挂程序设计的相关文章

【Apache学习】linux中基于ip、基于端口的虚拟主机

由于httpd服务核心主机和虚拟主机,两种方式水火不容,所以,要设置虚拟主机,首先需要关闭核心主机,即注释httpd主配文件中的 vim /etc/httpd/conf/httpd.conf 虚拟主机有三种工作模式: 基于IP 基于Port 基于Host 基于IP 实现如下要求的两台虚拟主机 使用的ip为192.168.56.169(虚拟机的ip),192.168.56.170(需要自己添加ip) 全局监听Listen 80 增加ip 物理机ping这两个ip 修改配置文件 按如下创建目录和内容

Linux中基于apache httpd的svn服务器搭建与配置

mod_dav_svn是apache连接svn的模块 yum install subversion mod_dav_svn httpd 配置文件简单说明, SVNParentPath 说明可以在指定的目录下,创建多个SVN项目 ----------------------- vim /etc/httpd/conf.d/subversion.conf LoadModule dav_svn_module     modules/mod_dav_svn.so LoadModule authz_svn_

Linux下基于文件描述符的文件操作(非缓冲)

1 文件描述符 内核为每个进程维护一个已打开文件的记录表(实现为结构体数组),文件描述符是一个较小的正整数(0-1023)(结构体数组下标),它代表记录表的一项,通过文件描述符和一组基于文件描述符的文件操作函数,就可以实现对文件的读.写.创建.删除等操作. 常用基于文件描述符的函数有open(打开).creat(创建).close(关闭).read(读取).write(写入).ftruncate(改变文件大小).lseek(定位).fsync(同步).fstat(获取文件状态).fchmod(权

Linux 中httpd基于文件的用户的访问控制和CGI

基于用户访问控制(这里控制的是整个页面控制)         用户认证类型:             基本认证:Basic             摘要认证:digest,是否明文还是密文的控制. 虚拟用户:仅用于访问某服务和获取资源的凭证:         用户帐号密码存放位置:.htpasswd 这个文件用户名是明文的,密码是加密的.这个文件的名字也是你自己取的,一般我们不改动.htpasswd存放在httpd配置文件下即可                 实例:我们这里基于文件的认证(文件

聊聊 Linux 中的五种 IO 模型

本文转载自: http://mp.weixin.qq.com/s?__biz=MzAxODI5ODMwOA==&mid=2666538919&idx=1&sn=6013c451b5f14bf809aec77dd5df6cff&scene=21#wechat_redirect 上一篇<聊聊同步.异步.阻塞与非阻塞>已经通俗的讲解了,要理解同步.异步.阻塞与非阻塞重要的两个概念点了,没有看过的,建议先看这篇博文理解这两个概念点.在认知上,建立统一的模型.这样,大家在

task_struct结构体字段介绍--Linux中的PCB

task_struct结构体 字段介绍 Linux内核通过一个被称为进程描述符的task_struct结构体来管理进程, task_struct是Linux中的[进程控制块PCB结构]的具体数据结构 这个结构体包含了一个进程所需的所有信息.它定义在linux-2.6.38.8/include/linux/sched.h文件中. 下面对task_struct这个结构体 进行各个字段的详细介绍 1. 调度数据成员(1) volatile long states;表示进程的当前状态:? TASK_RU

Android系统篇之----Android中的run-as命令引出升降权限的安全问题(Linux中的setuid和setgid)

一.前言 最近一周比较忙,没时间写东西了,今天继续开始我们今天的话题:run-as命令,在上周的开发中,遇到一个问题,就是在使用run-as命令的时候出现了一个错误,不过当时因为工作进度的问题,这问题就搁浅没有解决,用了其他一个曲线救国的方式去解决的.那么咋们今天闲来说说Android中的run-as命令吧. 二.遇到的问题&解决问题 Android中我们知道如果设备没有root,我们想看一个应用的沙盒数据(/data/data/目录内容),在以前的方式很难办到,一般人都是选择root之后,去查

Linux中的select,poll,epoll模型

Linux中的 select,poll,epoll 都是IO多路复用的机制. select select最早于1983年出现在4.2BSD中,它通过一个select()系统调用来监视多个文件描述符的数组,当select()返回后,该数组中就绪的文件描述符便会被内核修改标志位,使得进程可以获得这些文件描述符从而进行后续的读写操作.select目前几乎在所有的平台上支持,其良好跨平台支持也是它的一个优点,事实上从现在看来,这也是它所剩不多的优点之一.select的一个缺点在于单个进程能够监视的文件描

Linux 中的文件共享服务

Linux 中的文件共享服务 ============================================================================== 概述:    本章将主要介绍文件共享服务中的ftp服务,内容包括:ftp的程序环境,配置文件的相关介绍,以及如何配置基于虚拟用户的vsftpd服务 文件服务 1)介绍 ★ftp: 应用层,C/S架构,文件共享:file transfer protocol: ★nfs,cifs:文件系统接口,网络文件系统: ☉n