[Windows] 分析使用nodejs启动NTQQ | 祭夜の咖啡馆
  • 欢迎光临,这个博客颜色有点多

[Windows] 分析使用nodejs启动NTQQ

猿之力 msojocs 1周前 (10-05) 27次浏览 已收录 0个评论 扫描二维码
文章目录[隐藏]

前言

上篇实现了Linux平台使用nodejs启动的分析,这篇是Windows的,相对更麻烦了。

[Linux] 分析使用nodejs启动NTQQ

文章目录[隐藏] 前言 分析 总结 前言 自己有做一个机器人框架:https://github.com/pro […]

分析

一样的,在wrapper.node目录建立test.js,执行一下看看情况:
[Windows] 分析使用nodejs启动NTQQ

文件没找到,但是没说什么文件,抽象windows。。。。

那只能借助工具,来看程序在读取什么文件,然后失败的是什么文件。

Process Monitor

设置过滤条件:进程名包含node;启动记录,然后执行一下程序。

可以看到QQNT.dll文件在当前目录没找到,然后去系统环境的目录找,一直都没找到;

手动搜索,在版本目录找到了,补一下。
[Windows] 分析使用nodejs启动NTQQ

继续按照这个方式,补充ffmped.dll

持续到提示发生变化:
[Windows] 分析使用nodejs启动NTQQ

对比Linux,可以发现并没有手动补充函数的操作,这是因为两个平台的加载逻辑不一样;

Linux是类似于普通nodejs加载模块的逻辑,但是Windows不一样,下面是Windows的简图:
[Windows] 分析使用nodejs启动NTQQ

根据图示,Windows的node环境是在库里面的,间接调用的。

于是,可行的方法是伪造一个让程序以为是node环境的状况,让程序执行;

简单说就是伪造QQNT.dll,然后把函数调用转发给真正的node环境。

大致流程:
1. 原版QQNT.dll改名为QQNT.original.dll
2. 伪造一个QQNT.dll,直接转发调用给QQNT.original.dll
3. 修改QQNT.dll,把能转发的函数全转到node.exe
4. 尽可能脱离QQNT.original.dll(理想情况)

伪造QQNT.dll

我在尝试了aheadlib伪造后,发现这个工具不支持C++复杂符号的导出,放弃了;

转头找AI去了。。。。

导出表处理

首先,Windows加载dll的时候会严格校验导出表,如有不一样,就会报错,所以需要获取QQNT.dll的完全导出表。

使用mingw64环境的gendef获取导出定义QQNT.def;这个去网上找教程,很快。

然后,在导出表基础上做转发修改:

导出的形式:
Cr_z_adler32

修改为:
Cr_z_adler32=QQNT.original.dll.Cr_z_adler32

设置库的定义:
set(QQNT_DEF ${PROJECT_SOURCE_DIR}/src/qqnt/qqnt.def)
if(EXISTS ${QQNT_DEF})
        if(MSVC)
            set_target_properties(QQNT PROPERTIES LINK_FLAGS "/DEF:${QQNT_DEF}")
    else()
        target_link_options(QQNT PRIVATE "-Wl,--input-def=${QQNT_DEF}")
    endif()
else()
    message(FATAL_ERROR "QQNT.def not found")
endif()

还需要把原导入表做链接:

execute_process(COMMAND
    ${CMAKE_AR} /def:QQNT.def /out:QQNT.lib /machine:x64 ${CMAKE_STATIC_LINKER_FLAGS}
    WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/thirds/external
    COMMAND_ERROR_IS_FATAL ANY
)
set(QQNT_LIB ${PROJECT_SOURCE_DIR}/thirds/external/QQNT.lib)
if(EXISTS ${QQNT_LIB})
    target_link_libraries(QQNT PRIVATE ${QQNT_LIB})
else()
    message(FATAL_ERROR "QQNT.lib not found")
endif()

按此规则完成全部修改,编译,执行;

成功的话就是错误提示不变。

调整转发规则

有点复杂,记不清了,这里简略了许多

获取wrapper.node的导入表,先把QQNT.dll中记录的函数做修改:

把QQNT.original.dll替换为node.exe,编译执行;

执行后,直接崩溃,猜测是函数交互之间底层还有交互;

于是把所有的都替换了。

报错了,看起来是某个函数node.exe里面没有:
[Windows] 分析使用nodejs启动NTQQ

根据wrapper.node的导入表检查它用到的函数哪个是node.exe没有的。

立马就找到了,IsEnvironmentStopping这个函数没有:
[Windows] 分析使用nodejs启动NTQQ

实现一下,然后在def替换转发目标:

// 这个函数,node没有自带
// Wrapper for mangled C++ symbol: ?IsEnvironmentStopping@node@@YA_NPEAVIsolate@v8@@@Z
// Original signature: bool IsEnvironmentStopping(node::Isolate*) (approx)
extern "C" __declspec(dllexport) int My_IsEnvironmentStopping_node(void* isolate)
{
    spdlog::info("My_IsEnvironmentStopping_node called");
    return 0;
}

// def
?IsEnvironmentStopping@node@@YA_NPEAVIsolate@v8@@@Z=My_IsEnvironmentStopping_node

欸,成功了:
[Windows] 分析使用nodejs启动NTQQ

总结

windows处理相比Linux复杂许多,中途报错一直没变化,快放弃了;

然后睡了一觉,想到拿一个函数少的做一下尝试(“QBar.dll”),尝试之后懂了整体流程,然后再去改的QQNT.dll这才成功的。


祭夜の咖啡馆 , 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:[Windows] 分析使用nodejs启动NTQQ
喜欢 (0)
[1690127128@qq.com]
分享 (0)
发表我的评论
取消评论
OwO表情
贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址