53.x86游戏实战-XXX获取人物状态

news2024/9/20 14:42:11

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动!

本次游戏没法给

内容参考于:微尘网络安全

工具下载:

链接:https://pan.baidu.com/s/1rEEJnt85npn7N38Ai0_F2Q?pwd=6tw3

提取码:6tw3

复制这段内容后打开百度网盘手机App,操作更方便哦

上一个内容:52.x86游戏实战-XXX获取房间坐标

上一个内容里得到了人物所在的当前位置(当前副本内所在的房间),然后有一个情况,角色可能不在副本内这种情况副本内瞬移的代码就不能让它执行,所以要找一下一个标志位,最好这个标志位代表了角色在城镇、在选择副本、在副本内容等

首先打开游戏,打开CE并附加到游戏

然后使用未知的初始值进行扫描

首次扫描完

首次扫描完之后在使用未变动的扫描

然后上方的图玩家角色是在城镇里,然后让角色进入选择地图界面(选择地图状态),然后使用变动的数值再次扫描

一直重复上方的操作(就是切换角色状态,使用变动的数值,不切换角色状态使用未变动的数值)

然后到了3千多不好筛选了,这个状态推测它是0到10之间的一个数,然后使用值介于...两者之间再次扫描

然后还有144个

144个还是很多,然后继续使用未变动和变动的方式继续筛选

然后它又有了超过10 的数字了,所以再次使用介于两者之前的方式再次扫描

使用介于两者之前的方式再次扫描

经过多次重复改变状态(进入副本、选择副本、在城镇、角色选择、大区选择)扫描,最终剩下这几个

然后经过切换状态观察它们的值,最终确定0x2EA12E78和0x0019EAB0是标志位,因为它俩的值,在选择角色界面它俩的值是0,进入城镇它俩的值是1,进入选择副本界面它俩的值是2,进入副本之后它俩的值是3,然后在下图选择频道界面0x2EA12E78和0x0019EAB0的值是6,然后上图蓝框里的值也是6,所以可以确定蓝框里的不是状态了,然后上图绿框像是一个次数,每次切换状态的时候它会加1,所以现在状态找到了,接下来开始找它俩的基址

然后0x0019EAB0它的值更新的很慢,所以状态的值就只剩下0x2EA12E78了

然后在打开OD之前先处理一下检测,过检测

然后打开OD并附加游戏,然后在下图输入dd 0x2EA12E78

然后下一个硬件访问断点

然后来到下图位置,ecx+0x28位置访问了状态

然后取消断点

然后CTRL+F9,来到下图位置

然后在下图位置打断点

然后断点住之后在下图红框位置输入dd ecx+0x28,确认一下值是不是状态,如下图 ecx+0x28的值是状态的值

然后开始找ecx的值哪来的,ecx最近一次赋值是来自于esi,在下图断点查看ecx的值是不是来自于esi

然后按F8,发现ecx的值确实来自于esi,所以接下来找esi的值来自哪

esi的值来自于ecx,ecx来自于上一层

然后在下图红框位置打断点

断点住之后

然后取消断点

然后按CTRL+F9,看到ecx的值来自于0x1A5FB4C

然后在下图红框位置输入dd [[0x1A5FB4C]+0x14]+0x28,然后就找到了状态地址,然后写到C++里

C++代码:

效果图:

本次修改的代码很少,所以不提单到百度网盘了

MyStrust.cpp文件的内容:修改了 InitMy函数

#include "pch.h"
#include "MyStrust.h"

void MyStrust::InitMy()
{
	//  [[0x1AB7CDC]+0x258] 名字
	/*
		*这个符号表示地址,在c++中被称为指针或指针类型
		int表示4字节数字
		int*就表示指针类型的int
		(int*)0x1AB7CDC;这样表示0x1AB7CDC地址里的内容是4字节的数字
	*/
	int* address = (int*)0x1AB7CDC;
	/*
		取出地址中的值,也就是取出0x1AB7CDC里的内容
		*address这样在左边只写一个*表示取内存地址里的值
		也就是取address它的值,address是0x1AB7CDC,也就是取0x1AB7CDC它的值

	*/
	int addressValue = *address;
	/*
		(*(int*)addressValue)意思是
		把addressValue转成int*,也就是把
		addressValue的值当成内存地址,addressValue的值现在是[0x1AB7CDC]+0x258这个
		现在这个地址里面的值是名字的地址,所以在左边加了一个*让把名字的地址去除了出来
		取出来之后就得到了名字,名字是UNICODE类型,UNICODE又被称为宽字节,宽字节的数据是用两个字节描述一个文字或字母
		在c++里wchar_t类型就是UNICODE
		然后在c++中名字这种数据被称为字符串,如果要用字符串必须用指针类型也就是wchar_t*
		右边加上*让wchar_t变成指针类型的wchar_t,才能在c++中使用字符串

	*/
	this->My.Name = (wchar_t*)(*(int*)(addressValue+0x258));
	// 一般函数名后面是W就表示有UNICODE,也就是要用宽字节
	// OutputDebugStringW(this->My.Name);
	// L""这两个"之间表示字符串,L""表示这个字符串是宽字节(使用Unicode编码)
	call_logW(L"wetool:人物姓名=%ws,测试=%ws", this->My.Name,L" 52am");
	//  [[0x1AB7CDC]+0x18C]x坐标
	//  [[0x1AB7CDC]+0x190]y坐标
	/*
		取出地址中的值,也就是取出0x1AB7CDC里的内容
		*address这样在左边只写一个*表示取内存地址里的值
		也就是取address它的值,address是0x1AB7CDC,也就是取0x1AB7CDC它的值

	*/
 
	this->My.X= *(float*)(addressValue + 0x18C);
	this->My.Y = *(float*)(addressValue + 0x190);
	char buf[256] = { 0 };
	// 拼接文字,%f表示拼接一个小数(单浮点数)
	sprintf(buf, "wetool:x=%f;y=%f", this->My.X, this->My.Y);
	OutputDebugStringA(buf);

	// [[0x1AB7CDC]+0x36A0]血量
	this->My.Blood = *(int*)(addressValue + 0x36A0);
	// 拼接文字,%d表示拼接一个整数(32位的整数)
	sprintf(buf, "wetool:血量 = %d", this->My.Blood);
	OutputDebugStringA(buf);

	My.RoomX = ReadDword(ReadDword(ReadDword(ReadDword(0x1A5FB18) + 0x20A050) + 0x8C) + 0x610);
	My.RoomY = ReadDword(ReadDword(ReadDword(ReadDword(0x1A5FB18) + 0x20A050) + 0x8C) + 0x614);
	My.State = ReadDword(ReadDword(ReadDword(0x1A5FB4C) + 0x14) + 0x28);
	call_logA("wetool:副本内x坐标:%d,副本内y坐标:%d,State:%d", My.RoomX, My.RoomY, My.State);

}

void MyStrust::UseObject(DWORD object)
{
	object += 3; // 背包物品序号
	/*
	  try的作用
		如果
		__asm {
			pushad
			push object
			mov ecx, 0x1A5FB24 // 背包基址
			mov ecx, [ecx]
			mov eax, 0x7B9130 // 使用物品的函数地址
			call eax
			popad
		}
		这个代码运行过程中出现错误了,我不会让游戏崩溃,出现错误之后会执行
		catch (...) {
			OutputDebugStringA("MyStrust::UseObject error");
		}
		这个catch里面的代码,现在也就是执行OutputDebugStringA("MyStrust::UseObject error");这一行
	*/
	try { 
		__asm {
			pushad
			push object
			mov ecx, 0x1A5FB24 // 背包基址
			mov ecx, [ecx]
			mov eax, 0x7B9130 // 使用物品的函数地址
			call eax 
			popad
		}
	}
	catch (...) {
		OutputDebugStringA("MyStrust::UseObject error");
	}
}

void MyStrust::ChangeBlooad(int v)
{
	try {
		__asm {
			pushad
			push 0
			push 0
			push 0
			push v
			mov ecx, 0x1AB7CDC // 里面有我们玩家角色数据的基址
			mov ecx, [ecx]
			mov eax, 0x8174E0 // 修改血量的函数地址
			call eax
			popad
		}
	}
	catch (...) {
		OutputDebugStringA("MyStrust::ChangeBlooad error");
	}
}

void MyStrust::NewChangeBlooad(DWORD nEcx)
{
	try {
		__asm {
			pushad
			push 0
			push 0
			push 0
			push 0
			mov ecx, nEcx
			mov eax, 0x8174E0 // 修改血量的函数地址
			call eax
			popad
		}
	}
	catch (...) {
		OutputDebugStringA("MyStrust::NewChangeBlooad error");
	}
}

// 遍历怪物列表函数,加吸怪
void MyStrust::FindMaster()
{
	wchar_t* Tmp1;
	/* 
		[[[[[0x1A5E258]+3*4+0xA8]+0x14]+0x88]+0x10]
		下方 ReadDword 函数通过 [[[[[0x1A5E258]+3*4+0xA8]+0x14]+0x88]+0x10] 这个取值算法得到附近列表(怪物列表)
	*/
	DWORD Tmp = ReadDword(ReadDword(ReadDword(ReadDword(ReadDword(0x1A5E258) + 0x3 * 4 + 0xA8) + 0x14) + 0x88) + 0x10);
	if (Tmp != 0) {// 如果是0说明没有找到怪物列表
		for (size_t i = 0; i < 100; i++)// 这里的100是随便写的
		{
			if (ReadDword(Tmp + i * 4)>0 && (ReadDword(ReadDword(Tmp + i * 4) + 0x90) == 0x211)) {
			//if (ReadDword(Tmp + i * 4)>0) {
				Tmp1 = (wchar_t*)ReadDword(ReadDword(Tmp + i * 4) + 0x258); // 0x258位置是名字
				if (Tmp1 == 0) {// 如果是0说明没有名字
					 //call_logW(L"wetool:NULL\n");
					 this->masterNum.Name[i] = L"";
				}
				else {
					/*
						打印名字到 Dbgview.exe,其中 wetool这个是为了过滤 Dbgview.exe打印的一些跟我们不相关的日志

					*/
					//call_logW(L"wetool:%ws\n", Tmp1);
					this->masterNum.Name[i] = Tmp1;
				}
				// 血量与玩家角色不是一个位置,可以在修改血量的位置追,这个不重要,后面有机会再找
				//masterNum.Blood[i] = ReadDword(ReadDword(Tmp + i * 4) + 0x90); 
				this->masterNum.type[i] = ReadDword(ReadDword(Tmp + i * 4) + 0x90);
				this->masterNum.x[i] = ReadFloat(ReadDword(Tmp + i * 4) + 0x18C);
				this->masterNum.y[i] = ReadFloat(ReadDword(Tmp + i * 4) + 0x190);
				
				this->masterNum.x[i] = this->My.X;
				this->masterNum.y[i] = this->My.Y;
				this->masterNum.Object[i] = ReadDword(Tmp + i * 4);
				
				*(FLOAT*)(ReadDword(ReadDword(Tmp + i * 4) + 0xA8) + 0xC) = this->My.X; // 修改之后会瞬移的坐标,把它的值赋值成我们玩家的坐标
				*(FLOAT*)(ReadDword(ReadDword(Tmp + i * 4) + 0xA8) + 0x10) = this->My.Y; // 修改之后会瞬移的坐标,把它的值赋值成我们玩家的坐标
				call_logW(L"wetool:第%d个对象:%x 怪物名字:%ls type:0x%x x:%f y:%f", i, this->masterNum.Object[i], this->masterNum.Name[i], this->masterNum.type[i], this->masterNum.x[i], this->masterNum.y[i]);
			}
		}
	}
	else {
		call_logA("wetool:Tmp error");
	}
}

// 吸怪加秒杀
void MyStrust::AllKill()
{
	try {
	this->InitMy();
	this->FindMaster();
	for (size_t i = 0; i < 100; i++)
	{
		if (this->masterNum.Object[i] > 0 && (this->masterNum.type[i] == 0x211)) {
		
				call_logW(L"wetool:AllKill-第%d个对象:%x 怪物名字:%ls type:0x%x x:%f y:%f", i, this->masterNum.Object[i], this->masterNum.Name[i], this->masterNum.type[i], this->masterNum.x[i], this->masterNum.y[i]);
				this->NewChangeBlooad(this->masterNum.Object[i]);// 调用修改血量的函数
		}
	}
	}
	catch (...) {
		OutputDebugStringA("MyStrust::AllKill error");
	}
}

void MyStrust::StartIn()
{
	try {
		__asm
		{
			pushad
			// 切换地图
			push 0x26
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127D60
			call eax

			push 0xE
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0x2
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0x1E
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			push 0x10F
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			push 0x5
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0xE
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			push 0x1
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127EC0
			call eax
			// 进入副本选择界面
			push 0xF
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127D60
			call eax

			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127EC0
			call eax
			// 进入副本
			push 0x10
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127D60
			call eax

			push 0x68
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128580
			call eax

			push 0
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			push 0
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1128550
			call eax

			mov eax, 0x1127EC0
			call eax

			popad

			// 进入副本选择界面
			pushad

			push 0xF
			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127D60
			call eax

			mov ecx, 0x1AEB6E4
			mov ecx, [ecx]
			mov eax, 0x1127EC0
			call eax
			popad

		}
	}
	catch (...)
	{
		OutputDebugStringA(" MyStrust::StartIn error");
	}

}

void MyStrust::MoveInMap(DWORD x, DWORD y)
{
	try {
		DWORD nEcx = *(DWORD*)0x1AEB6E4;
		__asm {
			pushad

			push 0x30
			mov ecx, nEcx
			mov eax, 0x1127D60
			call eax

			// 这里的0x2它是地图x的数据
			push x
			mov ecx, nEcx
			mov eax, 0x1128550
			call eax
			// 这里的0x1它是地图y的数据
			push y
			mov ecx, nEcx
			mov eax, 0x1128550
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128550
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax

			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x1128580
			call eax
			// 入参没用
			push 0x0
			mov ecx, nEcx
			mov eax, 0x11285B0
			call eax

			mov ecx, nEcx
			mov eax, 0x1127EC0
			call eax

			popad
		}
	}catch (...) {
		OutputDebugStringA(" MyStrust::StartIn error");
	}

}

void MyStrust::ComeBackTwon()
{
	try {
		DWORD nEcx = *(DWORD*)0x1AEB6E4;
		__asm {
			pushad
			mov ecx, 0x1A3CBF4
			mov ecx, [ecx]
			push 0x138D
			mov eax, 0x4E9740
			call eax
			popad
		}
	}
	catch (...) {
		OutputDebugStringA(" MyStrust::ComeBackTwon error");
	}
}

MyStrust.h文件的内容:修改了 Myself结构体

#pragma once
struct Myself {
	DWORD Blood;// 血量
	FLOAT X; // x坐标
	FLOAT Y; // y坐标
	wchar_t* Name; // 名字
	DWORD RoomX; // 副本内的x坐标
	DWORD RoomY; // 副本内的y坐标
	DWORD State; // 角色状态、在城镇还是副本中,还是选择副本界面
};

struct Master {
	DWORD Object[100];
	DWORD Blood[100];
	FLOAT x[100];
	FLOAT y[100];
	wchar_t* Name[100];
	DWORD type[100];
};

class MyStrust
{
public:
	Myself My;
	Master masterNum;
	void InitMy();// 玩家角色基本信息(血量、名字、坐标)
	void UseObject(DWORD object); // 修改血量
	void ChangeBlooad(int v); // 使用物品
	void NewChangeBlooad(DWORD nEcx);
	void FindMaster();// 遍历怪物
	void AllKill(); // 吸怪加秒杀
	void StartIn();// 秒进副本
	void MoveInMap(DWORD x, DWORD y); // 副本内瞬移
	void ComeBackTwon(); // 返回城镇
};

img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2098557.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一套高效、稳定的自卸车自动充电系统

随着工业自动化和智能化水平的不断提升&#xff0c;无人化作业已成为现代生产线的必然趋势。在山西地区的室内生产条件下&#xff0c;富唯智能凭借其在自卸车充电系统领域的深厚积累&#xff0c;成功设计出一套高效、稳定的自卸车自动充电系统&#xff0c;为工业领域带来革命性…

GeoScene Pro教程(003):手机拍摄带有坐标的照片批量上图到GeoScenePro

文章目录 1、创建【地图】工程2、添加底图3、照片转点4、更改符号5、设置时间动画1、创建【地图】工程 2、添加底图 选中【地图】选项卡下的【底图】按钮 ,选择适合的底图。 3、照片转点 1、查看图片GPS,右键【属性】,这样就可以确保照片可以转点 2、选中工具栏的【分析】…

公司注册资本金验资出具验资报告的看法

验资报告&#xff08;Capital Verification Report&#xff09;是注册会计师根据《中国注册会计师审计准则第1602号&#xff0d;验资》的规定&#xff0c;在对被审验单位的股东&#xff08;投资者、合伙人、主管部门等&#xff09;出资情况实施审验工作的基础上&#xff0c;所出…

typedef关键字讲解

目录&#xff1a; 1. typedef关键字 2. ui的位置 3.ui的使用 很多人都见过typedef&#xff0c;但是少有人知道它的作用&#xff0c;其实它的作用就是让关键词简单化 比如说当我们用到 unsigned int 时&#xff0c;每次都要打印这么长的关键词&#xff0c;十分耗费时间 有没…

Electron桌面应用与文件路径处理:从Git、SourceTree到TortoiseGit的安装与配置

更多内容前往个人网站&#xff1a;孔乙己大叔 在开发Electron桌面应用程序时&#xff0c;正确处理文件路径是一个至关重要的环节。特别是当涉及到需要调用外部程序&#xff08;如Git、SourceTree或TortoiseGit&#xff09;时&#xff0c;确保这些程序安装在正确的位置&#xff…

超越卷积滤波器,HyCoT利用Transformer捕捉高光谱图像的全局依赖性 !

近年来&#xff0c;基于学习的高光谱图像&#xff08;HSI&#xff09;压缩模型的开发引起了大量关注。现有的模型主要使用卷积滤波器&#xff0c;仅捕捉局部依赖性。 此外&#xff0c;它们通常会带来高昂的训练成本&#xff0c;并具有较大的计算复杂性。 为了解决这些问题&…

【全能型AI“草莓”来袭】探索未来AI市场的多元化与边界

&#x1f41f;作者简介&#xff1a;一名大三在校生&#xff0c;喜欢编程&#x1fab4; &#x1f421;&#x1f419;个人主页&#x1f947;&#xff1a;Aic山鱼 &#x1f420;WeChat&#xff1a;z7010cyy &#x1f988;系列专栏&#xff1a;&#x1f3de;️ 前端-JS基础专栏✨前…

C语言基础(三十三)

1、链表排序之归并排序与线性搜索 测试代码&#xff1a; #include "date.h" #include <stdio.h> #include <stdlib.h>// 链表节点结构体 typedef struct Node {int data;struct Node *next; } Node;// 插入节点到链表末尾 Node* insertNode(Node *hea…

2.6 时序与总线操作

&#x1f393; 微机原理考点专栏&#xff08;通篇免费&#xff09; 欢迎来到我的微机原理专栏&#xff01;我将帮助你在最短时间内掌握微机原理的核心内容&#xff0c;为你的考研或期末考试保驾护航。 为什么选择我的视频&#xff1f; 全程考点讲解&#xff1a;每一节视频都…

创建一个Spring MVC项目(配置,导入依赖,以及前端控制器)

Tomcat&#xff08;10.1.28&#xff09;配置 详细讲解&#xff01; 链接https://blog.csdn.net/or77iu_N/article/details/141266535?spm1001.2014.3001.5502 1、创建 Java Web 项目 File -> New -> Project 2、导入 Spring MVC 相关依赖 <dependency> <gro…

docker-compose 启动的harbor页面能登录,但是不能推送镜像

问题现象&#xff1a; docker-compose 安装的harbor&#xff0c;页面可以正常打开&#xff0c;但是不能推送镜像。 报错信息提示&#xff1a;connect: connection refused 故障原因&#xff1a; harbor.yml 中的external_url参数写错。这个是提供外部访问。页面请求地址和…

macos下的 sed命令安装与使用 gnu-sed

sed命令是我们在linu类系统中非常重要的一个命令, 但是在macos下面默认是没有sed命令的, 不过我们可以通过brew install gnu-sed ( 或者通过 sudo port install gsed )这个软件包来获得这个命令 GNU sed 命令安装 下面2种方式,选择一种安装即可 # brew安装 brew install gn…

论文《Generalized Focal Loss》阅读笔记

论文作者对自己文章的中文介绍&#xff1a;这里&#xff0c;所以本人结合论文进行一些简单记录。 存在的问题 之前的工作在训练阶段和推理阶段对最终得分的计算有些问题&#xff0c;即训练分开计算分类得分和定位得分&#xff0c;但是推理时又相乘得到最终的得分进行NMS&#…

PHP 项目流水线部署与错误问题解决

在现代软件开发中&#xff0c;持续集成&#xff08;CI&#xff09;和持续部署&#xff08;CD&#xff09;已成为确保代码质量和加快发布速度的关键实践。本文将介绍如何构建一个 PHP 项目的流水线部署&#xff0c;涵盖从代码提交到生产环境的自动化流程。 #### 1. 什么是流水线…

Amazon SPAPI PWC(普华永道)审计问题流程

如之前德勤审计记录&#xff0c;SP-API审计是public开发者必然会面临的一个流程&#xff1a;https://blog.csdn.net/MarcoMaJF/article/details/141825436 其流程和德勤审计差别不大&#xff0c;流程如下&#xff1a; PWC SP-API审计 1.开发者邮箱收到审计邮件. 2.回复确认会…

使用神卓互联内网穿透搭建微信开发回调环境

在开发微信应用的过程中&#xff0c;往往需要搭建一个本地开发环境来测试和调试代码。然而&#xff0c;由于微信平台需要通过公网访问开发者的服务器来进行消息推送和事件通知&#xff0c;这就要求开发者必须有一个可公开访问的域名或者IP地址。对于不具备公网IP的开发者来说&a…

问题合集更更更之vant组件适配桌面端

前言 &#x1f44f;问题合集更更更之vant组件适配桌面端~ &#x1f947;记得点赞关注收藏&#xff01; 1.问题描述 在pc端&#xff08;桌面端&#xff09;使用vant组件时&#xff0c;清除按钮不生效&#xff1f;除此之外&#xff0c;下拉框等滑动事件也无法正确触发。 注&…

Win10桌面出现Removable Storage Devices文件夹无法删除

最近在 coding 的时候&#xff0c;电脑桌面上突然间蹦出来一个 文件夹 “Removable Storage Devices” , 可移除的存储设备&#xff1f;&#xff0c;但是我们也没有放什么东西呀&#xff0c;就有点蒙圈了。 最后在网上百度了好久才 get 到这个方法&#xff0c;成功解决。 Win…

深度学习(二)-损失函数+梯度下降

损失函数 损失函数&#xff08;Loss Function&#xff09;&#xff0c;也有称之为代价函数&#xff08;Cost Function&#xff09;&#xff0c;用来度量预测值和实际值之间的差异。 损失函数的作用 度量决策函数f&#xff08;x&#xff09;和实际值之间的差异。 作为模型性能…

解耦利器 - Java中的SPI机制

为什么需要SPI机制 SPI和API的区别是什么 SPI是一种跟API相对应的反向设计思想&#xff1a;API由实现方确定标准规范和功能&#xff0c;调用方无权做任何干预&#xff1b; 而SPI是由调用方确定标准规范&#xff0c;也就是接口&#xff0c;然后调用方依赖此接口&#xff0c;第…