首页
社区
课程
招聘
[原创]管道应用之捕获控制台程序信息
发表于: 2007-6-5 17:49 10282

[原创]管道应用之捕获控制台程序信息

2007-6-5 17:49
10282

前几天问了朋友关于怎样捕捉控制台信息的问题,原来是用了管道技术,而且我这儿还有这方面的资料,只是我平时没注意罢了,真是.......

下面就简单介绍一下管道,说白了就是进程或网络间通信,有两种管道,即有名管道和匿名管道。匿名管道就是没有名字的管道了,也就是说在使用它们时不需要知道其名字。而有名管道正好相反,在使用前必须知道其名字。

也可以根据管道的特性来分类,即是单向的还是双向的。单向管道,数据只能沿一个方向移动,从一端流向另一端,而双向管道数据可以在两端间自由交换。匿名管道通常是单向的而有名管道通常是双向的。有名管道常用于一个服务器联络多个客户端的网络环境。

网络的我不了解,先说说进程的罢,我这人表达能力不行,就举个例子吧,比如说我们现在要捕捉ping程序的输出信息用管道就很容易实现,我们首先在程序中创建一个管道(通过CreatePipe)这样我们就得到了一个管道的写端口和一个读端口,然后我们通过CreateProcess创建控制台子进程,其中要用到STARTUPINFO这个结构,这个结构中就有控制台的三个标准句柄,(输入,输出,错误)我们要做的就是把上面CreatePipe中得到的写端口送给这里的输出端口,这样控制台应用程序的输出就会被我们偷偷的捕捉了,而它不知道这一切,它还是以为它是向控制台做标准输出,是不是挺爽的.说了这么多的废话下面是一个捕获PING程序输出信息的小程序,大家将就着看看吧!别扔砖啊!

#include "windows.h"
#include "resource.h"
HWND hInst;
LRESULT CALLBACK PING(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
        DWORD hWrite,hRead;
        STARTUPINFO startupinfo;
        PROCESS_INFORMATION pinfo;
        SECURITY_ATTRIBUTES sat;
        TCHAR        szBuffer[1024],ipBuffer[20];
        int bytesRead;
        HWND        hwndEdit;
        switch (message)
        {
                case WM_INITDIALOG:
                       
                                SendMessage(hDlg,WM_SETICON,ICON_BIG,LoadIcon(hInst,ICO_PING));
                                return TRUE;

                case WM_COMMAND:
                        switch (LOWORD(wParam))
                        {
                        case IDC_EXIT:
                                EndDialog(hDlg, LOWORD(wParam));
                                break;
                        case IDOK:
                                RtlZeroMemory(ipBuffer,20);
                                strcpy(ipBuffer,"ping ");
                                GetDlgItemText(hDlg,IDC_IPADDRESS,ipBuffer+5,20);

                                hwndEdit=GetDlgItem(hDlg,IDC_OUTINFOR);

                                sat.nLength=sizeof(SECURITY_ATTRIBUTES);
                                sat.bInheritHandle=TRUE;
                                sat.lpSecurityDescriptor=NULL;
                               
                                if(CreatePipe(&hRead,&hWrite,&sat,0)==0)    //创建匿名管道
                                        MessageBox(hDlg,TEXT("创建管道失败"),TEXT("PING"),MB_OK);
                                else
                                {
                                        startupinfo.cb=sizeof(STARTUPINFO);
                                        GetStartupInfo(&startupinfo);
                                        startupinfo.hStdOutput=hWrite;                        //用管道的写端代替控制台程序的输出端以便得到输出的信息
                                        startupinfo.hStdError=hWrite;
                                        startupinfo.dwFlags=STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES ;
                                        startupinfo.wShowWindow=SW_HIDE;        //隐藏控制台程序窗口
                                        if(CreateProcess(NULL, ipBuffer,NULL,NULL,TRUE,NULL,NULL,NULL,&startupinfo,&pinfo)==NULL)
                                                MessageBox(hDlg,TEXT("创建进程失败"),TEXT("PING"),MB_OK);
                                        else
                                        {
                                                CloseHandle(hWrite);                                //关关闭写端,因为写端已经给了控制台程序,不能存在两个写端
                                                while(TRUE)
                                                {
                            RtlZeroMemory(szBuffer,1024);
                            if(ReadFile(hRead,szBuffer,1023,&bytesRead,NULL)==NULL)  //注意ReadFile的第一个参数正是读端的句柄
                                break;
                            SendMessage(hwndEdit,EM_SETSEL,-1,0);
                            SendMessage(hwndEdit,EM_REPLACESEL,FALSE,szBuffer);                //循环读入信息直到没有信息可读
                        }

                                        }
                                        CloseHandle(hWrite);
                                }
                                break;
                        }
                        return TRUE;
        }
    return FALSE;
}
int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
        hInst=hInstance;
         DialogBoxParam(hInstance,(LPCTSTR)DLG_MAIN,NULL,(DLGPROC)PING,NULL);
        return 0;
}


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (14)
雪    币: 158
活跃值: (263)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
2
不错的东西,测试一下
2007-6-5 21:00
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
3
每一次在捕捉控制台输出之前,应该先把命令回显的地方清空比较好点

丢个汇编版本滴:

.386
.model flat, stdcall
option casemap :none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include                windows.inc
include                user32.inc
includelib        user32.lib
include                kernel32.inc
includelib        kernel32.lib
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
ICO_MAIN        equ                1000h        ;图标
DLG_CMD        equ                911               
IDC_CmdShell        equ                9011
IDC_CreateCmdShell        equ                9012
IDC_JieGuo        equ                9013
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 数据段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data?
hInstance        dd                ?
szBuff db 1024 dup(?)
sat SECURITY_ATTRIBUTES<?>
startupinfo STARTUPINFO<?>
pinfo PROCESS_INFORMATION<?>
lpBuff db 1024 dup(?)
bytesRead DWORD ?
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
_ProcDlgCmd        proc        uses ebx edi esi hWnd,wMsg,wParam,lParam
   local hRead,hWrite,hwndEdit
                mov        eax,wMsg
                .if        eax == WM_CLOSE
                        invoke        EndDialog,hWnd,NULL
                .elseif        eax == WM_INITDIALOG
                        invoke        LoadIcon,hInstance,ICO_MAIN
                        invoke        SendMessage,hWnd,WM_SETICON,ICON_BIG,eax
                .elseif        eax == WM_COMMAND
                        mov        eax,wParam
                        .if        ax == IDC_CreateCmdShell
                        invoke RtlZeroMemory,addr szBuff,sizeof szBuff
                        invoke GetDlgItemText,hWnd,IDC_CmdShell,addr szBuff,sizeof szBuff
                        invoke GetDlgItem,hWnd,IDC_JieGuo
                        mov hwndEdit,eax
                        mov sat.nLength,sizeof SECURITY_ATTRIBUTES
                        mov sat.bInheritHandle,TRUE
                        mov sat.lpSecurityDescriptor,NULL
                        invoke CreatePipe,addr hRead,addr hWrite,addr sat,0
                        .if eax==NULL
                                mov eax,FALSE
                                ret
                        .endif
                        mov startupinfo.cb,sizeof STARTUPINFO
                        invoke GetStartupInfo,addr startupinfo
                        push hWrite
                        pop startupinfo.hStdOutput ;用管道的写端代替控制台程序的输出端以便得到输出的信息
                        push hWrite
                        pop startupinfo.hStdError
                        mov startupinfo.dwFlags,STARTF_USESHOWWINDOW or STARTF_USESTDHANDLES
                        mov startupinfo.wShowWindow,SW_HIDE;
                        invoke CreateProcess,NULL,addr szBuff,NULL,NULL,TRUE,NULL,NULL,NULL,addr startupinfo,addr pinfo
                        .if eax==NULL
                                mov eax,FALSE
                                ret
                        .endif
                        invoke CloseHandle,hWrite
                        .while TRUE
                                invoke RtlZeroMemory,addr lpBuff,sizeof lpBuff
                                invoke ReadFile,hRead,addr lpBuff,1023,addr bytesRead,NULL
                                .if eax==NULL
                                        ret
                                .endif
                        invoke SendMessage,hwndEdit,EM_SETSEL,-1,0
                        invoke SendMessage,hwndEdit,EM_REPLACESEL,FALSE,addr lpBuff
                        .endw
                        invoke CloseHandle,hWrite
                        .endif
                .else
                        mov        eax,FALSE
                        ret
                .endif
                mov        eax,TRUE
                ret

_ProcDlgCmd        endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
start:
                invoke        GetModuleHandle,NULL
                mov        hInstance,eax
                invoke        DialogBoxParam,hInstance,DLG_CMD,NULL,offset _ProcDlgCmd,NULL
                invoke        ExitProcess,NULL
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
                end        start
上传的附件:
2007-6-6 18:00
0
雪    币: 268
活跃值: (40)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
4
感谢测试,我写平时写程序确实不严谨!
2007-6-6 18:45
0
雪    币: 214
活跃值: (40)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
支持一下下
2007-6-6 21:07
0
雪    币: 268
活跃值: (40)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
6
在此还要感谢一下天涯浪人!
2007-6-6 21:09
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
7
你的头像我喜欢。
2007-6-7 08:29
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
8
木马中用得多,远程控制台那种。
2007-6-7 20:18
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
不错的东西,测试一下
2007-6-9 21:06
0
雪    币: 255
活跃值: (11)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
反应时间太长时,界面会死锁
2007-6-13 13:22
0
雪    币: 796
活跃值: (370)
能力值: ( LV9,RANK:380 )
在线值:
发帖
回帖
粉丝
11
可以用多线程
2007-6-13 15:55
0
雪    币: 268
活跃值: (40)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
12
当时就是为了学习一下管道,就随便写了个小程序练练手,没有考虑那么多,如果有兴趣可以改成多线程的,那也加不了几句代码,哈
2007-6-13 20:17
0
雪    币: 268
活跃值: (40)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
13
当时就是为了学习一下管道,就随便写了个小程序练练手,没有考虑那么多,如果有兴趣可以改成多线程的,那也加不了几句代码,哈
网速慢,发重了!!
2007-6-13 20:25
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
学习一下了。。
2007-6-14 11:58
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
努力看懂中~~!
2007-6-14 14:39
0
游客
登录 | 注册 方可回帖
返回
//