华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

admin 2024年4月2日00:27:49评论4 views字数 3000阅读10分0秒阅读模式

作者坛账号:SNSD99

0.前言
最近好奇这个充电保护程序为什么可以控制最高充电百分比,所以我想分析一下。
该程序适用于华硕飞行堡垒fx63vd7700型号,如果适用华硕其它型号的可以试试看。
注意该充电保护程序不适用于其它品牌、或华硕其它型号的笔记本电脑。
这个软件的界面如下图所示。
模式有三种:完整充电模式、平衡保养模式、最佳保养模式。三种模式限制充电百分比分别为100%,80%、和60%。
华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

目录如下:
华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

1.x64dbg动态调试
双击BhcApp.exe,启动充电保护软件。x64dbg附加“BhcMgr.exe”。
DeviceIoControl处插入断点,这个函数用于和设备通信,随便选中一个模式然后点确定就会触发断点。
例如我选中的“平衡保养模式”。
调用堆栈如下图所示。
华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

DeviceIoControl的参数如下:

BOOL DeviceIoControl(  [in]                HANDLE       hDevice,  [in]                DWORD        dwIoControlCode,  [in, optional]      LPVOID       lpInBuffer,  [in]                DWORD        nInBufferSize,  [out, optional]     LPVOID       lpOutBuffer,  [in]                DWORD        nOutBufferSize,  [out, optional]     LPDWORD      lpBytesReturned,  [in, out, optional] LPOVERLAPPED lpOverlapped);

回到DeviceIoControl上层函数“sub_321C90”。观察DeviceIoControl的入参:
华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

HANDLE hDevice = 0x274
DWORD dwIoControlCode = 0x22240C
LPVOID lpInBuffer = 0xB7F010
DWORD nInBufferSize = 0x10
LPVOID lpOutBuffer = 0x93F238
DWORD nOutBufferSize = 0x400
LPDWORD lpBytesReturned = 0x93F234
LPOVERLAPPED lpOverlapped = 0

1.1 查看缓冲区lpInBuffer: 0xB7F010
如下图所示为缓冲区内容,大小0x10字节。
华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

这个可以视为一个结构体。代码如下。

struct BatteryIOCtlInfo{        DWORD head; // 头部        DWORD nextSize; // 后续结构体成员大小        DWORD num2; // 未知四字节数,固定为0x120057        DWORD perecent; // 充电百分比,0x50为80%,0x3C为60,0x64为100%};

结构体各成员值填写为:

BatteryIOCtlInfo btinfo;btinfo.head = 0x53564544;btinfo.nextSize=8;btinfo.num2 = 0x120057;// 0x3c 60%// 0x50 80%// 0x64 100%btinfo.perecent = 0x3c;

1.2 输出缓冲区lpOutBuffer: 0x93F238
只有头四节被填充0x1,剩余的0x400 - 4个字节均为0.
华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

输出缓冲区里的内容没有什么特别的,只需保证有输出缓冲区,以及该缓冲区有0x400字节大小即可。

2.IDA静态分析
以上分析了DeviceIoControl的入参,但是还不知道设备句柄是怎么获取的。
进入sub_321C90的代码段,在IDA为“sub_401C90”,00401D0C为调用DeviceIoControl的语句。
华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

选中"hDevice",按下X键看看哪个语句写入了这个hDevice。如下图所示。(Type:r表示读取read,w表示写入write)
华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

进入了函数sub_401D70。
华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

原来是CreateFileW打开(电池)设备的句柄。

CreateFileW参数如下:

HANDLE CreateFileW(  [in]           LPCWSTR               lpFileName,  [in]           DWORD                 dwDesiredAccess,  [in]           DWORD                 dwShareMode,  [in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,  [in]           DWORD                 dwCreationDisposition,  [in]           DWORD                 dwFlagsAndAttributes,  [in, optional] HANDLE                hTemplateFile);

LPCWSTR lpFileName:"\.ATKACPI"
DWORD dwDesiredAccess: 0xC0000000 ( GENERIC_READ | GENERIC_WRITE == 0xC0000000 )
DWORD dwShareMode: 0x3 (FILE_SHARE_READ | FILE_SHARE_WRITE == 0x3)
LPSECURITY_ATTRIBUTES lpSecurityAttributes: NULL
DWORD dwCreationDisposition: 0x3 (OPEN_EXISTING == 3)
DWORD dwFlagsAndAttributes: NULL
HANDLE hTemplateFile: NULL

3. 代码复现
因此控制笔记本最高充电百分比的C++代码如下:

#include <stdio.h>#include <stdlib.h>#include <Windows.h> struct BatteryIOCtlInfo{    DWORD head;    DWORD nextSize;    DWORD num2;    DWORD perecent;}; int main(int argc, char** argv, char** envp){    // GENERIC_READ | GENERIC_WRITE == 0xC0000000    // FILE_SHARE_READ | FILE_SHARE_WRITE == 0x3    // OPEN_EXISTING == 3    HANDLE hhh = CreateFileW        (            L"\\.\ATKACPI",             GENERIC_READ | GENERIC_WRITE,            FILE_SHARE_READ | FILE_SHARE_WRITE,             NULL,            OPEN_EXISTING,            NULL,            NULL        );    //    BatteryIOCtlInfo btinfo;    btinfo.head = 0x53564544;    btinfo.nextSize=8;    btinfo.num2 = 0x120057;    // 0x3c 60%    // 0x50 80%    // 0x64 100%    btinfo.perecent = 0x3c;  // 修改此处数值    // out buffer    void* out_buf = malloc(0x400);    DWORD returnBytes = 0;    //    DeviceIoControl(        hhh,        0x22240C,        &btinfo,        sizeof(btinfo),        out_buf,        0x400,        &returnBytes,        NULL);    CloseHandle(hhh);    free(out_buf);    return 0;}

经测试可以修改最高充电百分比,但是只能有60%,80%和100%三种数值。如果修改为其它数值,则默认最高充电百分比为100%。

-官方论坛

www.52pojie.cn

原文始发于微信公众号(白帽子):华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年4月2日00:27:49
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   华硕fx63vd7700充电保护程序“ASUS Battery Health Charging”逆向分析https://cn-sec.com/archives/2622223.html

发表评论

匿名网友 填写信息