【问题标题】:Are there any possible complications from seeding a PRNG with the machine's stack pointer?使用机器的堆栈指针播种 PRNG 是否有任何可能的并发症?
【发布时间】:2014-03-15 00:42:46
【问题描述】:

我对低级编程和 x86 架构有一个粗略的了解。据我了解,当前堆栈指针(英特尔机器上的SPESPRSP)处的值是不可预测的,因为它很可能在一秒钟内更改多次,我觉得它是一个更好的不可预测种子比当前系统时间(通常以秒为单位)。

例如:

.386
.MODEL FLAT, STDCALL
.DATA
    fmt db "%d", 10, 0
.CODE
INCLUDELIB MSVCRT
EXTERN printf:PROC
EXTERN rand:PROC
EXTERN srand:PROC
_main PROC
    push ebp
    mov ebp, esp

    push esp
    call srand
    add esp, 4

    mov ecx, 10

l1:
    push ecx
    call rand
    push eax
    push offset fmt
    call printf
    add esp, 8
    pop ecx
    loop l1

    mov esp, ebp
    pop ebp
    add esp, 4
    jmp dword ptr [esp-4]
_main ENDP
END

即使同一程序在一秒钟内执行多次,该程序的输出也会有所不同。

但是,我认为,由于我很可能不是这个星球上第一个想到这个想法的人,如果我这样做有任何潜在的陷阱或灾难的风险这样 - 正如我之前所说,我现在才学习组装。

【问题讨论】:

    标签: assembly random x86 cpu-registers


    【解决方案1】:

    虽然堆栈指针不会保持不变的基本假设是合理的,但将其用作随机数生成器存在几个主要问题:

    首先-当您在程序中处于同一级别时(例如,4 个函数)-堆栈指针将保持几乎不变。例如,如果我从 main 到 proc1 到 proc2,那么每次进入 proc1 都会将 5 个项目压入堆栈,每次离开 proc1 都会从堆栈中弹出 7 个项目。最后,每当我进入 proc1 时,我的堆栈指针几乎都在同一个地方。这在随机数生成器的情况下很糟糕,因为如果你多次调用它,你通常会以相同的深度调用它,因此大约是相同的堆栈指针。如果您在递归函数中使用它,这不是问题,但这是非常有限的。

    第二 - 虽然堆栈指针确实发生了变化,但并没有太大变化。良好的随机性不仅意味着良好的随机函数,还意味着良好的种子 - 高级/密码系统可以并且经常确实将其熵“耗尽”。从某种意义上说,在 random 函数的两次连续运行之间,您的堆栈指针仅更改了大约 0x10 到 0x40 字节,这对于良好的随机性来说还远远不够。

    最后 - 堆栈的起始大小对程序输出有很大影响。堆栈是从大小 0x1000 开始还是从大小 0x3000 开始都会对输出产生重大影响,因为输入值通常会徘徊在该起始值附近(假设您的程序不是特别大),使其成为主要来源过程中的随机性。

    组装中的随机性很难,但这不是解决方案

    【讨论】:

      【解决方案2】:

      Time Stamp Counter 前进得非常快,而堆栈指针(和其他寄存器)可能会在程序运行期间使用一些地址(基本上,每个可能的调用链对应一个指向你的播种函数的调用链,可能只有一个)。

      您需要 PRNG 做什么?在 Linux 上有随机设备,专门用于此类用途。 AFAIU,BSD Unices 也有类似的东西。对于模拟或测试,能够重复序列是有用的;例如TSC当前时间的游戏播种应该很多。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-10-07
        • 1970-01-01
        • 2015-11-16
        • 2013-06-30
        • 1970-01-01
        • 1970-01-01
        • 2010-11-30
        相关资源
        最近更新 更多