Merge pull request #29 from Mbucari/master
Add major version migration and hacked avformat-58
This commit is contained in:
commit
8f8e0645a4
@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
@ -173,7 +172,7 @@ namespace AaxDecrypter
|
|||||||
{
|
{
|
||||||
DecryptProgressUpdate?.Invoke(this, 0);
|
DecryptProgressUpdate?.Invoke(this, 0);
|
||||||
|
|
||||||
var tempRipFile = Path.Combine(outDir, "funny.mp4");
|
var tempRipFile = Path.Combine(outDir, "funny.aac");
|
||||||
|
|
||||||
var fail = "WARNING-Decrypt failure. ";
|
var fail = "WARNING-Decrypt failure. ";
|
||||||
|
|
||||||
@ -207,8 +206,8 @@ namespace AaxDecrypter
|
|||||||
Console.WriteLine($"Decrypting with key={audible_key}, iv={audible_iv}");
|
Console.WriteLine($"Decrypting with key={audible_key}, iv={audible_iv}");
|
||||||
|
|
||||||
var returnCode = 100;
|
var returnCode = 100;
|
||||||
var thread = new Thread((b) => returnCode = ngDecrypt(b));
|
var thread = new Thread(_ => returnCode = ngDecrypt(tempRipFile));
|
||||||
thread.Start(tempRipFile);
|
thread.Start();
|
||||||
|
|
||||||
double fileLen = new FileInfo(inputFileName).Length;
|
double fileLen = new FileInfo(inputFileName).Length;
|
||||||
while (thread.IsAlive && returnCode == 100)
|
while (thread.IsAlive && returnCode == 100)
|
||||||
@ -225,9 +224,81 @@ namespace AaxDecrypter
|
|||||||
return returnCode;
|
return returnCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int ngDecrypt(object tempFileNameObj)
|
private int ngDecrypt(string tempFileName)
|
||||||
{
|
{
|
||||||
var tempFileName = tempFileNameObj as string;
|
#region avformat-58.dll HACK EXPLANATION
|
||||||
|
/* avformat-58.dll HACK EXPLANATION
|
||||||
|
*
|
||||||
|
* FFMPEG refused to copy the aac stream from AAXC files with 44kHz sample rates
|
||||||
|
* with error "Scalable configurations are not allowed in ADTS". The adts encoder
|
||||||
|
* can be found on github at:
|
||||||
|
* https://github.com/FFmpeg/FFmpeg/blob/master/libavformat/adtsenc.c
|
||||||
|
*
|
||||||
|
* adtsenc detects scalable aac by a flag in the aac metadata and throws an error if
|
||||||
|
* it is set. It appears that all aaxc files contain aac streams that can be written
|
||||||
|
* to adts, but either the codec is parsing the header incorrectly or the aaxc
|
||||||
|
* header is incorrect.
|
||||||
|
*
|
||||||
|
* As a workaround, i've modified avformat-58.dll to allow adtsenc to ignore the
|
||||||
|
* scalable flag and continue. To modify:
|
||||||
|
*
|
||||||
|
* Open ffmpeg.exe in x64dbg (https://x64dbg.com)
|
||||||
|
*
|
||||||
|
* Navigate to the avformat module and search for the error string "Scalable
|
||||||
|
* configurations are not allowed in ADTS". (00007FFE16AA5899 in example below).
|
||||||
|
*
|
||||||
|
* 00007FFE16AA587B | 4C:8D05 DE5E6900 | lea r8,qword ptr ds:[7FFE1713B760] | 00007FFE1713B760:"960/120 MDCT window is not allowed in ADTS\n"
|
||||||
|
* 00007FFE16AA5882 | BA 10000000 | mov edx,10 |
|
||||||
|
* 00007FFE16AA5887 | 4C:89F1 | mov rcx,r14 |
|
||||||
|
* 00007FFE16AA588A | E8 697A1900 | call <JMP.&av_log> |
|
||||||
|
* 00007FFE16AA588F | B8 B7B1BBBE | mov eax,BEBBB1B7 |
|
||||||
|
* 00007FFE16AA5894 | E9 D5F8FFFF | jmp avformat-58.7FFE16AA516E |
|
||||||
|
* 00007FFE16AA5899 | 4C:8D05 F05E6900 | lea r8,qword ptr ds:[7FFE1713B790] | 00007FFE1713B790:"Scalable configurations are not allowed in ADTS\n"
|
||||||
|
* 00007FFE16AA58A0 | BA 10000000 | mov edx,10 |
|
||||||
|
* 00007FFE16AA58A5 | 4C:89F1 | mov rcx,r14 |
|
||||||
|
* 00007FFE16AA58A8 | E8 4B7A1900 | call <JMP.&av_log> |
|
||||||
|
* 00007FFE16AA58AD | B8 B7B1BBBE | mov eax,BEBBB1B7 |
|
||||||
|
* 00007FFE16AA58B2 | E9 B7F8FFFF | jmp avformat-58.7FFE16AA516E |
|
||||||
|
* 00007FFE16AA58B7 | 4C:8D05 4A5E6900 | lea r8,qword ptr ds:[7FFE1713B708] | 00007FFE1713B708:"MPEG-4 AOT %d is not allowed in ADTS\n"
|
||||||
|
* 00007FFE16AA58BE | BA 10000000 | mov edx,10 |
|
||||||
|
* 00007FFE16AA58C3 | 4C:89F1 | mov rcx,r14 |
|
||||||
|
* 00007FFE16AA58C6 | E8 2D7A1900 | call <JMP.&av_log> |
|
||||||
|
* 00007FFE16AA58CB | B8 B7B1BBBE | mov eax,BEBBB1B7 |
|
||||||
|
* 00007FFE16AA58D0 | E9 99F8FFFF | jmp avformat-58.7FFE16AA516E |
|
||||||
|
* 00007FFE16AA58D5 | 4C:8D05 EC5E6900 | lea r8,qword ptr ds:[7FFE1713B7C8] | 00007FFE1713B7C8:"Extension flag is not allowed in ADTS\n"
|
||||||
|
* 00007FFE16AA58DC | BA 10000000 | mov edx,10 |
|
||||||
|
* 00007FFE16AA58E1 | 4C:89F1 | mov rcx,r14 |
|
||||||
|
* 00007FFE16AA58E4 | E8 0F7A1900 | call <JMP.&av_log> |
|
||||||
|
* 00007FFE16AA58E9 | B8 B7B1BBBE | mov eax,BEBBB1B7 |
|
||||||
|
* 00007FFE16AA58EE | E9 7BF8FFFF | jmp avformat-58.7FFE16AA516E |
|
||||||
|
* 00007FFE16AA58F3 | 4C:8D05 365E6900 | lea r8,qword ptr ds:[7FFE1713B730] | 00007FFE1713B730:"Escape sample rate index illegal in ADTS\n"
|
||||||
|
* 00007FFE16AA58FA | BA 10000000 | mov edx,10 |
|
||||||
|
* 00007FFE16AA58FF | 4C:89F1 | mov rcx,r14 |
|
||||||
|
* 00007FFE16AA5902 | E8 F1791900 | call <JMP.&av_log> |
|
||||||
|
* 00007FFE16AA5907 | B8 B7B1BBBE | mov eax,BEBBB1B7 |
|
||||||
|
* 00007FFE16AA590C | E9 5DF8FFFF | jmp avformat-58.7FFE16AA516E |
|
||||||
|
*
|
||||||
|
* Select the instruction that loads the error string's address, and search for all
|
||||||
|
* references. You should only find one referance, a conditional jump
|
||||||
|
* (00007FFE16AA513C example below).
|
||||||
|
*
|
||||||
|
* 00007FFE16AA511D | 89C2 | mov edx,eax |
|
||||||
|
* 00007FFE16AA511F | 89C1 | mov ecx,eax |
|
||||||
|
* 00007FFE16AA5121 | 83C0 01 | add eax,1 |
|
||||||
|
* 00007FFE16AA5124 | C1EA 03 | shr edx,3 |
|
||||||
|
* 00007FFE16AA5127 | 83E1 07 | and ecx,7 |
|
||||||
|
* 00007FFE16AA512A | 41:8B1414 | mov edx,dword ptr ds:[r12+rdx] |
|
||||||
|
* 00007FFE16AA512E | 0FCA | bswap edx |
|
||||||
|
* 00007FFE16AA5130 | D3E2 | shl edx,cl |
|
||||||
|
* 00007FFE16AA5132 | C1EA FF | shr edx,FF |
|
||||||
|
* 00007FFE16AA5135 | 39F8 | cmp eax,edi |
|
||||||
|
* 00007FFE16AA5137 | 0F47C7 | cmova eax,edi |
|
||||||
|
* 00007FFE16AA513A | 85D2 | test edx,edx |
|
||||||
|
* 00007FFE16AA513C | 0F85 57070000 | jne avformat-58.7FFE16AA5899 |
|
||||||
|
*
|
||||||
|
* Edit that jump with six nop instructions and save the patched assembly.
|
||||||
|
*/
|
||||||
|
#endregion
|
||||||
|
|
||||||
string args = "-audible_key "
|
string args = "-audible_key "
|
||||||
+ audible_key
|
+ audible_key
|
||||||
@ -276,11 +347,29 @@ namespace AaxDecrypter
|
|||||||
FileName = DecryptSupportLibraries.ffmpegPath,
|
FileName = DecryptSupportLibraries.ffmpegPath,
|
||||||
Arguments = "-y -i \"" + mp4_file + "\" -f ffmetadata -i \"" + ff_txt_file + "\" -map_metadata 1 -bsf:a aac_adtstoasc -c:a copy" + str1 + " -map 0 \"" + tempChapsPath + "\""
|
Arguments = "-y -i \"" + mp4_file + "\" -f ffmetadata -i \"" + ff_txt_file + "\" -map_metadata 1 -bsf:a aac_adtstoasc -c:a copy" + str1 + " -map 0 \"" + tempChapsPath + "\""
|
||||||
};
|
};
|
||||||
tagAndChapterInfo.RunHidden();
|
|
||||||
|
var thread = new Thread(_ => tagAndChapterInfo.RunHidden());
|
||||||
|
thread.Start();
|
||||||
|
|
||||||
|
double fileLen = new FileInfo(mp4_file).Length;
|
||||||
|
|
||||||
|
while (thread.IsAlive)
|
||||||
|
{
|
||||||
|
Thread.Sleep(500);
|
||||||
|
if (File.Exists(tempChapsPath))
|
||||||
|
{
|
||||||
|
double tempLen = new FileInfo(tempChapsPath).Length;
|
||||||
|
var percentProgress = tempLen / fileLen * 100.0;
|
||||||
|
DecryptProgressUpdate?.Invoke(this, (int)percentProgress);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DecryptProgressUpdate?.Invoke(this, 0);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public bool Step4_InsertCoverArt()
|
public bool Step4_InsertCoverArt()
|
||||||
{
|
{
|
||||||
// save cover image as temp file
|
// save cover image as temp file
|
||||||
|
|||||||
Binary file not shown.
@ -3,6 +3,7 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using AudibleApi;
|
using AudibleApi;
|
||||||
|
using AudibleApi.Authorization;
|
||||||
using FileManager;
|
using FileManager;
|
||||||
using InternalUtilities;
|
using InternalUtilities;
|
||||||
using LibationWinForms;
|
using LibationWinForms;
|
||||||
@ -29,6 +30,7 @@ namespace LibationLauncher
|
|||||||
|
|
||||||
migrate_to_v4_0_0();
|
migrate_to_v4_0_0();
|
||||||
migrate_to_v4_0_3(); // add setting for whether to delete/retain aax
|
migrate_to_v4_0_3(); // add setting for whether to delete/retain aax
|
||||||
|
migrate_to_v5_x_x();
|
||||||
|
|
||||||
ensureLoggingConfig();
|
ensureLoggingConfig();
|
||||||
ensureSerilogConfig();
|
ensureSerilogConfig();
|
||||||
@ -194,7 +196,7 @@ namespace LibationLauncher
|
|||||||
|
|
||||||
var jLocale = jObj.Property("LocaleCountryCode");
|
var jLocale = jObj.Property("LocaleCountryCode");
|
||||||
var jDecryptKey = jObj.Property("DecryptKey");
|
var jDecryptKey = jObj.Property("DecryptKey");
|
||||||
|
|
||||||
jDecryptKey?.Remove();
|
jDecryptKey?.Remove();
|
||||||
jLocale?.Remove();
|
jLocale?.Remove();
|
||||||
|
|
||||||
@ -220,14 +222,51 @@ namespace LibationLauncher
|
|||||||
if (jRetainAaxFiles is null)
|
if (jRetainAaxFiles is null)
|
||||||
{
|
{
|
||||||
jObj.Add("RetainAaxFiles", false);
|
jObj.Add("RetainAaxFiles", false);
|
||||||
|
|
||||||
var newContents = jObj.ToString(Formatting.Indented);
|
var newContents = jObj.ToString(Formatting.Indented);
|
||||||
File.WriteAllText(Configuration.Instance.SettingsFilePath, newContents);
|
File.WriteAllText(Configuration.Instance.SettingsFilePath, newContents);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private static string defaultLoggingLevel { get; } = "Information";
|
#region migrate_to_v5_x_x re-gegister device if device info not in settings
|
||||||
|
private static void migrate_to_v5_x_x()
|
||||||
|
{
|
||||||
|
if (!File.Exists(AudibleApiStorage.AccountsSettingsFile))
|
||||||
|
return;
|
||||||
|
|
||||||
|
var accountsPersister = AudibleApiStorage.GetAccountsSettingsPersister();
|
||||||
|
|
||||||
|
foreach (var account in accountsPersister?.AccountsSettings?.Accounts)
|
||||||
|
{
|
||||||
|
var identity = account?.IdentityTokens;
|
||||||
|
|
||||||
|
if (identity is null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(identity.DeviceType) &&
|
||||||
|
!string.IsNullOrWhiteSpace(identity.DeviceSerialNumber) &&
|
||||||
|
!string.IsNullOrWhiteSpace(identity.AmazonAccountId))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var authorize = new AudibleApi.Authorization.Authorize(identity.Locale);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
authorize.DeregisterAsync(identity.ExistingAccessToken, identity.Cookies.ToKeyValuePair()).GetAwaiter().GetResult();
|
||||||
|
identity.Invalidate();
|
||||||
|
|
||||||
|
var api = AudibleApiActions.GetApiAsync(new LibationWinForms.Login.WinformResponder(account), account).GetAwaiter().GetResult();
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
// Don't care if it fails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private static string defaultLoggingLevel { get; } = "Information";
|
||||||
private static void ensureLoggingConfig()
|
private static void ensureLoggingConfig()
|
||||||
{
|
{
|
||||||
var config = Configuration.Instance;
|
var config = Configuration.Instance;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user