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

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

SysInfo主要是通过WMI来获取系统信息的,但是WMI获取的操作系统信息中没有Windows操作系统是32位还是64位的内容,所以需要另外想办法编程获取,比较常见的方法是调用Windows API函数GetNativeSystemInfo()或IsWow64Process()。之前分别用MASM32和VC分别编写了调用GetNativeSystemInfo()的代码。

今天把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窗口就没有任何提示地自动关闭了。

image.png

用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

image.png

然后就出现问题了:

E xception 000006BA . exception is non-continuable

image.png

main()函数中的

invoke MessageBox, NULL, eax, OFFSET g_szOsType, MB_OK

1.

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

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

参数

[out] lpSystemInfo

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

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

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

参考:

GetNativeSystemInfo 函数 (sysinfoapi.h)


相关文章
|
11天前
|
弹性计算 人工智能 架构师
阿里云携手Altair共拓云上工业仿真新机遇
2024年9月12日,「2024 Altair 技术大会杭州站」成功召开,阿里云弹性计算产品运营与生态负责人何川,与Altair中国技术总监赵阳在会上联合发布了最新的“云上CAE一体机”。
阿里云携手Altair共拓云上工业仿真新机遇
|
8天前
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
2520 17
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
7天前
|
机器学习/深度学习 算法 数据可视化
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
2024年中国研究生数学建模竞赛C题聚焦磁性元件磁芯损耗建模。题目背景介绍了电能变换技术的发展与应用,强调磁性元件在功率变换器中的重要性。磁芯损耗受多种因素影响,现有模型难以精确预测。题目要求通过数据分析建立高精度磁芯损耗模型。具体任务包括励磁波形分类、修正斯坦麦茨方程、分析影响因素、构建预测模型及优化设计条件。涉及数据预处理、特征提取、机器学习及优化算法等技术。适合电气、材料、计算机等多个专业学生参与。
1522 14
【BetterBench博士】2024年中国研究生数学建模竞赛 C题:数据驱动下磁性元件的磁芯损耗建模 问题分析、数学模型、python 代码
|
3天前
|
存储 关系型数据库 分布式数据库
GraphRAG:基于PolarDB+通义千问+LangChain的知识图谱+大模型最佳实践
本文介绍了如何使用PolarDB、通义千问和LangChain搭建GraphRAG系统,结合知识图谱和向量检索提升问答质量。通过实例展示了单独使用向量检索和图检索的局限性,并通过图+向量联合搜索增强了问答准确性。PolarDB支持AGE图引擎和pgvector插件,实现图数据和向量数据的统一存储与检索,提升了RAG系统的性能和效果。
|
9天前
|
编解码 JSON 自然语言处理
通义千问重磅开源Qwen2.5,性能超越Llama
击败Meta,阿里Qwen2.5再登全球开源大模型王座
571 14
|
1月前
|
运维 Cloud Native Devops
一线实战:运维人少,我们从 0 到 1 实践 DevOps 和云原生
上海经证科技有限公司为有效推进软件项目管理和开发工作,选择了阿里云云效作为 DevOps 解决方案。通过云效,实现了从 0 开始,到现在近百个微服务、数百条流水线与应用交付的全面覆盖,有效支撑了敏捷开发流程。
19282 30
|
9天前
|
人工智能 自动驾驶 机器人
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
过去22个月,AI发展速度超过任何历史时期,但我们依然还处于AGI变革的早期。生成式AI最大的想象力,绝不是在手机屏幕上做一两个新的超级app,而是接管数字世界,改变物理世界。
479 49
吴泳铭:AI最大的想象力不在手机屏幕,而是改变物理世界
|
1月前
|
人工智能 自然语言处理 搜索推荐
阿里云Elasticsearch AI搜索实践
本文介绍了阿里云 Elasticsearch 在AI 搜索方面的技术实践与探索。
18839 20
|
1月前
|
Rust Apache 对象存储
Apache Paimon V0.9最新进展
Apache Paimon V0.9 版本即将发布,此版本带来了多项新特性并解决了关键挑战。Paimon自2022年从Flink社区诞生以来迅速成长,已成为Apache顶级项目,并广泛应用于阿里集团内外的多家企业。
17528 13
Apache Paimon V0.9最新进展
|
2天前
|
云安全 存储 运维
叮咚!您有一份六大必做安全操作清单,请查收
云安全态势管理(CSPM)开启免费试用
364 4
叮咚!您有一份六大必做安全操作清单,请查收