Frida Tutorial 2

htARTE (HackTricks AWS Red Team 전문가)로부터 AWS 해킹을 처음부터 전문가까지 배우세요

버그 바운티 팁: 해커들에 의해 만들어진 프리미엄 버그 바운티 플랫폼Intigriti에 가입하세요! 오늘 https://go.intigriti.com/hacktricks에서 참여하여 최대 $100,000의 바운티를 받아보세요!

이 글은 다음 글의 요약입니다: https://11x256.github.io/Frida-hooking-android-part-2/ (파트 2, 3 및 4) APK 및 소스 코드: https://github.com/11x256/frida-android-examples

파트 1은 매우 쉽습니다.

일부 원본 코드는 작동하지 않고 여기서 수정되었습니다.

파트 2

여기서 동일한 이름을 가진 2개의 함수를 후킹하는 예제를 볼 수 있습니다. 또한, 자체 매개변수로 함수를 호출하는 방법을 배우게 될 것입니다. 마지막으로, 클래스의 인스턴스를 찾아 함수를 호출하도록 만드는 예제가 있습니다.

//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 () { }
});
});

당신은 String을 생성하기 위해 먼저 java.lang.String 클래스를 참조하고, 그 클래스의 String 내용을 가진 $new 객체를 생성했다는 것을 볼 수 있습니다. 이것은 클래스의 새 객체를 생성하는 올바른 방법입니다. 그러나 이 경우에는 this.fun("hey there!")와 같이 어떤 String이든 this.fun()에 전달할 수 있습니다.

파이썬

//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

파이썬

이제 훅된 앱으로 명령을 보내어 함수를 호출하는 방법을 파이썬을 통해 살펴보겠습니다:

//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

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

여기서는 JSON 객체를 사용하여 Python과 JS가 상호 작용하는 방법을 살펴볼 것입니다. JS는 데이터를 Python 클라이언트로 보내기 위해 send() 함수를 사용하고, Python은 데이터를 JS 스크립트로 보내기 위해 post() 함수를 사용합니다. JS는 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

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/

버그 바운티 팁: Intigriti에 가입하여 해커들을 위해 만들어진 프리미엄 버그 바운티 플랫폼에 참여하세요! https://go.intigriti.com/hacktricks에서 오늘부터 최대 $100,000의 바운티를 받아보세요!

htARTE (HackTricks AWS Red Team Expert)를 통해 **제로부터 히어로까지 AWS 해킹을 배우세요**!

Last updated