public static void InstallFrameworkIfMissing(ApkFile apkFile) { IEnumerable<string> frameworkFiles = apkFile.Project.Properties.FrameWorkFiles; if (frameworkFiles.Count() == 0) return; string apkToolFrameWorkTag = apkFile.Project.Properties.ApkToolFrameWorkTag; apkToolFrameWorkTag = string.IsNullOrWhiteSpace(apkToolFrameWorkTag) ? apkFile.Project.Name : apkToolFrameWorkTag; string[] installedFrameworkFiles = Directory.GetFiles(CrcsSettings.Current.ApkToolFrameWorkFolder, "*" + apkToolFrameWorkTag + "*.apk", SearchOption.TopDirectoryOnly); if (frameworkFiles.Count() == installedFrameworkFiles.Length) return; var ep = new ExecuteProgram((message) => MessageEngine.AddError(null, message)); foreach (string file in frameworkFiles) { var arguments = new StringBuilder(); string apkToolFile = apkFile.Project.Solution.Properties.ApkToolFile; arguments.Append("-jar \"").Append(apkToolFile).Append("\""); arguments.Append(" if \"").Append(file).Append("\""); if (!string.IsNullOrWhiteSpace(apkToolFrameWorkTag)) { arguments.Append(" ").Append(apkToolFrameWorkTag); } if ( ep.Execute(CrcsSettings.Current.JavaFile, arguments.ToString(), Path.GetDirectoryName(apkToolFile)) != 0) { throw new Exception(string.Format("Program {0} failed", Path.GetFileName(apkToolFile))); } } }
/// <summary> /// Default ctor /// </summary> public ApkRunner(IIde ide, string apkPath, string packageName, string activity, bool debuggable, int launchFlags) { this.ide = ide; this.apkPath = apkPath; this.packageName = packageName; this.activity = activity; this.debuggable = debuggable; this.launchFlags = launchFlags; cancellationTokenSource = new CancellationTokenSource(); outputPane = ide.CreateDot42OutputPane(); DeployApk = true; // Load package try { var apk = new ApkFile(apkPath); if (!apk.Manifest.TryGetMinSdkVersion(out minSdkVersion)) { minSdkVersion = -1; } } catch (Exception ex) { minSdkVersion = -1; ErrorLog.DumpError(ex); } }
private Icon generateIcon() { if (!File.Exists(currentFile)) { return(null); } var apkFile = new ApkFile { LongFileName = currentFile }; apkFile = SqliteConnector.ReadApkFile(apkFile); var iconAsByteArray = SqliteConnector.ReadIcon(apkFile); if (iconAsByteArray != null) { //Create stream from byte array var memoryStream = new MemoryStream(iconAsByteArray); //Create bitmap from stream var bitmap = new Bitmap(memoryStream); var iconHandle = bitmap.GetHicon(); //Dispose memorystream for GC Cleanup memoryStream.Close(); memoryStream.Dispose(); //Return Icon return(Icon.FromHandle(iconHandle)); } return(null); }
private SourceFile(ApkFile apk, JarFile jar, ISpySettings settings, MapFile mapFile, string singleFilePath = null) { this.apk = apk; this.jar = jar; this.settings = settings; this.mapFile = mapFile; this.singleFilePath = singleFilePath; #if DEBUG classLoader = new AssemblyClassLoader(module.OnClassLoaded); var modParams = new ModuleParameters { AssemblyResolver = new AssemblyResolver(new[] { Frameworks.Instance.FirstOrDefault().Folder }, classLoader, module.OnAssemblyLoaded), Kind = ModuleKind.Dll }; assembly = AssemblyDefinition.CreateAssembly(new AssemblyNameDefinition("spy", Version.Parse("1.0.0.0")), "main", modParams); classLoader.LoadAssembly(assembly); var dot42Assembly = modParams.AssemblyResolver.Resolve("dot42"); // Force loading of classes if (jar != null) { foreach (var fileName in jar.ClassFileNames) { OpenClass(fileName); } } #endif }
/// <summary> /// Collect all icons /// </summary> private static void CollectIcons(ApkFile apk, List <BarEntry> entries, Dictionary <string, string> apkPath2barPath) { #if DEBUG Debugger.Launch(); #endif var iconNames = apk.Manifest.Activities.Select(x => x.Icon).Where(x => !string.IsNullOrEmpty(x)).ToList(); var appIcon = apk.Manifest.ApplicationIcon; if (!string.IsNullOrEmpty(appIcon)) { iconNames.Add(appIcon); } foreach (var name in iconNames) { if (apkPath2barPath.ContainsKey(name)) { continue; } int nameAsInt; if (!int.TryParse(name, out nameAsInt)) { continue; } var resId = apk.Resources.GetResourceIdentifier(nameAsInt); var iconData = IconBuilder.GetIcon(resId, apk); if (iconData != null) { var barPath = "android/res/drawable/" + resId + ".png"; var entry = new BarEntry(barPath, new MemoryStream(iconData)); entries.Add(entry); apkPath2barPath[name] = barPath; } } }
private static void UpdateIcon(ApkFile apkFile, byte[] iconBytes) { using (var dbConnection = new SQLiteConnection(DataSource)) { dbConnection.Open(); using (var transaction = dbConnection.BeginTransaction()) { using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "UPDATE apk SET icon = ? WHERE hash = ?"; command.Parameters.Add(new SQLiteParameter(DbType.Binary, "icon") { Value = iconBytes }); command.Parameters.Add(new SQLiteParameter(DbType.String, "hash") { Value = apkFile.Md5Hash }); command.ExecuteNonQuery(); } transaction.Commit(); } } }
private void AppendOtherInfo(string packageName, string latestVersion, string googlePlayName, string price, string category, DateTime lastGooglePlayFetch) { //Update database var apkFileToUpdate = new ApkFile { PackageName = packageName, LatestVersion = latestVersion, GooglePlayName = googlePlayName, Price = price, Category = category, LastGooglePlayFetch = lastGooglePlayFetch, GooglePlayFetchFail = false }; SqliteConnector.UpdateApkFile(apkFileToUpdate); foreach (ListViewItem lvi in lvMain.Items) { var apkFile = (ApkFile) lvi.Tag; if (apkFile.PackageName == packageName) { lvi.SubItems[(int)ApkColumn.LatestVersion].Text = latestVersion; apkFile.LatestVersion = latestVersion; lvi.SubItems[(int)ApkColumn.GooglePlayName].Text = googlePlayName; apkFile.GooglePlayName = googlePlayName; lvi.SubItems[(int)ApkColumn.Price].Text = price; apkFile.Price = price; lvi.SubItems[(int)ApkColumn.Category].Text = category; apkFile.Category = category; lvi.SubItems[(int)ApkColumn.RefreshDate].Text = lastGooglePlayFetch.ToRelativeTimeString(); apkFile.LastGooglePlayFetch = lastGooglePlayFetch; SetColorsForListViewItem(lvi); } } }
private DexLookup LoadDex() { var apk = new ApkFile(_apkPath); var dex = apk.Load("classes.dex"); return(new DexLookup(Dex.Read(new MemoryStream(dex)))); }
/// <summary> /// Create an attrs.xml parser for the data in the given framework folder. /// </summary> private static AttrsXmlParser CreateAttrXmlParser(ApkFile apkFile) { var data = (apkFile != null) ? apkFile.Load("attrs.xml") : null; if (data == null) { return(new AttrsXmlParser(null)); } return(new AttrsXmlParser(new MemoryStream(data))); }
/// <summary> /// Create an layout.xml parser for the data in the given framework folder. /// </summary> private static LayoutXmlParser CreateLayoutXmlParser(ApkFile apkFile) { var data = (apkFile != null) ? apkFile.Load("layout.xml") : null; if (data == null) { return(new LayoutXmlParser(null)); } return(new LayoutXmlParser(new MemoryStream(data))); }
/// <summary> /// Load a resources table from the given apk. /// </summary> private static Table CreateResourcesArsc(ApkFile apkFile) { var data = (apkFile != null) ? apkFile.Load("resources.arsc") : null; if (data == null) { return(null); } return(new Table(new MemoryStream(data))); }
/// <summary> /// Try to load a bitmap from file. /// Returns null when that was not possible. /// </summary> private static Image LoadBitmap(ApkFile apk, string fileName) { var data = apk.Load(fileName); if (data == null) { return(null); } return(Image.FromStream(new MemoryStream(data))); }
public static byte[] ExtractIconAsByteArray(ApkFile apkFile) { if (apkFile != null && !string.IsNullOrWhiteSpace(apkFile.IconPath)) { using (var memStream = ExtractIconAsMemoryStream(apkFile)) { return(memStream.ToArray()); } } return(null); }
/// <summary> /// Run the process. /// </summary> protected override void DoWork() { // Get APK package name var apk = new ApkFile(apkPath); var packageName = apk.Manifest.PackageName; // Now install var adb = new Adb { Logger = LogOutput }; adb.InstallApk(device.Serial, apkPath, packageName, Adb.Timeout.InstallApk); }
public ApkViewer(ApkFile file) { InitializeComponent(); _apkListView.ItemDoubleClicked += ApkListViewItemDoubleClicked; _file = file; //_apkListView = new ApkListView(); //_apkListView.FontFamily = new FontFamily("Segoe UI"); //_apkListView.FontSize = 12; TabTitle = _file.Name; TabToolTip = _file.FileSystemPath; CreateFilterCollection(); _initialized = true; }
public static MemoryStream ExtractIconAsMemoryStream(ApkFile apkFile) { if (apkFile != null && !string.IsNullOrWhiteSpace(apkFile.IconPath)) { //Unzip icon var memoryStream = new MemoryStream(); using (var zip = ZipFile.Read(apkFile.LongFileName)) { var zf = zip[apkFile.IconPath]; zf.Extract(memoryStream); } return(memoryStream); } return(null); }
public static byte[] ReadIcon(ApkFile apkFile) { if (string.IsNullOrWhiteSpace(apkFile.IconPath)) { return(null); } byte[] iconBytes = null; var alreadyCached = false; using (var dbConnection = new SQLiteConnection(DataSource)) { dbConnection.Open(); using (var transaction = dbConnection.BeginTransaction()) { using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "SELECT icon FROM apk WHERE hash = ?"; command.Parameters.Add(new SQLiteParameter(DbType.String, "hash") { Value = apkFile.Md5Hash }); using (var reader = command.ExecuteReader()) { while (reader.Read()) { if (reader["icon"] != null && !Convert.IsDBNull(reader["icon"])) { alreadyCached = true; iconBytes = (byte[])reader["icon"]; } } } } transaction.Commit(); } } if (!alreadyCached) { iconBytes = clsUtils.ResizeIcon(ApkParser.ExtractIconAsByteArray(apkFile)); Task.Factory.StartNew(() => UpdateIcon(apkFile, iconBytes)); } return(iconBytes); }
public override void Start(bool withDebugging) { // Open the package ApkFile apkFile; var apkPath = ApkPath; try { apkFile = new ApkFile(apkPath); } catch (Exception ex) { MessageBox.Show(string.Format("Failed to open package because: {0}", ex.Message)); return; } // Show device selection var ide = Dot42Addin.Ide; int minSdkVersion; if (!apkFile.Manifest.TryGetMinSdkVersion(out minSdkVersion)) { minSdkVersion = -1; } var targetFramework = (minSdkVersion > 0) ? Frameworks.Instance.GetBySdkVersion(minSdkVersion) : null; var targetVersion = (targetFramework != null) ? targetFramework.Name : null; var runner = new ApkRunner(ide, ApkPath, apkFile.Manifest.PackageName, apkFile.Manifest.Activities.Select(x => x.Name).FirstOrDefault(), withDebugging, 0); using (var dialog = new DeviceSelectionDialog(ide, IsCompatible, targetVersion)) { if (dialog.ShowDialog() == DialogResult.OK) { // Run on the device now var device = dialog.SelectedDevice; ide.LastUsedUniqueId = device.UniqueId; using (var xDialog = new LauncherDialog(apkPath, withDebugging)) { var stateDialog = xDialog; stateDialog.Cancel += (s, x) => runner.Cancel(); stateDialog.Load += (s, x) => runner.Run(device, stateDialog.SetState); stateDialog.ShowDialog(); } } } }
public static void UpdateApkFile(ApkFile apkFile) { using (var dbConnection = new SQLiteConnection(DataSource)) { dbConnection.Open(); using (var transaction = dbConnection.BeginTransaction()) { using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "UPDATE apk SET google_play_name = ?, category = ?, latest_version = ?, price = ?, last_google_play_fetch = ?, google_play_fetch_fail = 0 WHERE package_name = ?"; command.Parameters.Add(new SQLiteParameter(DbType.String, "google_play_name") { Value = apkFile.GooglePlayName }); command.Parameters.Add(new SQLiteParameter(DbType.String, "category") { Value = apkFile.Category }); command.Parameters.Add(new SQLiteParameter(DbType.String, "latest_version") { Value = apkFile.LatestVersion }); command.Parameters.Add(new SQLiteParameter(DbType.String, "price") { Value = apkFile.Price }); command.Parameters.Add(new SQLiteParameter(DbType.DateTime, "last_google_play_fetch") { Value = apkFile.LastGooglePlayFetch }); command.Parameters.Add(new SQLiteParameter(DbType.String, "package_name") { Value = apkFile.PackageName }); command.ExecuteNonQuery(); } transaction.Commit(); } } }
internal static byte[] GetIcon(string resourceId, ApkFile apk) { // Look for the files var iconFileNames = apk.FileNames.Where(x => MatchesWith(x, resourceId)).ToList(); // Load all variations var icons = iconFileNames.Select(x => LoadBitmap(apk, x)).Where(x => x != null).OrderByDescending(x => Math.Max(x.Width, x.Height)).ToList(); var icon = icons.FirstOrDefault(x => (x.Height <= MaxWidthHeight) && (x.Width <= MaxWidthHeight)); if (icon == null) { return(null); // Try scaling } // Return icon var stream = new MemoryStream(); icon.Save(stream, ImageFormat.Png); return(stream.ToArray()); }
public static void InstallFrameworkIfMissing(ApkFile apkFile) { IEnumerable <string> frameworkFiles = apkFile.Project.Properties.FrameWorkFiles; if (frameworkFiles.Count() == 0) { return; } string apkToolFrameWorkTag = apkFile.Project.Properties.ApkToolFrameWorkTag; apkToolFrameWorkTag = string.IsNullOrWhiteSpace(apkToolFrameWorkTag) ? apkFile.Project.Name : apkToolFrameWorkTag; string[] installedFrameworkFiles = Directory.GetFiles(CrcsSettings.Current.ApkToolFrameWorkFolder, "*" + apkToolFrameWorkTag + "*.apk", SearchOption.TopDirectoryOnly); if (frameworkFiles.Count() == installedFrameworkFiles.Length) { return; } var ep = new ExecuteProgram((message) => MessageEngine.AddError(null, message)); foreach (string file in frameworkFiles) { var arguments = new StringBuilder(); string apkToolFile = apkFile.Project.Solution.Properties.ApkToolFile; arguments.Append("-jar \"").Append(apkToolFile).Append("\""); arguments.Append(" if \"").Append(file).Append("\""); if (!string.IsNullOrWhiteSpace(apkToolFrameWorkTag)) { arguments.Append(" ").Append(apkToolFrameWorkTag); } if ( ep.Execute(CrcsSettings.Current.JavaFile, arguments.ToString(), Path.GetDirectoryName(apkToolFile)) != 0) { throw new Exception(string.Format("Program {0} failed", Path.GetFileName(apkToolFile))); } } }
private static void UninstallAPK(string path) { var pathSet = new HashSet <string>(); if (File.Exists(path)) { pathSet.Add(path); } else if (Directory.Exists(path)) { foreach (var file in Directory.EnumerateFiles(path, "*.apk", SearchOption.AllDirectories)) { pathSet.Add(file); } } try { var names = new HashSet <string>(); foreach (var iterator in pathSet) { var apk = new ApkFile(iterator); var name = apk.Manifest.PackageName; names.Add(name); } foreach (var name in names) { UninstallAPKByPackageName(name); } } catch (Exception ex) { Console.WriteLine("Failed to uninstall {0} because {1}", path, ex.Message); } }
static void ReadApk(String filePath) { using (ApkFile apk = new ApkFile(filePath)) { Console.WriteLine("Package: {0}", apk.AndroidManifest.Package); Console.WriteLine("Application name: {0} ({1})", apk.AndroidManifest.Application.Label, apk.AndroidManifest.VersionName); if (apk.MfFile != null) { UInt32 totalFiles = 0; UInt32 hashNotFound = 0; UInt32 invalidHash = 0; foreach (String apkFilePath in apk.GetFiles()) { totalFiles++; String sHash = apk.MfFile[apkFilePath]; if (sHash == null) { //Console.WriteLine("Hash not found for file: {0}", apkFilePath); hashNotFound++; } else if (!apk.MfFile.ValidateHash(apkFilePath, apk.GetFile(apkFilePath))) { //Console.WriteLine("InvalidHash: {0} ({1})", apkFilePath, sHash); invalidHash++; } } Console.WriteLine("Total files: {0:N0}", totalFiles); if (hashNotFound > 0) { Console.WriteLine("Hash Not found: {0:N0}", hashNotFound); } if (invalidHash > 0) { Console.WriteLine("Invalid hash: {0:N0}", invalidHash); } } TreeDto root = BuildTree(apk.GetHeaderFiles().ToArray(), '/'); String test = ConvertTreeToStringRec(root, 0); foreach (String xmlFile in apk.GetHeaderFiles()) { switch (Path.GetExtension(xmlFile).ToLowerInvariant()) { case ".xml": /*if(xmlFile.Equals("AndroidManifest.xml", StringComparison.OrdinalIgnoreCase)) * continue;*/ Byte[] file = apk.GetFile(xmlFile); //ManifestFile manifest = new ManifestFile(file); //Console.WriteLine(manifest.Xml.ConvertToString()); AxmlFile axml = new AxmlFile(StreamLoader.FromMemory(file, xmlFile)); if (axml.Header.IsValid) { XmlNode xml = axml.RootNode; Console.WriteLine("---" + xmlFile + ":"); Console.WriteLine(xml.ConvertToString()); } else { Console.WriteLine("---" + xmlFile + ":"); Console.WriteLine(System.Text.Encoding.UTF8.GetString(file)); } break; } } ReadApkManifestRecursive(apk.AndroidManifest); } }
public static ApkFile ReadApkFile(ApkFile apkFile) { var md5Hash = HashHelper.GetMd5HashForFile(apkFile.LongFileName); apkFile.Md5Hash = md5Hash; bool alreadyCached; using (var dbConnection = new SQLiteConnection(DataSource)) { dbConnection.Open(); using (var transaction = dbConnection.BeginTransaction()) { using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "SELECT * FROM apk WHERE hash = ?"; command.Parameters.Add(new SQLiteParameter(DbType.String, "hash") { Value = md5Hash }); using (var reader = command.ExecuteReader()) { alreadyCached = reader.HasRows; if (alreadyCached) { //Read from apk table while (reader.Read()) { //Static information apkFile.IdApkFile = Convert.ToInt32(reader["id_apk"]); if (reader["package_name"] != null && !Convert.IsDBNull(reader["package_name"])) { apkFile.PackageName = Convert.ToString(reader["package_name"]); } if (reader["internal_name"] != null && !Convert.IsDBNull(reader["internal_name"])) { apkFile.InternalName = Convert.ToString(reader["internal_name"]); } if (reader["local_version"] != null && !Convert.IsDBNull(reader["local_version"])) { apkFile.LocalVersion = Convert.ToString(reader["local_version"]); } if (reader["version_code"] != null && !Convert.IsDBNull(reader["version_code"])) { apkFile.VersionCode = Convert.ToString(reader["version_code"]); } if (reader["minimum_sdk_version"] != null && !Convert.IsDBNull(reader["minimum_sdk_version"])) { apkFile.MinimumSdkVersion = Convert.ToString(reader["minimum_sdk_version"]); } if (reader["target_sdk_version"] != null && !Convert.IsDBNull(reader["target_sdk_version"])) { apkFile.TargetSdkVersion = Convert.ToString(reader["target_sdk_version"]); } if (reader["icon_path"] != null && !Convert.IsDBNull(reader["icon_path"])) { apkFile.IconPath = Convert.ToString(reader["icon_path"]); } //Dynamic information if (reader["google_play_name"] != null && !Convert.IsDBNull(reader["google_play_name"])) { apkFile.GooglePlayName = Convert.ToString(reader["google_play_name"]); } if (reader["category"] != null && !Convert.IsDBNull(reader["category"])) { apkFile.Category = Convert.ToString(reader["category"]); } if (reader["latest_version"] != null && !Convert.IsDBNull(reader["latest_version"])) { apkFile.LatestVersion = Convert.ToString(reader["latest_version"]); } if (reader["price"] != null && !Convert.IsDBNull(reader["price"])) { apkFile.Price = Convert.ToString(reader["price"]); } if (reader["last_google_play_fetch"] != null && !Convert.IsDBNull(reader["last_google_play_fetch"])) { apkFile.LastGooglePlayFetch = Convert.ToDateTime(reader["last_google_play_fetch"]); } } } } } if (alreadyCached) { using (var command = new SQLiteCommand(dbConnection)) { //Read from extra table command.CommandText = "SELECT id_extra, id_apk, id_extra_type, extra FROM extra WHERE id_apk = ?"; command.Parameters.Clear(); command.Parameters.Add(new SQLiteParameter(DbType.Int64, apkFile.IdApkFile)); using (var reader = command.ExecuteReader()) { if (reader.HasRows) { while (reader.Read()) { var idExtraType = Convert.ToInt32(reader["id_extra_type"]); switch (idExtraType) { case 1: //Screen size apkFile.ScreenSizes.Add(Convert.ToString(reader["extra"])); break; case 2: //Screen density apkFile.ScreenDensities.Add(Convert.ToString(reader["extra"])); break; case 3: //Permission apkFile.Permissions.Add(Convert.ToString(reader["extra"])); break; case 4: //Feature apkFile.Features.Add(Convert.ToString(reader["extra"])); break; } } } } } } transaction.Commit(); } } if (!alreadyCached) { apkFile = ApkParser.ParseApk(apkFile); apkFile = InsertApkFile(apkFile); } return(apkFile); }
private static ApkFile InsertApkFile(ApkFile apkFile) { using (var dbConnection = new SQLiteConnection(DataSource)) { dbConnection.Open(); using (var transaction = dbConnection.BeginTransaction()) { using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "INSERT OR IGNORE INTO apk (hash, package_name, internal_name, local_version, version_code, minimum_sdk_version, target_sdk_version, icon_path) VALUES (?, ?, ?, ?, ?, ?, ?, ?)"; command.Parameters.Add(new SQLiteParameter(DbType.String, "hash") { Value = apkFile.Md5Hash }); command.Parameters.Add(new SQLiteParameter(DbType.String, "package_name") { Value = apkFile.PackageName }); command.Parameters.Add(new SQLiteParameter(DbType.String, "internal_name") { Value = apkFile.InternalName }); command.Parameters.Add(new SQLiteParameter(DbType.String, "local_version") { Value = apkFile.LocalVersion }); command.Parameters.Add(new SQLiteParameter(DbType.String, "version_code") { Value = apkFile.VersionCode }); command.Parameters.Add(new SQLiteParameter(DbType.String, "minimum_sdk_version") { Value = apkFile.MinimumSdkVersion }); command.Parameters.Add(new SQLiteParameter(DbType.String, "target_sdk_version") { Value = apkFile.TargetSdkVersion }); command.Parameters.Add(new SQLiteParameter(DbType.String, "icon_path") { Value = apkFile.IconPath }); command.ExecuteNonQuery(); } using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "SELECT id_apk FROM apk WHERE hash = ?"; command.Parameters.Add(new SQLiteParameter(DbType.String, "hash") { Value = apkFile.Md5Hash }); using (var reader = command.ExecuteReader()) { if (reader.HasRows) { while (reader.Read()) { if (reader["id_apk"] != null && !Convert.IsDBNull(reader["id_apk"])) { apkFile.IdApkFile = Convert.ToInt64(reader["id_apk"]); } } } } } var extrasInserted = false; using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "SELECT count(*) as extras_count FROM extra WHERE id_apk = ?"; command.Parameters.Add(new SQLiteParameter(DbType.Int64, "id_apk") { Value = apkFile.IdApkFile }); using (var reader = command.ExecuteReader()) { if (reader.HasRows) { while (reader.Read()) { if (reader["extras_count"] != null && !Convert.IsDBNull(reader["extras_count"])) { var extrasCount = Convert.ToInt32(reader["extras_count"]); if (extrasCount > 0) { extrasInserted = true; } } } } } } if (!extrasInserted) { foreach (var screenSize in apkFile.ScreenSizes) { using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "INSERT INTO extra (id_apk, id_extra_type, extra) VALUES (?, 1, ?)"; command.Parameters.Add(new SQLiteParameter(DbType.Int64, "id_apk") { Value = apkFile.IdApkFile }); command.Parameters.Add(new SQLiteParameter(DbType.String, "extra") { Value = screenSize }); command.ExecuteNonQuery(); } } foreach (var screenDensity in apkFile.ScreenDensities) { using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "INSERT INTO extra (id_apk, id_extra_type, extra) VALUES (?, 2, ?)"; command.Parameters.Add(new SQLiteParameter(DbType.Int64, "id_apk") { Value = apkFile.IdApkFile }); command.Parameters.Add(new SQLiteParameter(DbType.String, "extra") { Value = screenDensity }); command.ExecuteNonQuery(); } } foreach (var permission in apkFile.Permissions) { using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "INSERT INTO extra (id_apk, id_extra_type, extra) VALUES (?, 3, ?)"; command.Parameters.Add(new SQLiteParameter(DbType.Int64, "id_apk") { Value = apkFile.IdApkFile }); command.Parameters.Add(new SQLiteParameter(DbType.String, "extra") { Value = permission }); command.ExecuteNonQuery(); } } foreach (var feature in apkFile.Features) { using (var command = new SQLiteCommand(dbConnection)) { command.CommandText = "INSERT INTO extra (id_apk, id_extra_type, extra) VALUES (?, 4, ?)"; command.Parameters.Add(new SQLiteParameter(DbType.Int64, "id_apk") { Value = apkFile.IdApkFile }); command.Parameters.Add(new SQLiteParameter(DbType.String, "extra") { Value = feature }); command.ExecuteNonQuery(); } } } transaction.Commit(); } } return(apkFile); }
/// <summary> /// Compile the given resources into a suitable output folder. /// </summary> internal bool Compile(List <Tuple <string, ResourceType> > resources, List <string> appWidgetProviderCodeFiles, List <string> references, List <string> referenceFolders, string baseApkPath) { // Remove temp folder if (Directory.Exists(tempFolder)) { Directory.Delete(tempFolder, true); } // Ensure temp\res folder exists var resFolder = Path.Combine(tempFolder, "res"); Directory.CreateDirectory(resFolder); var tempApkPath = Path.Combine(tempFolder, "temp.apk"); // Compile each resource foreach (var resource in resources.Where(x => x.Item2 != ResourceType.Manifest)) { CopyResourceToFolder(tempFolder, resource.Item1, resource.Item2); } // Extract resources out of library project references var resolver = new AssemblyResolver(referenceFolders, null, null); foreach (var path in references) { ExtractLibraryProjectResources(resFolder, path, resolver); } // Select manifest path var manifestPath = resources.Where(x => x.Item2 == ResourceType.Manifest).Select(x => x.Item1).FirstOrDefault(); // Ensure files exists for the appwidgetproviders CreateAppWidgetProviderFiles(tempFolder, manifestPath, appWidgetProviderCodeFiles); // Create system ID's resource CreateSystemIdsResource(tempFolder); // Run aapt var args = new[] { "p", "-f", "-S", resFolder, "-M", GetManifestPath(tempFolder, manifestPath, packageName), "-I", baseApkPath, "-F", tempApkPath }; var runner = new ProcessRunner(Locations.Aapt, args); var exitCode = runner.Run(); if (exitCode != 0) { ProcessAaptErrors(runner.Output, tempFolder, resources); return(false); } // Unpack compiled resources to base folder. Table resourceTable = null; using (var apk = new ApkFile(tempApkPath)) { foreach (var name in apk.FileNames) { // Extract var data = apk.Load(name); // Save var path = Path.Combine(baseFolder, name); Directory.CreateDirectory(Path.GetDirectoryName(path)); File.WriteAllBytes(path, data); // Is resource table? yes -> load it if (name == "resources.arsc") { resourceTable = new Table(new MemoryStream(data)); } } } // Create R.cs if (!string.IsNullOrEmpty(generatedCodeFolder)) { var codeBuilder = new CreateResourceIdsCode(resourceTable, resources, valuesResourceProcessor.StyleableDeclarations); codeBuilder.Generate(generatedCodeFolder, packageName, generatedCodeNamespace, generatedCodeLanguage, lastModified); } // Create resource type usage info file if (!string.IsNullOrEmpty(resourceTypeUsageInformationPath)) { // Ensure folder exists var folder = Path.GetDirectoryName(resourceTypeUsageInformationPath); if (!Directory.Exists(folder)) { Directory.CreateDirectory(folder); } // Create file File.WriteAllLines(resourceTypeUsageInformationPath, layoutProcessor.CustomClassNames); } return(true); }
private void Wc_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) { var googlePlayPage = new HtmlAgilityPack.HtmlDocument(); try { googlePlayPage.LoadHtml(e.Result); //Current Version string currentVersion = null; if (googlePlayPage.DocumentNode.SelectNodes("//div[.='Current Version']")?.Count >= 1) { var currentVersionNode = googlePlayPage.DocumentNode.SelectNodes("//div[.='Current Version']").First(); var nextNodeAfterCurrentVersionNode = currentVersionNode.NextSibling; if (!string.IsNullOrWhiteSpace(nextNodeAfterCurrentVersionNode?.InnerText)) { currentVersion = nextNodeAfterCurrentVersionNode.InnerText; } } //Genre string genre = null; if (googlePlayPage.DocumentNode.SelectNodes("//a[@itemprop='genre']")?.Count >= 1) { genre = googlePlayPage.DocumentNode.SelectNodes("//a[@itemprop='genre']").First().InnerText; } //Name string name = null; if (googlePlayPage.DocumentNode.SelectNodes("//h1[@itemprop='name']")?.Count >= 1) { var nameNode = googlePlayPage.DocumentNode.SelectNodes("//h1[@itemprop='name']").First(); var innerNameNode = nameNode.FirstChild; if (innerNameNode != null && !string.IsNullOrWhiteSpace(innerNameNode.InnerText)) { name = innerNameNode.InnerText; } } //Price string price = null; if (googlePlayPage.DocumentNode.SelectNodes("//meta[@itemprop='price']")?.Count >= 1) { var priceNode = googlePlayPage.DocumentNode.SelectNodes("//meta[@itemprop='price']").First(); if (priceNode.Attributes.Contains("content") && !string.IsNullOrWhiteSpace(priceNode.Attributes["content"].Value)) { price = priceNode.Attributes["content"].Value; } } if (!string.IsNullOrWhiteSpace(currentVersion) && !string.IsNullOrWhiteSpace(genre) && !string.IsNullOrWhiteSpace(name)) { //HtmlDecode currentVersion = WebUtility.HtmlDecode(currentVersion); genre = WebUtility.HtmlDecode(genre); name = WebUtility.HtmlDecode(name); var lastGooglePlayFetch = DateTime.Now; string fixedPrice; if (string.IsNullOrWhiteSpace(price) || price.Trim() == "0") { fixedPrice = "Free"; } else { fixedPrice = price; } lblGooglePlayNameValue.Text = name; lblLatestVersionValue.Text = currentVersion; lblCategoryValue.Text = genre; lblPriceValue.Text = fixedPrice; //Update database var apkFileToUpdate = new ApkFile { PackageName = Convert.ToString(e.UserState), LatestVersion = currentVersion, GooglePlayName = name, Price = fixedPrice, Category = genre, LastGooglePlayFetch = lastGooglePlayFetch, GooglePlayFetchFail = false }; SqliteConnector.UpdateApkFile(apkFileToUpdate); } else { SqliteConnector.SetGooglePlayFetchFail(Convert.ToString(e.UserState)); } } catch { SqliteConnector.SetGooglePlayFetchFail(Convert.ToString(e.UserState)); } finally { btnRefreshDetails.Enabled = true; } }
private void ShowInfo() { var apkFile = new ApkFile { LongFileName = _fileName }; //Filename lblFilenameValue.Text = apkFile.ShortFileName; Text = string.Format("Properties of {0}", apkFile.ShortFileName); //Read APK File apkFile = SqliteConnector.ReadApkFile(apkFile); //Package lblPackageNameValue.Text = apkFile.PackageName; //Internal name lblInternalNameValue.Text = apkFile.InternalName; //Google Play name lblGooglePlayNameValue.Text = apkFile.GooglePlayName; //Local Version lblLocalVersionValue.Text = apkFile.LocalVersion; //Latest Version lblLatestVersionValue.Text = apkFile.LatestVersion; //Category lblCategoryValue.Text = apkFile.Category; //Price lblPriceValue.Text = apkFile.Price; //Version code lblVersionCodeValue.Text = apkFile.VersionCode; //Minium SDK Version lblMinSDKVersionValue.Text = clsUtils.TranslateSdkVersion(apkFile.MinimumSdkVersion); //Target SDK Version lblTargetSDKVersionValue.Text = clsUtils.TranslateSdkVersion(apkFile.TargetSdkVersion); //Permissions if (apkFile.Permissions.Count > 0) { txtPermissionsValue.Text = string.Empty; foreach (var permission in apkFile.Permissions) { txtPermissionsValue.Text += string.Format("{0}\r\n", permission); } txtPermissionsValue.Text = txtPermissionsValue.Text.Remove(txtPermissionsValue.Text.Length - 2, 2); } //Features if (apkFile.Features.Count > 0) { txtFeaturesValue.Text = string.Empty; foreach (var feature in apkFile.Features) { txtFeaturesValue.Text += string.Format("{0}\r\n", feature); } txtFeaturesValue.Text = txtFeaturesValue.Text.Remove(txtFeaturesValue.Text.Length - 2, 2); } //Screen sizes if (apkFile.ScreenSizes.Count > 0) { lblScreenSizesValue.Text = string.Empty; foreach (var screenSize in apkFile.ScreenSizes) { lblScreenSizesValue.Text += string.Format("{0}, ", screenSize); } lblScreenSizesValue.Text = lblScreenSizesValue.Text.Remove(lblScreenSizesValue.Text.Length - 2, 2); } //Screen densities if (apkFile.ScreenDensities.Count > 0) { lblScreenDensitiesValue.Text = string.Empty; foreach (var screenDensity in apkFile.ScreenDensities) { lblScreenDensitiesValue.Text += string.Format("{0}, ", screenDensity); } lblScreenDensitiesValue.Text = lblScreenDensitiesValue.Text.Remove(lblScreenDensitiesValue.Text.Length - 2, 2); } //Icon Task.Factory.StartNew(() => SqliteConnector.ReadIcon(apkFile)).ContinueWith(t => SetApkIcon(t.Result)); //Fetch details if (!apkFile.LastGooglePlayFetch.HasValue && (!apkFile.GooglePlayFetchFail.HasValue || !apkFile.GooglePlayFetchFail.Value) && Convert.ToBoolean(SqliteConnector.GetSettingValue(SettingEnum.AutoFetchGooglePlay))) { btnRefreshDetails.Enabled = false; var wc = new WebClient { Encoding = Encoding.UTF8 }; wc.DownloadStringCompleted += Wc_DownloadStringCompleted; wc.DownloadStringAsync(new Uri(GooglePlayHelper.GetUrlForPackageName(apkFile.PackageName, true)), apkFile.PackageName); } else { btnRefreshDetails.Enabled = true; } }
/// <summary> /// Gets the name of the APK package. /// </summary> private string GetApkName() { var apk = new ApkFile(Package.ItemSpec); return(apk.Manifest.PackageName); }
/// <summary> /// Default ctor /// </summary> public MetaInfManifestBuilder(ApkFile apk, string author, string debugTokenPath, Dictionary <string, string> apkPath2barPath) { // Prepare var developmentMode = !string.IsNullOrEmpty(debugTokenPath); var debugToken = developmentMode ? new BarFile(debugTokenPath) : null; if (debugToken != null) { // Verify debug token if (!string.Equals(debugToken.Manifest.PackageType, "debug-token", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException(string.Format("Debug token {0} has invalid package type", debugTokenPath)); } if (string.IsNullOrEmpty(debugToken.Manifest.PackageAuthor)) { throw new ArgumentException(string.Format("Debug token {0} has no package author", debugTokenPath)); } if (string.IsNullOrEmpty(debugToken.Manifest.PackageAuthorId)) { throw new ArgumentException(string.Format("Debug token {0} has no package author id", debugTokenPath)); } } // Create manifest AppendLine("Archive-Manifest-Version: 1.1"); AppendLine("Created-By: dot42"); AppendLine(); var androidManifest = apk.Manifest; if (developmentMode) { AppendLine("Package-Author: " + debugToken.Manifest.PackageAuthor); AppendLine("Package-Author-Id: " + debugToken.Manifest.PackageAuthorId); } else { AppendLine("Package-Author: " + author); AppendLine("Package-Author-Id: " + FormatID(author)); } AppendLine("Package-Name: " + androidManifest.PackageName); AppendLine("Package-Id: " + FormatID(androidManifest.PackageName)); AppendLine("Package-Version: " + androidManifest.VersionName); AppendLine("Package-Version-Id: " + FormatID(androidManifest.VersionName)); AppendLine("Package-Type: application"); AppendLine(); AppendLine("Application-Name: " + androidManifest.ApplicationLabel); AppendLine("Application-Id: " + FormatID(androidManifest.ApplicationLabel)); AppendLine("Application-Version: " + androidManifest.VersionName); AppendLine("Application-Version-Id: " + FormatID(androidManifest.VersionName)); if (developmentMode) { AppendLine("Application-Development-Mode: true"); } AppendLine(); // Collect permissions var permissions = new HashSet <string> { "access_shared", "play_audio" }; foreach (var permission in androidManifest.UsesPermissions) { string bbPerm; var key = (permission.Name ?? string.Empty).ToUpperInvariant(); if (permissionMap.TryGetValue(key, out bbPerm)) { permissions.Add(bbPerm); } } var userActions = string.Join(",", permissions); var entryPoint = GetEntryPoint(androidManifest); if (entryPoint != null) { AppendLine("Entry-Point-Name: " + androidManifest.ApplicationLabel); AppendLine("Entry-Point-Type: Qnx/Android"); AppendLine("Entry-Point: " + string.Format("android://{0}?activity-name={1}", androidManifest.PackageName, entryPoint.Name)); if (!string.IsNullOrEmpty(userActions)) { AppendLine("Entry-Point-User-Actions: " + userActions); } var icon = entryPoint.Icon; if (string.IsNullOrEmpty(icon)) { icon = androidManifest.ApplicationIcon; } if (!string.IsNullOrEmpty(icon)) { string iconBarPath; if (apkPath2barPath.TryGetValue(icon, out iconBarPath)) { AppendLine("Entry-Point-Icon: " + iconBarPath); } } AppendLine(); } }
public static ApkFile ParseApk(ApkFile apkFile) { var apk = apkFile.LongFileName; var aaptPath = string.Format("\"{0}\"", Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "aapt")); var psi = new ProcessStartInfo(aaptPath); var tempApk = string.Empty; var aaptArguments = string.Empty; if (clsUtils.ContainsUnicodeCharacter(apk)) { tempApk = Path.Combine(clsUtils.GetSystemRootTempPath(), string.Format("{0}.apk", Guid.NewGuid())); File.Copy(apk, tempApk); aaptArguments = string.Concat(" d badging \"", tempApk, "\""); } else { aaptArguments = string.Concat(" d badging \"", apk, "\""); } psi.Arguments = aaptArguments; psi.UseShellExecute = false; psi.CreateNoWindow = true; psi.RedirectStandardInput = true; psi.RedirectStandardOutput = true; var commandLine = new Process { StartInfo = psi }; commandLine.Start(); var standardOutput = new StreamReader(commandLine.StandardOutput.BaseStream, Encoding.UTF8); var outputLines = new List <string>(); string currentLine; while ((currentLine = standardOutput.ReadLine()) != null) { outputLines.Add(currentLine); } commandLine.WaitForExit(); standardOutput.Close(); if (!string.IsNullOrWhiteSpace(tempApk)) { File.Delete(tempApk); } foreach (var outputLine in outputLines) { var currentKey = outputLine.Split(new[] { ":" }, StringSplitOptions.None)[0].Trim(); switch (currentKey) { case "application": //Get internal name apkFile.InternalName = outputLine.Substring("label='", "'"); break; case "launchable-activity": //Get internal name (if previous failed) if (string.IsNullOrWhiteSpace(apkFile.InternalName)) { apkFile.InternalName = outputLine.Substring("label='", "'"); } break; case "package": //Get package name apkFile.PackageName = outputLine.Substring("name='", "'"); //Get local version apkFile.LocalVersion = outputLine.Substring("versionName='", "'"); //Get local version code apkFile.VersionCode = outputLine.Substring("versionCode='", "'"); break; case "uses-permission": //Get permissions var permission = outputLine.Substring("'", "'"); if (!apkFile.Permissions.Contains(permission)) { apkFile.Permissions.Add(permission); } break; case "uses-feature": case "uses-feature-not-required": case "uses-implied-feature": //Get features var feature = outputLine.Substring("'", "'"); if (!apkFile.Features.Contains(feature)) { apkFile.Features.Add(feature); } break; case "sdkVersion": //Get min sdk version apkFile.MinimumSdkVersion = outputLine.Substring("'", "'"); break; case "targetSdkVersion": //Get target sdk version apkFile.TargetSdkVersion = outputLine.Substring("'", "'"); break; case "supports-screens": apkFile.ScreenSizes = clsUtils.GetQuotedOccurencesInString(outputLine); break; case "densities": apkFile.ScreenDensities = clsUtils.GetQuotedOccurencesInString(outputLine); break; default: if (outputLine.StartsWith("application-icon-")) { apkFile.IconPath = outputLine.Substring("'", "'"); if (!apkFile.IconPath.ToLower().EndsWith(".png")) { apkFile.IconPath = null; } } break; } } apkFile.Permissions.Sort(); apkFile.Features.Sort(); return(apkFile); }
private IProjectFile CreatNewFile(string fileSystemPath, bool included, bool ignoreDecompileErrors) { string extension = (Path.GetExtension(fileSystemPath) ?? "").ToUpperInvariant(); IProjectFile file = null; switch (extension) { case ".ODEX": return null; case ".APK": file = new ApkFile(fileSystemPath, included, this); ((ApkFile) file).IgnoreDecompileErrors = ignoreDecompileErrors; break; case ".JAR": file = new JarFile(fileSystemPath, included, this); string locationsOfDependency = Path.GetDirectoryName(fileSystemPath); if (!_locationsOfDependencies.Contains(locationsOfDependency)) { _locationsOfDependencies.Add(locationsOfDependency); } break; default: if (BinaryExtensions.Contains(extension) || FileUtility.IsBinary(fileSystemPath)) { file = new BinaryFile(fileSystemPath, included, this); } else { file = new TextFile(fileSystemPath, included, this); } break; } var compositFile = file as CompositFile; if (compositFile != null) { string name = compositFile.Name.ToUpperInvariant(); if (_additionalDependencies.ContainsKey(name)) { compositFile.AddAdditionalDependencies(_additionalDependencies[name]); } } return file; }