首先使用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, &regs); //获取寄存器参数
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, &regs); //将write的输出从标准输出改为fp
}
ptrace(PTRACE_SYSCALL, child, NULL, NULL); //继续trace }
}
close(fp);
return 0;
}

使用ptrace将标准输出重定位到文件的更多相关文章

  1. 南京大学计算机基础 X64函数调用和链接器原理和可重定位的文件.o

    一. 1.函数调用差别 X64的函数调用,和X86函数调用区别,在于参数的传递不一样了,X64的参数传递不在依靠栈来传,而是寄存器,不过还是具有局限性的 比如只能允许六个寄存器来传,分别是RDI,RS ...

  2. [CSAPP-II] 链接[符号解析和重定位] 静态链接 动态链接 动态链接接口

    1 平台 转http://blog.csdn.net/misskissc/article/details/43063419 1.1 硬件 Table 1. 硬件(lscpu) Architecture ...

  3. 《CSAPP》 可重定位目标文件格式

    可重定位目标文件 ELF文件 ELF头以一个16字节的序列开始,这个序列描述了生成该文件的系统的字的大小和字节顺序.ELF头剩下的部分包含帮助链接器语法分析和解释目标文件的信息.其中包括ELF头的大小 ...

  4. ELF学习--重定位文件

    add.c int data = 1;int bss;const int rodata = 1;int add(int num1, int num2){ int sum = 0; sum = num1 ...

  5. PE文件 03 重定位表

    0x01  重定位表结构   重定位表是由数据目录表中的第六个成员指出的: typedef struct _IMAGE_DATA_DIRECTORY { DWORD VirtualAddress; D ...

  6. 关于C++中的重定位

    "标准库定义了4个IO对象,处理输入时使用命名为cin的istream类型对象,这个对象也成为标准输入.处理输出时使用命名为cout的ostream类型对象,这个对象也称为标准输出.标准库还 ...

  7. Reverse Core 第二部分 - 16&17章 - 基址重定位表&.reloc节区

    第16-17章 - 基址重定位表&.reloc节区 @date: 2016/11/31 @author: dlive 0x00 前言 这几天忙着挖邮箱漏洞,吃火锅,马上要被关禁闭,看书进度比较 ...

  8. ELF Format 笔记(十)—— 重定位(relocation)

    ilocker:关注 Android 安全(新手) QQ: 2597294287 重定位就是把符号引用与符号定义链接起来的过程,这也是 android linker 的主要工作之一. 当程序中调用一个 ...

  9. [PE结构分析] 10.基址重定位

    源代码如下: typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; // WORD Type ...

  10. 小甲鱼PE详解之基址重定位详解(PE详解10)

    今天有一个朋友发短消息问我说“老师,为什么PE的格式要讲的这么这么细,这可不是一般的系哦”.其实之所以将PE结构放在解密系列继基础篇之后讲并且尽可能细致的讲,不是因为小甲鱼没事找事做,主要原因是因为P ...

随机推荐

  1. 咕咕list

    做完以后会留在榜上一天,这样显得咕咕list长一些 CF666E Forensic Examination(done on 2023.2.6) dp选做

  2. linux环境下部署mysql环境

    一.部署步骤 1.将安装包上传到Linux服务器上(目录随意),然后解压缩 2.进入到解压后的目录下,分别执行以下命令安装四个包(严格按照顺序执行) rpm -ivh mysql-community- ...

  3. 如何获取obs视频帧的二进制数据

    前面几篇文章梳理了obs的录屏和推流流程,几条纵线整理下来,算是基本理清了obs的工作流程. 现在回到第一个目标:捕捉桌面的帧数据,用rendertarget显示并输出到UE5材质. 那么,帧数据到底 ...

  4. 字符串常见API(charCodeAt\fromCharCode)

    1.myStr.charCodeAt(num) 返回指定位置的字符的Unicode(是字符编码的一种模式)编码. 2.String.fromCharCode() String的意思就是不能用自己定义的 ...

  5. PyQt5学习 (2)--QWidget(上)

    描述:   1.所有可视控件的基类   2.是一个最简单的空白控件   3.控件时用户界面的最小元素:接收各种事件.绘制在桌面上,展示给用户看   4.每个控件都是矩形的,它们按Z轴顺序排序   5. ...

  6. 最新centos7 部署 k8s v1.26,简单易懂,跟着命令敲就完事

    其实没什么好说的,搭环境搞了一整天,人已经麻了,踩了很多坑,网上教程的版本大都比较旧,总是和最新版本各种地方不兼容,把坑踩完了,k8s目前最新的版本是v1.26,跟着命令敲就行了,我已经重复部署了很多 ...

  7. python入门教程之五数据结构

    变量 Python 变量类型 变量存储在内存中的值,这就意味着在创建变量时会在内存中开辟一个空间. 基于变量的数据类型,解释器会分配指定内存,并决定什么数据可以被存储在内存中. 因此,变量可以指定不同 ...

  8. [Linux/Git]比较两份文件的差异

    Command vim -d fileA fileB 或 git diff <oldCommitId> <newCommitId> X Recommend Files Matc ...

  9. [工具/Maven]Maven工程目录结构 | Maven自动构建骨架(maven-archetype)中quickstart与webapp的区别

    1 maven-archetype-quickstart 1.1 IDEA中的前期准备 1.2 自动构建后 ↓pom.xml↓ <?xml version="1.0" enc ...

  10. 虚拟机安装linux操作系统中IP设置

    问题描述:用虚拟机安装linux操作系统时,不选择分配IP,系统默认会分配动态IP,如果是临时搭建,就可以默认动态IP,也可以使用连接工具连接虚拟机.但如果是长期使用,选择使用固定的IP会更好,需要手 ...