Reverse-engineering a camera bug
My old phone got died on me... sad, I know. It was time to give up on it. So, finally I bought a new phone, transitioned from a vintage iPhone to modernish Sony phone.
It was a Sony xperia 1 mark III. One of the first things I did was installing some apps including the camera app called VWFNDR™ + MBL. Since it's a camera app, I tried to click an image. But it failed, it only showed a black screen instead. I looked everywhere for this issue and possible fix. Unfortunatly I couldn't find any fix. That made me think that "Why me?" and that thought got transitioned into "Is it a bug? glitch? or some permission issue?" and the deeper I dived into the camera app's permission and possible issues, I doubted it'll be it's camera2 or HAL.
Then I did what a normal person would do in my shoes, I plugged into ADB and looked into the logs while playing with that app. The ADB output was this:
18:52:40.164 CaptureEngine: Capture starts for capture id=1
18:52:40.190 camera-hal: Unsupported noise reduction mode 3.
18:52:40.190 camera-hal: validateCaptureSettings failed.
18:52:40.190 camera-hal: Invalid settings for capture.
18:52:40.190 VendorSomcCamDevSession: HAL process_capture_request call failed!
18:52:40.191 Camera3-Device: Unable to submit capture request 74 to HAL device: Invalid argument (-22)
18:52:40.191 Camera2ClientBase: Camera 0: start to disconnect
after that, the app dies:
18:52:53.150 ActivityManager:
Scheduling restart of crashed service
com.vwfndr.mbl/org.chromium.content.app.SandboxedProcessService0:0
18:52:53.166 Camera2ClientBase:
Camera 0: start to disconnect
18:52:53.166 Camera2ClientBase:
Closed Camera 0. Client was: com.vwfndr.mbl
18:52:53.168 WindowManager:
WIN DEATH: Window{... com.vwfndr.mbl/com.vwfndr.mbl.MainActivity}
Well, if this scares you, lemme explain... I clicked the shutter -> app requests to Camera2 -> request reaches Sony's camera HAL. And after that, Sony checks the request and saw
NOISE_REDUCTION_MODE = 3
And the app crashed. Why? well, my phone doesn't support NOISE_REDUCTION_MODE = 3, it only supports 0, 1 and 2.
Usually android allows 5 modes:
| Value | Mode | Meaning |
|---|---|---|
0 |
OFF |
No noise reduction |
1 |
FAST |
Noise reduction without reducing sensor frame rate |
2 |
HIGH_QUALITY |
Higher-quality noise reduction, may reduce frame rate |
3 |
MINIMAL |
Basic raw-domain noise reduction, mainly for artifacts |
4 |
ZERO_SHUTTER_LAG |
Different NR levels depending on output stream |
But not all phones support all modes. Mine doesn't support 3 and it crashed. Just because of an integer.
How deep the rabbit hole goes?
Ofcourse, I found the issue. I should report it to them, right..? But my ADHD brain told me to go further and make sure it is the real issue and I am not hallucinating like Google's Gemini.
I did what a normal person would do, I reverse engineered the app.
I pulled the apk through ADB and decompiled it:
apktool d base.apk -o apktool-out
jadx -d jadx-out base.apk
Located the camera configuration in CaptureConfigurator and changed the 3 into 2.
NOISE_REDUCTION_MODE = 3
Rebuilt and signed the APK, then installed the patched build.
Obstacles...
It should be working, atleast theoretically...
But there was a Google Play licensing check. It means, I can't use the app if I didn't installed it from play store directly. It's a way of security.
So I decompiled it again and removed the check. I am not gonna say how...
And then eurekaaa... It worked and didn't crashed. The capture worked perfectly fine.
They didn't sue me (thankfully)
I reached out to them explaining that some devices like mine doesnt support NOISE_REDUCTION_MODE = 3 and need to fallback into 2. Instead of suing me, they made me their alpha tester. And they fixed the code the same day and released the alpha version. I tested it and worked perfectly.