分类 开发随笔 下的文章

前言

在本文中,我将使用x86汇编和简易的小小程序片段,其中将会使用最新的C++ 23标准进行代码编写。所以当你开始阅读这篇短文时,希望你有理解C++ 23,内存,指针和标准Win32 API的基本概念的能力。

代码段

#include <iostream>

int main() {
    auto string = "Hello, World! ";
    auto integer = 114514;
    std::cout << string << integer << std::endl;
    system("pause");
    return 0;
}

在这段简单的代码中,很明显这只是一个利用了C++新特性的HelloWorld程序,不难看出它最终会在命令提示符打出”Hello, World! 114514”这个字符串和整数并且传输pause指令给命令提示符,让其暂停运行并显示“按任意键继续”的提示。
提示:在编译时候记得加上-static给CMAKE_EXE_LINKER_FLAGS,这样才可以让编译出的可执行文件独立运行

入口点

当你将编译出的可执行文件拖入IDA的窗口之后,当IDA自动分析完成整个程序的互相调用,会给出一张十分复杂的调用图(如下图)。
IDA_MainGraph
你可能会很好奇为什么,只是一个简单的Hello,World程序而已为什么会存在这么多的调用,并没有在代码中体现出来哇?
放大其中任意一个代码块(如下图)你会发现,他们做的那么多事情,无非就是在准备运行现场,错误处理等现代编程语言自带的功能,在现如今的编程中,这些以往繁琐的操作,都将会被自动处理。
IDA_AnyPreFunc
在这个简单的程序中,入口点是main函数,我们手工构建了一个主函数。在IDA自动生成的调用图中,可以看到许多Win32 API函数被调用。这些函数包括获取当前进程的句柄、获取控制台窗口的句柄、向标准输出打印信息、调用系统命令行窗口实现以实现等待用户按键等。这些函数是必要的,因为它们提供了程序运行所必需的环境和支持。

main?WinMainCRTStartup和mainCRTStartup?

WinMainCRTStartup和mainCRTStartup是CRT(C Runtime)库提供的启动代码。它们都是程序入口点,但是它们的参数和返回值类型不同,适用于不同的应用程序类型以及适配了不同平台的实现。
IDA_mainCRTStartup
由上图可知mainCRTStartup是用于控制台应用程序的入口点,它不带任何参数执行。mainCRTStartup会进行一些必要的初始化工作,然后调用main函数。在main函数执行完毕后,它会自动退出程序,并返回main函数的返回值作为程序的退出码。
IDA_WinmainCRTStartup
在Win的部分中,由于当前程序只有命令行界面,故Win部分的实际实现也与标准入口点相同,其中混合部分Windows特有处理。

反编译的伪代码

IDA_Pseudocode
在IDA中,使用F5可以反编译出伪代码,看以上的伪代码思路要比直接看汇编效率高出很多,非常方便的可以看出这是一个典型的入口点函数,执行的操作也很清晰明了。

总结

在这篇文中,可以大概理解到一个纯命令行程序在Windows下的简易执行逻辑。
1.初始化C/C++运行时环境,包括初始化全局变量、静态变量等。
2.调用MainCRTStartup/WinMainCRTStartup函数,该函数初始化Win32 API环境,并调用Main函数。
3.设置标准输入、标准输出和标准错误流,以便程序可以向控制台输出信息。
4.初始化异常处理机制,包括设置SEH(结构化异常处理)机制*Windows特有。
总之,在现代的程序环境下,大部分与系统底层交互的部分,都存在完备的已封装功能,我们只需要直接调用即可。然而,在一定程度上了解这些内容也是有些必要,对底层更为了解,也更好的优化自己的作品。


这些GUID用于DisplayHdrLevel中的认证项目显示,需要多字符串值(Multi-String)且可叠加使用

VESA DisplayHDR

VESA DisplayHDR 400 (1.0)
20C5A9AF-CD1A-42B1-AA71-4C96A273DEF1
VESA DisplayHDR 400 (1.1)
0D710BC2-6368-4EB2-A829-CBBD45CE3BD2
VESA DisplayHDR 500 (1.1)
C47B4522-B803-47B0-831F-2ED63B56CE79
VESA DisplayHDR 600 (1.0)
D4C5928E-9488-46AF-8DA8-4F996EE4177F
VESA DisplayHDR 600 (1.1)
7134A821-9254-4AF4-9973-95B3FCF720CC
VESA DisplayHDR 1000 (1.0)
78137DFC-3400-412E-B0AF-08120754623A
VESA DisplayHDR 1000 (1.1)
C624859D-304A-4DE8-86DC-8BE82B79527A
VESA DisplayHDR 1400 (1.0)
0D710BC2-6368-4EB2-A829-CBBD45CE3BD2
VESA DisplayHDR 1400 (1.1)
3CA0903F-99E0-46FB-9BEC-DE023507BEF0
VESA DisplayHDR 2000 (1.1)
80931144-16F1-4710-91F4-2E66713B134D
VESA DisplayHDR 400 True Black (1.0)
1A6CBAFB-15FF-4CF0-AD75-12360E9B9F4A
VESA DisplayHDR 400 True Black (1.1)
FB4CB49B-F5A8-4084-800C-EB38E9CA16DE
VESA DisplayHDR 500 True Black (1.0)
86413F8C-0CDB-4D49-81F7-06BB64A8FED1
VESA DisplayHDR 500 True Black (1.1)
3B6DAA9E-3794-4D85-897E-93AE990D275D
VESA DisplayHDR 600 True Black (1.1)
9AD0FB30-006E-49FE-AA15-8F65F28A476B
VESA DisplayHDR 1000 True Black (1.1)
9C5D5F59-1FA8-4D2B-87DD-2E3B2BFF37D5

DOLBY

Dolby Vision
6363AA90-A651-4154-A9E1-2D765C08E68F

NVIDIA

NVIDIA G-SYNC ULTIMATE
35FBD985-74F0-4271-AC61-295F11D71AEF

AMD

AMD Freesync Premium Pro
F9310F0E-93B2-4A58-8642-17358D8CB2E3


最近因为笔记本的SSD出现了奇怪的问题,所以选择了重装系统,在重装系统之后,发现Dolby Atmos这些组件,由于声卡驱动的软件组件的存在,一旦连接到网络,即可通过Windows Update自动重新下载和安装,但是Dolby Vision这类额外组件,则需要手动补全。但在通过Microsoft Store的已购买功能找到Dolby Vision客户端安装后,发现调整设置没有反应,在Dolby Access中直接没有了杜比视界选项,播放Dolby Vision视频也没有了Logo提示和色彩校准,Netflix HDR视频内容也完全是偏色的状态。
FixDBV_MissingVision
在网上大量寻找资料,得知Dolby Vision是需要校准+密钥二合一文件才可在Windows下打开,于是便在网上大量寻找我这个型号的校准+密钥二合一文件,然而联想并未任何单独下载,其他OEM的方案则是通过显示器驱动来解决,然而联想并未给我这个型号提供任何显示器驱动。
由于跟我这个产品的PM有认识,他给出的方法是建议送到附近的维修站重装系统,然而我目前不在国内,并不具备去到服务站的条件。其后,他又给出了一个建议,使用联想海外版本的LDDRS(Lenovo Digital Download Recovery Service)服务,自行制作官方恢复盘进行恢复(可在此处找到)
但在刻录完启动盘之后,从U盘启动,发现其要格式化整个硬盘来重装系统,并且恢复到旧版本的Windows,由于前一次重装系统后数据已经重新安排妥当,所以我没有选择直接恢复,而是开始对恢复盘的文件内容进行逆向。
其恢复盘内的大部分内容通过IMZ文件(本体)+CRI文件(基本信息)来组成
FixDBV_RecoveryFileDetails
由于CRI是文本文件,则很方便的就寻找到了DolbyVision所对应的CRI和IMZ文件
FixDBV_CriInEditor
同时发现其所谓的IMZ,也仅仅只是7z压缩包而已
但是,在解压时,却又出现了问题
FixDBV_PasswordError
发现其中提到的"Password=lenovo"根本不对!这里有坑!所以又继续爬贴,爬Github,终于在一个小众论坛和Github上找到了解决方案(这里这里),在此感谢DenizOezmen的逆向!
那时候觉得Python不够优雅,所以把它给移植到了C++和Javascript,代码和可执行文件如下
网页版

#include <iostream>
#include <string>

using namespace std;

int main()
{
    string PwChars = "k`gybs0vampjd";
    string Password;
    cout << "Lenovo Recovery Image IMZ File Password Analyzer\n(C)Yuu 2022\n";
    cout << "Password in CRI File>>";
    cin >> Password;
    cout << "Real Password: ";
    for (int i = 0; i < Password.length(); i++)
    {
        cout << (char)(PwChars[Password[i] % 13] - (i % 3) + 2);
    }
    cout << endl;
    system("pause");
    return 0;
}

下载可执行文件(Windows-x86)
执行后,成功得到了真实密码!
FixDBV_RealPassword
也终于成功解压出了所有文件!
FixDBV_RealFile
在对setup.cmd进行简单的分析过后,发现其实并不用那么复杂,其全部过程即为
1.先行安装"Headedcode"或"Headlesscode"文件夹内的appx

注:
1.如果你的设备使用DolbyAccess来管理所有杜比组件,则安装Headlesscode中的appx(即为Store中的Dolby Vision Extension)
2.如果你的设备跟我的一样,使用单独的Dolby Vision App来管理,则需要安装Headedcode中的appx

2.再通过管理员权限执行其中的ProvisionDolbyVision.exe,有可能会报错但不影响使用
3.此时重启设备,你会发现你的DolbyVision回来了!
FixDBV_Succeed

注:
通过对ProvisionDolbyVision.exe的分析,发现其只是检测MONITOR/后的字符串,然后从ICMS文件夹中,选定要复制的文件,将文件名改为PQCONFIG.DV后,复制到<SYSTEM_DRIVE>:\WINDOWS\System32\spool\drivers\color目录下而已,如果这个一键程序无法正常工作,则可以通过直接复制的方法来解决问题

最近有在WindowsMe下跑某软合成器,由于其是依赖VXD的驱动,所以只得搭建虚拟环境后才可正常运行
但直接在现代虚拟机里运行如此古早的操作系统肯定会有缺少驱动及功能不完整的问题
在此,我通过各种渠道以及方法收集到了这些驱动,且于WindowsMe测试可用
完整安装之后即可消除全部的设备管理器中的叹号并添加完整USB2.0支持,且Sound Blaster 128可导入自选软波表

类别设备名版本号日期
NICPCNET4.51.0.02004/07/07
AICSound Blaster 128PCI5.12.01.20652001/10/26
USBPCI to USB Enhanced Host Controller4.90.3000.102003/09/26
USBUSB 2.0 Root Hub4.90.3000.102003/09/26
HIDPointing Device2001/06/11
GPUSVGA II10.7.0.02001/11/28
SYSVMCI Bus7.2.30.02009/07/16

版权归属
© Advanced Micro Devices, Inc 2004
© Creative Technology Ltd. 2001
© Microsoft Corporation 2003
© VMware, Inc. 2001-2009

点此下载ISO


最近突发奇想想看看ICOM的短波发射机的固件
就花了一晚上时间写了个算法解压了它
我作为懒人,肯定懒得写分析日志
所以给出两条提示:
1.找到正确的头,大胆删无用数据
2.Lempel–Ziv–Storer–Szymanski(LZSS)压缩算法
在此提供成功解压后的IC-7300的1.40版本固件,发布于2021年2月26日
点此下载
同时得知该设备的AP为RENESAS RZ-A1,是ARM架构,有空再用IDA看看再写下一篇分析日志(咕咕咕~)