The MASM Forum
General => The Laboratory => Topic started by: Vortex on October 29, 2020, 07:20:20 AM
-
This is a function similar to Hutch's random string generator :
http://masm32.com/board/index.php?topic=8881.0
.386
.model flat,stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\msvcrt.inc
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\msvcrt.lib
RandStr PROTO :DWORD,:DWORD
.data?
buffer db 64 dup(?)
.code
start:
invoke RandStr,ADDR buffer,64
invoke ExitProcess,0
RandStr PROC uses esi ebx string:DWORD,stringLen:DWORD
LOCAL _st:SYSTEMTIME
invoke GetSystemTime,ADDR _st
movzx ebx,SYSTEMTIME.wMilliseconds[_st]
@@:
invoke crt_rand
sub ebx,1
jnz @b
mov esi,string
mov edi,255
mov ebx,stringLen
@@:
invoke crt_rand
; xor edx,edx
; div edi
; mov BYTE PTR [esi],dl
mov BYTE PTR [esi],al
add esi,1
sub ebx,1
jnz @b
mov eax,string
ret
RandStr ENDP
END start
Thanks to Hutch for the original PowerBASIC version.
-
How does it work, Erol? With Masm32 "print" I get this:
¡¤ı░╩' ÏØ¶M¶y'YB|£┴°═îç #d©ªçòL░ZìN-Öþ=▒`Ì▒ÇAÚgAÑıƒõ↑ƒ§B
invoke RandStr,ADDR buffer,64
print addr buffer
invoke ExitProcess,0
See also here (http://masm32.com/board/index.php?topic=6483.msg74734#msg74734).
-
JJ,
That's what its supposed to do, generate random binary strings for things like window class names and private message strings. It is different each time the app starts which makes identifying a running app far more difficult.
-
random binary strings for things like window class names and private message strings
Is it documented somewhere that all Windows versions tolerate non-Ascii (or non-Utf8) strings for such purposes?
If not, I would suggest something along these lines:
include \masm32\MasmBasic\MasmBasic.inc
Rand$Buffer db 21 dup(?) ; simple macro to generate random names
Rand$ MACRO
push edi
push ecx
mov edi, offset Rand$Buffer
xor ecx, ecx
.Repeat
add Rand(26), 97 ; lowercase a-z
mov byte ptr [edi+ecx], al
inc ecx
.Until ecx>=20
xchg eax, edi
pop ecx
pop edi
exitm <eax>
ENDM
Init
xor ecx, ecx
.Repeat
PrintLine Str$(ecx), Tb$, Rand$()
inc ecx
.Until ecx>=20
MsgBox 0, "ok?", "Hi", MB_OK
EndOfCode
Output:
0 hgkdugsoymqlnuhekjrl
1 qjgllyaczfaqgytbcflt
2 jfpimsnesezizoxiqggj
3 uhzrgvbnekpucfixjywa
4 trmiqelwactabxvaewvf
5 jbmijqoeaiusqmijxjnf
6 ktyuyseayxfqrrnwlgfh
7 vmermmcpbnqisysjcodv
8 zbmpbvssfaalssgintim
9 vcfnbdixserndiupzhiy
10 qkqafqlkhpehfhuqxyvg
11 eztrbonqwnqtqsadmlgx
12 ivvriptscgynlspuztck
13 elzaubshhezywxceytmc
14 quflzoeqjuclbuvndeos
15 xvuirculozaoknzblxyk
16 wgsiohaskhbjuzoroatq
17 mvvxorhwgzimzhvtfwxf
18 lfmphjrukrhwtoaqcffr
19 mcogdlegsjmjfcibzkcj
-
Btw all suggestions suffer from the fact that a clever coder can do an EnumWindows and find window names that contain non-Ascii characters. Even the one below is not safe in this respect: find a window whose name starts with "x", or any window containing multiple numbers, etc.
In pure Masm32 code:
include \masm32\include\masm32rt.inc
.686p
.data?
Rand$Buffer db 21 dup(?)
.code
Rand$ MACRO ; simple macro to generate random names
rdtsc
invoke lstrcpy, offset Rand$Buffer, str$(eax)
mov byte ptr Rand$Buffer, "x"
exitm <offset Rand$Buffer>
ENDM
start:
xor ebx, ebx
.Repeat
print str$(ebx), 9
print Rand$(), 13, 10
invoke Sleep, 100
inc ebx
.Until ebx>=20
MsgBox 0, "ok?", "Hi", MB_OK
exit
end start
Output:
0 x034471557
1 x2009285427
2 x1754927414
3 x1501939927
4 x1245299944
5 x988643757
6 x731742907
7 x474656169
8 x218009469
9 x9105431
10 x96267723
11 x53192993
12 x10338773
13 x067610048
14 x324033156
15 x583438831
16 x840354643
17 x096978243
18 x1936173115
19 x1679015015
If I seriously wanted to hide my application, I would enum all active windows and randomly use one of the existing names.
-
While discussing the algo type with a couple of the PB members, produced another version that produced variable length strings with numbers, upper and lower case characters excluded. I don't think it matters much, a simple one makes the window harder to find and reduced the possibility of tracking down private message strings. Note that the PB "RND" function is only a general purpose function and not suitable for encryption purposes.
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
FUNCTION randstr() as STRING
#REGISTER NONE
LOCAL var as DWORD
LOCAL ccnt as DWORD
LOCAL rnm as DWORD
! db &H0F,&H31
! db &H0F,&HC8
! mov var, eax
randomize var ' seed the PB rnd function
src$ = "" ' allocate an empty basic string
ccnt = rnd(11,71) ' make output variable length
! mov esi, ccnt
lbl:
rnm = rnd(1,255)
If rnm > 47 and rnm < 58 Then ' no numbers
! jmp lbl
End If
If rnm > 64 and rnm < 91 Then ' no upper case
! jmp lbl
End If
If rnm > 96 and rnm < 123 Then ' no lower case
! jmp lbl
End If
src$ = src$ + chr$(rnm)
! sub esi, 1
! jnz lbl
FUNCTION = src$
End FUNCTION
' ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
-
I have used the GetSystemTime function to generate adresses .It's a good soluce but the function
couldn't be recall without problem's ,see microsoft.
To solve this,I have made a compound of two chains, one is given by GetSystemTime
and the oher by increment of the AAA chain.
new adress = getsystemTime chain + AA?
-
GetSystemTime has a reasonable resolution, but rdtsc is even better:
include \masm32\include\masm32rt.inc
.686p
.data?
db ?
Rand$Buffer db 30 dup(?)
.code
Rand$ MACRO ; simple macro to generate random names
rdtsc
invoke lstrcpy, offset Rand$Buffer-1, str$(eax)
rdtsc
invoke lstrcpy, offset Rand$Buffer+8, hex$(eax)
or dword ptr Rand$Buffer, 420042h
and dword ptr Rand$Buffer, 0FFEFFFEFh
or dword ptr Rand$Buffer+4, 420042h
and dword ptr Rand$Buffer+4, 0FFEFFFEFh
exitm <offset Rand$Buffer>
ENDM
start:
.repeat
xor ebx, ebx
.Repeat
print str$(ebx), 9
print Rand$(), 13, 10
invoke Sleep, 40
inc ebx
.Until ebx>=20
inkey "press Ctrl C to exit"
.until 0
exit
end start
Output:
0 k5f7f0f5FA4F3148
1 b4f0g6B5004D0B01
2 b9g9g1g106885595
3 c4g7b8j90CCD2F61
4 c8c6b2g512F9DD0E
5 b0g4b3f419140F5B
6 b3j5j3c91F397BCB
7 b6c7g1j92555C449
8 c1c0c9c92B93CD29
9 c5k0c8f431D2EBDE
10 f0f5g6g6380E41C7
11 b4b9c9c03E2A07FF
12 c4g6f9j34467C7D3
13 b4k9k1f74A8165A7
14 c5b2c7g850993F0A
15 f5f6f6f856D2B51D
16 g5k3c9j85CF16098
17 f6g7b1b56348A3FB
18 g6j2j0f96965DDAF
19 j7b7k0f26F820893
The problem remains that a clever coder can do the enum and search for the pattern, in this case: "starts with a lowercase character, followed by a number". Non-Ascii characters are even easier to spot.
-
Hi Jochen,
Here is another version creating strings with mixed case :
include RandStr.inc
BUFF_SIZE equ 64
.data?
buffer db BUFF_SIZE dup(?)
.code
start:
invoke RandStr,ADDR buffer,BUFF_SIZE
invoke StdOut,ADDR buffer
invoke ExitProcess,0
RandStr PROC uses esi edi ebx string:DWORD,stringLen:DWORD
LOCAL _st:SYSTEMTIME
invoke GetSystemTime,ADDR _st
movzx ebx,SYSTEMTIME.wMilliseconds[_st]
@@:
invoke crt_rand
sub ebx,1
jnz @b
mov esi,string
mov edi,26
mov ebx,stringLen
@@:
invoke crt_rand
xor edx,edx
div edi
and eax,1
shl eax,5
lea edx,[edx+eax+65]
mov BYTE PTR [esi],dl
add esi,1
sub ebx,1
jnz @b
mov eax,string
ret
RandStr ENDP
END start
Output sample :
RandStr.exe
mGNkEuFdXOtOgbgXpEyaNFetCukePZSHKlJuGgGekjdqzJeNpevQgxiEpjSrDZjA
RandStr.exe
MwzoBiWybxDUUnFSkSrsrtEKmqDCyZjEeUHMsrQCOZijIPfioNeedDpSZrNAvYmm
RandStr.exe
yLfPBNPljVRVipYamyehwQnqrqPMxUjjlOOvAOwUxwHMsNCBXCOksfzkVATXdKNl
RandStr.exe
wKbJzwucWljfrimPMYHchzRIWKBarxBgFcBceyhjUgIXWTBvTrEhbBcPXIfBxvFB
RandStr.exe
tlyhNkOaUGzqRCDDIUTeiojwayyzpVScMpSajlfVgUBfAAOvlZYlNTrKdCpwSRtE
-
JJ,
If you use BSWAP EAX directly after RDTSC you get a much faster and wider change to the output number.
-
@Erol: works fine :thumbsup:
@Hutch: as an attacker, you would concentrate on byte #4 then
-
Byte 4 will not give you the other 3 and this is where the difficulty lies for the attacker. If you were worried about it you multi-sample then do whatever you want to make it more complex. It 64 but you simply take 2 samples and write the to the low and high DWORD respectively.
-
Very nice, Nidud :thumbsup:
However, I'd prefer a runtime name generator, for obvious reasons ;-)
-
Here is another version with the cryptographic functions :
include \masm32\include\masm32rt.inc
include \masm32\include\advapi32.inc
includelib \masm32\lib\advapi32.lib
RandomBytes PROTO :DWORD,:DWORD
.data
.data?
buffer db 64 dup(?)
.code
start:
call main
invoke StdOut,ADDR buffer
invoke ExitProcess,0
main PROC uses esi edi ebx
invoke RandomBytes,64,ADDR buffer
mov esi,OFFSET buffer
mov edi,26
mov ebx,64
@@:
movzx eax,BYTE PTR [esi]
xor edx,edx
div edi
and eax,1
shl eax,5
lea edx,[edx+eax+65]
mov BYTE PTR [esi],dl
add esi,1
sub ebx,1
jnz @b
ret
main ENDP
RandomBytes PROC dwLength:DWORD,pBuffer:DWORD
LOCAL hProvider:HANDLE
invoke CryptAcquireContext,ADDR hProvider,0,0,\
PROV_RSA_FULL,CRYPT_VERIFYCONTEXT or CRYPT_SILENT
invoke CryptGenRandom,hProvider,dwLength,pBuffer
invoke CryptReleaseContext,hProvider,0
ret
RandomBytes ENDP
END start
-
Hi,
in my macro, I need to get random values, which will always be different within the macro run. There is a similar example, but the code does not want to be assembled in UASM, where can there be an error? Thanks!
;qmMDFcgHjiU2y96o@vs93fuiJodNZso4FJRyrHUZmfSZs4TxxKz7Ce4cc1@u4mix
;TeDDsTXjffOecOT4jH5NuPnufXgt@J8TA18jX1xLZptpuSgVyre48IXBxFwECW9V
;Q2Fq57gbwFV9?StZIB?QQtWGZBZyM1pZ_@q9K0Ey_T?xWwLDITLXcOpxa72iZEdz
;piPeuTB?eehJDWf3md_4QKz_xXXa_9_SqbfU7EX_50Dg0@6Jzkf@1Fe2Xe93cQF2
;KZIxs_UkQVuhWwbekgzxTEpwGXz8jbs1tYccZamaNPO2bLZsak7QtubswbYVnJau
;Hp?4uWdXf5NV1GSYs0ZbdOBDu4X9qT5M_y3DCb3ZoXEMvcoJTn?K9XAgzxXssEwN
;8iyQi8E1C3Dj_SM@FJg?t@Z9oEPnLIy1XLau0qG1NEi61ztAWQ2mgU6atY_cI_zf
;Yr4MEGWNNyFMiBsTIN5Mm_@RTs9LGnHkwppVacyC5O4ahwaX?skB2sEFMjJA1H2B
;fGxqaR@mmxsADxc8C7oz?CshpyqQbr2RtWc@Xe8v418JvCn5rnOOTyOq3g2A2bzW
;qhrY?hy066pGsN9yy2jp7Ugh6rTPYTGaH45qvqV_ZK1VwP2OAyv3RRpZ1c5QzJtN
;AM0dHg3EVX_zsA6GMlfW1rOcRK15YqzHty1vPrgdkpfbLp2vj6dJ5z4FYt@IjrqH
;fzW3ouXCudgvj3r015C7ygxvSGFVhT4p2T4CsaZDAReBlxX1XG12X?Oy9sNj8@pa
;KVbCXwEaM?5nCpwMtX9sSaqyx3VCI6epa2yct4rKBxsW3T1gJzPRTv@_JYqW04n0
;cYQ3lSEvJj97NQtpBzfnlKNY4N5Xh5rw3pp_GWoTawKNYT_wFd_ag7UT66lXsOCM
;RG9JpXoBu7LzB_As5GxeLorO9zbdUiI8CWdK3IQYpt3Bk7dEas1HvMtfQf6yymSr
;?9VmqRADSiGDlMgq8vrObibbcmR@T5ToWTPvZZljc3gV7cd@Bp_rTkvAZZDC9u7W
PCG32_STATE = 0x853c49e6748fea9b ;+ @SubStr(%@Time,7,2)
__randa macro
local r, t, x
PCG32_STATE = PCG32_STATE * 6364136223846793005 + 0xda3e39cb94b95bdb
t = PCG32_STATE
r = ( ( ( t sar 18 ) xor t ) sar 27 )
x = t shr 59
t = r shr x
r = r shl ( -x and 31 )
r = r or t
r = r and 0x7F
exitm<r>
endm
__randc macro
local a
a = __randa()
while a gt 'z' or \
a lt '0' or \
a ge ':' and a le '>' or \
a ge '[' and a le '`' and a ne '_'
a = __randa()
endm
exitm<a>
endm
__rands macro n
local string
.data
string label byte
repeat n
db __randc()
endm
db 0
.code
exitm<string>
endm
.code
main proc
repeat 16
printf("%s\n", &__rands(64))
endm
ret
main endp
end main
-
Hi LiaoMi
My best guess is that UASM currently only supports 32-bit arithmetic for macro calculations.
In your case you are doing 64-bit calculations. The error messages are misleading...
Biterider
-
Hi LiaoMi!!
Are you sure that "sar" is valid directive for preprocessor?
It's not for ML64.
HSE
-
Hi
HSE is right. :cool:
The following code works for me.
I added a seed value (initial state), so that on each run it generates a different value.
PCG32_STATE = @CatStr(@SubStr(%@Time, 1, 2), @SubStr(%@Time, 4, 2), @SubStr(%@Time, 7, 2))
__randa macro
local r, t, x
PCG32_STATE = PCG32_STATE * 6364136223846793005 + 0xda3e39cb94b95bdb
t = PCG32_STATE
r = ( ( ( t shr 18 ) xor t ) shr 27 )
; r = ( ( ( t sar 18 ) xor t ) sar 27 )
x = t shr 59
t = r shr x
r = r shl ( -x and 31 )
r = r or t
r = r and 0x7F
exitm <r>
endm
__randc macro
local a
a = __randa()
while a gt 'z' or \
a lt '0' or \
a ge ':' and a le '>' or \
a ge '[' and a le '`' and a ne '_'
a = __randa()
endm
exitm <a>
endm
__rands macro n
local string
.data
string label byte
repeat n
db __randc()
endm
db 0
.code
exitm <string>
endm
Note: it appears that the calculations are performed using 64 bits, but that is not the case. The values are truncated internally to 32 bits!
Biterider
-
Hi Biterider,
Hi HSE,
thanks, it works :thup:
Hi LiaoMi
Note: it appears that the calculations are performed using 64 bits, but that is not the case. The values are truncated internally to 32 bits!
Biterider
Is this also the case in the 64 bit version of Masm?