好友
阅读权限40
听众
最后登录1970-1-1
|
本帖最后由 冥界3大法王 于 2026-5-19 09:53 编辑
[Asm] 纯文本查看 复制代码 #include <windows.h>
// 声明一个在外部(汇编文件里)实现的函数
extern "C" void HandleHotKey();
// WinMain 是 Windows 窗口程序的入口,这样启动时就绝对不会弹出黑色控制台
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
// 注册 Ctrl + Space 热键,ID 设为 1
if (!RegisterHotKey(NULL, 1, MOD_CONTROL, VK_SPACE)) {
return 1; // 如果注册失败(比如被其他软件占用了),程序直接退出
}
MSG msg = { 0 };
// 纯净的消息循环:平时完全静默,不占 CPU
while (GetMessage(&msg, NULL, 0, 0)) {
if (msg.message == WM_HOTKEY && msg.wParam == 1) {
HandleHotKey(); // 触发我们在汇编里写的按键映射逻辑
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
// 退出时注销热键
UnregisterHotKey(NULL, 1);
return 0;
}
[Asm] 纯文本查看 复制代码 .code
; --- 降维打击:VS非要找mainCRTStartup,那我们就顺着它,直接提供这个符号 ---
public mainCRTStartup
mainCRTStartup proc
jmp AsmMain
mainCRTStartup endp
; 声明所有需要用到的 Windows API
extern RegisterHotKey: proc
extern GetMessageA: proc
extern TranslateMessage: proc
extern DispatchMessageA: proc
extern SendInput: proc
extern ExitProcess: proc
AsmMain proc
push rbp
mov rbp, rsp
sub rsp, 40h ; 分配基础影子空间并对齐栈
; 1. 注册全局热键 Ctrl + Space (ID = 1)
xor rcx, rcx
mov edx, 1
mov r8d, 2 ; MOD_CONTROL (0x0002)
mov r9d, 20h ; VK_SPACE (0x0020)
call RegisterHotKey
test eax, eax
jz _Exit
_MessageLoop:
; 2. 消息循环
lea rcx, [rsp + 32] ; 利用栈空间存放 MSG 结构体
xor rdx, rdx
xor r8d, r8d
xor r9d, r9d
call GetMessageA
test eax, eax
jle _Exit
; 检查是否是热键消息 (msg.message == WM_HOTKEY [0x0312])
mov eax, dword ptr [rsp + 40]
cmp eax, 312h
jne _Translate
; 检查热键 ID 是否为 1
mov rax, qword ptr [rsp + 48]
cmp rax, 1
jne _Translate
; 触发热键映射逻辑
call TriggerWinSpace
_Translate:
lea rcx, [rsp + 32]
call TranslateMessage
lea rcx, [rsp + 32]
call DispatchMessageA
jmp _MessageLoop
_Exit:
xor ecx, ecx
call ExitProcess
AsmMain endp
; ---- 映射核心:释放 Ctrl 并发送 Win + Space ----
TriggerWinSpace proc
push rbp
mov rbp, rsp
; 分配 240 字节栈空间(5个 INPUT 结构体 * 40字节 + 32字节影子空间)
sub rsp, 0F0h
; ==== 0. 强行释放物理 Ctrl 键 (VK_CONTROL = 0x11),防止组合键冲突 ====
mov dword ptr [rsp + 32], 1 ; type = INPUT_KEYBOARD (1)
mov word ptr [rsp + 40], 11h ; wVk = VK_CONTROL
mov word ptr [rsp + 42], 0
mov dword ptr [rsp + 44], 2 ; dwFlags = KEYEVENTF_KEYUP (2)
mov dword ptr [rsp + 48], 0
mov qword ptr [rsp + 56], 0
; ==== 1. 模拟 Win 键按下 (VK_LWIN = 0x5B) ====
mov dword ptr [rsp + 72], 1
mov word ptr [rsp + 80], 5Bh
mov word ptr [rsp + 82], 0
mov dword ptr [rsp + 84], 0 ; dwFlags = 0 (按下)
mov dword ptr [rsp + 88], 0
mov qword ptr [rsp + 96], 0
; ==== 2. 模拟 Space 键按下 (VK_SPACE = 0x20) ====
mov dword ptr [rsp + 112], 1
mov word ptr [rsp + 120], 20h
mov word ptr [rsp + 122], 0
mov dword ptr [rsp + 124], 0 ; dwFlags = 0 (按下)
mov dword ptr [rsp + 128], 0
mov qword ptr [rsp + 136], 0
; ==== 3. 模拟 Space 键弹起 ====
mov dword ptr [rsp + 152], 1
mov word ptr [rsp + 160], 20h
mov word ptr [rsp + 162], 0
mov dword ptr [rsp + 164], 2 ; dwFlags = KEYEVENTF_KEYUP (2)
mov dword ptr [rsp + 168], 0
mov qword ptr [rsp + 176], 0
; ==== 4. 模拟 Win 键弹起 ====
mov dword ptr [rsp + 192], 1
mov word ptr [rsp + 200], 5Bh
mov word ptr [rsp + 202], 0
mov dword ptr [rsp + 204], 2 ; dwFlags = KEYEVENTF_KEYUP (2)
mov dword ptr [rsp + 208], 0
mov qword ptr [rsp + 216], 0
; ---- 调用 SendInput(5, &Inputs, sizeof(INPUT)) ----
mov ecx, 5 ; cInputs = 5
lea rdx, [rsp + 32] ; pInputs
mov r8d, 40 ; cbSize = 40
call SendInput
add rsp, 0F0h
pop rbp
ret
TriggerWinSpace endp
end
我试着让腾讯龙虾 和 谷哥AI,重新挑战了下,但发现编译之后的程序大小没有太大的变化了。而且按键不起作用了。 |
|