AceLauncher
AceLauncher
AceLauncher is a Potentially Unwanted Program (PUP) similar to Wave Browser, OneStart, and OneLaunch. It’s a Chromium based browser that creates several tasks, AppData directories, and registry keys to maintain persistence on a device. While not overtly malicious, users will likely want to remove the browser as it does redirect and serve potentially malicious content. This includes functions that link to ManualsLib domains and references to Wave Browser and Recipe Lister. The browser also uses Yahoo’s Hosted Search platform to serve sponsored content driving revenue to the AceLauncher organization.
AceLauncher Removal Guide
This is a simple removal script for AceLauncher installations. While the browser does come with an uninstallation function that does remove the CurrentVersion\Run\ registry item, it does not appear to remove all artifacts.
This script enumerates all users on the device and removes any AceLauncher files in AppData/Local/*, Downloads, HKU:\*\Software\, and HKU\*\Software\Microsoft\Windows\CurrentVersion\run\.
Note: You can pull the History file for the AceLauncher browser for analysis at C:\Users\%USER%\AppData\Local\AceLauncher\User Data\Default\History. This will show all the URL visits and downloads the user made while using the browser. It may be prudent to ensure that all downloads and visited domains are legitimate or policy abiding.
AceLaunch sets itself as the default browser. You likely want to change this back to the primary browser. Removing the files without changing the default browser will cause issues with shell associations for html and other web files.
$FolderName="AceLauncher"
$users = (Get-Item C:\Users\*).Name
Write-Host "Stopping all AceLauncher processes"
Get-Process "*AceLauncher*" | Stop-Process -Force
foreach($user in $users){
$path = "C:\Users\$user\Downloads"
$appath = "C:\Users\$user\AppData\Local\"
Write-Host "Removing all AceLauncher Folders in $appath"
Remove-Item "$appath\$FolderName*" -Recurse -Force
Write-Host "Removing AceLauncher Tasks"
unregister-scheduledtask -TaskName "AceLauncher*" -Confirm:$false
Write-Host "Removing installers from Downloads"
Remove-Item "$path\*$FolderName*" -Force
Remove-ItemProperty -path "registry::hku\*\Software\Microsoft\Windows\CurrentVersion\run\" -name "com.acelauncher.dock" -Force
Remove-ItemProperty -path "registry::hku\*\Software\Microsoft\Windows\CurrentVersion\run\" -name "GoogleChromeAutoLaunch_*" -Force
Remove-Item -path "registry::hku\*\Software\AceLauncher" -Recurse -Force
Remove-Item -path "registry::hku\*\Software\AceLauncherUpdater" -Recurse -Force
}
Manual Removal
AceLauncher creates directories at the following AppData/Local paths:
- AceLauncher
- AceLauncherAutoUpdate
- AceLauncherDock
Additionally, AceLauncher creates the following scheduled tasks:
- AceLauncher Autoupdate
- AceLauncher Statistics
- AceLauncher Wakeup
AceLauncher registry items:
- CurrentVersion\run\ com.acelauncher.dock
- CurrentVersion\run\ GoogleChromeAutoLaunch_
- Software\AceLauncher
- Software\AceLauncherUpdater
You may also find that numerous processes are running. All processes should include AceLauncher in the name. Proceseses must be stopped before removal begins.
AceLauncher Internals
This mostly focuses on the Dock application and the extensions. The main browser application and updater were not fully analyzed.
AceLauncher Dock
The AceLauncher browser functions like other common PUPs. It silently launches in the background, creating RunKeys to ensure that it launches on startup. This can be seen in the InstallHelper and OnInstall functions.
public static class InstallHelper
{
private const int maxRetries = 5;
private static TimeSpan poll_freq => AceBrowserHelper.poll_freq;
public static async Task OnInstall()
{
if (!File.Exists(ConstValues.BrowserExeFullPath))
{
return;
}
Util.GenerateNativeManifest();
LocalState.SetBackgroundMode(false);
Process proc = new Process
{
// Start in bacckground
StartInfo = new ProcessStartInfo(ConstValues.BrowserExeFullPath, "--from-installer --silent-launch")
{
WorkingDirectory = Path.GetDirectoryName(ConstValues.BrowserExeFullPath),
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = false,
RedirectStandardOutput = false,
RedirectStandardError = false,
WindowStyle = ProcessWindowStyle.Normal
}
};
try
{
proc.Start();
if (!(await AceBrowserHelper.AreExtensionsUnpacked((TimeSpan?)TimeSpan.FromSeconds(7.0))))
{
BackgroundTaskBox.Run((Action)async delegate
{
await OnInstall2(proc);
});
return;
}
proc.Kill();
}
catch
{
}
await OnInstall2(proc);
}
private static async Task OnInstall2(Process first_proc)
{
await AceBrowserHelper.AreExtensionsUnpacked((TimeSpan?)null);
if (!first_proc.HasExited)
{
first_proc.Kill();
}
await AceBrowserHelper.CloseAceBrowser();
if (!AceBrowserHelper.IsAceBrowserRunning)
{
AceBrowserHelper.RepairPositioning();
}
int i;
if (File.Exists(ConstValues.BrowserLockFile))
{
i = 12;
while (i > 0 && File.Exists(ConstValues.BrowserLockFile))
{
await Task.Delay(poll_freq);
int num = i - 1;
i = num;
}
}
bool flag = !string.IsNullOrWhiteSpace(BrowserUpdaterSettings.VerboseLoggingPath);
string arguments = "--start-maximized" + (flag ? " --enable-logging=stderr --v=1" : string.Empty);
Process process = new Process
{
StartInfo = new ProcessStartInfo(ConstValues.BrowserExeFullPath, arguments)
{
// Start with no window
WorkingDirectory = Path.GetDirectoryName(ConstValues.BrowserExeFullPath),
CreateNoWindow = true,
UseShellExecute = false,
RedirectStandardInput = false,
RedirectStandardOutput = false,
RedirectStandardError = flag,
WindowStyle = ProcessWindowStyle.Maximized
}
};
if (flag)
{
process.ErrorDataReceived += delegate(object s, DataReceivedEventArgs e)
{
File.AppendAllLines(BrowserUpdaterSettings.VerboseLoggingPath, new string[1] { e.Data });
};
}
process.Start();
if (flag)
{
process.BeginErrorReadLine();
}
await AceBrowserHelper.BringToFront(false);
i = 5;
while (i > 0)
{
if (await Util.CheckExtensionAvailable())
{
if (BrowserUpdaterSettings.RunInBackgroundEnabled)
{
LocalState.SetBackgroundMode(true);
}
break;
}
await Task.Delay(TimeSpan.FromMilliseconds(200 << 5 - i));
int num = i - 1;
i = num;
}
}
}
...
private static RegistryKey GetAutoRunRegistryKey()
{
// RunKey creation
return Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", writable: true);
}
private static async Task OnInstall()
{
AceBrowserHelper.TryLaunchThankYouPage();
DigestSender.BlockDigest();
using (RegistryKey registryKey = GetAutoRunRegistryKey())
{
registryKey?.SetValue(AutoRunAppName, "\"" + Application.ExecutablePath + "\" " + ConstValues.WakeUpArg);
}
Util.AddUnlockHook();
DigestSender.IncrementMetric($"{(object)(DigestMetrics)3}_{BrowserUpdaterSettings.NewTabStyle}");
int num = ProfileCopiers.GetProfiles(LocalState.AceLauncherUserFolder).Count();
DigestSender.IncrementMetric($"{(object)(DigestMetrics)4}_{num}");
DigestSender.SendDigest((ToolbarNotifyType)1);
await InstallHelper.OnInstall();
DigestSender.ForceDigest();
DigestSender.SendDailyDigest();
}
The Search bar function of AceLauncher routes through the Yahoo Hosted Search (YHS) platform using the yhs-acelauncher identifier. The browser likely derives revenue by pushing sponsored results to the top of the Yahoo search results using the YHS platform.
public static string GetYahooSearchURL(string query)
{
return "https://search.yahoo.com/yhs/search?hspart=ssl&hsimp=yhs-acelauncher&type=" + SearchTypeTag + "&p=" + Uri.EscapeDataString(query);
}
Bundeled within the browser is a search function that redirects user queries to well known ManualsLib domains. These domains are often infected with malicious advertisements and offer further PUPs for download.
public ManualDialog()
{
BlockInitialFocus();
Util.StylizeForm((ShapedForm)(object)this, InitializeComponent);
((Control)(object)this).BackColor = Color.FromArgb(241, 241, 241);
((ContainerControl)this).AutoScaleMode = AutoScaleMode.None;
iconClose = IconButton.MakeSimpleButton(Icons.close, "Close");
iconClose.AllowMouseover = false;
iconClose.Location = phClose.Location;
iconClose.Anchor = phClose.Anchor;
((Control)this).Controls.Remove(phClose);
IconButton iconButton = iconClose;
iconButton.Click = (EventHandler)Delegate.Combine(iconButton.Click, (EventHandler)delegate
{
((Form)this).Close();
});
((Control)this).Controls.Add(iconClose);
siteTable.Controls.Add(MakeLogo(ManualLogo.manuals_lib, "ManualsLib", "https://www.manualslib.com/brand/"), 0, 0);
siteTable.Controls.Add(MakeLogo(ManualLogo.hifi, "HiFi Engine", "https://www.hifiengine.com/manual-library.shtml"), 0, 1);
siteTable.Controls.Add(MakeLogo(ManualLogo.free_service, "Free Service Manuals", "http://freeservicemanuals.info/en/"), 0, 2);
siteTable.Controls.Add(MakeLogo(ManualLogo.audio, "Audioservice Manuals", "https://www.audioservicemanuals.com/"), 0, 3);
siteTable.Controls.Add(MakeLogo(ManualLogo.manuallz, "Manualzz", "https://manualzz.com/"), 1, 0);
siteTable.Controls.Add(MakeLogo(ManualLogo.manua_ls, "Manua.ls", "https://www.manua.ls/"), 1, 1);
siteTable.Controls.Add(MakeLogo(ManualLogo.elektrotanya, "Elektrotanya", "https://elektrotanya.com/keres"), 1, 2);
siteTable.Controls.Add(MakeLogo(ManualLogo.internet_archive, "Internet Archive", "https://archive.org/search?query=subject%3A%22Manuals%22"), 1, 3);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_acer, "Acer", "https://www.manualslib.com/brand/acer/"), 0, 0);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_bosch, "Bosch", "https://www.manualslib.com/brand/bosch/"), 1, 0);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_cisco, "Cisco", "https://www.manualslib.com/brand/cisco/"), 2, 0);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_epson, "Epson", "https://www.manualslib.com/brand/epson/"), 3, 0);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_ge, "GE", "https://www.manualslib.com/brand/ge/"), 0, 1);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_honeywell, "Honeywell", "https://www.manualslib.com/brand/honeywell/"), 1, 1);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_kenmore, "Kenmore", "https://www.manualslib.com/brand/kenmore/"), 2, 1);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_lg, "LG", "https://www.manualslib.com/brand/lg/"), 3, 1);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_samsung, "Samsung", "https://www.manualslib.com/brand/samsung/"), 0, 2);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_sony, "Sony", "https://www.manualslib.com/brand/sony/"), 1, 2);
brandTable.Controls.Add(MakeBrand(ManualLogo.logo_whirlpool, "Whirlpool", "https://www.manualslib.com/brand/whirlpool/"), 2, 2);
FontLoader.ProcessFonts(((Control)this).Controls, lblLinks, lblTitle, lblTitleBrands);
brandTable.Controls.Add(MakeMore(), 3, 2);
txtBrand.PlaceHolderText = "Type brand name";
txtModel.PlaceHolderText = "Type model name";
((Control)this).MouseEnter += refreshHighlight;
((Control)this).MouseLeave += refreshHighlight;
siteTable.MouseEnter += refreshHighlight;
siteTable.MouseLeave += refreshHighlight;
((Control)this).Click += delegate(object sender, EventArgs args)
{
txtBrand.SearchBox_Leave(sender, args);
txtModel.SearchBox_Leave(sender, args);
FocusTrap.Focus();
};
Util.StylizeButton(btnSearch);
txtBrand.KeyUp += txtSearch_KeyUp;
txtModel.KeyUp += txtSearch_KeyUp;
txtBrand.Text = BrandText;
txtModel.Text = ModelText;
ManualDialog_SizeChanged(null, null);
}
The AceLauncher browser comes with a custom DLL named AceLauncherShared.dll. This DLL has a function named SendDigest that sends the following parameters to hxxps[://]analytics[.]acelauncher[.]com/partialdigest
| Parameter | Usage |
|---|---|
| Notify Type | |
| User Key | Identifier unique to installation |
| Toolbar Version | The version of the AceLauncherDock |
| Default Search Provider | The default search provider for the AceLauncher browser |
| Dock Hidden/Visible | Status of the AceLauncherDock |
| Has Shift2/No Shift2 | Queries SOFTWARE\\Clients\\StartMenuInternet for Shift Browser |
| Extension Status | Status of the AceLauncher browser extension |
| Has Wave/No Wave | Queries Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\WaveBrowser for Wave Browser |
| AceLaunch Browser Status | Queries Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\AceLauncher and Software\\AceLauncherUpdater\\BrowserSettings for installation and wakeup status |
public void SendDigest(ToolbarNotifyType notifyType)
{
try
{
string userKey = UserKey;
DigestParameter param = new DigestParameter
{
NotifyType = notifyType,
UserKey = userKey,
ToolbarVersion = (Version ?? "")
};
if (notifyType == ToolbarNotifyType.DailyDigest && DigestVersion == DigestVersion.Dock)
{
Dictionary<string, int> dictionary = DockSettings.Metrics ?? new Dictionary<string, int>();
string searchProvider = GetSearchProvider();
if (!string.IsNullOrWhiteSpace(searchProvider))
{
dictionary["defaultsearch_" + searchProvider] = 1;
}
else
{
dictionary["defaultsearch_unknown"] = 1;
}
if (DockSettings.ClosedByUser)
{
dictionary["dockhidden"] = 1;
}
else
{
dictionary["dockvisible"] = 1;
}
dictionary[SharedUtil.HasShift() ? "hasshift2" : "noshift2"] = 1;
if (!DockSettings.ExtensionConnected.HasValue)
{
dictionary["ExtensionConnection_Unknown"] = 1;
}
else if (DockSettings.ExtensionConnected == true)
{
dictionary["ExtensionConnection_Connected"] = 1;
}
else if (DockSettings.ExtensionConnected == false)
{
dictionary["ExtensionConnection_DisConnected"] = 1;
}
using (RegistryKey registryKey = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\WaveBrowser"))
{
dictionary[(registryKey != null) ? "haswave" : "nowave"] = 1;
}
bool flag;
using (RegistryKey registryKey2 = Registry.CurrentUser.OpenSubKey("Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\AceLauncher"))
{
flag = registryKey2 != null;
}
bool flag2;
using (RegistryKey registryKey3 = Registry.CurrentUser.OpenSubKey("Software\\AceLauncherUpdater\\BrowserSettings"))
{
flag2 = registryKey3 != null && bool.TrueString.Equals(registryKey3.GetValue("wakeup")?.ToString(), StringComparison.InvariantCultureIgnoreCase);
}
if (!flag)
{
dictionary["browseruninstalled"] = 1;
}
else if (flag2)
{
dictionary["browserwakeup"] = 1;
}
else
{
dictionary["browsersleep"] = 1;
}
string metrics = ((dictionary == null || !dictionary.Any()) ? null : string.Join(",", dictionary.Select((KeyValuePair<string, int> x) => $"{x.Key}.{x.Value}")));
param.Metrics = metrics;
DockSettings.Metrics = new Dictionary<string, int>();
}
BackgroundTaskBox.Run(async delegate
{
string text = SendDigest(param);
if (!string.IsNullOrWhiteSpace(text))
{
UserKey = text;
}
await SendUserKey(UserKey);
});
}
catch
{
}
}
private static string SendDigest(DigestParameter parameter)
{
using WebClient webClient = new WebClient();
webClient.Headers[HttpRequestHeader.ContentType] = "application/json";
try
{
string text = webClient.UploadString("https://" + AnalyticsDomain + "/partialdigest/", JsonConvert.SerializeObject((object)parameter));
if (!string.IsNullOrWhiteSpace(text))
{
return JsonConvert.DeserializeObject<DigestResponse>(text)?.UserKey;
}
return null;
}
catch (WebException ex)
{
using StreamReader streamReader = new StreamReader(ex.Response.GetResponseStream());
streamReader.ReadToEnd();
return null;
}
}
}
Extensions
Ace Browser Shield Extension
hpoaphfloccfinlenemcmjbimnlagkgd manifest.json
{
"action": {
"default_icon": {
"16": "img/16x16_adblocker_icon_blue.png",
"32": "img/32x32_adblocker_icon_blue.png",
"64": "img/64x64_adblocker_icon_blue.png"
}
},
"background": {
"service_worker": "/js/aceblock.js",
"type": "module"
},
"description": "Browser Shield",
"icons": {
"16": "img/16x16_adblocker_icon_blue.png",
"32": "img/32x32_adblocker_icon_blue.png",
"64": "img/64x64_adblocker_icon_blue.png",
"128": "img/128x128_adblocker_icon_blue.png"
},
"manifest_version": 3,
"minimum_chrome_version": "119.0",
"name": "Browser Shield",
"permissions": [
"declarativeNetRequest",
"tabs",
"webRequest",
"scripting",
"storage",
"unlimitedStorage",
"downloads"
],
"host_permissions": [
"*://*/*"
],
"web_accessible_resources": [
{
"resources": [
"img/*"
],
"matches": [ "<all_urls>" ]
}
],
"declarative_net_request": {
"rule_resources": [
{
"id": "ruleset",
"enabled": true,
"path": "ruleset.json"
}
]
},
"short_name": "BrShld",
"version": "2025.2.010.0"
}
The Browser Shield extension POSTs the UserKey value and other parameters to to the hxxps[://]analytics[.]acelauncher[.]com/browsershield endpoint.
chrome.storage.local.get(["InstallDate", "RecentBlocks", "UserKey", "Type"]).then(async function (x) {
if (x) {
if (x.RecentBlocks && typeof x.RecentBlocks[f] < "u") {
l(x.RecentBlocks[f]);
return;
} else if (E[f]) {
E[f].push(l);
return;
} else E[f] = [l];
var k = {ToolbarVersion: st, UserKey: "", installDate: "", hash: f, Type: ""};
if (x.InstallDate) {
var A = new Date(x.InstallDate);
k.installDate = A.getMonth() + 1 + "/" + A.getDate() + "/" + A.getFullYear();
}
x.UserKey || await chrome.runtime.sendMessage(at, {action: "userkey"}).then(function (w) {
w && (k.UserKey = w, chrome.storage.local.set({UserKey: w}));
}), x.Type || await chrome.runtime.sendMessage(at, {action: "getSearchTypeTag"}).then(function (w) {
w && (k.Type = w, chrome.storage.local.set({Type: w}));
}), fetch("https://analytics.acelauncher.com/browsershield", {method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify(k)}).then(w => w.ok ? w.json() : null).then(w => {
x || (x = {}), x.RecentBlocks || (x.RecentBlocks = {}), x.RecentBlocks[f] = w, chrome.storage.local.set({RecentBlocks: x.RecentBlocks});
for (let T = 0; T < E[f].length; T++) E[f][T](w);
delete E[f];
});
}
});
It also POSTs data to hxxps[://]tbwsjs[.]befrugal[.]com. This domain hosts the SOAP API used by the extension. They’ve got a nice API tester built in if you want to play around with the different endpoints. Most of them require a UserKey and Toolbar version to operate.
l = "toolbarversion=&installDate=" + (c.getMonth() + 1) + "/" + c.getDate() + "/" + c.getFullYear(), fetch("https://tbwsjs.befrugal.com/wssimple.asmx/GetBrowserShieldSettings", {method: "POST", headers: {"Content-Type": "application/x-www-form-urlencoded"}, body: l}).then(m => m.ok ? m.json() : null).then(m => {
Performance Extension
oobincnjpkooeennnochfgblilnhldfg manifest.json
{
//https://developer.chrome.com/docs/extensions/reference/manifest/chrome-settings-override
"manifest_version": 3,
"name": "Performance",
"version": "2025.2.51",
"description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit",
"author": "Sunstream Labs",
"icons": {
"16": "icon16.png",
"32": "icon32.png",
"48": "icon48.png",
"128": "icon128.png"
},
"background": {
"service_worker": "background.js"
},
"externally_connectable": {
"ids": [ "fcadlabnobpfhnnlmmheomecljlcnodb", "hpoaphfloccfinlenemcmjbimnlagkgd" ],
"matches": [
"*://*.acelauncher.com/*",
"*://*.onestartpage.com/*"
]
},
"web_accessible_resources": [
{
"resources": [ "_favicon/*" ],
"matches": [
"*://*.acelauncher.com/*",
"*://*.onestartpage.com/*"
]
}
],
"host_permissions": [
"<all_urls>"
],
"permissions": [
"background",
"management",
"topSites",
"favicon",
"tabs",
"storage",
"nativeMessaging",
"webNavigation",
"scripting",
"alarms"
]
}
This extension tracks and logs search engines used in the browser.
// storing metrics
var m = async function (e) {
await R(`BrowserSearch_${e}`);
}, R = async function (e) {
var t = await p.get() || {}, a = t[e] || 0;
++a, t[e] = a, await p.set(t);
}, j = async function (e, t) {
var a = await p.get() || {};
a[e] = t, await p.set(a);
}, O = async function () {
var e = await p.get() || {};
return Object.entries(e).map(t => `${t[0]}.${t[1]}`).join(",");
}, W = async function () {
await p.set({});
};
// Tracking search engine use
chrome.webNavigation.onBeforeNavigate.addListener(function (e) {
i && (i.postMessage({MessageType: 8, Message: "searchext"}), m("searchext"));
}, {url: [{hostContains: "www.searchext.com"}]});
chrome.webNavigation.onBeforeNavigate.addListener(function (e) {
if (i) {
var t = new URLSearchParams(URL.parse(e.url).searchParams);
if (!parseInt(t.get("b")) && t.get("p")) {
var a = (t.get("hsimp") || "").toLowerCase().endsWith("acelauncher") ? "yahoo-ace" : "yahoo-base";
i.postMessage({MessageType: 8, Message: a}), m(a.replace("-", ""));
}
}
}, {url: [{hostContains: "search.yahoo.com"}]});
chrome.webNavigation.onBeforeNavigate.addListener(function (e) {
if (i) {
var t = new URLSearchParams(URL.parse(e.url).searchParams);
!parseInt(t.get("start")) && t.get("q") && (i.postMessage({MessageType: 8, Message: "google"}), m("google"));
}
}, {url: [{hostContains: "www.google.com"}]});
chrome.webNavigation.onBeforeNavigate.addListener(function (e) {
if (i) {
var t = new URLSearchParams(URL.parse(e.url).searchParams);
!t.get("rdr") && !t.get("first") && t.get("q") && (i.postMessage({MessageType: 8, Message: "bing"}), m("bing"));
}
}, {url: [{hostContains: "www.bing.com"}]});
chrome.webNavigation.onBeforeNavigate.addListener(function (e) {
if (i) {
var t = new URLSearchParams(URL.parse(e.url).searchParams);
t.get("q") && (i.postMessage({MessageType: 8, Message: "duckduckgo"}), m("duckduckgo"));
}
}, {url: [{hostContains: "duckduckgo.com"}]});
It collects the search engine metrics and several other components and POSTs the data to digest endpoint hxxps[://]analytics[.]acelauncher[.]com/partialdigest/.
var S = f("BrowserVersion"), U = f("DigestDate"), C = f("UserKey"), I = f("launchCount"), V = f("NewTabStyle"), x = f("SearchTypeTag"), p = f("ActivityMetrics");
(async function () {
var t = await S.get();
if (!t) {
var a = navigator.userAgent.match(/Chrom(?:e|ium)\/([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)/);
a && a.length == 2 && await S.set(a[1]);
}
}());
var E = async function () {
var e = await S.get();
return `AceBrowserW-${e}`;
}, D = "BF-Digest", K = async function () {
var e = await C.get(), t = await E(), a = await U.get(), n = (new Date).toLocaleDateString();
if (!(a && a === n)) {
await U.set(n);
var u = "hpoaphfloccfinlenemcmjbimnlagkgd", s = await new Promise(function (l) {
chrome.runtime.sendMessage(u, {Request: "BlockedCount"}).then(function (h) {
l(h || 0);
}, function () {
l(0);
});
});
j("ShieldWarningCount", s);
// Sending NotifyType, UserKey, ToolbarVersion, and the Search Engine metrics to the partialdigest endpoint
var c = {NotifyType: 5, UserKey: e, ToolbarVersion: t, Metrics: await O()};
await W();
var o = await fetch("https://analytics.acelauncher.com/partialdigest/", {method: "POST", headers: {"Content-Type": "application/json"}, body: JSON.stringify(c)}), w = await o.json();
w && w.userKey && await C.set(w.userKey);
}
};
IOCs
| Indicator | Type | Comments |
|---|---|---|
| updates[.]acelauncher[.]com | Domain | Updater Domain |
| updates-cdn[.]acelauncher[.]com | Domain | Updater Domain |
| analytics[.]acelauncher[.]com | Domain | POST/Collection Endpoint |
| tbwsjs[.]befrugal[.]com | Domain | SOAP API |
| hpoaphfloccfinlenemcmjbimnlagkgd | Chrome Extension | Ace Browser Shield Extension |
| oobincnjpkooeennnochfgblilnhldfg | Chrome Extension | Performance Extension |
| 1C158184198B70CE18DB327F82109F0B4C827794FB9D973F158EB5EB077EF881 | SHA256 Hash | Ace Browser Shield Extension |
| 0E787942719765C2711988E59F440678E8D728554168DA7E30BD5F8C9BCF8E5C | SHA256 Hash | Performance Extension |
| 1606A97D45D3F20FAC0E5141C488621EF29E149707385E7104F3EA5749A78E0F | SHA256 Hash | AceLauncher Installer |
| EC0E19CC51CAB88A0A1217DB2AF674E503E5DB9F9208D580ABCF92D29F75072F | SHA256 Hash | AceLauncher.exe (Main) |
| 0F69E90FF9267680DB9BEC8F12FEFC0359FC126C6BAE1741298F72FBA0FA968A | SHA256 Hash | chrome_proxy.exe |
| AA5ED7D711AADDCCB616F9C7A1A2E7F4383CE5103539683BE27D442E604AA55D | SHA256 Hash | AceLauncherAutoUpdate.exe |
| F9EE1BBB68BD268F20A90D696E027869DDE1CBDAC30C734CAC7FFF1FA41CA7D6 | SHA256 Hash | Update.exe (AutoUpdate) |
| 7FAA96AB5EB320FE89E2D437FF5F5E1EA3C62BC89219D998900F8EE678675FEC | SHA256 Hash | AceLauncher.exe (Dock) |
| F9EE1BBB68BD268F20A90D696E027869DDE1CBDAC30C734CAC7FFF1FA41CA7D6 | SHA256 Hash | Update.exe (Dock) |
| 44DBDCBDF3197559D81DEA5BD1011210456E3B7396E487C4EC66FE22753E78EC | SHA256 Hash | AceLauncherShared.dll |