Comments 35
Приятно видеть людей которые безвозмездно делают мир чуточку лучше.
Надо было баг-репорт отправлять прям на dmitriyap.dyndns.org, разработчики немного бы удивились :)
В момент исследования dmitriyap.dyndns.org был в глухом офлайне :) Да и моей целью было не показать разработчикам Яндекс.Денег какой я типа крутой хакер, а помочь сделать их продукт чуть лучше. Вроде получилось :)
Если Вы о конкурсе «Охота за ошибками», то Яндекс.Деньги в нем не участвуют (странно, да?). Так что нет, награды мне не будет. Ну да мне и плевать если честно )
В конкурсе Яндекс.Деньги уже участвуют. Но вот мобильные приложения Денег, пока нет, к сожалению.
Я не очень понимаю, любой нормальный компилятор отбрасывает неиспользуемый код, попутно выводя warning. Чей косяк, Android SDK, JDK?
Или этот метод всё же где-то вызывается...? Поэтому в версии 1.80 весь код и обсфуцировали. (Пробую найти теорию заговора ))
Думаю этот код не был отброшен из-за (пишу псевдокодом, так короче и понятнее, кому интересно — сам посмотрит как это выглядит в Smali):

public class CoreApplication implements LocationListener {
 
  // ...неинтересный код был тут

  public static CoreApplication getCoreApplication() {
    if (coreApplication == null)
      throw new RuntimeException("here CoreApplication must exists!");
    return coreApplication;
  }
  
  private static void onNativeCrashed() {
    Class localClass = getCoreApplication().params.getCrashHandlerClass();
    if ((localClass != null) && (!getAppBuildIdFromNative().contains("master_market"))) {
      new RuntimeException("crashed here (native trace should follow after the Java trace)");
      new StringBuilder("App name is ").append(getAppNameFromNative());
      new StringBuilder("Build ID is ").append(getAppBuildIdFromNative());
      if (getAppBuildIdFromNative().length() > 32)
        applicationContext.startActivity(new Intent(applicationContext, localClass).setFlags(268435456));
    }
	
	// ...неинтересный код был тут
}

Обратите внимание на метод onNativeCrashed(). Он вызывается при краше native библиотеки которая работает с Яндекс.Картами. Метод получает класс, унаследованный от CrashHandler (в котором и как раз и живет тот самый безобразный метод sendBug(String paramString)) путём вызова

Class localClass = getCoreApplication().params.getCrashHandlerClass();

Если класс получен успешно (см. дальше условия if ((localClass != null)...) и если native-библиотека которая отвечает за взаимодействие с Яндекс.Картами вернула правильный пароль :) — стартует activity, из которой потом можно будет вызвать этот самый гадкий sendBug(String paramString).

Но есть одно «но»! Если посмотреть на метод getCrashHandlerClass(), то мы увидим что он всегда возвращает null:

public class MapsCoreApplicationParams extends CoreApplicationParams
{
  // ...ля-ля-ля, не важно
  
  public Class getCrashHandlerClass()
  {
    return null;
  }
  
  // ...ля-ля-ля, тоже не важно
}

Поэтому класс никогда не будет получен, а следовательно activity не стартует и метод sendBug(String paramString) никогда не будет вызван. Как видите, тут все запутано как бразильском сериале :) Думаю поэтому компилятор не смог до конца вкурить все эти связи и стремный код на всякий случай оставил.

Я не стал включать все эти исследования в статью — решил ограничится общей фразой про то что мол тщательное исследование кода приложения заставляет думать что ля-ля-ля…
Возможно, нормальный компилятор так и делает, если это сильно связанный код, но писать такой код сейчас не принято.
А принимать решение за разработчика, и выкидывать public и protected методы нормальный компилятор не должен.
Возможную причину я написал выше, но может Вы и правы — дело действительно в том, что Java не склонна выкидывать public и protected методы. Честно говоря точно не знаю.
Компилятор в принципе не может определить, вызывается ли метод. По причине Reflection например в случае Явы. Неиспользуемый код убирается только в пределах одного метода (и то бывает чревато).
Хм, а в SDK нет штатного механизма отправки багрепортов? Мне кажется довольно логичным иметь возможность получить из системных логов все записи своего приложения за предыдущие N минут, и как-то через гугель закинуть их разработчику приложив к traceback'у с места падения.

Видимо яндекс решил не делиться с гуглем незашифрованными персональными данными в логах.
данные перед отправкой в штатный механизм можно и зашифровать, не должно быть проблемой.
Вроде бы тоже даёт (ну по крайней мере нужный твиттер в первой десятке). Но с Google у меня как-то лучше любовь складывается, поэтому пользуюсь в основном им :)
Извиняюсь, проглядел абзац, мне показалось, что вы работаете в Яндексе. Троллинг не получился.
Нет, я свободный художник. Если бы я работал в Яндексе, то наверное я бы имел исходный код этого приложения и не было бы смысла заморачиваться с дизассемблированием и дебаггингом. Но так даже лучше — без исходного кода ковырять программу интереснее :)
Да, он. Помнится, там ещё во время взлома какая-то девушка хакеру делала мине… ну в общем отвлекала хакера от процесса :)
UFO landed and left these words here
UFO landed and left these words here
Это была не Хэлли Берри, кстати;)
Там какая то другая белая подружка глав террориста была.
*чёрт, какую же фигню мой мозг помнит*
В «Социальной сети», помнится, конкурс для программистов включал работу после выпивания спиртного.

Осталось объединить идеи :)
Так вот для чего каждое второе приложение из гуглплея хочет смотреть логкат. Правда я такие приложения все равно не ставлю.
Ну в logcat логе только системный лог (например такая-то activity стартовала, такой-то процесс завершился и т.п.) и то что приложения сами пишут туда с помощью методов из android.util.Log. По идее приложение не должно писать в лог никакой конфиденциальной информации, но на практике разработчики часто используют методы из android.util.Log в процессе разработки с целью отладки, а потом забывают убрать вызовы этих методов из релиза. Я подозреваю что с Яндекс.Деньгами 1.71 так и получилось. В версии 1.80 это пофиксили.
Дима, напишите мне в личку или по job.rabota@gmail.com есть вопрос, а то не могу найти контактных данных в профиле. Спасибо
Only those users with full accounts are able to leave comments. Log in, please.