返回顶部
首页 > 资讯 > 精选 >C程序和子进程
  • 848
分享到

C程序和子进程

2024-02-22 12:02:52 848人浏览 八月长安
摘要

问题内容 我编写了这个简单的 c 程序来解释具有相同特征的更困难的问题。 #include <stdio.h> int main(int arGC, char *argv

问题内容

我编写了这个简单的 c 程序来解释具有相同特征的更困难的问题。

#include <stdio.h>

int main(int arGC, char *argv[])
{
    int n;
    while (1){
        scanf("%d", &n);
        printf("%d\n", n);
    }
    return 0;
}

它按预期工作。

我还编写了一个子进程脚本来与该程序交互:

from subprocess import popen, pipe, stdout

process = popen("./a.out", stdin=pipe, stdout=pipe, stderr=stdout)

# sending a byte
process.stdin.write(b'3')
process.stdin.flush()

# reading the echo of the number
print(process.stdout.readline())

process.stdin.close()

问题是,如果我运行 python 脚本,执行会在 readline() 上冻结。事实上,如果我中断脚本,我会得到:

/tmp » Python script.py
^ctraceback (most recent call last):
  file "/tmp/script.py", line 10, in <module>
    print(process.stdout.readline())
          ^^^^^^^^^^^^^^^^^^^^^^^^^
keyboardinterrupt

如果我更改我的 python 脚本:

from subprocess import popen, pipe, stdout

process = popen("./a.out", stdin=pipe, stdout=pipe, stderr=stdout)

with process.stdin as pipe:
    pipe.write(b"3")
    pipe.flush()

# reading the echo of the number
print(process.stdout.readline())

# sending another num:
pipe.write(b"4")
pipe.flush()

process.stdin.close()

我得到了这个输出:

» python script.py
b'3\n'
Traceback (most recent call last):
  File "/tmp/script.py", line 13, in <module>
    pipe.write(b"4")
ValueError: write to closed file

这意味着第一个输入已正确发送,并且读取已完成。

我真的找不到解释这种行为的东西;有人可以帮助我理解吗? 提前致谢

[编辑]:由于有很多要点需要澄清,所以我添加了此编辑。我正在使用 rop 技术进行缓冲区溢出漏洞利用的培训,并且我正在编写一个 python 脚本来实现这一目标。为了利用这个漏洞,由于aslr,我需要发现libc地址并使程序重新启动而不终止。由于脚本将在目标机器上执行,我不知道哪些库可用,那么我将使用 subprocess,因为它是内置于 python 中的。不详细说明,攻击在第一个 scanf 上发送一系列字节,目的是泄漏 libc 基地址并重新启动程序;然后发送第二个有效负载以获得一个 shell,我将通过它以交互模式进行通信。

这就是为什么:

  1. 我只能使用内置库
  2. 我必须发送字节并且无法附加结尾 \n:我的有效负载将无法对齐或可能导致失败
  3. 我需要保持 stdin 打开
  4. 我无法更改 c 代码


正确答案


更改这些:

  • 在 c 程序读取的数字之间发送分隔符。 scanf(3) 接受任何非数字字节作为分隔符。为了最简单的缓冲,请从 python 发送换行符(例如 .write(b'42\n'))。如果没有分隔符,scanf(3) 将无限期地等待更多数字。

  • 每次写入(c 和 python 中)后,刷新输出。

这对我有用:

#include <stdio.h>

int main(int argc, char *argv[])
{
    int n;
    while (1){
        scanf("%d", &n);
        printf("%d\n", n);
        fflush(stdout);  
    }
    return 0;
}
import subprocess

p = subprocess.popen(
    ('./a.out',), stdin=subprocess.pipe, stdout=subprocess.pipe)
try:
  print('a'); p.stdin.write(b'42 '); p.stdin.flush()
  print('b'); print(repr(p.stdout.readline()));
  print('c'); p.stdin.write(b'43\n'); p.stdin.flush()
  print('d'); print(repr(p.stdout.readline()));
finally:
  print('e'); print(p.kill())

原始 c 程序在终端窗口中交互运行时能够正常工作的原因是,在 c 中,当将换行符 (\n) 写入终端时,输出会自动刷新。因此 printf("%d\n", n); 最后会隐式执行 fflush(stdout);

当使用 subprocess 从 python 运行时,原始 c 程序无法工作的原因是它将输出写入管道(而不是终端),并且没有自动刷新到管道。发生的情况是,python 程序正在等待字节,而 c 程序不会将这些字节写入管道,但它正在等待更多字节(在下一个 scanf 中),因此两个程序都在无限期地等待对方。 (但是,在输出几 kib(通常为 8192 字节)后,将会出现部分自动刷新。但是单个十进制数太短,无法触发该操作。)

如果无法更改 c 程序,那么您应该使用终端设备而不是管道来在 c 和 python 程序之间进行通信。 pty python 模块可以创建终端设备,这对我来说适用于你的原始 c 程序:

import os, pty, subprocess

master_fd, slave_fd = pty.openpty()
p = subprocess.popen(
    ('./a.out',), stdin=slave_fd, stdout=slave_fd,
    preexec_fn=lambda: os.close(master_fd))
try:
  os.close(slave_fd)
  master = os.fdopen(master_fd, 'rb+', buffering=0)
  print('a'); master.write(b'42\n'); master.flush()
  print('b'); print(repr(master.readline()));
  print('c'); master.write(b'43\n'); master.flush()
  print('d'); print(repr(master.readline()));
finally:
  print('e'); print(p.kill())

如果你不想从python发送换行符,这里有一个没有换行符的解决方案,它对我有用:

import os, pty, subprocess, termiOS

master_fd, slave_fd = pty.openpty()
ts = termios.tcgetattr(master_fd)
ts[3] &= ~(termios.ICANON | termios.ECHO)
termios.tcsetattr(master_fd, termios.TCSANOW, ts)
p = subprocess.Popen(
    ('./a.out',), stdin=slave_fd, stdout=slave_fd,
    preexec_fn=lambda: os.close(master_fd))
try:
  os.close(slave_fd)
  master = os.fdopen(master_fd, 'rb+', buffering=0)
  print('A'); master.write(b'42 '); master.flush()
  print('B'); print(repr(master.readline()));
  print('C'); master.write(b'43\t'); master.flush()
  print('D'); print(repr(master.readline()));
finally:
  print('E'); print(p.kill())

以上就是C程序和子进程的详细内容,更多请关注编程网其它相关文章!

--结束END--

本文标题: C程序和子进程

本文链接: https://lsjlt.com/news/567170.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C程序和子进程
    问题内容 我编写了这个简单的 c 程序来解释具有相同特征的更困难的问题。 #include <stdio.h> int main(int argc, char *argv...
    99+
    2024-02-22
  • C#结束进程及子进程
    这是个我在C#调用批处理文件时遇到的问题。首先我通过Process.Start方法调用一个批处理文件,那个批处理文件里面则调用了一大堆程序。当退出C#程序时,我在程序中结束杀掉了那个...
    99+
    2024-04-02
  • C#如何结束进程及子进程
    这篇文章主要讲解了“C#如何结束进程及子进程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C#如何结束进程及子进程”吧!代码如下:    static...
    99+
    2023-07-02
  • c语言主程序怎么调用子程序
    在C语言中,主程序可以通过函数调用的方式来调用子程序。以下是一个简单的示例:```c#include // 声明子程序void su...
    99+
    2023-10-12
    c语言
  • Shell中怎么查杀子进程和僵尸进程
    本篇文章给大家分享的是有关Shell中怎么查杀子进程和僵尸进程,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。代码如下:#!/bin/sh# 递归找到导致进程僵死的最底层子进程并...
    99+
    2023-06-09
  • Linux中怎么显示守护进程和子进程
    在Linux中,可以使用ps命令来显示守护进程和子进程。下面是一些常用的ps命令选项: 显示所有进程(包括守护进程和子进程): ...
    99+
    2024-04-02
  • c语言子程序有哪几种
    在C语言中,子程序有以下几种:1. 函数:函数是一种可重用的子程序,用于执行特定的任务。函数可以接受参数,执行一系列的操作,并返回一...
    99+
    2023-09-22
    c语言
  • Python的子线程和子进程是如何手动结束的?
    如何结束Python的子线程和子进程 结束子线程的方法: 这个是搬运其他大神的代码,鄙人也不知道原理,反正拿来主义,暂时没发现什么缺点,先用着再说。 import inspect...
    99+
    2024-04-02
  • C++中父子进程之间如何通信
    在C++中,父进程和子进程之间可以通过管道、共享内存、信号量、消息队列等方式进行通信。下面分别介绍这些通信方式: 管道(Pipe...
    99+
    2024-04-02
  • Node.js进程管理之子进程详解
    一、理论 之前看多进程这一章节时发现这块东西挺多,写Process模块的时候也有提到,今天下午午休醒来静下心来好好的看了一遍,发现也不是太难理解。 Node.js是单线程的,对于现在...
    99+
    2024-04-02
  • 怎么在C++中安全的终止子进程
    在C++中安全地终止子进程可以使用以下方法: 使用waitpid()函数来等待子进程终止并收集其退出状态。可以在父进程中调用wai...
    99+
    2024-04-02
  • c语言如何跳转到其他子程序
    在C语言中,可以使用函数调用来跳转到其他子程序。要跳转到其他子程序,需要先定义并声明该子程序,然后在主程序中使用函数调用来调用该子程...
    99+
    2023-10-12
    c语言
  • 进程和程序的本质区别在哪
    进程和程序的本质区别是:1、执行状态,进程具备执行能力,程序没有主动的执行能力;2、资源分配,进程需要操作系统为其分配资源,程序只是一份静态的代码,不需要分配额外的资源;3、生命周期,进程具有创建,执行,暂停,恢复和终止等阶段,程序的生命周...
    99+
    2023-08-09
  • Linux进程控制【进程程序替换】
    ✨个人主页: Yohifo 🎉所属专栏: Linux学习之旅 🎊每篇一句: 图片来源 🎃操作环境: CentOS 7.6 阿里云远程服务器 Good judgment comes fro...
    99+
    2023-08-22
    linux 运维 服务器 云原生 后端
  • C语言进程程序替换的实现详解
    目录进程程序替换替换原理替换函数替换函数名称助记进程程序替换 替换原理 使用fork创建子进程后执行的是和父进程相同的程序,但是那样并没有多大的意义,子进程往往会“程序替...
    99+
    2024-04-02
  • linux怎么查看进程创建的子进程
    要查看Linux中进程创建的子进程,可以使用`ps`命令结合一些参数来实现。1. 使用`ps -ef`命令可以列出系统上所有进程的详...
    99+
    2023-09-12
    linux
  • Node.js进程管理之子进程实例分析
    这篇“Node.js进程管理之子进程实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Node.js进程管理之子进程实例...
    99+
    2023-07-02
  • 一文聊聊Node.js中的进程与子进程
    进程:process模块process 模块是 nodejs 提供给开发者用来和当前进程交互的工具,它的提供了很多实用的 API。【相关教程推荐:nodejs视频教程】从文档出发,管中窥豹,进一步认识和学习 process 模块:如何处理命...
    99+
    2022-11-22
    子进程 进程 Node.js
  • Node.js中的进程与子进程怎么处理
    这篇文章主要讲解了“Node.js中的进程与子进程怎么处理”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Node.js中的进程与子进程怎么处理”吧!进程:process模块process 模...
    99+
    2023-07-04
  • python子进程模块subproce
    属性1.Popen.poll():用于检查子进程是否已经结束。设置并返回returncode属性。2.Popen.wait():等待子进程结束。设置并返回returncode属性。3.Popen.communicate(input=None...
    99+
    2023-01-31
    模块 进程 python
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作