Linux系统调用


$%(*#&I3,>’&%( 。 第 一 个 函 数 是 在 把 模 块 插 入 内 核 时 调
用的; 第二个函数则在删除该模块时调用。 由于内核模块是内核的一部分,所以能访问所有内 核 资 源 。 根 据 前 面 对 D"#&N 系 统 调 用 机 制 的 分 析 , 如果要 增加系统调用,可以编写自己的函数来实现,然后在
文 件 "#B?$D> @ E7F @ $#"7CDAG 为 每 个 系 统 调 用 规 定 了 唯 一 的 编 号 。假 设 用 #EF> 表 示 系 统 调 用 的 名 称 , 那么系 统调用号与系统调用响应函数的关系是:以系统调用号
546<>C9:<;F97879BE??
以 <>C9:;<F97879BE?? 入 口 的 汇 编 程 序 段 在 !"#$% 进 程管理中起到了十分重要的作用。所有系统调用结束前 以及大部分中断服务返回前, 都会跳转至此处入口地址。 该段程序不仅仅为系统调用服务,它还处理中断嵌套、 信号等事务。 +&T 调 度 、
!KKK
李善平, 郑 扣 根 .D"#&N 操 作 系 统 及 实 验 教 程 . 北 京 : 机械 工业出版社, 0777 陈向阳, 方 汉 .D"#&N 实 用 大 全 . 北 京 : 科学出版社, 077:
G0H 编 写 系 统 调 用 内 核 模 块
1"#$%&’(M%"#&N ) <(8#(%./O 1"#$%&’(M%"#&N ) ,>’&%(./O 1"#$%&’(M%"#&N ) ,>’W(8+">#+./O
编译内核的命令为: ?$$JV*%%JC!J^AC^SDFJ^3_F54FD3J$ +6+$*%%.$
JV*%% 通知编 译 程 序 显 示 警 告 信 息 ; 参 数 JC! 是 关 于
代码优化的设置, 内核模块必须优化; 参 数 J^AC^SDF 通 知头 文 件 向 内 核 模 块 提 供 正 确 的 定 义 ; 参 数 J^3_F54FD3 通知头 文 件 , 这个程序代码将在内核模式下运行。编译成 功 后 将 生 成 +6+$*%%.> 文 件 。 最 后 使 用 "#+,>’ +6+$*%%.> 命 令将模块插入内核后即可使用增加的系统调用。 比较以上二种方法,笔者认为采用内核模块的方法 较好。因为这种方法可省去编译新内核并用新内核重新 启动的麻烦, 这一优点对于代码的调试是非常有价值的, 可以节省大量时间。 参考文献 0 ! 9 ‘
是所有系统调用的总入口。
语言函数名的集合。然而, !"#$% 系 统 调 用 的 内 部 实 现 方 式 却 与 ,’( 的 )-. /01 相 似 , 它 是 经 过 )-. 2%321 软 中断进入后, 再根据系统调用号分门别类地服务。 从系统分析的角度, !"#$% 的 系 统 调 用 涉 及 4 个 方 面 的问题。
5J6 系 统 调 用 功 能 模 块 的 初 始 化
对 系 统 调 用 的 初 始 化 也 就 是 对 )-. 2%32 的 初 始 化 。 系统启动时, 汇 编 子 程 序 7>C$P9"DC5 见 E<BG @ "J3K @ =><#>? @ 由 7CE<C9=><#>? 56 5 见 I>EDA(6 准 备 了 0 张 /4K 项 的 "DC 表 ,
506 与 系 统 调 用 有 关 的 数 据 结 构 和 函 数
开头, 后跟该系统调用的名字。例 函数名以“ 7879 ” 如, 系 统 调 用 :;<= 56 的 响 应 函 数 是 7879:;<= 56 5 见 =><#>? @
>%"C56 的 响 应 函 数 是 7879>%"C565 见 =><#>? @ >%"CAB6 。 :;<=AB6 ,
9-H9#EF> 作 为 下 标 , 可 找 出 系 统 调 用 表 7879BE??9CEI?>
它正好 5 见 E<BG @ "J3K @ =><#>? @ >#C<8A(6 中 对 应 表 项 的 内 容 , 是 该 系 统 调 用 的 响 应 函 数 7879#EF> 的 入 口 地 址 。系 统 调 用 表 7879BE??9CEI?> 记 录 了 各 7879#EF> 函 数 在 表 中 的 位 置, 共 0L2 项 。 有 了 这 张 表 , 就很容易根据特定系统调用 在表中的偏移量,找到对应的系统调用响应函数的入口 地 址 。系 统 调 用 表 共 /4K 项 , 余下的项是可供用户自己添 加的系统调用空间。
! "#$%&’( ) *+, ) &#"+-’./
在这个文件中加入 0 行: 1’(2"#(3453-(+-+6+$*%%
" *8$ ) "9:; ) <(8#(% ) (#-86.=
这个文件用来对指针数组初始化,在这个文件中增 加 0 行汇编指令: .%>#? =@ABCD34EAFG3+6+3-(+-+6+$*%%H 将 .8(I- 453+6+$*%%+J07K 改 为 453+6+$*%%+J070 , 然 后重建和运行新内核。
软件天地
!"#$% 下增加系统调用的二种方法
武 汉 汽 车 工 业 大 学 计 算 机 系 !"#$$%$& 陈明俊

要 : 在 分 析 !"#$% 系 统 调 用 机 制 的 基 础 上 通 过 修 改 内 核 源 代 码 和 插 入 内 核 模 块 实 现 二 种 系统调用 操作系统
增加系统调用的方法。 关 键 词 : !"#$%
G9H 使 用 新 的 系 统 调 用
在 标 准 的 L 语 言 库 中 没 有 新 系 统 调 用 的 程序段 , 必 须自己建立。 利 用 3+6+$*%%4 GH 宏 指 令 , 使 用 新 的 -(+-+6+$*%% GH 系 统 调用的简单 L 程序如下: 1"#$%&’(M%"#&N ) &#"+-’./O 3+6+$*%%KG"#- , -(+-+6+$*%%H ,*"#GH P -(+-+6+$*%%GH ; Q 这 里 用 了 3+6+$*%%KGH 宏 指 令 , 宏指令本身在你的程序 中 将 扩 展 成 名 称 为 -(+-+6+$*%%GH 的 函 数 , 它 在 ,*"# GH 函 数 内部加以调用。 在 -(+-+6+$*%%GH 函 数 中 , 预处理程序产生所 有必要的机器指令代码,包括用系统调用参数值加载相 应 的 LRS 寄 存 器 , 然 后 执 行 "#- KN:K 中 断 指 令 。
506 编 写 C>7C787BE??56 系 统 调 用
编写一个系统调用意味着要给内核增加 0 个函数, 将 新 函 数 放 入 文 件 =><#>? @ 787AB 中 。 新 函 数 代 码 如 下 : E7F?"#=EQ> 7879C>7C787BE??56 V X B;#7;?>9P<"#C5 “ 1>??; , U;<?DW# ” 6; <>C$<# 2 ;
陈 莉 君 .D"#&N 操 作 系 统 内 核 分 析 . 北 京 : 人民邮电出版社,
!
利 用 "#$%& 内 核 模 块 添 加 系 统 调 用
模块是内核的一部分,但是并没有被编译到内核里
面 去 。它 们 被 分 别 编 译 并 连 接 成 一 组 目 标 文 件 , 这些文件 能被插入到正在运行的内核,或者从正在运行的内核中 移走。内核模块至少必须有 ! 个函数: "#"-3,>’&%( 和
5/6 进 程 的 系 统 调 用 命 令 转 换 为 )-. 2%32 中 断 的 过 程
宏 定 义 9787BE??-565 见 "#B?$D> @ E7F @ $#"7CDAG6 用 于 系 统 调 用 的 格 式 转 换 和 参 数 的 传 递 。- 取 2M4 之 间 的 整 数 。 参 数 个 数 为 - 的 系 统 调 用 由 9787BE??-56 负 责 格 式 转 换 和 参 数 传 递 。系 统 调 用 号 放 入 NO* 寄 存 器 , 启 动 )-. 2%32 后, 规 定 返 回 值 送 NO* 寄 存 器 。
G!H 使 用 新 的 系 统 调 用
1"#$%&’(M%"#&N ) &#"+-’./O 1’(2"#(3453-(+-+6+$*%% 070 3+6+$*%%KG"#- , -(+-+6+$*%%H ,*"#GH P -(+-+6+$*%%GH ; Q
合集下载

linux下ecall用法

linux下ecall用法

linux下ecall用法
在Linux下,ecall是用于执行系统调用的一种机制。

系统调用是操作系统提供给应用程序的接口,用于访问操作系统内核提供的服务。

通过ecall,应用程序可以调用系统调用并与之交互。

在Linux中,ecall的使用通常涉及到以下几个步骤:
1.包含头文件:在程序中包含必要的头文件,以便使用ecall机制。

通常情况下,需要包含<sys/syscall.h>头文件。

2.定义系统调用号:在程序中定义系统调用的编号。

系统调用号是一个整数值,用于标识特定的系统调用。

可以在头文件中找到系统调用号的定义。

3.调用ecall函数:在程序中使用ecall函数来执行系统调用。

ecall函数的原型如下:
long ecall(long num, long arg1, long arg2, long arg3, long arg4, long arg5);
其中,num参数指定要执行的系统调用编号,其他参数是传递给系统调用的参数。

4.处理返回值:ecall函数将返回系统调用的结果。

根据不同的系统调用,返回值的意义可能不同。

可以通过检查返回值来处理系统调用的结果。

需要注意的是,ecall函数是低级函数,通常用于与内核交互。

在实际的应用程序开发中,更常用的是高级的系统调用接口,如open(), read(), write(), close()等函数。

这些函数提供了更高级别的抽象,使得程序更加易于使用和管理。

第10章 linux系统调用接口

第10章 linux系统调用接口

10.1 API和系统调用 API和系统调用
UNIX操作系统为编程员提供了应用编 操作系统为编程员提供了应用编 程接口(API)。 程接口 。 提供的libc标准函数库中,一部分 标准函数库中, 在API提供的 提供的 标准函数库中 是用户态的库函数, 是用户态的库函数,另一部分是系统调 库函数和系统调用的区别是 区别是: 用。库函数和系统调用的区别是:
中断描述符寄存器IDTR 中断描述符寄存器
IDT的基址 的基址 限长
中断描述符表 物理存储器 ┇
offset selector dpl 01111 offset
陷阱门 80H
CS(代码段寄存器 代码段寄存器) 代码段寄存器
selector
GATE 0
一个门描 述符占8B。 述符占 。 在GDT或 或 LDT中的 中的 代码段描 述符。 述符。
调用参数个 数 系统调用名 字
_syscall0(int,fork)
返回类型值
write()系统调用有 个参数,其封装例程 系统调用有3个参数 系统调用有 个参数, 宏指令格式是: 宏指令格式是: _syscall3(int,write,int,fd, const char*, buf, 参数个数 unsigned int,count) 其中,兰色字符串是write()系统调用需 其中,兰色字符串是 系统调用需 要的3对参数 对参数。 要的 对参数。 可以按照程序清单10-1把 把 可以按照程序清单 _syscall3(int,write,┅)宏展开成下面的代码: 宏展开成下面的代码: ┅ 宏展开成下面的代码
第10章 10章 系统调用接口
系统调用接口的功能
内核为用户与硬件设备(例如: 内核为用户与硬件设备 例如:CPU,磁 例如 , 打印机等)交互提供了一个接口 交互提供了一个接口。 盘,打印机等 交互提供了一个接口。该 接口被称为系统调用接口。它的功能是: 接口被称为系统调用接口。它的功能是: 使用户编程更加容易, 使用户编程更加容易,把用户从学习硬件 设备的低级编程特性中解放出来。 设备的低级编程特性中解放出来。 可以极大提高系统的安全性, 可以极大提高系统的安全性,因为内核接 收用户请求之前,可以检查其合法性。 收用户请求之前,可以检查其合法性。 使用系统调用接口使得程序具有良好的可 移植性。 移植性。

linux动态库和静态库调用方法

linux动态库和静态库调用方法

linux动态库和静态库调用方法
在Linux操作系统中,动态库和静态库的调用方法如下:
1. 动态库(Shared Library):动态库在程序运行时被载入内存,可以被多个程序同时使用,节省内存空间。

在Linux中,动态库一般存放在/usr/lib或/lib目录下。

调用方法:在程序中使用extern "C"来声明函数接口,然后通过dlopen(), dlsym()等函数来动态调用动态库中的函数。

2. 静态库(Static Library):静态库在程序编译时被包含进可执行程序中,每个程序都有一份自己的库副本。

静态库一般存放在/usr/lib或/lib目录下。

调用方法:在程序中直接使用静态库中的函数,不需要额外的调用方法。

只需要在编译时使用"-l"选项指定要链接的库名,例如"gcc -o test test.c -lmylib"。

需要注意的是,对于动态库和静态库的使用,一般建议优先使用动态库,因为这样可以节省内存空间,并且可以在不停止程序运行的情况下更新库文件。

第1页/ 共1页。

linux hook系统调用函数

linux hook系统调用函数

linux hook系统调用函数
Linux的hook系统调用函数是指在系统调用执行之前或之后,
通过注入自定义代码来拦截和修改系统调用的过程。

这种机制可以用于实现一些安全措施,例如检测和防止恶意软件的行为,或者限制用户对系统资源的访问。

hook系统调用函数的实现方式有多种,其中比较常用的是使用
内核模块来实现。

内核模块可以通过注册自定义的处理函数来拦截指定的系统调用,并在需要的时候调用原始的系统调用函数或者执行自己的逻辑。

例如,可以编写一个hook系统调用函数来监控用户进程
的文件打开操作,以此来检测和防止恶意软件对系统文件的篡改。

需要注意的是,hook系统调用函数可能会对系统性能产生一定
的影响,因此应该谨慎使用。

此外,由于hook系统调用函数在内核
层面进行操作,因此编写和调试这类代码需要一定的专业知识和技能。

总之,Linux的hook系统调用函数是一种非常有用的机制,可
以为我们提供更多的安全保障和系统控制能力。

然而,在使用之前,我们需要充分了解其实现方式和潜在的影响,以确保其能够正确地工作并不会对系统性能造成过大的影响。

- 1 -。

linux sys_execve 用法

linux sys_execve 用法

linux sys_execve 用法sys_execve 是Linux 系统调用,用于在当前进程上下文中执行一个新程序。

这个系统调用实际上是由execve 库函数在用户空间提供的接口背后所调用的。

sys_execve 的原型如下:cint execve(const char *filename, char *const argv[], char *const envp[]);参数说明:filename:要执行的程序的路径名。

argv:一个字符串数组,其中每个字符串都是传递给新程序的命令行参数。

这个数组必须以一个空指针结束。

envp:一个字符串数组,其中每个字符串都定义了新程序的环境变量。

这个数组也必须以一个空指针结束。

如果你不关心环境变量,可以传递NULL。

返回值:如果成功,execve 不会返回,因为调用进程的映像已经被新程序替换。

如果出现错误,它会返回-1,并设置全局错误变量errno 以指示发生了什么错误。

注意:由于execve 替换当前进程的映像,所以它会丢失所有当前进程的内存内容(除了某些特定的内容,如打开的文件描述符)。

示例用法:c#include <unistd.h>#include <stdio.h>#include <stdlib.h>int main() {char *argv[] = {"/bin/ls", "-l", NULL};char *envp[] = {NULL}; // 使用当前环境,或者你可以定义自己的环境变量if (execve("/bin/ls", argv, envp) == -1) {perror("execve"); // 打印出错误信息exit(EXIT_FAILURE);}// 如果execve 成功,以下代码不会被执行exit(EXIT_SUCCESS); // 这只是为了完整性而写的,实际上永远不会被执行到}在这个例子中,我们使用execve 来执行/bin/ls 命令并传递-l 参数给它。

linux 系统调用流程

linux 系统调用流程

linux 系统调用流程Linux系统调用流程一、引言Linux是一种自由开源的操作系统,其核心部分是内核。

内核负责管理计算机的硬件资源,并提供各种系统调用供用户程序使用。

本文将介绍Linux系统调用的流程,包括用户程序如何通过系统调用接口向内核发起请求以及内核如何处理这些请求。

二、系统调用的定义系统调用是用户程序与内核之间的接口。

用户程序通过调用特定的系统调用函数来请求内核执行某些操作,例如读写文件、创建进程等。

内核接收到这些请求后,会进行相应的处理并返回结果给用户程序。

三、系统调用的流程1. 用户程序发起系统调用请求用户程序通过调用系统调用函数向内核发起请求。

这些系统调用函数通常由C库提供,并在用户程序中使用。

用户程序需要提供相应的参数,以告知内核所需的操作类型和操作对象。

2. 用户程序转入内核态用户程序发起系统调用请求后,会进入内核态。

在内核态下,用户程序的权限更高,可以执行一些普通用户无法执行的操作,例如访问硬件资源。

3. 内核处理系统调用请求内核接收到系统调用请求后,会根据请求的类型和参数进行相应的处理。

内核会首先检查请求的合法性,验证用户程序的权限和参数的有效性。

如果请求合法,内核会执行相应的操作;如果请求非法,内核会返回错误信息给用户程序。

4. 内核执行系统调用操作内核根据系统调用请求的类型和参数执行相应的操作。

例如,如果用户程序请求打开一个文件,内核会检查文件是否存在,并分配相应的文件描述符。

如果用户程序请求创建一个进程,内核会为进程分配资源并初始化进程上下文。

5. 内核返回结果给用户程序内核在执行完系统调用操作后,会将结果返回给用户程序。

如果操作成功,内核会返回相应的数据或完成状态;如果操作失败,内核会返回错误码,用户程序可以根据错误码进行相应的处理。

6. 用户程序继续执行用户程序在接收到内核返回的结果后,会根据结果进行相应的处理。

如果操作成功,用户程序可以继续执行后续的逻辑;如果操作失败,用户程序可以根据错误码采取相应的措施,例如重新尝试或向用户报告错误信息。

Linux系统调用详细全过程

方法分配和释放内存。
6
系统命令、内核函数
系统调用与系统命令

系统命令相对API来说,更高一层。每个系统命令
都是一个执行程序,如ls命令等。这些命令的实现
调用了系统调用。
系统调用与内核函数


系统调用是用户进入内核的接口层,它本身并非内
核函数,但是它由内核函数实现。
进入内核后,不同的系统调用会找到各自对应的内
常,CPU便被切换到内核态执行内核函
数,转到了系统调用处理程序的入口:
system_call()。
int $0x80指令将用户态的执行模式转变为内
核态,并将控制权交给系统调用过程的起点
system_call()处理函数。
4
system_call()函数
system_cal()检查系统调用号,该号码告诉内核
SYMBOL_NAME(sys_exit)
.long
.longSYMBOL_NAME(sys_read)
SYMBOL_NAME(sys_fork)
.long
.longSYMBOL_NAME(sys_write)
SYMBOL_NAME(sys_read)
.long
.longSYMBOL_NAME(sys_open)
SYMBOL_NAME(sys_write)
.long
.long
…… SYMBOL_NAME(sys_open)
……
……
……
.long
SYMBOL_NAME(sys_getuid)
.long SYMBOL_NAME(sys_getuid)
* 4
+
21
系统调用的返回
当服务例程结束时,system_call( ) 从eax

linux系统调用 api 手册

linux系统调用 api 手册【实用版】目录I.Linux 系统调用 API 手册概述II.Linux 系统调用 API 的功能III.Linux 系统调用 API 的使用方法IV.Linux 系统调用 API 的示例正文I.Linux 系统调用 API 手册概述Linux 系统调用 API 手册是指提供了一系列用于在 Linux 系统中调用系统功能的 API 函数。

这些 API 函数可以让程序员在编写程序时,更加方便、高效地与 Linux 系统进行交互,实现各种系统操作。

II.Linux 系统调用 API 的功能Linux 系统调用 API 的功能主要包括以下几个方面:1.文件操作:包括文件的打开、关闭、读取、写入等操作。

2.进程管理:包括进程的创建、终止、切换等操作。

3.系统管理:包括系统时间的获取、设置,内存的管理等操作。

4.网络操作:包括网络套接字的创建、连接、接收、发送等操作。

III.Linux 系统调用 API 的使用方法要使用 Linux 系统调用 API,首先需要在程序中包含相应的头文件,然后调用相应的函数。

例如,要使用文件操作相关的 API,需要在程序中包含`<unistd.h>`头文件,然后调用如`open()`、`read()`、`write()`等函数。

IV.Linux 系统调用 API 的示例以下是一个简单的使用 Linux 系统调用 API 的示例,该示例展示了如何使用`read()`和`write()`函数实现文件的读写操作:```c#include <stdio.h>#include <unistd.h>int main() {int fd = open("example.txt", O_RDWR);if (fd < 0) {perror("Error opening file");return -1;}char buffer[1024];if (read(fd, buffer, 1024) < 0) {perror("Error reading from file");return -1;}printf("Content of file: %s", buffer);char new_content[1024] = "Hello, world!";if (write(fd, new_content, 1024) < 0) {perror("Error writing to file");return -1;}printf("New content written to file.");close(fd);return 0;}```在这个示例中,我们首先使用`open()`函数打开名为`example.txt`的文件,然后使用`read()`函数从文件中读取内容,使用`write()`函数向文件中写入新内容。

linux 系统调用号表

linux 系统调用号表Linux系统调用号表是一个非常重要的概念,它提供了Linux操作系统中各种系统调用的编号及其对应的功能。

系统调用是操作系统提供给用户程序使用的一组接口,通过系统调用,用户程序可以请求操作系统执行特定的功能,如文件操作、进程管理等。

Linux系统调用号表是一个包含了众多系统调用的列表,每个系统调用都有一个唯一的编号。

这个编号是操作系统内部用来标识不同系统调用的方式之一。

通过使用系统调用号,用户程序可以向操作系统发起请求,告诉操作系统需要执行哪个系统调用。

在Linux系统中,系统调用号表是以数组的形式存在的。

数组的每个元素对应一个系统调用,其值为该系统调用的编号。

通过查阅系统调用号表,用户程序可以获知每个系统调用的编号,从而方便地使用系统调用提供的功能。

系统调用号表的设计是经过精心考虑的,每个系统调用的编号都是根据其功能特点和使用频率来确定的。

编号的分配是有一定规律的,相似功能的系统调用通常会有相近的编号,这样可以方便用户程序记忆和使用。

系统调用号表的设计是为了方便用户程序开发者使用系统调用,提供了一种统一的方式来标识和调用系统调用。

通过使用系统调用号表,用户程序可以直接通过编号来调用系统调用,而不需要知道系统调用的具体名称和实现细节。

Linux系统调用号表是Linux操作系统中一个重要的数据结构,它提供了系统调用的编号及其对应的功能。

通过使用系统调用号表,用户程序可以方便地调用系统调用,从而实现各种功能。

这个表的设计是经过精心考虑的,以方便用户程序的开发和使用。

无论是文件操作、进程管理还是其他功能,系统调用号表都为用户程序提供了一个统一的接口。

linux hook系统调用函数

linux hook系统调用函数Linux中的hook系统调用函数是一种操作系统机制,允许用户程序在系统函数执行时注入自己的代码。

这个机制为系统的安全性、性能调优和应用方便提供了很好的途径,因此也成为了Linux内核中非常重要的一个特性。

hook函数的定义和实现是很简单的,一个hook函数是一个被插入到系统调用链表的函数指针,当系统调用相应的函数被触发时,操作系统就会按顺序调用这些函数。

在这些函数中,用户程序可以进行一些自己的操作,比如在系统调用前检测输入参数的有效性,或者在系统调用完成后添加其他处理。

1. SYS_clone:允许多个进程同时运行,该系统调用复制一个新的进程。

2. SYS_fork:同样也是创建子进程的系统调用,但是新创建的进程将完全继承父进程的环境。

3. SYS_execve:替换当前进程的用户空间内容,允许程序在运行时加载新的代码。

5. SYS_exit:系统自动完成进程销毁等操作。

6. SYS_chdir:改变所在路径。

7. SYS_open:打开文件并返回文件描述符。

8. SYS_read:读取文件内容。

9. SYS_write:将数据写入文件。

10. SYS_close:关闭文件。

Linux的hook系统调用函数非常灵活,用户程序可以根据需要注入不同的操作代码来完成某些操作。

但是,注入的代码必须要十分精炼,避免对系统的性能造成不必要的损失或者对系统的安全性造成潜在威胁。

Linux中的hook机制不仅在用户程序中得到广泛应用,还在许多开源软件和内核补丁中得到了广泛使用。

在Linux的安全性、性能调优和应用方便这些方面,hook机制都起到了至关重要的作用。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档