Author Topic: Miscellaneous snippets  (Read 88995 times)

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
Miscellaneous snippets
« on: August 20, 2017, 08:02:31 AM »
include \masm32\MasmBasic\MasmBasic.inc         ; download
  Init
  Dim MyInts() As DWORD
  For_ ct=0 To 999
        mov MyInts(ct), Rand(100)       ; 0...99
  Next
  Open "O", #0, "even.txt"
  Open "O", #1, "odd.txt"
  For_ ct=0 To MyInts(?)-1
        test MyInts(ct), 1
        setne al
        movsx ecx, al
        Print #ecx, Str$("%__i ", MyInts(ct))
  Next
  Close
  PrintLine     "even.txt: ", FileRead$("even.txt"), CrLf$
  Inkey         "odd.txt:  ", FileRead$("odd.txt")
EndOfCode


Output (shortened):
Code: [Select]
even.txt:  86  82  22  78   2  56  36  14  58  46  68  16  84  12  94  42   0  16  90  42   8  94  90  52  92  90  42  60  88  86  10  64  3
8  92  16  24  92  10  46  34  28  66  74  92  88  82  40  44  26  84  94  48  32   8   0  44  68  40  50   0   2  12  38  12  82  80   0  7
2  76   0  74   8   0  76  64   8  28  46  10  48   6  94  90  10  84  68  62   2  82  96   0  98  20  36  12  96  14  98   8  96

odd.txt:   45   7  13  65  51  57  67  25  97  63  23  77  87  95  39  57  33  87  55  99   5  47  69  79  87  67  19  95  83  49  21  85  4
9  53   7  39  25  31  49  83  17  65  29  27  99  61  19  67  67  77  49  61  73  79  29  47  31  95  49  45  55  81  71  29   7  79  65  2
3  89  93  19  81  17  19  87  83  63  93  25  75  51  79  75  99   7  55  17  19  57  45  33  83  81  87  51  75  81  79  55  93

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
A suicide proggie
« Reply #1 on: November 10, 2017, 09:39:13 PM »
Ever tried to kill the current executable? It's not that straightforward, for security reasons, but it can be done with little helpers:
Code: [Select]
include \masm32\include\masm32rt.inc ; pure Masm32

.data?
ThisExe db MAX_PATH dup(?)

.code
start:
  mov edi, offset ThisExe
  invoke lstrcpy, edi, chr$("KillMe.exe ")
  invoke lstrcat, edi, rv(GetCommandLine)  ; this returns the path of the current exe
  invoke WinExec, edi, SW_MINIMIZE
  add edi, 11 ; advance to compensate for <KillMe.exe >
  print "check your disk to see if "
  print edi
  print " was killed"
  exit

end start

Source and binaries attached, must sit in the same folder as the current exe.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
Re: Miscellaneous snippets
« Reply #2 on: November 12, 2017, 09:14:40 PM »
Playing with inline assembly in FreeBasic, source attached; see discussion. Watch out for the red calls below...

Code: [Select]
Function LeapYearJ(ByVal yea As ULong) As ULong
Asm
  mov ecx, dword ptr [yea]
  test ecx, 3
  setz al
  jne 0f
  mov eax, ecx
  cdq
  push 100
  idiv dword ptr [esp] ' 0, 4, 8, ..., 96, 0
  test edx, edx ' mod 100=0 should set zero flag
  jne 1f
  mov eax, ecx
  cdq
  push 400
  idiv dword ptr [esp]
  pop eax
  dec edx '*** invert the zero flag ***
  sets dl ' sign set if edx was zero
  test dl, dl
1:
  pop eax
  setnz al
0:
  movsx eax, al
  mov [function], eax ' MichaelW
End Asm
End Function
...
Code: [Select]
for i = 1 to years ' assembly function, inlined by compiler
asm int 3 ' forum
lyears=lyears+LeapYearJ(i)
asm nop
asm nop
asm nop
asm nop
next

00407C20        �> �CC                �int3
00407C21        �. �8B45 D0           �mov eax, [ebp-30]
00407C24        �. �8945 D8           �mov [ebp-28], eax
00407C27        �. �C745 DC 00000000  �mov dword ptr [ebp-24], 0
00407C2E        �. �C70424 24A04000   �mov dword ptr [esp], offset 0040A02 ; ASCII "C:\FreeBasic\tmp\TmpFile.bas"
00407C35        �. �E8 169EFFFF       �call 00401A50                       ; �TmpFile.00401A50
00407C3A        �. �56                �push esi                            ; �Arg1
00407C3B        �. �8945 C0           �mov [ebp-40], eax                   ; �
00407C3E        �. �C70424 80A04000   �mov dword ptr [esp], offset 0040A08 ; �ASCII "LEAPYEARJ"
00407C45        �. �E8 669EFFFF       �call 00401AB0                       ; �TmpFile.00401AB0
00407C4A        �. �57                �push edi
00407C4B        �. �8945 BC           �mov [ebp-44], eax
00407C4E        �. �8B4D D8           �mov ecx, [ebp-28]
00407C51        �. �F7C1 03000000     �test ecx, 00000003
00407C57        �. �0F94C0            �setz al
00407C5A        �.�75 22             �jnz short 00407C7E
00407C5C        �. �89C8              �mov eax, ecx
00407C5E        �. �99                �cdq
00407C5F        �. �6A 64             �push 64
00407C61        �. �F73C24            �idiv dword ptr [esp]
00407C64        �. �85D2              �test edx, edx
00407C66        �.�75 12             �jnz short 00407C7A
00407C68        �. �89C8              �mov eax, ecx
00407C6A        �. �99                �cdq
00407C6B        �. �68 90010000       �push 190
00407C70        �. �F73C24            �idiv dword ptr [esp]
00407C73        �. �58                �pop eax
00407C74        �. �4A                �dec edx
00407C75        �. �0F98C2            �sets dl
00407C78        �. �84D2              �test dl, dl
00407C7A        �> �58                �pop eax
00407C7B        �. �0F95C0            �setnz al
00407C7E        �> �0FBEC0            �movsx eax, al
00407C81        �. �8945 DC           �mov [ebp-24], eax
00407C84        �. �8B7D BC           �mov edi, [ebp-44]
00407C87        �. �893C24            �mov [esp], edi
00407C8A        �. �E8 219EFFFF       �call 00401AB0                       ; �TmpFile.00401AB0
00407C8F        �. �50                �push eax                            ; �Arg1
00407C90        �. �8B45 C0           �mov eax, [ebp-40]                   ; �
00407C93        �. �890424            �mov [esp], eax                      ; �
00407C96        �. �E8 B59DFFFF       �call 00401A50                       ; �TmpFile.00401A50
00407C9B        �. �50                �push eax                            ; �Arg1
00407C9C        �. �8B45 DC           �mov eax, [ebp-24]                   ; �
00407C9F        �. �0145 D4           �add [ebp-2C], eax                   ; �
00407CA2        �. �90                �nop                                 ; �
00407CA3        �. �90                �nop                                 ; �
00407CA4        �. �90                �nop                                 ; �
00407CA5        �. �90                �nop                                 ; �
00407CA6        �. �8B45 D0           �mov eax, [ebp-30]                   ; �
00407CA9        �. �40                �inc eax                             ; �
00407CAA        �. �8945 D0           �mov [ebp-30], eax                   ; �
00407CAD        �. �3D 80969800       �cmp eax, 989680                     ; �
00407CB2        �.�0F86 68FFFFFF     �jbe 00407C20                        ; �

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
List of files in a zip archive
« Reply #3 on: November 26, 2017, 10:55:33 PM »
Build it, then drag an archive over the exe:

include \masm32\MasmBasic\MasmBasic.inc         ; download
  Init
  UnzipInit CL$()
  .if !Sign?
        For_ ecx=0 To edx-1
                PrintLine Files$(ecx)
        Next

  .endif
  Inkey CrLf$, "Now copy the names from the console menu"
EndOfCode


Output e.g. from the COM interface archive:
Code: [Select]
GetComInterface.asc
GetComInterface.dll

aw27

  • Guest
Re: A suicide proggie
« Reply #4 on: November 27, 2017, 02:08:34 AM »
Ever tried to kill the current executable? It's not that straightforward, for security reasons, but it can be done with little helpers:
Code: [Select]
include \masm32\include\masm32rt.inc ; pure Masm32

.data?
ThisExe db MAX_PATH dup(?)

.code
start:
  mov edi, offset ThisExe
  invoke lstrcpy, edi, chr$("KillMe.exe ")
  invoke lstrcat, edi, rv(GetCommandLine)  ; this returns the path of the current exe
  invoke WinExec, edi, SW_MINIMIZE
  add edi, 11 ; advance to compensate for <KillMe.exe >
  print "check your disk to see if "
  print edi
  print " was killed"
  exit

end start

Source and binaries attached, must sit in the same folder as the current exe.

Come on, JJ  :badgrin: :badgrin:

Try this instead: http://masm32.com/board/index.php?topic=6713.0

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
Set wallpaper with IActiveDesktop::SetWallpaper
« Reply #5 on: December 13, 2017, 10:45:07 AM »
This should work but it doesn't :(

It builds fine and returns S_OK, no error, but it does not set the wallpaper. MSDN says it's supported for XP and earlier - seriously? But even on XP it has no effect.

include \masm32\MasmBasic\MasmBasic.inc
include IActiveDesktop.inc      ; IActiveDesktop STRUCT, CLSID_ActiveDesktop, IID_IActiveDesktop (attached)
.code
SetMyWallpaper proc pDesktopImg  ; adapted from johnsa's code
LOCAL pAD
  invoke CoCreateInstance, addr CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, addr IID_IActiveDesktop, addr pAD
  .if eax==S_OK
       CoInvoke pAD, IActiveDesktop.SetWallpaper, pDesktopImg, 0
       deb 4, "SetWp", $Err$()         ; OK, operation completed - but no effect
       CoInvoke pAD, IActiveDesktop.Release
  .endif
  ret
SetMyWallpaper endp
  Init
  If_ Not rv(CoInitializeEx, 0, COINIT_APARTMENTTHREADED) Then invoke SetMyWallpaper, wChr$("\Masm32\examples\exampl04\car\car.jpg")
  invoke CoUninitialize
EndOfCode

Vortex

  • Member
  • *****
  • Posts: 2788
Re: Miscellaneous snippets
« Reply #6 on: December 14, 2017, 05:41:02 AM »
Hi Jochen,

Can you try the attached sample?

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
Re: Miscellaneous snippets
« Reply #7 on: December 14, 2017, 06:56:10 AM »
Hi Erol,
Your example changed slightly the position of the existing wallpaper, but the old image remained...
To be continued ;-)

Vortex

  • Member
  • *****
  • Posts: 2788
Re: Miscellaneous snippets
« Reply #8 on: December 14, 2017, 07:07:05 AM »
Hi Jochen,

Not sure but maybe specifying the full path of the image can solve the problem.

Code: [Select]
WSTR        DesktopImg,"test.bmp"
.
.
coinvoke    pAD,IActiveDesktop,SetWallpaper,OFFSET DesktopImg,0

GetFullPathName can retrieve the full path.

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
Re: Miscellaneous snippets
« Reply #9 on: December 14, 2017, 08:09:15 AM »
Hi Erol,

Full path works, thanks a lot! Now I'll try my version 8)

P.S.: It works ;)

include \masm32\MasmBasic\MasmBasic.inc
include IActiveDesktop.inc      ; IActiveDesktop STRUCT, CLSID_ActiveDesktop, IID_IActiveDesktop
.code
SetMyWallpaper proc pDesktopImg         ; adapted from Vortex and johnsa's code
LOCAL pAD, wpo:WALLPAPEROPT
  ClearLocals
  .if !rv(CoCreateInstance, addr CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, addr IID_IActiveDesktop, addr pAD)
        add wpo.dwSize, WALLPAPEROPT
        add wpo.dwStyle, WPSTYLE_CENTER or WPSTYLE_STRETCH
        CoInvoke pAD, IActiveDesktop.SetWallpaper, wRec$(pDesktopImg), 0
        CoInvoke pAD, IActiveDesktop.SetWallpaperOptions, addr wpo, 0
        CoInvoke pAD, IActiveDesktop.ApplyChanges, AD_APPLY_ALL
        CoInvoke pAD, IActiveDesktop.Release
  .endif
  ret
SetMyWallpaper endp
  Init
  Let esi=wCL$()
  .if !rv(CoInitializeEx, 0, COINIT_APARTMENTTHREADED)
        wMsgBox 0, esi, "Set as wallpaper?", MB_OKCANCEL or MB_ICONQUESTION
        If_ eax==IDOK Then <invoke SetMyWallpaper, Qtrim$(Utf8$(esi))>
        invoke CoUninitialize
  .endif
EndOfCode


Full project attached, including a really nice wallpaper - a very special view of a European city. Extract all files to a folder, then drag the jpg over the exe :biggrin:
« Last Edit: December 14, 2017, 03:11:03 PM by jj2007 »

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
Delay until
« Reply #10 on: December 16, 2017, 02:51:15 PM »
I am testing a new syntax for Delay and would appreciate some results for other Windows versions:

include \masm32\MasmBasic\MasmBasic.inc         ; download
uselib ntdll
  SetGlobals resMin, resMax, resCurrent
  Init
  invoke NtQueryTimerResolution, addr resMin, addr resMax, addr resCurrent
  deb 4, "Timer resolution", resMin, resMax, resCurrent

  PrintLine CrLf$, "These lines should print about one second after the start, at ", fTime$(0, "HH:mm:??.123"), " millisecs"
  For_ ecx=0 To 4
        Delay Rand(500)         ; sleep 0..499 milliseconds
        NanoTimer()
        PrintLine fTime$(0, "HH:mm:ss.fff"), Tb$, "started"
        Delay until fTime$(s:1, "HH:mm:ss.123")         ; use time$(current plus one second)
        PrintLine fTime$(0, "HH:mm:ss.fff "), Tb$, NanoTimer$(), " passed", CrLf$
  Next
  Inkey Str$("This is Windows version %i", MbWinVersion()), Str$(".%i", ecx)
EndOfCode


Output:
Code: [Select]
Timer resolution
resMin          156001
resMax          5000
resCurrent      10000

These lines should print about one second after the start, at 04:47:??.123 millisecs
04:47:16.057    started
04:47:17.123    1066 ms passed

04:47:17.159    started
04:47:18.123    964 ms passed

04:47:18.191    started
04:47:19.123    932 ms passed

04:47:19.554    started
04:47:20.123    569 ms passed

04:47:20.450    started
04:47:21.123    673 ms passed

This is Windows version 6.1

The new version of the fTime$() macro can display milliseconds using the fff format specifier. See Microsoft: How to: Display Milliseconds in Date and Time Values for details.

felipe

  • Member
  • *****
  • Posts: 1381
Re: Miscellaneous snippets
« Reply #11 on: December 16, 2017, 02:54:37 PM »
Timer resolution
resMin          156250
resMax          5000
resCurrent      156255

These lines should print about one second after the start, at 23:52:??.123 milli
secs
23:52:37.774    started
23:52:38.123    348 ms passed

23:52:38.161    started
23:52:39.123    962 ms passed

23:52:39.193    started
23:52:40.124    930 ms passed

23:52:40.556    started
23:52:41.123    567 ms passed

23:52:41.451    started
23:52:42.123    672 ms passed

This is Windows version 6.3

From windows 8.1

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
Re: Miscellaneous snippets
« Reply #12 on: December 16, 2017, 07:36:52 PM »
Thanks, Felipe :t
Here are Win10 results:
Code: [Select]
Timer resolution
resMin          156250
resMax          5000
resCurrent      5007

These lines should print about one second after the start, at 09:35:??.123 millisecs
09:35:03.858    started
09:35:04.123    264 ms passed

09:35:04.159    started
09:35:05.123    964 ms passed

09:35:05.191    started
09:35:06.123    931 ms passed

09:35:06.554    started
09:35:07.123    568 ms passed

09:35:07.450    started
09:35:08.123    672 ms passed

This is Windows version 10.0

Note that even after a reboot, the current resolution is 0.5 milliseconds:
Code: [Select]
resMax          5000
resCurrent      5007

Your Windows 8.1 results are still at the 15.6 ms resolution. It seems they changed it definitely with Win10, which makes sense because a) the hardware got faster and b) even an ordinary browser like FF or PaleMoon sets it to 10000 when you visit YouTube.

So has GetTickCount finally become a high resolution timer?

NOPE. Have a look at these GetTickCount results:
Code: [Select]
ticks   systime
   0    10:02:51.678
   0    10:02:51.679
   0    10:02:51.681
   0    10:02:51.682
   0    10:02:51.683
   0    10:02:51.684
   0    10:02:51.686
  15    10:02:51.688
  15    10:02:51.689
  15    10:02:51.690
  15    10:02:51.691
  15    10:02:51.692
  15    10:02:51.693
  15    10:02:51.695
  15    10:02:51.696
  15    10:02:51.697
  15    10:02:51.698
  15    10:02:51.700
  15    10:02:51.701
  15    10:02:51.702
  31    10:02:51.703
  31    10:02:51.705
  31    10:02:51.706

Between each line, there is a Sleep(1), and the high resolution timer shows that the systemtime gets adjusted in one milliseconds increments; but GetTickCount keeps reporting with its low 15.625 ms granularity 8)

Vortex

  • Member
  • *****
  • Posts: 2788
Re: Miscellaneous snippets
« Reply #13 on: December 16, 2017, 09:11:50 PM »
Hi Jochen,

Here are my results, XP 64-bit :

Code: [Select]
Timer resolution
resMin          156250
resMax          10000
resCurrent      156250

These lines should print about one second after the start, at 13:11:??.123 milli
secs
13:11:17.531    started
13:11:18.125    591 ms passed

13:11:18.156    started
13:11:19.125    966 ms passed

13:11:19.187    started
13:11:20.125    935 ms passed

13:11:20.562    started
13:11:21.125    560 ms passed

13:11:21.453    started
13:11:22.109    669 ms passed

This is Windows version 5.2

jj2007

  • Moderator
  • Member
  • *****
  • Posts: 13937
  • Assembly is fun ;-)
    • MasmBasic
Re: Miscellaneous snippets
« Reply #14 on: December 16, 2017, 09:15:25 PM »
Thanks, Erol. So it starts always 2 ms later, 125 instead of 123... ::)

Similar for XP-32, a Virtual Machine:
Code: [Select]
Timer resolution
resMin          100144
resMax          10032
resCurrent      100144

These lines should print about one second after the start, at 11:16:??.123 milli
secs
11:16:29.859    started
11:16:30.129    254 ms passed

11:16:30.159    started
11:16:31.121    963 ms passed

11:16:31.191    started
11:16:32.122    931 ms passed

11:16:32.553    started
11:16:33.124    570 ms passed

11:16:33.454    started
11:16:34.125    669 ms passed

This is Windows version 5.1