kd8耐磨吗跑步:管道技术实现控制台交互操作的技术实现 易语言

来源:百度文库 编辑:中财网 时间:2024/04/29 07:12:27
管道技术实现控制台交互操作的技术实现   Post By:2009-1-27 21:42:00

  这种方法是目前普遍使用的方法.所谓管道,就是系统提供给进程之间通信的一
种途径.管道又分为命名管道和匿名管道,我这里就用匿名管道来说明,通过API函数CreatePipe
很容易创建一个匿名管道.
当然,光有管道也是不能达到目地的,我们还要了解一个API函数CreateProcess
.DLL命令 创建进程, 整数型, , "CreateProcessA"
    .参数 程序名称, 整数型
    .参数 命令行, 文本型, ,这里是CMD名称
    .参数 进程属性, 整数型
    .参数 线程属性, 整数型
    .参数 参数一, 整数型,这里设为-1
    .参数 参数二, 整数型
    .参数 参数三, 整数型
    .参数 运行目录, 文本型, , 如需指定运行目录设为文本行
    .参数 启动信息, 启动信息, ,关键,设置的CMD的启动信息
    .参数 进程信息, 进程信息, ,返回的CMD进程信息

在这里它的作用是创建一个CMD进程,虽然参数暴多,但我们只要关注有注释的那几个,其它的一概
用0来填充,我们来看看进程信息和启动信息的结构
.数据类型 进程信息
    .成员 进程号, 整数型
    .成员 线程号, 整数型
    .成员 进程ID, 整数型
    .成员 线程ID, 整数型

.数据类型 启动信息
    .成员 cb, 整数型
    .成员 lpReserved, 整数型
    .成员 lpDesktop, 整数型
    .成员 lpTitle, 整数型
    .成员 dwX, 整数型
    .成员 dwY, 整数型
    .成员 dwXSize, 整数型
    .成员 dwYSize, 整数型
    .成员 dwXCountChars, 整数型
    .成员 dwYCountChars, 整数型
    .成员 dwFillAttribute, 整数型
    .成员 dwFlags, 整数型
    .成员 wShowWindow, 短整数型
    .成员 cbReserved2, 短整数型
    .成员 lpReserved2, 整数型
    .成员 hStdInput, 整数型
    .成员 hStdOutput, 整数型
    .成员 hStdError, 整数型
呵呵,吓着了吧,其实启动信息我们只要关注以下几个:
dwFlags,wShowWindow,hStdInput,hStdOutput,hStdError
其中dwFlags是设置新建进程的窗口大小的,wShowWindow是控制窗口的状态的
那么hStdInput,hStdOutput,hStdError又是什么意思呢?
首先,我需要说明一下这里的管道和进程之间的关系
我们们假设有2个匿名管道,2个单向的管道:管道A和管道B,每个管道分别有一个输入和输出端.
第一步:
我们要假设执行这样一个命令:dir,我们要怎样才能把这个命令传给控制台(CMD进程)呢?
上面的hStdInput就是标准输入,本来是在屏幕上负责接收用户的输入,我们现在把它挂接在A管道
的输出端负责读入管道A的数据.
第二步:
现在管道A的输出端已经接到CMD的输入端,现在管道A的输入端就是CMD的输入端,我们就可以向这
个输入端口写入命令,好现在命令输入的问题解决了,那么怎样读出CMD的输出数据呢?
第三歩:
通过上面的分析,我们知道管道A是不可能得到CMD的输出数据,这个时候就需要另外一个管道来读
出CMD的输出数据,接就是我们的管道B.上面的hStdOutput就是标准输出,本来是输出到屏幕上的,
我们把它挂接在管道B的输入端,负责接收CMD的输出数据,那hStdError呢,这个是标准错误输出,
本来也是输出到屏幕上的的,现在我们索性也把它接到管道B的输入端,作为CMD的输出,
第四步:
管道B的输入端已经接到CMD的输出了,现在管道B的输出端就是CMD的输出了,我们就可以从这个端
口接收数据了,然后反馈给用户了.

既然原理搞懂了,现在开始实际的建立一个匿名管道.
建立匿名管道的方法是调用API函数CreatePipe,CreatePipe函数原型如下:
.DLL命令 创建匿名管道, 整数型, , "CreatePipe"
    .参数 输出端, 整数型, 传址
    .参数 输入端, 整数型, 传址
    .参数 管道属性, 安全性结构_, 传址
    .参数 尺寸, 整数型
其中前两个就是我们说的匿名管道的输入和输出端,管道属性是管道的配制参数,是一个安全性结
构(SECURITY_ATTRIBUTES)类型的结构,最后一个参数置0
示例代码为:
=============================================================
.程序集变量 进程信息, 进程信息
.程序集变量 管道b, 整数型
.程序集变量 管道a, 整数型
.程序集变量 安全属性b, 安全性结构_, , , SECURITY_ATTRIBUTES
.程序集变量 安全属性a, 安全性结构_
.程序集变量 启动信息, 启动信息
.程序集变量 a输出管道, 整数型
.程序集变量 a输入管道, 整数型
.程序集变量 b输出管道, 整数型
.程序集变量 b输入管道, 整数型

' 匿名管道A,用来写
安全属性a.长度 = 12
安全属性a.权限 = 0
安全属性a.句柄 = -1
管道a = 创建匿名管道 (a输出管道, a输入管道, 安全属性a, 0)
' 匿名管道B,用来读
安全属性b.长度 = 12
安全属性b.权限 = 0
安全属性b.句柄 = -1
管道b = 创建匿名管道 (b输出管道, b输入管道, 安全属性b, 0)
' 创建CMD进程,重定向输入和输出到匿名管道
GetStartupInfo (启动信息)  ' 用本进程启动信息填充CMD启动信息其它项
启动信息.dwFlags = 257  ' 大小类型
启动信息.hStdInput = a输出管道  ' 重定向标准输入
启动信息.hStdOutput = b输入管道  ' 重定向标准输出
启动信息.hStdError = b输入管道  ' 重定向标准错误输出
启动信息.wShowWindow = 0  ' 隐藏运行
创建进程 = 创建进程 (0, "cmd.exe", 0, 0, -1, 0, 0, 字符 (0), 启动信息, 进程信息)

==========================================================
这样建立了模型后,可以很方便的用:
======================================
.子程序 读管道, 文本型
.局部变量 实际尺寸, 整数型
.局部变量 缓存, 字节集
缓存 = 取空白字节集 (260)
ReadFile (b输出管道, 缓存, 260, 实际尺寸, 0)
返回 (到文本 (取字节集左边 (缓存, 实际尺寸)))
=============================================
读取管道中CMD的反馈信息,也可以很方便的用:
=================================
.子程序 写管道, 整数型
.参数 命令, 文本型
.局部变量 实际尺寸, 整数型
.局部变量 写入内容, 字节集
.局部变量 缓存, 字节集
写入内容 = 到字节集 (命令 + #换行符)
WriteFile (a输入管道, 写入内容, 取字节集长度 (写入内容), 实际尺寸, 0)
返回 (实际尺寸)
======================================
来把需要的命令写入CMD进程.
  如此,就建立了一个交互式的Shell过程,这在后门编写中应用很广泛,甚至是在Shellcode的编
写中也经常使用到,如果把读写两个管道分别用两个线程进行同步,这样就可以实现实时的交互操
作,效果就更好了,如果不在需要这些管道了,必须关闭相应的CMD进程,管道的4个端口句柄,结束
管道和相应已经开启的资源.
END
源文件就不提供了,其实上面已经给出源码了,我可是费了好大劲才写出来的,可别辜负了我的一
片苦心啊!呵呵,我个人认为,这样就会进步快点,记住一句话:技术是在研究中成长的,有什么问
题可以在这里提出.