标题: 【挑战】批处理如何创建仅含一个nul字符的文件 [打印本页]
作者: plp626 时间: 2011-5-13 12:49 标题: 【挑战】批处理如何创建仅含一个nul字符的文件
本帖最后由 plp626 于 2011-5-13 12:51 编辑
如题,如何用 cmd的内部命令 创建 仅含一个nul字符的文本文件
没有挑战的意思,只是问题难度较大
这个问题的思考了来源于 。。。 暂时 不好描述, 总之就是解决批处理的三方工具依赖性缺陷。
我知道用外部命令debug,fsutil可方便 创建ascii码为nul的字符 文件,但是,这和我解决问题的目的有些本末倒置。
思考片刻,无果,觉得不可能实现,不知大家有何看法。谢谢。。
===============================
PS: 批处理变量结束符为 NUL 字符,所以用变量的方法 ,我本人认为是行不通的,建议大家把注意力放在 copy prompt 。。。还有 for /f usebackq ('....')的bug,以及其他内部命令bug上,并加以利用(个人观点)
鉴于论坛过滤一些特殊的ascii码字符,大家给代码的时候描述思路或者上传源文件即可。
作者: plp626 时间: 2011-5-13 13:05
如果哪位能给个可行的思路,必将有一个惊喜产生。。。
还是娱乐,娱乐度 甚高!!
作者: CrLf 时间: 2011-5-13 13:13
让我想起了batman那个获取制表符函数所用的方法...
作者: plp626 时间: 2011-5-13 13:21
3# zm900612
那个制表符的获取用了变量
nul 不同于tab 是最特殊的字符
变量的值不可能含有 nul 字符, 除非你能找到cmd变量存储的bug加以利用
但这种技巧可遇不可求,或者你已经发现。
作者: CrLf 时间: 2011-5-13 13:57
cmd /u /c echo asdfasdfasdf之类的可以生成带nul的输出,但是没想到如何提取,用delims试过似乎也不行
作者: batman 时间: 2011-5-13 15:36
有难度,先占楼思考。。。
作者: zz100001 时间: 2011-5-13 16:30
可执行文件的头部就是固定的格式,包含了NUL字符,用 type %windir%\system32\cmd.exe 或者 findstr MZ %windir%\system32\cmd.exe 就能得到包含 NUL 的字符串了,试了一下无法提取,CMD存变量的时候好像自动给搞掉了。
作者: Bearxy 时间: 2011-5-13 17:40
囧啊,初学者看不懂.难道是ECHO.NUL>TEST.TXT
作者: plp626 时间: 2011-5-13 20:43
8# Bearxy
我也是从初学者过来,呵呵,慢慢来,看你的回复很可爱。
NUL 是asiic码值为0的那个控制字符,你搜索 下载 hedit (很小的体积)可以查看任意文件的 asiic码 信息。
作者: Bearxy 时间: 2011-5-13 23:30
本帖最后由 Bearxy 于 2011-5-13 23:41 编辑
9# plp626
呵呵,我看过上次你和别人论证的那个帖.
所以猜到你出的题可能不会是那么简单……但没办法呀,batman不是一直说重在参与么
作者: batman 时间: 2011-5-14 00:10
抛砖了:- @echo off
- (echo A100&echo MOV DL,00&echo MOV AH,02&echo INT 21&echo INT 20&echo,&echo G&echo q)>db
- for /f "skip=8 delims=Progamteindly" %%a in ('debug^<db') do set/p=%%a<nul>a.txt&goto next
- :next
- del /q db
复制代码
作者: hanyeguxing 时间: 2011-5-14 02:49
本帖最后由 hanyeguxing 于 2011-5-14 03:31 编辑
- fsutil file createnew 125.txt 1
复制代码
批处理中cmd用 iswspace () 直接检查变量、参数、文件名等字符串中的空字符并进行处理,所以set/p和for/f以及echo等都不能用,只能考虑那些直接操作文件的命令。more把空字符当换行处理;就剩下type、copy等这些了;可只用他们怎么把包含空字符的文件拆开呢?
作者: batman 时间: 2011-5-14 09:36
12# hanyeguxing
我上面的代码就是用的set /p输出,生成的就是1字节的空文本啊。。。
作者: qzwqzw 时间: 2011-5-14 10:43
本帖最后由 qzwqzw 于 2011-5-14 10:59 编辑
11楼的代码也犯了本末倒置的错误了
生成0字节是为了避免使用外部命令
结果你却使用外部命令debug生成了0字节
如果允许用debug
那么直接用e命令就可以直接写任何字节了
何必还要用a命令汇编dos中断呢?- @echo off
- for %%f in (e100 00 rcx 1 nnull.txt w q) do echo %%f>>debug.scr
- debug < debug.scr >nul
复制代码
对于这个问题
我能想到的仍然是ASCODE方案
因为它本身就是为了解决第三方工具依赖而出现的
生成0字节只是一个小小的副产物而已- @echo off
- echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>echoo.com
- echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU!WvX0GwUY Wv;ovBX2Gv0ExGIuht6>>echoo.com
- echo ?@xAyJHmH@=a?}VjuN?_LEkS?`w`s_{OCIvJDGEHtc{OCIKGMgELCI?GGg>>echoo.com
- echo EL?s?WL`LRBcx=k_K?AxVD?fCo?Cd?BLDs0>>echoo.com
- echoo >nul
- echoo.com $00>null.txt
- del echoo.com
复制代码
作者: qzwqzw 时间: 2011-5-14 10:49
倒是想起另外一个类似的问题
如何生成一个仅含1个eof字符的文件
eof即文件结束符
ASCII码十六进制形式为0x1A
作者: plp626 时间: 2011-5-14 13:01
本帖最后由 plp626 于 2011-5-14 13:40 编辑
15# qzwqzw
这个直接签到bat源代码中,不过要在注释行加转义字符^- ::{^}
- @echo off
- set/p sub=<%~s0
- setlocal EnableDelayedExpansion
- set sub=!sub:~4,1!
- set/p=!sub!<nul>sub.txt
复制代码
还可借助copy nul的特性,但要生产临时文件,不过很简洁复制代码
作者: plp626 时间: 2011-5-14 13:27
本帖最后由 plp626 于 2011-5-14 13:46 编辑
re: qzwqzw
有个疑问,你14楼的代码为什么要多一行 echoo >nul?- @echo off
- (echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=
- echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU!WvX0GwUY Wv;ovBX2Gv0ExGIuht6
- echo ?@xAyJHmH@=a?}VjuN?_LEkS?`w`s_{OCIvJDGEHtc{OCIKGMgELCI?GGg
- echo EL?s?WL`LRBcx=k_K?AxVD?fCo?Cd?BLDs0)>echoo.com
- echoo.com $00>null.txt
复制代码
如此也可方便生产0x00字符;
刚才看到15楼的询问,我还以为这个echoo.com 不方便生产0x1a,试了试也可以,不但可以,还可以生产任意"字符流",以至于可以生成我们想要的任何三方工具,非常惊喜!(未考虑速度)- @echo off
- (echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=
- echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU!WvX0GwUY Wv;ovBX2Gv0ExGIuht6
- echo ?@xAyJHmH@=a?}VjuN?_LEkS?`w`s_{OCIvJDGEHtc{OCIKGMgELCI?GGg
- echo EL?s?WL`LRBcx=k_K?AxVD?fCo?Cd?BLDs0)>echoo.com
- echoo.com $00$1a$0d$0dplp626>test.txt
复制代码
这段神奇的代码让我产生了很大的兴趣,试了试,参数$不紧跟16进制的数据,比如
echoo.com $# 创建的是"-"
echoo.com $$创建 但是"="
而echoo.com $#$$ 又创建的不是"=-" 而是"4#"
这里是怎么对应的?
======================
qzw兄可否把这段代码给大伙讲解下。。。
作者: plp626 时间: 2011-5-14 14:06
题外话,我发这个帖子是因为对于ascii码0-255,除了0x00外,我都找到了可以在bat中用变量存放他们并加以利用的方法,可就这个0x00我没办法,
若能0x00可以被利用了,我惊讶的发现,bat 不靠任何外部命令,仅内部命令,便可以生产任何我想要的三方!
这就是我发现的秘密。
只是看来要用到ascode技术,那么人家的方案比我的简洁很多多多。。。
作者: 523066680 时间: 2011-5-14 14:54
plp的帖子我从此不看
作者: asnahu 时间: 2011-5-14 15:37
本帖最后由 asnahu 于 2011-5-14 19:40 编辑
qzw 开个专题讲解一下 ascode 吧
作者: CrLf 时间: 2011-5-14 15:40
plp的帖子我从此不看
523066680 发表于 2011-5-14 14:54
这是为神马...
作者: powerbat 时间: 2011-5-14 16:47
>仅内部命令,便可以生产任何我想要的三方
不明白怎么实现。。。
exe→转化→批处理可存储的字符→还原→exe
转化和还原仅内部命令可以实现吗?
或者你不是采用这种转换模式?
难道是用echo之类命令直接生成exe文件?
那你exe文件结构的了解不是一般的彻底,那是相当彻底。
拜服。。。
相比之下ascode技术倒没有如此令我惊叹。
作者: yjstone 时间: 2011-5-14 21:08
本帖最后由 yjstone 于 2011-5-14 22:57 编辑
不好意思,理解错了,还以为是生成一个含nul字符的文件文件呢!
作者: yjstone 时间: 2011-5-14 21:22
本帖最后由 yjstone 于 2011-5-14 22:59 编辑
学习一下高手的方法,我原来以为 是用ehco.^nul >a.txt呢。
作者: Hello123World 时间: 2011-5-15 11:31
我也一直以为是echo nul>1.txt
原来是空字符文本,中英混合的语法错误,我觉得楼主把nul改成空字符更便于理解。
作者: neorobin 时间: 2011-5-15 11:36
以下的代码利用外部命令 findstr 达成目的, 但楼主明确要求 不使用任何外部命令,
期待完全符合楼主期望的代码.- >> bin.txt findstr /v /r /c:$ "%~0"
- REM statements
- REM command...
- <only a null charactor>
复制代码
此代码的末行是唯一的一个 null 字符, 若 bin.txt (.txt 扩展名不是必须的)不存在,
将创建仅含一个 null 字符的文件, 否则将一个 null 字符加入到文件的末尾.
这个字符输入方式:
命令行中: (配合 copy con 可保存到新建的文件中)
Ctrl+@
Alt+256 (数字小键盘区, 笔记本可用 Alt+Fn+256 (数字小键区))
notepad++:
输入并选择:
00
"TextFX" -> "TextFX Convert" -> "Convert Hex to text"
小趣发现: 命令行下, 输入 Ctrl+@, 回车, 显示 more? , 再输入 Ctrl+@, 回车, 窗口被关闭.
参考:
http://stackoverflow.com/questions/2730732/how-can-i-write-a-null-ascii-character-nul-to-a-file-with-a-windows-batch-scrip
作者: qzwqzw 时间: 2011-5-15 21:11
有个疑问,你14楼的代码为什么要多一行 echoo >nul?
是为了防止在不同的语言环境下出现“Invalid keyboard code specified”的错误输出干扰echoo.com的正常输出
主要是针对系统内不存在“英语(美国)”语言的情况
第一次运行echoo.com或其它的16位程序后键盘代码会进行切换
第二次运行不会再有这样的提示
echoo.com $# 创建的是"-"
echoo.com $$创建 但是"="
而echoo.com $#$$ 又创建的不是"=-" 而是"4#"
这里是怎么对应的?
程序固定从$后取两个字符进行计算
如果只跟一个字符则会将回车符0x0d取入合并计算
16进制转10进制算法并不严格检验输入数的合法性
所以会有一些莫名其秒的误差
第三句是取了$#$ 再取$
这段代码仍然是ASCII汇编大师Herbert Kleebauer 的作品
其作品通常只会有Motorola样式汇编源码
与通常我们所学习的Intel样式汇编略有不同
有余力的可以查看以下代码- @=$178
- move.w #1,r2 ; write 1 char
- move.w r2,r3 ; to stdout
- move.w #buf,r1 ; write buffer
- move.w r1,r6
- move.w #$80,r5
-
- movu.bw (r5.w),r4 ; cmdline length
- _30: inc.w r5
- dec.w r4
- bmi.b _100 ; at least 1 byte
- cmp.b #' ',(r5.w)
- beq.b _30
-
- _10: move.b (r5.w),r0 ; next byte from cmdline
- inc.w r5
- move.b r0,(r6.w)
- cmp.b #',r0
- bne.b _20
- move.b (r5.w),r0
- inc.w r5
- bsr.w hex2bin
- move.b (r5.w),r0
- inc.w r5
- bsr.w hex2bin
- _20: move.b #$40,m0
- trap #$21
- dec.w r4
- bpl.b _10
- _100: rts.w
-
- hex2bin:
- or.b #$20,r0
- sub.b #'a'-10,r0
- bpl.b _10
- add.b #'a'-10-'0',r0
- _10: lsl.b #4,(r6.w)
- add.b r0,(r6.w)
- dec.w r4
- rts.w
- buf:
复制代码
作者: caruko 时间: 2011-5-18 02:48
本帖最后由 caruko 于 2011-5-18 02:49 编辑
copy con a.txt
然后输入 ctrl+z
想了一下,可以这样 copy nul a.txt
debug a.txt
d100 发现全0
作者: caruko 时间: 2011-5-18 02:53
呃,copy nul 原来有了。
回复没翻页没看到。
作者: caruko 时间: 2011-5-18 02:57
本帖最后由 caruko 于 2011-5-18 10:28 编辑
不过,变量赋值为00这个16进制字符,使用它会提示变量没有定义。
一般 set "x=",表示销毁X变量, 除非利用DEBUG,更改变量表中的数据。
制作了一个 0077 2个字节的文本。
notepad打开只看到一个w。
type 输出可以看到w前有一个空格。
但是set /p=<nnn.txt,跟for 提取都提取不到。
试试,type输出,然后复制出来的复制代码
作者: CrLf 时间: 2011-5-18 13:57
copy con a.txt
然后输入 ctrl+z
想了一下,可以这样 copy nul a.txt
debug a.txt
d100 发现全0
caruko 发表于 2011-5-18 02:48
不是的,debug无论看什么文件,只要超过有效内容而低于64k,显示的都是一堆00,要判断是否输出了nul到文件,用debug可能不合适,还是用dir看字节更明显
plp之所以用@copy nul+nul sub.txt能获取结束符,是利用了copy ?+?时会自动给文件之间加上结束符的特性,而copy /b就不会加上这个结束符。可以看到,此处的nul仍然相当于空,而非十六进制的00,至于copy con再结束输入,好奇之下试了试,似乎也没有效果。
作者: CrLf 时间: 2011-5-18 14:00
还有,上次寒夜孤星教过我们如何用debug查看内存中的环境变量,cmd中的环境变量以00为分隔符,内存中的内容我们甚至都没法转义,这大概就像变量替换中的“=”一样,恐怕拿它没办法,所以plp在顶楼说nul无法用变量获取
作者: Demon 时间: 2011-5-31 14:26
以下的代码利用外部命令 findstr 达成目的, 但楼主明确要求 不使用任何外部命令,
期待完全符合楼主期望的代码.>> bin.txt findstr /v /r /c "%~0"
REM statements
REM command...
此代码的末行是唯一的一个 ...
neorobin 发表于 2011-5-15 11:36
最简单的方法居然无人问津,真是悲哀
作者: CrLf 时间: 2011-5-31 14:42
33# Demon
汗一个,当时没看明白,现在一回顾才有点懂了,确实可行
作者: plp626 时间: 2011-6-11 14:34
本帖最后由 plp626 于 2011-6-11 14:35 编辑
参考26楼的思路,某前得到如下结论:
批处理可以仅依赖外部命令findstr 生成仅含一个nul(ascii 0x00)字符的文件:- cmd /u/cecho.>$.tmp
- findstr/vrc:$ $.tmp>0x00.txt
- del $.tmp
复制代码
作者: yiwuyun 时间: 2014-11-25 07:46
搞毛线啊,弄那么复杂。
type nul>1.txt
0字节的空文件,不晓得是不是这个意思。
作者: DAIC 时间: 2014-11-25 08:37
回复 36# yiwuyun
是你理解错了,仅含一个nul字符的文本文件不是0字节空文件。
作者: yiwuyun 时间: 2014-11-25 09:20
回复 37# DAIC
你试了我的代码吗。1.txt中就不是NUL字符。是0x00
作者: amwfjhh 时间: 2014-11-25 09:32
回复 38# yiwuyun
请问你的测试环境是……?我这里type nul>1.txt也仅是建一个空白文件而已,没有任何内容。不含0x00字节。
作者: DAIC 时间: 2014-11-25 11:19
回复 38# yiwuyun
测试环境:Win7 SP1 x64
没看到0x00在哪里。你是怎么看到的?
c:\Test>type nul>1.txt
c:\Test>xxd 1.txt
c:\Test>
其实有一个非常简单的方法来判断,如果文件里面包含NUL(0x00),它的文件大小不可能是零。
你也试试别人的代码吧,看看是不是跟你自己的代码得到的结果不一样:
c:\Test>cmd /u/cecho.>$.tmp
c:\Test>findstr/vrc $.tmp>2.txt
c:\Test>xxd 2.txt
0000000: 00 .
c:\Test>
作者: email10t 时间: 2015-4-5 15:40
不用外部指令就没法实现- fsutil file createnew (filename) 1
复制代码
作者: email10t 时间: 2015-4-5 15:59
re: qzwqzw
有个疑问,你14楼的代码为什么要多一行 echoo >nul?如此也可方便生产0x00字符;
刚才看到 ...
plp626 发表于 2011-5-14 13:27
echoo.com $# 创建的是"-"
echoo.com $$创建 但是"="
而
echoo.com $$$# 又创建的不是"=-" 而是"4#"
作者: cheng 时间: 2015-6-3 07:49
如是想生成一个空文件,如下命令即可(在命令提示符中)
type nul>cheng.txt
作者: aa77dd@163.com 时间: 2016-10-17 15:39
原生的外部命令最容易的方式
41楼
http://bbs.bathome.net/redirect. ... 2284&pid=165948
作者: 老刘1号 时间: 2017-5-10 23:30
本帖最后由 老刘1号 于 2017-7-17 15:39 编辑
- >tmp Echo AA==
- certutil -decode tmp null.txt
- del tmp
复制代码
base64看多了……现在直接手写…
作者: 无忧 时间: 2017-5-15 15:41
复制代码
这样么?在文件里显示nul字符??
作者: 1055367558 时间: 2017-9-14 21:56
转义符?^..............
欢迎光临 批处理之家 (http://bbs.bathome.net/) |
Powered by Discuz! 7.2 |