Reversing Snapchat – Pressure Cooker Hidden Code?

So I was screwing around with Android app hacking and I figured the Snapchat App for Android would be a cool read. While I was originally more interested in reversing the app and making a script to automate Snapchat it turns out someone has already done it: https://github.com/dstelljes/php-snapchat

Dang it!

The process was no a complete waste however, as I stumbled upon something very weird…

Note: To get this source for yourself you’ll need to get the Snapchat APK. Then use dex2jar to create a .jar file, now you can use a Java Decompiler to view the source (in Java). This is possible because Java compiles into bytecode (an intermediary language) and not into machine code.

If you check under the “ui” package:

Selection_024

You’ll notice this:

Selection_023

 

Here is the weird code I’ve found:

package com.snapchat.android.ui;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Build.VERSION;
import android.preference.PreferenceManager;
import android.view.MotionEvent;
import com.WazaBe.HoloEverywhere.widget.Toast;
import com.snapchat.android.util.ApiHelper;

public class PressureCooker
{
  private static final float MAX_OUTPUT = 40.0F;
  private static final float MIN_OUTPUT;
  private Context mContext;
  private CropProcessor mPressureProcessor;
  private LowpassProcessor mSizeProcessor;

  public PressureCooker(Context paramContext)
  {
    this.mContext = paramContext;
    SharedPreferences localSharedPreferences = PreferenceManager.getDefaultSharedPreferences(paramContext);
    this.mPressureProcessor = new CropProcessor(localSharedPreferences.getFloat("HISTORICAL_LOW_PRESSURE", (0.0F / 0.0F)), localSharedPreferences.getFloat("HISTORICAL_HIGH_PRESSURE", (0.0F / 0.0F)));
    this.mSizeProcessor = new LowpassProcessor(localSharedPreferences.getFloat("HISTORICAL_LOW_SIZE", (0.0F / 0.0F)), localSharedPreferences.getFloat("HISTORICAL_HIGH_SIZE", (0.0F / 0.0F)));
  }

  private float lerp(float paramFloat1, float paramFloat2, float paramFloat3)
  {
    return paramFloat1 * (1.0F - paramFloat3) + paramFloat3 * paramFloat2;
  }

  public float getFiltered(MotionEvent paramMotionEvent)
  {
    if ((Build.VERSION.SDK_INT >= 14) && (paramMotionEvent.getToolType(0) == 2));
    for (float f = this.mPressureProcessor.getFiltered(paramMotionEvent.getPressure()); ; f = this.mSizeProcessor.getFiltered(paramMotionEvent.getSize()))
      return lerp(0.0F, 40.0F, f * (f * f));
  }

  public float getHistoricalFiltered(MotionEvent paramMotionEvent, int paramInt)
  {
    if ((Build.VERSION.SDK_INT >= 14) && (paramMotionEvent.getToolType(0) == 2));
    for (float f = this.mPressureProcessor.getFiltered(paramMotionEvent.getHistoricalPressure(paramInt)); ; f = this.mSizeProcessor.getFiltered(paramMotionEvent.getHistoricalSize(paramInt)))
      return lerp(0.0F, 40.0F, f * (f * f));
  }

  public void onPause()
  {
    SharedPreferences.Editor localEditor = PreferenceManager.getDefaultSharedPreferences(this.mContext).edit();
    localEditor.putFloat("HISTORICAL_LOW_PRESSURE", this.mPressureProcessor.mLowestInput);
    localEditor.putFloat("HISTORICAL_HIGH_PRESSURE", this.mPressureProcessor.mHighestInput);
    localEditor.putFloat("HISTORICAL_LOW_SIZE", this.mSizeProcessor.mLowestInput);
    localEditor.putFloat("HISTORICAL_HIGH_SIZE", this.mSizeProcessor.mHighestInput);
    ApiHelper.safeSharedPreferencesSave(localEditor);
  }

  public void resetLowPassFilter()
  {
    LowpassProcessor.access$002(this.mSizeProcessor, (0.0F / 0.0F));
  }

  private class CropProcessor
  {
    private static final float DEFAULT_VALUE = 0.01F;
    private static final int INITIALIZATION_SAMPLES = 400;
    public float mHighestInput;
    public float mLowestInput;
    private int mNeededSamples;

    public CropProcessor(float paramFloat1, float arg3)
    {
      this.mLowestInput = paramFloat1;
      Object localObject;
      this.mHighestInput = localObject;
      this.mNeededSamples = 0;
    }

    public float getFiltered(float paramFloat)
    {
      if ((this.mLowestInput != this.mLowestInput) || (this.mHighestInput != this.mHighestInput))
      {
        this.mLowestInput = paramFloat;
        this.mHighestInput = paramFloat;
        this.mNeededSamples = 400;
        Toast.makeText(PressureCooker.this.mContext, 2131624111, 1).show();
      }
      float f1;
      if (paramFloat < this.mLowestInput)
      {
        this.mLowestInput = paramFloat;
        f1 = (paramFloat - this.mLowestInput) / (this.mHighestInput - this.mLowestInput);
        if (f1 <= 1.0F)
          break label152;
        f1 = 1.0F;
      }
      while (true)
      {
        if (this.mNeededSamples > 0)
        {
          this.mNeededSamples = (-1 + this.mNeededSamples);
          float f2 = this.mNeededSamples / 400.0F;
          f1 = 0.01F * f2 + f1 * (1.0F - f2);
        }
        return f1;
        if (paramFloat <= this.mHighestInput)
          break;
        this.mHighestInput = paramFloat;
        break;
        label152: if (f1 < 0.0F)
          f1 = 0.0F;
      }
    }
  }

  private class LowpassProcessor extends PressureCooker.CropProcessor
  {
    private static final float LOWPASS_RATE = 0.1F;
    private float mOldVal = (0.0F / 0.0F);

    public LowpassProcessor(float paramFloat1, float arg3)
    {
      super(paramFloat1, localObject);
    }

    public float getFiltered(float paramFloat)
    {
      if (this.mOldVal != this.mOldVal)
        this.mOldVal = paramFloat;
      for (float f = this.mOldVal; ; f = this.mOldVal)
      {
        return super.getFiltered(f);
        this.mOldVal = (0.9F * this.mOldVal + 0.1F * paramFloat);
      }
    }
  }
}

To make things even more weird it’s not reference or used anywhere!

Seriously. It’s just a random class that’s never actually used anywhere:

Not sure what to think about this, I’ve put it here to see if anyone else reverses the Snapchat app and Googles this code ;). If you are reversing the code and have more info please let me know in the comments or personally as I’m interested as to why this is here at all.

Until next time,

-mandatory

Matthew Bryant (mandatory)

Matthew Bryant (mandatory)
Security researcher who needs to sleep more. Opinions expressed are solely my own and do not express the views or opinions of my employer.