首页
社区
课程
招聘
[求助]控制台程序窗口如何取消?
发表于: 2007-11-24 08:45 8656

[求助]控制台程序窗口如何取消?

2007-11-24 08:45
8656
有一个用C写的控制台程序

运行参数:ABC.exe 123.txt B

如何用另外一个程序打开它(还有输入参数)

且不显示DOS窗口,在后台运行。。。

可以实现吗!望高手指点。。。


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (11)
雪    币: 2134
活跃值: (14)
能力值: (RANK:170 )
在线值:
发帖
回帖
粉丝
2
你用了控制台输入输出吗,如果有的话可以改为debugprint之类,或者输出到文件
然后改为/subsystem:windows应该就可以,另外可以写为服务
2007-11-24 10:04
0
雪    币: 375
活跃值: (12)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
3
当初不用控制台就要可以了嘛~

改连接参数是可以的。
2007-11-24 11:12
0
雪    币: 230
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
你应该要的是这样吧。蓝色部份换成你的命令。要注意程序的路径.

.data
szCommand        db 'cmd.exe /c ping www.pediy.com -n 10 >a.txt',0
;szCommand         db 'NOTEPAD.EXE',0
stStartup    STARTUPINFO <?>
stProcess    PROCESS_INFORMATION <?>
szMsg                db '成功运行',0

.code

start:
       
        invoke GetStartupInfo,addr stStartup
        mov stStartup.dwFlags,STARTF_USESHOWWINDOW
        mov stStartup.wShowWindow,SW_HIDE
        invoke CreateProcess,0,addr szCommand,0,0, 1, \
                NORMAL_PRIORITY_CLASS,NULL,NULL,addr stStartup,addr stProcess
        .if eax
                invoke MessageBox,0,addr szCommand,addr szMsg,MB_OK               
        .endif

        invoke ExitProcess,0

end start
2007-11-24 13:20
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
cmd.exe /c ping www.pediy.com -n 10 >a.txt',0

这个是什么意思?

没学过ASM写程序,大体看得懂一点...

那个控制台程序不是我写的,是一个小形的编译器,我想写一个窗口调用他
2007-11-24 19:06
0
雪    币: 415
活跃值: (34)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
楼上,意思是把结果输入到a.txt文件中.
2007-11-24 19:48
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
7
同意四楼的办法
2007-11-24 22:44
0
雪    币: 297
活跃值: (10)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
8
不知道楼主到底是什么需求?
1: 输出重定向?
解决方法: 你可以用CreateProcess来创建.其中参数里的STARTUPINFO结构里有一个HANDLE hStdOutput,这就是一个重定向输出的句柄.他可以是一个socket句柄或者文件句柄、管道句柄.你可以通过wShowWindow设置为SW_HIDE 同时把dwFlags设置为STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES,  然后为这个程序的输出重定向创建一个匿名管道,接着可以用PeekNamedPipe()来捕获管道输出的信息,从而实时输出在你的GUI程序中.

2:或者把标注输出重定向侄某个文件中.
这是ring3下偶做的一个DbgPrint.

// dgb_prt.h

#include <windows.h>

#define _DEBUG_INFO_FILE  "gfx_dbg_info.txt" // 修改这里的输出文件

VOID _cdecl __DPrt(const WCHAR *fmt, ...);
VOID _cdecl __RPrt(const WCHAR *fmt, ...);
VOID _cdecl __ADPrt(BOOL, const WCHAR *fmt, ...);
VOID _cdecl __ARPrt(BOOL, const WCHAR *fmt, ...);

#ifndef NDEBUG
# define _DbgPrt __DPrt
#else
# define _DbgPrt __RPrt
#endif

#ifndef NDEBUG
# define _AstPrt __ADPrt
#else
# define _AstPrt __ARPrt
#endif


 


// dbg_prt.cpp

 // -------------------------------------------------------------------------
#define _STDOUT_FP        (1)

#define _DEBUG_INFO_FILE  "dbg_info.txt"

// -------------------------------------------------------------------------
typedef struct __DbgPrtPara
{
 FILE *pfp;
 int   pfd;
 unsigned long pret;
} _DbgPrtPara, *_PDbgPrtPara;

_PDbgPrtPara __stdcall __DPrtInit()
{
 _PDbgPrtPara pDbgPara = (_PDbgPrtPara)malloc(sizeof(_DbgPrtPara));
 pDbgPara->pfd = _dup(_STDOUT_FP);
 pDbgPara->pfp = freopen(_DEBUG_INFO_FILE, "a+", stdout);
 unsigned short buff[128] = {'\0'};
 _wstrtime(buff);
 wprintf(L"%s: ", buff);
 return pDbgPara;
}

void __stdcall __DPrtClose(_PDbgPrtPara pDbgPara)
{
 fflush(pDbgPara->pfp);
 fclose(pDbgPara->pfp);
 _dup2(pDbgPara->pfd, _STDOUT_FP);
 free(pDbgPara);
 pDbgPara = NULL;
}

// -------------------------------------------------------------------------
__declspec(naked) void __DPrt(const unsigned short *fmt, ...)
{
 
#ifdef _M_IX86
 
 __asm{
  call    __DPrtInit
  pop     ebx
  mov     dword ptr [eax + 8], ebx
  mov     ebx, eax
  
  call    dword ptr [wprintf]
  
  push    ebx
  mov     eax, dword ptr [ebx + 8]
  mov     ebx, eax
  call    __DPrtClose
  push    ebx
  ret
 }
 
#endif
 
}

// -------------------------------------------------------------------------
void __RPrt(const unsigned short *fmt, ...)
{
 
}


// -------------------------------------------------------------------------
__declspec(naked) void __ADPrt(unsigned long, const unsigned short *fmt, ...)
{
 
#ifdef _M_IX86
 
 __asm{
  mov     eax, dword ptr [esp + 4]
  cmp     eax, 0
  je      EXE_TRUE
  ret
EXE_TRUE:
  call    __DPrtInit
  pop     ebx
  mov     dword ptr [eax + 8], ebx
  mov     ebx, eax
  pop     eax
  
  call    dword ptr [wprintf]
  
  push    ebx
  mov     eax, dword ptr [ebx + 8]
  mov     ebx, eax
  call    __DPrtClose
  sub     esp, 4
  push    ebx
  ret
 }
 
#endif
 
}

// -------------------------------------------------------------------------
void _cdecl __ARPrt(unsigned long, const unsigned short *fmt, ...)
{
 
}

// -------------------------------------------------------------------------

2007-11-24 23:03
0
雪    币: 112
活跃值: (16)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
9
先看看PE文件结构:
    +-------------------+
    |       MZ头部       |
    +-------------------+
    | DOS-stub           |
    +-------------------+
    | file-header        |
    +- - - - - - - - - - -+
    | optional header |
    |- - - - - - - - - - - -|
    |                           |
    | data directories |
    |                           |
    +-------------------+
    |                           |
    | section headers |
    |                           |
    +-------------------+
    |                           |
    | section 1            |
    |                          |
    +-------------- ---+
    |                          |
    | section 2           |
    |                          |
    +------------------+
    |                          |
    | ...                     |
    |                          |
    +-------------------+
    |                           |
    | section n           |
    |                           |
    +-------------------+
    |     ....                 |
    +-------------------+
DOS-stub and Signature
----------------------
DOS STUB的概念在16位WINDOWS可执行文件内就已经被熟知了,STUB是用于OS/2可执行文件,自解压文档和其他程序。对于PE文件,它是DOS2兼容可执行文件,总是包含100字节内容,输出一个错误信息:比如"this program needs windows NT".
你认识到一个DOSSTUB通过验证DOS-header,就是一个IMAGE_DOS_HEADER结构,前两个字节必须使"MZ"(有一个定义针对这个WORD,IMAGE_DOS_SIGNATURE )。你通过尾部的'e_lfanew' 给出的偏移量所确定的签名区别一个PE文件。对于PE文件,它是一个32位,按照8字节对齐边界。其值0x00004550由IMAGE_NT_SIGNATURE 定义.

IMAGE_NT_HEADERS STRUCT
  Signature         DWORD                   ?
  FileHeader        IMAGE_FILE_HEADER       <>
  OptionalHeader    IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS

文件头File Header
-----------
IMAGE_FILE_HEADER STRUCT
  Machine               WORD    ?
  NumberOfSections      WORD    ?
  TimeDateStamp         DWORD   ?
  PointerToSymbolTable  DWORD   ?
  NumberOfSymbols       DWORD   ?
  SizeOfOptionalHeader  WORD    ?
  Characteristics       WORD    ?
IMAGE_FILE_HEADER ENDS

要得到IMAGE_FILE_HEADER,确认DOS头的前2个字节"MZ",然后找到'e_lfanew'成员,然后从文件开始跳过许多字节,验证你找到的签名。文件头作为一个IMAGE_FILE_HEADER结构,就从它后面开始。从上到下描述其成员。

第1:Machine, 16位值,指明可执行文件所需要的系统。已知合法值如下:
    IMAGE_FILE_MACHINE_I386
    0x014c  Intel 80386 处理器。
    0x014d  Intel 80486处理器
    0x014e  Pentium 处理器
    0x0160  R3000 (MIPS)处理器
    IMAGE_FILE_MACHINE_R3000 (0x162) R3000 (MIPS)处理器
    IMAGE_FILE_MACHINE_R4000 (0x166) R4000 (MIPS)处理器
    IMAGE_FILE_MACHINE_R10000 (0x168)R10000 (MIPS)处理器
    IMAGE_FILE_MACHINE_ALPHA (0x184) DEC Alpha AXP处理器
    IMAGE_FILE_MACHINE_POWERPC (0x1F0)IBM Power PC处理器
第2:NumberOfSections,16位值,它是跟随于头后面的节数。我们在后面讨论。
第3:TimeDateStamp,32位值,文件创建的时间。可以通过该值区分不同的文件版本。时间戳用于绑定输入目录,后面讲到。有些连接器设置该值为荒唐的值。
第3:PointerToSymbolTable和NumberOfSymbols,都是32位的。用于调试信息。一般都是0。
第4:SizeOfOptionalHeader,16位,是IMAGE_OPTIONAL_HEADER的尺寸.可以用它确认PE文件结构的正确性。
第5:Characteristics,16位值,包括一个标志集合,多数只对目标文件和库有效。
    Bit 0 (IMAGE_FILE_RELOCS_STRIPPED) 如果文件内没有重定位信息该位置1。这里指的是每个节内的重定位信息。不用于可执行文件,可执行文件的重定位信息在后面提到的base relocation目录。
    Bit 1 (IMAGE_FILE_EXECUTABLE_IMAGE) 如果文件是可执行的则置1,例如不是一个目标文件或者库文件。如果连接器试图创建可执行文件,但由于某种原因失败了,也置1。
    Bit 2 (IMAGE_FILE_LINE_NUMS_STRIPPED)如果行数信息剥离,置1,对可执行文件无效。
    Bit 3 (IMAGE_FILE_LOCAL_SYMS_STRIPPED) 如果没有本地符号信息该位置1。对可执行文件无效。
    Bit 4 (IMAGE_FILE_AGGRESIVE_WS_TRIM) 如果操作系统被假定通过页换出抢占式修剪进程的工作集(进程使用的内存数),该位置1。
    Bits 7 (IMAGE_FILE_BYTES_REVERSED_LO)和15(IMAGE_FILE_BYTES_REVERSED_HI) 如果文件的的endianess不是机器期望的,则置1,于是读之前必须交换字节。对可执行文件不可靠。
    Bit 8 (IMAGE_FILE_32BIT_MACHINE) 如果机器被期望是32位机器,置1。
    Bit 9 (IMAGE_FILE_DEBUG_STRIPPED)如果没有调试信息在文件内,置1。对可执行文件无效。
    Bit 10 (IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP) 如果程序不能够从可移动媒体比如软盘或光驱,置1。操作系统建议拷贝文件到交换文件然后执行。
    Bit 11 (IMAGE_FILE_NET_RUN_FROM_SWAP) 如果不能够才网络运行,置1。操作系统建议拷贝文件到交换文件然后执行。
    Bit 12 (IMAGE_FILE_SYSTEM) 如果文件是类似驱动程序的系统文件,置1。对执行文件无效。
    Bit 13 (IMAGE_FILE_DLL) 如果文件是DLL,置1.
    Bit 14 (IMAGE_FILE_UP_SYSTEM_ONLY) 如果文件不是为多处理器设计的,置1 。

相对虚拟地址Relative Virtual Addresses
--------------------------
PE格式使用所谓的RVA。用于描述内存地址,如果你不知道基地址的话。需要你加上基地址得到线性地址。基地址是PE映像加载的地址。例如:假如可执行文件加载到0x400000,可执行文件的RVA是0x1560. 有效执行起始地址为0x401560.如果被加载到0x100000,则执行起始位置在0x101560.

情况变的复杂起来,由于节不必按照加载的映像那样对齐。例如,节一般按照512字节对齐。加载的映像可能按照4096字节对齐。参看'SectionAlignment' and 'FileAlignment' 。对齐的意思就是地址值=对齐长度的倍数。

于是为了找到一个特殊的RVA指向的信息,你必须计算偏移量好象文件被加载一样。假如知道执行起点在RVA 0x1560, 想从这反汇编代码。要找到文件内的地址,你必须找出在RAM内的按照4096对齐的节,".code"节自内存RVA 0x1000开始,16384字节长,你知道RVA 0x1560的偏移量在那个节内是0x560.找出节在文件内按照512字节对齐,且".code"从0x800开始,那么在文件内的代码执行起点是0x800+0x560=0xd60。
然后反汇编,并发现一个存取地址0x1051d0处的变量.线性地址在加载执行文件时重新分配,并给出优先加载地址。你发现优先加载地址是0x100000,于是我们处理RVA 0x51d0. 这是一个开始于RVA 0x5000的数据区,2048字节长。它开始于文件偏移量0x4800.变量可以在文件偏移量0x4800+0x51d0-0x5000=0x49d0处发现。

可选头Optional Header
---------------
紧跟在文件头的后面是IMAGE_OPTIONAL_HEADER,尽管名字是可选,实际一直存在。包含关于如何精确处理PE文件的信息。从上到下介绍成员。
IMAGE_OPTIONAL_HEADER32 STRUCT
  Magic                         WORD       ?
  MajorLinkerVersion            BYTE       ?
  MinorLinkerVersion            BYTE       ?
  SizeOfCode                    DWORD      ?
  SizeOfInitializedData         DWORD      ?
  SizeOfUninitializedData       DWORD      ?
  AddressOfEntryPoint           DWORD      ?
  BaseOfCode                    DWORD      ?
  BaseOfData                    DWORD      ?
  ImageBase                     DWORD      ?
  SectionAlignment              DWORD      ?
  FileAlignment                 DWORD      ?
  MajorOperatingSystemVersion   WORD       ?
  MinorOperatingSystemVersion   WORD       ?
  MajorImageVersion             WORD       ?
  MinorImageVersion             WORD       ?
  MajorSubsystemVersion         WORD       ?
  MinorSubsystemVersion         WORD       ?
  Win32VersionValue             DWORD      ?
  SizeOfImage                   DWORD      ?
  SizeOfHeaders                 DWORD      ?
  CheckSum                      DWORD      ?
  Subsystem                     WORD       ?
  DllCharacteristics            WORD       ?
  SizeOfStackReserve            DWORD      ?
  SizeOfStackCommit             DWORD      ?
  SizeOfHeapReserve             DWORD      ?
  SizeOfHeapCommit              DWORD      ?
  LoaderFlags                   DWORD      ?
  NumberOfRvaAndSizes           DWORD      ?
  DataDirectory                 IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<> )
IMAGE_OPTIONAL_HEADER32 ENDS
IMAGE_OPTIONAL_HEADER  equ  <IMAGE_OPTIONAL_HEADER32>

第1个16位字是'Magic',总是0x010b.

下面2个字节是连接器的版本号'MajorLinkerVersion'和'MinorLinkerVersion',这些值都不可靠,不能总是妥当的反映连接器版本。有些连接器不设置该域。

下面3个longwords(32位)指定执行代码尺寸('SizeOfCode'),初始化数据尺寸
'SizeOfInitializedData', 所谓的数据段"data segment", 未初始化数据尺寸
'SizeOfUninitializedData',所谓的"bss segment".这些数值也不可靠。

往下一个32位的RVA.是入口点的偏移量。('AddressOfEntryPoint').执行从此开始。

下面2个32位是可执行代码('BaseOfCode')和初始化数据('BaseOfData')的RVAs 我们对它没有兴趣,因为可以通过节来查看更可靠的信息。非初始化数据没有RVA。

下面是一个32位值,ImageBase'作为整个文件的优先加载地址,包括所有头在内。该值总是
64KB的倍数,文件已经被连接器重定位,如果文件能够真正加载到这个地址,加载器不必重定位文件。如果另一个映像已经被加载到那个地址,则优先地址不可使用。这种情况下,映像被加载到其他地址,需要重定位。如果映像是DLL,还有更多结果,因为"bound imports"不再有效,需要对使用DLL的执行文件进行修正。参见'import directory' 。

下面2个32位是当映像文件加载后,PE文件的节在内存内的对齐,'SectionAlignment', 以及在文件内的对齐'FileAlignment'. 一般文件对齐是512,节对齐是4096.

下面2个16位的字是期望的操作系统版本,'MajorOperatingSystemVersion'和 'MinorOperatingSystemVersion'。

下面2个16位的字是期望的可执行文件版本,'MajorImageVersion'和
'MinorImageVersion'. 许多连接器不正确设置这些信息。

下面2个16位的字是期望的子系统版本,'MajorSubsystemVersion和MinorSubsystemVersion. 这个必须是Win32版本或者POSIX版本。该版本需要正确提供,因为它被检查并使用。如果程序是Win32-GUI并运行在NT4,子系统版本不是4.0,对话框不是3D效果。

然后是Win32VersionValue,32位。大部分情况下是0。

下面是32位的映像需要的内存数量'SizeOfImage'.是所有的头和节的总和,如果节已经对齐。它是给加载器的线索,需要多少页加载映像。

下面一个是32位的所有头的总和,包括数据目录和节头。'SizeOfHeaders'.它也是才文件开始到第一节的偏移量。

然后是32位的校验码'CheckSum'.对当前版本的NT,只校验映像是否是NT驱动程序。对于其他可执行文件类型,不必提供这个码,可能为0。

然后是16的子系统Subsystem'表明在什么系统上运行:
    IMAGE_SUBSYSTEM_NATIVE (1)执行文件不需要子系统,用于驱动程序。
    IMAGE_SUBSYSTEM_WINDOWS_GUI (2)映像是Win32图形程序可以打开控制台   
    IMAGE_SUBSYSTEM_WINDOWS_CUI (3)映像是Win32控制台程序,可以得到缺省控制台。
    IMAGE_SUBSYSTEM_OS2_CUI (5)映像是OS/2 控制台,程序是OS/2格式。   
    IMAGE_SUBSYSTEM_POSIX_CUI (7)映像使用POSIX控制台子系统
Windows 95可执行文件总是使用Win32 subsystem,于是合法值是2和3。

下面是16位,DllCharacteristics,表明是否是DLL,如果0位置1,DLL被通知进程结合。位1置1,DLL被通知线程脱离。位2置1,DLL被通知线程结合。位3置1,DLL被通知进程脱离。

下面4个 32 位预留堆栈大小'SizeOfStackReserve',提交的堆栈大小'SizeOfStackCommit',预留的堆的大小'SizeOfHeapReserve'和提交的的堆的的大小'SizeOfHeapCommit'.

预留数量是地址空间不是真实的RAM,程序启动时,提交的数量是真正的分配的内存。这个值也是堆和栈根据需要增长的一个数量。
例如:一个程序预留1 MB的堆并提交的堆时64KB,该堆就从64KB开始,并保证可以加大到1MB.堆将以64KB块增长。该堆在这里是主要堆,默认堆。一个进程可以创建多个堆如果需要的话。栈是第一个线程的栈,进程可以创建许多线程,每个都有自己的堆栈,DLLs 没有栈或者堆,于是在其映像内该值被忽略。

下面是32位的LoaderFlags, 没有用。

然后是32位的NumberOfRvaAndSizes,在随后的目录内的有效项目数。最好使用
IMAGE_NUMBEROF_DIRECTORY_ENTRIES,即16。

下面是具有IMAGE_NUMBEROF_DIRECTORY_ENTRIES(16)个成员的IMAGE_DATA_DIRECTORYs结构数组.

IMAGE_DATA_DIRECTORY STRUCT
  VirtualAddress    DWORD      ?
  isize             DWORD      ?
IMAGE_DATA_DIRECTORY ENDS

每个目录描述了节内特定信息位置,32 bits RVA VirtualAddress 和尺寸32 bit,各个成员索引如下(括号内为索引值):
    IMAGE_DIRECTORY_ENTRY_EXPORT (0)输出符号目录用于DLL   
    IMAGE_DIRECTORY_ENTRY_IMPORT (1)输入符号目录   
    IMAGE_DIRECTORY_ENTRY_RESOURCE (2)资源目录   
    IMAGE_DIRECTORY_ENTRY_EXCEPTION (3)异常目录   
    IMAGE_DIRECTORY_ENTRY_SECURITY (4)安全目录   
    IMAGE_DIRECTORY_ENTRY_BASERELOC (5)重定位表   
    IMAGE_DIRECTORY_ENTRY_DEBUG (6)调试目录
    IMAGE_DIRECTORY_ENTRY_COPYRIGHT (7)描述版权串   
    IMAGE_DIRECTORY_ENTRY_GLOBALPTR (8)机器值   
    IMAGE_DIRECTORY_ENTRY_TLS (9)Thread local storage目录
    IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG (10)Load configuration 目录   
    IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (11)Bound import directory目录   
    IMAGE_DIRECTORY_ENTRY_IAT (12)Import Address Table输入地址表目录

例如,如果我们找到索引7的2个值0x12000和33, 加载地址是0x10000, 我们知道版权数据是在 0x10000+0x12000,版权字数为33。如果一个特定类型的目录没有被使用,地址和尺寸都为0。

看完这个答案也就很明显了,只要把PE文件头的这个IMAGE_NT_HEADERS ->IMAGE_OPTIONAL_HEADER ->Subsystem值修改一下也就可以了,修改为2,
    IMAGE_SUBSYSTEM_WINDOWS_GUI (2)映像是Win32图形程序可以打开控制台   
    IMAGE_SUBSYSTEM_WINDOWS_CUI (3)映像是Win32控制台程序,可以得到缺省控制台。
2就代表映像是Win32图形程序,原本的那个控制台就不会显示出来了,
至于怎么修改,方法很多,可以用PE编辑器实现数据的修改,麻烦点的话,用16进制打开器打开exe程序找到子系统的标志,也可以修改的,当然,自己写程序修改也可以.LOADPE,PEDITOR都可以
2007-11-25 01:01
0
雪    币: 221
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
问题解决了

谢谢各位的指点!!按照[壹只老虎]说的方法,把03改为02就可以了!!
2007-11-25 02:08
0
雪    币: 486
活跃值: (13)
能力值: ( LV9,RANK:430 )
在线值:
发帖
回帖
粉丝
11
好帖,支持一下。
2007-11-26 08:19
0
雪    币: 1393
活跃值: (570)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
12
壹只老虎 先看看PE文件结构: &nbsp; &nbsp; +-------------------+ &nbsp; &nbsp; |&nbsp; &nbsp ...
说得清楚,支持一下!
2018-12-5 23:43
0
游客
登录 | 注册 方可回帖
返回
//