标题: [其他] 跟踪CMD中的随机数%random% [打印本页]
作者: vsbat 时间: 2010-11-26 20:30 标题: 跟踪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函数,简化下给大家看- push 1
- call FlsGetValue ;返回值eax 是一个结构的指针(这个结构与纤程有关,我们不管其具体含义)
- mov ecx,[eax + 14h] ;[eax + 14h]对我们的随机数 至关重要 !从计算过程可以看出,它直接影响随机数的计算!
- imul ecx,ecx,343FDh ;ecx里就是从[eax + 14h]取出来的值,看它在计算了
- add ecx,269EC3h
- mov [eax + 14h],ecx ;这里更新了 [eax + 14h],这样下次我们再取随机数,再用到[eax + 14h],那么他已经不是原来的值了
- mov eax,ecx ;这样每一次的数值才可能不同
- shr eax,10h
- 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语句内部的确是与预处理有关,就如这个- @echo off
- for /l %%a in (1,1,10) do echo %random%
- pause>nul
复制代码
它的执行是,执行时处理%random%然后就echo random的值10次,其间不再调用 msvcrt.dll 里的 rand 函数,大家知道,这就意味着,
它只负责把变量处理一次,然后自己找个地方存起来,以后for里面do后的命令都用它自己存起来的这个值,不再重新获得变量的值!
而开启了 变量延迟 的是:每次 都重新 调用 msvcrt.dll 里的 rand 函数,即每次系统都主动更新变量,不自己存储。
【内容 已更新,找到了随机数种子 ~~~ 就是 时间 】
[ 本帖最后由 vsbat 于 2010-12-2 00:12 编辑 ]
作者: vsbat 时间: 2010-11-26 21:02
汇编看着可能比较乱 ~~~ 排版不知道怎么就这样了
想看的可以复制到 记事本里 效果好点,加了 code 标签后更乱了,就没加
另:
测试环境 : Win 7 Home Basic
作者: zqz0012005 时间: 2010-11-26 22:09
我感觉基本上所有程序员都对批处理不屑一顾,但终于偶尔发现还是有些人对这个东西有点研究。
期待更多人一起把cmd.exe彻底破解!对命令、脚本的解析原理和流程等从根本上给出解释。
作者: netbenton 时间: 2010-11-26 22:41
同一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 编辑 ]
作者: netbenton 时间: 2010-11-27 00:03
又测试了一下,发现,并不是与系统开机时间有关,而是直接与系统时间有关,
同样用上一面的aaaa.bat
再进行以下测试:
bbbb.bat- echo; 0:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 1:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 2:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 3:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 4:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 5:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 6:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 7:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 8:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 9:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 10:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
-
- echo; 11:00:00.00 | time
- ping -n 3 127.1 >nul
- start aaaa.bat %time%
复制代码
可以看出,cmd 里第一次调用%random%绝对的和时间有关
再做一次实验,把 aaaa.bat再增加几行, 改成以下:
echo %random%
echo %random%
echo %random%
然后运行两次 bbbb.bat ,
哇~~~~
只要第一次调用 %random% 的结果相同则后面的全都对应的相同,可见,%random%是以上一次的结果进行一定运算所得。
作者: vsbat 时间: 2010-11-27 00:34 标题: 回 LS
嗯 ~~ 我明天 继续挖挖 ~~ 是个 问题
感觉应该 与时间有关联~
[ 本帖最后由 vsbat 于 2010-11-27 00:35 编辑 ]
作者: cjiabing 时间: 2010-11-27 07:59
个个都是高手!~
看来上次我说的那个不幸言中:random是伪随机数,而time才是真随机数!~
作者: vsbat 时间: 2010-11-27 10:36
谢 netbenton ,是他催使我继续跟踪了一番~~~
以前 以为 时间种子初始值是与时间无关的 --- 但
跟踪后 发现 人家 CMD 居然 调用 了 msvcrt.dll 里的 time 函数 和 srand 函数,来实现以 时间 作为 随机数种子 !
这就能解释 为什么连续多次 打开 同一个 echo %random% 的bat 其显示的 数值 接近了!
相关内容 已更新至 顶楼
作者: cjiabing 时间: 2010-11-27 10:54
用时间和随机数表重新做%random%
- 03 47 43 73 86 36 96 47 36 61 46 99 69 81 62
- 97 74 24 67 62 42 81 14 57 20 42 53 32 37 32
- 16 76 02 27 66 56 50 26 71 07 32 90 79 78 53
- 12 56 85 99 26 96 96 68 27 31 05 03 72 93 15
- 55 59 56 35 64 38 54 82 46 22 31 62 43 09 90
- 16 22 77 94 39 49 54 43 54 82 17 37 93 23 78
- 84 42 17 53 31 57 24 55 06 88 77 04 74 47 67
- 63 01 63 78 59 16 95 55 67 19 98 10 50 71 75
- 33 21 12 34 29 78 64 56 07 82 52 42 07 44 28
- 57 60 86 32 44 09 47 27 96 54 49 17 46 09 62
- 18 18 07 92 46 44 17 16 58 09 79 83 86 19 62
- 26 62 38 97 75 84 16 07 44 99 83 11 46 32 24
- 23 42 40 54 74 82 97 77 77 81 07 45 32 14 08
- 62 36 28 19 95 50 92 26 11 97 00 56 76 31 38
- 37 85 94 35 12 83 39 50 08 30 42 34 07 96 88
- 70 29 17 12 13 40 33 20 38 26 13 89 51 03 74
- 56 62 18 37 35 96 83 50 87 75 97 12 25 93 47
- 99 49 57 22 77 88 42 95 45 72 16 64 36 16 00
- 16 08 15 04 72 33 27 14 34 09 45 59 34 68 49
- 31 16 93 32 43 50 27 89 87 19 20 15 37 00 49
复制代码
作者: powerbat 时间: 2010-11-27 22:52
计算机实现的随机算法大多为伪随机。
时间不应该是随机数吧?只是我们“获取时间”这个动作才是随机的。
(当然如果从相对论来看,时间是与物质相关的,物质的变化如果是随机的,时间就是随机的。但宇宙中的物质的变化在某些尺度(宏观)是有规律的,在另一些尺度(微观)是随机的,它们是如何影响时间的?天啊,这在我想像力之外...)
作者: jqrung 时间: 2010-12-2 11:54
效果不错噢 学习啦
作者: ht河豚 时间: 2012-9-2 11:34
看来,%random%要改进啊
欢迎光临 批处理之家 (http://bathome.net./) |
Powered by Discuz! 7.2 |