diff --git a/AaxDecrypter/AaxDecrypter.csproj b/AaxDecrypter/AaxDecrypter.csproj
index d8b57fcf..6ca88326 100644
--- a/AaxDecrypter/AaxDecrypter.csproj
+++ b/AaxDecrypter/AaxDecrypter.csproj
@@ -10,57 +10,11 @@
-
-
-
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
-
- Always
-
Always
diff --git a/AaxDecrypter/AaxToM4bConverter.cs b/AaxDecrypter/AaxToM4bConverter.cs
index 6baf6637..8dffb706 100644
--- a/AaxDecrypter/AaxToM4bConverter.cs
+++ b/AaxDecrypter/AaxToM4bConverter.cs
@@ -62,16 +62,18 @@ namespace AaxDecrypter
public Tags tags { get; private set; }
public EncodingInfo encodingInfo { get; private set; }
- public static async Task CreateAsync(string inputFile, string decryptKey, Chapters chapters = null)
+ private Func> getKeyFuncAsync { get; }
+
+ public static async Task CreateAsync(string inputFile, string decryptKey, Func> getKeyFunc, Chapters chapters = null)
{
- var converter = new AaxToM4bConverter(inputFile, decryptKey);
+ var converter = new AaxToM4bConverter(inputFile, decryptKey, getKeyFunc);
converter.chapters = chapters ?? new AAXChapters(inputFile);
await converter.prelimProcessing();
converter.printPrelim();
return converter;
}
- private AaxToM4bConverter(string inputFile, string decryptKey)
+ private AaxToM4bConverter(string inputFile, string decryptKey, Func> getKeyFunc)
{
ArgumentValidator.EnsureNotNullOrWhiteSpace(inputFile, nameof(inputFile));
if (!File.Exists(inputFile))
@@ -93,6 +95,7 @@ namespace AaxDecrypter
inputFileName = inputFile;
this.decryptKey = decryptKey;
+ this.getKeyFuncAsync = getKeyFunc;
}
private async Task prelimProcessing()
@@ -209,22 +212,12 @@ namespace AaxDecrypter
private int getKey_decrypt(string tempRipFile)
{
- getKey();
+ decryptKey = getKey();
return decrypt(tempRipFile);
}
- private void getKey()
- {
- Console.WriteLine("Discovering decrypt key");
- Console.WriteLine("Getting file hash");
- var checksum = BytesCracker.GetChecksum(inputFileName);
- Console.WriteLine("File hash calculated: " + checksum);
-
- Console.WriteLine("Cracking activation bytes");
- var activation_bytes = BytesCracker.GetActivationBytes(checksum);
- decryptKey = activation_bytes;
- Console.WriteLine("Activation bytes cracked. Decrypt key: " + activation_bytes);
- }
+ // I am NOT happy about doing async this way. Async needs to be added to Step framework
+ string getKey() => getKeyFuncAsync().GetAwaiter().GetResult();
private int decrypt(string tempRipFile)
{
diff --git a/AaxDecrypter/BytesCracker.cs b/AaxDecrypter/BytesCracker.cs
deleted file mode 100644
index a9752b14..00000000
--- a/AaxDecrypter/BytesCracker.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.IO;
-using System.Text;
-using System.Threading.Tasks;
-using Dinah.Core;
-using Dinah.Core.Diagnostics;
-
-namespace AaxDecrypter
-{
- public static class BytesCracker
- {
- public static string GetChecksum(string aaxPath)
- {
- var info = new ProcessStartInfo
- {
- FileName = BytesCrackerSupportLibraries.ffprobePath,
- Arguments = aaxPath.SurroundWithQuotes(),
- WorkingDirectory = Directory.GetCurrentDirectory()
- };
-
- // checksum is in the debug info. ffprobe's debug info is written to stderr, not stdout
- var ffprobeStderr = info.RunHidden().Error;
-
- // example checksum line:
- // ... [aax] file checksum == 0c527840c4f18517157eb0b4f9d6f9317ce60cd1
- var checksum = ffprobeStderr.ExtractString("file checksum == ", 40);
-
- return checksum;
- }
-
- /// use checksum to get activation bytes. activation bytes are unique per audible customer. only have to do this 1x/customer
- public static string GetActivationBytes(string checksum)
- {
- var info = new ProcessStartInfo
- {
- FileName = BytesCrackerSupportLibraries.rcrackPath,
- Arguments = @". -h " + checksum,
- WorkingDirectory = Directory.GetCurrentDirectory()
- };
-
- var rcrackStdout = info.RunHidden().Output;
-
- // example result
- // 0c527840c4f18517157eb0b4f9d6f9317ce60cd1 \xbd\x89X\x09 hex:bd895809
- var activation_bytes = rcrackStdout.ExtractString("hex:", 8);
-
- return activation_bytes;
- }
- }
-}
diff --git a/AaxDecrypter/BytesCrackerLib/alglib1.dll b/AaxDecrypter/BytesCrackerLib/alglib1.dll
deleted file mode 100644
index 6da4ca52..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/alglib1.dll and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_0_10000x789935_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_0_10000x789935_0.rtc
deleted file mode 100644
index 6359b7a3..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_0_10000x789935_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_1_10000x791425_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_1_10000x791425_0.rtc
deleted file mode 100644
index 57aa2b11..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_1_10000x791425_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_2_10000x790991_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_2_10000x790991_0.rtc
deleted file mode 100644
index 0ab3c43a..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_2_10000x790991_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_3_10000x792120_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_3_10000x792120_0.rtc
deleted file mode 100644
index 8e0438c8..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_3_10000x792120_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_4_10000x790743_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_4_10000x790743_0.rtc
deleted file mode 100644
index 1e169c3e..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_4_10000x790743_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_5_10000x790568_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_5_10000x790568_0.rtc
deleted file mode 100644
index 77c2a193..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_5_10000x790568_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_6_10000x791458_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_6_10000x791458_0.rtc
deleted file mode 100644
index 4f7b21c9..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_6_10000x791458_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_7_10000x791707_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_7_10000x791707_0.rtc
deleted file mode 100644
index f4b7b061..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_7_10000x791707_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_8_10000x790202_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_8_10000x790202_0.rtc
deleted file mode 100644
index e279ee04..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_8_10000x790202_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_9_10000x791022_0.rtc b/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_9_10000x791022_0.rtc
deleted file mode 100644
index 18e558f2..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/audible_byte#4-4_9_10000x791022_0.rtc and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/ffmpeg.exe b/AaxDecrypter/BytesCrackerLib/ffmpeg.exe
deleted file mode 100644
index 57ceafbc..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/ffmpeg.exe and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/ffprobe.exe b/AaxDecrypter/BytesCrackerLib/ffprobe.exe
deleted file mode 100644
index 42721143..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/ffprobe.exe and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerLib/rcrack.exe b/AaxDecrypter/BytesCrackerLib/rcrack.exe
deleted file mode 100644
index a67724e5..00000000
Binary files a/AaxDecrypter/BytesCrackerLib/rcrack.exe and /dev/null differ
diff --git a/AaxDecrypter/BytesCrackerSupportLibraries.cs b/AaxDecrypter/BytesCrackerSupportLibraries.cs
deleted file mode 100644
index 256b97cb..00000000
--- a/AaxDecrypter/BytesCrackerSupportLibraries.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System.IO;
-
-namespace AaxDecrypter
-{
- public static class BytesCrackerSupportLibraries
- {
- // GetActivationBytes dependencies
- // rcrack.exe
- // alglib1.dll
- // RainbowCrack files to recover your own Audible activation data (activation_bytes) in an offline manner
- // audible_byte#4-4_0_10000x789935_0.rtc
- // audible_byte#4-4_1_10000x791425_0.rtc
- // audible_byte#4-4_2_10000x790991_0.rtc
- // audible_byte#4-4_3_10000x792120_0.rtc
- // audible_byte#4-4_4_10000x790743_0.rtc
- // audible_byte#4-4_5_10000x790568_0.rtc
- // audible_byte#4-4_6_10000x791458_0.rtc
- // audible_byte#4-4_7_10000x791707_0.rtc
- // audible_byte#4-4_8_10000x790202_0.rtc
- // audible_byte#4-4_9_10000x791022_0.rtc
-
- private static string appPath_ { get; } = Path.GetDirectoryName(Dinah.Core.Exe.FileLocationOnDisk);
- private static string bytesCrackerLib_ { get; } = Path.Combine(appPath_, "BytesCrackerLib");
-
- public static string ffprobePath { get; } = Path.Combine(bytesCrackerLib_, "ffprobe.exe");
- public static string rcrackPath { get; } = Path.Combine(bytesCrackerLib_, "rcrack.exe");
- }
-}
diff --git a/FileLiberator/DecryptBook.cs b/FileLiberator/DecryptBook.cs
index b331d137..835c3444 100644
--- a/FileLiberator/DecryptBook.cs
+++ b/FileLiberator/DecryptBook.cs
@@ -4,6 +4,7 @@ using System.IO;
using System.Linq;
using System.Threading.Tasks;
using AaxDecrypter;
+using AudibleApi;
using DataLayer;
using Dinah.Core;
using Dinah.Core.ErrorHandling;
@@ -56,9 +57,11 @@ namespace FileLiberator
if (AudibleFileStorage.Audio.Exists(libraryBook.Book.AudibleProductId))
return new StatusHandler { "Cannot find decrypt. Final audio file already exists" };
- var chapters = await downloadChapterNames(libraryBook);
+ var api = await AudibleApiActions.GetApiAsync(libraryBook.Account, libraryBook.Book.Locale);
- var outputAudioFilename = await aaxToM4bConverterDecrypt(aaxFilename, libraryBook, chapters);
+ var chapters = await downloadChapterNames(libraryBook, api);
+
+ var outputAudioFilename = await aaxToM4bConverterDecrypt(aaxFilename, libraryBook, chapters, api);
// decrypt failed
if (outputAudioFilename == null)
@@ -92,7 +95,23 @@ namespace FileLiberator
}
}
- private async Task aaxToM4bConverterDecrypt(string aaxFilename, LibraryBook libraryBook, Chapters chapters = null)
+ private static async Task downloadChapterNames(LibraryBook libraryBook, Api api)
+ {
+ try
+ {
+ var contentMetadata = await api.GetLibraryBookMetadataAsync(libraryBook.Book.AudibleProductId);
+ if (contentMetadata?.ChapterInfo is null)
+ return null;
+
+ return new DownloadedChapters(contentMetadata.ChapterInfo);
+ }
+ catch
+ {
+ return null;
+ }
+ }
+
+ private async Task aaxToM4bConverterDecrypt(string aaxFilename, LibraryBook libraryBook, Chapters chapters, Api api)
{
DecryptBegin?.Invoke(this, $"Begin decrypting {aaxFilename}");
@@ -104,7 +123,7 @@ namespace FileLiberator
.AccountsSettings
.GetAccount(libraryBook.Account, libraryBook.Book.Locale);
- var converter = await AaxToM4bConverter.CreateAsync(aaxFilename, account.DecryptKey, chapters);
+ var converter = await AaxToM4bConverter.CreateAsync(aaxFilename, account.DecryptKey, api.GetActivationBytesAsync, chapters);
converter.AppName = "Libation";
TitleDiscovered?.Invoke(this, converter.tags.title);
@@ -134,23 +153,6 @@ namespace FileLiberator
}
}
- private async Task downloadChapterNames(LibraryBook libraryBook)
- {
- try
- {
- var api = await AudibleApiActions.GetApiAsync(libraryBook.Account, libraryBook.Book.Locale);
- var contentMetadata = await api.GetLibraryBookMetadataAsync(libraryBook.Book.AudibleProductId);
-
- if (contentMetadata?.ChapterInfo != null)
- return new DownloadedChapters(contentMetadata.ChapterInfo);
- return null;
- }
- catch
- {
- return null;
- }
- }
-
private static string moveFilesToBooksDir(Book product, string outputAudioFilename)
{
// create final directory. move each file into it. MOVE AUDIO FILE LAST
diff --git a/LibationLauncher/LibationLauncher.csproj b/LibationLauncher/LibationLauncher.csproj
index 25781d94..fbd552c1 100644
--- a/LibationLauncher/LibationLauncher.csproj
+++ b/LibationLauncher/LibationLauncher.csproj
@@ -13,7 +13,7 @@
win-x64
- 4.3.0.4
+ 4.4.0.5
diff --git a/_Demos/ffmpeg decrypt/Form1.cs b/_Demos/ffmpeg decrypt/Form1.cs
index aa6e1262..f2714444 100644
--- a/_Demos/ffmpeg decrypt/Form1.cs
+++ b/_Demos/ffmpeg decrypt/Form1.cs
@@ -10,8 +10,6 @@ namespace ffmpeg_decrypt
{
public partial class Form1 : Form
{
- public static string resdir { get; } = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "res");
-
public Form1()
{
InitializeComponent();
@@ -47,10 +45,10 @@ namespace ffmpeg_decrypt
inputPnl.Enabled = false;
statuslbl.Text = "Getting File Hash...";
- var checksum = await GetChecksum(inputdisplay.Text);
+ var checksum = await RCrack.GetChecksum(inputdisplay.Text);
statuslbl.Text = "Cracking Activation Bytes...";
- var activation_bytes = await GetActivationBytes(checksum);
+ var activation_bytes = await RCrack.GetActivationBytes(checksum);
statuslbl.Text = "Converting File...";
var encodeTo
@@ -70,81 +68,6 @@ namespace ffmpeg_decrypt
statuslbl.Text = "Conversion Complete!";
}
- private static async Task GetChecksum(string aaxPath)
- {
- Extract("ffprobe.exe");
-
- var startInfo = new ProcessStartInfo
- {
- FileName = Path.Combine(resdir, "ffprobe.exe"),
- Arguments = aaxPath.SurroundWithQuotes(),
- CreateNoWindow = true,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- UseShellExecute = false,
- WorkingDirectory = Directory.GetCurrentDirectory()
- };
-
- using var ffp = new Process { StartInfo = startInfo };
- ffp.Start();
-
- // checksum is in the debug info. ffprobe's debug info is written to stderr, not stdout
- var ffprobeStderr = ffp.StandardError.ReadToEnd();
-
- await Task.Run(() => ffp.WaitForExit());
-
- ffp.Close();
-
- // example checksum line:
- // ... [aax] file checksum == 0c527840c4f18517157eb0b4f9d6f9317ce60cd1
- var checksum = ffprobeStderr.ExtractString("file checksum == ", 40);
-
- return checksum;
- }
-
- /// use checksum to get activation bytes. activation bytes are unique per audible customer. only have to do this 1x/customer
- private static async Task GetActivationBytes(string checksum)
- {
- Extract("rcrack.exe");
-
- Extract("alglib1.dll");
- // RainbowCrack files to recover your own Audible activation data (activation_bytes) in an offline manner
- Extract("audible_byte#4-4_0_10000x789935_0.rtc");
- Extract("audible_byte#4-4_1_10000x791425_0.rtc");
- Extract("audible_byte#4-4_2_10000x790991_0.rtc");
- Extract("audible_byte#4-4_3_10000x792120_0.rtc");
- Extract("audible_byte#4-4_4_10000x790743_0.rtc");
- Extract("audible_byte#4-4_5_10000x790568_0.rtc");
- Extract("audible_byte#4-4_6_10000x791458_0.rtc");
- Extract("audible_byte#4-4_7_10000x791707_0.rtc");
- Extract("audible_byte#4-4_8_10000x790202_0.rtc");
- Extract("audible_byte#4-4_9_10000x791022_0.rtc");
-
- var startInfo = new ProcessStartInfo
- {
- FileName = Path.Combine(resdir, "rcrack.exe"),
- Arguments = @". -h " + checksum,
- CreateNoWindow = true,
- RedirectStandardOutput = true,
- UseShellExecute = false,
- WorkingDirectory = Directory.GetCurrentDirectory()
- };
-
- using var rcr = new Process { StartInfo = startInfo };
- rcr.Start();
-
- var rcrackStdout = rcr.StandardOutput.ReadToEnd();
-
- await Task.Run(() => rcr.WaitForExit());
- rcr.Close();
-
- // example result
- // 0c527840c4f18517157eb0b4f9d6f9317ce60cd1 \xbd\x89X\x09 hex:bd895809
- var activation_bytes = rcrackStdout.ExtractString("hex:", 8);
-
- return activation_bytes;
- }
-
// ProcessStartInfo.Arguments: use Escaper.EscapeArguments instead of .SurroundWithQuotes()
// see also: https://stackoverflow.com/questions/4291912/process-start-how-to-get-the-output
@@ -164,7 +87,7 @@ namespace ffmpeg_decrypt
private static async Task decryptAndSaveFile(string activation_bytes, string inputPath, string outputPath, TextBoxBase debugWindow, EncodeTo encodeTo, int encodeQuality = 80)
{
- Extract("ffmpeg.exe");
+ Resources.Extract("ffmpeg.exe");
var fileBase = Path.Combine(outputPath, Path.GetFileNameWithoutExtension(inputPath));
@@ -186,7 +109,7 @@ namespace ffmpeg_decrypt
// nothing in stdout. progress/debug info is in stderr
var startInfo = new ProcessStartInfo
{
- FileName = Path.Combine(resdir, "ffmpeg.exe"),
+ FileName = Path.Combine(Resources.resdir, "ffmpeg.exe"),
Arguments = arguments,
CreateNoWindow = true,
RedirectStandardError = true,
@@ -203,24 +126,6 @@ namespace ffmpeg_decrypt
ffm.Close();
}
- /// extract embedded resource to file if it doesn't already exist
- private static void Extract(string resourceName)
- {
- // first determine whether files exist already in res dir
- if (File.Exists(Path.Combine(resdir, resourceName)))
- return;
-
- // extract embedded resource
- // this technique works but there are easier ways:
- // https://stackoverflow.com/questions/13031778/how-can-i-extract-a-file-from-an-embedded-resource-and-save-it-to-disk
- Directory.CreateDirectory(resdir);
- using var resource = System.Reflection.Assembly.GetCallingAssembly().GetManifestResourceStream($"{nameof(ffmpeg_decrypt)}.res." + resourceName);
- using var reader = new BinaryReader(resource);
- using var file = new FileStream(Path.Combine(resdir, resourceName), FileMode.OpenOrCreate);
- using var writer = new BinaryWriter(file);
- writer.Write(reader.ReadBytes((int)resource.Length));
- }
-
private void decryptConvertRb_CheckedChanged(object sender, EventArgs e) => convertGb.Enabled = convertRb.Checked;
}
}
diff --git a/_Demos/ffmpeg decrypt/RCrack.cs b/_Demos/ffmpeg decrypt/RCrack.cs
new file mode 100644
index 00000000..1783b061
--- /dev/null
+++ b/_Demos/ffmpeg decrypt/RCrack.cs
@@ -0,0 +1,85 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Threading.Tasks;
+
+namespace ffmpeg_decrypt
+{
+ public static class RCrack
+ {
+ public static async Task GetChecksum(string aaxPath)
+ {
+ Resources.Extract("ffprobe.exe");
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = Path.Combine(Resources.resdir, "ffprobe.exe"),
+ Arguments = aaxPath.SurroundWithQuotes(),
+ CreateNoWindow = true,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ UseShellExecute = false,
+ WorkingDirectory = Directory.GetCurrentDirectory()
+ };
+
+ using var ffp = new Process { StartInfo = startInfo };
+ ffp.Start();
+
+ // checksum is in the debug info. ffprobe's debug info is written to stderr, not stdout
+ var ffprobeStderr = ffp.StandardError.ReadToEnd();
+
+ await ffp.WaitForExitAsync();
+
+ ffp.Close();
+
+ // example checksum line:
+ // ... [aax] file checksum == 0c527840c4f18517157eb0b4f9d6f9317ce60cd1
+ var checksum = ffprobeStderr.ExtractString("file checksum == ", 40);
+
+ return checksum;
+ }
+
+ /// use checksum to get activation bytes. activation bytes are unique per audible customer. only have to do this 1x/customer
+ public static async Task GetActivationBytes(string checksum)
+ {
+ Resources.Extract("rcrack.exe");
+
+ Resources.Extract("alglib1.dll");
+ // RainbowCrack files to recover your own Audible activation data (activation_bytes) in an offline manner
+ Resources.Extract("audible_byte#4-4_0_10000x789935_0.rtc");
+ Resources.Extract("audible_byte#4-4_1_10000x791425_0.rtc");
+ Resources.Extract("audible_byte#4-4_2_10000x790991_0.rtc");
+ Resources.Extract("audible_byte#4-4_3_10000x792120_0.rtc");
+ Resources.Extract("audible_byte#4-4_4_10000x790743_0.rtc");
+ Resources.Extract("audible_byte#4-4_5_10000x790568_0.rtc");
+ Resources.Extract("audible_byte#4-4_6_10000x791458_0.rtc");
+ Resources.Extract("audible_byte#4-4_7_10000x791707_0.rtc");
+ Resources.Extract("audible_byte#4-4_8_10000x790202_0.rtc");
+ Resources.Extract("audible_byte#4-4_9_10000x791022_0.rtc");
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = Path.Combine(Resources.resdir, "rcrack.exe"),
+ Arguments = @". -h " + checksum,
+ CreateNoWindow = true,
+ RedirectStandardOutput = true,
+ UseShellExecute = false,
+ WorkingDirectory = Directory.GetCurrentDirectory()
+ };
+
+ using var rcr = new Process { StartInfo = startInfo };
+ rcr.Start();
+
+ var rcrackStdout = rcr.StandardOutput.ReadToEnd();
+
+ await rcr.WaitForExitAsync();
+ rcr.Close();
+
+ // example result
+ // 0c527840c4f18517157eb0b4f9d6f9317ce60cd1 \xbd\x89X\x09 hex:bd895809
+ var activation_bytes = rcrackStdout.ExtractString("hex:", 8);
+
+ return activation_bytes;
+ }
+ }
+}
diff --git a/_Demos/ffmpeg decrypt/Resources.cs b/_Demos/ffmpeg decrypt/Resources.cs
new file mode 100644
index 00000000..35d2c6fe
--- /dev/null
+++ b/_Demos/ffmpeg decrypt/Resources.cs
@@ -0,0 +1,28 @@
+using System;
+using System.IO;
+
+namespace ffmpeg_decrypt
+{
+ public static class Resources
+ {
+ public static string resdir { get; } = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "res");
+
+ /// extract embedded resource to file if it doesn't already exist
+ public static void Extract(string resourceName)
+ {
+ // first determine whether files exist already in res dir
+ if (File.Exists(Path.Combine(resdir, resourceName)))
+ return;
+
+ // extract embedded resource
+ // this technique works but there are easier ways:
+ // https://stackoverflow.com/questions/13031778/how-can-i-extract-a-file-from-an-embedded-resource-and-save-it-to-disk
+ Directory.CreateDirectory(resdir);
+ using var resource = System.Reflection.Assembly.GetCallingAssembly().GetManifestResourceStream($"{nameof(ffmpeg_decrypt)}.res." + resourceName);
+ using var reader = new BinaryReader(resource);
+ using var file = new FileStream(Path.Combine(resdir, resourceName), FileMode.OpenOrCreate);
+ using var writer = new BinaryWriter(file);
+ writer.Write(reader.ReadBytes((int)resource.Length));
+ }
+ }
+}
diff --git a/_Demos/inAudibleLite/Form1.cs b/_Demos/inAudibleLite/Form1.cs
index 89c1c4b6..ca95fd2b 100644
--- a/_Demos/inAudibleLite/Form1.cs
+++ b/_Demos/inAudibleLite/Form1.cs
@@ -66,6 +66,14 @@ namespace inAudibleLite
Console.SetOut(multiLogger);
}
+ string aaxPath;
+ public async Task getActivationBytes()
+ {
+ var checksum = await ffmpeg_decrypt.RCrack.GetChecksum(aaxPath);
+ var activationBytes = await ffmpeg_decrypt.RCrack.GetActivationBytes(checksum);
+ return activationBytes;
+ }
+
private async void btnSelectFile_Click(object sender, EventArgs e)
{
var openFileDialog = new OpenFileDialog { Filter = "Audible files (*.aax)|*.aax" };
@@ -75,7 +83,8 @@ namespace inAudibleLite
this.rtbLog.Clear();
this.txtInputFile.Text = openFileDialog.FileName;
- converter = await AaxToM4bConverter.CreateAsync(this.txtInputFile.Text, this.decryptKeyTb.Text);
+ aaxPath = this.txtInputFile.Text;
+ converter = await AaxToM4bConverter.CreateAsync(this.txtInputFile.Text, this.decryptKeyTb.Text, getActivationBytes);
pictureBox1.Image = Dinah.Core.Drawing.ImageReader.ToImage(converter.coverBytes);
@@ -90,7 +99,7 @@ namespace inAudibleLite
// only re-process prelim stats if input filename was changed
//also pick up new decrypt key, etc//if (this.txtInputFile.Text != converter?.inputFileName)
- converter = await AaxToM4bConverter.CreateAsync(this.txtInputFile.Text, this.decryptKeyTb.Text);
+ converter = await AaxToM4bConverter.CreateAsync(this.txtInputFile.Text, this.decryptKeyTb.Text, getActivationBytes);
converter.AppName = APP_NAME;
converter.SetOutputFilename(this.txtOutputFile.Text);
diff --git a/_Demos/inAudibleLite/inAudibleLite.csproj b/_Demos/inAudibleLite/inAudibleLite.csproj
index 9c9dd707..e38de6b0 100644
--- a/_Demos/inAudibleLite/inAudibleLite.csproj
+++ b/_Demos/inAudibleLite/inAudibleLite.csproj
@@ -9,6 +9,7 @@
+
\ No newline at end of file