热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C-使用ptrace和waitpid进行分段错误

如何解决《C-使用ptrace和waitpid进行分段错误》经验,为你挑选了1个好方法。

对于C语言中的实验学校,我们必须编写一个进程(我们将称之为A),需要连接到另一个进程(B)并在函数中放置一个陷阱(陷阱指令是0xCC),所以我们做了但是当B输入是这个函数时,我们有一个分段错误

所以这是附加到其他进程的进程A.

#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char *argv[]) {

pid_t pidTargetProgram;
FILE *file;
int buf;
char path[50];
long long int address;


if (argc == 2) {
   fprintf(stderr, "Argument waited !\n");
   exit(1);
 }

// The second argument is the PID of the program 
pidTargetProgram = atoi(argv[1]);

// The third argument is the address of the function where we are going to put a trap
address = strtoll(argv[2], NULL, 16);

// We put the path to the file mem of the program 
sprintf(path, "/proc/%s/mem", argv[1]);

// We attach to the other program
if(ptrace(PTRACE_ATTACH, pidTargetProgram, NULL, NULL) <0) {
  perror("Error with ptrace_attach !");
  exit(1);
}

// We wait it to be synchronize
if (waitpid(pidTargetProgram, NULL, WUNTRACED) <0) {
  perror("Error with waitpid !\n");
  exit(0);
  }



// We open the file mem in read and write mode
  if ((file = fopen(path, "r+")) == NULL) {
    perror("Error during the opening of mem file from process !");
    exit(1);
  }



// We place our cursor on the address of the function
  fseek(file, address, SEEK_SET);

  char trap[] = {0xCC, 0x00, 0x00, 0x00};

  // We put the trap in the foo function
  if (fwrite(trap, 1, 5, file) <1) {
    perror("Error to write !");
    exit(1);
    }

  int counter = 0;

  fseek(file, address, SEEK_SET);

  // We print the other function's memory
  while (fread(&buf, 4, 1, file) > 0) {
    printf("Line n°%d : 0x%x\n", counter++, buf);
    }

  // We close the file
  if (fclose(file) != 0) {
    perror("Error during the closing !");
    exit(1);
  }

  // We said to continue to the other program
  if (ptrace(PTRACE_CONT, pidTargetProgram, NULL, NULL) <0) {
    perror("Error during ptrace_cont !\n");
    exit(1);
    }

  printf("continued !\n");

  // We wait the other program stop
  if (waitpid(pidTargetProgram, NULL, WUNTRACED) <0) {
    perror("Error with waitpid !\n");
    exit(0);
    }

  printf("Trace declenched !\n");

  // We detach 
  if (ptrace(PTRACE_DETACH, pidTargetProgram, NULL, NULL) <0) {
    perror("Error during ptrace_detach !");
    exit(1);
    }

  printf("detach success ! \n");

  return 0;
}

这是程序B:

#include 
#include 
#include 
#include 

// Function to execute to take the trap
void foo(){
  int i = 0;
  printf("foo :::: %d", i);
}

int main(int argc, char *argv[]) {

  char text[10];
  pid_t pidProgram;

  // We get the PID
  pidProgram = getpid();

  // We print the PID
  fprintf(stdout, "PID's program : %d\n", pidProgram);

  // We print the address of foo()
  fprintf(stdout, "foo address : %p\n", &(foo));

  // We stop the program to lunch the other program
  fgets(text, 10, stdin);

  int i;
  for(i = 0 ; i <100 ; i++){
    foo(i);
  }

  return 0;
}

为了执行此操作,我们首先启动B,因此它为我们提供了PID和地址,并在fgets处暂停.所以在那之后,我们启动程序A,我们给它PID和地址,它停在第二个waitpid.之后我们继续B并写一些东西,我们有一个分段错误并停止.我们不明白为什么因为在内存中我们可以清楚地看到陷阱(0xCC)并且它不起作用但是在程序A中,我们有Trace declenched!分离成功!

因此A上没有错误但B有分段错误

你对此有什么想法吗?我们使用Centos作为操作系统.对不起我的英语不好.

谢谢

朱利安



1> Ctx..:

该计划按预期工作:

首先,将运行过程映像更改为0xcc在函数开始时设置foo,这会触发断点/陷阱.

然后,在进程跟踪进程时调用此函数a.所以这个电话

waitpid(pidTargetProgram, NULL, WUNTRACED) <0) // Process a

回报.现在你从进程b中分离出来

ptrace(PTRACE_DETACH, pidTargetProgram, NULL, NULL);

但是,您之前没有恢复过程中的覆盖指令!因此,下一条指令已损坏并导致您观察到的段错误.此外,该过程在下一条指令PC + 1(直接在0xcc之后)重新启动,因此您需要使用一个字节将PC设置回一个字节PTRACE_GETREGS/PTRACE_SETREGS

顺便说一句.使用ptrace接口设置和重置断点指令PTRACE_POKETEXT而不是使用/proc/pid/mem方式更优雅.

TL; DR:您需要首先恢复原始指令并在重新启动进程b之前重置PC,然后它应该按预期工作.


推荐阅读
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • 本文介绍了在Windows系统上使用C语言命令行参数启动程序并传递参数的方法,包括接收参数程序的代码和bat文件的编写方法,同时给出了程序运行的结果。 ... [详细]
  • 本文介绍了GTK+中的GObject对象系统,该系统是基于GLib和C语言完成的面向对象的框架,提供了灵活、可扩展且易于映射到其他语言的特性。其中最重要的是GType,它是GLib运行时类型认证和管理系统的基础,通过注册和管理基本数据类型、用户定义对象和界面类型来实现对象的继承。文章详细解释了GObject系统中对象的三个部分:唯一的ID标识、类结构和实例结构。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • c语言\n不换行,c语言printf不换行
    本文目录一览:1、C语言不换行输入2、c语言的 ... [详细]
  • 本文介绍了使用PHP实现断点续传乱序合并文件的方法和源码。由于网络原因,文件需要分割成多个部分发送,因此无法按顺序接收。文章中提供了merge2.php的源码,通过使用shuffle函数打乱文件读取顺序,实现了乱序合并文件的功能。同时,还介绍了filesize、glob、unlink、fopen等相关函数的使用。阅读本文可以了解如何使用PHP实现断点续传乱序合并文件的具体步骤。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • Html5-Canvas实现简易的抽奖转盘效果
    本文介绍了如何使用Html5和Canvas标签来实现简易的抽奖转盘效果,同时使用了jQueryRotate.js旋转插件。文章中给出了主要的html和css代码,并展示了实现的基本效果。 ... [详细]
  • 浏览器中的异常检测算法及其在深度学习中的应用
    本文介绍了在浏览器中进行异常检测的算法,包括统计学方法和机器学习方法,并探讨了异常检测在深度学习中的应用。异常检测在金融领域的信用卡欺诈、企业安全领域的非法入侵、IT运维中的设备维护时间点预测等方面具有广泛的应用。通过使用TensorFlow.js进行异常检测,可以实现对单变量和多变量异常的检测。统计学方法通过估计数据的分布概率来计算数据点的异常概率,而机器学习方法则通过训练数据来建立异常检测模型。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • C语言判断正整数能否被整除的程序
    本文介绍了使用C语言编写的判断正整数能否被整除的程序,包括输入一个三位正整数,判断是否能被3整除且至少包含数字3的方法。同时还介绍了使用qsort函数进行快速排序的算法。 ... [详细]
author-avatar
迎风奔跑的狼
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有