Windows熱鍵註冊(反彙編方法 檢視win32api 原理)
BOOL RegisterHotKey(
HWND hWnd,
int id,
UINT fsModifiers,
UINT vk
);
函式功能:該函式定義一個系統範圍的熱鍵。
函式原型:BOOL RegisterHotKey(HWND hWnd,int id,UINT fsModifiers,UINT vk);
引數:
hWnd:接收熱鍵產生WM_HOTKEY訊息的視窗控制代碼。若該引數NULL,傳遞給呼叫執行緒的WM_HOTKEY訊息必須在訊息迴圈中中進行處理。
id:定義熱鍵的識別符號。呼叫執行緒中的其他熱鍵不能使用同樣的識別符號。應用功能程式必須定義一個0X0000-0xBFFF範圍的值。一個共享的動態連結庫(DLL)必須
定義一個0xC000-0xFFFF範圍的值伯GlobalAddAtom函式返回該範圍)。為了避免與其他動態連結庫定義的熱鍵衝突,一個DLL必須使用GlobalAddAtom函式獲得熱鍵的標
識符。
fsModifoers:定義為了產生WM_HOTKEY訊息而必須與由nVirtKey引數定義的鍵一起按下的鍵。該引數可以是如下值的組合:
MOD_ALT:按下的可以是任一Alt鍵。MOD_CONTROL:按下的可以是任一Ctrl鍵。
MOD_SHIFT:按下的可以是任一Shift鍵。
MOD_WIN:按下的可以是任一Windows按鍵。這些鍵可以用Microsoft Windows日誌記錄下來。
MOD_NOREPEAT:Windows 7或者後續版本: 更改熱鍵行為,以便鍵盤自動重複不會產生多個熱鍵通知。
vk:定義熱鍵的虛擬鍵碼。
返回值:若函式呼叫成功,返回一個非O值。若函式呼叫失敗,則返回值為0。若要獲得更多的錯誤資訊,可以呼叫GetLastError函式。
備註:當某鍵被接下時,系統在所有的熱鍵中尋找匹配者。一旦找到一個匹配的熱鍵,系統將把WM_HOTKEY訊息傳遞給登記了該熱鍵的執行緒的訊息佇列。該訊息被傳
送到佇列頭部,因此它將在下一輪訊息迴圈中被移去。該函式不能將熱鍵同其他執行緒建立的視窗關聯起來。
若為一熱鍵定義的擊鍵己被其他熱鍵所定義,則RegisterHotKey函式呼叫失敗。
若hWnd引數標識的視窗已用與id引數定義的相同的識別符號登記了一個熱鍵,則引數fsModifiers和vk的新值將替代這些引數先前定義的值。
Windows CE:Windows CE 2.0以上版本對於引數fsModifiers支援一個附加的標誌位。叫做MOD_KEYUP。
若設定MOD_KEYUP位,則當發生鍵被按下或被彈起的事件時,視窗將傳送WM_HOTKEY訊息。
RegisterHotKey可以被用來線上程之間登記熱鍵。
速查:Windows NT:3.1及以上版本;Windows:95及以上版本;Windows CE:不支援;標頭檔案:winuser.h;庫檔案:Hotkey.lib。
F12鍵是偵錯程式所使用的保留,所以不應將其註冊為熱鍵
#define MOD_ALT 0x0001 = 1
#define MOD_CONTROL 0x0002 = 10
#define MOD_SHIFT 0x0004 = 100
#define MOD_WIN 0x0008 = 1000
在IDA中反彙編RegisterHotKey
.text:77D1EBB3 mov eax, 11EAh //系統服務號
.text:77D1EBB8 mov edx, 7FFE0300h
.text:77D1EBBD call dword ptr [edx]
.text:77D1EBBF retn 10h
.text:77D1EBBF [email protected] endp
系統把服務號儲存在eax暫存器,直接call [edx]
OD檢視得到7FFE0300
dd 7FFE0300
7FFE0300 7C92E510 ntdll.KiFastSystemCall
7FFE0304 7C92E514 ntdll.KiFastSystemCallRet
Windbg檢視得到
lkd> dd ffdf0300 l2
ffdf0300 7c92e510 7c92e514
lkd> u 7c92e510
7c92e510 8bd4 mov edx,esp
7c92e512 0f34 sysenter
windows中0x7FFE0000和0x0FFDF0000被對映到同一個實體地址,供4KB,但在使用者模式下該地址是不可寫的,核心模式下的可寫,4K空間作業系統佔用一部分,
餘下的大約有3K
USER:0x7FFE0000
KERNEL:0x0FFDF0000
在Windbg可用dt nt!_KUSER_SHARED_DATA命令檢視該共享區域
lkd> dt nt!_KUSER_SHARED_DATA
+0x000 TickCountLow : Uint4B
+0x004 TickCountMultiplier : Uint4B
+0x008 InterruptTime : _KSYSTEM_TIME
+0x014 SystemTime : _KSYSTEM_TIME
+0x020 TimeZoneBias : _KSYSTEM_TIME
+0x02c ImageNumberLow : Uint2B
+0x02e ImageNumberHigh : Uint2B
+0x030 NtSystemRoot : [260] Uint2B
+0x238 MaxStackTraceDepth : Uint4B
+0x23c CryptoExponent : Uint4B
+0x240 TimeZoneId : Uint4B
+0x244 Reserved2 : [8] Uint4B
+0x264 NtProductType : _NT_PRODUCT_TYPE
+0x268 ProductTypeIsValid : UChar
+0x26c NtMajorVersion : Uint4B
+0x270 NtMinorVersion : Uint4B
+0x274 ProcessorFeatures : [64] UChar
+0x2b4 Reserved1 : Uint4B
+0x2b8 Reserved3 : Uint4B
+0x2bc TimeSlip : Uint4B
+0x2c0 AlternativeArchitecture : _ALTERNATIVE_ARCHITECTURE_TYPE
+0x2c8 SystemExpirationDate : _LARGE_INTEGER
+0x2d0 SuiteMask : Uint4B
+0x2d4 KdDebuggerEnabled : UChar
+0x2d5 NXSupportPolicy : UChar
+0x2d8 ActiveConsoleId : Uint4B
+0x2dc DismountCount : Uint4B
+0x2e0 ComPlusPackage : Uint4B
+0x2e4 LastSystemRITEventTickCount : Uint4B
+0x2e8 NumberOfPhysicalPages : Uint4B
+0x2ec SafeBootMode : UChar
+0x2f0 TraceLogging : Uint4B
+0x2f8 TestRetInstruction : Uint8B
+0x300 SystemCall : Uint4B
+0x304 SystemCallReturn : Uint4B
+0x308 SystemCallPad : [3] Uint8B
+0x320 TickCount : _KSYSTEM_TIME
+0x320 TickCountQuad : Uint8B
+0x330 Cookie : Uint4B
11EA = 1000111101010 = 13~14位選擇服務描述表,選擇KeServiceDescriptorTableShadow,系統共有4個服務描述表,第一個在ntoskrnl.exe中
並匯出KeServiceDescriptorTable指標
可見該函式沒做任何處理直接進入核心(win32k.sys)中,在Windbg反彙編:
lkd> uf win32k!NtUserRegisterHotKey
win32k!NtUserRegisterHotKey+0x34:
bf899720 33c0 xor eax,eax //eax = NULL
bf899722 eb29 jmp win32k!NtUserRegisterHotKey+0x36 (bf89974d)
win32k!NtUserRegisterHotKey:
bf899729 8bff mov edi,edi
bf89972b 55 push ebp
bf89972c 8bec mov ebp,esp
bf89972e 56 push esi
bf89972f e8b673f6ff call win32k!EnterCrit (bf800aea)
bf899734 f74510f07fffff test dword ptr [ebp+10h],0FFFF7FF0h //fsModifiers是否有效,是否大於1000b 11111111111111110111111111110000
bf89973b 752d jne win32k!NtUserRegisterHotKey+0x14 (bf89976a)//fsModifiers無效則跳轉
win32k!NtUserRegisterHotKey+0x20:
bf89973d 8b4d08 mov ecx,dword ptr [ebp+8] //hWnd
bf899740 85c9 test ecx,ecx
bf899742 74dc je win32k!NtUserRegisterHotKey+0x34 (bf899720)//hWnd == NULL
win32k!NtUserRegisterHotKey+0x27:
bf899744 e86a7ef6ff call win32k!ValidateHwnd (bf8015b3)//則驗證控制代碼
bf899749 85c0 test eax,eax
bf89974b 7427 je win32k!NtUserRegisterHotKey+0x30 (bf899774) //返回NULL
win32k!NtUserRegisterHotKey+0x36:
bf89974d ff7514 push dword ptr [ebp+14h] //vk
bf899750 ff7510 push dword ptr [ebp+10h] //fsModifiers
bf899753 ff750c push dword ptr [ebp+0Ch] //id
bf899756 50 push eax //pWnd
bf899757 e8aefeffff call win32k!_RegisterHotKey (bf89960a)
bf89975c 8bf0 mov esi,eax
win32k!NtUserRegisterHotKey+0x47:
bf89975e e8b373f6ff call win32k!LeaveCrit (bf800b16)
bf899763 8bc6 mov eax,esi
bf899765 5e pop esi
bf899766 5d pop ebp
bf899767 c21000 ret 10h
win32k!NtUserRegisterHotKey+0x14:
bf89976a 68ec030000 push 3ECh //錯誤碼:1004,引數無效
bf89976f e83da0f6ff call win32k!UserSetLastError (bf8037b1)
win32k!NtUserRegisterHotKey+0x30:
bf899774 33f6 xor esi,esi
bf899776 ebe6 jmp win32k!NtUserRegisterHotKey+0x47 (bf89975e)
/***************************************/
PWND FASTCALL ValidateHwnd(
HWND hwnd);
//NtUserRegisterHotKey虛擬碼:
BOOLEN APIENTRY
NtUserRegisterHotKey(HWND hWnd,
int id,
UINT fsModifiers,
UINT vk)
{
BOOLEN bRet;
PWND pWnd = NULL;
EnterCrit();
if(!(fsModifiers & 0x0FFFF7FF0h))
{
if(hWnd)
{
pWnd = ValidateHwnd(hWnd);
}
bRet = _RegisterHotKey(pWnd,id,fsModifiers,vk);
}
else
{
UserSetLastError(1004);//1004無效標誌
bRet = FALSE;
}
LeaveCrit();
return bRet;
}
//系統熱鍵結構:
typedef struct _HOT_KEY_ITEM
{
PETHREAD Thread;
HWND spwnd;
UINT fsModifiers;
UINT vk;
int id;
struct _HOT_KEY_ITEM phkNext;
} HOT_KEY_ITEM, *PHOT_KEY_ITEM;
_RegisterHotKey虛擬碼如下:
BOOL _RegisterHotKey(
PWND pwnd,
int id,
UINT fsModifiers,
UINT vk)
{
PHOT_KEY_ITEM phk;
BOOL fKeysExist = FALSE;
PTHREADINFO ptiCurrent;
PWINDOWSTATION pwinsta = _GetProcessWindowStation(NULL);
DWORD ErrorCode;
ptiCurrent = gptiCurrent;
//如果呼叫者不是WindowStation初始化的執行緒和不適當的許可權
if(grpwinstaList && !CheckWinstaWriteAttributesAccess())
{
return FALSE;
}
//不能為其他執行緒的視窗註冊熱鍵
if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER))
{
if (GETPTI(pwnd) != ptiCurrent)
{
UserSetLastError(1408); //1408錯誤碼:無效視窗;它屬於另一執行緒。
return FALSE;
}
}
phk = FindHotKey(ptiCurrent, pwnd, id, fsModifiers, vk, FALSE, &fKeysExist);
//如果其他執行緒已經註冊過該熱鍵,返回FALSE
if (fKeysExist)
{
UserSetLastError(1409); //1409錯誤碼:熱鍵已被註冊
return FALSE;
}
if (phk == NULL)
{
//熱鍵並未被註冊
phk = (PHOT_KEY_ITEM)HeavyAllocPool(sizeof(HOT_KEY_ITEM), TAG_HOTKEY);
//分配失敗,返回FALSE
if (phk == NULL)
{
return FALSE;
}
phk->pti = ptiCurrent;
if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER))
{
phk->spwnd = NULL;
HMAssignmentLock(&phk->spwnd, pwnd);
}
else
{
phk->spwnd = pwnd;
}
phk->fsModifiers = fsModifiers;
phk->vk = vk;
phk->id = id;
//插入到系統熱鍵連結串列中
//gphkFirst - 這是不匯出變數儲存了系統結構熱鍵(phkNext指向下一個熱鍵結構域)地址
phk->phkNext = gphkFirst;
gphkFirst = phk;
}
else
{
//如果本執行緒已註冊過該熱鍵,則重新覆蓋
phk->fsModifiers = fsModifiers;
phk->vk = vk;
}
return TRUE;
}
//用Windbg檢視下gphkFirst
lkd> dd gphkFirst L1
bf9af814 e2ce10d8
e2ce10d8就是最近一次軟體向系統註冊的全域性熱鍵,繼續
lkd> dd e2ce10d8 l6
e2ce10d8 e2265008 bbe35a28 00000003 00000054
e2ce10e8 0000c024 e2291a68
e2265008 是ETHREAD,檢視發現是QQ的一個執行緒
bbe35a28 是視窗控制代碼
00000003 是功能鍵11,說明有Ctrl+Alt鍵
00000054 是VK_?,0x54對應ASCI碼的大寫T,Ctrl+ATL+T(QQ上:傳送騰訊微博的)
0000c024 是熱鍵的ID
e2291a68 是下一個熱鍵結構
PHOT_KEY_ITEM FindHotKey(
PTHREADINFO ptiCurrent,
PWND pwnd,
int id,
UINT fsModifiers,
UINT vk,
BOOL fUnregister,
PBOOL pfKeysExist)
{
PHOT_KEY_ITEM phk, phkRet, phkPrev;
//初始化返回值
*pfKeysExist = FALSE;
phkRet = NULL;
phk = gphkFirst;
while (phk)
{
if ((phk->pti == ptiCurrent) && (phk->spwnd == pwnd) && (phk->id == id))
{
if (fUnregister)
{
//摘掉熱鍵
if (phk == gphkFirst)
{
gphkFirst = phk->phkNext;
}
else
{
phkPrev->phkNext = phk->phkNext;
}
if ((pwnd != PWND_FOCUS) && (pwnd != PWND_INPUTOWNER))
{
Unlock(&phk->spwnd);
}
UserFreePool((PVOID)phk);
return((PHOT_KEY_ITEM)1);
}
phkRet = phk;
}
//如果熱鍵已經註冊過,設定已存在標誌
if ((phk->fsModifiers == fsModifiers) && (phk->vk == vk))
{
if (phk->spwnd == PWND_FOCUS)
{
if (phk->pti == ptiCurrent)
{
*pfKeysExist = TRUE;
}
}
else
{
*pfKeysExist = TRUE;
}
}
phkPrev = phk;
phk = phk->phkNext;
}
return phkRet;
}
//遍歷系統熱鍵
VOID DumpHotKeys()
{
ULONG dwAddr;
KAPC_STATE ApcState;
PETHREAD pThread;
PEPROCESS pProc;
PHOTKEY phk;
//必須在GUI執行緒中遍歷
KeStackAttachProcess( pExpEprocess , &ApcState );
dwAddr = *(PULONG)gphkFirst;
KeUnstackDetachProcess(&ApcState);
phk = (PHOTKEY)dwAddr;
//解析系統所有熱鍵
while( phk != NULL )
{
pThread = *(PULONG)phk->pti;
//0x220位置指向當前執行緒的EPROCESS
pProc = *(PULONG)( (ULONG)pThread + 0x220 );
//EPROCESS + 0x174指向程序名字
KdPrint(("Process Name : %s\n" , (ULONG)pProc + 0x174 ));
KdPrint(("id : %d\n" , phk->id ));
KdPrint(("Combination : %s + %X\n" , GetButton( phk->fsModifiers ) , phk->vk ));
KdPrint(("------------------------------------------\n"));
phk = phk->phkNext;
}
}
相關推薦
Windows熱鍵註冊(反彙編方法 檢視win32api 原理)
要像系統註冊一個全域性熱鍵,需要用到RegisterHotKey,函式用法如下(MSDN): BOOL RegisterHotKey( HWND hWnd, int id, UINT fsM
Windows熱鍵註冊原理
要像系統註冊一個全域性熱鍵,需要用到RegisterHotKey,函式用法如下(MSDN):BOOL RegisterHotKey( HWND hWnd, int id, UINT fsModifi
ARM的BIN檔案反彙編方法
最近在除錯uboot的程式碼時,用的新版本的uboot,lowlevel_init函式裡是空的,而且在連結檔案中也沒有發現對lowlevel_init.o的連結。在bl lowlevel_init 之前和之中加了兩個電燈,發現在bl之後的部分並沒有被執行,所以想看看具體程式
轉——一個超級wince牛人使用反彙編工具修改程式的方法
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
windows下端口占用解決方法-檢視和殺死佔用埠程序
在Windows下啟動程式時有時會遇到埠被佔用的情況,由於一個埠同時只能執行一個程序,所以要想啟動新的程式就要先把佔用該埠的程序給kill掉,具體的命令分為以下三步, 以殺死佔用了80埠的程序為例: 1、根據埠號“80”查詢程序號 netstat -ano|findstr "80" TCP
windows、ubuntu系統程式執行檢視視訊記憶體方法
ubuntu系統 開啟終端 在終端直接輸入命令列 nvidia-smi 即可檢視 windows系統 執行 命令列 nvidia-smi.exe -l 方法如下: nvidia-smi.exe 路徑 C:\Windows\System32\DriverStor
dex2jar反彙編android的dex/APK檔案為jar包命令和方法
1、下載dex2jar 2、windows系統開啟cmd進入dex2jar.bat目錄 輸入命令: dex2jar.bat ./classes.dex 或者 d2j-dex2jar classes.dex(classes.dex 為需要反編譯的檔案,) 3、即可生成
反彙編檢視gcc行為
int i = 3; printf(”%d/n”, i++ * ++i + i– * –i); 在吉林大學的視訊c教程中, 上式值為18.她的解法是字首優先於字尾,所以就是3 * 4 + 3 * 2。在gcc中得到的結果是25。 這種行為是標準未定義的。 可以通過反彙編來檢視gcc的行為。如下,我們看看呼叫
windows 程式設計 註冊熱鍵
網上找了很多關於註冊熱鍵的,都是基於MFC 響應的。 本文是 直接響應 對於註冊多個熱鍵,使用hotkeyid ,我這裡是使用 對於 輸入的按鍵,進行拼接,將保證每次鍵入的id 都不同,方便移除熱鍵/****************************/ /***直接
shellcode 反彙編,模擬執行以及除錯方法
onlinedisassembler https://onlinedisassembler.com 線上反彙編工具,類似於lda。功能比較單一。 Any.run 等平臺線上分析 將shellcode儲存為檔案 通過如下指令碼,轉換shellcode為char陣列 import binascii fil
windows 微軟註冊
alt cnblogs 分享 windows es2017 ima ges http src windows 微軟註冊
未知打磨IC芯片型號鑒定IC芯片型號查詢單片機絲印反查詢方法!
芯片型號鑒定 ic芯片查詢 芯片型號查詢 ic型號查詢 未知打磨IC芯片型號鑒定IC芯片型號查詢單片機絲印反查詢方法! 我們在PCB抄板解密時經常會遇到IC芯片被打磨了沒有字,或者真實的型號被擦除並絲印上假的型號。這樣無法做出完整的電路板B
metasploit下Windows的多種提權方法
sys png 獲得 詳細信息 參考 leg hack 用法 spl metasploit下Windows的多種提權方法 前言 當你在愛害者的機器上執行一些操作時,發現有一些操作被拒絕執行,為了獲得受害機器的完全權限,你需要繞過限制,獲取本來沒有的一些權限,這些權限可以
VMware 上windows 系統密碼忘記修改方法
windows虛擬機密碼* 1.下載PE,ISO本版本的(帶密碼破解軟件) * 2.上傳PE ISO 至虛擬機服務器 * 3.關閉windows虛擬機 * 4.點擊編輯虛擬機設置 * 5.點擊硬件,點擊CD/DVD驅動器,勾選數據存儲ISO文件,點擊瀏覽選擇上傳的PE ISO文件 * 6.點擊選項,勾選強制執
Windows10中啟用原來的Windows照片查看器方法
eas txt文件 PE col pan 保存文件 str RR 垃圾 前言: ============================================== Windows10 版系統自帶很多垃圾應用,圖片查看器弄得很不好用,還是習慣Windows
3星|《數據的真相》:常見的數據誤導與反誤導方法
內容 心理學 原因 體重 href eas 關聯 至少 蘋果手機 數據的真相:如何在數字時代做出明智決策 全書由許多小章節組成,每一小章節是一篇相對獨立的短文,講一種數據造成的誤解/誤導,和讀者的反誤解/反誤導方法。比如說看數據的話美國的副市長的平均工資高於市長的平均
Win10系統清理Windows Store緩存的方法
下回 朋友 是我 助手 51cto 管理員 www 運行 mar Win10系統的應用商店相比之前有了許多的更新,微軟也成立了專門的團隊準備對應用商店進行完善,但是我們在使用應用商店的過程中會產生許多緩存文件,占用電腦空間資源,也會影響電腦的運行速度。下面<A hre
在Linux下訪問Windows共享目錄的配置方法
admin 完全 linu all 計算 ifs amba 方法 linux 1、在Windows上設置一個共享目錄mailbak(設置用戶權限,用戶名和密碼這些)對該共享目錄有完全控制權限(讀、寫)2、在Linux下安裝samba-client客戶端# yum insta
SQLSERVER誤刪Windows登錄用戶驗證方式使用Windows身份驗證的解決方法
ros 命令 microsoft gif ride 給他 服務器 reat lan 今天看到這篇文章:沒有了SA密碼,無法Windows集成身份登錄,DBA怎麽辦? 想起來之前著急哥問我的一個問題,一個DBA刪除了Windows登錄用戶,而且SQLSERVER服務器的驗證
談談fastjson反序列方法JSON.parseObject(String text, Class<T> clazz)--來源於生產實踐
名稱 種類 種類型 oba hashmap tde font 關註 內存 fastjson這一工具包幫助我們進行java對象和json格式的字符串之間的相互轉換。對象到字符串的過程,我們稱之為序列化;反之,我們稱為反序列化。 現在我們就來談談fastjson提供的反序列化方