MASM32编程完善SysInfo遇到奇怪故障,真切感受全局变量和局部变量之别……

Posted 紫郢剑侠

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MASM32编程完善SysInfo遇到奇怪故障,真切感受全局变量和局部变量之别……相关的知识,希望对你有一定的参考价值。

SysInfo主要是通过WMI来获取系统信息的,但是WMI获取的操作系统信息中没有Windows操作系统是32位还是64位的内容,所以需要另外想办法编程获取,比较常见的方法是调用Windows API函数GetNativeSystemInfo()或IsWow64Process()。之前分别用MASM32和VC分别编写了调用GetNativeSystemInfo()的代码。详见:MASM32编程访问结构体成员要注意的一点https://blog.csdn.net/Purpleendurer/article/details/128063894?spm=1001.2014.3001.5501

今天把32or64.asm中的相关代码移植到SysInfo中来显示,主要是把32or64.asm中的相关代码改为一个函数showOsType(),原来的一些全局变量相应改成函数内部的局部变量,代码如下:

    g_szOsType                  db    "系统类型:", 0
    g_sz32Bit                   db    "32位",0
    g_sz64Bit                   db    "64位",0
    g_szGetNativeSystemInfo     db    "GetNativeSystemInfo", 0
    g_szkernel32Dll             db    "kernel32.dll", 0
    g_szFailGetModuleHandle     db    "GetModuleHandle失败", 0
    g_szFailGetProcAddress      db    "GetProcAddress失败", 0
    g_szFailGetNativeSystemInfo db    "GetNativeSystemInfo失败", 0

showOsType proc
    LOCAL lpSI: dword
    LOCAL lpfnGetNativeSystemInfo: _LPFNGetNativeSystemInfo

    invoke editCatStr, OFFSET g_szOsType

    invoke GetModuleHandle, OFFSET g_szkernel32Dll
    .if    eax==NULL
        push OFFSET g_szFailGetModuleHandle 

    .else
        invoke GetProcAddress, eax, OFFSET g_szGetNativeSystemInfo
        .IF eax==NULL
            push   OFFSET g_szFailGetProcAddress ; for call editCatStr()
        .ELSE
            mov    lpfnGetNativeSystemInfo, eax 

            invoke lpfnGetNativeSystemInfo, ADDR lpSI                               

            lea    eax, lpSI
            movzx eax, (_SYSTEM_INFO ptr [eax]).wProcessorArchitecture
            .if (eax==PROCESSOR_ARCHITECTURE_IA64) || (eax==PROCESSOR_ARCHITECTURE_AMD64) || (eax==PROCESSOR_ARCHITECTURE_ARM64)
                push OFFSET g_sz64Bit
            .else
                push OFFSET g_sz32Bit
            .endif
        .ENDIF
    .endif

    call editCatStr ;invoke editCatStr, eax
    
    ret
showOsType endp

修改的程序汇编连接正常,运行时可以正常显示Windows操作系统类型是32位还是64位的,但显示完这行信息后停滞了一下,随后SysInfo窗口就没有任何提示地自动关闭了。

 

用OllyDbg跟踪了代码运行情况,代码运行正常,可以获得正确的操作系统类型信息,但是在函数执行结束返回时出现了访问异常。

还是第一次遇到这种情况,为了弄清楚原因,把showOsType()代码拿出来单独测试,代码如下:

;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
; FileName: WinBit.asm
; Function: Show windows bit with API GetNativeSystemInfo
;   Author: PurpleEndurer
;   DevEnv: Windows 10  + MASM32
; 
; Log:
;---------------------------------------------------------------
;  20221216 Created
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
.586
.model     flat, stdcall
option     casemap:none
include    \\masm32\\include\\windows.inc
include    \\masm32\\include\\kernel32.inc
includelib \\masm32\\lib\\kernel32.lib
include    \\masm32\\include\\user32.inc
includelib \\masm32\\lib\\user32.lib
 
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
;proto
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
_GetNativeSystemInfo     TYPEDEF proto :DWORD
_LPFNGetNativeSystemInfo TYPEDEF Ptr _GetNativeSystemInfo
 
showOsType           proto
 
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
;.const
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
;PROCESSOR_ARCHITECTURE_INTEL   equ 0      ;x86
;PROCESSOR_ARCHITECTURE_ARM     equ 5      ;ARM
;PROCESSOR_ARCHITECTURE_IA64    equ 6      ;基于 Intel Itanium 的
;PROCESSOR_ARCHITECTURE_AMD64   equ 9      ;x64 (AMD 或 Intel)
PROCESSOR_ARCHITECTURE_ARM64    equ 12     ;ARM64
;PROCESSOR_ARCHITECTURE_UNKNOWN equ 0ffffh ;未知体系结构。
 
 
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
;.data
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
  

 
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss
.code
;sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss

    g_szOsType                  db    "系统类型:", 0
    g_sz32Bit                   db    "32位",0
    g_sz64Bit                   db    "64位",0
    g_szGetNativeSystemInfo     db    "GetNativeSystemInfo", 0
    g_szkernel32Dll             db    "kernel32.dll", 0
    g_szFailGetModuleHandle     db    "GetModuleHandle失败", 0
    g_szFailGetProcAddress      db    "GetProcAddress失败", 0
    g_szFailGetNativeSystemInfo db    "GetNativeSystemInfo失败", 0

showOsType proc
    LOCAL lpSI: dword
    LOCAL lpfnGetNativeSystemInfo: _LPFNGetNativeSystemInfo

    invoke GetModuleHandle, OFFSET g_szkernel32Dll
    .if    eax==NULL
        mov eax, OFFSET g_szFailGetModuleHandle 
    .else
        invoke GetProcAddress, eax, OFFSET g_szGetNativeSystemInfo
        .IF eax==NULL
            mov eax, OFFSET g_szFailGetProcAddress
        .ELSE
            mov   lpfnGetNativeSystemInfo, eax

            invoke lpfnGetNativeSystemInfo, ADDR lpSI
                               
            lea   eax, lpSI
            movzx eax, (SYSTEM_INFO ptr [eax]).wProcessorArchitecture
            .if (eax==PROCESSOR_ARCHITECTURE_IA64) || (eax==PROCESSOR_ARCHITECTURE_AMD64) || (eax==PROCESSOR_ARCHITECTURE_ARM64)
                mov eax, OFFSET g_sz64Bit   ; push OFFSET g_sz64Bit
            .else
                mov eax, OFFSET g_sz32Bit   ; push OFFSET g_sz32Bit
            .endif
        .ENDIF
    .endif

push eax
      invoke MessageBox, NULL, eax, OFFSET g_szOsType, MB_OK
pop eax
    ret
showOsType endp


main  proc
      invoke showOsType
      invoke MessageBox, NULL, eax, OFFSET g_szOsType, MB_OK
      invoke ExitProcess, NULL
 main endp
 
end main

代码汇编连接成功,运行时正常显示showOsType()中

invoke MessageBox, NULL, eax, OFFSET g_szOsType, MB_OK

显示的信息框:

然后就出现问题了:

E xception 000006BA . exception is non-continuable

 

 main()函数中的

invoke MessageBox, NULL, eax, OFFSET g_szOsType, MB_OK

 并没有得到执行,显示出信息框来。

开始百思不得其解,后面重新研究了GetNativeSystemInfo的参数说明:

参数

[out] lpSystemInfo

指向接收信息的 SYSTEM_INFO 结构的指针。

我代码中传递GetNativeSystemInfo()的参数dword类型变量lpSI,其值没有初始化,而不是指向一个SYSTEM_INFO结构的地址(指针)。这样GetNativeSystemInfo函数返回的SYSTEM_INFO结构信息数据覆盖了函数返回信息数据,导致函数结束返回时跳到了错误的地址,引发异常。

原来如此,看来lpSI定义为全局变量没有出现问题纯属侥幸。写代码一定要看清楚函数原型和说明。

参考:

GetNativeSystemInfo 函数 (sysinfoapi.h)

以上是关于MASM32编程完善SysInfo遇到奇怪故障,真切感受全局变量和局部变量之别……的主要内容,如果未能解决你的问题,请参考以下文章

sysInfo-用MASM32编写的Windows系统软件硬件网络信息收集程序(补充了下载地址)

sysInfo-用MASM32编写的Windows系统软件硬件网络信息收集程序

MASM32编程访问结构体成员要注意的一点

MASM32编程访问结构体成员要注意的一点

Win10 + MASM32 + EditPlus 汇编语言编程环境设置

MASM32v11编程调用Process32First失败: 程序发出命令,但命令长度不正确