This commit is contained in:
widevinedump 2021-12-23 17:15:20 +05:30
parent ca452cf3ad
commit de9a72801e
1025 changed files with 224421 additions and 0 deletions

11
Movie_AVC_1080p.bat Normal file
View File

@ -0,0 +1,11 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
set/p aud="Enter Audio Language= "
wvripper.pyc %URL% --region eu --smart-select -vp AVC -q 1080 -gr FUCKU -o Downloads ^
--audio-language %aud%
pause.

11
Movie_AVC_720p.bat Normal file
View File

@ -0,0 +1,11 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
set/p aud="Enter Audio Language= "
wvripper.pyc %URL% --region eu --smart-select -vp AVC -q 720 -gr FUCKU -o Downloads ^
--audio-language %aud%
pause.

12
Movie_HDR_4K.bat Normal file
View File

@ -0,0 +1,12 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
wvripper.pyc %URL% --region eu -vp UHD —android -q 2160 -gr FUCKU -o Downloads ^
--audio-language en ^
--subtitle-language en
pause.

11
Movie_HEVC_1080p.bat Normal file
View File

@ -0,0 +1,11 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
set/p aud="Enter Audio Language= "
wvripper.pyc %URL% --region eu --smart-select -vp HEVC -q 1080 -gr FUCKU -o Downloads ^
--audio-language %aud%
pause.

11
Movie_HEVC_720p.bat Normal file
View File

@ -0,0 +1,11 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
set/p aud="Enter Audio Language= "
wvripper.pyc %URL% --region eu --smart-select -vp HEVC -q 720 -gr FUCKU -o Downloads ^
--audio-language %aud%
pause.

View File

@ -1,2 +1,29 @@
# WV-AMZN-4K-RIPPER
Tool To download Amazon 4k SDR HDR 1080, CDM IS Not Included
For CDM You can Mail :- wvfuck@cyberfiends.net
Leaked with Lots of Love
__________
.~#########%%;~.
/############%%;`\
/######/~\/~\%%;,;,\
|#######\ /;;;;.,.|
|#########\/%;;;;;.,.|
XX |##/~~\####%;;;/~~\;,| XX
XX..X |#| o \##%;/ o |.| X..XX
XX.....X |##\____/##%;\____/.,| X.....XX
XXXXX.....XX \#########/\;;;;;;,, / XX.....XXXXX
X |......XX%,.@ \######/%;\;;;;, / @#%,XX......| X
X |.....X @#%,.@ |######%%;;;;,.| @#%,.@ X.....| X
X \...X @#%,.@ |# # # % ; ; ;,| @#%,.@ X.../ X
X# \.X @#%,.@ @#%,.@ X./ #
## X @#%,.@ @#%,.@ X #
, "# #X @#%,.@ @#%,.@ X ##
`###X @#%,.@ @#%,.@ ####'
. ' ### @#%.,@ @#%,.@ ###`"
. ";" @#%.@#%,.@ ;"` ' .
' @#%,.@ ,.
` , @#%,.@ @@ `
@@@ @@@ .

12
SeaSon_AVC_1080p.bat Normal file
View File

@ -0,0 +1,12 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
set/p aud="Enter Audio Language= "
set/p Episode="Enter Episode= "
wvripper.pyc %URL% --region eu --smart-select -vp AVC -q 1080 -s 1 -e %Episode% -gr SaiTama -o Downloads ^
--audio-language %aud%
pause.

11
SeaSon_AVC_720.bat Normal file
View File

@ -0,0 +1,11 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
set/p aud="Enter Audio Language= "
set/p Episode="Enter Episode= "
wvripper.pyc %URL% --region eu --smart-select -vp AVC -q 720 -s 1 -e %Episode% -gr SaiTama -o Downloads ^
--audio-language %aud%
pause.

11
SeaSon_HDR_4K.bat Normal file
View File

@ -0,0 +1,11 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
set/p Season="Enter Season Number= "
wvripper.pyc %URL% --region eu -vp UHD —android -q 2160 -s %Season% -gr SaiTama -o Downloads ^
--audio-language en ^
--subtitle-language en
pause.

11
SeaSon_HEVC_1080p.bat Normal file
View File

@ -0,0 +1,11 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
set/p aud="Enter Audio Language= "
set/p Episode="Enter Episode= "
wvripper.pyc %URL% --region eu --smart-select -vp HEVC -q 1080 -s 1 -e %Episode% -gr FUCKU -o Downloads ^
--audio-language %aud%
pause.

11
SeaSon_HEVC_720.bat Normal file
View File

@ -0,0 +1,11 @@
@@ECHO OFF
set/p URL="Enter Primevideo URL= "
set/p aud="Enter Audio Language= "
set/p Episode="Enter Episode= "
wvripper.pyc %URL% --region eu --smart-select -vp HEVC -q 720 -s 1 -e %Episode% -gr SaiTama -o Downloads ^
--audio-language %aud%
pause.

BIN
configs/Cookies/cl (1).exe Normal file

Binary file not shown.

BIN
configs/Cookies/cl.exe Normal file

Binary file not shown.

View File

View File

View File

@ -0,0 +1,17 @@
# HTTP Cookie File downloaded with cookies.txt by Genuinous @genuinous
# This file can be used by wget, curl, aria2c and other standard compliant tools.
# Usage Examples:
# 1) wget -x --load-cookies cookies.txt "https://www.primevideo.com/detail/The-Handmaids-Tale-Series/0QW7NQ3CQIVMI5ED05XYS19P9U"
# 2) curl --cookie cookies.txt "https://www.primevideo.com/detail/The-Handmaids-Tale-Series/0QW7NQ3CQIVMI5ED05XYS19P9U"
# 3) aria2c --load-cookies cookies.txt "https://www.primevideo.com/detail/The-Handmaids-Tale-Series/0QW7NQ3CQIVMI5ED05XYS19P9U"
#
.primevideo.com TRUE / TRUE 1653714942 session-id 257-0038347-0468755
.primevideo.com TRUE / TRUE 1653714942 ubid-main-av 259-1850744-5064919
.primevideo.com TRUE / FALSE 1652961059 i18n-prefs USD
.primevideo.com TRUE / TRUE 1652961059 x-main-av "ScrnSKLUeYEm9QlZHlwt3dZo782g6?buizSHPaFdhvjGMEbmm8?7OjHJTqsIQG7?"
.primevideo.com TRUE / TRUE 1652961059 at-main-av Atza|IwEBIPO8plmb1MYDw9U1C7pP8JqQyay6o4juc-tcKRWs1W94AYF7XzYzmuEnqnRafyMRsxqaZNAzceuYSWmM4hitJz9u0jbH3HGbdBzoiQBQNeFuAvub0p2Fmp3fpjy8c0185XsQkTjMxfWSoFs6brScaTfrgEl-xfoLNRCT7SNh6I8QgJh9V6onZA9KuRriLQvEBFPEow78ro1rFZZA4rWha2l9
.primevideo.com TRUE / TRUE 1652961059 sess-at-main-av "pdEPotZ1sWXm/+f/qV0SJ1aLA+yLWwSM04HLxIlWf3g="
.primevideo.com TRUE / FALSE 1655626116 lc-main-av de_DE
.primevideo.com TRUE / TRUE 1653714712 session-token "mtRVF4lOAzfyhTEkcJTnul8r9UdIC5egMEPYermEqJg+SvS7WOQDkOQbk878qqNiKv5vFCF67IFoHc8JoJeehwOzyjeKEUtEqrct0T26fWavDo9ih4TuAmm78jI06nIutdB8QyhHcImqxDCHA9GtnAYD6/JSA8aPsY23+1g0dI85LcKTXb7rBk3LxihUBw9f6RVM3p1LwrtvMHMy1D7WZQ=="
.primevideo.com TRUE / FALSE 1653714942 session-id-time 2082758401l
www.primevideo.com FALSE / FALSE 1652418943 csm-hit tb:V4A6B5JR131JV44WAJEY+s-P6F7H6HX20CJ3MG3NNVX|1622178943543&t:1622178943544&adb:adblk_yes

View File

View File

@ -0,0 +1,22 @@
# HTTP Cookie File downloaded with cookies.txt by Genuinous @genuinous
# This file can be used by wget, curl, aria2c and other standard compliant tools.
# Usage Examples:
# 1) wget -x --load-cookies cookies.txt "https://www.amazon.com/gp/video/detail/B08WYHRBBH/ref=atv_3p_hbo_c_7bUTvm_brws_2_1"
# 2) curl --cookie cookies.txt "https://www.amazon.com/gp/video/detail/B08WYHRBBH/ref=atv_3p_hbo_c_7bUTvm_brws_2_1"
# 3) aria2c --load-cookies cookies.txt "https://www.amazon.com/gp/video/detail/B08WYHRBBH/ref=atv_3p_hbo_c_7bUTvm_brws_2_1"
#
.associates-amazon.com TRUE / TRUE 1624841566 abid e6bcb1cc-6df0-b57d-a226-76cb8be24829
.amazon.com TRUE / TRUE 1653958585 ubid-main 131-9705044-5253861
.amazon.com TRUE / FALSE 2082787201 lc-main en_US
.amazon.com TRUE / TRUE 1653958161 ubid-main-av 135-0014401-4583503
.amazon.com TRUE / TRUE 1653958016 lc-main-av zh_TW
.amazon.com TRUE / FALSE 0 skin noskin
.amazon.com TRUE / TRUE 1653958585 session-id 147-2017101-9262448
.amazon.com TRUE / TRUE 1653958573 session-token "SmO/Pi7JXxECw4qGIpgvs60FQ04zRGX5ioS27++ZRs02GwR9E+7l9oC1H9oAIKjQOJL+7sU9ZXJswsGFu+Qdv1//hzkBsusXQJV28mHsY1Wn7RvcG+j8bzezebCTHMEMRFnn+E3QEhxTvgpOkiF66P8Z8ATlYYc0zf1GwPq+c6cYfy+k9xQrCIqdQ+YBdO4xPLP03jeKaBS8Ewebw5iIF9QHy8t98IDW16EU5zbqS4s="
.amazon.com TRUE / TRUE 1653958573 x-main "9atgnNhYPLAdgqLwOubcLzhra0MEaqE9k0oOqn6APNo@e8g8QuzWUdaLTpqJ4KJ0"
.amazon.com TRUE / TRUE 1653958447 at-main Atza|IwEBIOZTPeWg1i5KCfjkoVaDH7vU_Bj6fu4KqrDpv7xp1GcfTQyDNgoFJKaApqF7eG1lsEvwjTXgoIiCGteEhixyG_GO-dhQRQ8eYhkNNrL95YUnZvRCdCA68Mm1n5fR87hkUBFPTp6IO_wx4UOTdPcI-3AKP7D4b_3oA6xdYSkfZo4wrBjMCGX4ZkR2wKGC9rl_Bvs6vsgq4eIXtH_wqAHd0vP4
.amazon.com TRUE / TRUE 1653958447 sess-at-main "YWyWD1e0HRsfoRcPJXFKGs+gDXtQTbas47fEVJzWn6A="
.amazon.com TRUE / TRUE 1653958447 sst-main Sst1|PQEk337sIEiZEXH7Oe-lynv5CepAtSy7zc8lh22uwm5L-xvvDzQOc7tYMEpgNwBqURUo8mWwKPTVBSscQjMyNLam308eCgTuowo1WfAn7of4Ylspz5aFOamAE6cGqQUpzEiYTEDwSc7ARrs7RjDQ64Pet7vxHXE-ouJorEup35y-yAIv9UtaVIYXFI5WXnjTmO7phqWYvy2hINgw8XQUjhvT_dGYN6l8m_bpRGC1VwtN5d2qFXIUhe7anAGbg_lCufeXIPJZhsDNYXemHG2diPUYxW_Q7mF30t7l6XfHAjIqkM8
.amazon.com TRUE / FALSE 1653958573 i18n-prefs USD
.amazon.com TRUE / FALSE 1653958585 session-id-time 2082787201l
www.amazon.com FALSE / FALSE 1652662578 csm-hit tb:s-KP49VK73TBB0WT6V4WM8|1622422577773&t:1622422578481&adb:adblk_no

View File

@ -0,0 +1,17 @@
# HTTP Cookie File downloaded with cookies.txt by Genuinous @genuinous
# This file can be used by wget, curl, aria2c and other standard compliant tools.
# Usage Examples:
# 1) wget -x --load-cookies cookies.txt "https://www.primevideo.com/detail/The-Handmaids-Tale-Series/0QW7NQ3CQIVMI5ED05XYS19P9U"
# 2) curl --cookie cookies.txt "https://www.primevideo.com/detail/The-Handmaids-Tale-Series/0QW7NQ3CQIVMI5ED05XYS19P9U"
# 3) aria2c --load-cookies cookies.txt "https://www.primevideo.com/detail/The-Handmaids-Tale-Series/0QW7NQ3CQIVMI5ED05XYS19P9U"
#
.primevideo.com TRUE / TRUE 1653714942 session-id 257-0038347-0468755
.primevideo.com TRUE / TRUE 1653714942 ubid-main-av 259-1850744-5064919
.primevideo.com TRUE / FALSE 1652961059 i18n-prefs USD
.primevideo.com TRUE / TRUE 1652961059 x-main-av "ScrnSKLUeYEm9QlZHlwt3dZo782g6?buizSHPaFdhvjGMEbmm8?7OjHJTqsIQG7?"
.primevideo.com TRUE / TRUE 1652961059 at-main-av Atza|IwEBIPO8plmb1MYDw9U1C7pP8JqQyay6o4juc-tcKRWs1W94AYF7XzYzmuEnqnRafyMRsxqaZNAzceuYSWmM4hitJz9u0jbH3HGbdBzoiQBQNeFuAvub0p2Fmp3fpjy8c0185XsQkTjMxfWSoFs6brScaTfrgEl-xfoLNRCT7SNh6I8QgJh9V6onZA9KuRriLQvEBFPEow78ro1rFZZA4rWha2l9
.primevideo.com TRUE / TRUE 1652961059 sess-at-main-av "pdEPotZ1sWXm/+f/qV0SJ1aLA+yLWwSM04HLxIlWf3g="
.primevideo.com TRUE / FALSE 1655626116 lc-main-av de_DE
.primevideo.com TRUE / TRUE 1653714712 session-token "mtRVF4lOAzfyhTEkcJTnul8r9UdIC5egMEPYermEqJg+SvS7WOQDkOQbk878qqNiKv5vFCF67IFoHc8JoJeehwOzyjeKEUtEqrct0T26fWavDo9ih4TuAmm78jI06nIutdB8QyhHcImqxDCHA9GtnAYD6/JSA8aPsY23+1g0dI85LcKTXb7rBk3LxihUBw9f6RVM3p1LwrtvMHMy1D7WZQ=="
.primevideo.com TRUE / FALSE 1653714942 session-id-time 2082758401l
www.primevideo.com FALSE / FALSE 1652418943 csm-hit tb:V4A6B5JR131JV44WAJEY+s-P6F7H6HX20CJ3MG3NNVX|1622178943543&t:1622178943544&adb:adblk_yes

View File

@ -0,0 +1,23 @@
# HTTP Cookie File for domains related to amazon.com.
# Downloaded with cookies.txt Chrome Extension (https://chrome.google.com/webstore/detail/njabckikapfpffapmjgojcnbfjonfjfg)
# Example: wget -x --load-cookies cookies.txt https://www.amazon.com/
#
.amazon.com TRUE / TRUE 1654080101 session-id 131-7859327-9648921
.amazon.com TRUE / TRUE 1654080101 ubid-main 131-7622153-8191118
.associates-amazon.com TRUE / TRUE 1624466535 abid a6bcba4b-184a-79ca-fd5d-4f939a73eff4
.amazon.com TRUE / FALSE 2082787202 lc-main en_US
.amazon.com TRUE / TRUE 1654068574 x-main "qMm01hOue0S61wKyr3cHx7JQW37zGNOnb@rWK7AbQW0XAur8YvcW@GCwGUXUT?nF"
.amazon.com TRUE / TRUE 1652926420 at-main Atza|IwEBIJrxfwLUK6HS-5D8TJsvmL4GYytj6qGK2hQrp7WUkEiIb8f_Qyzh456DDgS9JQtoZKFf2j42hQeuN6Yyzp75vnDKBfdFibHk2ESKyrT-1F6wV6ygKbI2HCR6pPX9N93UZf2sBU6J0azAIeVu4no3G6GIlatI9h3SlLfxJxsOhQuDfhgKTNn1G6mekXGd903QYZdXRP9rWcO-jsW08B5yCT6u
.amazon.com TRUE / TRUE 1652926420 sess-at-main "OyzHXBcU9E8NV4+67WI32JiY5Po+mdIs+9n8r/uz+oA="
.amazon.com TRUE / TRUE 1652926420 sst-main Sst1|PQHUAEZSCnHyQoZlK5WlmQbGCdlKfFzmrEJi0D-iWa_UjWbZ6lny2eCUPGXNSdWqnb8GhfqNAqBf98GYYekTHdbxYc9YrS3pc-YHUc-0tDmNk4faQOAjV546D0zh8T0X05l-HsTZ5oU_vaZJkB1Zec-tb3ZRG3qxX5Lxb7vy6IAxG57036Ykv9IMyGOOCqdgoHa7YS09Ht_pAfAQZYN6VM-LzvnF68iAvAmtISSkyXnQme_PHgozlGGRRj27cJSDXLvQP6ZFNGhFq9kptOxx9Slw6UQBmx1eo0TyfeiCt_6kpAI
.amazon.com TRUE / FALSE 1654068574 i18n-prefs USD
.aws.amazon.com TRUE / FALSE 1653735711 aws-priv eyJ2IjoxLCJldSI6MCwic3QiOjB9
.amazon.com TRUE / FALSE 1653736859 s_fid 08CC8BDD22AD0635-1817E9A096C69103
.amazon.com TRUE / FALSE 1653736859 regStatus pre-register
.amazon.com TRUE / FALSE 1655895709 aws-target-data %7B%22support%22%3A%221%22%7D
.amazon.com TRUE / FALSE 1653735710 aws-target-visitor-id 1622199709297-329210.34_0
.aws.amazon.com TRUE / FALSE 1653735710 _mkto_trk id:112-TZM-766&token:_mch-aws.amazon.com-1622199710412-51353
.amazon.com TRUE / FALSE 0 skin noskin
.amazon.com TRUE / FALSE 1654080101 session-id-time 2082787201l
.amazon.com TRUE / FALSE 2082787201 session-token "K6hL7YwHIrZL5wFPfIRl1z+QoXk7m9aQEuDBE4eskYhfrFNtBFgI3XlG7WedhSP9drA1Ouawulrw+Sr+Gz8tsVgQVqOBLr6M30Eu3MmJkKCGDMe6CFLAqXuS3x8f5pnKA2WhkzmHePItVp+1UCp6PrrDB6MWvgK6kdTcWj3RLVd4graGyeAijznY1oHfOOaV7WsNZQpDvE6TW9m3sUOP/A=="
www.amazon.com FALSE / FALSE 1652784100 csm-hit tb:s-MSQPAFJNYPA20RVBJ170|1622544099143&t:1622544100333&adb:adblk_no

View File

@ -0,0 +1 @@
KID:KEY

View File

@ -0,0 +1,108 @@
{
"refresh_token": "Atnr|EwICIFqjcW3qfSYbPsGahXGhAsWeKSW8YbXqDEBQiFrzSH_SdXqEplGhBfcOGC03hdRtqmpIj3oFGwYx0TIwyaJWRqLU2mx0JR6E3iTt_9cSCgICt1hlV9LejnNHKvck5fEsZ1343oeDhfZ6br6FZkwsU_x-LNlvDyBBfRYddPMqLq-X7qBJWAXZuvG0YLxWDDuAN1A2BFU4QSWDYvEFuoeIcPgZQtkt5ebVdJxv1keiXF6F-Lgft5b1aBL-eK83G7ZFJPH-lanJZ_3tk_xTOTv13G8XBLeSwwPJ-r70tz8Ccao12g",
"access_token": "bearer Atna|EwICID3U3hvIE0TqTBEPqG2B3Nn8Yhr-SFJ3e-aFoEec7oYtssLaFBAKBTmwz9arRM_fRHca2C_aRPMcA5SRto1HkreyzVEdKIfVKiibsZtAxEjeztj9XCCzkoFskeWdBf9nGtMC2872jbigtj0g6QDKiYvH2eh1I6l1Y3yDl-fA1DncGr5qum_lT88JIlMdT9sH8OkJ2YW1-aJhYuZDNXetN-tWTIrPanUQ6OEy9vTEa4ZpOLQEOTeKsJMV0M7aFEc68ZnGmBe-jHxKpbqbw20tnm6mFoVQ5gxySDh_L1qlZPd6WXZ9fiRNSEQwp58m5Vtkitw",
"cookies": "session-id=145-5028685-5307043; ubid-main=134-7715513-6480940; x-main=\"1pTJtEcDLpLk25jg7gq0CiWz?6O2Y7EoeAgdCMGvicmGKGSsWY9cvH5XW@oZoTIw\"; at-main=\"Atza|IwEBIKY9z1_GBAJM5wyewJwl8Y_WWW45FX6YvfH_Xd8M8sPI6st3xj2x6DVYN90J508W0y2fFT_gJE2BYSDkezb9maFVMz3EZuIwvylzWOc2a4Qay8LME9fYqRZu2NA4EvsESRrWUgKhW-iX56dDL5Xg-9LJsNYD2l1kvVz4N1Tx4ZTDjfkiV5wRa8asBS-6htJGyOZ93xvhjz8oS3Aubed4SUHRfS1NPusExThL-6Pl4qsNFtuth_uVQRengHgzgj-7WAoGiW4NytrtlpxcXiL14MWseo0TdEZAuZEloLblad06a7t1vIy9HZfCnSUfLsKmAdBLAl2f9wd8uJgW5EHOeTHG\"; sess-at-main=\"eIH1m+wPTEwWNixmBz9UJe6KOE8CJT2qZSUcz3kt5Ug=\"",
"device_serial": "9925GGTLDIMG71I5N730OKVLFL29M9FFYBTAZ4EA",
"device_type": "A1KAXIG6VXSG8Y",
"expire_in": 1622857693,
"params": {
"public_code": "BYXUY9",
"private_code": "06be357b-269f-4a3e-9ea5-b13bb1ad6f2b",
"domain": "com",
"region": "ps",
"ANDROID_REGISTRATION": {
"domain": "Device",
"app_name": "AIV",
"app_version": "3.12.0",
"device_model": "SHIELD Android TV",
"os_version": "28",
"device_type": "A1KAXIG6VXSG8Y",
"device_serial": "9925GGTLDIMG71I5N730OKVLFL29M9FFYBTAZ4EA",
"device_name": "%FIRST_NAME%'s%DUPE_STRATEGY_1ST% Shield TV",
"software_version": "248"
}
},
"RESPONSE": {
"response": {
"success": {
"extensions": {
"device_info": {
"device_name": "Rajdeep's 3rd Shield TV",
"device_serial_number": "9925GGTLDIMG71I5N730OKVLFL29M9FFYBTAZ4EA",
"device_type": "A1KAXIG6VXSG8Y"
},
"customer_info": {
"account_pool": "Amazon",
"user_id": "amzn1.account.AELPYORG7577ZOG4WH33UGEQPU5A",
"home_region": "NA",
"name": "Rajdeep Biswas",
"given_name": "Rajdeep"
}
},
"tokens": {
"website_cookies": [
{
"Path": "/",
"Secure": "true",
"Value": "145-5028685-5307043",
"Expires": "30 May 2041 05:19:13 GMT",
"Domain": ".amazon.com",
"HttpOnly": "false",
"Name": "session-id"
},
{
"Path": "/",
"Secure": "true",
"Value": "134-7715513-6480940",
"Expires": "30 May 2041 05:19:13 GMT",
"Domain": ".amazon.com",
"HttpOnly": "false",
"Name": "ubid-main"
},
{
"Path": "/",
"Secure": "true",
"Value": "\"1pTJtEcDLpLk25jg7gq0CiWz?6O2Y7EoeAgdCMGvicmGKGSsWY9cvH5XW@oZoTIw\"",
"Expires": "30 May 2041 05:19:13 GMT",
"Domain": ".amazon.com",
"HttpOnly": "false",
"Name": "x-main"
},
{
"Path": "/",
"Secure": "true",
"Value": "\"Atza|IwEBIKY9z1_GBAJM5wyewJwl8Y_WWW45FX6YvfH_Xd8M8sPI6st3xj2x6DVYN90J508W0y2fFT_gJE2BYSDkezb9maFVMz3EZuIwvylzWOc2a4Qay8LME9fYqRZu2NA4EvsESRrWUgKhW-iX56dDL5Xg-9LJsNYD2l1kvVz4N1Tx4ZTDjfkiV5wRa8asBS-6htJGyOZ93xvhjz8oS3Aubed4SUHRfS1NPusExThL-6Pl4qsNFtuth_uVQRengHgzgj-7WAoGiW4NytrtlpxcXiL14MWseo0TdEZAuZEloLblad06a7t1vIy9HZfCnSUfLsKmAdBLAl2f9wd8uJgW5EHOeTHG\"",
"Expires": "5 Jun 2021 05:19:13 GMT",
"Domain": ".amazon.com",
"HttpOnly": "true",
"Name": "at-main"
},
{
"Path": "/",
"Secure": "true",
"Value": "\"eIH1m+wPTEwWNixmBz9UJe6KOE8CJT2qZSUcz3kt5Ug=\"",
"Expires": "5 Jun 2021 05:19:13 GMT",
"Domain": ".amazon.com",
"HttpOnly": "true",
"Name": "sess-at-main"
}
],
"store_authentication_cookie": {
"cookie": "7oCEXDSy60WboDHQYCe/T0jQ+1NDez+6/5MbLVNZDtNmk1fz/74JBIZXldC+Auu3Kn2sLJsZ6a5nq4rGPWub3H47nq6NJEkcKkk/2GU49dTUX05cVFw+HDHStc/G0Wd5KwL0ad4VBuZ3FA0izAi2P0SFDIqt52JERuZfcfUf7kwIhz3B9cvOboS7EMBNzlLD"
},
"mac_dms": {
"device_private_key": "-----BEGIN RSA PRIVATE KEY-----\nMIIEpAIBAAKCAQEA0dXVFsllaGZK1SM9hr96Wc9qY6be/+39My9xGXv5FNyjvkjR\nK73WEq/jANaZ9Bv4vPHK75Qa/MmqGv9WDrjFCW+/525rz9MdgBSwtKidEHR7uCaI\nINtWlR5gPaMUmlHLYchRfWmxDIErO0WUhK5h7mhanp2EfA1UwMe2dZxJWp+esgSd\nxdvn+pW3hiGU0jB7+HGFLnxwPlASUXpLQkjXdeanBTtNCfX5m6QKREy0wTzpklCt\nJqMadva8ibYM12s3LF7N0hJhE7Vyp5pKAmbFG8pNgYbJ2CVG97bmgKYpgx/Yt+Mb\n70Z70xXZPUx3ZOSWsESmi3ah3VMsInJukwmp0wIDAQABAoIBAQDOXvbHBWX1yn0Y\nqCMPzmv/vi3NOkYiASc/2w3p2XK8oM9uCuGlmnvbPx8MKQObAJOfCFLlU41DRvdE\nvBEgQ3qN8FkVvRTNfb2KxU6RLy/iCh3PnB3P6sh5ujk/BY/ywjU7wy7aIEOfn74r\n+h+6amMofXt6ekLdWqMbQo/hlcbTF1W0zzI+aWbbGNdh+xavvD3LC37jGRD1VxNe\nvPATuX5MpCdTa/qrDbrnqlnKoXXbWO+DvNgMWi5IjCancqp9BW8J9rAQ5OA6fRLD\n7pFtWi+V18/Gttj6rOGvOpmC7LRp4JNSG2rQzR8PTg43R7dyd2dQIn4krswxKYPA\nOpRvi2gpAoGBAP5pudhprE5aaHeZTt+MytmJ4BiLgjoVbWOCtup/VVktEQbN7EUJ\nlJcWGF5Qo0C3WaN4vOlRKm5e/Kt1QvaHb8faE0zNh1WTqz47G8iVy+qehYE1PywG\nUabz0tau0y/ZZE/LXrQwVD2Dt4nwlfysc3/xnDs1pM0Wxxg2nMeehuHlAoGBANMk\n64EHCGHAvxU/y5mWre8zc4Fd66eipc8MFgPlJVCj9ffRpnUU9N9aRKuuilMbA82Z\nEL7MAXkfAlPCal2MGFlbJSYGvFygPeFg0NvQXoK+uc3A5nDJJBZrxGlutDVobs67\nnSpglt6b1A79029C3sYgs55ZDYsLPnQ6xKFp/QFXAoGALuHy0nOewg2dBLUmuMFs\nPCxRNJS42dVLBDR5Wrs+UiGg6p0V9h7u1+zFbtPzUaC4DwzX2zMO26n7a+k+/sk0\niyKfvd5+GwIMY3pnA06/diviNE5Ipuc/MsHpz5AF8OJhvuaePBxP2colD3FbYmWx\nHxm6DZs0FGsnI0olGBAZkRUCgYA3KOEBXzX4W6NPyM/Guw+LevSE6mVi8OHCOlUS\nBW3/KCZc7H9A/Q2PwARKmZl3ZopSztcKET+dRdWUzih9cdj2lxIYYhAZXp9r3qAR\nnNjj7TGbJ/bLpjBwTw0Lwij//t1b0rWXWY5wb2Mx22u+GEkcl3R1PKyGE5ToRmYS\nCR9YlwKBgQDfVuQZCfPJmDpKldf3up0hgY+ZC5SrpX3QM0Fz5RrhKwPfRvWENJMT\nEqyOXOGJ2RaDRcEjtF2b9/v3mTD5RB68Qozj0vTRPxjzbrjs5rg8VCVeZGBUlGRx\nnkUNDaeO4PYd4+UW2nNFEoawQYB1J71paOvk20QKueM1MRUpEI6gdA==\n-----END RSA PRIVATE KEY-----\n",
"adp_token": "{enc:0p/vZ2wugGUr8L3A6hBKRzlgo5pHXOH2/Iu9fK4VYGxIUHhRrMtMonE9CFjTTNX6TcHPRXjUqWRPqvZo6Sg5NNua16bO/+SVtdOTGFyVg9dX6c81bCUtS6GyljEsvUSuq4kfbjo7l0Xgh27Y5ihASgwpMybD58+ifUqkgIuxNpUmWDOZiVZYi7+EUdM8EDilRlHf7LwOhkzGDSmaKKeSxRNNBgqozaUraUciM1+a3CM7lOFlJJePf/li4NpfdAC9A2Ww8TroIEE9HuiWCV/6t1HlBYKZH8RTgMiwQDpi7qc8hSlfE2gJwAAmlJEQUY8A7P+4EYa4fKU3tsIe0e1DF4pxMBzVSaTZH3EpHmrrpBKF4xywYKosCY/c/jxfS6gog4BecNXAIW8YL+nfpLtTLIqlTiKNHfTwm6AhT5TIgKq3sSWY9pwPO0BNov6tcXQ5caQllul1PJhLPN2PjPQ9/7fyzKjrxi3oZiVdS7gh7mlievOmplAVixc9K4fc/xiTy8fyQZqck1v/9paWqi6NJnQdYqt0wtK5qYz0p3oaLZI3G8/zz6MLeZxpKyXr88jqbvNthLpdxXe1cB5sRMNJRp8gSdluH5mR1dB05GAYwbU+GbckkEoQIqHB3vQLSMJUjMTXv/a43+uTqd8E1vjtMgrpy4mhbmcBrrPF1K0LWR8z3T2Z75sRWxNb8KpW43ouw0ck3Sm05cYegIma5b8P9/NbiRfZm/9Gz0GVQz25U1NqE4a7pBOk3jE3oooscsf3GZM+5TENvZDx4MAV979FEA/Z2k4jgrrOduTIYwfuF4PGjNkN1QsMuYczxHmrjsvuNJ3TM76/IcG5jBGfFQZBQO5Fzv3R7l4dlqISYtV17MkCDNnXwJ6rohnz8H0C+gxbR/Kcl+tWdtAAHkKYIgmCfkZgPByQTSKwC1je4EuC6YL96sR+LV5GUg8kaLJ/Ud3RZ/fnxZ+gi/jRskjKN2Hxn/8ZugMoxySfSc7RRBaSowUErnt8iPgg/8owi8OZUpMsDPr0sIKgjZScRklsJeAeDv1l031Y9EgabbCUm7O7Vtp1l6fXQWfKZcxYYKqypGBh}{key:Vc+00rapFNEmIT8NYQRlJqt8S9ZxCFpz+MVaGdng4jVu5EE00X/tFQzusA8FGaWW3rpbYqHSpKEZVa2gJapE4sgB9dWLaiT6tidNE4aKmgopF2/+ubc9lahrDjVTsvczx9RoTvvEtMgJtvwJ04rOb4N93q25K/IyUEFve7U/NcASSumpoB07Q2OIiW6DPHimqms/Y00W4NFq6F/unnO5vdEZWYeql+W3NTJd4pR+zC1rpgOpvFbquiibcgdxVm2Y4fQqNil6GdA9biCx7Otr6BudaJzxij1to9tH4tBt+LgibGrRA+aYWtrnt4rijor4tLdlqRo3jKaSBBZ+pYTO3w==}{iv:qThxxSnffr/fJPoOCU5U4w==}{name:QURQVG9rZW5FbmNyeXB0aW9uS2V5}{serial:Mg==}"
},
"bearer": {
"access_token": "Atna|EwICIA7Jo3vvomqEX-KCECWtgoCap7ksP5_4S75wLzPrYDAGPYI2Jk06lVQJRuOZBCH7znrUETXpPp1Fbvsp-Ucn0CtT5Ql0gx5_damtPsnxoG1BiBo75Zjq_EZeyal8f12U53IVcXhLD2vjiis9s21PuP0uL3K6hH1qLgTktX6WfwAnt-Y8t7Kj_jFPf-0cjFlLHvs5gmEnKmqWDpxa4OSbougPMU1cmH5iXrWKuYAE-542nw",
"refresh_token": "Atnr|EwICIFqjcW3qfSYbPsGahXGhAsWeKSW8YbXqDEBQiFrzSH_SdXqEplGhBfcOGC03hdRtqmpIj3oFGwYx0TIwyaJWRqLU2mx0JR6E3iTt_9cSCgICt1hlV9LejnNHKvck5fEsZ1343oeDhfZ6br6FZkwsU_x-LNlvDyBBfRYddPMqLq-X7qBJWAXZuvG0YLxWDDuAN1A2BFU4QSWDYvEFuoeIcPgZQtkt5ebVdJxv1keiXF6F-Lgft5b1aBL-eK83G7ZFJPH-lanJZ_3tk_xTOTv13G8XBLeSwwPJ-r70tz8Ccao12g",
"expires_in": "3600"
}
},
"customer_id": "amzn1.account.AELPYORG7577ZOG4WH33UGEQPU5A"
}
},
"request_id": "e6229631-03db-41f4-a3ce-8aba27c91de7"
}
}

BIN
configs/__init__.pyc Normal file

Binary file not shown.

13
configs/config.cfg Normal file
View File

@ -0,0 +1,13 @@
[CONFIG]
#####################PROXY#####################
nrd_email =
nrd_password =
prv_email =
prv_password =
tor_email =
tor_password =

BIN
configs/config.pyc Normal file

Binary file not shown.

BIN
helpers/Parsers.pyc Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
helpers/Utils/__init__.pyc Normal file

Binary file not shown.

BIN
helpers/Utils/aria2.pyc Normal file

Binary file not shown.

BIN
helpers/Utils/ffmpeg.pyc Normal file

Binary file not shown.

BIN
helpers/Utils/keyloader.pyc Normal file

Binary file not shown.

Binary file not shown.

BIN
helpers/Utils/schedule.pyc Normal file

Binary file not shown.

BIN
helpers/Utils/subtitle.pyc Normal file

Binary file not shown.

BIN
helpers/Utils/utils.pyc Normal file

Binary file not shown.

BIN
helpers/Utils/vpn.pyc Normal file

Binary file not shown.

BIN
helpers/__init__.pyc Normal file

Binary file not shown.

BIN
helpers/main.pyc Normal file

Binary file not shown.

BIN
helpers/tracks.pyc Normal file

Binary file not shown.

BIN
helpers/tracks_colored.pyc Normal file

Binary file not shown.

BIN
helpers/wvdownloader.pyc Normal file

Binary file not shown.

BIN
helpers/wvtracks.pyc Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

369
pywidevine/cdm/cdm.py Normal file
View File

@ -0,0 +1,369 @@
#if __name__ == 'pywidevine.cdm':
import base64
import os
import time
import binascii
from google.protobuf.message import DecodeError
from google.protobuf import text_format
from pywidevine.cdm.formats import wv_proto2_pb2 as wv_proto2
from pywidevine.cdm.session import Session
from pywidevine.cdm.key import Key
from Cryptodome.Random import get_random_bytes
from Cryptodome.Random import random
from Cryptodome.Cipher import PKCS1_OAEP, AES
from Cryptodome.Hash import CMAC, SHA256, HMAC, SHA1
from Cryptodome.PublicKey import RSA
from Cryptodome.Signature import pss
from Cryptodome.Util import Padding
import logging
import warnings
class Cdm:
def __init__(self):
self.logger = logging.getLogger(__name__)
self.sessions = {}
def open_session(self, init_data_b64, device, raw_init_data = None, offline=False):
self.logger.debug("open_session(init_data_b64={}, device={}".format(init_data_b64, device))
self.logger.info("opening new cdm session")
if device.session_id_type == 'android':
# format: 16 random hexdigits, 2 digit counter, 14 0s
rand_ascii = ''.join(random.choice('ABCDEF0123456789') for _ in range(16))
counter = '01' # this resets regularly so its fine to use 01
rest = '00000000000000'
session_id = rand_ascii + counter + rest
session_id = session_id.encode('ascii')
elif device.session_id_type == 'chrome':
rand_bytes = get_random_bytes(16)
session_id = rand_bytes
else:
# other formats NYI
self.logger.error("device type is unusable")
return 1
if raw_init_data and isinstance(raw_init_data, (bytes, bytearray)):
# used for NF key exchange, where they don't provide a valid PSSH
init_data = raw_init_data
self.raw_pssh = True
else:
init_data = self._parse_init_data(init_data_b64)
self.raw_pssh = False
if init_data:
new_session = Session(session_id, init_data, device, offline)
else:
self.logger.error("unable to parse init data")
return 1
self.sessions[session_id] = new_session
self.logger.info("session opened and init data parsed successfully")
return session_id
def _parse_init_data(self, init_data_b64):
with warnings.catch_warnings():
warnings.simplefilter('error')
parsed_init_data = wv_proto2.WidevineCencHeader()
try:
self.logger.debug("trying to parse init_data directly")
parsed_init_data.ParseFromString(base64.b64decode(init_data_b64))
except (DecodeError, SystemError):
self.logger.debug("unable to parse as-is, trying with removed pssh box header")
try:
id_bytes = parsed_init_data.ParseFromString(base64.b64decode(init_data_b64)[32:])
except (DecodeError, SystemError):
self.logger.error("unable to parse, unsupported init data format")
return None
self.logger.debug("init_data:")
for line in text_format.MessageToString(parsed_init_data).splitlines():
self.logger.debug(line)
return parsed_init_data
def close_session(self, session_id):
self.logger.debug("close_session(session_id={})".format(session_id))
self.logger.info("closing cdm session")
if session_id in self.sessions:
self.sessions.pop(session_id)
self.logger.info("cdm session closed")
return 0
else:
self.logger.info("session {} not found".format(session_id))
return 1
def set_service_certificate(self, session_id, cert_b64):
self.logger.debug("set_service_certificate(session_id={}, cert={})".format(session_id, cert_b64))
self.logger.info("setting service certificate")
if session_id not in self.sessions:
self.logger.error("session id doesn't exist")
return 1
session = self.sessions[session_id]
message = wv_proto2.SignedMessage()
try:
message.ParseFromString(base64.b64decode(cert_b64))
except DecodeError:
self.logger.error("failed to parse cert as SignedMessage")
service_certificate = wv_proto2.SignedDeviceCertificate()
if message.Type:
self.logger.debug("service cert provided as signedmessage")
try:
service_certificate.ParseFromString(message.Msg)
except DecodeError:
self.logger.error("failed to parse service certificate")
return 1
else:
self.logger.debug("service cert provided as signeddevicecertificate")
try:
service_certificate.ParseFromString(base64.b64decode(cert_b64))
except DecodeError:
self.logger.error("failed to parse service certificate")
return 1
self.logger.debug("service certificate:")
for line in text_format.MessageToString(service_certificate).splitlines():
self.logger.debug(line)
session.service_certificate = service_certificate
session.privacy_mode = True
return 0
def get_license_request(self, session_id):
self.logger.debug("get_license_request(session_id={})".format(session_id))
self.logger.info("getting license request")
if session_id not in self.sessions:
self.logger.error("session ID does not exist")
return 1
session = self.sessions[session_id]
# raw pssh will be treated as bytes and not parsed
if self.raw_pssh:
license_request = wv_proto2.SignedLicenseRequestRaw()
else:
license_request = wv_proto2.SignedLicenseRequest()
client_id = wv_proto2.ClientIdentification()
if not os.path.exists(session.device_config.device_client_id_blob_filename):
self.logger.error("no client ID blob available for this device")
return 1
with open(session.device_config.device_client_id_blob_filename, "rb") as f:
try:
cid_bytes = client_id.ParseFromString(f.read())
except DecodeError:
self.logger.error("client id failed to parse as protobuf")
return 1
self.logger.debug("building license request")
if not self.raw_pssh:
license_request.Type = wv_proto2.SignedLicenseRequest.MessageType.Value('LICENSE_REQUEST')
license_request.Msg.ContentId.CencId.Pssh.CopyFrom(session.init_data)
else:
license_request.Type = wv_proto2.SignedLicenseRequestRaw.MessageType.Value('LICENSE_REQUEST')
license_request.Msg.ContentId.CencId.Pssh = session.init_data # bytes
if session.offline:
license_type = wv_proto2.LicenseType.Value('OFFLINE')
else:
license_type = wv_proto2.LicenseType.Value('DEFAULT')
license_request.Msg.ContentId.CencId.LicenseType = license_type
license_request.Msg.ContentId.CencId.RequestId = session_id
license_request.Msg.Type = wv_proto2.LicenseRequest.RequestType.Value('NEW')
license_request.Msg.RequestTime = int(time.time())
license_request.Msg.ProtocolVersion = wv_proto2.ProtocolVersion.Value('CURRENT')
if session.device_config.send_key_control_nonce:
license_request.Msg.KeyControlNonce = random.randrange(1, 2**31)
if session.privacy_mode:
if session.device_config.vmp:
self.logger.debug("vmp required, adding to client_id")
self.logger.debug("reading vmp hashes")
vmp_hashes = wv_proto2.FileHashes()
with open(session.device_config.device_vmp_blob_filename, "rb") as f:
try:
vmp_bytes = vmp_hashes.ParseFromString(f.read())
except DecodeError:
self.logger.error("vmp hashes failed to parse as protobuf")
return 1
client_id._FileHashes.CopyFrom(vmp_hashes)
self.logger.debug("privacy mode & service certificate loaded, encrypting client id")
self.logger.debug("unencrypted client id:")
for line in text_format.MessageToString(client_id).splitlines():
self.logger.debug(line)
cid_aes_key = get_random_bytes(16)
cid_iv = get_random_bytes(16)
cid_cipher = AES.new(cid_aes_key, AES.MODE_CBC, cid_iv)
encrypted_client_id = cid_cipher.encrypt(Padding.pad(client_id.SerializeToString(), 16))
service_public_key = RSA.importKey(session.service_certificate._DeviceCertificate.PublicKey)
service_cipher = PKCS1_OAEP.new(service_public_key)
encrypted_cid_key = service_cipher.encrypt(cid_aes_key)
encrypted_client_id_proto = wv_proto2.EncryptedClientIdentification()
encrypted_client_id_proto.ServiceId = session.service_certificate._DeviceCertificate.ServiceId
encrypted_client_id_proto.ServiceCertificateSerialNumber = session.service_certificate._DeviceCertificate.SerialNumber
encrypted_client_id_proto.EncryptedClientId = encrypted_client_id
encrypted_client_id_proto.EncryptedClientIdIv = cid_iv
encrypted_client_id_proto.EncryptedPrivacyKey = encrypted_cid_key
license_request.Msg.EncryptedClientId.CopyFrom(encrypted_client_id_proto)
else:
license_request.Msg.ClientId.CopyFrom(client_id)
if session.device_config.private_key_available:
key = RSA.importKey(open(session.device_config.device_private_key_filename).read())
session.device_key = key
else:
self.logger.error("need device private key, other methods unimplemented")
return 1
self.logger.debug("signing license request")
hash = SHA1.new(license_request.Msg.SerializeToString())
signature = pss.new(key).sign(hash)
license_request.Signature = signature
session.license_request = license_request
self.logger.debug("license request:")
for line in text_format.MessageToString(session.license_request).splitlines():
self.logger.debug(line)
self.logger.info("license request created")
self.logger.debug("license request b64: {}".format(base64.b64encode(license_request.SerializeToString())))
return license_request.SerializeToString()
def provide_license(self, session_id, license_b64):
self.logger.debug("provide_license(session_id={}, license_b64={})".format(session_id, license_b64))
self.logger.info("decrypting provided license")
if session_id not in self.sessions:
self.logger.error("session does not exist")
return 1
session = self.sessions[session_id]
if not session.license_request:
self.logger.error("generate a license request first!")
return 1
license = wv_proto2.SignedLicense()
try:
license.ParseFromString(base64.b64decode(license_b64))
except DecodeError:
self.logger.error("unable to parse license - check protobufs")
return 1
session.license = license
self.logger.debug("license:")
for line in text_format.MessageToString(license).splitlines():
self.logger.debug(line)
self.logger.debug("deriving keys from session key")
oaep_cipher = PKCS1_OAEP.new(session.device_key)
session.session_key = oaep_cipher.decrypt(license.SessionKey)
lic_req_msg = session.license_request.Msg.SerializeToString()
enc_key_base = b"ENCRYPTION\000" + lic_req_msg + b"\0\0\0\x80"
auth_key_base = b"AUTHENTICATION\0" + lic_req_msg + b"\0\0\2\0"
enc_key = b"\x01" + enc_key_base
auth_key_1 = b"\x01" + auth_key_base
auth_key_2 = b"\x02" + auth_key_base
auth_key_3 = b"\x03" + auth_key_base
auth_key_4 = b"\x04" + auth_key_base
cmac_obj = CMAC.new(session.session_key, ciphermod=AES)
cmac_obj.update(enc_key)
enc_cmac_key = cmac_obj.digest()
cmac_obj = CMAC.new(session.session_key, ciphermod=AES)
cmac_obj.update(auth_key_1)
auth_cmac_key_1 = cmac_obj.digest()
cmac_obj = CMAC.new(session.session_key, ciphermod=AES)
cmac_obj.update(auth_key_2)
auth_cmac_key_2 = cmac_obj.digest()
cmac_obj = CMAC.new(session.session_key, ciphermod=AES)
cmac_obj.update(auth_key_3)
auth_cmac_key_3 = cmac_obj.digest()
cmac_obj = CMAC.new(session.session_key, ciphermod=AES)
cmac_obj.update(auth_key_4)
auth_cmac_key_4 = cmac_obj.digest()
auth_cmac_combined_1 = auth_cmac_key_1 + auth_cmac_key_2
auth_cmac_combined_2 = auth_cmac_key_3 + auth_cmac_key_4
session.derived_keys['enc'] = enc_cmac_key
session.derived_keys['auth_1'] = auth_cmac_combined_1
session.derived_keys['auth_2'] = auth_cmac_combined_2
self.logger.debug('verifying license signature')
lic_hmac = HMAC.new(session.derived_keys['auth_1'], digestmod=SHA256)
lic_hmac.update(license.Msg.SerializeToString())
self.logger.debug("calculated sig: {} actual sig: {}".format(lic_hmac.hexdigest(), binascii.hexlify(license.Signature)))
if lic_hmac.digest() != license.Signature:
self.logger.info("license signature doesn't match - writing bin so they can be debugged")
with open("original_lic.bin", "wb") as f:
f.write(base64.b64decode(license_b64))
with open("parsed_lic.bin", "wb") as f:
f.write(license.SerializeToString())
self.logger.info("continuing anyway")
self.logger.debug("key count: {}".format(len(license.Msg.Key)))
for key in license.Msg.Key:
if key.Id:
key_id = key.Id
else:
key_id = wv_proto2.License.KeyContainer.KeyType.Name(key.Type).encode('utf-8')
encrypted_key = key.Key
iv = key.Iv
type = wv_proto2.License.KeyContainer.KeyType.Name(key.Type)
cipher = AES.new(session.derived_keys['enc'], AES.MODE_CBC, iv=iv)
decrypted_key = cipher.decrypt(encrypted_key)
if type == "OPERATOR_SESSION":
permissions = []
perms = key._OperatorSessionKeyPermissions
for (descriptor, value) in perms.ListFields():
if value == 1:
permissions.append(descriptor.name)
#print(permissions)
else:
permissions = []
session.keys.append(Key(key_id, type, Padding.unpad(decrypted_key, 16), permissions))
self.logger.info("decrypted all keys")
return 0
def get_keys(self, session_id):
if session_id in self.sessions:
return self.sessions[session_id].keys
else:
self.logger.error("session not found")
return 1

View File

@ -0,0 +1,57 @@
import os
device_sony_lvl1 = {
'name': 'sony_lvl1',
'description': 'sony d6503 firmware 6.0.1 lvl1 security level',
'security_level': 1,
'session_id_type': 'android',
'private_key_available': True,
'vmp': False,
'send_key_control_nonce': True
}
devices_available = [device_sony_lvl1]
#from __main__ import dirPath
main_folder = os.path.dirname(__file__)
#main_folder = os.path.join('.', 'pywidevine', 'cdm')
FILES_FOLDER = 'devices'
class DeviceConfig:
def __init__(self, device):
self.device_name = device['name']
self.description = device['description']
self.security_level = device['security_level']
self.session_id_type = device['session_id_type']
self.private_key_available = device['private_key_available']
self.vmp = device['vmp']
self.send_key_control_nonce = device['send_key_control_nonce']
if 'keybox_filename' in device:
self.keybox_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], device['keybox_filename'])
else:
self.keybox_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], 'keybox')
if 'device_cert_filename' in device:
self.device_cert_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], device['device_cert_filename'])
else:
self.device_cert_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], 'device_cert')
if 'device_private_key_filename' in device:
self.device_private_key_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], device['device_private_key_filename'])
else:
self.device_private_key_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], 'device_private_key')
if 'device_client_id_blob_filename' in device:
self.device_client_id_blob_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], device['device_client_id_blob_filename'])
else:
self.device_client_id_blob_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], 'device_client_id_blob')
if 'device_vmp_blob_filename' in device:
self.device_vmp_blob_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], device['device_vmp_blob_filename'])
else:
self.device_vmp_blob_filename = os.path.join(main_folder, FILES_FOLDER, device['name'], 'device_vmp_blob')
def __repr__(self):
return "DeviceConfig(name={}, description={}, security_level={}, session_id_type={}, private_key_available={}, vmp={})".format(self.device_name, self.description, self.security_level, self.session_id_type, self.private_key_available, self.vmp)

View File

@ -0,0 +1,21 @@
{
"token": "z2.token",
"client_info":
{
"company_name": "Sony",
"model_name": "D6503",
"architecture_name": "armeabi-v7a",
"device_name": "D6503",
"product_name": "D6503",
"build_info": "Sony/D6503/D6503:6.0.1/23.5.A.1.291/2769308465:user/release-keys",
"device_id": "U09OWV9YUEVSSUFfMDdkZV8wMDc1ZTkwMAAAAAAAAAA=",
"os_version": "6.0.1"
},
"capabilities":
{
"session_token": 1,
"max_hdcp_version": "HDCP_V2_2",
"oem_crypto_api_version": 11
}
}

Binary file not shown.

View File

@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCsw9uELBU9gKUT
Lt1eK+NKWHOJVrfxRFvF0yunCO5IH63QXyBVbZWziYJluHjLE9Fz6avSq3NB60Wy
n2blN/gxAd2zTX9Nz2aqTU5N0lzfbi+aIr1KNmYxnJ76VOK7BA5n7+nLpA3DeUDW
AXVK00yqO83ArElJXej+Lj74AFPzkN4ciGHH4MtN/OuYCe0PzCXGM23eaueHp9Gb
w6dPOTUsKpywDNKPElFhJ4FWTr6Lw8y/hrmSlYGXh0HtQ4NtR2q/qWFW/ItukCDl
IIRnxZeC2U/G9lOH02oYehJRe3Td44KmUE+XF0dD5gklhNDGbGCr3bbGAVt0Fxq8
Qu0mIct1AgMBAAECggEANw78KHU8F6ul8CUhW1+1Qf5KY9yFJpjYfoU8BjGsbsPZ
yuxmC5Ou/9a0/eH6bQ3V1JEFt0/4nWtzfOecDTT3HfcwRnJOPef5GhElAVwnSPV+
qiqkFMCddPYrHDBtSZiTVsB4y/Nuh3tfFFTGoqAQcLg6bEr72CvbkxX97197YcWl
VxEkJY/6ubb3j85zyq/3naktLcZQCE/9CCEo/ynqAEgITwWyFKtgVC7kYHj+OgvB
1vMcKvgsbiF3ME2QUyjsbkbUGeM6hobZfR4gsbgS4WVZyr2nTY3jL8wuKEe3/jT/
Qn7gGhJ/fGRSTYr/zi97UDSlsZjNOk31KLutBCiyCQKBgQDTrZlznpjUcL6ACIv2
5umjS/MlxE1kZB5oTGBKTMA/nWITtnMMluNbkdyT7O0YLtI2Sth3P36P25bbqBvW
ENBh7XwTZlumcFKdgJooF8SJildU0DFwPRoZTOPBVlzoJIWhOEeDGvkwmitlOdxw
F9i5X4kbx9oE9buiwC2hPZkU8wKBgQDQ8G9ec46cNxEm0E6Us9VRQgfdVO5AZ2p1
S8g/zzodj+9h74zEcfOGpN5SyPHhv3D2yYlgVCn/wJ9dTQPH7O9zz13vhxRNLkVb
iIQh0uyT+I3OWOfR30Op6FmSNQXin0WLcNoRVUerc8arDkezy2O10HYql80wjovq
PHJhHXBX9wKBgApV76g1lkDJQIP/5tWncMEIdFbjvuOn/9QX5pu6I6j3hlJwFi4H
MBLIjHyslOcZYipEfU1VTFi54CPZkYJiT8p4ThakaNU3ptEJ9nz+rBoLJzh88e0J
Dr0tg/FsxhyPq/azSMqeBozY+kV3DcxrXamvgIJav8p+NSs9Nv0ohNEBAoGAEiF7
GJAghO/GXj7fQsokLav0MMGo9w/CTjFoTBk4as5NsIrwBS/6OOnfnQFw8+z/6Xpt
oF1NU7MsYRVIybWGxd7twNZQ7a2hOSMsjB7YhrKf45MVcsHUBk9yTlypiRPXHhWJ
5s0mrfsa90cC89gna+SODH4lwRvtikL6jfDXCdsCgYEApnOtzB40/B6+9heGC1Gl
NP8f43sulFd5SmfTlO1aYR9ZgM2iyitFFJmmB2tFK5FShwrWPZGLD7z2yTwoZKKq
IMlIwvqpyhVEY+qAVjxUA49EKfKph02M9gDkKY00dAKDIStGwAEDGHCTTUgVzoCv
Px5FCz0Oml6fgbJD7kh1OPs=
-----END PRIVATE KEY-----

Binary file not shown.

View File

@ -0,0 +1,466 @@
syntax = "proto2";
// from x86 (partial), most of it from the ARM version:
message ClientIdentification {
enum TokenType {
KEYBOX = 0;
DEVICE_CERTIFICATE = 1;
REMOTE_ATTESTATION_CERTIFICATE = 2;
}
message NameValue {
required string Name = 1;
required string Value = 2;
}
message ClientCapabilities {
enum HdcpVersion {
HDCP_NONE = 0;
HDCP_V1 = 1;
HDCP_V2 = 2;
HDCP_V2_1 = 3;
HDCP_V2_2 = 4;
}
optional uint32 ClientToken = 1;
optional uint32 SessionToken = 2;
optional uint32 VideoResolutionConstraints = 3;
optional HdcpVersion MaxHdcpVersion = 4;
optional uint32 OemCryptoApiVersion = 5;
}
required TokenType Type = 1;
//optional bytes Token = 2; // by default the client treats this as blob, but it's usually a DeviceCertificate, so for usefulness sake, I'm replacing it with this one:
optional SignedDeviceCertificate Token = 2; // use this when parsing, "bytes" when building a client id blob
repeated NameValue ClientInfo = 3;
optional bytes ProviderClientToken = 4;
optional uint32 LicenseCounter = 5;
optional ClientCapabilities _ClientCapabilities = 6; // how should we deal with duped names? will have to look at proto docs later
optional FileHashes _FileHashes = 7; // vmp blob goes here
}
message DeviceCertificate {
enum CertificateType {
ROOT = 0;
INTERMEDIATE = 1;
USER_DEVICE = 2;
SERVICE = 3;
}
required CertificateType Type = 1; // the compiled code reused this as ProvisionedDeviceInfo.WvSecurityLevel, however that is incorrect (compiler aliased it as they're both identical as a structure)
optional bytes SerialNumber = 2;
optional uint32 CreationTimeSeconds = 3;
optional bytes PublicKey = 4;
optional uint32 SystemId = 5;
optional uint32 TestDeviceDeprecated = 6; // is it bool or int?
optional bytes ServiceId = 7; // service URL for service certificates
}
// missing some references,
message DeviceCertificateStatus {
enum CertificateStatus {
VALID = 0;
REVOKED = 1;
}
optional bytes SerialNumber = 1;
optional CertificateStatus Status = 2;
optional ProvisionedDeviceInfo DeviceInfo = 4; // where is 3? is it deprecated?
}
message DeviceCertificateStatusList {
optional uint32 CreationTimeSeconds = 1;
repeated DeviceCertificateStatus CertificateStatus = 2;
}
message EncryptedClientIdentification {
required string ServiceId = 1;
optional bytes ServiceCertificateSerialNumber = 2;
required bytes EncryptedClientId = 3;
required bytes EncryptedClientIdIv = 4;
required bytes EncryptedPrivacyKey = 5;
}
// todo: fill (for this top-level type, it might be impossible/difficult)
enum LicenseType {
ZERO = 0;
DEFAULT = 1; // 1 is STREAMING/temporary license; on recent versions may go up to 3 (latest x86); it might be persist/don't persist type, unconfirmed
OFFLINE = 2;
}
// todo: fill (for this top-level type, it might be impossible/difficult)
// this is just a guess because these globals got lost, but really, do we need more?
enum ProtocolVersion {
CURRENT = 21; // don't have symbols for this
}
message LicenseIdentification {
optional bytes RequestId = 1;
optional bytes SessionId = 2;
optional bytes PurchaseId = 3;
optional LicenseType Type = 4;
optional uint32 Version = 5;
optional bytes ProviderSessionToken = 6;
}
message License {
message Policy {
optional bool CanPlay = 1; // changed from uint32 to bool
optional bool CanPersist = 2;
optional bool CanRenew = 3;
optional uint32 RentalDurationSeconds = 4;
optional uint32 PlaybackDurationSeconds = 5;
optional uint32 LicenseDurationSeconds = 6;
optional uint32 RenewalRecoveryDurationSeconds = 7;
optional string RenewalServerUrl = 8;
optional uint32 RenewalDelaySeconds = 9;
optional uint32 RenewalRetryIntervalSeconds = 10;
optional bool RenewWithUsage = 11; // was uint32
}
message KeyContainer {
enum KeyType {
SIGNING = 1;
CONTENT = 2;
KEY_CONTROL = 3;
OPERATOR_SESSION = 4;
}
enum SecurityLevel {
SW_SECURE_CRYPTO = 1;
SW_SECURE_DECODE = 2;
HW_SECURE_CRYPTO = 3;
HW_SECURE_DECODE = 4;
HW_SECURE_ALL = 5;
}
message OutputProtection {
enum CGMS {
COPY_FREE = 0;
COPY_ONCE = 2;
COPY_NEVER = 3;
CGMS_NONE = 0x2A; // PC default!
}
optional ClientIdentification.ClientCapabilities.HdcpVersion Hdcp = 1; // it's most likely a copy of Hdcp version available here, but compiler optimized it away
optional CGMS CgmsFlags = 2;
}
message KeyControl {
required bytes KeyControlBlock = 1; // what is this?
required bytes Iv = 2;
}
message OperatorSessionKeyPermissions {
optional uint32 AllowEncrypt = 1;
optional uint32 AllowDecrypt = 2;
optional uint32 AllowSign = 3;
optional uint32 AllowSignatureVerify = 4;
}
message VideoResolutionConstraint {
optional uint32 MinResolutionPixels = 1;
optional uint32 MaxResolutionPixels = 2;
optional OutputProtection RequiredProtection = 3;
}
optional bytes Id = 1;
optional bytes Iv = 2;
optional bytes Key = 3;
optional KeyType Type = 4;
optional SecurityLevel Level = 5;
optional OutputProtection RequiredProtection = 6;
optional OutputProtection RequestedProtection = 7;
optional KeyControl _KeyControl = 8; // duped names, etc
optional OperatorSessionKeyPermissions _OperatorSessionKeyPermissions = 9; // duped names, etc
repeated VideoResolutionConstraint VideoResolutionConstraints = 10;
}
optional LicenseIdentification Id = 1;
optional Policy _Policy = 2; // duped names, etc
repeated KeyContainer Key = 3;
optional uint32 LicenseStartTime = 4;
optional uint32 RemoteAttestationVerified = 5; // bool?
optional bytes ProviderClientToken = 6;
// there might be more, check with newer versions (I see field 7-8 in a lic)
// this appeared in latest x86:
optional uint32 ProtectionScheme = 7; // type unconfirmed fully, but it's likely as WidevineCencHeader describesit (fourcc)
}
message LicenseError {
enum Error {
INVALID_DEVICE_CERTIFICATE = 1;
REVOKED_DEVICE_CERTIFICATE = 2;
SERVICE_UNAVAILABLE = 3;
}
//LicenseRequest.RequestType ErrorCode; // clang mismatch
optional Error ErrorCode = 1;
}
message LicenseRequest {
message ContentIdentification {
message CENC {
//optional bytes Pssh = 1; // the client's definition is opaque, it doesn't care about the contents, but the PSSH has a clear definition that is understood and requested by the server, thus I'll replace it with:
optional WidevineCencHeader Pssh = 1;
optional LicenseType LicenseType = 2; // unfortunately the LicenseType symbols are not present, acceptable value seems to only be 1 (is this persist/don't persist? look into it!)
optional bytes RequestId = 3;
}
message WebM {
optional bytes Header = 1; // identical to CENC, aside from PSSH and the parent field number used
optional LicenseType LicenseType = 2;
optional bytes RequestId = 3;
}
message ExistingLicense {
optional LicenseIdentification LicenseId = 1;
optional uint32 SecondsSinceStarted = 2;
optional uint32 SecondsSinceLastPlayed = 3;
optional bytes SessionUsageTableEntry = 4; // interesting! try to figure out the connection between the usage table blob and KCB!
}
optional CENC CencId = 1;
optional WebM WebmId = 2;
optional ExistingLicense License = 3;
}
enum RequestType {
NEW = 1;
RENEWAL = 2;
RELEASE = 3;
}
optional ClientIdentification ClientId = 1;
optional ContentIdentification ContentId = 2;
optional RequestType Type = 3;
optional uint32 RequestTime = 4;
optional bytes KeyControlNonceDeprecated = 5;
optional ProtocolVersion ProtocolVersion = 6; // lacking symbols for this
optional uint32 KeyControlNonce = 7;
optional EncryptedClientIdentification EncryptedClientId = 8;
}
// raw pssh hack
message LicenseRequestRaw {
message ContentIdentification {
message CENC {
optional bytes Pssh = 1; // the client's definition is opaque, it doesn't care about the contents, but the PSSH has a clear definition that is understood and requested by the server, thus I'll replace it with:
//optional WidevineCencHeader Pssh = 1;
optional LicenseType LicenseType = 2; // unfortunately the LicenseType symbols are not present, acceptable value seems to only be 1 (is this persist/don't persist? look into it!)
optional bytes RequestId = 3;
}
message WebM {
optional bytes Header = 1; // identical to CENC, aside from PSSH and the parent field number used
optional LicenseType LicenseType = 2;
optional bytes RequestId = 3;
}
message ExistingLicense {
optional LicenseIdentification LicenseId = 1;
optional uint32 SecondsSinceStarted = 2;
optional uint32 SecondsSinceLastPlayed = 3;
optional bytes SessionUsageTableEntry = 4; // interesting! try to figure out the connection between the usage table blob and KCB!
}
optional CENC CencId = 1;
optional WebM WebmId = 2;
optional ExistingLicense License = 3;
}
enum RequestType {
NEW = 1;
RENEWAL = 2;
RELEASE = 3;
}
optional ClientIdentification ClientId = 1;
optional ContentIdentification ContentId = 2;
optional RequestType Type = 3;
optional uint32 RequestTime = 4;
optional bytes KeyControlNonceDeprecated = 5;
optional ProtocolVersion ProtocolVersion = 6; // lacking symbols for this
optional uint32 KeyControlNonce = 7;
optional EncryptedClientIdentification EncryptedClientId = 8;
}
message ProvisionedDeviceInfo {
enum WvSecurityLevel {
LEVEL_UNSPECIFIED = 0;
LEVEL_1 = 1;
LEVEL_2 = 2;
LEVEL_3 = 3;
}
optional uint32 SystemId = 1;
optional string Soc = 2;
optional string Manufacturer = 3;
optional string Model = 4;
optional string DeviceType = 5;
optional uint32 ModelYear = 6;
optional WvSecurityLevel SecurityLevel = 7;
optional uint32 TestDevice = 8; // bool?
}
// todo: fill
message ProvisioningOptions {
}
// todo: fill
message ProvisioningRequest {
}
// todo: fill
message ProvisioningResponse {
}
message RemoteAttestation {
optional EncryptedClientIdentification Certificate = 1;
optional string Salt = 2;
optional string Signature = 3;
}
// todo: fill
message SessionInit {
}
// todo: fill
message SessionState {
}
// todo: fill
message SignedCertificateStatusList {
}
message SignedDeviceCertificate {
//optional bytes DeviceCertificate = 1; // again, they use a buffer where it's supposed to be a message, so we'll replace it with what it really is:
optional DeviceCertificate _DeviceCertificate = 1; // how should we deal with duped names? will have to look at proto docs later
optional bytes Signature = 2;
optional SignedDeviceCertificate Signer = 3;
}
// todo: fill
message SignedProvisioningMessage {
}
// the root of all messages, from either server or client
message SignedMessage {
enum MessageType {
LICENSE_REQUEST = 1;
LICENSE = 2;
ERROR_RESPONSE = 3;
SERVICE_CERTIFICATE_REQUEST = 4;
SERVICE_CERTIFICATE = 5;
}
optional MessageType Type = 1; // has in incorrect overlap with License_KeyContainer_SecurityLevel
optional bytes Msg = 2; // this has to be casted dynamically, to LicenseRequest, License or LicenseError (? unconfirmed), for Request, no other fields but Type need to be present
// for SERVICE_CERTIFICATE, only Type and Msg are present, and it's just a DeviceCertificate with CertificateType set to SERVICE
optional bytes Signature = 3; // might be different type of signatures (ex. RSA vs AES CMAC(??), unconfirmed for now)
optional bytes SessionKey = 4; // often RSA wrapped for licenses
optional RemoteAttestation RemoteAttestation = 5;
}
// This message is copied from google's docs, not reversed:
message WidevineCencHeader {
enum Algorithm {
UNENCRYPTED = 0;
AESCTR = 1;
};
optional Algorithm algorithm = 1;
repeated bytes key_id = 2;
// Content provider name.
optional string provider = 3;
// A content identifier, specified by content provider.
optional bytes content_id = 4;
// Track type. Acceptable values are SD, HD and AUDIO. Used to
// differentiate content keys used by an asset.
optional string track_type_deprecated = 5;
// The name of a registered policy to be used for this asset.
optional string policy = 6;
// Crypto period index, for media using key rotation.
optional uint32 crypto_period_index = 7;