nmap源代码分析.docx
《nmap源代码分析.docx》由会员分享,可在线阅读,更多相关《nmap源代码分析.docx(20页珍藏版)》请在冰豆网上搜索。
nmap源代码分析
以下代码是对nmap_main()函数基本的分析。
其中以///开头是新添加的注释。
而以类似于///的形式出现的注释用于标注一个比较大的功能代码段。
intnmap_main(intargc,char*argv[]){
inti;
vectorTargets;
time_tnow;
structhostent*target=NULL;
time_ttimep;
charmytime[128];
addrsetexclude_group;
#ifndefNOLUA
/*OnlyNSEscriptscanaddtargets*/
NewTargets*new_targets=NULL;///NewTargets为Singleton模式,产生单个实例
/*Pre-ScanandPost-Scanscriptresultsdatastructure*/
ScriptResults*script_scan_results=NULL;
#endif
char**host_exp_group;
intnum_host_exp_groups;
HostGroupState*hstate=NULL;
unsignedintideal_scan_group_sz=0;
Target*currenths;
char*host_spec=NULL;
charmyname[MAXHOSTNAMELEN+1];
intsourceaddrwarning=0;/*Havewewarnedthemyetaboutunguessable
sourceaddresses?
*/
unsignedinttargetno;
charhostname[MAXHOSTNAMELEN+1]="";
structsockaddr_storagess;
size_tsslen;
char**fakeargv=NULL;
now=time(NULL);
local_time=localtime(&now);
///设置错误log输出函数
if(o.debugging)
nbase_set_log(fatal,error);
else
nbase_set_log(fatal,NULL);
if(argc<2)printusage(-1);
/*argvfakingsilliness*/
fakeargv=(char**)safe_malloc(sizeof(char*)*(argc+1));
for(i=0;ifakeargv[i]=strdup(argv[i]);
}
fakeargv[argc]=NULL;
Targets.reserve(100);
#ifdefWIN32
win_pre_init();
#endif
///调用parse_options进行命令参数的解析
parse_options(argc,fakeargv);
///在Linux下设置终端为只读非阻塞方式,在Windows平台为空函数。
tty_init();//Putthekeyboardinrawmode
///将解析命令时需要延迟执行的操作在此处处理
apply_delayed_options();
#ifdefWIN32
///调用WSAStartup启动WinsockDLL,后续网络解析等需要用到。
win_init();
#endif
///如果用户使用了参数--iflist,那么会在此处打印网卡和路由表信息,然后退出。
///该选项对于显示指定发送网卡非常有帮助,可以提供基本的网络设备信息。
if(delayed_options.iflist){
print_iflist();
exit(0);
}
///quashargv部分用于修改命令行参数,将程序名字更改为FAKE_ARGV(默认为“pine”),
///并将剩余的各个参数都清空。
///在命令中加入-q可实现quashargv功能。
这最初是为了逃避ps等程序名称显示,便于隐蔽Nmap。
///不过在Windows系统上并无实效。
/*morefakeargvjunk,BTWmalloc'ingextraspaceinargv[0]doesn'twork*/
if(o.quashargv){
size_tfakeargvlen=strlen(FAKE_ARGV),argvlen=strlen(argv[0]);
if(argvlenfatal("Ifyouwantmetofakeyourargv,youneedtocalltheprogramwithalongername.Trythefullpathname,orrenameitfyodorssuperdedouperportscanner");
strncpy(argv[0],FAKE_ARGV,fakeargvlen);
memset(&argv[0][fakeargvlen],'\0',strlen(&argv[0][fakeargvlen]));
for(i=1;imemset(argv[i],'\0',strlen(argv[i]));
}
///如果使用FTPbouncescan的扫描方式,那么需要首先保证该FTP网站是可以访问到的。
///关于FTPbouncescan更多介绍,请参考:
http:
//nmap.org/nmap_doc.html#bounce
/*IfhewantstobounceoffofanFTPsite,thatsitebetterdamnwellbereachable!
*/
if(o.bouncescan){
if(!
inet_pton(AF_INET,ftp.server_name,&ftp.server)){
if((target=gethostbyname(ftp.server_name)))
memcpy(&ftp.server,target->h_addr_list[0],4);
else{
fatal("FailedtoresolveFTPbounceproxyhostname/IP:
%s",
ftp.server_name);
}
}elseif(o.verbose){
log_write(LOG_STDOUT,"ResolvedFTPbounceattackproxyto%s(%s).\n",
ftp.server_name,inet_ntoa(ftp.server));
}
}
///
fflush(stdout);
fflush(stderr);
timep=time(NULL);
///准备将基本的扫描输出到文件与控制台中
/*Briefinfoincasetheyforgetwhatwasscanned*/
Strncpy(mytime,ctime(&timep),sizeof(mytime));
chomp(mytime);///去掉字符串末尾换行符
char*xslfname=o.XSLStyleSheet();///XML样式表
xml_start_document();
if(xslfname){
xml_open_pi("xml-stylesheet");
xml_attribute("href","%s",xslfname);
xml_attribute("type","text/xsl");
xml_close_pi();
xml_newline();
}
std:
:
stringcommand;
if(argc>0)
command+=fakeargv[0];
for(i=1;icommand+="";
command+=fakeargv[i];
}
xml_start_comment();
xml_write_escaped("%s%sscaninitiated%sas:
%s",NMAP_NAME,NMAP_VERSION,mytime,join_quoted(fakeargv,argc).c_str());
xml_end_comment();
xml_newline();
log_write(LOG_NORMAL|LOG_MACHINE,"#");
log_write(LOG_NORMAL|LOG_MACHINE,"%s%sscaninitiated%sas:
",NMAP_NAME,NMAP_VERSION,mytime);
log_write(LOG_NORMAL|LOG_MACHINE,"%s",command.c_str());
log_write(LOG_NORMAL|LOG_MACHINE,"\n");
xml_open_start_tag("nmaprun");
xml_attribute("scanner","nmap");
xml_attribute("args","%s",join_quoted(fakeargv,argc).c_str());
xml_attribute("start","%lu",(unsignedlong)timep);
xml_attribute("startstr","%s",mytime);
xml_attribute("version","%s",NMAP_VERSION);
xml_attribute("xmloutputversion",NMAP_XMLOUTPUTVERSION);
xml_close_start_tag();
xml_newline();
output_xml_scaninfo_records(&ports);
xml_open_start_tag("verbose");
xml_attribute("level","%d",o.verbose);
xml_close_empty_tag();
xml_newline();
xml_open_start_tag("debugging");
xml_attribute("level","%d",o.debugging);
xml_close_empty_tag();
xml_newline();
/*Beforewerandomizetheportsscanned,letsout