• XSS.stack #1 – первый литературный журнал от юзеров форума

Редактирование обфусцированного кода в smali

cupcake

floppy-диск
Пользователь
Регистрация
24.12.2022
Сообщения
5
Реакции
0
Всем привет!
Реверсом занимаюсь относительно недавно.
В процессе попыток изменения smali кода, хотел добавить вывод данных на определённом моменте, но столкнулся с тем, что код обфусцирован и в нем наплодили большое количество переменных (я заметил это еще в декомпилировнных java классах, но тогда не придал этому значения, подумал, что так просто усложняют читаемость кода).

Как я узнал позднее, в smali есть ограничение на количество переменных. И они забиты по полной. Причем переодически в коде проиходят явно бессмысленные с точки зрения логики действия с ними (в основном математические), чтобы еще больше усложнить всё это дело.

Как новичку, можете посоветовать, в какую примерно сторону копать?
Также добавить функцию вывода в консоль, чтобы потом перехватить через adb также не получается, по той же причине.
 
Решение
Дам тебе несколько практических советов. Возможно тебе сгодится.

Совет #1. Если тебе мешает обфусцированный код, то всегда пробуй де-обфусцировать его.
К примеру, если твой код обфусцирован каким-нибудь бесплатным ProGuard от Android Studio, то его легко раскрутит практический любой деобфускатор.

Вот небольшой список бесплатных деобфускаторов:





Совет #2. Не рекомендуется (особенно когда ты новичек) внедрять в smali какой-либо код, при котором тебе придется инкрементировать количество переменных в методе или конструкторе.
Если тебе нужно что то...
Дам тебе несколько практических советов. Возможно тебе сгодится.

Совет #1. Если тебе мешает обфусцированный код, то всегда пробуй де-обфусцировать его.
К примеру, если твой код обфусцирован каким-нибудь бесплатным ProGuard от Android Studio, то его легко раскрутит практический любой деобфускатор.

Вот небольшой список бесплатных деобфускаторов:





Совет #2. Не рекомендуется (особенно когда ты новичек) внедрять в smali какой-либо код, при котором тебе придется инкрементировать количество переменных в методе или конструкторе.
Если тебе нужно что то дополнительно внедрить в код приложения, то могу посоветовать 2 способа, которые более менее подойдут для новичка.

Первый способ - самый легкий. Создай проект и дай точно такое же название package, куда будешь внедрять свой код. Далее создаешь SomeClass и static метод.
Реализовываешь все, что тебе нужно именно в методе этого SomeClass. Далее достаешь SomeClass.smali, копируешь SomeClass.smali в соответствующую директорию подопытного приложения.

Допустим, ты хочешь вызвать SomeClass.doSomethig() в методе onCreate MainActivity

Код:
.method public onCreate(Landroid/os/Bundle;)V
    .locals 2

    invoke-super {p0, p1}, Lbla/bla/bla/SomeActivity;->onCreate(Landroid/os/Bundle;)V

    invoke-virtual {p0}, Lyour/app/packagename/SomeClass;->doSomethig()V   // вызов твоего метода
    
    return-void
.end method

invoke-virtual {p0}, Lyour/app/packagename/SomeClass;->doSomethig()V - вот так будет выглядить вызов твоего метода и тебе нет нужды инкрементировать locals.

p0 здесь означает контекст приложения и он будет this.

Второй способ немного сложнее. Ты можешь менять поведение приложения в рантайме с помощью Frida.

Тебе нужен Linux с adb, рутованный девайс и непосредственно настроить Frida. И тебе придется писать хуки для Frida на javascript 😀

Ниже приведу небольшой пример хука на javascript для логирования всех URL, к которым обращается приложение. Здесь внедряемся в библиотеку OkHttp и переписываем
ее метод okHttpClient.open().

JavaScript:
Java.perform(function() {
    var httpclient = Java.use ("com.squareup.okhttp.v_l_5_l .OkHttpClient");
    httpclient.open.overload("java.net.URL").implementation = function(url) {
        console.log("request url:");
        console.log(url.toString());
        return this.open(url);
    }
});
 
Решение
Find the eval function would be a good beginning no?
 
Дам тебе несколько практических советов. Возможно тебе сгодится.

Совет #1. Если тебе мешает обфусцированный код, то всегда пробуй де-обфусцировать его.
К примеру, если твой код обфусцирован каким-нибудь бесплатным ProGuard от Android Studio, то его легко раскрутит практический любой деобфускатор.

Вот небольшой список бесплатных деобфускаторов:





Совет #2. Не рекомендуется (особенно когда ты новичек) внедрять в smali какой-либо код, при котором тебе придется инкрементировать количество переменных в методе или конструкторе.
Если тебе нужно что то дополнительно внедрить в код приложения, то могу посоветовать 2 способа, которые более менее подойдут для новичка.

Первый способ - самый легкий. Создай проект и дай точно такое же название package, куда будешь внедрять свой код. Далее создаешь SomeClass и static метод.
Реализовываешь все, что тебе нужно именно в методе этого SomeClass. Далее достаешь SomeClass.smali, копируешь SomeClass.smali в соответствующую директорию подопытного приложения.

Допустим, ты хочешь вызвать SomeClass.doSomethig() в методе onCreate MainActivity

Код:
.method public onCreate(Landroid/os/Bundle;)V
    .locals 2

    invoke-super {p0, p1}, Lbla/bla/bla/SomeActivity;->onCreate(Landroid/os/Bundle;)V

    invoke-virtual {p0}, Lyour/app/packagename/SomeClass;->doSomethig()V   // вызов твоего метода
   
    return-void
.end method

invoke-virtual {p0}, Lyour/app/packagename/SomeClass;->doSomethig()V - вот так будет выглядить вызов твоего метода и тебе нет нужды инкрементировать locals.

p0 здесь означает контекст приложения и он будет this.

Второй способ немного сложнее. Ты можешь менять поведение приложения в рантайме с помощью Frida.

Тебе нужен Linux с adb, рутованный девайс и непосредственно настроить Frida. И тебе придется писать хуки для Frida на javascript 😀

Ниже приведу небольшой пример хука на javascript для логирования всех URL, к которым обращается приложение. Здесь внедряемся в библиотеку OkHttp и переписываем
ее метод okHttpClient.open().

JavaScript:
Java.perform(function() {
    var httpclient = Java.use ("com.squareup.okhttp.v_l_5_l .OkHttpClient");
    httpclient.open.overload("java.net.URL").implementation = function(url) {
        console.log("request url:");
        console.log(url.toString());
        return this.open(url);
    }
});
Спасибо большое за развёрнутый ответ!

И еще три доп вопросика)) (надеюсь, что не утомил.. возможно, спрашиваю очевидные вещи)

1. Конкретно в приложении, которое пытаюсь обработать, необходимые мне данные принимаются с помощью сокета JSSE. Если я правильно понимаю, сокет не обращается к какому-либо адресу при каждом запросе, а я остаюсь без лога с адресом:confused:. Это так?
2. Чтобы мне в итоге те же данные, что и приложение, но уже по моим запросам и в нужное мне время, мне явно прийдется создавать свою релизацию сокета. Для этого, если я прав, мне нужно получить данные, которые используются для подключения к сокету. До прочтения вашего ответа, я бы, скорее всего, пытался долбиться используя frida, но сейчас меня посетила другая мысль. Не лучше ли таким же образом самостоятельно переписать нужный класс в JSSE, либо дополнить его и настроить вывод именно таким образом?

Ну и третий, это уже, скорее не вопрос а рассуждение.
Когда я успешно (на мой взгляд), меня что-либо в smali, приложение не запускалось дальше определённой стадии, скорее всего именно глохло на моменте подключения по сокету, из-за несоответствия подписей или чего-то подобного. Нет ли возможности сделать копию подписи и не редактированного приложения и затем (в измененном) скармливать её для проверки? Или такую практику вообще не используют, а в основном реализуют свои классы, либо хуки?
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх