正如@Igor Skochinsky已经评论过的那样,该软件确实是用在本机模式下编译的Visual Basic 6编写的(VB6 也支持 P 模式)。您可以使用Detect It Easy等 PE 信息工具来验证这一点(但在此之前您需要解压ASPack包装器)。
该错误的原因是由于多种原因。
该软件使用 WinApi 函数GlobalMemoryStatus来检索当前使用的系统内存。现在这个函数有几个怪癖:
第一的
在内存超过 4 GB 的计算机上,GlobalMemoryStatus 函数可能返回错误信息,报告值 –1 表示溢出。为此,应用程序应改用 GlobalMemoryStatusEx 函数。
因此,如果您的系统内存超过 4 GB,则此函数的输出不可靠,因此可能会显示错误值。解决这个问题很困难。
第二
在内存大于 2 GB 且小于 4 GB的Intel x86 计算机上,GlobalMemoryStatus 函数将始终在 MEMORYSTATUS 结构的 dwTotalPhys 成员中返回 2 GB。同样,如果总可用内存在 2 到 4 GB 之间,则 MEMORYSTATUS 结构的 dwAvailPhys 成员将向下舍入为 2 GB。如果使用 /LARGEADDRESSAWARE链接器选项链接可执行文件,则 GlobalMemoryStatus 函数将返回两个成员中正确的物理内存量
要修复此错误,您需要使应用程序具有Large Address Aware。这可以通过在CFF Explorer 中加载它来完成,并在Nt Headers -> File headers -> Characteristics下检查标志App can handle > 2GB address space。
现在,要将从中获得的整数内存值转换GlobalMemoryStatus为字符串,应用程序使用该CStr函数。
VB6 没有无符号的 32 位整数数据类型。唯一的无符号数据类型是 8 位Byte。
假设您的系统内存大于 2GB 但小于 4GB,并且您已经修复了上面提到的第二个错误。
假设您的系统有 3GB 内存。这相当于3,22,12,25,472十进制1100 0000 0000 0000 0000 0000 0000 0000字节或二进制字节。
由于此值的MSB为 1,因此传递给 时将被视为负数CStr。因此,结果字符串将- 1GB代替3GB. 对此也没有简单的解决方法。
因此,总而言之,该软件仅在您的系统内存小于 2GB 时可用。
更新(有符号整数错误修复)
可以修补有符号整数错误,使应用程序可用到 4GB。修补二进制以将SAR(有符号移位)转换为SHR(无符号移位)指令。
原始代码
00092DCD and edx,000FFFFF
00092DD3 add eax,edx
00092DD5 sar eax,14 ; <<<<<<<<<<<
00092DD8 mov dword ptr [ebp-28],eax
00092DDB mov eax,dword ptr [ebp-54]
00092DDE cdq
00092DDF and edx,000FFFFF
00092DE5 add eax,edx
00092DE7 sar eax,14 ; <<<<<<<<<<<
00092DEA mov dword ptr [ebp-30],eax
修补代码
00092DCD and edx,000FFFFF
00092DD3 add eax,edx
00092DD5 shr eax,14 ; <<<<<<<<<<<
00092DD8 mov dword ptr [ebp-28],eax
00092DDB mov eax,dword ptr [ebp-54]
00092DDE cdq
00092DDF and edx,000FFFFF
00092DE5 add eax,edx
00092DE7 shr eax,14 ; <<<<<<<<<<<
00092DEA mov dword ptr [ebp-30],eax
结合大地址感知和带符号整数补丁,该应用程序可用于 4 GB 内存。