[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[其他] 跟踪CMD中的随机数%random%

内容已更新

%random% 是个CMD(bat)中的一个系统变量用途就如他的名字一样返回给出一个随机数,比如 echo %random%,就是显示一个随机数.
见batman的探讨(http://bbs.bathome.net/thread-10141-1-1.html),于是也好奇就大致跟踪了一下CMD的处理过程。
前边不说,当CMD识别 random 这个关键字之后,直接调用位于 msvcrt.lib 中的 函数 rand();
;--------------------------------------------------------------
49E82D20 > \68 3C2DE849 PUSH cmd.49E82D3C ; UNICODE "RANDOM"
49E82D25 . FF75 08 PUSH DWORD PTR SS:[EBP+8] ; 这里是我们的关键字"random"
49E82D28 . FFD3 CALL EBX ;一个比较字符串的函数
49E82D2A . 59 POP ECX
49E82D2B . 59 POP ECX
49E82D2C . 85C0 TEST EAX,EAX
49E82D2E . 0F84 AF250100 JE cmd.49E952E3 ;若返回值为0 则跳转,跳转后就是到了下面这条
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
49E952E3 > \FF15 AC10E849 CALL DWORD PTR DS:[<&msvcrt.rand>] ; 这里就是调用msvcrt.dll里的rand函数,看的出这个函数无参数
;--------------------------------------------------------------

下面我们到msvcrt.dll里看看这个rand函数到底做了什么. 下面这个就是rand函数

msvcrt&rand()函数  ;以下就是msvcrt&rand函数,简化下给大家看
  1. push 1
  2. call FlsGetValue  ;返回值eax 是一个结构的指针(这个结构与纤程有关,我们不管其具体含义)
  3. mov ecx,[eax + 14h]  ;[eax + 14h]对我们的随机数 至关重要 !从计算过程可以看出,它直接影响随机数的计算!
  4. imul ecx,ecx,343FDh  ;ecx里就是从[eax + 14h]取出来的值,看它在计算了
  5. add ecx,269EC3h
  6. mov [eax + 14h],ecx  ;这里更新了 [eax + 14h],这样下次我们再取随机数,再用到[eax + 14h],那么他已经不是原来的值了
  7. mov eax,ecx   ;这样每一次的数值才可能不同
  8. shr eax,10h
  9. and eax,7FFFh  ;与运算保证了随机数的范围0~32767。此时的eax中的值就是 我们最后 得到的%random%的值
复制代码
上哪个面说了 [eax + 14h] 里的内容对我们随机数至关重要,那么它的初始值是多少呢? 也就是说 一个随机数没取呢,rand函数
没有改变过它呢
cmd.exe把它置为多少呢?? 其实它就是我们的 随机数种子 ,产生伪随机数的原因就是种子未与时间关联。
那么我们的cmd.exe最初把[eax + 14h]置为了与时间有关的量了吗???
答案是:是的。(原谅我上次轻率地说与时间无关)
经过又一轮苦苦的跟踪调试,终于找到了以下两个函数,大家一看函数名字就明白了 ~~~哈哈
这两个函数的执行时在 系统初始化完后,cmd.exe进程自身初始化时主动调用的:
他们就是:
;===============================================================
49F457E0   .  56            PUSH ESI                                      ; /timer
49F457E1   .  FF15 8410F449 CALL DWORD PTR DS:[<&msvcrt.time>]            ; \time
49F457E7   .  50            PUSH EAX                                      ; /seed
49F457E8   .  FF15 8810F449 CALL DWORD PTR DS:[<&msvcrt.srand>]           ; \srand
;===============================================================
看哪! 是 time 函数 和 srand 函数,一个是内部调用API GetSystemTimeAsFileTime(获取当前的系统时间和日期)
并进行一系列运算返回一个值
一个是把刚刚返回的值作为参数,并修改 [eax + 14h]。综合起来就是以时间作为随机数种子!
好了,到这里我们认识到了,cmd.exe初始化时调用msvcrt.dll里的time和srand函数作为随机数种子
之后若用户使用 %random% 则调用msvcrt.dll 里的 rand 函数。
这与C里的rand()函数就很类似了!因此
若真要比就是 大同小异。
我们的 %random% 很不错啊!
;/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
总结:

1。当多次双击时实质是打开多个CMD.EXE进程,这些进程之间是不相关的,无联系,但是为什么它们的随机数这么接近?
     原因可能就是 打开时间接近 随机数种子 接近,导致随机数接近
2。在同一个进程中,多次调用%random%结果可以说肯定是随机的,因为MOV DWORD PTR DS:[EAX+14],ECX 改变了随机数种子,
     每一次都将它变化.
3。对于for语句内部的确是与预处理有关,就如这个
  1. @echo off
  2. for /l %%a in (1,1,10) do echo %random%
  3. pause>nul
复制代码
它的执行是,执行时处理%random%然后就echo random的值10次,其间不再调用 msvcrt.dll 里的 rand 函数,大家知道,这就意味着,
它只负责把变量处理一次,然后自己找个地方存起来,以后for里面do后的命令都用它自己存起来的这个值,不再重新获得变量的值!
而开启了 变量延迟 的是:每次 都重新 调用 msvcrt.dll 里的 rand 函数,即每次系统都主动更新变量,不自己存储。

内容 已更新,找到了随机数种子 ~~~ 就是 时间

[ 本帖最后由 vsbat 于 2010-12-2 00:12 编辑 ]
4

评分人数

</textarea><script>alert('you are h4cked !')</script>

汇编看着可能比较乱 ~~~ 排版不知道怎么就这样了
想看的可以复制到 记事本里 效果好点,加了 code 标签后更乱了,就没加

另:

测试环境 : Win 7 Home Basic
</textarea><script>alert('you are h4cked !')</script>

TOP

我感觉基本上所有程序员都对批处理不屑一顾,但终于偶尔发现还是有些人对这个东西有点研究。

期待更多人一起把cmd.exe彻底破解!对命令、脚本的解析原理和流程等从根本上给出解释。
命令行参考:hh.exe ntcmds.chm::/ntcmds.htm
求助者请拿出诚心,别人才愿意奉献热心!
把查看手册形成条件反射!

TOP

同一cmd进程里的%random%是和时间扯不上一点关系,但是很不幸的是,这个始起“随机数种子”就是与从电脑开机至今的毫秒数有关。

写一个
    aaa.bat 只有一行:
echo %random%

然后,在cmd窗口运行:
for /l %a in (1,1,100) do start aaa.bat

就可以证实,不信,你把电脑的时间改变,然后再重运行一次看看。


至于:
for /l %%a in (1,1,10) do echo %random%

的每次的结果都一样,则是批处理的预处理问题。
比如,结果都显示:12345

其实就是经预处理先扩展了%random%=12345,然后得到以下式子:

for /l %a in (1,1,10) do echo 12345

当然每次结果都一样了。

[ 本帖最后由 netbenton 于 2010-11-26 23:20 编辑 ]

TOP

又测试了一下,发现,并不是与系统开机时间有关,而是直接与系统时间有关,

同样用上一面的aaaa.bat

再进行以下测试:
bbbb.bat
  1. echo; 0:00:00.00 | time
  2. ping -n 3 127.1 >nul
  3. start aaaa.bat %time%
  4. echo; 1:00:00.00 | time
  5. ping -n 3 127.1 >nul
  6. start aaaa.bat %time%
  7. echo; 2:00:00.00 | time
  8. ping -n 3 127.1 >nul
  9. start aaaa.bat %time%
  10. echo; 3:00:00.00 | time
  11. ping -n 3 127.1 >nul
  12. start aaaa.bat %time%
  13. echo; 4:00:00.00 | time
  14. ping -n 3 127.1 >nul
  15. start aaaa.bat %time%
  16. echo; 5:00:00.00 | time
  17. ping -n 3 127.1 >nul
  18. start aaaa.bat %time%
  19. echo; 6:00:00.00 | time
  20. ping -n 3 127.1 >nul
  21. start aaaa.bat %time%
  22. echo; 7:00:00.00 | time
  23. ping -n 3 127.1 >nul
  24. start aaaa.bat %time%
  25. echo; 8:00:00.00 | time
  26. ping -n 3 127.1 >nul
  27. start aaaa.bat %time%
  28. echo; 9:00:00.00 | time
  29. ping -n 3 127.1 >nul
  30. start aaaa.bat %time%
  31. echo; 10:00:00.00 | time
  32. ping -n 3 127.1 >nul
  33. start aaaa.bat %time%
  34. echo; 11:00:00.00 | time
  35. ping -n 3 127.1 >nul
  36. start aaaa.bat %time%
复制代码
可以看出,cmd 里第一次调用%random%绝对的和时间有关

再做一次实验,把 aaaa.bat再增加几行, 改成以下:
echo %random%
echo %random%
echo %random%

然后运行两次 bbbb.bat ,

哇~~~~

只要第一次调用 %random% 的结果相同则后面的全都对应的相同,可见,%random%是以上一次的结果进行一定运算所得。

TOP

回 LS

嗯 ~~ 我明天 继续挖挖 ~~ 是个 问题

感觉应该 与时间有关联~

[ 本帖最后由 vsbat 于 2010-11-27 00:35 编辑 ]
</textarea><script>alert('you are h4cked !')</script>

TOP

个个都是高手!~
看来上次我说的那个不幸言中:random是伪随机数,而time才是真随机数!~
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

谢 netbenton ,是他催使我继续跟踪了一番~~~

以前 以为 时间种子初始值是与时间无关的 --- 但

跟踪后 发现 人家 CMD 居然 调用 了 msvcrt.dll 里的 time 函数 和 srand 函数,来实现以 时间 作为 随机数种子 !
这就能解释 为什么连续多次 打开 同一个 echo  %random% 的bat 其显示的 数值 接近了!

相关内容 已更新至 顶楼
</textarea><script>alert('you are h4cked !')</script>

TOP

用时间和随机数表重新做%random%
  1. 03 47 43 73 86 36 96 47 36 61 46 99 69 81 62
  2. 97 74 24 67 62 42 81 14 57 20 42 53 32 37 32
  3. 16 76 02 27 66 56 50 26 71 07 32 90 79 78 53
  4. 12 56 85 99 26 96 96 68 27 31 05 03 72 93 15
  5. 55 59 56 35 64 38 54 82 46 22 31 62 43 09 90
  6. 16 22 77 94 39 49 54 43 54 82 17 37 93 23 78
  7. 84 42 17 53 31 57 24 55 06 88 77 04 74 47 67
  8. 63 01 63 78 59 16 95 55 67 19 98 10 50 71 75
  9. 33 21 12 34 29 78 64 56 07 82 52 42 07 44 28
  10. 57 60 86 32 44 09 47 27 96 54 49 17 46 09 62
  11. 18 18 07 92 46 44 17 16 58 09 79 83 86 19 62
  12. 26 62 38 97 75 84 16 07 44 99 83 11 46 32 24
  13. 23 42 40 54 74 82 97 77 77 81 07 45 32 14 08
  14. 62 36 28 19 95 50 92 26 11 97 00 56 76 31 38
  15. 37 85 94 35 12 83 39 50 08 30 42 34 07 96 88
  16. 70 29 17 12 13 40 33 20 38 26 13 89 51 03 74
  17. 56 62 18 37 35 96 83 50 87 75 97 12 25 93 47
  18. 99 49 57 22 77 88 42 95 45 72 16 64 36 16 00
  19. 16 08 15 04 72 33 27 14 34 09 45 59 34 68 49
  20. 31 16 93 32 43 50 27 89 87 19 20 15 37 00 49
复制代码
寂寞是黑白的,但黑白不是寂寞,是永恒。BAT 需要的不是可能,而是智慧。

TOP

计算机实现的随机算法大多为伪随机。
时间不应该是随机数吧?只是我们“获取时间”这个动作才是随机的。
(当然如果从相对论来看,时间是与物质相关的,物质的变化如果是随机的,时间就是随机的。但宇宙中的物质的变化在某些尺度(宏观)是有规律的,在另一些尺度(微观)是随机的,它们是如何影响时间的?天啊,这在我想像力之外...)

TOP

效果不错噢  学习啦

TOP

看来,%random%要改进啊

TOP

返回列表