首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

MASM32 實作:從登錄取得 WinRAR 安裝路徑

     編輯:組合語言

前言

這個 MASM32 範例示範如何在 Win32 組合語言中呼叫登錄 API (RegOpenKeyEx, RegQueryValueEx, RegCloseKey) 讀取 WinRAR 安裝路徑,並用訊息方塊顯示。展示了標準 Win32 程式架構、API 錯誤處理、字串緩衝區管理、巨集簡化資料搬移等實用技巧。

程式架構

.386
.model flat, stdcall
option casemap:none
include \masm32\include\windows.inc
include \masm32\include\advapi32.inc
include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
includelib \masm32\lib\advapi32.lib
includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib

GetRarPath PROTO :LPSTR
m_m2m MACRO d1, d2
 push d2
 pop d1
ENDM
  • .386/.model flat,stdcall:32 位元平坦模型,stdcall 慣例
  • option casemap:none:區分大小寫 (windows.inc 要求)
  • m_m2m 巨集:以堆疊中轉實現記憶體到記憶體搬移 (x86 無 MOV mem,mem)

資料區定義

.data
g_szTitle db "WinRAR路徑", 0
g_szRegPath db "SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe", 0
g_szFailRegOpenKeyEx db "RegOpenKeyEx失敗!", 0
g_szFailRegQueryValueEx db "RegQueryValueEx失敗!", 0
g_szValueName db "Path", 0

.data?
g_szRarPath db 256 dup(?)
g_hRegKey4IE HKEY ?
  • 登錄路徑:HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\WinRAR.exe
  • 查詢值名稱:Path (預設值為空字串,實際路徑存於預設值)
  • g_szRarPath:256 位元組接收緩衝區

主程式流程

start:
 invoke GetRarPath, ADDR g_szRarPath
 .if eax==1
  mov eax, OFFSET g_szFailRegOpenKeyEx
 .elseif eax==2
  mov eax, OFFSET g_szFailRegQueryValueEx
 .else
  mov eax, OFFSET g_szRarPath
 .endif
 invoke MessageBox, NULL, eax, OFFSET g_szTitle, MB_OK
 invoke ExitProcess, NULL

使用 MASM 高階語法 .if/.elseif/.else/.endif 處理 GetRarPath 返回碼:1=開啟鍵失敗,2=查詢值失敗,0=成功 (EAX=0)。

GetRarPath 核心函式

GetRarPath PROC lpszRarPath: LPSTR
 LOCAL dwcbData: dword

 invoke RegOpenKey, HKEY_LOCAL_MACHINE, ADDR g_szRegPath, ADDR g_hRegKey4IE
 .if eax!=ERROR_SUCCESS
  m_m2m eax, 1
  ret
 .endif

 m_m2m dwcbData, SIZEOF g_szRarPath
 invoke RegQueryValueEx, g_hRegKey4IE, ADDR g_szValueName, NULL, NULL, ADDR g_szRarPath, ADDR dwcbData
 .if eax!=ERROR_SUCCESS
  m_m2m eax, 2
 .else
  xor eax, eax
 .endif

 invoke RegCloseKey, g_hRegKey4IE
 ret
GetRarPath ENDP

關鍵 API 呼叫細節

  1. RegOpenKey (舊版 API,實為 RegOpenKeyEx 簡化版):開啟 HKLM 下指定子鍵,句柄存入 g_hRegKey4IE。失敗返回非 ERROR_SUCCESS (0)。
  2. RegQueryValueEx:
    • lpValueName = "Path"
    • lpReserved = NULL
    • lpType = NULL (不需類型)
    • lpData = g_szRarPath (輸出緩衝區)
    • lpcbData = &dwcbData (輸入緩衝區大小,輸出實際資料大小)
  3. RegCloseKey:釋放鍵句柄,避免洩漏。

技術亮點總結

技巧說明
m_m2m 巨集push/pop 實現 mem-to-mov,避免需經暫存器
LOCAL 區域變數dwcbData 自動配置堆疊空間,PROC 結束自動釋放
.if/.else 高階語法編譯器自動產生 CMP/Jcc 指令,提升可讀性
ADDR 操作符取得記憶體位址 (相當於 OFFSET,但支援區域變數)
ERROR_SUCCESS 常數windows.inc 定義為 0,語意化錯誤檢查
字串緩衝區大小計算SIZEOF g_szRarPath 自動計算 256

潛在改進

  • 使用 RegOpenKeyEx 替代舊版 RegOpenKey (支援 samDesired 權限控制)
  • 檢查 dwcbData 確保資料完整
  • 支援 HKCU (使用者層級安裝路徑)
  • 處理 Unicode 版本 API (RegQueryValueExW) 以支援長路徑/國際字元
  • 加入 SHGetFolderPath 等 Shell API 作為備選定位方式

結語

這個範例以約 60 行核心程式碼完成 Win32 登錄讀取實戰。它展示了 MASM32 在 Windows 系統程式開發中的實力:完整的 API 覆蓋、高階語法支援、標準庫整合、型別安全。對於需要無運行時依賴、極小體積、直接呼叫系統 API 的場合 (如安裝程式、啟動器、系統工具),MASM32 仍是極具競爭力的選擇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved