Board logo

标题: 【挑战】批处理如何创建仅含一个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

抛砖了:
  1. @echo off
  2. (echo A100&echo MOV DL,00&echo MOV AH,02&echo INT 21&echo INT 20&echo,&echo G&echo q)>db
  3. for /f "skip=8 delims=Progamteindly" %%a in ('debug^<db') do set/p=%%a<nul>a.txt&goto next
  4. :next
  5. del /q db
复制代码

作者: hanyeguxing    时间: 2011-5-14 02:49

本帖最后由 hanyeguxing 于 2011-5-14 03:31 编辑
  1. 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中断呢?
  1. @echo off
  2. for %%f in (e100 00 rcx 1 nnull.txt w q) do echo %%f>>debug.scr
  3. debug < debug.scr >nul
复制代码
对于这个问题
我能想到的仍然是ASCODE方案
因为它本身就是为了解决第三方工具依赖而出现的
生成0字节只是一个小小的副产物而已
  1. @echo off
  2. echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=>echoo.com
  3. echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU!WvX0GwUY Wv;ovBX2Gv0ExGIuht6>>echoo.com
  4. echo ?@xAyJHmH@=a?}VjuN?_LEkS?`w`s_{OCIvJDGEHtc{OCIKGMgELCI?GGg>>echoo.com
  5. echo EL?s?WL`LRBcx=k_K?AxVD?fCo?Cd?BLDs0>>echoo.com
  6. echoo >nul
  7. echoo.com $00>null.txt
  8. 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源代码中,不过要在注释行加转义字符^
  1. ::{^}
  2. @echo off
  3. set/p sub=<%~s0
  4. setlocal EnableDelayedExpansion
  5. set sub=!sub:~4,1!
  6. set/p=!sub!<nul>sub.txt
复制代码
还可借助copy nul的特性,但要生产临时文件,不过很简洁
  1. @copy nul+nul sub.txt
复制代码

作者: plp626    时间: 2011-5-14 13:27

本帖最后由 plp626 于 2011-5-14 13:46 编辑

re: qzwqzw

有个疑问,你14楼的代码为什么要多一行 echoo >nul?
  1. @echo off
  2. (echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=
  3. echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU!WvX0GwUY Wv;ovBX2Gv0ExGIuht6
  4. echo ?@xAyJHmH@=a?}VjuN?_LEkS?`w`s_{OCIvJDGEHtc{OCIKGMgELCI?GGg
  5. echo EL?s?WL`LRBcx=k_K?AxVD?fCo?Cd?BLDs0)>echoo.com
  6. echoo.com $00>null.txt
复制代码
如此也可方便生产0x00字符;

刚才看到15楼的询问,我还以为这个echoo.com 不方便生产0x1a,试了试也可以,不但可以,还可以生产任意"字符流",以至于可以生成我们想要的任何三方工具,非常惊喜!(未考虑速度)
  1. @echo off
  2. (echo Bj@jzh`0X-`/PPPPPPa(DE(DM(DO(Dh(Ls(Lu(LX(LeZRR]EEEUYRX2Dx=
  3. echo 0DxFP,0Xx.t0P,=XtGsB4o@$?PIyU!WvX0GwUY Wv;ovBX2Gv0ExGIuht6
  4. echo ?@xAyJHmH@=a?}VjuN?_LEkS?`w`s_{OCIvJDGEHtc{OCIKGMgELCI?GGg
  5. echo EL?s?WL`LRBcx=k_K?AxVD?fCo?Cd?BLDs0)>echoo.com
  6. 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 达成目的, 但楼主明确要求 不使用任何外部命令,
期待完全符合楼主期望的代码.
  1. >> bin.txt findstr /v /r /c:$ "%~0"
  2. REM statements
  3. REM command...
  4. <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样式汇编略有不同
有余力的可以查看以下代码
  1.         @=$178
  2.         move.w  #1,r2           ; write 1 char
  3.         move.w  r2,r3           ; to stdout
  4.         move.w  #buf,r1         ; write buffer
  5.         move.w  r1,r6
  6.         move.w  #$80,r5
  7.         movu.bw (r5.w),r4       ; cmdline length
  8. _30:    inc.w   r5
  9.         dec.w   r4
  10.         bmi.b   _100            ; at least 1 byte
  11.         cmp.b   #' ',(r5.w)
  12.         beq.b   _30
  13.         
  14. _10:    move.b  (r5.w),r0       ; next byte from cmdline
  15.         inc.w   r5
  16.         move.b  r0,(r6.w)
  17.         cmp.b   #',r0
  18.         bne.b   _20
  19.         move.b  (r5.w),r0
  20.         inc.w   r5
  21.         bsr.w   hex2bin
  22.         move.b  (r5.w),r0
  23.         inc.w   r5
  24.         bsr.w   hex2bin
  25. _20:    move.b  #$40,m0
  26.         trap    #$21
  27.         dec.w   r4
  28.         bpl.b   _10
  29. _100:   rts.w
  30. hex2bin:
  31.         or.b    #$20,r0
  32.         sub.b   #'a'-10,r0
  33.         bpl.b   _10
  34.         add.b   #'a'-10-'0',r0
  35. _10:    lsl.b   #4,(r6.w)
  36.         add.b   r0,(r6.w)
  37.         dec.w   r4
  38.         rts.w
  39. 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输出,然后复制出来的
  1. ^
复制代码

作者: 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)字符的文件:
  1. cmd /u/cecho.>$.tmp
  2. findstr/vrc:$ $.tmp>0x00.txt
  3. 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

不用外部指令就没法实现
  1. 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 编辑
  1. >tmp Echo AA==
  2. certutil -decode tmp null.txt
  3. del tmp
复制代码
base64看多了……现在直接手写…
作者: 无忧    时间: 2017-5-15 15:41

  1. echo nul>1.txt
复制代码
这样么?在文件里显示nul字符??
作者: 1055367558    时间: 2017-9-14 21:56

转义符?^..............




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2