[英]Are there any possible complications from seeding a PRNG with the machine's stack pointer?
我對低級編程和x86架構有一個粗略的了解。 據我所知,當前堆棧指針(英特爾機器上的SP
, ESP
或RSP
)的值是不可預測的,因為它很可能在一秒鍾內改變幾次,它讓我覺得比當前系統時間更難以預測的種子(通常以秒為單位)。
例如:
.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
即使在一秒鍾內多次執行相同的程序,該程序的輸出也會有所不同。
然而,我認為,因為我很可能不是地球上第一個想到這個想法的人,如果有任何潛在的陷阱或災難,我冒這樣做的風險 - 正如我之前所說,我'我剛剛學習裝配。
時間戳計數器進展非常快,而堆棧指針(和其他寄存器)可能會在程序運行時使用一些地址(實質上,每個可能的調用鏈一個地址導致您的播種器功能,可能只有一個)。
PRNG需要什么? 在Linux上有隨機設備,專門用於此類用途。 AFAIU,BSD Unices有類似的東西。 對於模擬或測試,能夠重復安全性是有用的; 例如,與TSC當前時間播種的游戲應該是充足的。
雖然堆棧指針不會保持不變的基本假設是合理的,但使用它作為隨機數生成器有幾個主要問題:
首先 - 當你在一個程序中處於同一級別時(例如,4個函數) - 堆棧指針將保持相當不變。 例如,如果我從main轉到proc1到proc2,那么每次進入proc1我都會將5個項目推送到堆棧,每次離開proc1時我都會從堆棧中彈出7個項目。 最后,每當我進入proc1時,我的堆棧指針幾乎都在同一個地方。 在隨機數生成器的情況下這是不好的,因為如果你多次調用它,你通常會在相同的深度調用它,因此大致相同的堆棧指針。 如果你在遞歸函數中使用它,這不是問題,但這是非常有限的。
第二 - 盡管堆棧指針確實發生了變化,但它並沒有那么大的變化。 良好的隨機性不僅意味着良好的隨機功能,而且意味着良好的種子 - 高級/密碼系統可以並且通常確實使其熵“耗盡”。 從某種意義上說,在隨機函數的兩次連續運行之間,您的堆棧指針只會改變大約0x10到0x40字節,這對於良好的隨機性來說不夠遠。
最后 - 堆棧的起始大小對程序輸出產生巨大影響。 堆棧的大小是否從0x1000開始或者是否從大小0x3000開始將對輸出產生重大變化,因為輸入值通常會在該起始值附近徘徊(假設您的程序不是特別大),使其成為主要來源隨機性的過程。
裝配中的隨機性很難,但這不是解決方案
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.