使用ptrace将标准输出重定位到文件
首先使用PTRACE_SYSCALL获取到系统调用号,如果是write则将文件描述符从标准输出变为我们打开的文件
#include <stdio.h>
#include <fcntl.h>
#include <sys/reg.h>
#include <sys/user.h>
#include <sys/wait.h>
#include <sys/ptrace.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>
using namespace std;
#if __WORDSIZE == 64
#define REG(reg) reg.orig_rax
#else
#define REG(reg) reg.orig_eax
#endif
const int long_size = sizeof(int);
//获取addr处也就是buf参数
void getdata(pid_t child, long addr,
char *str, int len)
{ char *laddr;
int i, j;
union u {
int val;
char chars[long_size];
}data;
i = 0;
j = len / long_size;
laddr = str;
while(i < j) {
data.val = ptrace(PTRACE_PEEKDATA, child,
addr + i * 4, NULL);
memcpy(laddr, data.chars, long_size);
++i;
laddr += long_size;
}
j = len % long_size;
if(j != 0) {
data.val = ptrace(PTRACE_PEEKDATA, child,
addr + i * 4, NULL);
memcpy(laddr, data.chars, j);
}
str[len] = '\0';
}
int main(int argc, char *argv[]){
int fp;
fp = open("./a.txt",O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IROTH);
pid_t child;
int status;
int64_t sys_num = -1;
child = fork();
if(child == 0){
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
execl("/bin/ls", "ls", NULL); //子进程标记为trace,并执行ls
}else{
while(1){
struct user_regs_struct regs;
wait(&status);
if(WIFEXITED(status))
break;
ptrace(PTRACE_SYSCALL, child, NULL, NULL); //在系统调用处发送信号到父进程
waitpid(child, &status, 0);
ptrace(PTRACE_GETREGS, child, NULL, ®s); //获取寄存器参数
sys_num=REG(regs);
if(sys_num==1){ //write调用的系统调用号
printf("syscall write\n");
printf("change I/O from %llu to file\n",regs.rdi);
size_t size = regs.rdx;
char * buffer = new char[size]; //存储write的数据
getdata(child, regs.rsi, buffer, size);
printf("%s\n",buffer);
regs.rdi = fp;
ptrace(PTRACE_SETREGS, child, 0, ®s); //将write的输出从标准输出改为fp
}
ptrace(PTRACE_SYSCALL, child, NULL, NULL); //继续trace
}
}
close(fp);
return 0;
}
使用ptrace将标准输出重定位到文件的更多相关文章
- 南京大学计算机基础 X64函数调用和链接器原理和可重定位的文件.o
一. 1.函数调用差别 X64的函数调用,和X86函数调用区别,在于参数的传递不一样了,X64的参数传递不在依靠栈来传,而是寄存器,不过还是具有局限性的 比如只能允许六个寄存器来传,分别是RDI,RS ...
- [CSAPP-II] 链接[符号解析和重定位] 静态链接 动态链接 动态链接接口
1 平台 转http://blog.csdn.net/misskissc/article/details/43063419 1.1 硬件 Table 1. 硬件(lscpu) Architecture ...
- 《CSAPP》 可重定位目标文件格式
可重定位目标文件 ELF文件 ELF头以一个16字节的序列开始,这个序列描述了生成该文件的系统的字的大小和字节顺序.ELF头剩下的部分包含帮助链接器语法分析和解释目标文件的信息.其中包括ELF头的大小 ...
- ELF学习--重定位文件
add.c int data = 1;int bss;const int rodata = 1;int add(int num1, int num2){ int sum = 0; sum = num1 ...
- PE文件 03 重定位表
0x01 重定位表结构 重定位表是由数据目录表中的第六个成员指出的: typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; D ...
- 关于C++中的重定位
"标准库定义了4个IO对象,处理输入时使用命名为cin的istream类型对象,这个对象也成为标准输入.处理输出时使用命名为cout的ostream类型对象,这个对象也称为标准输出.标准库还 ...
- Reverse Core 第二部分 - 16&17章 - 基址重定位表&.reloc节区
第16-17章 - 基址重定位表&.reloc节区 @date: 2016/11/31 @author: dlive 0x00 前言 这几天忙着挖邮箱漏洞,吃火锅,马上要被关禁闭,看书进度比较 ...
- ELF Format 笔记(十)—— 重定位(relocation)
ilocker:关注 Android 安全(新手) QQ: 2597294287 重定位就是把符号引用与符号定义链接起来的过程,这也是 android linker 的主要工作之一. 当程序中调用一个 ...
- [PE结构分析] 10.基址重定位
源代码如下: typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; // WORD Type ...
- 小甲鱼PE详解之基址重定位详解(PE详解10)
今天有一个朋友发短消息问我说“老师,为什么PE的格式要讲的这么这么细,这可不是一般的系哦”.其实之所以将PE结构放在解密系列继基础篇之后讲并且尽可能细致的讲,不是因为小甲鱼没事找事做,主要原因是因为P ...
随机推荐
- Z 函数
简单记一下,避免忘记. z 函数 对于字符串 \(S\),我们将 \(z(i)\) 定义为从 \(i\) 开始的后缀与 \(S\) 的最长公共前缀的长度. \(O(n)\) 求出 z 函数 我们添加一 ...
- Centos 7安装ansible自动化运维工具
1.介绍: ansible是新出现的自动化运维工具,基于Python开发,集合了众多运维工具(puppet.SaltStack.chef.func)的优点,实现了批量系统配置.批量程序部署.批 ...
- HashMap和ConcurrentHashMap扩容过程
HashMap 存储结构 HashMap是数组+链表+红黑树(1.8)实现的. (1)Node[] table,即哈希桶数组.Node是内部类,实现了Map.Entry接口,本质是键值对. 下图链表中 ...
- CSS实现文字颜色渐变效果
略微搜索查阅了网上的实现方法: 1.给元素添加背景渐变色,通过背景裁剪其中文字,再将文字设置为透明即可实现.(兼容性问题请自行添加浏览器前缀) background-color:linear-grad ...
- VUE中的$set与$delete的原理
我们上文说了,Vue 是通过 Object.defineProperty 和重写数组的原型方法来达到监控数据的目的.但是,在某些情况下,上面两种方案无法做到监控数据的变化,例如: (1):当我们给对象 ...
- vue3 封装el-table时,构造$children(类式写法)
由于业务需求(组件封装),需要在获取el-table下面的el-table-column实例 在 vue2.x 当中直接使用this.$children就可以获取到该实例 但是 vue3.x 弃用了$ ...
- scoket用法
一.scoket基本介绍 1.scoket简介(以下是来自chatgpt回答) 1)Socket(套接字)是计算机网络中用于描述主机之间通信的一种机制.它定义了一种标准的接口, 使得应用程序可以利用网 ...
- mapper接口中常见的增删改查
前言 相信大家在使用mybatis写mapper接口的时候,最常用且简单的方法就是增删改查了.我也是刚开始做项目,在本篇文章中,我将根据自己在vhr微人力项目中的mapper接口方法为实例,记录一下接 ...
- okio中数据存储的基本单位Segment
1.Segment是Buffer缓冲区存储数据的基本单位,每个Segment能存储的最大字节是8192也就是8k的数据 /** The size of all segments in bytes. * ...
- MySQL(八)哈希索引、AVL树、B树与B+树的比较
Hash索引 简介 这部分略了 Hash索引效率高,为什么还要设计索引结构为树形结构? Hash索引仅能满足 =.<>和IN查询,如果进行范围查询,哈希的索引会退化成O(n):而树型的 ...