的write方法有哪些参数_向子进程传递大量数据的方法

如何传递大型数据给子进程

昨天的一篇文章中,我们说到如果想向一个子进程传输多于32767个字符的数据,我们需要寻找其他的方法(而不是命令行参数)来实现。

我们能想到的第一个方法是:WM_COPYDATA。当子进程创建并进入消息循环后,我们使用FindWindow来寻找进程的窗口并发送WM_COPYDATA消息。但是,这种方法有几个问题:

> 你需要寻找一种方法确定子进程确实已经创建了目标窗口并进入消息循环,这样才可以进行窗口查找。(提示:可以使用WaitForInputIdle这个方法)

> 你需要确保我们使用FindWindow查找到的窗口确实是你希望得到的那个,因为如果其他进程的窗口碰巧也有相同的标题或者窗口类,则你可能得到的不是目标窗口。又或者,有多个相同的子进程实例,也会创建同样的窗口实例。所以,你需要确定查找到正确的目标窗口。(提示:可以使用GetWindowThreadProcessId这个方法)

> 你需要确保其他人不会查找到你的窗口并在你之前发送WM_COPYDATA,如果他们这样做了,那他们就得到了你的子进程的控制权了。

> 子进程需要设计一种机制,来对抗一些恶意进程发送伪造的WM_COPYDATA消息,并尽可能正确处理它们(丢弃这种请求)。

我所推荐的方法是:匿名共享内存

基本想法是,创建一块共享内存并填充你需要传输的数据。然后将它的句柄设置为可继承的,然后创建子进程,传输句柄的数字表示到子进程的命令行。
子进程会从命令行中得到这个句柄,并映射这块共享内存到它的进程空间,这样就能访问到你传递给它的数据了。

关于这种方法的几点说明:

> 子进程需要判断句柄的有效性,防止某些人传递一些无效的或者伪造的数据。

> 如果恶意进程想搞乱你的子进程命令行,则它们必须拥有PROCESS_VM_WRITE权限。如果它们想访问进程句柄表,则还需要有PROCESS_DUP_HANDLE权限。这些都是安全的访问掩码,所有配置合适的ACL可以起到很好的保护作用。(默认的ACL就可以起到保护,所以使用默认的ACL就行了)

> 在这种方法中,没有名字和数字可以被恶意进程监听或者伪造。前提是你对子进程实施了PROCESS_VM_WRITE和PROCESS_DUP_HANDLE保护。

> 因为我们使用的是共享内存,所以共享的数据不会真正地在两个进程之间拷贝,它们只是被操作系统重新映射而已。对于传输大型数据来说,这种方法十分高效。

在下面的例子代码中,我们演示了如何使用共享内存技术来传输数据。

4ca8d2bf396cbcaf164ea1dc1dc08291.png

在实际的项目中,上面的STARTUPPARAMS结构体的成员可能会十分复杂,但是出于演示目的,我在这里仅仅定义了一个整数成员。

2c0d4570d68e5ca59aec266a3a386bd4.png

CreateStartupParams创建了一个在共享内存区中的STARTUPPARAMS的结构体。首先,我们填充SECURITY_ATTRIBUTES结构体并将它的可继承属性设置为TRUE,这样子进程就可以访问到这块共享内存。将lpSecurityDescriptor设置为NULL表明我们希望使用默认的安全描述符,我们使用这个默认的值就够了。然后,我们创建了一个指定大小的共享内存对象,然后将它映射到内存,最后,我们返回了一个共享内存的句柄和映射后的内存地址。

90759ca02fb99f037bc7472a23edc1d1.png

GetStartupParams函数是与CreateStartupParams对应的函数。它从命令行上解析出句柄的值并尝试进行内存映射。如果句柄不是一个合法的文件映射句柄,则MapViewOfFile调用会失败,我们可以通过这种方法进行参数的有效性校验。然后,我们使用了VirtualQuery来查询内存映射区的大小。(这里,我们没有使用更加严格的测试方法,因为它的返回值可能被舍入到最近的页边界)

38ded11f41f415a85a6c1469895c9147.png

我们还需要释放共享内存来防止可能出现的内存泄露,所以我们定义了上面的FreeStartupParams函数实现这一点。

feac4aa4929d71cf7f2c4a4df8509f7c.png

上面的函数中,我们主要是构建子进程的命令行参数。我们使用了GetModuleFileName(NULL)来获取执行程序的全路径,然后传输句柄的数字表示,并在调用CreateProcess时设置了参数TRUE来表明我们希望子进程的句柄是可以继承的。
有一个小地方需要注意的:我们使用了引号来处理程序路径中含有空格的情况。

e721902d7bd5b70f43b05a8361c6ffec.png

最后,我们将上面所有的程序片段组合在一起。
如果命令行上已经有一个参数了,表明这次运行的是子进程,所以我们将这个参数转换为STARTUPPARAMS并获取其中的数据并显示出来。
如果命令行上没有传递参数,则表明我们运行的是父进程,在这种情况下,我们创建了一个STARTUPPARAMS,并设置我们需要传输的数据(这里使用了42作为例子),然后传输给子进程。

总结

今天我们演示了如何向子进程传输大量数据的方法,虽然在上面的例子中,我们传递的数据量很小,但是如果稍加改进,完全可以实现传递大型数据。
所以各位老哥,可以将这种方法,稳稳地放到你的技能工具箱了。

e9a666413faf30be4b4ab4e4a5605a89.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/539235.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

厉害了!中关村软件园人工智能军团有料有看点

人工智能已成为当下全球科技界的新热点,中外竞相攀登这座划时代的科技高峰。上月,国务院印发《新一代人工智能发展规划》,明确将人工智能作为未来国家重要的发展战略。《规划》提出前瞻布局新一代人工智能重大科技项目,到2030年中…

Hive的使用之hwi

概述 hwi是hive开发的网页形式查看数据。方便非专业人士使用。 安装步骤 1、下载hive源码包 地址:http://apache.fayea.com/hive/ apache-hive-2.1.0-src.tar.gz 2、打包war 解压apache-hive-2.1.0-src.tar.gz源码包,进入到 C:\Users\zengmg\Deskto…

c 服务器传输大文件,cend.me:不须经过服务器,直接点对点的文件传输免费服务...

要传送文件给远程的手机、平板、电脑等设备,通常的做法就是先将文件上传到服务器存放,然后再从服务器下载,这样的做法看似合理,但如果上传的同时就由远程的设备来接收,不要经过服务器,这样就能更节省上、下…

win10系统迁移后系统重装_win7/win10系统迁移到新SSD硬盘的方法

随着固态硬盘的普及,越来越多的朋友把电脑的硬盘换成了固态,原来的机械硬盘当数据盘使用,关于在固态硬盘中安装系统,那是简单的,和机械硬盘一样,当是对原来的系统比较重要,不能重装的朋友来说&a…

hive参数配置使用

概述 set命令设置hive的参数。 ${} 可以获取配置项的值,作为参数使用。 在启动hive时可以传入配置项启动。 hive参数初始化配置set命令~/.hiverc hive参数介绍 输入set,可以查看所有可设置项和现在设置项的值。 hive> set; 项太多了&#xff…

Thrift源码学习二——Server层

Thrift 提供了如图五种模式:TSimpleServer、TNonblockingServer、THsHaServer、TThreadPoolServer、TThreadSelectorServer ​​ TSimpleServer、TThreadPoolServer 属于阻塞模型 TNonblockingServer、THsHaServer、TThreadedSelectorServer 属于非阻塞模型 TServer…

linux top 命令可视化_25个Linux性能监控工具

一段时间以来,我们在网上向读者介绍了如何为Linux以及类Linux操作系统配置多种不同的性能监控工具。在这篇文章中我们将罗列一系列使用最频繁的性能监控工具,并对介绍到的每一个工具提供了相应的简介链接,大致将其划分为两类,基于…

base64是哪个jar包的_涨知识 | 用maven轻松管理jar包

前言相信只要做过 Java 开发的童鞋们,对 Ant 想必都不陌生,我们往往使用 Ant 来构建项目,尤其是涉及到特别繁杂的工作量,一个 build.xml 能够完成编译、测试、打包、部署等很多任务,这在很大的程度上解放了程序员们的双…

Hive数据类型

概述 Hive的内置数据类型可以分为两大类:(1)、基础数据类型;(2)、复杂数据类型。 基础数据类型 数据类型 所占字节 开始支持版本 TINYINT 1byte,-128 ~ 127 SMALLINT 2byte,-32,768 ~ 32,767 INT 4byte,-2,147,483,648 ~ 2,14…

JMS(Java消息服务)与消息队列ActiveMQ基本使用(一)

最近的项目中用到了mq,之前自己一直在码农一样的照葫芦画瓢。最近几天研究了下,把自己所有看下来的文档和了解总结一下。 一. 认识JMS 1.概述 对于JMS,百度百科,是这样介绍的:JMS即Java消息服务(Java Message Service&…

python单词反转_python文本 字符串逐字符反转以及逐单词反转

python文本 字符串逐字符反转以及逐单词反转 场景: 字符串逐字符反转以及逐单词反转 首先来看字符串逐字符反转,由于python提供了非常有用的切片,所以只需要一句就可以搞定了 >>> aabc edf degd >>> a[::-1] dged fde cba …

hive复合数据类型之struct

概述 STRUCT:STRUCT可以包含不同数据类型的元素。这些元素可以通过”点语法”的方式来得到所需要的元素,比如user是一个STRUCT类型,那么可以通过user.address得到这个用户的地址。 操作实例 1、创建表 create table student_test(id int,in…

pycharm 运行celery_Celery全面学习笔记

来源介绍Celery 是 Distributed Task Queue,分布式任务队列。分布式决定了可以有多个 worker 的存在,队列表示其是异步操作。Celery 核心模块Celery有一下5个核心角色Task就是任务,有异步任务和定时任务Broker中间人,接收生产者发…

hive复合数据类型之array

概述 ARRAY:ARRAY类型是由一系列相同数据类型的元素组成,这些元素可以通过下标来访问。比如有一个ARRAY类型的变量fruits,它是由[apple,orange,mango]组成,那么我们可以通过fruits[1]来访问元素orange,因为ARRAY类型的…

Exploit开发系列教程-Mona 2 SEH

P3nro5e 2015/07/10 10:580x00 Mona 2 前言 & 准备Mona 2是一种非常有用的插件,它由Corelan Team开发。起初是为Immunity Debugger写的,现在它适用于WinDbg调试器。你将需要为WinDbg x86 和 WinDbg x64安装一些工具:安装Python 2.7 (从这…

python集合的元素可以是_Python集合的元素中,为什么不可以是包含嵌套列表的元组?...

你有一个误解,hash算法针对的是元素的内容,并不是针对指针,所以指针不变不等于可hash。 如果你想深究细节的话,可以看tuple的源码: static Py_hash_t tuplehash(PyTupleObject *v) { Py_uhash_t x; /* Unsigned for de…

python lib库_python_lib基础库

1:argv传递给python脚本的命令行参数列表,argv[0]是脚本的名字(他是平台独立的,不管他是一个路径全名或不是),如果使用了-c参数选项,argv[0]会被设置为字符串-c,如果没有脚本名传递给python解释器&#xff…

hive复合数据类型之map

概述 MAP:MAP包含key->value键值对,可以通过key来访问元素。比如”userlist”是一个map类型,其中username是key,password是value;那么我们可以通过userlist[username]来得到这个用户对应的password; 操…

Beego框架使用

为什么80%的码农都做不了架构师&#xff1f;>>> Beego Web项目目录结构 new 命令是新建一个 Web 项目&#xff0c;我们在命令行下执行 bee new <项目名> 就可以创建一个新的项目。但是注意该命令必须在 $GOPATH/src 下执行。最后会在 $GOPATH/src 相应目录下…

oracle下lag和lead分析函数

Lag和Lead分析函数可以在同一次查询中取出同一字段的前N行的数据(Lag)和后N行的数据(Lead)作为独立的列。 这种操作可以代替表的自联接&#xff0c;并且LAG和LEAD有更高的效率。 语法&#xff1a; [sql] view plaincopy /*语法*/ lag(exp_str,offset,defval) over() Lead(…