如何从管道稳定可靠地获取多个NMAP扫描进程返回的结果? (附代码)

dibotiger 2015-11-09 09:08:50
想利用NMAP扫描的结果, 发现多线程改动太大,
就改利用多进程的方式直接调用执行NMAP来把多个扫描结果获取到当前程序.

看了半天的管道和双WaitForMultipleObjects机制, 依范例代码和意图"编写"了下面的代码.
可逻辑似乎和代码根本搭不上, 特来请教. 该如何修改下面的代码?

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
#include <windows.h>

#define NMAP_EXE_NAME "Nmap\\Nmap.exe"

int hcnt=0;

HANDLE *hProcess;
HANDLE *hReadPipe;
HANDLE *hWritePipe;

char* Activehost[] = {
"192.168.1.1",
"192.168.1.102",
"192.168.1.103",
"192.168.1.104",
};


void ReadDetailInfoFormPIPE(HANDLE hReadPipe)
{
char ReadBuf[1024 * 10]={0};
DWORD ReadNum,ReadNum2;
OVERLAPPED ov;
ov.Offset = 0;
ov.OffsetHigh = 0;
ov.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);

if(!ReadFile(hReadPipe, ReadBuf, 1024 * 10, &ReadNum, &ov))
{
if (GetLastError() == ERROR_IO_PENDING)
{
while(!GetOverlappedResult( hReadPipe , &ov, &ReadNum, TRUE))
{
DWORD dwError = GetLastError();
if(dwError == ERROR_IO_INCOMPLETE)
continue;
else
{
printf("%s",ReadBuf);
break;
}
}
}
}
else
{
printf("%s",ReadBuf);
}
}


DWORD WINAPI ReadPipe_Thread(LPVOID Param)
{

DWORD dwRet = 0;
int nIndex = 0;

while(1)
{
dwRet = WaitForMultipleObjects(hcnt, hProcess, false, INFINITE);

switch(dwRet)
{
case WAIT_TIMEOUT:
break;
case WAIT_FAILED:
hcnt=0;
return 1;
default:
{
nIndex = dwRet - WAIT_OBJECT_0;
ReadDetailInfoFormPIPE(hReadPipe[nIndex++]);

while(nIndex < hcnt)
{
dwRet = WaitForMultipleObjects(hcnt-nIndex, &hProcess[nIndex], false, 0);
switch(dwRet)
{
case WAIT_TIMEOUT:
nIndex = hcnt; //退出检测,因为没有被触发的对象了.
break;
case WAIT_FAILED:
hcnt=0;
return 1;
default:
{
nIndex = dwRet - WAIT_OBJECT_0;
ReadDetailInfoFormPIPE(hReadPipe[nIndex++]);
}
break;
}
}
}
break;
}
}
hcnt=-1;
return 0;
}


int main(int argc, char* argv[])
{
SECURITY_ATTRIBUTES sa;
PROCESS_INFORMATION pi;
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);

TCHAR szCommandLine[MAX_PATH]={0},szEXESelfPath[MAX_PATH]={0};
GetModuleFileName(NULL,szEXESelfPath,MAX_PATH);
if(char *p=strrchr(szEXESelfPath,'\\'))
*p='\0';

hcnt=sizeof(Activehost)/sizeof(char *);
hProcess=new HANDLE[hcnt];
hReadPipe=new HANDLE[hcnt];
hWritePipe=new HANDLE[hcnt];

for(int i=0,p=0;i<hcnt;i++,p++)
{
if(!CreatePipe(&hReadPipe[i], &hWritePipe[i], &sa, 1024*10))
{
goto Clean;
}

STARTUPINFO startupinfo;
GetStartupInfo(&startupinfo);
startupinfo.hStdError = hWritePipe[i];
startupinfo.hStdOutput = hWritePipe[i];
startupinfo.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
startupinfo.wShowWindow = SW_HIDE; // 隐藏窗口

sprintf(szCommandLine, "%s\\%s -O %s",szEXESelfPath,NMAP_EXE_NAME,Activehost[i]);
if(CreateProcess(NULL, szCommandLine, NULL, NULL, TRUE, 0 ,NULL, szEXESelfPath, &startupinfo, &pi))
{
hProcess[p] = pi.hProcess;
CloseHandle(pi.hThread);
}
}

CloseHandle(CreateThread(NULL,0,(LPTHREAD_START_ROUTINE)ReadPipe_Thread,0,0,0));

while(hcnt)
{
Sleep(1);
}

Clean:
delete[]hProcess;
delete[]hReadPipe;
delete[]hWritePipe;
hProcess=NULL;
hReadPipe=NULL;
hWritePipe=NULL;
//getch();
return 0;
}


...全文
129 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧