📜  取消关机计时器 - 汇编(1)

📅  最后修改于: 2023-12-03 15:07:25.768000             🧑  作者: Mango

取消关机计时器 - 汇编

在操作系统中,有时我们需要设定一个关机计时器,使计算机在一定时间后自动关机。但是有些情况下,我们又希望取消该计时器,让计算机保持开机状态。本文将介绍如何在汇编语言中实现取消关机计时器的功能。

实现原理

在微软的Windows操作系统中,取消关机计时器的实现原理是通过取消操作系统向API函数 InitiateSystemShutdownEx 发送的关机消息。具体地,我们需要通过关闭操作系统的关机 API 钩子来实现该目的。

实现步骤
  1. 加载用户32库函数 SetWindowsHookExA
  2. 设置回调函数 HookCallback
  3. 注册钩子 hHook
  4. 等待用户调用 CancelShutdown 函数
  5. 调用 UnhookWindowsHookEx 释放钩子
代码实现
.386
.model flat, stdcall
option casemap:none

include windows.inc
include kernel32.inc
include user32.inc

includelib kernel32.lib
includelib user32.lib

; 定义关键字
SHUTDOWN_REASON_MAJOR_OTHER equ 0x00000000
SHUTDOWN_REASON_MINOR_OTHER equ 0x00000000
SHTDN_REASON_LEGACY_API    equ 0x00000000
SHTDN_REASON_FLAG_PLANNED  equ 0x80000000

; 定义全局变量
.data
MsgBoxCaption db "Cancel Shutdown", 0
MsgBoxText    db "Shutdown canceled", 0

.CODE

; 定义回调函数
HookCallback proc nCode:DWORD, wParam:DWORD, lParam:DWORD
    ; 如果是关机消息
    cmp [lParam], SHTDN_REASON_FLAG_PLANNED
    jne  continue_hook
    ; 取消钩子
    call UnhookWindowsHookEx
    ; 关闭MessageBox
    push MB_OK
    push offset MsgBoxText
    push offset MsgBoxCaption
    push 0
    call MessageBoxA
    ; 取消关机
    call AbortSystemShutdown
    ; 退出程序
    push 0
    call ExitProcess
    
    ; 继续钩子
continue_hook:
    push dword[ebp+8]
    push dword[ebp+12]
    push dword[ebp+16]
    call CallNextHookEx
    add esp, 12
    ret 12
HookCallback endp

; 定义取消关机函数
CancelShutdown proc
    ; 创建一个计算机关机钩子
    push 0
    push 0
    push 0
    push GetCurrentThreadId
    call SetWindowsHookExA
    mov [hHook], eax
    ; 循环直到钩子被释放
    Loop:
        push 0, 0
        push offset MsgWaitForMultipleObjectsEx
        push [hHook]
        push 1
        push QS_ALLINPUT
        call MsgWaitForMultipleObjectsEx
        cmp eax, WAIT_OBJECT_0 + 1
        je Loop
    ret
CancelShutdown endp

; 定义程序入口函数
main proc
    ; 设定关机计时器
    push 0
    push SHUTDOWN_REASON_MAJOR_OTHER
    push SHUTDOWN_REASON_MINOR_OTHER
    push SHTDN_REASON_LEGACY_API or SHTDN_REASON_FLAG_PLANNED
    call InitiateSystemShutdownExA, 0, 0, 30, true, true
    ; 取消关机
    call CancelShutdown
    ret
main endp
end main
参考资料