209 lines
7.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Frida Tutorial 2
{{#include ../../../banners/hacktricks-training.md}}
**Це резюме посту**: [https://11x256.github.io/Frida-hooking-android-part-2/](https://11x256.github.io/Frida-hooking-android-part-2/) (Частини 2, 3 та 4)\
**APKs та вихідний код**: [https://github.com/11x256/frida-android-examples](https://github.com/11x256/frida-android-examples)
Перша частина дуже проста.
**Деякі частини оригінального коду не працюють і були змінені тут.**
## Частина 2
Тут ви можете побачити приклад того, як **перехопити 2 функції з однаковою назвою** але з різними параметрами.\
Також ви дізнаєтеся, як **викликати функцію з вашими власними параметрами**.\
І нарешті, є приклад того, як **знайти екземпляр класу і змусити його викликати функцію**.
```javascript
//s2.js
console.log("Script loaded successfully ");
Java.perform(function x() {
console.log("Inside java perform function");
var my_class = Java.use("com.example.a11x256.frida_test.my_activity");
//Hook "fun" with parameters (int, int)
my_class.fun.overload("int", "int").implementation = function (x, y) { //hooking the old function
console.log("original call: fun(" + x + ", " + y + ")");
var ret_value = this.fun(2, 5);
return ret_value;
};
//Hook "fun" with paramater(String)
var string_class = Java.use("java.lang.String");
my_class.fun.overload("java.lang.String").implementation = function (x) { //hooking the new function
console.log("*")
//Create a new String and call the function with your input.
var my_string = string_class.$new("My TeSt String#####");
console.log("Original arg: " + x);
var ret = this.fun(my_string);
console.log("Return value: " + ret);
console.log("*")
return ret;
};
//Find an instance of the class and call "secret" function.
Java.choose("com.example.a11x256.frida_test.my_activity", {
onMatch: function (instance) {
console.log(tring, and the it has"Found instance: " + instance);
console.log("Result of secret func: " + instance.secret());
},
onComplete: function () { }
});
});
```
Ви можете побачити, що для створення рядка спочатку було посилання на клас _java.lang.String_, а потім було створено об'єкт _$new_ цього класу з рядком як вмістом. Це правильний спосіб створення нового об'єкта класу. Але в цьому випадку ви могли б просто передати в `this.fun()` будь-який рядок, наприклад: `this.fun("hey there!")`
### Python
```python
//loader.py
import frida
import time
device = frida.get_usb_device()
pid = device.spawn(["com.example.a11x256.frida_test"])
device.resume(pid)
time.sleep(1) #Without it Java.perform silently fails
session = device.attach(pid)
script = session.create_script(open("s2.js").read())
script.load()
#prevent the python script from terminating
raw_input()
```
```
python loader.py
```
## Частина 3
### Python
Тепер ви побачите, як надсилати команди до підключеного додатку через Python для виклику функції:
```python
//loader.py
import time
import frida
def my_message_handler(message, payload):
print message
print payload
device = frida.get_usb_device()
pid = device.spawn(["com.example.a11x256.frida_test"])
device.resume(pid)
time.sleep(1) # Without it Java.perform silently fails
session = device.attach(pid)
with open("s3.js") as f:
script = session.create_script(f.read())
script.on("message", my_message_handler)
script.load()
command = ""
while 1 == 1:
command = raw_input("Enter command:\n1: Exit\n2: Call secret function\n3: Hook Secret\nchoice:")
if command == "1":
break
elif command == "2":
script.exports.callsecretfunction()
elif command == "3":
script.exports.hooksecretfunction()
```
Команда "**1**" **вийде**, команда "**2**" знайде і **екземпляр класу та викличе приватну функцію** _**secret()**_, а команда "**3**" **перехопить** функцію _**secret()**_, щоб вона **повертала** **інший рядок**.
Отже, якщо ви викликаєте "**2**", ви отримаєте **справжній секрет**, але якщо ви спочатку викликаєте "**3**", а потім "**2**", ви отримаєте **фальшивий секрет**.
### JS
```javascript
console.log("Script loaded successfully ")
var instances_array = []
function callSecretFun() {
Java.perform(function () {
if (instances_array.length == 0) {
// if array is empty
Java.choose("com.example.a11x256.frida_test.my_activity", {
onMatch: function (instance) {
console.log("Found instance: " + instance)
instances_array.push(instance)
console.log("Result of secret func: " + instance.secret())
},
onComplete: function () {},
})
} else {
//else if the array has some values
console.log("Result of secret func: " + instances_array[0].secret())
}
})
}
function hookSecret() {
Java.perform(function () {
var my_class = Java.use("com.example.a11x256.frida_test.my_activity")
var string_class = Java.use("java.lang.String")
my_class.secret.overload().implementation = function () {
var my_string = string_class.$new("TE ENGANNNNEEE")
return my_string
}
})
}
rpc.exports = {
callsecretfunction: callSecretFun,
hooksecretfunction: hookSecret,
}
```
## Частина 4
Тут ви побачите, як **Python і JS взаємодіють** за допомогою об'єктів JSON. JS використовує функцію `send()` для відправки даних до клієнта Python, а Python використовує функцію `post()` для відправки даних до скрипта JS. **JS заблокує виконання** до отримання відповіді від Python.
### Python
```python
//loader.py
import time
import frida
def my_message_handler(message, payload):
print message
print payload
if message["type"] == "send":
print message["payload"]
data = message["payload"].split(":")[1].strip()
print 'message:', message
data = data.decode("base64")
user, pw = data.split(":")
data = ("admin" + ":" + pw).encode("base64")
print "encoded data:", data
script.post({"my_data": data}) # send JSON object
print "Modified data sent"
device = frida.get_usb_device()
pid = device.spawn(["com.example.a11x256.frida_test"])
device.resume(pid)
time.sleep(1)
session = device.attach(pid)
with open("s4.js") as f:
script = session.create_script(f.read())
script.on("message", my_message_handler) # register the message handler
script.load()
raw_input()
```
### JS
```javascript
console.log("Script loaded successfully ")
Java.perform(function () {
var tv_class = Java.use("android.widget.TextView")
tv_class.setText.overload("java.lang.CharSequence").implementation =
function (x) {
var string_to_send = x.toString()
var string_to_recv = ""
send(string_to_send) // send data to python code
recv(function (received_json_object) {
string_to_recv = received_json_object.my_data
}).wait() //block execution till the message is received
console.log("Final string_to_recv: " + string_to_recv)
return this.setText(string_to_recv)
}
})
```
Є частина 5, яку я не буду пояснювати, оскільки там немає нічого нового. Але якщо ви хочете прочитати, вона тут: [https://11x256.github.io/Frida-hooking-android-part-5/](https://11x256.github.io/Frida-hooking-android-part-5/)
{{#include ../../../banners/hacktricks-training.md}}