Modernise security with stack randomisation PowerBASIC Peer Support Community (original) (raw)
I tried using your method 1 (post #1) and method 2 (post #15) with the following program
Code:
' Transient MsgBox RandStack.bas
' Transient message box which closes by itself after some time ' it has animation blinking message
' It incorporates the Randomized Stack routines by Steve
#COMPILE EXE #DIM ALL #INCLUDE "win32api.inc"
ENUM controlnumbers SINGULAR ID_MsgGrafix = 500 ID_countdown END ENUM
' for Stack1 method GLOBAL bstp AS DWORD
' for Stack2 method GLOBAL preesp AS DWORD ' stack pointer before mod GLOBAL pstesp AS DWORD ' stack pointer after mod
'============================= FUNCTION PBMAIN () AS LONG
GitRandNum_Stack2
DispTransientMsgBox
END FUNCTION
'====================================== ' initialize some random numbers ' to feed stack pointer (by Steve Hutchinson ) ' method 1 ' https://forum.powerbasic.com/forum/user-to-user-discussions/powerbasic-inline-assembler/819409-modernise-security-with-stack-randomisation#post819409 SUB GitRandNum_Stack1 LOCAL tcnt AS DWORD LOCAL seed AS DWORD LOCAL rand AS DWORD LOCAL lcnt AS DWORD
tcnt = GetTickCount ' get a number sample
! mov eax, tcnt
! bswap eax ' invert byte order
! mov seed, eax ' store it as a seed
! mov lcnt, 64 ' loop iteration count
RANDOMIZE seed ' set seed as base for rnd
lbl: rand = RND(1, 32) ' random numbers in the range of 1 to 32 ! sub lcnt, 1 ! jnz lbl
! mov eax, rand ' load rnd result into eax
! shl eax, 4 ' mul by 16 original side comment had not been updated but the code is correct
! sub esp, eax ' subtract result from stack pointer
! mov bstp, esp ' a copy of ESP after mod
END SUB
'====================================== ' initialize some random numbers ' to feed stack pointer (by Steve Hutchinson ) ' method 2 ' https://forum.powerbasic.com/forum/user-to-user-discussions/powerbasic-inline-assembler/819409-modernise-security-with-stack-randomisation?p=819498#post819498 SUB GitRandNum_Stack2 #REGISTER NONE
! mov preesp, esp ' store ESP default
' -------------------- ' randomise loop count ' -------------------- ! rdtsc ' get a fast changing number from the processor ! bswap eax ' invert it to get the fast changing end ! push eax ! call seed_rrand ' seed rrand ! push 64 ! push 16 ! call rrand ! mov esi, eax ' loop counter
' -------------------- ' randomise stack ' -------------------- ! rdtsc ' get a fast changing number from the processor ! bswap eax ' invert it to get the fast changing end ! push eax ! call seed_rrand ' seed rrand
lbl: ! push 64 ! push 1 ! call rrand ! sub esi, 1 ! jnz lbl
! shl eax, 4 ' mul by 16
! sub esp, eax ' subtract result from stack pointer
! mov pstesp, esp ' store modified ESP
END SUB
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
FASTPROC seed_rrand
GLOBAL rrand____seed AS DWORD
GLOBAL rrand____padd AS DWORD
! mov eax, [esp+4]
! mov rrand____seed, eax
! ret 4
END FASTPROC
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
FUNCTION rrand(BYVAL lowest AS DWORD,BYVAL highest AS DWORD) AS DWORD
#REGISTER NONE
PREFIX "!" ; ---------------------- ; generate random number ; ---------------------- mov eax, rrand____seed mov edx, rrand____padd mov rrand____seed, edx mov ecx, eax shl ecx, 13 xor eax, ecx mov ecx, eax xor ecx, edx shr eax, 19 xor ecx, eax mov eax, edx shr eax, 31 xor ecx, eax mov rrand____seed, ecx lea eax, [edx+ecx] bswap eax
' -------------------------- ' convert it to within range ' -------------------------- mov ecx, highest ; load highest into ecx sub ecx, lowest ; sub lowest from it add ecx, 1 ; correct the range div ecx ; divide eax by highest range value mov eax, edx ; copy division remainder into eax add eax, lowest ; add lowest to get correct range mov FUNCTION, eax ; return value in eax
END PREFIX
END FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
'============================== ' Display the Transient message box SUB DispTransientMsgBox LOCAL hMsgWin AS DWORD, Lreturnval AS LONG DIALOG NEW PIXELS, 0, "", , ,400, 80, _ %WS_POPUP OR %WS_BORDER TO hMsgWin
CONTROL ADD GRAPHIC, hMsgWin, %ID_MsgGrafix, "", _
0, 0, 400, 80, %SS_NOTIFY OR %WS_BORDER
DIALOG SHOW MODAL hMsgWin, CALL MsgDlgProc TO Lreturnval
END SUB
'================================== ' Callback function for the Transient message box CALLBACK FUNCTION MsgDlgProc() AS LONG STATIC downcount AS LONG
LOCAL hFONT9_bold AS DWORD
' Bold font for the label
FONT NEW "Arial",9,1 TO hFONT9_bold
SELECT CASE CB.MSG
CASE %WM_INITDIALOG
settimer(CB.HNDL, %ID_countdown , 500, 0)
' Change this to allocate the time to close down message box
downcount = 10
GRAPHIC ATTACH CB.HNDL, %ID_MsgGrafix
GRAPHIC COLOR %RGB_CRIMSON, %RGB_ALICEBLUE
GRAPHIC CLEAR
GRAPHIC SET FONT hFONT9_bold
GRAPHIC SET POS (10, 25)
' using stack randomizer method 1
' GRAPHIC PRINT "Please wait ... computation in progress Stack pointer: "+STR$(bstp)
' using stack randomizer method 2 -- did not work?
GRAPHIC PRINT "Please wait ... computation in progress Stack pointer: "+STR$(pstesp)
' this is to display Countdown message -- display only when needed
' GRAPHIC COLOR %RGB_DARKGREEN, %RGB_ALICEBLUE
' GRAPHIC SET POS (30, 50)
' GRAPHIC PRINT "Countdown " + TRIM$(downcount) + " "
CASE %WM_TIMER
GRAPHIC ATTACH CB.HNDL, %ID_MsgGrafix
SELECT CASE CB.CTL
CASE %ID_countdown
' this is to display Countdown message -- display only when needed
' GRAPHIC COLOR %RGB_DARKGREEN, %RGB_ALICEBLUE
' GRAPHIC SET POS (30, 50)
' GRAPHIC PRINT "Countdown: " + TRIM$(downcount) + " "
' Alternate display of thick frame border or no border on dialog
' changes with each countdown -- like a heartbeat
' if want rapid blinking reduce the timer time
SetWindowLong GetDlgItem(CB.HNDL, %ID_MsgGrafix), %GWL_STYLE, _
GetWindowLong(GetDlgItem(CB.HNDL, %ID_MsgGrafix), %GWL_STYLE) XOR %WS_BORDER
SetWindowPos GetDlgItem(CB.HNDL, %ID_MsgGrafix),0,0,0,0,0,_
%SWP_NoMove OR %SWP_NoSize OR %SWP_DrawFrame
DECR downcount
' modified to close the application
' when downcount < 0
' (about 10 secs if we start with downcount= 10)
IF downcount < 0 THEN
killtimer(CB.HNDL, %ID_countdown )
DestroyWindow CB.HNDL
END IF
END SELECT
END SELECT
END FUNCTION
Both methods work and method 2 gives more randomized pointers
Did I do anything wrong here?