SDK的IOS移动端笔记

SDK的IOS移动端笔记

SDK的移动端测试:真机测试、模拟器测试、直接测试、界面测试。

真机测试即:用苹果手机进行测试,真机架构一般是arm系列CPU架构。

模拟器测试即:xcode工具自带的仿真器模块,架构一般是x86_64或i386系列。

直接测试即 :直接建立工程,基于测试demo的调试性测试。

界面测试即:进行简单地APP界面开发,形成简单地测试操作界面。

IOS【iPhone】知识背景:
1. iOS 中的 armv7,armv7s,arm64,i386,x86_64 都是什么

2. 编译库属性设置:

1.Framework

Framework是Mac OS X下必不可少的部分,不妨去看看/System/Library/Frameworks/下面,一大堆Framework。Framework是dylib的进一步演化,它把头文件、文档、动态链接库等整合成一个有机的目录,类似一种自描述的方式,这种做法其实在Mac OS X下随处可见。比如应用程序,一般都是一个目录,譬如/Applications/iTunes.app目录对应应用程序iTunes,双击这个目录即开始执行。这种做法和Windows下常见的一个exe/dll打天下很不相同。Framework的创建工具也是libtool,详细用法参考man。

2.dylib

动态链接库已成为现代操作系统的基本组成部分,比如Windows下数不清的.DLL文件,Linux下成千上万的.so文件。Mac OS X下也有许多动态链接库,他们的扩展名是.dylib, 所谓dylib,就是bsd风格的动态库。.dylib是Mach-O格式,也就是Mac OS X下的二进制文件格式。Mac OS X提供了一系列工具,用于创建和访问动态链接库。

3.设置库编译属性

debug属性设置为no的时候,会编译支持所有架构的版本,编译的速度会变慢,设置为yes 的时候,只编译当前的architecture版本,编译速度快。

一般情况下,debug 设置为yes,release为no,这样发行版本能适应不同设备。

3. 常用mac工具:

  1. 编译xcode工程
xcodebuild -sdk  iphoneos8.1   -target test  -configuration Release  -arch arm64  -arch armv7  CODE_SIGN_IDENTITY="iPhone Distribution: xxxxxxx" clean build
/*
-sdk 指定最低的SDK版本
-target 指定打包的target
-configuration 指定测试或者发布包
-arch 指定cpu的指令集
CODE_SIGN_IDENTITY 指定证书
clean built 设定每次生成app之前都会清楚掉旧的记录
*/
xcodebuild -showsdks //查看所支持的SDK
xcodebuild -list //查看所支持的target

2. 【xrun: 通过app文件生成ipa文件

sudo xcrun -sdk iphoneos PackageApplication    -v build/Release-iphoneos/test.app  -o `pwd`/build/Release-iphoneos/test2.ipa --sign "iPhone Distribution: xxxxxxxxxx"

3.创建库【libtool】

libtool -static -o c a.framework/a b.framework/b
/*合并库*/
 lipo -create liba.a  libb.a  -output libc.a

4.【xcode-select】

XCODEDIR=`xcode-select --print-path`

5.【otool : 查看库依赖】

/* 在苹果审核的时候,苹果可以获取到我们包的API,用于私有API的检测,
那我们使用otool反编译ipa,就像Android的apkTool一样,简单有效。
选择你的ipa包,然后把后缀名改为zip,解压缩得到Payload文件夹,里面就是你的APP。*/
otool -L libfontmanager.dylib
otool -ov libwstssl.dylib
 /*[查看ipa包是否加壳:其中cryptid代表是否加壳,1代表加壳,0代表已脱壳 , 
两遍,其实代表着该可执行文件支持两种架构armv7和arm64.]*/
otool -l 可执行文件 | grep crypt 
otool -tV execfilename //查看汇编码

6.【lipo -info [lipo主要用于处理通用二进制文件] | file | otool -hv :查看库架构】

lipo -info libcurl.a   //查看库内容
file libcurl.a    //查看库架构
otool -hv xxxx.a // 查看库架构

lipo -info xxx.framework/xxx.a  //查看第三方库的architetures
lipo -create xxxx xxxx -output xxxx  //整合成Fat文件
lipo libReact.a -thin arm64 -output arm64/lib-arm64.a //提取特定的cpu架构的thin文件
lipo -remove cpu(armv7/arm64等) xxxx -output xxxx  // 移除掉特定的cpu架构的文件

7.【其他:gcc | nm | 】

/*
 编译器/usr/bin/cc
  汇编器/usr/bin/as
   链接器/usr/bin/ld
   创建动态链接库 /usr/bin/libtool
   【 cc -c a.c b.c】--》 【 ld -r -o c.o a.o b.o】--》
   【 libtool -dynamic -o c.dylib a.o b.o】
   【 libtool -static -o c.a a.o b.o  //创建静态库】
*/
libtool -dynamic -o c.dylib a.o b.o // 用libtool来创建动态链接库。 
gcc -dynamiclib -o c.dylib a.c b.c //gcc直接编译
 nm c.dylib  // 可以看到导出符号表
nm -nm a.out
 gcc -shared -o c.so a.c b.c // linux 下创建动态库

8.【ar: [create and maintain library archives]打包命令】

/*这个命令用于创建和管理归档(archive)文件。主要应用是解决第三方库冲突,例如ffmpeg冲突就可以用ar分离出冲突文件,并打包*/
ar -t lib-arm64.a // 查看库文件的member
otool -L libAFNetworking.a

ar -x lib-arm64.a  //将.a文件解压缩
ar -rcs liba.a ./*.o    //打包库
ar -d lib.a conflict.o  //将.o从.a静态库中删除

9.【xxd : 二进制查看命令,将文件显示为16进制字符串表示形式

/*查看YTKNetwork.a文件里面包含net字符串的,帮助我们分析一些二进制文件。*/
xxd libYTKNetwork.a | grep "net"

10.【dwarfdump:提取轻量符号表】

 /*DWARF("Debugging With Attributed RecordFormats")是记录应用的调试信息的文件,
 目前最新版本是V5。在iOS中,我们将Build Settings -> Debug Information Format
 修改为DWARF With dSYM File即可将调试信息从可执行文件中剥离到dSYM文件中。
 一旦可执行文件被剥离了DWARF文件,那么原则上可执行文件中内部的符号地址映射就不存在了(
 这里需要注意下,近期发现如果我们本地修改为release编译虽然能生成dSYM文件,
 但是可执行文件中依旧保留了符号表,如果有相关实验不要被此误导)。
 尽管我们可以通过OC的存储特性来还原这种映射关系,但是这已经脱离了DWARF的范围了。*/

dwarfdump --debug-info xxxx.app.dSYM/Contents/Resources/DWARF/xxxx //debug_info这个section中存储了主要的调试信息

/*
其他:
bugly提供了一种从dSYM文件中抽取轻量符号表的功能,生成的符号表更加小巧,而且保留了地址和符号的映射关系,日志解析后仍然可以精确到行号。
*/
SDK的IOS移动端笔记

11. 【class-dump:导出头文件.h 列表

class-dump -H 可执行文件(.app) -o 目标目录
/*class-dump-z 是对 class-dump 和 class-dump-x 的改进版,完全用C++重写,避免动态调用,
这使得 class-dump-z 比 class-dump 和 class-dump-x快10倍左右,
并且可以在 Linux、Mac、 iPhone 上运行。
*/

12.【其他:】

/*反汇编 objdump*/
objdump -x a.out  // 反汇编a.out所有header信息
objdump -D a.out // 反汇编a.out所有section信息

/* 修改动态库的寻找路径install_name_tool  [ change dynamic shared library install names], 	 Library not loaded 的错误时可以使用*/
install_name_tool -id @rpath/a.framework/a a.framework/a //注意上面的动态库路径是个绝对路径,动态链接器加载的时候肯定找不到动态库,我们需要用@RPATH的相对路径,需要使用install_name_tool修改
install_name_tool  -add_rpath /ameworks   ecord
install_name_tool -delete_rpath /Users/libs  /Users/xxx.dylib
install_name_tool oldpath newpath /path2APP/appName 
install_name_tool -change /usr/local/opt/sdl/lib/libSDL-1.2.0.dylib /usr/local/sdl1_2_15/lib/libSDL-1.2.0.dylib /usr/local/bin/ffplay

/*dumpdecrypted: 砸壳命令*/
/*reveal :分析UI工具**/
/*iOS-app-signer-master : ios重签名工具*/
/*cycript : 很多语法的解释器,可以动态修改和调试Mac app和iOS app*/
/*查找工程中是否包含某个文件*/
find . -type f | grep -e ".a" -e ".framework" -e ".m" -e ".cpp" | xargs grep -s ALSmartLink
/*MonkeyDev: 集成非越狱手机逆向工具的插件,集成了重签名、打包、classDump、cycript等等一系列逆向需要的工具,是Xcode的一个插件*/
/*Cydia Substrate: Cydia Substrate是一个基于Hook的代码修改框架,可以在Android、iOS平台使用,并实现修改系统默认代码。*/

4. IOS交叉编译

/*cmake 工程 可依赖 ios.toolchain.cmake  : 交叉编译工具链
ios-cmake作为iOS版的Cmake编译工具链,watchOS 和 tvOS开发支持全部的模拟器和相关选项。
Tested with the following combinations:

XCode 5.x, iOS SDK 7
XCode 6.1.x, iOS SDK 8.1
XCode 8.2.x, iOS SDK 10.2
XCode 9.4.x, iOS SDK 11.4
XCode 10.0.x, iOS SDK 12.0
*/
/*
cmake .. -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DIOS_PLATFORM=SIMULATOR64
*/
Options
Set -DIOS_PLATFORM to "SIMULATOR" to build for iOS simulator 32 bit (i386) DEPRECATED
Set -DIOS_PLATFORM to "SIMULATOR64" (example above) to build for iOS simulator 64 bit (x86_64)
Set -DIOS_PLATFORM to "OS" to build for Device (armv7, armv7s, arm64, arm64e)
Set -DIOS_PLATFORM to "OS64" to build for Device (arm64, arm64e)
Set -DIOS_PLATFORM to "TVOS" to build for tvOS (arm64)
Set -DIOS_PLATFORM to "SIMULATOR_TVOS" to build for tvOS Simulator (x86_64)
Set -DIOS_PLATFORM to "WATCHOS" to build for watchOS (armv7k, arm64_32)
Set -DIOS_PLATFORM to "SIMULATOR_WATCHOS" to build for watchOS Simulator (x86_64)

Additional Options
-DENABLE_BITCODE=(BOOL) - Enabled by default, specify FALSE or 0 to disable bitcode
-DENABLE_ARC=(BOOL) - Enabled by default, specify FALSE or 0 to disable ARC
-DENABLE_VISIBILITY=(BOOL) - Disabled by default, specify TRUE or 1 to enable symbol visibility support
-DIOS_ARCH=(STRING) - Valid values are: armv7, armv7s, arm64, arm64e, i386, x86_64, armv7k, arm64_32. By default it will build for all valid architectures based on -DIOS_PLATFORM (see above)

交叉编译脚本参考

编译涉及变量:

IOS_MIN_SDK=6.1

EXTRA_MAKE_FLAGS="-j4"

XCODEDIR=`xcode-select --print-path`

IOS_SDK=$(xcodebuild -showsdks | grep iphoneos | sort | head -n 1 | awk '{print $NF}')

SIM_SDK=$(xcodebuild -showsdks | grep iphonesimulator | sort | head -n 1 | awk '{print $NF}')

IPHONEOS_PLATFORM=${XCODEDIR}/Platforms/iPhoneOS.platform

IPHONEOS_SYSROOT=${IPHONEOS_PLATFORM}/Developer/SDKs/${IOS_SDK}.sdk

IPHONESIMULATOR_PLATFORM=${XCODEDIR}/Platforms/iPhoneSimulator.platform

IPHONESIMULATOR_SYSROOT=${IPHONESIMULATOR_PLATFORM}/Developer/SDKs/${SIM_SDK}.sdk

CFLAGS="-DNDEBUG -g -O0 -pipe -fPIC -fcxx-exceptions"

./configure --build=x86_64-apple-darwin13.0.0 --host=armv7-apple-darwin13.0.0 --enable-static --disable-shared --prefix=${PREFIX}

"CC=${CC}" "CFLAGS=${CFLAGS} -miphoneos-version-min=${IOS_MIN_SDK} -arch armv7 -isysroot ${IPHONEOS_SYSROOT}"

"CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch armv7 -isysroot ${IPHONEOS_SYSROOT}"

LDFLAGS="-arch armv7 -miphoneos-version-min=${IOS_MIN_SDK} ${LDFLAGS}" "LIBS=${LIBS}"


/*作者:https://blog.csdn.net/frodo_sens/article/details/41494081?locationNum=10&fps=1*/
#!/bin/bash
 
BUILD_I386_IOS_SIM=1
BUILD_ARMV7_IPHONE=1
BUILD_ARMV7S_IPHONE=1

BUILD_TARGET=lame 

IOS_MIN_SDK=6.1
 
(
 
PWD=`pwd`
PREFIX=${PWD}/${BUILD_TARGET}

rm -rf ${PREFIX}/platform
mkdir -p ${PREFIX}/platform
 
EXTRA_MAKE_FLAGS="-j4"
 
XCODEDIR=`xcode-select --print-path`

IOS_SDK=$(xcodebuild -showsdks | grep iphoneos | sort | head -n 1 | awk '{print $NF}')
SIM_SDK=$(xcodebuild -showsdks | grep iphonesimulator | sort | head -n 1 | awk '{print $NF}')


IPHONEOS_PLATFORM=${XCODEDIR}/Platforms/iPhoneOS.platform
IPHONEOS_SYSROOT=${IPHONEOS_PLATFORM}/Developer/SDKs/${IOS_SDK}.sdk

IPHONESIMULATOR_PLATFORM=${XCODEDIR}/Platforms/iPhoneSimulator.platform
IPHONESIMULATOR_SYSROOT=${IPHONESIMULATOR_PLATFORM}/Developer/SDKs/${SIM_SDK}.sdk

CC=clang
CFLAGS="-DNDEBUG -g -O0 -pipe -fPIC -fcxx-exceptions"
CXX=clang
CXXFLAGS="${CFLAGS} -std=c++11 -stdlib=libc++"
LDFLAGS="-stdlib=libc++"
LIBS="-lc++ -lc++abi"



if [ $BUILD_ARMV7_IPHONE -eq 1 ]
then


echo "##################"
echo " armv7 for iPhone"
echo "##################"


(
		cd ${PWD}
    
		make ${EXTRA_MAKE_FLAGS} distclean
    ./configure --build=x86_64-apple-darwin13.0.0 --host=armv7-apple-darwin13.0.0 --enable-static --disable-shared --prefix=${PREFIX} "CC=${CC}" "CFLAGS=${CFLAGS} -miphoneos-version-min=${IOS_MIN_SDK} -arch armv7 -isysroot ${IPHONEOS_SYSROOT}" "CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch armv7 -isysroot ${IPHONEOS_SYSROOT}" LDFLAGS="-arch armv7 -miphoneos-version-min=${IOS_MIN_SDK} ${LDFLAGS}" "LIBS=${LIBS}"
    make ${EXTRA_MAKE_FLAGS}
    make ${EXTRA_MAKE_FLAGS} install 
		
		cd ${PREFIX}/platform
		rm -rf armv7
		mkdir armv7
		cp ${PREFIX}/lib/*.a ${PREFIX}/platform/armv7
		
)
ARMV7_IPHONE_OUTPUT=`find ${PREFIX}/platform/armv7/*.a`



else

ARMV7_IPHONE_OUTPUT=

fi

if [ $BUILD_ARMV7S_IPHONE -eq 1 ]
then

echo "###################"
echo " armv7s for iPhone"
echo "###################"


(
		cd ${PWD}
		
    make ${EXTRA_MAKE_FLAGS}  distclean
    ./configure --build=x86_64-apple-darwin13.0.0 --host=armv7s-apple-darwin13.0.0 --enable-static --disable-shared --prefix=${PREFIX} "CC=${CC}" "CFLAGS=${CFLAGS} -miphoneos-version-min=${IOS_MIN_SDK} -arch armv7s -isysroot ${IPHONEOS_SYSROOT}" "CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch armv7s -isysroot ${IPHONEOS_SYSROOT}" LDFLAGS="-arch armv7s -miphoneos-version-min=${IOS_MIN_SDK} ${LDFLAGS}" "LIBS=${LIBS}"
    make ${EXTRA_MAKE_FLAGS}
    make ${EXTRA_MAKE_FLAGS} install 
		
		cd ${PREFIX}/platform
		rm -rf armv7s
		mkdir armv7s
		cp ${PREFIX}/lib/*.a ${PREFIX}/platform/armv7s

)
ARMV7S_IPHONE_OUTPUT=`find ${PREFIX}/platform/armv7s/*.a`


else

ARMV7S_IPHONE_OUTPUT=

fi



if [ $BUILD_I386_IOS_SIM -eq 1 ]
then

echo "###########################"
echo " i386 for iPhone Simulator"
echo "###########################"

(
		cd ${PWD}
		make ${EXTRA_MAKE_FLAGS} distclean
    ./configure --build=x86_64-apple-darwin13.0.0 --host=i386-apple-darwin13.0.0 --enable-static --disable-shared --prefix=${PREFIX} "CC=${CC}" "CFLAGS=${CFLAGS} -miphoneos-version-min=${IOS_MIN_SDK} -arch i386 -isysroot ${IPHONESIMULATOR_SYSROOT}" "CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch i386 -isysroot ${IPHONESIMULATOR_SYSROOT}" LDFLAGS="-arch i386 -miphoneos-version-min=${IOS_MIN_SDK} ${LDFLAGS}" "LIBS=${LIBS}"
    make ${EXTRA_MAKE_FLAGS}
    make ${EXTRA_MAKE_FLAGS} install
		
		
		cd ${PREFIX}/platform
		rm -rf sim
		mkdir sim
		cp ${PREFIX}/lib/*.a ${PREFIX}/platform/sim
)

IOS_SIM_OUTPUT=`find ${PREFIX}/platform/sim/*.a`

else

IOS_SIM_OUTPUT=

fi



echo "############################"
echo " Create Mixd Libraries"
echo "############################"



(

		cd ${PREFIX}/platform
		rm -rf mixd
		mkdir -p mixd

    lipo ${IOS_SIM_OUTPUT} ${ARMV7_IPHONE_OUTPUT} ${ARMV7S_IPHONE_OUTPUT} -create -output ${PREFIX}/platform/mixd/lib${BUILD_TARGET}.a
		
)


) 2>&1
#) >build.log 2>&1

echo "done"

【SSL】SDK移动端IOS测试

测试环境:同一局域网

客户端:Mac笔记本的xcode开发工具, iphone手机

服务端: 互联网机:Linux虚拟机: centos_7.6_x64_pure.vmx -->/usr/local/nginx的服务器

服务端:配置修改: 修改算法套件: ssl_ciphers ALL; listen: 4433 ssl;

客户端:
1. arm64/armv7测试---【armv7 暂无相应的测试机】
  环境: 
        1.真机通过数据线连接到Mac笔记本
        2.Xcode打开测试工程test_openssl_iphone,配置属性:1. 设备选真机 2. Build Phases: 添加头文件[compile], 库[link Binary with libraries]和证书【boundle】3. General : 配置测试的系统版本 ios11.3 4. Build Setting : (1.Architectures 2. Enable Bitcode: no 3. 所有的库文件搜索路径及头文件搜索路径配置) 4. info.plist: App Transport Security Settings-->Allow Arbitrary Loads :yes 
        3. main.m: 修改IP+端口, 或者其他配置项
        4. 编译通过后,在真机上进行如下配置: (1. 设置-通用-描述文件与设备管理-信任xxx.@qq.com. 2.设置--无线局域网--使用无线与蜂窝网APP-- test- open --- WLAN与蜂窝网络)
        5. 运行测试
 2. I386/x86_64测试:
环境:
1。打开Xcode, 选择Xcode的仿真机型
2. Xcode打开测试工程test_openssl_simulator,配置属性:1. 设备选真机 2. Build Phases: 添加头文件[compile], 库[link Binary with libraries]和证书【boundle】3. General : 配置测试的系统版本 ios11.3 4. Build Setting : (1.Architectures: [i386 x86_64 armv7 arm64 都配置上]  2. Enable Bitcode: no 3. 所有的库文件搜索路径及头文件搜索路径配置) 4. info.plist: App Transport Security Settings-->Allow Arbitrary Loads :yes  5. 
3. main.m: 修改IP+端口, 或者其他配置项
4. 编译通过后,在真机上进行如下配置: (1. 设置-通用-描述文件与设备管理-信任xxx.@qq.com. 2.设置--无线局域网--使用无线与蜂窝网APP-- test- open --- WLAN与蜂窝网络)
5. 运行测试

测试demo的模板:

main.m的模版:

//
//  main.m
//  ios_openssl_test
//
//  Created by westone on 2021/10/31.
//

#import 
#import "AppDelegate.h"
#include 

int ssl_conn() {
    NSLog(@"ssl_conn enter.
");
    
/*设置证书查找路径:*/
    //设置加载文件的名字及后缀,需要将文件添加至iOS的沙盒中:Copy Bundle Resources.
    ///private/var/containers/Bundle/Application/66F95C21-47DB-40C5-9960-A61D165ACF02/ios_openssl_test.app/CA.pem
    NSString *string = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
    //例如 :签名证书 :CS.pem ; 加载后路径指针为:sig_cert_path
    NSString *SIG_CERT_PATH = [[NSBundle mainBundle] pathForResource:@"CS" ofType:@"pem"];
    char *sig_cert_path = (char*)[SIG_CERT_PATH UTF8String];
    
    NSString *ENC_CERT_PATH = [[NSBundle mainBundle] pathForResource:@"CE" ofType:@"pem"];
    char *enc_cert_path = (char*)[ENC_CERT_PATH UTF8String];
    
    NSString *SIG_KEY_PATH = [[NSBundle mainBundle] pathForResource:@"CS" ofType:@"key"];
    char *sig_key_path = (char*)[SIG_KEY_PATH UTF8String];
    
    NSString *ENC_KEY_PATH = [[NSBundle mainBundle] pathForResource:@"CE" ofType:@"key"];
    char *enc_key_path = (char*)[ENC_KEY_PATH UTF8String];
    
    NSString *CA_CERT_PATH = [[NSBundle mainBundle] pathForResource:@"CA" ofType:@"pem"];
    char *ca_cert_path = (char*)[CA_CERT_PATH UTF8String];

    // 测试网络通信:通过request百度,测试网络互通性
    NSString *urlStr = @"https://baidu.com";
    //如果字符串里面含有中文要进行转码
    urlStr = [urlStr stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    //2.创建资源路径
    NSURL *url = [NSURL URLWithString:urlStr];
    //3.创建请求
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    //4.发送请求
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
        NSLog(@"%@",data);
    }];
    
    NSLog(@"sig_cert:@%s, sig_key:@%s, enc_cert:@%s, enc_key:%s, ca_cert:%s .
", 
              sig_cert_path, sig_key_path, enc_cert_path, enc_key_path, ca_cert_path);
    
/*--------功能验证开始---------*/
    
    
/*--------功能验证结束---------*/
    NSLog(@"ssl_conn end.
");
    return 1;
}


int main(int argc, char * argv[]) {
    NSString * appDelegateClassName;
    @autoreleasepool {
        // Setup code that might create autoreleased objects goes here.
        appDelegateClassName = NSStringFromClass([AppDelegate class]);
    }
    
    printf("openssl test start.
");
    
    int ret = ssl_conn();
    if (ret == 1)
        printf("ssl 测试成功.
");
    else
        printf("ssl 测试失败. 
");
    
    return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
SDK的IOS移动端笔记

展开阅读全文

页面更新:2024-03-03

标签:蜂窝   模拟器   路径   架构   处理器   符号   文件   测试   笔记   工具   动态

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top