dzgdp
驱动牛犊
驱动牛犊
  • 注册日期2004-06-28
  • 最后登录2004-07-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1699回复:13

用汇编语言编写windows2000 xp驱动程序(1)--- Kmdkit的下载和安装

楼主#
更多 发布于:2004-07-01 21:04
    在dos时代,程序可以访问所有的内存和端口,只要你想到的功能,只要付出足够的时间和精力,都可以实现。感觉自己用汇编写的程序就像随时可以大闹天宫的孙悟空,发挥的空间很大,主要看你的能力了。由于喜欢这种感觉,我在的dos下写过很多小程序,我写的《用hdcopy进行加密》曾在《电脑爱好者》杂志上发表。进入windows时代,用上了win9x、win2k、xp以后,再也找不到过去那种感觉了,处处受限制。汇编语言也和vb这种傻的只能用来干活的语言平等了,到处都是清规戒律,我的孙悟空变成唐僧了。为此我苦闷了很久,从看到罗云彬的网站开始学了masm32,他介绍的怎么用汇编来编图形界面,这些我是不学的,因为这不应该是用汇编来做的,用vb和vc更简单啊。后来我学了点保护模式编程的皮毛,知道了windows把自己的内核权限设成了ring0,用户程序运行在ring3,这就是程序处处受限制的原因。只有驱动程序才拥有ring0权限,我要让自己的程序拥有特权,必须通过驱动或象CIH病毒那样走后门。这样的后门在win9x 中使用还比较简单,在win2k中变得复杂而无法忍受。看来在想在win2k下不受限制的编程,只能学编驱动了。
    翻了很多讲解驱动程序编写方面的书,都是介绍怎么用c或c++来写,复杂、难懂,并且需要庞大的开发工具,先安装垃圾代码成堆的恐龙级怪物vc++,然后再安装个什么ddk。我只需要突破ring0的限制,让我的程序有该有的特权,有必要这么复杂吗?
    我一直在寻找用asm编写驱动的工具,终于找到了一个俄罗斯人Four-F的网站http://www.freewebs.com/four-f,他开发了一套工具Kmdkit(Kernel Mode Driver Development Kit for MASM32 ),可以实现我的愿望,看了他写的教程,发现用汇编语言编写windows2000 xp驱动程序竟然如此简单,把我熟悉的win32asm扩充一下,不需要什么vc、ddk之类,就能写驱动了。我的e文不好,只是自己能大约看懂这个网站,不敢把它翻译出来,怕误人子弟。(希望e文好的朋友能把他翻译出来,大家都会感谢你的)。罗嗦了这么多,下面开始来真的:)
    先安装masm32v8,下载地址:http://www.aogosoft.com/downpage.asp?code=download&table=soft&id=25
    安装目录是\masm32\
    下载Kmdkit,地址:http://www.aogosoft.com/bbs/upfile/kmdkit15.zip
    英文教程在http://www.assembly-journal.com/
    Kmdkit只有一个压缩文件kmdkit15.zip,展开后有几个子目录和两个文件install.bat,readme.txt,安装方法很简单,就是:
把 \include\w2k 下的文件拷到 \masm32\include
把 \macros\Strings.mac  下的文件拷到\masm32\macros
把 \lib\w2k 下的文件拷到\masm32\lib
或者直接运行 install.bat,安装完毕。

用汇编语言编写windows2000 xp驱动程序(2)--- 驱动程序的编译和连接
    Kmdkit推荐的方法是把汇编源程序写成批处理bat文件,以天杀的ring0.sys为例
把下面的代码存成ring0.bat

;@echo off
;goto make
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.586P ; 保护模式
.model flat,stdcall
option casemap:none
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
include \masm32\include\w2k\ntddk.inc
; 中断相关数据结构
IDT_REG STRUCT
limit WORD ?
base DWORD ?
IDT_REG ENDS

; 中断描述符
INT_DESCRIPTOR STRUCT
offs0_15 WORD ?
sel WORD ?
paramcnt BYTE ?
attrs BYTE ?
offs16_31 WORD ?
INT_DESCRIPTOR ENDS

;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code
szBuffer db 16 dup(0)
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
MyIntFunc proc
push edx
call eax
iretd
MyIntFunc endp

;====================================================================
AddMyInt proc uses edi
local @IDT

sidt szBuffer
mov edi,(IDT_REG ptr [szBuffer]).base
add edi,21h*8

; 使用Int21中断,该中断在Win2k下没有使用
; cli
mov eax,offset MyIntFunc
mov [edi],ax
shr eax,16
mov [edi+6],ax ; 设置入口地址
mov [edi+2],cs ; 设置段地址
; 设置Ring3可以访问
mov WORD ptr [edi+4],0EE00h
; sti

ret
AddMyInt endp
;====================================================================
WdmUnload proc DriverObject:DWORD
local @IDT

sidt szBuffer
mov edi,(IDT_REG ptr [szBuffer]).base
add edi,21h*8
xor eax,eax
mov [edi],ax
mov [edi+6],ax ; 设置入口地址
mov [edi+2],ax ; 设置段地址
mov WORD ptr [edi+4],ax

ret
WdmUnload endp
;====================================================================
DriverEntry proc DriverObj:DWORD,RegistryPath:DWORD


mov eax,DriverObj
assume eax:ptr DRIVER_OBJECT
mov [eax].DriverUnload,offset WdmUnload
assume eax:nothing
invoke AddMyInt

xor eax,eax
ret
DriverEntry endp
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end DriverEntry

:make

set drv=ring0

\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native

%drv%.obj

del %drv%.obj

echo.
pause
rem =====以上为ring0.bat的内容=============


双击ring0.bat,就完成了编译连接工作,生成了ring0.sys 怎么样?简单吧?

Kmdkit巧妙地把批处理和asm文件结合起来,使编译更傻瓜化。
需要修改代码时,在ring0.bat上点鼠标右键,点编辑。
需要编译时直接双击它.
需要注意的是,\masm32 和ring0.bat必须在一个磁盘上,如masm32安装在c:盘,ring0.bat也必须在c:盘

用汇编语言编写windows2000 xp驱动程序(3)--- 驱动程序的动态加载
    驱动程序做出来后,怎么用呢?根据Four-F的说法,有三种方式:服务控制管理器(Service Control Manager (SCM).)
服务控制程序(Service Control Program (SCP).)和服务程序(service program).
下面我们就用服务控制程序(SCP)来实现驱动程序的动态加载,例子程序在 KmdKit\examples\simple\Beeper
代码如下:
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;  scp.asm
;
;  Service Control Program for beeper.sys driver
;
;  Written by Four-F (four-f@mail.ru)
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.386
.model flat, stdcall
option casemap:none

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                  I N C L U D E   F I L E S                                        
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

include \masm32\include\windows.inc

include \masm32\include\kernel32.inc
include \masm32\include\user32.inc
include \masm32\include\advapi32.inc

includelib \masm32\lib\kernel32.lib
includelib \masm32\lib\user32.lib
includelib \masm32\lib\advapi32.lib

include \masm32\Macros\Strings.mac

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                         C O D E                                                  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.code

start proc

local hSCManager:HANDLE
local hService:HANDLE
local acDriverPath[MAX_PATH]:CHAR

; Open a handle to the SC Manager database
invoke OpenSCManager, NULL, NULL, SC_MANAGER_CREATE_SERVICE
.if eax != NULL
mov hSCManager, eax

push eax
invoke GetFullPathName, $CTA0("beeper.sys"), sizeof acDriverPath, addr acDriverPath, esp
     pop eax

; Register driver in SCM active database
invoke CreateService, hSCManager, $CTA0("beeper"), $CTA0("Nice Melody Beeper"), \
SERVICE_START + DELETE, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, \
SERVICE_ERROR_IGNORE, addr acDriverPath, NULL, NULL, NULL, NULL, NULL
.if eax != NULL
mov hService, eax
invoke StartService, hService, 0, NULL
; Here driver beeper.sys plays its nice melody
; and reports error to be removed from memory
; Remove driver from SCM database
invoke DeleteService, hService
invoke CloseServiceHandle, hService
.else
invoke MessageBox, NULL, $CTA0("Can't register driver."), NULL, MB_ICONSTOP
.endif
invoke CloseServiceHandle, hSCManager
.else
invoke MessageBox, NULL, $CTA0("Can't connect to Service Control Manager."), \
NULL, MB_ICONSTOP
.endif

invoke ExitProcess, 0

start endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                                                                                  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

end start
;=============以下是驱动程序源码beeper.bat的内容===========
;@echo off
;goto make

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;
;  beeper - Kernel Mode Driver
;  Makes beep thorough computer speaker
;
;  Written by Four-F (four-f@mail.ru)
;
;  WARNING: Tested W2000 & XP only!
;
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.386
.model flat, stdcall
option casemap:none

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                  I N C L U D E   F I L E S                                        
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

include \masm32\include\w2k\ntstatus.inc
include \masm32\include\w2k\ntddk.inc

include \masm32\include\w2k\hal.inc

includelib \masm32\lib\w2k\hal.lib

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                           U S E R   D E F I N E D   E Q U A T E S                                
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

TIMER_FREQUENCY equ 1193167 ; 1,193,167 Hz
OCTAVE equ 2

;PITCH_A equ 440 ;  440,00 Hz
;PITCH_As equ 446 ;  466,16 Hz
;PITCH_H equ 494 ;  493,88 Hz
PITCH_C equ 523 ;  523,25 Hz
PITCH_Cs equ 554 ;  554,37 Hz
PITCH_D equ 587 ;  587,33 Hz
PITCH_Ds equ 622 ;  622,25 Hz
PITCH_E equ 659 ;  659,25 Hz
PITCH_F equ 698 ;  698,46 Hz
PITCH_Fs equ 740 ;  739,99 Hz
PITCH_G equ 784 ;  783,99 Hz
PITCH_Gs equ 831 ;  830,61 Hz
PITCH_A equ 880 ;  880,00 Hz
PITCH_As equ 988 ;  987,77 Hz
PITCH_H equ 1047 ; 1046,50 Hz

; We are going to play c-major chord

TONE_1 equ TIMER_FREQUENCY/(PITCH_C*OCTAVE)
TONE_2 equ TIMER_FREQUENCY/(PITCH_E*OCTAVE)
TONE_3 equ (PITCH_G*OCTAVE); for HalMakeBeep

DELAY equ 1800000h ; for my ~800mHz machine

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                           U S E R   D E F I N E D   M A C R O S                                  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DO_DELAY MACRO
; Silly method, but it works ;-)
mov eax, DELAY
.while eax
dec eax
.endw
ENDM

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                          C O D E                                                  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

.code

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                         MakeBeep1                                                
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

MakeBeep1 proc dwPitch:DWORD

; Direct hardware access

cli

mov al, 10110110y
out 43h, al         ; Timer 8253-5 (AT: 8254.2).

mov eax, dwPitch
out 42h, al

mov al, ah
out 42h, al

; speaker ON
in al, 61h
or  al, 11y
out 61h, al

sti

DO_DELAY

cli

; speaker OFF
in al, 61h
and al, 11111100y
out 61h, al

sti

ret

MakeBeep1 endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                            MakeBeep2                                              
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

MakeBeep2 proc dwPitch:DWORD

; Hardware access via HAL using *_PORT_UCHAR/*_PORT_UCHAR functions

cli

invoke WRITE_PORT_UCHAR, 43h, 10110110y

mov eax, dwPitch
invoke WRITE_PORT_UCHAR, 42h, al
mov eax, dwPitch
invoke WRITE_PORT_UCHAR, 42h, ah

; speaker ON
invoke READ_PORT_UCHAR, 61h
or  al, 11y
invoke WRITE_PORT_UCHAR, 61h, al

sti

DO_DELAY

cli

; speaker OFF
invoke READ_PORT_UCHAR, 61h
and al, 11111100y
invoke WRITE_PORT_UCHAR, 61h, al

sti

ret

MakeBeep2 endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                       DriverEntry                                                
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING

invoke MakeBeep1, TONE_1
invoke MakeBeep2, TONE_2

; Hardware access via hal.dll function HalMakeBeep
invoke HalMakeBeep, TONE_3
DO_DELAY
invoke HalMakeBeep, 0

mov eax, STATUS_DEVICE_CONFIGURATION_ERROR
ret

DriverEntry endp

;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
;                                                                                                  
;:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

end DriverEntry

:make

set drv=beeper

\masm32\bin\ml /nologo /c /coff %drv%.bat
\masm32\bin\link /nologo /driver /base:0x10000 /align:32 /out:%drv%.sys /subsystem:native %drv%.obj

del %drv%.obj

echo.
pause
rem=============以上是驱动程序源码beeper.bat的内容===========

我们双击KmdKit\examples\simple\Beeper\下的beeper.bat,编译生成beeper.sys,然后像编译一般的win32asm程序那样编译scp.asm,生成scp.exe,双击scp.exe,你听到了什么?是主板上的喇叭发出的声音,这是通过直接控制端口发出来的,我们已经突破了ring0的限制,高兴吗?

最新喜欢:

dj_ukyodj_uky...
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2004-07-01 22:57
他的开发包不错,里面有很多例子,不过用他来开发驱动很繁琐,所以我还是放弃了,说实在的,玩玩可以,真要是做事就........
而且随着ADM64的流行,以后移植到64位也不方便,嘿嘿......
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
板凳#
发布于:2004-07-01 23:07
如果只要进RING0而已,很简单,WEBCRAZY经典代码我早就改为汇编代码了,有兴趣的话还可以参考MGF的病毒原码,通过直接在NTLDR的GDT中生成CALLGATE后门,可以直接在任意权限下杀入RING0.
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
dzgdp
驱动牛犊
驱动牛犊
  • 注册日期2004-06-28
  • 最后登录2004-07-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2004-07-02 07:58
可以直接在任意权限下杀入RING0?guest权限行吗?
请指教
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地下室#
发布于:2004-07-02 08:57
只要系统加载了NTLDR即可,嘿嘿.......
而且通用于2K/XP/2003,,LONGHORN没测试过,不知道如何......
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
dzgdp
驱动牛犊
驱动牛犊
  • 注册日期2004-06-28
  • 最后登录2004-07-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2004-07-02 11:34
能告诉我在哪里能找到你的汇编代码吗?麻烦你了
lpwnd
驱动小牛
驱动小牛
  • 注册日期2003-03-04
  • 最后登录2012-01-20
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2004-07-02 17:13
very good!
附件名称/大小 下载次数 最后更新
2004-07-02_DRIVER STUDY.chm (190KB)  13
dzgdp
驱动牛犊
驱动牛犊
  • 注册日期2004-06-28
  • 最后登录2004-07-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-07-04 11:00
谢谢
dzgdp
驱动牛犊
驱动牛犊
  • 注册日期2004-06-28
  • 最后登录2004-07-05
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-07-04 11:05
这个我有啊,我想要的是不用驱动杀入ring0的汇编代码啊
lpwnd
驱动小牛
驱动小牛
  • 注册日期2003-03-04
  • 最后登录2012-01-20
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2004-07-05 08:56
估计楼上也是道听图说吧,否则怎么不出现了,嘿嘿。。
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
10楼#
发布于:2004-07-05 10:52
http://www.luocong.com/bbs/dispbbs.asp?BoardID=2&ID=3646
很久以前写的,虽然垃圾,不过可以参考下,嘿嘿.....
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
11楼#
发布于:2004-07-05 10:55
例子里还包括如何从RING3通过GALLGATE把参数传到RING0,不过这里没什么用,嘿嘿......
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
12楼#
发布于:2004-07-05 11:40
wowo的嘿嘿真多,每句话都有嘿嘿,嘿嘿。。。 :D
lpwnd
驱动小牛
驱动小牛
  • 注册日期2003-03-04
  • 最后登录2012-01-20
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望1点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2004-07-05 14:30
wowo,GOOD
游客

返回顶部