游戏测试方法及装置、计算机存储介质和电子设备与流程

文档序号:30381488发布日期:2022-06-11 04:18阅读:153来源:国知局
游戏测试方法及装置、计算机存储介质和电子设备与流程

1.本公开涉及计算机技术领域,更具体地,涉及一种游戏测试方法、游戏测试装置、计算机存储介质和电子设备。


背景技术:

2.游戏在开发过程、内测过程、公测过程和版本升级过程中均需要通过游戏测试,测试游戏服务器对游戏用户输入的游戏动作等行为的响应情况,以检测出游戏中存在的漏洞或其它缺陷等问题,使得游戏在真正上线时能提供最佳的游戏体验。
3.相关技术中,通过在游戏中添加gm指令的脚本,通过操作gm指令界面、网络传输指令等方式远程调用测试脚本提供的接口,但是该方法在修改或增删gm指令时需要重新完成打包,不仅影响测试效率,也受限于操作系统对安装包体的要求,甚至容易将存在风险的因素引入至游戏;而相关技术中基于注入的游戏测试方法无法适用于python脚本开发的游戏测试。
4.需要说明的是,在上述背景技术部分发明的信息仅用于加强对本公开的背景的理解,因此可以包括不构成对本领域普通技术人员已知的现有技术的信息。


技术实现要素:

5.本公开的目的在于提供一种游戏测试方法及装置、计算机存储介质和电子设备,进而至少在一定程度上避免了相关技术中游戏测试介入方法测试效率低、安全性低,且无法适用于python脚本开发的游戏测试等问题。
6.本公开的其他特性和优点将通过下面的详细描述变得显然,或部分地通过本公开的实践而习得。
7.根据本公开的一个方面,提供一种游戏测试方法,包括:在游戏进程的python虚拟机中注入预设代码,所述预设代码用于获取所述python虚拟机中的目标函数地址以及建立所述游戏进程与控制端的数据传输连接,其中所述目标函数地址为所述python虚拟机中运行python脚本的目标函数对应的函数地址;
8.通过所述数据传输连接接收所述控制端发送的测试python数据,并基于所述目标函数地址在所述python虚拟机中执行所述测试python数据。
9.在本公开的一种示例性实施例中,所述建立所述游戏进程与控制端的数据传输连接,包括:将所述控制端的端口信息写入至python文件,并将所述python文件发送至所述游戏进程所在终端;通过所述预设代码运行所述python文件,以在所述游戏进程中建立任务监听线程;所述游戏进程通过所述任务监听线程与所述控制端建立数据传输连接。
10.在本公开的一种示例性实施例中,所述在游戏进程的python虚拟机中注入预设代码,包括:保存当前寄存器环境;调用内存映射函数mmap分配内存管理空间,向所述内存管理空间注入所述预设代码,并在所述内存管理空间写入所述预设代码的代码标识和所述预设代码对应的调用函数;对所述预设代码进行远程调用,并恢复所述当前寄存器环境。
11.在本公开的一种示例性实施例中,在所述对所述预设代码进行调用,并恢复所述当前寄存器环境之前,所述方法还包括:调用用于辅助获取所述目标函数地址的注入文件,且传入参数为所述预设代码的so文件。
12.在本公开的一种示例性实施例中,通过所述预设代码获取所述python虚拟机的目标函数地址,包括:获取动态链接库的基址;获取目标函数对应的函数偏移地址;将所述动态链接库的基址与函数偏移地址相加,得到所述目标函数地址。
13.在本公开的一种示例性实施例中,所述获取目标函数的函数偏移地址,包括:对所述游戏进程的python虚拟机的二进制文件进行代码反汇编,得到反汇编代码;比对所述反汇编代码和所述python虚拟机的源代码,并根据比对结果确定所述目标函数的函数偏移地址,所述python虚拟机的二进制文件为所述python虚拟机的源代码的编译文件。
14.在本公开的一种示例性实施例中,所述游戏进程通过所述任务监听线程与所述控制端建立socket连接;所述游戏进程与控制端进行数据传输,还包括:通过所述任务监听线程将所述python虚拟机执行所述测试python数据的运行结果重定向至所述socket连接,以通过所述socket连接返回至所述控制端。
15.在本公开的一种示例性实施例中,所述方法采用python进程锁机制在所述游戏进程中建立所述任务监听线程,并基于所述任务监听线程实现对所述python虚拟中内存数据的访问。
16.根据本公开的一个方面,提供一种游戏测试装置,包括:代码注入模块,用于在游戏进程的python虚拟机中注入预设代码,所述预设代码用于获取所述python虚拟机中的目标函数地址以及建立所述游戏进程与控制端的数据传输连接,其中所述目标函数地址为所述python虚拟机中运行python脚本的目标函数对应的函数地址;指令运行模块,用于通过所述数据传输连接接收所述控制端发送的测试python数据,并基于所述目标函数地址在所述python虚拟机中执行所述测试python数据。
17.根据本公开的一个方面,提供一种计算机存储介质,其上存储有计算机程序,所述计算机程序被处理器执行时实现上述任意一项所述的游戏测试方法。
18.根据本公开的一个方面,提供一种电子设备,包括:处理器;以及存储器,用于存储所述处理器的可执行指令;其中,所述处理器配置为经由执行所述可执行指令来执行上述任意一项所述的游戏测试方法。
19.本公开的示例性实施例中的游戏测试方法,通过将预设代码注入至游戏进程中的python虚拟机,以基于预设代码获取python虚拟机的目标函数地址并建立游戏进程与控制端的数据传输连接,在接收控制端发送的测试python数据后,基于目标函数地址在python虚拟机中运行测试python数据。一方面,本公开通过将测试脚本与游戏代码分离,能够根据测试需求进行测试脚本的开发,并通过与游戏进程中python虚拟机建立的连接,将测试python数据发送至python虚拟机进行测试,测试python数据的开发和修改等操作,无需依赖于游戏代码,因此不会对游戏代码产生影响,也不会因测试python数据的添加引起游戏包体中的风险因素,测试效率和测试操作的安全性高;另一方面,通过本公开的游戏测试方法,还可以将对游戏进行二次开发的相关游戏python数据,同样通过python虚拟机与控制端之间的连接注入至python虚拟机中,以通过在python虚拟机中启动并运行游戏python数据的方式,实现游戏的二次开发,提高游戏开发效率。此外,由于游戏引擎通常被运行在安
卓架构中的native层,而本公开将代码注入至python虚拟机,已属安卓架构中的native层范畴,因此本公开的游戏测试方法可以适用于任何使用python作为游戏脚本的游戏测试和开发项目。
20.应当理解的是,以上的一般描述和后文的细节描述仅是示例性和解释性的,并不能限制本公开。
附图说明
21.通过参考附图阅读下文的详细描述,本公开示例性实施方式的上述以及其他目的、特征和优点将变得易于理解。在附图中,以示例性而非限制性的方式示出了本公开的若干实施方式,其中:
22.图1示出了根据本公开示例性实施例的游戏测试方法的流程图;
23.图2示出了根据本公开示例性实施例的建立游戏进程与控制端的连接的流程图;
24.图3示出了根据本公开一示例性实施例的在游戏进程的python虚拟机中注入预设代码的流程图;
25.图4示出了根据本公开另一示例性实施例的在游戏进程的python虚拟机中注入预设代码的流程图;
26.图5示出了根据本公开示例性实施例的通过预设代码获取python虚拟机的目标函数地址的流程图;
27.图6示出了根据本公开示例性实施例的通过预设代码获取python虚拟机的目标函数地址的流程图;
28.图7示出了根据本公开示例性实施例的获取信息对象的流程图;
29.图8示出了根据本公开示例性实施例的游戏测试装置的结构示意图;
30.图9示出了根据本公开示例性实施例的游戏测试的系统架构图;
31.图10示出了根据本公开示例性实施例的存储介质的示意图;以及
32.图11示出了根据本公开示例性实施例的电子设备的框图。
33.在附图中,相同或对应的标号表示相同或对应的部分。
具体实施方式
34.现在将参考附图更全面地描述示例性实施方式。然而,示例性实施方式能够以多种形式实施,且不应被理解为限于在此阐述的范例;相反,提供这些实施例使得本公开将更加全面和完整,并将示例性实施方式的构思全面地传达给本领域的技术人员。图中相同的附图标记表示相同或类似的结构,因而将省略它们的详细描述。
35.此外,所描述的特征、结构或特性可以以任何合适的方式结合在一个或更多实施例中。在下面的描述中,提供许多具体细节从而给出对本公开的实施例的充分理解。然而,本领域技术人员将意识到,可以实践本公开的技术方案而没有所述特定细节中的一个或更多,或者可以采用其它的方法、组元、装置、步骤等。在其它情况下,不详细示出或描述公知结构、方法、装置、实现或者操作以避免模糊本公开的各方面。
36.附图中所示的方框图仅仅是功能实体,不一定必须与物理上独立的实体相对应。即,可以采用软件形式来实现这些功能实体,或在一个或多个软件硬化的模块中实现这些
功能实体或功能实体的一部分,或在不同网络和/或处理器装置和/或微控制器装置中实现这些功能实体。
37.在本领域的相关技术中,游戏测试介入方式包括在游戏中添加gm执行的脚本,并在游戏界面中添加gm指令界面或通过网络连接远程控制端,从而测试人员可以通过操作gm指令界面或网络传输指令等方式远程调用测试脚本提供的接口,以进行游戏测试。然而,该方法存在如下缺陷:a.由于gm指令需打包至安卓应用程序包中执行,若对相关gm指令脚本进行修改或添加等操作时,需要重新打包,影响测试效率;b.若添加过多gm指令文件将增加包体大小,而受限于android系统对安装包体大小的要求;c.包体脚本中存在的gm指令或接收指令端口存在安全隐患,一旦被非法利用则将导致严重后果,而且gm指令文件的添加也可能导致不必要的漏洞风险,存在安全隐患。而通过进程注入的方式,由于游戏引擎被打包成so库文件并运行在安卓架构中的native层,而针对java层的测试介入方法无法适用于使用python脚本开发的游戏。
38.基于此,在本公开示例性实施例中,首先提供了一种游戏测试方法。参考图1所示,该游戏测试方法包括以下步骤:
39.步骤s110:在游戏进程的python虚拟机中注入预设代码,其中预设代码用于获取python虚拟机中的目标函数地址以及建立游戏进程与控制端的数据传输连接,其中目标函数地址为python虚拟机中运行python脚本的目标函数对应的函数地址;
40.步骤s120:通过数据传输连接接收控制端发送的测试python数据,并基于目标函数地址在python虚拟机中执行测试python数据;
41.根据本示例实施例中的游戏测试方法,通过将测试脚本与游戏代码分离,能够根据测试需求进行测试脚本的开发,并通过与游戏进程中python虚拟机建立的连接,将测试python数据发送至python虚拟机进行测试,测试python数据的开发和修改等操作,无需依赖于游戏代码,因此不会对游戏代码产生影响,也不会因测试python数据的添加引起游戏包体中的风险因素,测试效率和测试操作的安全性高;通过本公开的游戏测试方法,还可以将对游戏进行二次开发的相关游戏python数据,同样通过python虚拟机与控制端之间的连接注入至python虚拟机中,以通过在python虚拟机中启动并运行游戏python数据的方式,实现游戏的二次开发,提高游戏开发效率。此外,由于游戏引擎通常被运行在安卓架构中的native层,而本公开将代码注入至python虚拟机,已属安卓架构中的native层范畴,因此本公开的游戏测试方法可以适用于任何使用python作为游戏脚本的游戏测试和开发项目。
42.下面结合图1对本公开示例性实施例中的游戏测试方法进行进一步的说明。
43.在步骤s110中,在游戏进程的python虚拟机中注入预设代码,其中预设代码用于获取python虚拟机中的目标函数地址以及建立游戏进程与控制端的数据传输连接,其中目标函数地址为python虚拟机中运行python脚本的目标函数对应的函数地址。
44.在本公开的示例性实施例中,游戏进程为待测试游戏或待二次开发的游戏进程,python虚拟机为游戏进程的组成部分之一,python虚拟机为python字节码的虚拟执行环境,python并不是将python文件编译为机器码运行,而是由python虚拟机逐条将python文件进行解释运行。控制端用于提供用户操作的交互界面,并将测试python数据发送至游戏进程。
45.在一示例性实施例中,可以通过在游戏进程中建立任务监听线程,并通过任务监
听线程建立与控制端的连接。其中,任务监听线程可以为shell线程,本公开的shell线程是指控制端监听在游戏进程(被监控端)中的端口,游戏进程发起请求到该端口,并将其命令行的输入输出转到控制端,控制端由此可在本地向远程被控制端(游戏进程)发送python脚本数据,即通过在游戏进程启动shell线程,建立起游戏进程与控制端的数据传输连接。当然,也可以根据实际需求选择其它类型的任务监听线程。
46.如图2示出了根据本公开的示例性实施例的建立游戏进程与控制端的连接的流程图,如图2所示,该过程包括如下步骤:
47.在步骤s210中,将控制端的端口信息写入至python文件,并将python文件发送至游戏进程所在终端。
48.在本公开的示例性实施例中,控制端的端口信息包括但不限于控制端的网际互联协议ip地址、端口名称和端口号等可用于建立数据传输连接的相关信息。通过将控制端的端口信息写入至游戏进程中的python文件中,以完成端口信息的替换。其中,可以通过逐行查找反向连接的端口信息,并完成替换,从而通过将python文件发送至游戏进程所在终端,可以建立控制端与游戏进程的数据传输连接。其中,python文件可以为reverseshell.py文件,即将控制端的端口信息写入reverseshell.py文件,并将该reverseshell.py文件发送至游戏进程所在终端。
49.在本公开的示例性实施例中,还可以同时向python文件中写入启动语句,在通过将python文件发送至游戏进程所在终端后,以便后续通过启动语句启动任务监听线程。
50.需要说明的是,在将控制端的端口信息写入至python文件之前,需先获取控制端的初始化本地端口的相关信息,即先获取控制端的端口信息,以确保写入至python文件的控制端的端口信息的准确性和完整性。
51.通过本示例性实施例,将控制端的端口信息写入至python文件并发送至游戏进程所在终端,以便后续通过运行该python文件,建立游戏进程与控制端之间的数据传输连接,进而将脚本注入至游戏进程实现游戏测试或二次开发,此部分将在后续介绍,在此不再赘述。
52.在步骤s220中,通过预设代码运行python文件以在游戏进程中建立任务监听线程。
53.在本公开的示例性实施例中,在将写有控制端的端口信息的python文件发送至游戏进程所在终端后,可以在终端启动并运行该python文件,从而通过该python文件在游戏进程中启动任务监听线程。
54.在一示例性实施例中,任务监听线程可以通过socket连接反向连接至控制端,并向控制端发送连接请求;当控制端监听到连接请求后,接收并完成与任务监听线程(游戏进程)之间数据传输连接的建立。其中,socket是对网络中不同主机上的应用进程之间进行双向通信的端点的抽象,用于完成两个应用程序之间的数据传输。相应的,还可以通过游戏进程中的任务监听线程监听socket端口发送的python虚拟机运行测试python数据,以及将python虚拟机运行测试python数据的运行结果重定向至socket连接,以通过socket连接返回控制端。
55.通过本示例性实施方式,通过预设代码运行python文件,在游戏进程中启动任务监听线程,使得通过任务监听线程作为游戏进程与控制端进行数据传输连接的桥梁,实现
游戏进程与控制端的双向通信。
56.在步骤s230中,游戏进程通过任务监听线程与控制端建立数据传输连接。
57.在本公开的示例性实施例中,在游戏进程中启动任务监听线程后,游戏进程即可通过任务监听线程与控制端建立数据传输连接。基于该数据传输连接可以进行后续的测试python数据的分发与执行和游戏二次开发等过程。
58.在本公开的示例性实施例中,预设代码至少用于获取python虚拟机中的目标函数地址,目标函数地址为python虚拟机中运行python脚本的目标函数对应的函数地址。代码注入的方式包括但不限于系统进程zygote注入、ptrace注入等。其中,ptrace为linux提供的库函数,提供一种父进程可以控制子进程的运行,并可以访问、修改内存和寄存器中的数据。该方法的原理是通过向进程下发一个能够中断处理程序的中断指令,让其从用户态进入内核态,从而可以进行内存读写、寄存器读写等,从而方便该函数完成代码注入。
59.在一示例性实施例中,采用ptrace注入方式,并通过注入器将预设代码注入至游戏进程中的python虚拟机。图3示出了根据本公开的示例性实施例的通过注入器将预设代码注入至游戏进程中的python虚拟机的流程图,如图3所示,该过程包括:
60.在步骤s310中,通过注入器保存当前寄存器环境。
61.在本公开的示例性实施例中,在通过注入器保存当前寄存器环境之前,注入器先与游戏进程建立连接,例如通过ptrace attach连接至游戏进程。然后,利用ptrace getregs保存当前寄存器环境,也就是说,在进行代码注入时,需将游戏进程暂停,而为了在代码注入后游戏进程能够正常运行,则将此时游戏进程的各种信息保存,如当前游戏进程的代码上下文进行保存,以便在后续完成代码注入并重新运行游戏进程时,能够按照暂停前游戏进程所处的状态进行正常运行。
62.通过本示例性实施例,保存当前寄存器环境能够避免代码注入过程对游戏进程产生影响,使游戏进程不会因代码注入发生改变。
63.在步骤s320中,调用内存映射函数mmap分配内存管理空间,向内存管理空间注入预设代码,并在内存管理空间写入预设代码的代码标识和预设代码对应的调用函数。
64.在本公开的示例性实施例中,内存映射函数mmap为一种内存映射文件的方法,通过调用内存映射函数mmap可以将一个文件或其它对象映射进内存。本公开通过调用内存映射函数mmap分配内存管理空间,并向分配得到的内存管理空间中注入预设代码,以及在该内存管理空间中写入预设代码的代码标识和预设代码对应的调用函数,即不仅需要在内存管理空间中写入预设代码,同时也在内存管理空间中声明该预设代码的代码标识和对应的调用函数,以便后续基于该预设代码实现进程注入和获取python虚拟中运行python脚本的目标函数对应的函数地址、以及启动并运行测试python数据等过程。
65.在一示例性实施例中,内存映射函数mmap的调用方式可以包括:使用dloopen获取libc.so句柄,通过dlsym获取mmap地址,并通过游戏进程中proc/pid/maps文件查询mmap的函数偏移地址,最后根据该函数偏移地址完成mmap函数的调用。其中,该调用过程至少包括设置寄存器环境、等待执行完成和返回执行结果至注入器等。其中,可以通过ptrace writedada向内存管理空间中写入预设代码的代码标识和对应的调用函数。
66.通过本公开的示例性实施例,通过在游戏进程中获取内存管理空间并写入预设代码的方式,可以实现预设代码的注入。
67.在步骤s330中,对预设代码进行远程调用,并恢复当前寄存器环境。
68.在本公开的示例性实施例中,可以远程调用预设代码,该调用过程也包括设置寄存器环境、等待执行完成和返回执行结果至注入器。在此之后,可以恢复当前寄存器环境,并将注入器与游戏进程断开连接,至此完成将预设代码注入至游戏进程中的python虚拟机的过程。该过程无需对游戏代码做出调整,实现测试脚本与游戏代码的分离,不仅方便测试python数据的灵活开发,通过进程注入获取python虚拟机中运行python脚本的目标函数对应的目标函数地址,进而能够实现在python虚拟机中运行测试python数据的功能。
69.需要说明的是,在本公开的示例性实施例中,预设代码除获取python虚拟机中运行python脚本的目标函数对应的函数地址之外,至少还用于获取编译python虚拟机的so库句柄、查找获取python虚拟机运行python脚本的函数调用方式等,并基于获得的so库句柄和目标函数地址和调用方式,实现在python虚拟机中运行测试python数据。
70.在一示例性实施例中,如图4所示,在对预设代码进行远程调用,并恢复当前寄存器环境之前,还可以包括步骤s323,调用用于辅助获取目标函数地址的注入文件,且传入参数为预设代码的so文件,返回注入文件句柄。
71.其中,可以通过远程调用dlopen函数打开一注入模块,并通过远程调用dlsym函数来获取需要调用的函数地址,其中调用dlopen函数和dlsym函数的方式与调用mmap的方式相同,在此不再赘述。
72.通过本示例性实施例,由于注入至python虚拟机的预设代码可能无法全面获取上述所述的目标函数地址和目标函数的调用方式等信息,通过调用注入文件,用来辅助获取目标函数地址等python虚拟机的相关函数调用信息,以进一步确保能够在python虚拟机中运行用户所期望的测试python数据。
73.在步骤s120中,通过数据传输连接接收控制端发送的测试python数据,并基于目标函数地址在python虚拟机中执行测试python数据。
74.在本公开的示例性实施例中,测试python数据可以包括执行指令(如python语句)或脚本文件(如python脚本文件)。若测试python数据为执行指令,则将该执行指令通过任务监听线程直接发送至虚拟机中的接收端进行执行,并返回执行结果。若测试python数据为脚本文件,则至指定目录下获取python脚本文件,并将该python脚本文件的内容发送至虚拟机中的接收端进行执行,并返回执行结果。本公开可根据实际测试需求,选择不同类型的测试python数据,本公开对此不做特殊限定。
75.如图5示出了根据本公开的示例性实施例的通过预设代码获取python虚拟机的目标函数地址的流程图,如图5所示,该过程至少包括:在步骤s510中,获取动态链接库的基址;在步骤s520中,获取目标函数对应的函数偏移地址;在步骤s530中,将动态链接库的基址与函数偏移地址相加,得到目标函数地址。
76.下面以ptrace注入方式为例,结合图6对通过预设代码获取python虚拟机的目标函数地址过程进行详细阐述,且游戏引擎将python虚拟机打包至client.so文件中。
77.在步骤s610中,通过获取proc/pid/maps文件获取libclient.so基址,即动态链接库的基址。其中,若目标函数在同一so文件中,则对应的基址是相同的。
78.在步骤s620中,获取全局解释器锁python gil锁,该过程通过调用pygilstate_ensure函数完成。在本公开的示例性实施例中,基于python进程锁机制,可以在一个线程使
用全局解释器访问权之后,其它线程均需等待该线程释放全局解释器访问权后才进行执行,因此通过在游戏进程中的多线程建立任务监听线程后,通过该任务监听线程争夺全局解释器访问权,以访问存储在内存中的所有python对象,即本公开通过在游戏进程中开辟新的线程实现对python虚拟机中所有内存数据的访问。
79.在步骤s630中,调用pyrunsimple_string执行测试python数据,执行过程需要分别调用该函数的子函数。
80.在步骤s640至步骤s670中,分别计算目标函数对应的函数偏移地址,如pyimport_addmodule函数偏移地址、pymodule_getdict函数偏移地址、pyrun_stringflags函数偏移地址和pyflushlines函数偏移地址。
81.可选地,可以通过ida(interactive disassembler,交互式反汇编器)完成偏移地址的计算,且计算过程中涉及到的api(application programming interface,应用程序编程接口)至少包括:
82.表1
83.函数名称函数功能get_strlist_qty获取ida分析得到的字符串列表datarefsto获取对该数据段的引用get_func获取该地址所在的函数基址coderefsto获取函数的交叉引用列表
84.在本公开的示例性实施例中,获取目标函数的偏移地址可以包括如下步骤:首先,对游戏进程的python虚拟机的二进制文件进行代码反汇编,得到反汇编代码,其次比对反汇编代码和python虚拟机的源代码,并根据比对结果确定目标函数的偏移地址。其中,python虚拟机的二进制文件为python虚拟机的源代码的编译文件,即python虚拟机的二进制文件为python虚拟机的源代码在编译后得到的文件。
85.在本公开的示例性实施例中,根据反汇编代码和python虚拟机的源代码的比对结果确定目标函数的偏移地址至少可以包括三种情况:
86.1)若目标函数中存在目标字符串,且该目标字符串只存在于该目标函数中,则可以直接通过目标字符串引用关系获取该目标函数的偏移地址,并利用idapython提供接口,首先调用datarefsto找到该目标字符串的引用地址,调用get_func获取该地址所在的函数基址;
87.2)若目标函数中不存在目标字符串,将该目标函数拆分为多个子函数,并查找子函数是否存在目标字符串,如果存在则可以通过直接调用子函数,完成该目标函数的执行过程;
88.3)若目标函数中出现的目标字符串同时出现在其他函数中,则无法通过目标字符串唯一定位到该目标函数,则可以将该目标函数拆分为子函数,通过定位子函数的交叉调用关系(coderefsto)与目标字符串结合来定位到该目标函数。
89.在步骤s680中,释放全局解释器锁python gil锁(pygilstate_release),以使python虚拟机恢复至获取该锁之前的运行状态。
90.在步骤s690中,将每个目标函数的函数偏移地址分别与动态链接库的基址相加,得到各个目标函数的目标函数地址。
91.通过本公开的示例性实施例,将测试脚本与游戏代码分离,能够根据测试需求进行测试脚本的开发,并通过与游戏进程中python虚拟机建立的连接,将测试脚本注入至python虚拟机进行测试,测试脚本的开发和修改等操作,无需依赖于游戏代码,因此不会对游戏代码产生影响,也不会因测试脚本的添加引起游戏包体中的风险因素,测试效率和测试操作的安全性高,且由于游戏引擎通常被运行在安卓架构中的native层,而本公开将代码注入至python虚拟机,已属安卓架构中的native层,因此可以适用于任何使用python作为游戏脚本的游戏测试。
92.此外,通过本公开的游戏测试方法,还可以将对游戏进行二次开发的相关游戏脚本,同样通过python虚拟机与控制端之间的连接注入至python虚拟机中,以通过在phthon虚拟机中启动并运行游戏脚本的方式,实现游戏的二次开发,提高游戏开发效率。
93.在一示例性实施例中,可以预先开发用于提供基础功能的扩展模块,包括各种可注入至游戏进程中的phthon虚拟机的脚本文件,包括但不限于对python虚拟机信息遍历(如进行模块、单元和对象信息遍历的功能)、获取模块、单元和对象方法的调用、提供函数hook方法等等。
94.其中,虚拟机信息遍历包括模块(单元)信息的遍历与对象信息的遍历,遍历利用了python对象存储机制,python虚拟机中所有数据均以对象的形式存储在内存中,且python虚拟机通过保存字典的方式存储该对象的全部属性,通过dir函数可以获取对象的所有attribute属性。再使用type和dir函数来获取该属性的类型与子属性,进行信息收集或是方法的遍历。python虚拟机使用import机制,将所有导入模块存储在全局sys.modules中,每次导入的模块都是从全局模块中,可以让不受命名空间的限制。
95.在获得模块实例或对象实例后,可以进行模块、单元和对象方法的调用。如图7示出了根据本公开的示例性实施例的获取信息对象的流程图,如图7所示,该过程包括:
96.在步骤s700中,判断获取对象的类型,包括静态信息模块和动态创建对象。
97.在步骤s710中,通过dir查找当前作用域是否存在该静态信息模块。
98.在步骤s720中,如果当前作用域存在静态信息模块,则继续使用dir函数查找该静态信息模块中的属性,找到最终的静态方法或是全局变量。
99.在步骤s730中,如果不存在,则遍历sys.modules查找模块名。
100.在步骤s740中,查找成功后,通过import导入到当前module,此时可以继续步骤s720,完成静态信息模块属性的获取。
101.如果需要提供对动态创建的对象实例进行访问,则通过:
102.s750、通过dir查找当前module是否存在该对象实例。
103.s760、如果存在,则继续通过dir函数遍历该对象实例的属性,如使用变量名称访问对象实例,找到目标信息,然后根据实际需求进行信息获取或是方法调用。
104.s770、如果不存在则查找globals全局变量中是否存在module名,若存在则通过步骤s720查找。
105.s780、如果不存在,则遍历sys.modules查找对象实例所在的module名,并将其import到当前module。此时可通过global将该对象实例将其导入到global函数中,也可通过ctypes提供的方式通过内存地址计算对象。
106.s790、通过ctypes提供的函数id计算出对象实例的内存地址,并使用该内存地址
通过pyobj_fromptr获取到对象指针。然后通过步骤s720进行相应操作。
107.s7100、通过内存地址来访问该对象实例。
108.在一示例性实施例中,还可以提供函数hook方法,以通过本公开的游戏测试方法的同样流程,将该函数hook方法注入至游戏进程,实现游戏的二次开发。
109.其中,函数hook框架使用装饰器的原理,同样是利用了python虚拟机中所有数据均以对象字典的形式存储,由于函数在python中也是一个对象,且函数对象被赋值给变量,所以通过变量也能调用该函数,在hook的过程中可通过函数对象的_name_属性获取到函数的属性名字,修改该属性名字,并构造一个新的函数对象,并使新的函数指针指向该属性名字,就完成了函数指针的替换,然后在新的函数中调用原函数,完成函数hook,基于该原理可完成参数获取、修改,函数返回结果获取、修改等功能。具体步骤如下:
110.1)通过模块遍历的方式进入待hook的模块中;
111.2)利用dir获取原函数对象,修改原函数的_name_属性名字;
112.3)创建新的函数对象,并修改_name_属性为原函数属性名字,在该函数对象完成原函数的调用;
113.4)在原函数调用前截取到函数参数,进行修改的功能,同时获取原函数的返回值,进行打印或是修改操作。
114.需要说明的是,上述的对python虚拟机信息遍历、获取模块、单元和对象方法的调用、提供函数hook方法仅仅是示例性的,还可以根据实际开发需求,提供其它功能扩展类型,凡是用于对游戏进行二次开发且可以注入至游戏进程中的python虚拟机的脚本文件,均可以通过本公开的游戏测试方法的同样流程注入至游戏进程中的python虚拟机且使python虚拟机运行此类开发脚本文件,提高游戏的二次开发效率,本公开包括但不限于上述提供的功能扩展类型。
115.在本公开的示例性实施例中,还提供了一种游戏测试装置。参考图8所示,该游戏测试装置800可以包括代码注入模块810和指令运行模块820。具体地,
116.代码注入模块810,用于在游戏进程的python虚拟机中注入预设代码,其中预设代码用于获取python虚拟机中的目标函数地址以及建立游戏进程与控制端的数据传输连接,其中目标函数地址为python虚拟机中运行python脚本的目标函数对应的函数地址;
117.指令运行模块820,用于通过数据传输连接接收控制端发送的测试python数据,并基于目标函数地址在python虚拟机中执行测试python数据。
118.在一示例性实施例中,如图9示出了根据本公开的示例性实施例的游戏测试的系统架构图,如图9所示,注入器(代码注入模块)将预设代码注入至游戏进程中的python虚拟机,python虚拟机属于游戏进程的组成部分之一,预设代码通过调用并运行游戏中的python文件(reverseshell.py文件)在游戏进程中建立shell线程,进而游戏进程通过在接收端(指令运行模块)启动的shell线程与控制端进行连接,且接收端还用于完成控制端发送的测试python数据的解析和执行,并将执行结果反馈至控制端。其中,预设代码shellcode还用于获取目标函数的函数地址,从而在接收端完成控制端发送的测试python数据的解析和执行的过程中,基于目标函数地址在python虚拟机中执行该测试python数据。
119.由于本公开的示例性实施例的游戏测试装置和游戏测试系统中的各个功能模块
与上述游戏测试方法的发明实施例中相同,因此在此不再赘述。
120.应当注意,尽管在上文详细描述中提及了游戏测试装置和游戏测试系统的若干模块或者单元,但是这种划分并非强制性的。实际上,根据本公开的实施方式,上文描述的两个或更多模块或者单元的特征和功能可以在一个模块或者单元中具体化。反之,上文描述的一个模块或者单元的特征和功能可以进一步划分为由多个模块或者单元来具体化。
121.此外,在本公开示例性实施方式中,还提供了一种能够实现上述方法的计算机存储介质。其上存储有能够实现本说明书上述方法的程序产品。在一些可能的实施例中,本公开的各个方面还可以实现为一种程序产品的形式,其包括程序代码,当所述程序产品在终端设备上运行时,所述程序代码用于使所述终端设备执行本说明书上述“示例性方法”部分中描述的根据本公开各种示例性实施例的步骤。
122.参考图10所示,描述了根据本公开的示例性实施方式的用于实现上述方法的程序产品1000,其可以采用便携式紧凑盘只读存储器(cd-rom)并包括程序代码,并可以在终端设备,例如个人电脑上运行。然而,本公开的程序产品不限于此,在本文件中,可读存储介质可以是任何包含或存储程序的有形介质,该程序可以被指令执行系统、装置或者器件使用或者与其结合使用。
123.所述程序产品可以采用一个或多个可读介质的任意组合。可读介质可以是可读信号介质或者可读存储介质。可读存储介质例如可以为但不限于电、磁、光、电磁、红外线、或半导体的系统、装置或器件,或者任意以上的组合。可读存储介质的更具体的例子(非穷举的列表)包括:具有一个或多个导线的电连接、便携式盘、硬盘、随机存取存储器(ram)、只读存储器(rom)、可擦式可编程只读存储器(eprom或闪存)、光纤、便携式紧凑盘只读存储器(cd-rom)、光存储器件、磁存储器件、或者上述的任意合适的组合。
124.计算机可读信号介质可以包括在基带中或者作为载波一部分传播的数据信号,其中承载了可读程序代码。这种传播的数据信号可以采用多种形式,包括但不限于电磁信号、光信号或上述的任意合适的组合。可读信号介质还可以是可读存储介质以外的任何可读介质,该可读介质可以发送、传播或者传输用于由指令执行系统、装置或者器件使用或者与其结合使用的程序。
125.可读介质上包含的程序代码可以用任何适当的介质传输,包括但不限于无线、有线、光缆、rf等等,或者上述的任意合适的组合。
126.可以以一种或多种程序设计语言的任意组合来编写用于执行本公开操作的程序代码,所述程序设计语言包括面向对象的程序设计语言—诸如java、c++等,还包括常规的过程式程序设计语言—诸如“c”语言或类似的程序设计语言。程序代码可以完全地在用户计算设备上执行、部分地在用户设备上执行、作为一个独立的软件包执行、部分在用户计算设备上部分在远程计算设备上执行、或者完全在远程计算设备或服务器上执行。在涉及远程计算设备的情形中,远程计算设备可以通过任意种类的网络,包括局域网(lan)或广域网(wan),连接到用户计算设备,或者,可以连接到外部计算设备(例如利用因特网服务提供商来通过因特网连接)。
127.此外,在本公开的示例性实施例中,还提供了一种能够实现上述方法的电子设备。所属技术领域的技术人员能够理解,本公开的各个方面可以实现为系统、方法或程序产品。因此,本公开的各个方面可以具体实现为以下形式,即:完全的硬件实施例、完全的软件实
施例(包括固件、微代码等),或硬件和软件方面结合的实施例,这里可以统称为“电路”、“模块”或“系统”。
128.下面参照图11来描述根据本公开的这种实施例的电子设备1100。图11显示的电子设备1100仅仅是一个示例,不应对本公开实施例的功能和使用范围带来任何限制。
129.如图11所示,电子设备1100以通用计算设备的形式表现。电子设备1100的组件可以包括但不限于:上述至少一个处理单元1110、上述至少一个存储单元1120、连接不同系统组件(包括存储单元1120和处理单元1110)的总线1130、显示单元1140。
130.其中,所述存储单元存储有程序代码,所述程序代码可以被所述处理单元1110执行,使得所述处理单元1110执行本说明书上述“示例性方法”部分中描述的根据本公开各种示例性实施例的步骤。
131.存储单元1120可以包括易失性存储单元形式的可读介质,例如随机存取存储单元(ram)1121和/或高速缓存存储单元1122,还可以进一步包括只读存储单元(rom)1123。
132.存储单元1120还可以包括具有一组(至少一个)程序模块1125的程序/实用工具1124,这样的程序模块1125包括但不限于:操作系统、一个或者多个应用程序、其它程序模块以及程序数据,这些示例中的每一个或某种组合中可能包括网络环境的实现。
133.总线1130可以为表示几类总线结构中的一种或多种,包括存储单元总线或者存储单元控制器、外围总线、图形加速端口、处理单元或者使用多种总线结构中的任意总线结构的局域总线。
134.电子设备1100也可以与一个或多个外部设备1200(例如键盘、指向设备、蓝牙设备等)通信,还可与一个或者多个使得用户能与该电子设备1100交互的设备通信,和/或与使得该电子设备1100能与一个或多个其它计算设备进行通信的任何设备(例如路由器、调制解调器等等)通信。这种通信可以通过输入/输出(i/o)接口1150进行。并且,电子设备1100还可以通过网络适配器1160与一个或者多个网络(例如局域网(lan),广域网(wan)和/或公共网络,例如因特网)通信。如图所示,网络适配器1160通过总线1130与电子设备1100的其它模块通信。应当明白,尽管图中未示出,可以结合电子设备1100使用其它硬件和/或软件模块,包括但不限于:微代码、设备驱动器、冗余处理单元、外部磁盘驱动阵列、raid系统、磁带驱动器以及数据备份存储系统等。
135.通过以上的实施例的描述,本领域的技术人员易于理解,这里描述的示例实施例可以通过软件实现,也可以通过软件结合必要的硬件的方式来实现。因此,根据本公开实施例的技术方案可以以软件产品的形式体现出来,该软件产品可以存储在一个非易失性存储介质(可以是cd-rom,u盘,移动硬盘等)中或网络上,包括若干指令以使得一台计算设备(可以是个人计算机、服务器、终端装置、或者网络设备等)执行根据本公开实施例的方法。
136.此外,上述附图仅是根据本公开示例性实施例的方法所包括的处理的示意性说明,而不是限制目的。易于理解,上述附图所示的处理并不表明或限制这些处理的时间顺序。另外,也易于理解,这些处理可以是例如在多个模块中同步或异步执行的。
137.本领域技术人员在考虑说明书及实践这里公开的发明后,将容易想到本公开的其他实施例。本公开旨在涵盖本公开的任何变型、用途或者适应性变化,这些变型、用途或者适应性变化遵循本公开的一般性原理并包括本公开未公开的本技术领域中的公知常识或惯用技术手段。说明书和实施例仅被视为示例性的,本公开的真正范围和精神由权利要求
指出。
138.应当理解的是,本公开并不局限于上面已经描述并在附图中示出的精确结构,并且可以在不脱离其范围进行各种修改和改变。本公开的范围仅由所附的权利要求来限。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1