Found a free piano app in the app store and removed Google ads through reverse engineering.
Difficulty
★★☆☆☆
Tools and Environment
- Jailbroken iOS 14.4
- frida-ios-dump
- frida
- frida-trace
- IDA 7.7
- reveal
Analysis Approach
There are many methods to remove ads within an app.
- Use IDA to analyze the maco file, locate the ad code, and remove it directly.
- Use frida to hook network requests and intercept ad requests.
- Use reveal to analyze the app’s UI and hide the ad view.
- Intercept and redirect domain resolution requests.
Analyzing Ad Code with IDA
After decrypting the app, load it into IDA and search for ad-related keywords like “adver” in the function list.

From the method name, we can infer that createAdvertisementBannerView is the method for creating the ad view.

Check cross-references to analyze the upper-level calling functions.

The upper-level function contains many operations including class initialization, method calls, object property access, and some memory management operations (like objc_retain and objc_release).
- Create an AdvertisementIdentifiers object and initialize it with multiple parameters.
- Create an AdvertisementBannerViewConfiguration object.
- Get the app’s delegate, possibly to obtain the root view controller.
- Use the AdvertisementManager class to create an ad banner view (BannerView).
- Based on certain conditions, get the main screen size of the app and set it to the ad banner view (BannerView).

Replacing Ad Loading Function with frida
var baseAddr = Module.findBaseAddress('ThePiano'); console.log("The Piano base address: " + baseAddr); var targetFunctionAddr = baseAddr.add(0x6E854); console.log("Target function address: " + targetFunctionAddr); const targetFunction = new NativeFunction(targetFunctionAddr, 'void', []); Interceptor.replace(targetFunctionAddr, new NativeCallback(function () { console.log("Skipping ad loading at offset 0x6E854"); }, 'void', [])); const targetFunctionAddrRootVC = baseAddr.add(0x864A8); Interceptor.attach(targetFunctionAddrRootVC, { onEnter: function (args) { console.log('Entering the calling function of the ad loading function'); }, onLeave: function (retval) { console.log('Exiting the calling function of the ad loading function'); } });
The effect is as follows:
frida -U -f com.impalastudios.pianofree -l piano.js
Analyzing Ad UI with reveal
Enable debugging in the reveal settings.

Then connect the jailbroken iPad to the Mac.

Hide the ad view in reveal.

Intercepting Domain Resolution Requests with frida-trace
frida-trace -U -f com.impalastudios.pianofree -i "getaddrinfo"
Intercept the domain resolution within the app and redirect it to 127.0.0.1. Modify the frida-trace script as follows:
{ onEnter(log, args, state) { var hostname = Memory.readUtf8String(args[0]); // log('Intercepted call to getaddrinfo for ' + hostname); // Redirect if the domain contains 'google' if (hostname.includes('google')) { log('Redirecting request for ' + hostname + ' to 127.0.0.1'); args[0] = Memory.allocUtf8String('127.0.0.1'); } }, onLeave(log, retval, state) { } }
