Сценарий: срок действия обучающего видео, купленного моей девушкой, истекает через месяц (по истечении срока загрузку невозможно просмотреть локально. Она попросила меня помочь скачать видео. Я заранее записал файл m3u8 и загрузил фрагменты видео для синтеза). это было полное видео. Я думал, что эта миссия очень простая~
Ранго, проверь информацию о приложении, она усилена (псевдоусилена)
Он усилен, а обстрелы и компиляции пока не рассматриваются.
Итак, я начал захватывать пакеты. На моем телефоне Android нет root-прав. При захвате приложения определенного класса был обнаружен прокси-сервер, и в приложении определенного класса не было сети. Я случайно обнаружил его, когда играл в реверс-инжиниринг Android.
Некоторые приложения можно поместить в контейнеры, а данные захвата пакетов запущенных приложений можно получить, захватив контейнеры. То есть установите xx в VirtualXpose, и Хуанняо захватит VirtualXpose.
VirtualXposedСвязь:Нажмите на меня
Примечание. Этот метод применим только к некоторым приложениям, а некоторые из них будут аварийно завершать работу после установки.
Скриншот части захвата пакетов:
Выше приведена захваченная информация m3u8. Согласно предыдущему шагу, файл ключа и фрагмента видео должен быть в состоянии синтезировать полное видео.
Однако при доступе к красной части ключа отображается 404. Видеофрагмент можно загрузить, но нельзя расшифровать.
Я видел блог об удалении ключа после одного доступа. Мне нужно было угадать, получил ли клиент приложения файл ключа после доступа к нему, проанализировал загруженный файл ресурсов во внешнем интерфейсе приложения и затем воспроизвел его с момента обращения к нему. , Однажды полученные мной данные перехвата пакетов уже были доступны. Здесь я посмотрел каталог кеша приложения. Там много искаженных символов, и я не знаю, где находится файл ключа, поэтому я написал все. процесс в питоне.
теперь напиши Авторизоваться->Получить информацию о пользователе иtoken->Получить все курсы->курс, курс->видеоid кодирование На сегодня всё, завтра проверю. В настоящее время я обнаружил, что ссылка на m3u8 взята с сайта.
https://api/userid/x/video_id.m3u8 Позиция x неопределенна, вам не нужно носить с собой следующее:
Реальный адрес: https://hls.videocc.net/9b52ce99c4/d/9b52ce99c4df4d856f4b770a2e8112ad_2.m3u8?did=1638152451432X1376979
Код и интерфейс будут обсуждаться завтра. Если у вас есть лучшие мнения, мнения или новые идеи относительно моего личного мнения, прокомментируйте и поделитесь вышеизложенным.
import requests
import json
#Crawl Library Course онлайн оплата курса видео
#Поскольку срок действия платного видео, купленного моей девушкой, истекает, я хочу скачать его и сохранить в качестве резервной копии Не торопитесь и посмотрите
def login(uuid,password):
host = "https://new6api.kuke99.com/user/login"
#
params = {
"password":password,
"mobile":'MTU5NjkxMTA5Mjc='
}
header = {
"clientType": "3",
'version': '6.2.13',
"Referer": "https://m.kuke99.com",
"UUID": uuid,
"Content-Type": "application/x-www-form-urlencoded;charset=UTF-8",
"deviceType": "V1814T",
"osVersion": "9",
"Content-Length": "78",
"Host": "new6api.kuke99.com",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/4.9.1"
}
cookies = {
# "acw_tc": acw_tc
}
response = requests.post(host, data=params,headers=header)
# Вы также можете напрямую заменить поле данных полем json, которое поддерживается после версии 2.4.3.
# response = requests.post(url, json = body, headers = headers)
# Информация о возврате
data_string=response.json()
print(data_string)
if(data_string['code']=='0'):
print("====Вход успешен====\n")
print("Идентификатор студента:" + data_string['data']['stu_id'])
print("Ник пользователя:"+data_string['data']['stu_name'])
print("Мобильный телефон пользователя:" + data_string['data']['mobile'])
global access_token
access_token=data_string['data']['access_token']
print("Токен_доступа успешно депонирован"+токен_доступа)
return access_token
else:
print("!!!!!Авторизоватьсянеудача!!!!!!")
def refresh(uid,accessTok):
url = "https://new6api.kuke99.com/learning/learning_list"
#
params = {
"subject_id": '0',
"cate_id": '0'
}
header = {
"accessToken": accessTok,
"clientType": "3",
'version': '6.2.13',
"Referer": "https://m.kuke99.com",
"UUID": uid,
"Content-Type": "application/x-www-form-urlencoded",
"deviceType": "V1814T",
"osVersion": "9",
"Content-Length": "22",
"Host": "new6api.kuke99.com",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/4.9.1"
}
cookies = {
# "acw_tc": acw_tc
}
response = requests.post(url, data=params, headers=header)
# Вы также можете напрямую заменить поле данных полем json, которое поддерживается после версии 2.4.3.
# response = requests.post(url, json = body, headers = headers)
# Информация о возврате
data2_string = response.json()
# print(data2_string)
if(data2_string['code']=='0'):
print("====Получение списка курсов успешно===")
for keys in data2_string['data']['general']:
print("Название курса: "+keys['goods_title']+" Идентификатор курса: "+keys['goods_id']+" goods_type:"+keys['goods_type'])
else:
print("Не удалось получить список, попробуйте еще раз. Рекомендуется проверить пароль uuid правильность")
def xiangqing(g_id,g_type,access_oken,uuid):
url = "https://new6api.kuke99.com/goods_collation/detail"
#
params = {
"goods_id": g_id,
"goods_type": g_type,
"ac_type":''
}
header = {
"accessToken": access_oken,
"clientType": "3",
'version': '6.2.13',
"Referer": "https://m.kuke99.com",
"UUID": uuid,
"Content-Type": "application/x-www-form-urlencoded",
"deviceType": "V1814T",
"osVersion": "9",
"Content-Length": "22",
"Host": "new6api.kuke99.com",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/4.9.1"
}
cookies = {
# "acw_tc": acw_tc
}
response = requests.post(url, data=params, headers=header)
# Вы также можете напрямую заменить поле данных полем json, которое поддерживается после версии 2.4.3.
# response = requests.post(url, json = body, headers = headers)
# Информация о возврате
data3_string = response.json()
print(data3_string)
Страница подробностей #видео
def get_m3u8(video_id,access_oken,uuid):
host = "https://hls.videocc.net/9b52ce99c4/f/"+video_id+".m3u8?did=1638275844261X1898885"
print(host)
params = {
}
headers = {
"accessToken": access_oken,
"clientType": "3",
'version': '6.2.13',
"Referer": "https://m.kuke99.com",
"UUID": uuid,
"Content-Type": "application/x-www-form-urlencoded",
"deviceType": "V1814T",
"osVersion": "9",
"Content-Length": "25",
"Host": "hls.videocc.net",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "polyv-android-sdk2.15.3-20210520 Dalvik/2.1.0 (Linux; U; Android 9; V1814T Build/PKQ1.180819.001)"
}
cookies = {
}
r = requests.get(host, data=params)
data3_string = r.json()
print(data3_string)
def download(g_id,g_type,access_oken,uuid):
url = "https://new6api.kuke99.com/download/node_list"
#
params = {
"goods_id": g_id,
"goods_type": g_type,
}
header = {
"accessToken": access_oken,
"clientType": "3",
'version': '6.2.13',
"Referer": "https://m.kuke99.com",
"UUID": uuid,
"Content-Type": "application/x-www-form-urlencoded",
"deviceType": "V1814T",
"osVersion": "9",
"Content-Length": "25",
"Host": "new6api.kuke99.com",
"Connection": "Keep-Alive",
"Accept-Encoding": "gzip",
"User-Agent": "okhttp/4.9.1"
}
cookies = {
# "acw_tc": acw_tc
}
response = requests.post(url, data=params, headers=header)
# Вы также можете напрямую заменить поле данных полем json, которое поддерживается после версии 2.4.3.
# response = requests.post(url, json = body, headers = headers)
# Информация о возврате
data3_string = response.json()
# print(data3_string)
print(data3_string['code'])
if(data3_string['code']=='0'):
for keys in data3_string['data']:
print("Выбранное загружаемое видео id:"+keys['video_id'])
else:
print("Не удалось получить информацию о загрузке")
#видео Загрузить информацию о странице
if __name__ == '__main__':
UUID=''#Uid идентификатора пользователя
пароль=""#Пароль
логин(UUID,пароль)#Авторизоватьсяпароль аккаунта для получения токена
# print(access_token)
обновить(UUID,access_token)#Прочитать всю информацию о купленном курсе (список обучения)
#Пользователь вручную вводит данные
goods_id = input("Введите идентификатор_товара:")
print('Входное значение:' + goods_id)
goods_type = input("goods_type:")
print('Входное значение:' + goods_type)
# xiangqing(goods_id,goods_type,access_token,UUID)#видео Подробнее download(goods_id, goods_type, access_token, UUID) # Получить список загрузок
video_id = input("Введите video_id:")
print('Входное значение:' + video_id)
get_m3u8(video_id,access_token,UUID)#Получить ссылку m3u8