项目原由
因为疫情原因,学校需要每天提交问卷,在开始时候也分析过app,挺简单,后来觉得疫情应该很快就过去,写这个就不值当了。可是一转眼过了半年……还是要每天打卡,就很烦!于是写了这个功能类!
项目说明
发出来肯定有喷子说是抄袭代码,本博客全部本人原创技术和代码,包括此app的分析过程也会详细讲出来!本项目的代码仅供学习交流!
下载APP
下载HttpCanary
HttpCanary是一款安卓抓包神器,可自行百度下载
开始抓包
经过抓包,发现核心请求有部分是加密的,根据以往经验,这种情况会很费劲,只能逆向app拿到加密算法,但是我发现了更简单的办法
分析请求
于是我换了一种思路,在app中查看网页请求,app是可以使用教务账号登陆,每个学校的网址也都是学校【域名前缀.campusphere.net】这个格式,
我们可以直接登陆进去,f12分析请求,可以看到有很多js文件,这些js是压缩过的,但是不妨碍我们查看代码!
js已经拿到,我们可以继续查阅代码,经过分析会发现一个api合集
通过此api,我们可以执行任意操作!
模拟登陆
此app登陆使用的是sso单点登录系统,登陆的同时会携带安全码等信息,但是我们仍可以模拟登陆,如果失败次数过多,此账号登陆下一次必定出现验证码,登陆成功,则下次登陆验证码消失,下面是安全码的请求
则验证码,是按照lt值来的,重新登陆携带lt值和cookie值即可
登陆成功会进行多次重定向跳转,这里不再叙述了,到最后我们可以拿到MOD_AUTH_CAS名的cookie值,这就是最终结果了,
其他api
以上已经说过一个api合集,通过合集的api名以及查找,会找到每个api的参数列表,发送模拟post即可,但是要注意的是content-type为json,这个api只是一小部分,很多api在app还是可以抓到的,都是明文传输!
更新日志
2020/09/26:
1. 修复登录协议
登陆接口
接口地址:
http://tool.clwl.online/cpdaily/login.php?url=【学校iap地址】&user=【账户】&pwd=【密码】
说明:
本接口可强制登录,无视验证码各种操作!适用于各种iap登录
例如:
http://tool.clwl.online/cpdaily/login.php?url=https://ahctc.campusphere.net&user=test&pwd=test
功能实现
以下是我封装的今日校园功能类,基本实现了所有接口,代码仅供学习交流!
<?php
/**
* 今日校园功能类
* @param Author 流逝中沉沦
* @param QQ 1178710004
* @param Date 2020/06/30
*/
class CpDaily
{
private $loginapi = ''; //登陆API
private $ua = 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Mobile Safari/537.36'; //默认UA
private $ApiUrl = 'https://ahctc.campusphere.net'; //学校网站地址
private $cookies = "";
/**
* 设置cookie
* @param String $cookie cookies值
*/
public function SetCookie($cookie)
{
if (is_array($cookie)) {
$this->cookies = urldecode(str_replace("&", ";", http_build_query($cookie)));
} else {
$this->cookies = urldecode($cookie);
}
}
/**
* 设置学校地址
* @param String $url 学校网站地址
*/
public function SetSchool($url)
{
$this->ApiUrl = $url;
}
/**
* 设置登陆代理
*/
public function SetLoginProxy($url)
{
$this->loginapi = $url;
}
/**
* 获取学校列表
* @return Mixed 数据集
*/
public function SchoolList()
{
$url = 'https://static.campushoy.com/apicache/tenantListSort';
$res = $this->get_curl($url);
$arr = json_decode($res, true);
if (empty($arr) || $arr['errCode'] != 0) {
return false;
}
return $arr['data'];
}
/**
* 获取学校信息
* @param Int $id 学校ID
* @return Mixed 数据集
*/
public function SchoolInfo($id = 'cd2eeac7-8519-4d02-80eb-8e582f30c1ed')
{
$url = 'https://mobile.campushoy.com/v6/config/guest/tenant/info?ids=' . $id;
$res = $this->get_curl($url);
$arr = json_decode($res, true);
if (empty($arr) || $arr['errCode'] != 0) {
return false;
}
return $arr['data'];
}
/**
* 账户登录(获取Cookie)
* @param String $user 账户
* @param String $pwd 密码
* @param String $lt 验证码ID
* @param String $cookie Cookie值
* @param String $code 验证码值
* @return Mixed 数据集
*/
public function Login($user, $pwd, $lt = "", $cookie = "", $code = "")
{
if (empty($lt) || empty($cookie)) {
$res = $this->get_curl($this->ApiUrl . "/portal/login", 0, 0, 0, 1, 0, 0, 0, 1);
$location = $this->GetLocation($res['header']);
$res = $this->get_curl($location, 0, 0, 0, 1, 0, 0, 0, 1);
$location = $this->GetLocation($res['header']);
$cookie = $this->GetCookie($res['header']);
$lt = explode("=",$location)[1];
}
//进行登录请求
$post = 'username=' . $user . '&password=' . $pwd . '&mobile=&dllt=&captcha=' . $code . '&rememberMe=false<=' . $lt;
$referer = $this->ApiUrl . "/iap/login/mobile.html";
$res = $this->get_curl($this->ApiUrl . "/iap/doLogin", $post, $referer, $cookie, 1, 0, 0, 0, 1);
$arr = json_decode($res['body'], true);
$codelist = '[["SUCCESS", "成功"],["FAIL_UPNOTMATCH","用户名密码不匹配"],["FAIL_UPNULL", "用户名获取密码为空"], ["LT_NULL", "LT为空"], ["LT_NOTMATCH", "LT安全校验失败"], ["CAPTCHA_NOTMATCH", "验证码不匹配"], ["USER_FREEZED", "用户冻结"], ["USER_STOPPED", "用户停用"], ["CAMPUS_UNKOWNHOST", "公有云平台认证-校内认证集成提供服务域名没法解析"],["CAMPUS_TIMEOUT", "公有云平台认证-校内认证集成提供服务连接超时或者响应超时"], ["UNIQUE_CONFLICT", "账号和考生号冲突,请检查数据!"], ["ERROR", "程序发生错误"], ["REDIRECT", "重定向"], ["NO_AUTH", "没有权限"], ["NEW_ORIGINAL_PASS_SAME", "新密码不能与最近一次密码一致"],["TOKEN_NULL", "token为空"], ["TOKEN_EXPIRE", " token过期、或者token匹配不正确"], ["ORIGINAL_PASS_FAIL", "原密码校验失败"], ["NEW_PASS_NOTRULE", "新密码密码规则不达标"], ["FORCE_PASS_FAIL", "强制修改密码失败"], ["SOCIAL_LOGIN_FAIL", "社交账号绑定登录失败"],["SOCIAL_LOGIN_EXIST", "社交账号已被绑定"], ["MOBILE_CAPTCHA_NOTMATCH", "手机验证码不匹配"], ["MOBILE_BINDING_ERROR", "手机号绑定异常"], ["ACCOUNT_ALREADY_BINDING_MOBILE", "该账户已经绑定手机号"]]';
$codearr = json_decode($codelist, true);
$newarr = array();
foreach ($codearr as $key) {
$newarr[$key[0]] = $key[1];
}
if ($res['body'] == '') {
//进行重定向
$cookie .= $this->GetCookie($res['header']);
$referer = $this->ApiUrl . "/iap/login/mobile.html";
$url = $this->ApiUrl . "/iap/login?service=" . urlencode($this->ApiUrl) . "%2Fportal%2Flogin";
$res = $this->get_curl($url, 0, $referer, $cookie, 1, 0, 0, 0, 1);
//获取Ticket重定向
$ticket = $this->GetLocation($res['header']);
$ret = $this->get_curl($ticket, 0, 0, 0, 1);
$cookie = $this->GetCookie($ret, true);
return array('code' => 1, 'msg' => '登陆成功!', 'cookie' => $cookie);
} elseif ($arr['resultCode'] == 'CAPTCHA_NOTMATCH') {
return array('code' => 2, 'msg' => '需要验证码', 'verfy' => $lt, 'cookie' => $cookie, 'captcha' => $this->ApiUrl . '/iap/generateCaptcha?ltId=' . $lt);
}
return array('code' => 0, 'msg' => $newarr[$arr['resultCode']]);
}
/**
* 获取正在进行问卷数据
* @param Int $pageSize 分页容量
* @param Int $pageNumber 页码
* @param Mixed cookies失效|数据集
*/
public function GetProcessingList($pageSize = 99999, $pageNumber = 1)
{
$url = $this->ApiUrl . '/wec-counselor-collector-apps/stu/collector/queryCollectorProcessingList';
$post = '{"pageSize":"' . $pageSize . '","pageNumber":"' . $pageNumber . '"}';
$res = $this->get_curl($url, $post, 0, $this->cookies, 0, 0, 0, 1);
$arr = json_decode($res, true);
if (empty($arr) || (isset($arr['datas']['WEC-HASLOGIN']) && !$arr['datas']['WEC-HASLOGIN'])) {
return false;
}
return $arr['datas']['rows'];
}
/**
* 获取已经填写的问卷数据
* @param Int $pageSize 分页容量
* @param Int $pageNumber 页码
* @param Mixed cookies失效|数据集
*/
public function GetHistoryList($pageSize = 99999, $pageNumber = 1)
{
$url = $this->ApiUrl . '/wec-counselor-collector-apps/stu/collector/queryCollectorHistoryList';
$post = '{"pageSize":"' . $pageSize . '","pageNumber":"' . $pageNumber . '"}';
$res = $this->get_curl($url, $post, 0, $this->cookies, 0, 0, 0, 1);
$arr = json_decode($res, true);
if (empty($arr) || (isset($arr['datas']['WEC-HASLOGIN']) && !$arr['datas']['WEC-HASLOGIN'])) {
return false;
}
return $arr['datas']['rows'];
}
/**
* 获取问卷信息
* @param Int $collectorWid 问卷ID
* @param Mixed cookies失效|数据集
*/
public function CollectorInfo($collectorWid)
{
$url = $this->ApiUrl . '/wec-counselor-collector-apps/stu/collector/detailCollector';
$post = '{"collectorWid":"' . $collectorWid . '"}';
$res = $this->get_curl($url, $post, 0, $this->cookies, 0, 0, 0, 1);
$arr = json_decode($res, true);
if (empty($arr) || (isset($arr['datas']['WEC-HASLOGIN']) && !$arr['datas']['WEC-HASLOGIN'])) {
return false;
}
return $arr['datas'];
}
/**
* 获取阿里云OSS信息
* @param Mixed cookies失效|数据集
*/
public function OssInfo()
{
$url = $this->ApiUrl . '/wec-counselor-collector-apps/stu/collector/getStsAccess';
$res = $this->get_curl($url, '{}', 0, $this->cookies, 0, 0, 0, 1);
$arr = json_decode($res, true);
if (empty($arr) || (isset($arr['datas']['WEC-HASLOGIN']) && !$arr['datas']['WEC-HASLOGIN'])) {
return false;
}
return $arr['datas'];
}
/**
* 获取问卷表单信息
* @param Int $collectorWid 问卷ID
* @param Int $formWid 表单ID
* @param Mixed cookies失效|数据集
*/
public function FormFields($collectorWid, $formWid)
{
$url = $this->ApiUrl . '/wec-counselor-collector-apps/stu/collector/getFormFields';
$post = '{"collectorWid":"' . $collectorWid . '","formWid":"' . $formWid . '"}';
$res = $this->get_curl($url, $post, 0, $this->cookies, 0, 0, 0, 1);
$arr = json_decode($res, true);
if (empty($arr) || (isset($arr['datas']['WEC-HASLOGIN']) && !$arr['datas']['WEC-HASLOGIN'])) {
return false;
}
return $arr['datas'];
}
/**
* 提交问卷表单信息
* @param Int $collectorWid 问卷ID
* @param Int $formWid 表单ID
* @param Int $schoolTaskWid 学校任务ID
* @param Array $fields 表单内容
* @param String $address 地点
* @return Mixed 数据集
*/
public function SubmitForm($collectWid, $formWid, $schoolTaskWid, $fields = array(), $address = "定位失败")
{
$url = $this->ApiUrl . '/wec-counselor-collector-apps/stu/collector/submitForm';
$post = json_encode(array(
'formWid' => $formWid,
'address' => $address,
'collectWid' => $collectWid,
'schoolTaskWid' => $schoolTaskWid,
'form' => $fields
));
$res = $this->get_curl($url, $post, 0, $this->cookies, 0, 0, 0, 1);
$arr = json_decode($res, true);
if (empty($arr) || (isset($arr['datas']['WEC-HASLOGIN']) && !$arr['datas']['WEC-HASLOGIN'])) {
return false;
}
return $arr;
}
/**
* 提交所有未填写的问卷
*/
public function SubmitAllForms()
{
$list = $this->GetProcessingList();
$return = array();
foreach ($list as $key) {
$arr = $this->CollectorInfo($key['wid']);
$wid = $arr['collector']['wid'];
$formWid = $arr['collector']['formWid'];
$schoolTaskWid = $arr['collector']['schoolTaskWid'];
$forminfo = $this->FormFields($wid, $formWid);
$form = array();
foreach ($forminfo['rows'] as $key2 => $value) {
if (!isset($value['fieldItems'])) {
continue;
}
$temp = array();
foreach ($value['fieldItems'] as $key3) {
if (!isset($key3['isSelected'])||$key3['isSelected']!=1) {
continue;
}
$temp = $key3;
}
if (!empty($temp)) {
$value['fieldItems'] = array($temp);
$form[] = $value;
}
}
$return[] = $this->SubmitForm($wid, $formWid, $schoolTaskWid, $form);
}
return $return;
}
/**
* 获取今日任务列表
* @return Mixed false|数据集
*/
public function TodayTasks()
{
$url = $this->ApiUrl . '/wec-counselor-sign-apps/stu/sign/getStuSignInfosInOneDay';
$post = '{}';
$res = $this->get_curl($url, $post, 0, $this->cookies, 0, 0, 0, 1);
$arr = json_decode($res, true);
if (empty($arr) || (isset($arr['datas']['WEC-HASLOGIN']) && !$arr['datas']['WEC-HASLOGIN'])) {
return false;
}
return $arr['datas'];
}
/**
* 获取签到任务信息
* @param Int $signInstanceWid 签到实例ID
* @param Int $signWid 签到任务ID
* @return Mixed false|数据集
*/
public function SignTaskInfo($signInstanceWid, $signWid)
{
$url = $this->ApiUrl . '/wec-counselor-sign-apps/stu/sign/detailSignInstance';
$post = json_encode(array(
'signInstanceWid' => $signInstanceWid,
'signWid' => $signWid
));
$res = $this->get_curl($url, $post, 0, $this->cookies, 0, 0, 0, 1);
$arr = json_decode($res, true);
if (empty($arr) || (isset($arr['datas']['WEC-HASLOGIN']) && !$arr['datas']['WEC-HASLOGIN'])) {
return false;
}
return $arr['datas'];
}
/**
* 提交签到
* @param Int $wid 签到任务ID
* @param Float $longitude 精度
* @param Float $latitude 纬度
* @param String $abnormalReason 补充原因
* @param String $signPhotoUrl 图片地址
* @param String $position 位置
* @return Mixed 数据集
*/
public function submitSign($wid, $longitude, $latitude, $abnormalReason = "", $signPhotoUrl = "", $position = "定位失败")
{
$url = $this->ApiUrl . '/wec-counselor-sign-apps/stu/sign/submitSign';
$post = json_encode(array(
'signInstanceWid' => $wid,
'longitude' => $longitude,
'latitude' => $latitude,
'isMalposition' => 1,
'abnormalReason' => $abnormalReason,
'signPhotoUrl' => $signPhotoUrl,
'position' => $position
));
$res = $this->get_curl($url, $post, 0, $this->cookies, 0, 0, 0, 1);
$arr = json_decode($res, true);
if (empty($arr) || (isset($arr['datas']['WEC-HASLOGIN']) && !$arr['datas']['WEC-HASLOGIN'])) {
return false;
}
return $arr['datas'];
}
/**
* 返回cookie
* @param String $header 头部信息
* @param Bolean $array 是否数组输出
* @return Mixed 数据集
*/
private function GetCookie($header, $array = false)
{
preg_match_all('/Set-Cookie: (.*?);/iU', $header, $matchs);
$cookie = '';
$cookies = array();
foreach ($matchs[1] as $val) {
if (substr($val, -1) == '=') continue;
$cookie .= $val . '; ';
$temp = explode("=", explode(";", $val)[0]);
$cookies[$temp[0]] = $temp[1];
}
if ($array) {
return $cookies;
}
return $cookie;
}
/**
* 返回重定向
* @param String $header 头部信息
* @return String 数据
*/
private function GetLocation($header){
$location = substr($header, strpos($header, "Location: "));
$location = trim(str_replace(array("Location:"), "", $location));
return $location;
}
/**
* Curl get post请求
* @param String $url 网址
* @param String $post POST参数
* @param String $referer refer地址
* @param String $cookie 携带COOKIE
* @param String $header 请求头
* @param String $ua User-agent
* @param String $nobaody 重定向
* @return String 数据
*/
private function get_curl($url, $post = 0, $referer = 0, $cookie = 0, $header = 0, $ua = 0, $nobaody = 0, $json = 0, $split = 0)
{
if ($this->loginapi) return $this->get_curl_proxy($url, $post, $referer, $cookie, $header, $ua, $nobaody);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$httpheader[] = "Accept:*/*";
$httpheader[] = "Accept-Encoding: gzip,deflate,sdch";
$httpheader[] = "Accept-Language: zh-CN,zh;q=0.8";
$httpheader[] = "Connection: keep-alive";
if ($json) {
$httpheader[] = "Content-Type: application/json";
}
curl_setopt($ch, CURLOPT_HTTPHEADER, $httpheader);
if ($post) {
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
if ($header) {
curl_setopt($ch, CURLOPT_HEADER, TRUE);
}
if ($cookie) {
curl_setopt($ch, CURLOPT_COOKIE, $cookie);
}
if ($referer) {
curl_setopt($ch, CURLOPT_REFERER, $referer);
}
if ($ua) {
curl_setopt($ch, CURLOPT_USERAGENT, $ua);
} else {
curl_setopt($ch, CURLOPT_USERAGENT, $this->ua);
}
if ($nobaody) {
curl_setopt($ch, CURLOPT_NOBODY, 1);
}
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_ENCODING, "gzip");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ret = curl_exec($ch);
if ($split) {
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$header = substr($ret, 0, $headerSize);
$body = substr($ret, $headerSize);
$ret = array();
$ret['header'] = $header;
$ret['body'] = $body;
}
curl_close($ch);
return $ret;
}
/**
* Curl 代理 get post请求
* @param String $url 网址
* @param String $post POST参数
* @param String $referer refer地址
* @param String $cookie 携带COOKIE
* @param String $header 请求头
* @param String $ua User-agent
* @param String $nobaody 重定向
* @return String 数据
*/
private function get_curl_proxy($url, $post = 0, $referer = 0, $cookie = 0, $header = 0, $ua = 0, $nobaody = 0)
{
$data = array('url' => $url, 'post' => $post, 'referer' => $referer, 'cookie' => $cookie, 'header' => $header, 'ua' => $ua, 'nobaody' => $nobaody);
$ch = curl_init();
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_URL, $this->loginapi);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}
}
$test = new CpDaily();
$arr = $test->Login("*******","*******");
if($arr['code']==1){
$test->SetCookie($arr['cookie']);
$arr = $test->SubmitAllForms();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
- 101
- 102
- 103
- 104
- 105
- 106
- 107
- 108
- 109
- 110
- 111
- 112
- 113
- 114
- 115
- 116
- 117
- 118
- 119
- 120
- 121
- 122
- 123
- 124
- 125
- 126
- 127
- 128
- 129
- 130
- 131
- 132
- 133
- 134
- 135
- 136
- 137
- 138
- 139
- 140
- 141
- 142
- 143
- 144
- 145
- 146
- 147
- 148
- 149
- 150
- 151
- 152
- 153
- 154
- 155
- 156
- 157
- 158
- 159
- 160
- 161
- 162
- 163
- 164
- 165
- 166
- 167
- 168
- 169
- 170
- 171
- 172
- 173
- 174
- 175
- 176
- 177
- 178
- 179
- 180
- 181
- 182
- 183
- 184
- 185
- 186
- 187
- 188
- 189
- 190
- 191
- 192
- 193
- 194
- 195
- 196
- 197
- 198
- 199
- 200
- 201
- 202
- 203
- 204
- 205
- 206
- 207
- 208
- 209
- 210
- 211
- 212
- 213
- 214
- 215
- 216
- 217
- 218
- 219
- 220
- 221
- 222
- 223
- 224
- 225
- 226
- 227
- 228
- 229
- 230
- 231
- 232
- 233
- 234
- 235
- 236
- 237
- 238
- 239
- 240
- 241
- 242
- 243
- 244
- 245
- 246
- 247
- 248
- 249
- 250
- 251
- 252
- 253
- 254
- 255
- 256
- 257
- 258
- 259
- 260
- 261
- 262
- 263
- 264
- 265
- 266
- 267
- 268
- 269
- 270
- 271
- 272
- 273
- 274
- 275
- 276
- 277
- 278
- 279
- 280
- 281
- 282
- 283
- 284
- 285
- 286
- 287
- 288
- 289
- 290
- 291
- 292
- 293
- 294
- 295
- 296
- 297
- 298
- 299
- 300
- 301
- 302
- 303
- 304
- 305
- 306
- 307
- 308
- 309
- 310
- 311
- 312
- 313
- 314
- 315
- 316
- 317
- 318
- 319
- 320
- 321
- 322
- 323
- 324
- 325
- 326
- 327
- 328
- 329
- 330
- 331
- 332
- 333
- 334
- 335
- 336
- 337
- 338
- 339
- 340
- 341
- 342
- 343
- 344
- 345
- 346
- 347
- 348
- 349
- 350
- 351
- 352
- 353
- 354
- 355
- 356
- 357
- 358
- 359
- 360
- 361
- 362
- 363
- 364
- 365
- 366
- 367
- 368
- 369
- 370
- 371
- 372
- 373
- 374
- 375
- 376
- 377
- 378
- 379
- 380
- 381
- 382
- 383
- 384
- 385
- 386
- 387
- 388
- 389
- 390
- 391
- 392
- 393
- 394
- 395
- 396
- 397
- 398
- 399
- 400
- 401
- 402
- 403
- 404
- 405
- 406
- 407
- 408
- 409
- 410
- 411
- 412
- 413
- 414
- 415
- 416
- 417
- 418
- 419
- 420
- 421
- 422
- 423
- 424
- 425
- 426
- 427
- 428
- 429
- 430
- 431
- 432
- 433
- 434
- 435
- 436
- 437
- 438
- 439
- 440
- 441
- 442
- 443
- 444
- 445
- 446
- 447
- 448
- 449
- 450
- 451
- 452
- 453
- 454
- 455
- 456
- 457
- 458
- 459
- 460
- 461
- 462
- 463
- 464
- 465
- 466
- 467
- 468
- 469
结语
至此,app协议已经全部实现出来了,现在90%的app都是http传输,在安全性方面是落后于socket传输的,想了解socket通信的可以看我QQ登陆代码示例!至于自动签到网,后期实现!
网站实现
自动化网址已开发完成,每日可自动进行任务。前往
Скачать новинки музыки 2024 бесплатно в mp3, самые свежие новинки
Последние новинки музыки 2024 скачать и слушать онлайн
На данном сайте вы можете скачать и слушать новинки музыки 2024 года бесплатно в хорошем качестве.
Музыка 2024 – слушать онлайн и скачать бесплатно без регистрации в хорошем качестве mp3
Популярные песни 2024 года, скачать mp3 и слушать онлайн бесплатно
На нашем сайте вы можете скачать музыку 2024 года бесплатно в mp3 формате.
На нашем сайте вы можете скачать и слушать онлайн последние новинки музыки 2024 бесплатно.
Скачать новинки музыки 2024 бесплатно в mp3, самые свежие новинки
На данном сайте вы можете скачать и слушать новинки музыки 2024 года бесплатно в хорошем качестве.
На данном сайте вы можете скачать в mp3 качестве и слушать онлайн популярные песни 2024 года, сайт обновляется новыми хитами каждый день.
Музыка 2024 года слушать онлайн и скачать бесплатно mp3
На нашем сайте вы можете скачать музыку 2024 года бесплатно в mp3 формате.
Скачать новинки музыки 2024 бесплатно в mp3, самые свежие новинки
Последние новинки музыки 2024 скачать и слушать онлайн бесплатно
Скачать и слушать новинки музыки 2024 бесплатно в хорошем качестве
Музыка 2024 – слушать онлайн и скачать бесплатно без регистрации в хорошем качестве mp3
На данном сайте вы можете скачать в mp3 качестве и слушать онлайн популярные песни 2024 года, сайт обновляется новыми хитами каждый день.
Скачать музыку 2024 года бесплатно в mp3
Скачать новинки музыки 2024 бесплатно в mp3, самые свежие новинки
На данном сайте вы можете скачать и слушать новинки музыки 2024 года бесплатно в хорошем качестве.
Последние новинки музыки 2024 скачать и слушать онлайн бесплатно
На данном сайте вы можете слушать онлайн и скачать музыку 2024 года бесплатно без регистрации в хорошем качестве mp3.
Популярные песни 2024 года, скачать mp3 и слушать онлайн бесплатно
Скачать музыку 2024 года бесплатно в mp3
Скачать новинки музыки 2024 бесплатно в mp3, самые свежие новинки
Скачать и слушать новинки музыки 2024 бесплатно в хорошем качестве
Последние новинки музыки 2024 скачать и слушать онлайн бесплатно
На данном сайте вы можете слушать онлайн и скачать музыку 2024 года бесплатно без регистрации в хорошем качестве mp3.
Популярные песни 2024 скачать mp3 и слушать онлайн
Скачать музыку 2024 года бесплатно в mp3