Frida 문법 정리

Frida 문법 정리


1 dexclassLoader.loadClass

dexclassLoader.loadClass.overload('java.lang.String').implementation = function(name){
  • 메모리에 적재할 class 호출
  • loadclass 함수중에 string 타입을 사용하는 함수를 후킹하겟따.
  • 만약에 loadclass overload안쓰고 쓰면 에러 나는데 그때 코드 다나오니까 그거보고 하면됨
  • implementation 쓸 때 리턴값있는지 암튼 확인하고 맞춰쓰기
  • implementation은 자바에서만 사용 가능
  • class를 계속 긁어옴 (for문이 자동으로 돌고잇다고생각하면댐)


2 this.

this.[본래 함수()]

  • implementation 사용시 에러남을 방지하기 위함
  • 다만 이걸 넣으면 함수 실행 후 이기때문에 일부 값이 바뀌어있을 수 있음


3 enumerateClassLoaders

Java.enumerateClassLoaders({
onMatch: function(class)
  • 현재 적재된 클래스를 긁어옴
  • dexclassLoader는 실시간으로 계속 긁어오지만 얘는 현재만.!
  • onMatch가 될 때까지 for문처럼 돌아감


4 onMatch / onComplete

onMatch / onComplete

  • onMatch는 오리지널 코드를 그대로 두고 앞에 코드를 추가할 수 있음 / 매개변수 출력 / 매개변수 조작
  • implementation은 소스 코드 내부를 완전히 뒤바꾼다는 점에서 onMatch와 차이가 있다.
  • onComplete 끝나기전에 리턴값 확인 / 소스코드 추가 / 리턴값 조작


5 enumerateClassLoadersSync

Java.enumerateClassLoadersSync()[N]

var classLoaderToUse = Java.enumerateClassLoadersSync()[2]; //Get another classloader
Java.classFactory.loader = classLoaderToUse; //Set the classloader to the correct one
var test = Java.classFactory.use("com.aaa.aaa");
test.z.overload('int','int').implementation = function(arg1, arg2){
  • Java.enumerateClassLoadersSync()[] 의 배열 내 값의 의미는 다음과 같다
  • [0] : main dex , [1]:library [2]: 추가된 dex
  • 이 중 [2] 자리가 차있따는건 뭔가 추가가 되었다는 의미이고 이 코드 상에서는 필요한 dex가 로드됨
  • 로드된 dex를 classfactory.loader에 로드한 후, com.aaa.aaa클래스를 사용하기 위해 test변수에 담는다
  • test.z(int a, int b) 함수를 오버로드 하여 후킹진행


6 Interceptor.attach

  • java는 메소드 패ㅣ키지명이 잘 나와있지만 C는 잘안나와있기 때문에 INTERCEPT 를 써서 주소값 기반으로 후킹을 주로 진행.(attach([주소값]))

Case1) 모듈명과 메소드명 알 때

Interceptor.attach("[Name.so]", "[method Name]")

Interceptor.attach("[Name.so]", "[method Name]"), {
onEnter: function(args) {
  • 모듈이름과 메소드명을 알아야 함 혹은 주소값을 정확히 알아야 함
  • 보통 C에다 건다.
  • 메소드 이름을 아는 것이 가장 조흠

Case2) 주소값 알 때

 Interceptor.attach(addr , {
        onEnter: function(args) {
           ...
        }
    });

Interceptor.attach(addr,callback)

  • addr은 후킹할 함수의 시작주소
  • callback은 attch 칙후 실행할 실제 코드가 들어간다.



7 onEnter / onLeave

  • onEnter : 후킹한 함수에 진입하기 전에 실행 될 코드. args는 후킹한 함수가 전달받는 인수의 배열
  • onLeave(): 함수가 진행되고 난 후 실행할 코드
  onEnter(log, args, state) {
    log('open()',args[0].readUtf8String());
  },


  onLeave(log, retval, state) {
  }
}
  • open() 함수로 stacktrace 할 경우 사용하는 코드인데, 위처럼 args 를 넣어서 open 하는 함수의 주소값을 읽어오기도 한다.



8 Module.findExportByName

var unlinkPtr = Module.findExportByName([module], [method]);

Module.findExportByName(null,'unlink');
  • unlink라는 이름을 가진 메소드의 주소값을 알려줌
  • 커스텀 라이브러리가 아닌 기본라이브러리는 가져올 수 있는데 커스텀은 쉽지않음(왜냐면 함수 이름이 명확하지가 않음)
  • 해당 함수를 이용해 open 함수의 주소값을 반환받을 수 있음
  • 정확한 모듈이름을 모를때는 null 만 입력하고 함수의 이름만 넣어도됨. 단 이 함수는 모듈이 메모리에 올라와있을때만 사용이 가능하고 만약 모듈이 올라오지 않은 상태라면 null 값을 반환받는다


9 dalvik.system.DexClassLoader

dalvik.system.DexClassLoader

  • Run-time Dynamic Class Loading 기법을 사용하게 해주는 것.
  • java에서는 java.lang.classloader를 통하여 JVM 상에 클래스를 RUN-time에 로드한다. 이와 같은 방법.
  • java의 java.lang.classloader의 경우, java코드를 컴파일하여 생성된 .class 파일을 로드한다
  • Android의 dalvik.system.DexClassLoader의 경우, .class 파일이 아닌 .jar파일 혹은 apk파일이 포함되어있는 class.dex파일을 로드한다.

Run-time Dynamic loading이란?

코드를 실행하는 순간에 클래스를 로딩하는 기법.



10 enumerateLoadedClasses

Java.enumerateLoadedClasses (callbacks)

  • 현재 로드 된 모든 클래스를 열거하고 배열에 있는 키 클래스와 비교하여 호출된 실제 클래스를 찾는데에 사용된다. 다음과 같이 사용한다.
Java.perform (function () {
 
    // 위에서 찾은 여러 클래스
    var key_class = [ "com.facebook.plugin.widget.dkplayer.controller.PlayerVideoController",
                     "com.iqiyi.plugin.widget.dkplayer.controller.PlayerVideoController",
                     "com.facebook.plugin.widget.dkplayer.controller.VideoController",
                     "com.iqiyi.plugin.widget.dkplayer.controller.VideoController"]
 
    Java.enumerateLoadedClasses ({
        "onMatch": function (이름, 핸들) {
            for (var i = 0; i <key_class.length; i ++) {
                if (key_class [i] == 이름) {
                    console.log (이름);
                }
            }
        },
        "onComplete": function () {
            console.log ( "성공");
        }
    });
});


11 Java.use

Java.use

  • Method 가 static으로 되어있는 경우 함수가 메모리에 올라오므로 java.use를 이용하여 후킹


12 Java.choose

Java.choose

  • static이 아닐경우 인스턴스를 choose로 다루어준다.


13 Process.enumerateModules

Process.enumerateModules

  • 호출되었을때, 메모리에 올라와있는 모든 라이브러리 목록을 호출해준다.
Process.enumerateModues({
    onMatch: function(module){
        console.log('module name : ' + module.name + " - " + "Base Address: " + module.base.toString());
    },
    onComplete: function(){}
});
  • 상기와 같이 사용하며, 보통 if 문으로 감싸서 특정 상황일때 메모리에 올라와있는 모든 라이브러리 목록을 호출한다.
  • C,C+ 로 작성된 native method 후킹 시 라이브러리가 메모리에 올라간 후에 후킹해야하므로 네이티브 메소드 후킹할때 자주쓰는 메소드다.



참고 : java.use vs java.choose

[참고 사이트]

좋은 웹페이지 즐겨찾기