当前位置: 首页 > news >正文

85.网游逆向分析与插件开发-物品使用-物品使用的逆向分析与C++代码的封装

内容参考于:易道云信息技术研究院VIP课

上一个内容:项目需求与需求拆解-CSDN博客

码云地址(ui显示角色数据 分支):https://gitee.com/dye_your_fingers/sro_-ex.git

码云版本号:453dd83d54140d2e1ee65c915ed2cede543f7400

代码下载地址,在 SRO_EX 目录下,文件名为:SRO_Ex-物品使用的逆向分析与C++代码的封装.zip

链接:https://pan.baidu.com/s/1W-JpUcGOWbSJmMdmtMzYZg

提取码:q9n5

--来自百度网盘超级会员V4的分享

HOOK引擎,文件名为:黑兔sdk.zip

链接:https://pan.baidu.com/s/1IB-Zs6hi3yU8LC2f-8hIEw

提取码:78h8

--来自百度网盘超级会员V4的分享

以 82.网游逆向分析与插件开发-背包的获取-装备栏数据与算法的C++还原-CSDN博客 它的代码为基础进行修改

选择从网络的地方去下手,因为网络这个东西是它肯定避不开的环节,这是一个非常好的下手点,网络游戏整个逆向,或者说但凡有统一,就是所有东西都会访问一个函数,这种反而会分析起来难度比其它的难度要低非常多。

然后梳理一下思路,首先使用物品这时发出ui的消息,这个时候它一定会换算成网络消息,然后网络消息会经过一个组合,然后经过一个加密,然后经过一个发送,这就是它的一个大概的情况,这整个流程里面,只有一个最好切入,就是发送这个地方最好切入,使用ui的地方消息太多了,处理起来肯定会很麻烦,然后组合什么的都是算法,这东西没有一个明确的点没有一个明确的特征所以找不着,然后到了发送的地方,就简单了,因为网络的发送就是围绕着send函数和wsasend函数或sendto等函数,所以可以对这几个函数下断点来回溯它整个过程,然后分析过程中有一个要点,就是分析的时候会发现一个问题,发现它用了send函数或wsasend函数,这个时候一路往回找,但是要在哪停呢?比如第一次找去找到跟ui相关的,跟ui相关的会看到跟消息有关的函数,然后接下来再往后,这个时候要随时观察函数的参数,只要在参数里发现可以辨别的东西,那这个东西就基本找到了,所以有几个东西是需要密切关注的,比如物品的指针,或者说数组它的序号等这些信息比较重要,所以要随时观察,什么时候出现了这些数据就很关键,就知道什么时候停了。

然后打开x96dbg下断点,首先是send函数

然后是sendto函数,sendto一般在聊天软件里用的比较多

然后WSASend函数,它可以实现iocp(iocp例子),它是异步的,在新的游戏里用的比较多

然后可以发现WSASend会触发断点,那基本上就可以确认是它了,然后它会不停的断下来,会有干扰

然后游戏不动它也会停下来,原因是,游戏为了保证安全它有心跳包,这个时候最好找到它的长度通过条件断点筛选掉,或者眼疾手快点,然后使用物品,使用一个药物,然后它的id是应该是5912或者5913,然后因为现在以及知道它背包的物品是一个指针的数组,所以如果服务器响应这个东西,就要告诉服务器要用哪个物品,所以应该会给服务器发送一个可以证明是哪一个物品的数据,如果是数组的话使用序号的可能性要大,然后下图红框位置的物品数组下标是22,然后也可能是5912或者5913,所以看到这几个数据要敏感

然后接下来眼疾手快一点使用物品,然后就断下来了

 然后断点住后,把断点取消掉,再往上跟否则它会乱

然后一直ctrl+f9,再按f8,大致的过一遍,看看到什么位置就过不去了,然后就会看到在下图红框位置就结束了,这说明在循环里,然后下图红框位置附近有Sleep函数,这个Sleep函数一般跟消息靠的比较近,现在就大概知道它是一个什么情况了,函数很长,然后接着往下看

这么长的函数该怎样处理?首先要分清楚它的一个结构,就是游戏它有各种操作,比如a操作使用物品,b操作走路,c操作心跳包,d操作使用技能,它们都会走到网络的部分发送数据,刚刚经历的一系列函数,假设a是使用物品,那么它有一部分是属于a使用物品的,它的前面还有ui管理或者消息管理的一部分,如果要精确的找到a的过程,才能去分析它,刚刚的一系列操作该怎样排除ui或者send呢?倒着分析的逻辑的话是不需要排除ui的,只需要排除网络的部分,不可能在WSASend函数分析使用物品的逻辑,所以该怎样排除WSASend函数?然后ABCD这四个操作它基本上是共用或者部分共用这个send函数,就是共用网络发送的部分,网络发送的函数它一定是由N个函数构成,也就是说在ABCD所有的操作它到最后都会跑到send函数里,如果现在处在A的操作里面就会只有A操作能触发,就比如走路它就一定不触发A操作,使用使能也不会触发A操作,只有使用物品触发A操作,所以通过这一点就可以很容易的定位到A操作,所以接下来重新回到WSASend函数里,ctrl+f9再按f8每按一次都在上一行代码(调用函数的位置)打断点,然后走路或者执行一个非使用物品的操作,看看是否还会触发断点,如果触发就接着在断点位置使用一次物品,然后继续往上跟(ctrl+f9再按f8这个操作),然后一路这样打断点做非使用物品的操作,最终来到下图位置0x860A43,它并不会被其它操作影响,只会在使用物品的时候断下来

但是这个函数并不怎样理想,它的参数看不懂,ecx的数据也看不懂,这没关系,因为游戏它组织数据的时候一定也是循序渐进的,所以就继续往前找,一定能找到一个能看懂的地方,这个时候才好切入

然后ctrl+f9再按f8来到上一层,关键点 0x74688F

然后它的参数0x85F640函数的入参,它有三个入参,通过0x85F640函数的返回也就是ret位置看出的它是ret c,所以是三个参数,然后通过下图可以看出其中一个参数是索引,使用的物品正好是22

然后使用第一个物品,eax的值是0,所以它是索引,然后0x85F640函数就是使用物品的函数,它是0x1256E3C类里的成员函数,这个0x1256E3C之前已经用C++封装过了,也就是SRO_Control类的成员函数

效果图:可以正常使用物品了

总结:

在盲分析的情况下,可以发现是非常需要依赖参数的,能看懂参数会省很大的劲,可以尝试在0x74688F位置往上跟一层,看看它的入参,看看它的触发机制,还有下图所示的物品栏,是不是也能通过 0x74688F 位置分析到

新加按钮:

GameBase.cpp文件的修改,修改了 Init函数

#include "pch.h"
#include "GameBase.h"GameBase* _pgamebase;void GameBase::Init()
{unsigned* addrRead = (unsigned*)0x1256E3C;SRO_Res = (PRes)0x1036518;SRO_Control = (PControl)addrRead[0];addrRead = (unsigned*)0x1037D3C;SRO_Player = (PAIM)addrRead[0];InitClassProc(&Res::_ReadTitle, 0x9A46C0);InitClassProc(&Res::_ReadItemTitle, 0x9A4640);InitClassProc(&Control::_NormalNotice, 0x848580);InitClassProc(&Control::_NetNotice, 0x844E40);InitClassProc(&Control::_ChatNotice, 0x844E80);InitClassProc(&Control::_GetPPack, 0x866140);InitClassProc(&Control::_UseItem, 0x85F640);InitClassProc(&ITEM::_GetItemRes, 0x995800);InitClassProc(&Pack::_GetPackPack, 0x7722C0);InitClassProc(&Pack::_GetEquipPack, 0x772300);}void GameBase::InitClassProc(LPVOID proc_addr, unsigned value)
{unsigned* uWrite = (unsigned*)proc_addr;uWrite[0] = value;
}GameBase::GameBase()
{_pgamebase = this;// Init();// 初始化机制,完成游戏与我们dll的对接
}

Control.h文件的修改,新加 PROC_D_D_D函数指针类型、_UseItem函数指针变量、UseItem函数声明

#pragma once
#include "SRO_String.h"
#include "Pack.h"
typedef class Control
{typedef PPack (Control::* PROC)();typedef void (Control::* PROC_PSROSTR)(PSROSTRING);typedef void (Control::* PROC_D_PWSTR_D_D)(int, wchar_t*, int, int);typedef void (Control::* PROC_D_D_D)(int, int, int);
public:static PROC _GetPPack;static PROC_PSROSTR _NormalNotice;static PROC_PSROSTR _NetNotice;static PROC_D_PWSTR_D_D _ChatNotice;static PROC_D_D_D _UseItem;
public:void NormalNotice(PSROSTRING _txt);void NetNotice(PSROSTRING _txt);void ChatNotice(wchar_t* _txt, int color=0xFFFFAEC3, int type1=0x3, int type2=0x1);void UseItem(int index, int p1 = -1, int p2 = -1);PPack GetPPack();
}*PControl;

Control.cpp文件的修改,新加 UseItem函数、_UseItem变量初始化

#include "pch.h"
#include "Control.h"Control::PROC Control::_GetPPack{};
Control::PROC_PSROSTR Control::_NormalNotice{};
Control::PROC_PSROSTR Control::_NetNotice{};
Control::PROC_D_PWSTR_D_D Control::_ChatNotice{};
Control::PROC_D_D_D Control::_UseItem{};void Control::NormalNotice(PSROSTRING _txt)
{(this->*_NormalNotice)(_txt);
}void Control::NetNotice(PSROSTRING _txt)
{(this->*_NetNotice)(_txt);
}/**type1 默认0x3type2 默认0x1
*/
void Control::ChatNotice(wchar_t* _txt, int color, int type1, int type2)
{(this->*_ChatNotice)(type1, _txt, color, type2);
}void Control::UseItem(int index, int p1, int p2)
{(this->*_UseItem)(index, p1, p2);
}PPack Control::GetPPack()
{return (this->*_GetPPack)();
}

CUIWnd_1.cpp文件的修改,新加OnBnClickedButton3函数,OnBnClickedButton3函数是Button3按钮的点击事件处理函数

// CUIWnd_1.cpp: 实现文件
//#include "pch.h"
#include "htdMfcDll.h"
#include "CUIWnd_1.h"
#include "afxdialogex.h"
#include "extern_all.h"// CUIWnd_1 对话框IMPLEMENT_DYNAMIC(CUIWnd_1, CDialogEx)CUIWnd_1::CUIWnd_1(CWnd* pParent /*=nullptr*/): CDialogEx(IDD_PAGE_1, pParent)
{}CUIWnd_1::~CUIWnd_1()
{
}void CUIWnd_1::DoDataExchange(CDataExchange* pDX)
{CDialogEx::DoDataExchange(pDX);DDX_Control(pDX, IDC_LIST1, lstPack);
}BEGIN_MESSAGE_MAP(CUIWnd_1, CDialogEx)ON_BN_CLICKED(IDC_BUTTON1, &CUIWnd_1::OnBnClickedButton1)ON_BN_CLICKED(IDC_BUTTON2, &CUIWnd_1::OnBnClickedButton2)ON_BN_CLICKED(IDC_BUTTON3, &CUIWnd_1::OnBnClickedButton3)
END_MESSAGE_MAP()// CUIWnd_1 消息处理程序void CUIWnd_1::OnBnClickedButton1()
{// int count = _pgamebase->SRO_Control->GetPPack()->GetPackBack()->PackCount();CString tmp;// tmp.Format(L"%d", count);// AfxMessageBox(tmp);PBackPack _PackBack = _pgamebase->SRO_Control->GetPPack()->GetPackBack();lstPack.ResetContent();for (int i = 0; i < _PackBack->PackCount(); i++){PITEM item = _PackBack->GetItem(i);if ((item != NULL) && (item->Type)) {tmp.Format(L"[%s][数量:%d][耐久:%d/%d]\n", item->GetNameByWide(), item->Count, item->Durabillty, item->MaxDurabillty);lstPack.AddString(tmp);}}}void CUIWnd_1::OnBnClickedButton2()
{// int count = _pgamebase->SRO_Control->GetPPack()->GetPackBack()->PackCount();CString tmp;// tmp.Format(L"%d", count);// AfxMessageBox(tmp);PEquipPack _PackBack = _pgamebase->SRO_Control->GetPPack()->GetEquipBack();lstPack.ResetContent();for (int i = 0; i < 13; i++){PITEM item = _PackBack->GetItem((EquipType)i);if ((item != NULL) && (item->Type > 0)) {tmp.Format(L"[%s][数量:%d][耐久:%d/%d]\n", item->GetNameByWide(), item->Count, item->Durabillty, item->MaxDurabillty);lstPack.AddString(tmp);}}
}void CUIWnd_1::OnBnClickedButton3()
{_pgamebase->SRO_Control->UseItem(12);
}

相关文章:

85.网游逆向分析与插件开发-物品使用-物品使用的逆向分析与C++代码的封装

内容参考于&#xff1a;易道云信息技术研究院VIP课 上一个内容&#xff1a;项目需求与需求拆解-CSDN博客 码云地址&#xff08;ui显示角色数据 分支&#xff09;&#xff1a;https://gitee.com/dye_your_fingers/sro_-ex.git 码云版本号&#xff1a;453dd83d54140d2e1ee65c9…...

JVM系列——垃圾收集器

对象存活判断 引用计数法 在对象中添加一个引用计数器&#xff0c;每当有一个地方引用它时&#xff0c;计数器值就加一&#xff1b;当引用失效时&#xff0c;计数器值就减一&#xff1b;任何时刻计数器为零的对象就是不可能再被使用的。 可达性分析算法 通过一系列称为“GC …...

那些年与指针的情仇(二)---二级指针指针与数组的那点事函数指针

关注小庄 顿顿解馋(&#xff61;&#xff65;∀&#xff65;)&#xff89;&#xff9e; 欢迎回到我们的大型纪录片《那些年与指针的爱恨情仇》&#xff0c;在本篇博客中我们将继续了解指针的小秘密&#xff1a;二级指针&#xff0c;指针与数组的关系以及函数指针。请放心食用&a…...

APPCRASH 文件管理器不停重启问题记录 (最后reinstall解决)以及重装后到底会怎样

问题诱因&#xff1a; 时间 2024年1月 &#xff08;严重怀疑&#xff0c;但无法实锤&#xff09; 是我不知道什么时候&#xff08;应该是近期&#xff09;安装了powertoy的预览版&#xff0c;系统不知道什么时候&#xff08;也应该是这两天&#xff09;安装了微软出品的PC man…...

导出excel功能,前端的解决方案

import { utils, writeFileXLSX } from xlsx // 导出excel async exportToExcel() {// 获取要导出的业务数据&#xff08;这里的接口自己改成实际使用的接口&#xff09;const res await getRuleListAPI(this.params)// 表头英文字段key&#xff08;这里的数据改成接口返回的实…...

【lesson24】MySQL索引的理解

文章目录 建立测试表插入多条记录查看插入结果中断一下---为何IO交互要是 Page重谈page理解单个page理解多个page 页目录单页情况多页情况复盘一下InnoDB 在建立索引结构来管理数据的时候&#xff0c;其他数据结构为何不行&#xff1f;B vs B聚簇索引 VS 非聚簇索引 建立测试表…...

Oracle篇—分区索引的重建和管理(第三篇,总共五篇)

☘️博主介绍☘️&#xff1a; ✨又是一天没白过&#xff0c;我是奈斯&#xff0c;DBA一名✨ ✌✌️擅长Oracle、MySQL、SQLserver、Linux&#xff0c;也在积极的扩展IT方向的其他知识面✌✌️ ❣️❣️❣️大佬们都喜欢静静的看文章&#xff0c;并且也会默默的点赞收藏加关注❣…...

前端大厂面试题探索编辑部——第一期

目录 简介 题目 单选题 题解 A选项的Content-Security-Policy http-equiv属性 content属性 B选项的CSRF 使用CSRF Token 验证Referer和Origin头 C选项的HTTP Only D选项的防止SQL注入 输入验证和转义 简介 这个是一个长系列&#xff0c;我会以题目为导向&#xff…...

图扑 HT UI 5.0 全新升级,开箱即用!

为顺应数字时代的不断发展&#xff0c;图扑 HT UI 5.0 在原有功能强大的界面组件库的基础上进行了全面升级&#xff0c;融入了更先进的技术、创新的设计理念以及更加智能的功能。HT UI 5.0 使用户体验更为直观、个性化&#xff0c;并在性能、稳定性和安全性等方面达到新的高度。…...

数据结构----链表介绍、模拟实现链表、链表的使用

文章目录 1. ArrayList存在的问题2. 链表定义2.1 链表的概念及结构2.2 链表的组合类型 3. 链表的实现3.1 单向、不带头、非循环链表的实现3.2 双向、不带头节点、非循环链表的实现 4.LinkedList的使用4.1 什么是LinkedList4.2 LinkedList的使用4.2.1. LinkedList的构造4.2.2. L…...

微信小程序如何控制元素的显示和隐藏

目录 方式一:display 方式二:wx:if 有时在微信小程序元素的显示需要通过特定的条件,比如组件的显示,通常需要在主界面有指定操作。可以通过以下两种方式控制元素的显示和隐藏。 方式一:display 在wxml或者wxss中设置display样式可以控制元素显示情况,元素默认显示,可…...

解决ssh: connect to host github.com port 22: Connection timed out

当连接 GitHub 时无法连接到 22 端口时&#xff0c;可以尝试将端口更换为 443 首先&#xff0c;尝试使用以下命令从 GitHub 克隆仓库&#xff1a; $ git clone gitgithub.com:xxxxx/xxxx.git my-awesome-proj如果出现以下错误信息&#xff1a; Cloning into my-awesome-proj…...

idea 创建 spring boot

1.创建步骤 2. 编码添加 2.1 这是自动生成的启动函数 package com.example.comxjctest4;import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication public class Application {publi…...

【智能家居入门之微信小程序控制下位机】(STM32、ONENET云平台、微信小程序、HTTP协议)

实现微信小程序控制单片机外设动作 一、使用ONENET可视化组件控制单片机外设动作二、使用微信小程序控制单片机外设动作三、总结 本篇博客话接上文&#xff1a; https://blog.csdn.net/m0_71523511/article/details/135892908 上一篇博客实现了微信小程序接收单片机上传的数据…...

07.领域驱动设计:了解3种常见微服务架构模型的对比和分析

目录 1、概述 2、整洁架构 3、六边形架构 4、三种微服务架构模型的对比和分析 5、从三种架构模型看中台和微服务设计 5.1 中台建设要聚焦领域模型 5.2 微服务要有合理的架构分层 5.2.1 项目级微服务 5.2.2 企业级中台微服务 5.3 应用和资源的解耦与适配 6、总结 1、概…...

设计模式——模板方法模式(Template Method Pattern)

概述 模板方法模式&#xff1a;定义一个操作中算法的框架&#xff0c;而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。模板方法模式是一种基于继承的代码复用技术&#xff0c;它是一种类行为型模式。模板方法模式是结…...

07. STP的基本配置

文章目录 一. 初识STP1.1. STP概述1.2. STP的出现1.3. STP的作用1.4. STP的专业术语1.5. BPDU的报文格式1.6. STP的选择原则&#xff08;1&#xff09;选择根桥网桥原则&#xff08;2&#xff09;选择根端口原则 1.7. 端口状态1.8. STP报文类型1.9. STP的收敛时间 二. 实验专题…...

oracle分区范围修改与数据迁移处理

背景 由于对应用上线后流量越来越大&#xff0c;原来的按年自动分区性能跟不上&#xff0c;因此决定改成按月自动分区&#xff0c;同时将原有分区数据重新迁移到新的分区 步骤 修改表分区为一个月一个分区 alter table my_table set INTERVAL (NUMTOYMINTERVAL(1, month));…...

回归预测 | Matlab实现CPO-LSSVM【24年新算法】冠豪猪优化最小二乘支持向量机多变量回归预测

回归预测 | Matlab实现CPO-LSSVM【24年新算法】冠豪猪优化最小二乘支持向量机多变量回归预测 目录 回归预测 | Matlab实现CPO-LSSVM【24年新算法】冠豪猪优化最小二乘支持向量机多变量回归预测效果一览基本介绍程序设计参考资料 效果一览 基本介绍 1.Matlab实现CPO-LSSVM【24年…...

SeaTunnel Web安装 一把成

安装相关jar包&#xff0c;以及SeaTunnel 和Web 打成的包&#xff0c;可以直接使用&#xff0c;但是需要安装MySQL客户端的分享&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1qrt1RAX38SgIpNklbQJ7pA 提取码&#xff1a;0kmf 1. 环境准备 环境名称版本系统环境C…...

对话泛能网程路:能源产业互联网,行至中程

泛能网的能源产业互联网的标杆价值还不仅于此。其在产业互联之外&#xff0c;也更大的特殊性在于其也更在成为整个碳市场的“辅助运营商”&#xff0c;包括电力、碳等一系列被泛能网帮助企业改造和沉淀的要素资产&#xff0c;都在构成着碳交易市场的未来底层。 这恰是产业互联…...

Doris简介及单机部署(超详细)

文章目录 一、Doris简介1、Doris介绍2、Doris架构 二、Doris单机部署&#xff08;Centos7.9&#xff09;1、下载Doris2、准备环境3、安装部署3.1 创建存储目录3.2 配置 FE3.3 启动 FE3.4 查看 FE 运行状态3.5 配置 BE3.6 启动 BE3.7 添加 BE 节点到集群3.8 查看 BE 运行状态3.9…...

Pytest 识别case规则

一、Python测试框架&#xff0c;主要特点有以下几点&#xff1a; 简单灵活&#xff0c;容易上手&#xff1b;支持参数化&#xff1b;能够支持简单的单元测试和复杂的功能测试&#xff0c;还可以用来做selenium/appnium等自动化测试、接口自动化测试&#xff08;pytestrequests…...

gorm+mysql查询/修改json列相关操作汇总

目录 具体操作 1&#xff0c;查询JSON段落指定key的值是否有等于value的 或 指定keyvalue的数据记录 2&#xff0c;查询JSON段落中price>19的记录 3&#xff0c;查询JSON段中key为k0的记录 4、JSON段落中提取指定键值对到指定结构 5&#xff0c;查询JSON数组是否包含…...

CMake-Cookbook 第0章 配置环境

文章目录 第0章 配置环境0.1 获取代码0.2 Docker镜像0.3 安装必要的软件0.3.1 获取CMake0.3.2 编译器0.3.3 自动化构建工具0.3.4 Python0.3.5 依赖软件0.3.5.1 BLAS和LAPACk0.3.5.2 消息传递接口(MPI)0.3.5.3 线性代数模板库0.3.5.4 Boost库0.3.5.5 交叉编译器0.3.5.6 ZeroMQ, …...

优质硬盘检测工具SMART Utility,保障您的Mac数据安全

在日常使用Mac电脑的过程中&#xff0c;我们经常会存储大量的重要数据&#xff0c;如照片、文档、视频等。然而&#xff0c;硬盘故障却是一件令人头疼的事情&#xff0c;可能会导致数据丢失、系统崩溃等严重后果。为了保障您的数据安全&#xff0c;我们推荐一款专业的硬盘检测工…...

Spring: alibaba代码规范校验工具checkstyle

文章目录 一、idea配置checkstyle插件二、激活CheckStyle三、配置自动格式化功能四、使用代码格式化 一、idea配置checkstyle插件 下载 Intellij IDEA Checkstyle 插件&#xff1a;File -> setting -> plugin通过关键字CheckStyle-IDEA搜索并安装。 安裝完成后重启idea…...

c++线程thread示例

本文章记录c创建线程&#xff0c;启动线程和结束线程的代码。 需要注意&#xff0c;编译时需要添加-lpthread依赖。 代码&#xff1a; ThreadTest.h #ifndef TEST_THREAD_TEST_H #define TEST_THREAD_TEST_H#include <thread> #include <mutex>class ThreadTes…...

Compose | UI组件(十一) | Spacer - 留白

文章目录 前言Spacer组件的参数说明Spacer组件的使用 总结 前言 Spacer组件是让两组件之间留有空白间隔 Spacer组件的参数说明 Spacer只有一个修饰符&#xff0c;修饰留空白的大小和比例&#xff0c;颜色 Spacer(modifier: Modifier)Spacer组件的使用 Row {Box(modifier M…...

PyTorch的nn.Module类的详细介绍

在PyTorch中&#xff0c;nn.Module 类是构建神经网络模型的基础类&#xff0c;所有自定义的层、模块或整个神经网络架构都需要继承自这个类。nn.Module 类提供了一系列属性和方法用于管理网络的结构和训练过程中的计算。 1. PyTorch中nn.Module基类的定义 在PyTorch中&#xff…...