News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Fix it up a bit

Started by Magnum, November 21, 2012, 03:05:29 AM

Previous topic - Next topic

Magnum

This used to work fine. After running it leaves a CLOSE THIS WINDOW window open.

It sometimes ends the program ok, but still leave that open window.

Andy



; kill_FEP.asm       Tuesday, August 04, 2009
; Help from Tedd,sinsi,Nordwind64,AsmGuru62,Jongware,
;
; Terminates bartshel.exe!!
; (A badly behaved program no longer needed after connection.)
.586
.model flat,stdcall
option casemap:none

include  \masm32\include\windows.inc
include  \masm32\include\user32.inc
include  \masm32\include\OLD_kernel32.inc
include  \masm32\include\shlwapi.inc
include  \masm32\macros\macros.asm
include  \masm32\include\advapi32.inc
include  \masm32\include\process.inc
includelib  \masm32\lib\advapi32.lib
includelib  \masm32\lib\user32.lib
includelib  \masm32\lib\OLD_kernel32.lib
includelib  \masm32\lib\shlwapi.lib

; Local Prototypes

    IsWinNT         PROTO
    ReqNTPrivilege  PROTO :DWORD
   
.const

    dwMaskNT        DWORD   2

WinMain proto :DWORD,:DWORD,:DWORD,:DWORD

.data

   msg_NotNT   BYTE    "This is NOT an NT system.",0
   msg_NotPL   BYTE    "Privilege requested NOT granted.",0
   BoxName     BYTE    "ASM Win NT Shutdown",0
   
   ClassName    BYTE    "MainWinClass",0
   AppName      BYTE    "CLOSE THIS WINDOW!",0
   ProcessName  BYTE    "MsMpEng.exe",0
   successtext  BYTE    "Program has been terminated!                                                                                          ",0
   failedtext   BYTE    "Program is not currently running!",0
   started      BYTE    "Bye_Bye",0

.data?

   hInstance   HINSTANCE ?
   CommandLine LPSTR     ?

.code

start:

    invoke GetModuleHandle, NULL
    mov    hInstance,eax
   
    invoke GetCommandLine
    mov    CommandLine,eax
   
    invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT

    ; with ReqNTPrivilege call, we ask for the 'SeShutdownPrivilege'
    ; note string names of possible privilege are in windows.inc

    invoke  ReqNTPrivilege, SADD("SeShutdownPrivilege")
    .if eax == FALSE
      invoke  MessageBox,NULL,addr msg_NotPL,addr BoxName,MB_OK
      invoke  ExitProcess,NULL
    .endif

    invoke ExitProcess,eax
   
KillProcess proc lpszExecutable:LPSTR
    LOCAL bLoop:BOOL
    LOCAL bResult:BOOL
    LOCAL pe32:PROCESSENTRY32
    LOCAL hProcess:HANDLE
    LOCAL hProcesses:HANDLE

    mov bLoop,TRUE
    mov bResult,FALSE

    ; Returns an open handle to the specified snapshot if successful or - 1 otherwise.
    invoke CreateToolhelp32Snapshot,TH32CS_SNAPPROCESS,0
    mov hProcesses,eax   

    mov pe32.dwSize,SIZEOF PROCESSENTRY32

    invoke Process32First,hProcesses,ADDR pe32
    .IF eax
        .WHILE bLoop
            invoke CompareString, LOCALE_USER_DEFAULT, NORM_IGNORECASE, addr pe32.szExeFile, -1, lpszExecutable, -1
            .IF eax==2 ; check if strings are equal in lexical value
                 
                invoke OpenProcess, PROCESS_TERMINATE, FALSE, pe32.th32ProcessID ; returns handle

                 .IF eax!=NULL
                    mov hProcess, eax        ; Need to save the process handle to terminate
                    invoke TerminateProcess, hProcess, 0
                    invoke CloseHandle, hProcess ; fails if eax is zero
                   
                    mov bResult,TRUE;
                   
                .endif
            .endif
           ; why go on to next process ?
           invoke Process32Next, hProcesses, ADDR pe32
            ; Retrieves information about the next process recorded in a system snapshot.

            mov bLoop,eax
        .endw
        invoke CloseHandle,hProcesses
    .endif
    mov eax,bResult
    ret

KillProcess endp

WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD
    LOCAL wc:WNDCLASSEX
    LOCAL msg:MSG
    LOCAL hwnd:HWND
    LOCAL tc   :DWORD
   
    mov   wc.cbSize,SIZEOF WNDCLASSEX
    mov   wc.style, CS_HREDRAW or CS_VREDRAW
    mov   wc.lpfnWndProc, OFFSET WndProc
    mov   wc.cbClsExtra,NULL
    mov   wc.cbWndExtra,NULL
    push  hInstance
    pop   wc.hInstance
    mov   wc.hbrBackground,COLOR_BTNFACE+1
    mov   wc.lpszMenuName,NULL
    mov   wc.lpszClassName,OFFSET ClassName
   
    invoke LoadIcon,NULL,IDI_APPLICATION
    mov   wc.hIcon,eax
    mov   wc.hIconSm,eax
   
    invoke LoadCursor,NULL,IDC_ARROW
    mov   wc.hCursor,eax
   
   
    invoke RegisterClassEx, addr wc

    ; If I want a window off screen
    ;
    ; Replacing CW_USEDEFAULT with NULL creates a "hidden" window

    INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,NULL,\ ; creates a "hidden" window
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
           hInst,NULL
    mov   hwnd,eax

    invoke ShowWindow, hwnd,SW_MINIMIZE    ;Minimal window
    invoke UpdateWindow, hwnd

     add tc,1    ; get rid of window quickly
                 ; 2000 =  2 seconds

   
    ; loop until Tick count catches up with added time
   
    @@:
      invoke GetTickCount
        .if tc > eax
          jmp @B
        .endif
   
    ; Close screen
   
      invoke SendMessage,hwnd,WM_SYSCOMMAND,SC_CLOSE,NULL
   
    ; Loop until PostQuitMessage is sent

    StartLoop:
      invoke GetMessage,ADDR msg,NULL,0,0
      cmp eax, 0
      je ExitLoop
      invoke TranslateMessage, ADDR msg
      invoke DispatchMessage,  ADDR msg
      jmp StartLoop
    ExitLoop:
   
    mov     eax,msg.wParam
    ret
WinMain endp

WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
   
    LOCAL bResult:BOOL
    LOCAL bLoop:BOOL

    .IF uMsg==WM_DESTROY
        invoke PostQuitMessage,NULL

    .ELSEIF uMsg==WM_CREATE
        mov eax, -1        ;FALSE
       
        mov bResult,eax
        invoke KillProcess,OFFSET ProcessName

        mov bResult,eax ;

        .IF bResult==FALSE
            invoke MessageBox,0,OFFSET failedtext,OFFSET started,MB_OK
        .ELSE
            invoke MessageBox,0,OFFSET successtext,OFFSET started,MB_OK
        .ENDIF

         mov bLoop,FALSE
                 
        ret
   
    .ELSE
        invoke DefWindowProc,hWnd,uMsg,wParam,lParam       
        ret
    .ENDIF
   
    xor eax,eax
    ret
WndProc endp

ReqNTPrivilege proc lpPrivilegeName:DWORD

; return TRUE (not zero) in eax if privilege is granted
; lpPrivilegeName parameter points to a string with request privilege name

    LOCAL   hProcess:DWORD
    LOCAL   hToken:DWORD
    LOCAL   phToken:DWORD
    LOCAL   RetLen:DWORD
    LOCAL   pRetLen:DWORD
    LOCAL   tkp:TOKEN_PRIVILEGES
    LOCAL   tkp_old:TOKEN_PRIVILEGES
;
    invoke  GetCurrentProcess
    mov     hProcess, eax
    lea     eax, hToken
    mov     phToken, eax
    invoke  OpenProcessToken, hProcess, \
            TOKEN_ADJUST_PRIVILEGES Or TOKEN_QUERY, \
            phToken
    .if eax != FALSE
      lea     eax, tkp.Privileges[0].Luid
      invoke  LookupPrivilegeValue, NULL, \
              lpPrivilegeName, \
              eax
      lea     eax, RetLen
      mov     pRetLen, eax
      mov     tkp.PrivilegeCount, 1
      mov     tkp.Privileges[0].Attributes, SE_PRIVILEGE_ENABLED
      invoke  AdjustTokenPrivileges, hToken, \
              NULL, \
              addr tkp, \
              sizeof tkp_old, \
              addr tkp_old, \
              pRetLen
    .endif
    ret
   
ReqNTPrivilege endp

end start

Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

the WM_DESTROY message is handled by posting with PostQuitMessage, which tells the message loop to terminate the program
you did that correctly

before that happens, the WM_CLOSE message is used to actually destroy the window
we also use it to perform cleanup, like deleting GDI objects, freeing memory, or closing handles, etc
according to the documentation, the DefWindowProc function handles it by destroying the window
but, i always put a handler in there and call DestroyWindow

    .ELSEIF uMsg==WM_CLOSE
        INVOKE  DestroyWindow,hWnd


another possibility is the IF/ELSEIF/ELSE structure
the way you have it written, and i have seen this before, WndProc always returns 0
the way i do it is to allow the return value from DefWindowProc be the return value for WndProc
i do this by setting the return value individually for each message handled...

    .IF uMsg==WM_DESTROY
        INVOKE  PostQuitMessage,NULL
        xor     eax,eax                               ;return 0

    .ELSEIF uMsg==WM_CLOSE
        INVOKE  DestroyWindow,hWnd
        xor     eax,eax                               ;return 0

    .ELSEIF uMsg==WM_CREATE

        ;create code goes here

        xor     eax,eax                               ;return 0

    .ELSE
        INVOKE  DefWindowProc,hWnd,uMsg,wParam,lParam

    .ENDIF
    ret


one more thing....
in the windows.inc file, FALSE is defined as 0 and TRUE is defined as 1   :biggrin:
in days of old (other languages), we used to define TRUE as -1

dedndave

another method i have seen is to use a seperate RET for the DefWindowProc
    .IF uMsg==WM_DESTROY
        INVOKE  PostQuitMessage,NULL

    .ELSE
        INVOKE  DefWindowProc,hWnd,uMsg,wParam,lParam
        ret                                           ;return EAX from DefWindowProc

    .ENDIF
    xor     eax,eax                                   ;return 0
    ret


that works, but the assembler may generate a considerable amount of epilogue code for each RET
i have also seen something like this to get around it...

    .IF uMsg==WM_DESTROY
        INVOKE  PostQuitMessage,NULL

    .ELSE
        INVOKE  DefWindowProc,hWnd,uMsg,wParam,lParam
        jmp     DefExit                               ;return EAX from DefWindowProc

    .ENDIF
    xor     eax,eax                                   ;return 0

DefExit:
    ret


both of these methods work, but i prefer the method in my earlier post
for some messages, you may want to return a non-zero value

Magnum

I am wondering why what used to be good working code, now isn't.

I forgot how to add a reg entry to add olly to my menu pick for opening .exes.

I did an internet search, but found little that helped.

ANdy
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

HKEY_LOCAL_MACHINE\SOFTWARE\MICROSOFT\WINDOWS NT\CURRENTVERSION\AEDEBUG

i think Olly will change the setting for you in the Options menu

Magnum

Dave,

The API says this. I don't think non-zero necessarily implies a 1.

f the function succeeds, the return value is nonzero.
If the function fails, the return value is zero.

one more thing....
in the windows.inc file, FALSE is defined as 0 and TRUE is defined as 1   :biggrin:
in days of old (other languages), we used to define TRUE as -1
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

dedndave

i understand what you mean
and - non-zero is not always the same as TRUE (quite often, a 1 is returned, though)

but - i was refering to this piece of code...

    .ELSEIF uMsg==WM_CREATE
        mov eax, -1        ;FALSE

        mov bResult,eax
        invoke KillProcess,OFFSET ProcessName

        mov bResult,eax ;

        .IF bResult==FALSE
            invoke MessageBox,0,OFFSET failedtext,OFFSET started,MB_OK
        .ELSE
            invoke MessageBox,0,OFFSET successtext,OFFSET started,MB_OK
        .ENDIF

         mov bLoop,FALSE

        ret

Magnum

Here is a pic of the mystery window that shows up.

I did find out that if I try to shutdown notepad and wordpad, it works fine with the exception of that "mystery" window.

I would like to find out what is causing it.

http://i1127.photobucket.com/albums/l637/bicycle77017/close_Window.png

Andy
Take care,
                   Andy

Ubuntu-mate-18.04-desktop-amd64

http://www.goodnewsnetwork.org

hfheatherfox07

Quote from: Magnum on November 22, 2012, 03:39:21 PM
Here is a pic of the mystery window that shows up.

I did find out that if I try to shutdown notepad and wordpad, it works fine with the exception of that "mystery" window.

I would like to find out what is causing it.

http://i1127.photobucket.com/albums/l637/bicycle77017/close_Window.png

Andy

I had the same results .....
For starters you are creating that window !
than you are showing t here :

invoke ShowWindow, hwnd,SW_MINIMIZE    ;Minimal window
Also not closing it right....

I think this prog has a few other bugs .... hit Ctrl Alt Delete and see if it exits OK

Here are some changes that I made  ...
Your code and your skills will be assimilated. Your programming language is irrelevant.
We are the ASM Borg and you will become part of us. Compile and be assembled.

sinsi


                   invoke TerminateProcess, hProcess, 0
                    invoke CloseHandle, hProcess ; fails if eax is zero
                   
                    mov bResult,TRUE;

bResult is always TRUE, is this right?

Also, if you are trying to kill MsMpEng note that it will protect itself, even Process Explorer gets an access denied error.

dedndave

i don't get that window, Andy
maybe you could use WinSpy++ to get some info on it

i use ver 8...
http://mdb-blog.blogspot.com/2010/11/microsoft-spy-or-spyxx-for-download.html