# 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) 파트 1은 매우 쉽습니다. **원본 코드의 일부는 작동하지 않으며 여기에서 수정되었습니다.** ## Part 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 ``` ## Part 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, } ``` ## Part 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}}