This works but I don't know how to eliminate that last window that
pops open without getting that endless loop that I had previously.
This version no longer stays in memory. :-)

Thanks.


; killit1.asm
;
; Kills notepad.exe
;
.586
.model flat,stdcall
option casemap:none

include  \masm32\include\windows.inc
include  \masm32\include\user32.inc
include  \masm32\include\kernel32.inc
include  \masm32\include\shlwapi.inc
include  \masm32\macros\macros.asm
include  \masm32\include\advapi32.inc

includelib  \masm32\lib\advapi32.lib
includelib  \masm32\lib\user32.lib
includelib  \masm32\lib\kernel32.lib
includelib  \masm32\lib\shlwapi.lib

STOP    equ NOP  ; marker

; Local Prototypes

    IsWinNT         PROTO
    ReqNTPrivilege  PROTO :DWORD

.const

    dwMaskNT        DWORD   2

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

.data

    BoofText          db "Something wrong !!",0
    MsgCaption        db "OOPS",0

    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
    Watermark   db      "Andrew Kennedy 5/10/07",0

   ClassName    db "MainWinClass",0
   AppName      db "Main Window",0
   ProcessName  db "notepad.exe",0
   started      db "KillIt",0
   startedtext  db "KillIt has started!",0
   quittext     db "KillIt is suceeding!",0
   successtext  db "KillIt has succeeded in killing notepad.exe!",0
   failedtext   db "KillIt has failed!",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    ;  Did not need 2 copies of your snap shot

    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

                      ;  With having addr pe32.th32ProcessID you were
getting an invalid PID
                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
                    STOP ; 1st ; confirmed tht process IS sucessfully
terminated
                    mov bResult,TRUE;
                    STOP ; 2nd
                .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

    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

    INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\
           hInst,NULL
    mov   hwnd,eax

    invoke ShowWindow, hwnd,SW_SHOWNORMAL
    invoke UpdateWindow, hwnd

    .WHILE TRUE
        invoke GetMessage, ADDR msg,NULL,0,0
        .BREAK .IF (!eax)
        invoke TranslateMessage, ADDR msg
        invoke DispatchMessage, ADDR msg
    .ENDW

    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
        STOP
        mov bResult,eax
        invoke MessageBox,0,OFFSET startedtext,OFFSET started,MB_OK
        invoke KillProcess,OFFSET ProcessName

        mov bResult,eax ; don't see why we need two of these
        STOP

        .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
         ; .WHILE !bLoop
;             invoke GetAsyncKeyState,VK_ESCAPE ; determines whether
key is up or down
;            ; .IF  eax < 0
;             ; .IF SDWORD PTR eax < 0 ; this doesn't work
;              test eax,8000000h       ; or this
;              .IF !ZERO?              ; "
;                 invoke MessageBox,0,OFFSET quittext,OFFSET
started,MB_OK
;                 invoke SendMessage,hWnd,WM_DESTROY,0,0
;                 mov bLoop,TRUE
;             .ENDIF
        ; .WHILE !bLoop ; WHY is this checking for a key press ?
        ;     invoke GetAsyncKeyState,VK_ESCAPE
        ;      .IF ax != 0
        ;        invoke MessageBox,0,OFFSET quittext,OFFSET
started,MB_OK
        ;        invoke SendMessage,hWnd,WM_SYSCOMMAND,SC_CLOSE,NULL ;
closes window ?
        ;        mov bLoop,TRUE
        ;    .ENDIF

        ;.ENDW
        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


Posted on 2007-05-14 04:59:51 by skywalker