jni| unicorn | androidemu | frida_hook

这篇具有很好参考价值的文章主要介绍了jni| unicorn | androidemu | frida_hook。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

yang神脚本大全:
https://codeooo.blog.csdn.net/article/details/122988215

pip install unicorn
pip install androidemu

jni| unicorn | androidemu | frida_hook,App逆向工具,python,开发语言
AndroidNativeEmu
https://gitee.com/keji8/ExAndroidNativeEmu/
https://github.com/AeonLucid/AndroidNativeEmu

# -*- coding: utf-8 -*-
# @Author  : Codeooo
# @Time    : 2022-09-29


import logging
import posixpath
import sys
import os

from unicorn import *
from unicorn.arm_const import *

from androidemu.emulator import Emulator
from androidemu.java.java_class_def import JavaClassDef
from androidemu.java.java_method_def import java_method_def
import androidemu.utils.debug_utils
from androidemu.utils.chain_log import ChainLogger
from androidemu.java.classes.string import String

import capstone
import traceback

g_cfd = ChainLogger(sys.stdout, "./ins-jni.txt")


# Add debugging.
def hook_code(mu, address, size, user_data):
    try:
        emu = user_data
        if (not emu.memory.check_addr(address, UC_PROT_EXEC)):
            logger.error("addr 0x%08X out of range" % (address,))
            sys.exit(-1)
        #
        # androidemu.utils.debug_utils.dump_registers(mu, sys.stdout)
        androidemu.utils.debug_utils.dump_code(emu, address, size, g_cfd)
    except Exception as e:
        logger.exception("exception in hook_code")
        sys.exit(-1)
    #


#

def hook_mem_read(uc, access, address, size, value, user_data):
    pc = uc.reg_read(UC_ARM_REG_PC)

    if (address == 0xCBC80640):
        logger.debug("read mutex")
        data = uc.mem_read(address, size)
        v = int.from_bytes(data, byteorder='little', signed=False)
        logger.debug(
            ">>> Memory READ at 0x%08X, data size = %u,  data value = 0x%08X, pc: 0x%08X," % (address, size, v, pc))
    #


#

def hook_mem_write(uc, access, address, size, value, user_data):
    pc = uc.reg_read(UC_ARM_REG_PC)
    if (address == 0xCBC80640):
        logger.debug("write mutex")
        logger.debug(
            ">>> Memory WRITE at 0x%08X, data size = %u, data value = 0x%08X, pc: 0x%08X" % (address, size, value, pc))
    #


#

class MainActivity(metaclass=JavaClassDef, jvm_name='com/roysue/easyso1/MainActivity'):

    def __init__(self):
        pass

    @java_method_def(name='decrypt', signature='(Ljava/lang/String;)Ljava/lang/String;', native=True)
    def decrypt(self, mu):
        pass

    def test(self):
        pass


logger = logging.getLogger(__name__)

# Initialize emulator
emulator = Emulator(
    vfs_root=posixpath.join(posixpath.dirname(__file__), "vfs")
)

# Register Java class.
emulator.java_classloader.add_class(MainActivity)
# emulator.mu.hook_add(UC_HOOK_CODE, hook_code, emulator)

# emulator.mu.hook_add(UC_HOOK_MEM_WRITE, hook_mem_write)
# emulator.mu.hook_add(UC_HOOK_MEM_READ, hook_mem_read)

# Load all libraries.
lib_module = emulator.load_library("tests/bin/libroysue2.so")

# androidemu.utils.debug_utils.dump_symbols(emulator, sys.stdout)

# Show loaded modules.
logger.info("Loaded modules:")

for module in emulator.modules:
    logger.info("=> 0x%08x - %s" % (module.base, module.filename))

try:
    # Run JNI_OnLoad.
    #   JNI_OnLoad will call 'RegisterNatives'.
    emulator.call_symbol(lib_module, 'JNI_OnLoad', emulator.java_vm.address_ptr, 0x00)

    # Do native stuff.
    # main_activity = MainActivity()
    # logger.info("Response from JNI call: %s" % main_activity.string_from_jni(emulator))
    logger.info(
        "Response from JNI call: %s" % emulator.call_symbol(lib_module, "Java_com_roysue_easyso1_MainActivity_method01",
                                                            emulator.java_vm.jni_env.address_ptr, 0x00,
                                                            String('Hellor0ysue12345')))
    logger.info(
        "Response from JNI call: %s" % emulator.call_symbol(lib_module, "_Z8method02P7_JNIEnvP7_jclassP8_jstring",
                                                            emulator.java_vm.jni_env.address_ptr, 0x00, String(
                '9979a01fb97395969d358aa0f4c8fbdc3828d9b706c8cac023c4346a9d9c424e')))

    # Dump natives found.
    logger.info("Exited EMU.")
    # logger.info("Native methods registered to MainActivity:")

except UcError as e:
    print("Exit at %x" % emulator.mu.reg_read(UC_ARM_REG_PC))
    raise




h2.js

function hookJava(){
    Java.perform(function(){
        console.log("hooking java...")
        Java.use("com.roysue.easyso1.MainActivity").decrypt.implementation = function(str){
            var result = this.decrypt(str)
            console.log("str,result => ,",str,result)
            return result;
        }

    })
}
function invokeJava(){
    Java.perform(function(){
        var result  = Java.use("com.roysue.easyso1.MainActivity").decrypt("82e8edd5b05654bf0fedcdfc1c9b4b0f")    
        console.log("result => ,",result)      
        
    })
}


var is_hook_libart = false;

function hook_dlopen() {
    Interceptor.attach(Module.findExportByName(null, "dlopen"), {
        onEnter: function(args) {
            var pathptr = args[0];
            if (pathptr !== undefined && pathptr != null) {
                var path = ptr(pathptr).readCString();
                console.log("dlopen:", path);
                if (path.indexOf("libroysue.so") >= 0) {
                    this.can_hook_libart = true;
                    console.log("[dlopen:]", path);
                }
            }
        },
        onLeave: function(retval) {
            if (this.can_hook_libart && !is_hook_libart) {                
                is_hook_libart = true;
                
            }
        }
    })

    Interceptor.attach(Module.findExportByName(null, "android_dlopen_ext"), {
        onEnter: function(args) {
            var pathptr = args[0];
            if (pathptr !== undefined && pathptr != null) {
                var path = ptr(pathptr).readCString();
                console.log("android_dlopen_ext:", path);
                if (path.indexOf("libroysue.so") >= 0) {
                    this.can_hook_libart = true;
                    console.log("[android_dlopen_ext:]", path);
                }
            }
        },
        onLeave: function(retval) {
            if (this.can_hook_libart && !is_hook_libart) {
                is_hook_libart = true;
                var method01 = Module.findExportByName("libroysue.so", "Java_com_roysue_easyso1_MainActivity_method01")
                var method02 = Module.findExportByName("libroysue.so", "_Z8method02P7_JNIEnvP7_jclassP8_jstring")
                console.log("method01 address is =>",method01)
                console.log("method02 address is =>",method02)
                // Interceptor.attach(method01,{
                //     onEnter:function(args){
                //         console.log("arg[2=>",args[2])

                //     },onLeave:function(retval){
                //         console.log("retval=>",retval)

                //     }
                // })
                // Interceptor.attach(method02,{
                //     onEnter:function(args){
                //         console.log("method02 arg[2=>",Java.vm.getEnv().getStringUtfChars(args[2], null).readCString())

                //     },onLeave:function(retval){
                //         console.log("method02  retval=>",Java.vm.getEnv().getStringUtfChars(retval, null).readCString())
                //     }
                // })
            }
        }
    });
}

function main(){
    console.log("Entering main...")
    // hookJava()
    hook_dlopen()
}
setImmediate(main)

动态注册魔改:

var ENV = null;
var JCLZ = null;

var method01addr = null;
var method02addr = null;
var method02 = null;

var addrNewStringUTF = null;

var NewStringUTF = null;


function hook_RegisterNatives() {
    var symbols = Module.enumerateSymbolsSync("libart.so");
    var addrRegisterNatives = null;
    for (var i = 0; i < symbols.length; i++) {
        var symbol = symbols[i];
        
        //_ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi
        if (symbol.name.indexOf("art") >= 0 &&
                symbol.name.indexOf("JNI") >= 0 && 
                symbol.name.indexOf("NewStringUTF") >= 0 && 
                symbol.name.indexOf("CheckJNI") < 0) {
            addrNewStringUTF = symbol.address;
            console.log("NewStringUTF is at ", symbol.address, symbol.name);
            NewStringUTF = new NativeFunction(addrNewStringUTF,'pointer',['pointer','pointer'])
        }
        if (symbol.name.indexOf("art") >= 0 &&
                symbol.name.indexOf("JNI") >= 0 && 
                symbol.name.indexOf("RegisterNatives") >= 0 && 
                symbol.name.indexOf("CheckJNI") < 0) {
            addrRegisterNatives = symbol.address;
            console.log("RegisterNatives is at ", symbol.address, symbol.name);
        }
    }

    if (addrRegisterNatives != null) {
        Interceptor.attach(addrRegisterNatives, {
            onEnter: function (args) {
                console.log("[RegisterNatives] method_count:", args[3]);
                var env = args[0];
                ENV = args[0];
                var java_class = args[1];
                JCLZ = args[1];
                var class_name = Java.vm.tryGetEnv().getClassName(java_class);
                //console.log(class_name);

                var methods_ptr = ptr(args[2]);

                var method_count = parseInt(args[3]);
                for (var i = 0; i < method_count; i++) {
                    var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
                    var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
                    var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));

                    var name = Memory.readCString(name_ptr);
                    var sig = Memory.readCString(sig_ptr);
                    var find_module = Process.findModuleByAddress(fnPtr_ptr);
                    console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, "module_name:", find_module.name, "module_base:", find_module.base, "offset:", ptr(fnPtr_ptr).sub(find_module.base));
                    if(name.indexOf("method01")>=0){
                        // method01addr = fnPtr_ptr;
                        continue;
                    }else if (name.indexOf("decrypt")>=0){
                        method02addr = fnPtr_ptr;
                        method02 = new NativeFunction(method02addr,'pointer',['pointer','pointer','pointer']);
                        method01addr = Module.findExportByName("libroysue.so", "Java_com_roysue_easyso1_MainActivity_method01")
                    }else{
                        continue;
                    }

                }
            }
        });
    }
}


function invokemethod01(contents){
    
    console.log("method01_addr is =>",method01addr)
    var method01 = new NativeFunction(method01addr,'pointer',['pointer','pointer','pointer']);
    var NewStringUTF = new NativeFunction(addrNewStringUTF,'pointer',['pointer','pointer'])
    var result = null;
    Java.perform(function(){    
        console.log("Java.vm.getEnv()",Java.vm.getEnv())
        var JSTRING = NewStringUTF(Java.vm.getEnv(),Memory.allocUtf8String(contents))
        result = method01(Java.vm.getEnv(),JSTRING,JSTRING);
        console.log("result is =>",result)
        console.log("result is ",Java.vm.getEnv().getStringUtfChars(result, null).readCString())
        result = Java.vm.getEnv().getStringUtfChars(result, null).readCString();

    })
    return result;
}

function invokemethod02(contents){
    var result = null;
    Java.perform(function(){    
        var JSTRING = NewStringUTF(Java.vm.getEnv(),Memory.allocUtf8String(contents))
        result = method02(Java.vm.getEnv(),JSTRING,JSTRING);
        result = Java.vm.getEnv().getStringUtfChars(result, null).readCString();
    })
    return result;
}
rpc.exports = {
    invoke1:invokemethod01,
    invoke2:invokemethod02
};

setImmediate(hook_RegisterNatives);


/*
java_class: com.example.demoso1.MainActivity name: method01 sig: (Ljava/lang/String;)Ljava/lang/String; fnPtr: 0x73e2cd1018 module_name: libnative-lib.so module_base: 0x73e2cc1000 offset: 0x10018
java_class: com.example.demoso1.MainActivity name: method02 sig: (Ljava/lang/String;)Ljava/lang/String; fnPtr: 0x73e2cd0efc module_name: libnative-lib.so module_base: 0x73e2cc1000 offset: 0xfefc

function hookmethod(addr){
    Interceptor.attach(addr,{
        onEnter:function(args){
            console.log("args[0]=>",args[0])
            console.log("args[1]=>",args[1])
            console.log("args[2]=>",Java.vm.getEnv().getStringUtfChars(args[2], null).readCString())
        },onLeave:function(retval){
            console.log(Java.vm.getEnv().getStringUtfChars(retval, null).readCString())
        }
    })
}


function replacehook(addr){
    //> 能够hook上,就能主动调用
    var addrfunc = new NativeFunction(addr,'pointer',['pointer','pointer','pointer']);
    Interceptor.replace(addr,new NativeCallback(function(arg1,arg2,arg3){
        // 确定主动调用可以成功,只要参数合法,地址正确
        var result = addrfunc(arg1,arg2,arg3)
        console.log(arg1,arg2,arg3)
        console.log("result is ",Java.vm.getEnv().getStringUtfChars(result, null).readCString())
        return result;
    },'pointer',['pointer','pointer','pointer']))
}


*/

frida -U --no-pause -f package_name -l hook_art.js


const STD_STRING_SIZE = 3 * Process.pointerSize;
class StdString {
    constructor() {
        this.handle = Memory.alloc(STD_STRING_SIZE);
    }

    dispose() {
        const [data, isTiny] = this._getData();
        if (!isTiny) {
            Java.api.$delete(data);
        }
    }

    disposeToString() {
        const result = this.toString();
        this.dispose();
        return result;
    }

    toString() {
        const [data] = this._getData();
        return data.readUtf8String();
    }

    _getData() {
        const str = this.handle;
        const isTiny = (str.readU8() & 1) === 0;
        const data = isTiny ? str.add(1) : str.add(2 * Process.pointerSize).readPointer();
        return [data, isTiny];
    }
}

function prettyMethod(method_id, withSignature) {
    const result = new StdString();
    Java.api['art::ArtMethod::PrettyMethod'](result, method_id, withSignature ? 1 : 0);
    return result.disposeToString();
}

/*
GetFieldID is at  0xe39b87c5 _ZN3art3JNI10GetFieldIDEP7_JNIEnvP7_jclassPKcS6_
GetMethodID is at  0xe39a1a19 _ZN3art3JNI11GetMethodIDEP7_JNIEnvP7_jclassPKcS6_
NewStringUTF is at  0xe39cff25 _ZN3art3JNI12NewStringUTFEP7_JNIEnvPKc
RegisterNatives is at  0xe39e08fd _ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi
GetStaticFieldID is at  0xe39c9635 _ZN3art3JNI16GetStaticFieldIDEP7_JNIEnvP7_jclassPKcS6_
GetStaticMethodID is at  0xe39be0ed _ZN3art3JNI17GetStaticMethodIDEP7_JNIEnvP7_jclassPKcS6_
GetStringUTFChars is at  0xe39d06e5 _ZN3art3JNI17GetStringUTFCharsEP7_JNIEnvP8_jstringPh
FindClass is at  0xe399ae5d _ZN3art3JNI9FindClassEP7_JNIEnvPKc
*/

function hook_libart() {
    var symbols = Module.enumerateSymbolsSync("libart.so");
    var addrGetStringUTFChars = null;
    var addrNewStringUTF = null;
    var addrFindClass = null;
    var addrGetMethodID = null;
    var addrGetStaticMethodID = null;
    var addrGetFieldID = null;
    var addrGetStaticFieldID = null;
    var addrRegisterNatives = null;
    var so_name = "lib";      //TODO 这里写需要过滤的so

    for (var i = 0; i < symbols.length; i++) {
        var symbol = symbols[i];
        if (symbol.name.indexOf("art") >= 0 &&
            symbol.name.indexOf("JNI") >= 0 &&
            symbol.name.indexOf("CheckJNI") < 0 &&
            symbol.name.indexOf("_ZN3art3JNIILb0") >= 0
        ) {
            if (symbol.name.indexOf("GetStringUTFChars") >= 0) {
                addrGetStringUTFChars = symbol.address;
                console.log("GetStringUTFChars is at ", symbol.address, symbol.name);
            } else if (symbol.name.indexOf("NewStringUTF") >= 0) {
                addrNewStringUTF = symbol.address;
                console.log("NewStringUTF is at ", symbol.address, symbol.name);
            } else if (symbol.name.indexOf("FindClass") >= 0) {
                addrFindClass = symbol.address;
                console.log("FindClass is at ", symbol.address, symbol.name);
            } else if (symbol.name.indexOf("GetMethodID") >= 0) {
                addrGetMethodID = symbol.address;
                console.log("GetMethodID is at ", symbol.address, symbol.name);
            } else if (symbol.name.indexOf("GetStaticMethodID") >= 0) {
                addrGetStaticMethodID = symbol.address;
                console.log("GetStaticMethodID is at ", symbol.address, symbol.name);
            } else if (symbol.name.indexOf("GetFieldID") >= 0) {
                addrGetFieldID = symbol.address;
                console.log("GetFieldID is at ", symbol.address, symbol.name);
            } else if (symbol.name.indexOf("GetStaticFieldID") >= 0) {
                addrGetStaticFieldID = symbol.address;
                console.log("GetStaticFieldID is at ", symbol.address, symbol.name);
            } else if (symbol.name.indexOf("RegisterNatives") >= 0) {
                addrRegisterNatives = symbol.address;
                console.log("RegisterNatives is at ", symbol.address, symbol.name);
            } else if (symbol.name.indexOf("CallStatic") >= 0) {
                console.log("CallStatic is at ", symbol.address, symbol.name);
                Interceptor.attach(symbol.address, {
                    onEnter: function (args) {
                        var module = Process.findModuleByAddress(this.returnAddress);
                        if (module != null && module.name.indexOf(so_name) == 0) {
                            var java_class = args[1];
                            var mid = args[2];
                            var class_name = Java.vm.tryGetEnv().getClassName(java_class);
                            if (class_name.indexOf("java.") == -1 && class_name.indexOf("android.") == -1) {
                                var method_name = prettyMethod(mid, 1);
                                console.log("<>CallStatic:", DebugSymbol.fromAddress(this.returnAddress), class_name, method_name);
                            }
                        }
                    },
                    onLeave: function (retval) { }
                });
            } else if (symbol.name.indexOf("CallNonvirtual") >= 0) {
                console.log("CallNonvirtual is at ", symbol.address, symbol.name);
                Interceptor.attach(symbol.address, {
                    onEnter: function (args) {
                        var module = Process.findModuleByAddress(this.returnAddress);
                        if (module != null && module.name.indexOf(so_name) == 0) {
                            var jobject = args[1];
                            var jclass = args[2];
                            var jmethodID = args[3];
                            var obj_class_name = Java.vm.tryGetEnv().getObjectClassName(jobject);
                            var class_name = Java.vm.tryGetEnv().getClassName(jclass);
                            if (class_name.indexOf("java.") == -1 && class_name.indexOf("android.") == -1) {
                                var method_name = prettyMethod(jmethodID, 1);
                                console.log("<>CallNonvirtual:", DebugSymbol.fromAddress(this.returnAddress), class_name, obj_class_name, method_name);
                            }
                        }
                    },
                    onLeave: function (retval) { }
                });
            } else if (symbol.name.indexOf("Call") >= 0 && symbol.name.indexOf("Method") >= 0) {
                console.log("Call<>Method is at ", symbol.address, symbol.name);
                Interceptor.attach(symbol.address, {
                    onEnter: function (args) {
                        var module = Process.findModuleByAddress(this.returnAddress);
                        if (module != null && module.name.indexOf(so_name) == 0) {
                            var java_class = args[1];
                            var mid = args[2];
                            var class_name = Java.vm.tryGetEnv().getObjectClassName(java_class);
                            if (class_name.indexOf("java.") == -1 && class_name.indexOf("android.") == -1) {
                                var method_name = prettyMethod(mid, 1);
                                console.log("<>Call<>Method:", DebugSymbol.fromAddress(this.returnAddress), class_name, method_name);
                            }
                        }
                    },
                    onLeave: function (retval) { }
                });
            }
        }
    }

    if (addrGetStringUTFChars != null) {
        Interceptor.attach(addrGetStringUTFChars, {
            onEnter: function (args) {
            },
            onLeave: function (retval) {
                if (retval != null) {
                    var module = Process.findModuleByAddress(this.returnAddress);
                    if (module != null && module.name.indexOf(so_name) == 0) {
                        var bytes = Memory.readCString(retval);
                        console.log("[GetStringUTFChars] result:" + bytes, DebugSymbol.fromAddress(this.returnAddress));
                    }
                }
            }
        });
    }
    if (addrNewStringUTF != null) {
        Interceptor.attach(addrNewStringUTF, {
            onEnter: function (args) {
                if (args[1] != null) {
                    var module = Process.findModuleByAddress(this.returnAddress);
                    if (module != null && module.name.indexOf(so_name) == 0) {
                        var string = Memory.readCString(args[1]);
                        console.log("[NewStringUTF] bytes:" + string, DebugSymbol.fromAddress(this.returnAddress));
                    }

                }
            },
            onLeave: function (retval) { }
        });
    }

    if (addrFindClass != null) {
        Interceptor.attach(addrFindClass, {
            onEnter: function (args) {
                if (args[1] != null) {
                    var module = Process.findModuleByAddress(this.returnAddress);
                    if (module != null && module.name.indexOf(so_name) == 0) {
                        var name = Memory.readCString(args[1]);
                        console.log("[FindClass] name:" + name, DebugSymbol.fromAddress(this.returnAddress));
                    }
                }
            },
            onLeave: function (retval) { }
        });
    }
    if (addrGetMethodID != null) {
        Interceptor.attach(addrGetMethodID, {
            onEnter: function (args) {
                if (args[2] != null) {
                    var clazz = args[1];
                    var class_name = Java.vm.tryGetEnv().getClassName(clazz);
                    var module = Process.findModuleByAddress(this.returnAddress);
                    if (module != null && module.name.indexOf(so_name) == 0) {
                        var name = Memory.readCString(args[2]);
                        if (args[3] != null) {
                            var sig = Memory.readCString(args[3]);
                            console.log("[GetMethodID] class_name:" + class_name + " name:" + name + ", sig:" + sig, DebugSymbol.fromAddress(this.returnAddress));
                        } else {
                            console.log("[GetMethodID] class_name:" + class_name + " name:" + name, DebugSymbol.fromAddress(this.returnAddress));
                        }
                    }
                }
            },
            onLeave: function (retval) { }
        });
    }
    if (addrGetStaticMethodID != null) {
        Interceptor.attach(addrGetStaticMethodID, {
            onEnter: function (args) {
                if (args[2] != null) {
                    var clazz = args[1];
                    var class_name = Java.vm.tryGetEnv().getClassName(clazz);
                    var module = Process.findModuleByAddress(this.returnAddress);
                    if (module != null && module.name.indexOf(so_name) == 0) {
                        var name = Memory.readCString(args[2]);
                        if (args[3] != null) {
                            var sig = Memory.readCString(args[3]);
                            console.log("[GetStaticMethodID] class_name:" + class_name + " name:" + name + ", sig:" + sig, DebugSymbol.fromAddress(this.returnAddress));
                        } else {
                            console.log("[GetStaticMethodID] class_name:" + class_name + " name:" + name, DebugSymbol.fromAddress(this.returnAddress));
                        }
                    }
                }
            },
            onLeave: function (retval) { }
        });
    }
    if (addrGetFieldID != null) {
        Interceptor.attach(addrGetFieldID, {
            onEnter: function (args) {
                if (args[2] != null) {
                    var module = Process.findModuleByAddress(this.returnAddress);
                    if (module != null && module.name.indexOf(so_name) == 0) {
                        var name = Memory.readCString(args[2]);
                        if (args[3] != null) {
                            var sig = Memory.readCString(args[3]);
                            console.log("[GetFieldID] name:" + name + ", sig:" + sig, DebugSymbol.fromAddress(this.returnAddress));
                        } else {
                            console.log("[GetFieldID] name:" + name, DebugSymbol.fromAddress(this.returnAddress));
                        }
                    }
                }
            },
            onLeave: function (retval) { }
        });
    }
    if (addrGetStaticFieldID != null) {
        Interceptor.attach(addrGetStaticFieldID, {
            onEnter: function (args) {
                if (args[2] != null) {
                    var module = Process.findModuleByAddress(this.returnAddress);
                    if (module != null && module.name.indexOf(so_name) == 0) {
                        var name = Memory.readCString(args[2]);
                        if (args[3] != null) {
                            var sig = Memory.readCString(args[3]);
                            console.log("[GetStaticFieldID] name:" + name + ", sig:" + sig, DebugSymbol.fromAddress(this.returnAddress));
                        } else {
                            console.log("[GetStaticFieldID] name:" + name, DebugSymbol.fromAddress(this.returnAddress));
                        }
                    }
                }
            },
            onLeave: function (retval) { }
        });
    }

    if (addrRegisterNatives != null) {
        Interceptor.attach(addrRegisterNatives, {
            onEnter: function (args) {
                console.log("[RegisterNatives] method_count:", args[3], DebugSymbol.fromAddress(this.returnAddress));
                var env = args[0];
                var java_class = args[1];
                var class_name = Java.vm.tryGetEnv().getClassName(java_class);

                var methods_ptr = ptr(args[2]);

                var method_count = parseInt(args[3]);
                for (var i = 0; i < method_count; i++) {
                    var name_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3));
                    var sig_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize));
                    var fnPtr_ptr = Memory.readPointer(methods_ptr.add(i * Process.pointerSize * 3 + Process.pointerSize * 2));

                    var name = Memory.readCString(name_ptr);
                    var sig = Memory.readCString(sig_ptr);
                    var find_module = Process.findModuleByAddress(fnPtr_ptr);
                    console.log("[RegisterNatives] java_class:", class_name, "name:", name, "sig:", sig, "fnPtr:", fnPtr_ptr, "module_name:", find_module.name, "module_base:", find_module.base, "offset:", ptr(fnPtr_ptr).sub(find_module.base));

                }
            },
            onLeave: function (retval) { }
        });
    }
}

setImmediate(hook_libart);

frida -U --no-pause -f package_name -l hook_artmethod.js -o hook_artmethod.log文章来源地址https://www.toymoban.com/news/detail-558938.html


const STD_STRING_SIZE = 3 * Process.pointerSize;
class StdString {
    constructor() {
        this.handle = Memory.alloc(STD_STRING_SIZE);
    }

    dispose() {
        const [data, isTiny] = this._getData();
        if (!isTiny) {
            Java.api.$delete(data);
        }
    }

    disposeToString() {
        const result = this.toString();
        this.dispose();
        return result;
    }

    toString() {
        const [data] = this._getData();
        return data.readUtf8String();
    }

    _getData() {
        const str = this.handle;
        const isTiny = (str.readU8() & 1) === 0;
        const data = isTiny ? str.add(1) : str.add(2 * Process.pointerSize).readPointer();
        return [data, isTiny];
    }
}

function prettyMethod(method_id, withSignature) {
    const result = new StdString();
    Java.api['art::ArtMethod::PrettyMethod'](result, method_id, withSignature ? 1 : 0);
    return result.disposeToString();
}

function hook_dlopen(module_name, fun) {
    var android_dlopen_ext = Module.findExportByName(null, "android_dlopen_ext");

    if (android_dlopen_ext) {
        Interceptor.attach(android_dlopen_ext, {
            onEnter: function (args) {
                var pathptr = args[0];
                if (pathptr) {
                    this.path = (pathptr).readCString();
                    if (this.path.indexOf(module_name) >= 0) {
                        this.canhook = true;
                        console.log("android_dlopen_ext:", this.path);
                    }
                }
            },
            onLeave: function (retval) {
                if (this.canhook) {
                    fun();
                }
            }
        });
    }
    var dlopen = Module.findExportByName(null, "dlopen");
    if (dlopen) {
        Interceptor.attach(dlopen, {
            onEnter: function (args) {
                var pathptr = args[0];
                if (pathptr) {
                    this.path = (pathptr).readCString();
                    if (this.path.indexOf(module_name) >= 0) {
                        this.canhook = true;
                        console.log("dlopen:", this.path);
                    }
                }
            },
            onLeave: function (retval) {
                if (this.canhook) {
                    fun();
                }
            }
        });
    }
    console.log("android_dlopen_ext:", android_dlopen_ext, "dlopen:", dlopen);
}


function hook_native() {
    var module_libart = Process.findModuleByName("libart.so");
    var symbols = module_libart.enumerateSymbols();
    var ArtMethod_Invoke = null;
    for (var i = 0; i < symbols.length; i++) {
        var symbol = symbols[i];
        var address = symbol.address;
        var name = symbol.name;
        var indexArtMethod = name.indexOf("ArtMethod");
        var indexInvoke = name.indexOf("Invoke");
        var indexThread = name.indexOf("Thread");
        if (indexArtMethod >= 0
            && indexInvoke >= 0
            && indexThread >= 0
            && indexArtMethod < indexInvoke
            && indexInvoke < indexThread) {
            console.log(name);
            ArtMethod_Invoke = address;
        }
    }
    if (ArtMethod_Invoke) {
        Interceptor.attach(ArtMethod_Invoke, {
            onEnter: function (args) {
                var method_name = prettyMethod(args[0], 0);
                if (!(method_name.indexOf("java.") == 0 || method_name.indexOf("android.") == 0)) {
                    console.log("ArtMethod Invoke:" + method_name + '  called from:\n' +
                        Thread.backtrace(this.context, Backtracer.ACCURATE)
                            .map(DebugSymbol.fromAddress).join('\n') + '\n');
                }
            }
        });
    }
}

function main() {
    hook_dlopen("libart.so", hook_native);
    hook_native();
}

setImmediate(main);

到了这里,关于jni| unicorn | androidemu | frida_hook的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • adb连接安卓模拟器或真机hook参数加密详细过程(frida)

    app逆向时,参数与函数的确定很关键,找到可疑的函数,不确定是否由该函数生成,该怎么解决?hook就应允而生了,首先是要求本地电脑和安卓模拟器(网易mumu模拟器支持多系统,该模拟器作为主流)或真机的连接,无论是网易mumu模拟器还是真机都要取得超级权限(root),

    2024年02月13日
    浏览(51)
  • [CTFTraining] ASIS CTF 2019 Quals Unicorn shop

    阿米尔卡比尔大学信息安全与密码学研究小组夺旗赛 ​ 我们随便买一件商品,1~3都显示: ​ 只有第4个显示: ​ 只允许输入一个字符,题目叫 Unicorn ,猜测为 Unicode 。在Unicode - Compart搜索比千大的 Unicode 码: ​ 最后填进去买下商品得到flag。 另外:

    2024年02月07日
    浏览(84)
  • 【论文阅读】UNICORN:基于运行时来源的高级持续威胁检测器(NDSS-2020)

    UNICORN: Runtime Provenance-Based Detector for Advanced Persistent Threats NDSS-2020 哈佛大学 Han X, Pasquier T, Bates A, et al. Unicorn: Runtime provenance-based detector for advanced persistent threats[J]. arXiv preprint arXiv:2001.01525, 2020. 源码:UNICORN https://github.com/crimson-unicorn   高级持续性威胁 (APT) 由于其 “低速” 攻

    2024年02月14日
    浏览(47)
  • [Frida集成篇]FB_01.内置frida-inject到手机系统

    主要内容: frida-inject 工具使用及说明 内置 frida-inject 工具到手机系统 frida-inject 是 frida 中提供的可以直接放到手机端执行注入 js 脚本到 App 程序进行 hook 的工具。也就是说使用 frida-inject 命令可以脱离 PC 端执行注入了。 平时我们用 frida 进行 App 注入的时候,多半都是 PC 端安

    2024年02月16日
    浏览(24)
  • frida https抓包

    web端导入证书、https代理即可解决大部分需求,但是,有些app需要处理ssl pinning验证。 废话不多说。frida处理ssl pin的步骤大体如下。 安装python3.x,并在python环境中安装frida: 下载frida-server,并使用adb命令push到/data/local/tmp目录下,并运行: 注意:此处的 f r i d a − s e r v e r 和 f

    2024年01月20日
    浏览(70)
  • frida安装配置教程

    frida版本和python版本以及Android要对应,python版本过高会导致frida不可用,以下是不严谨的版本对应关系 frida12.3.6 -- python3.7 -- Android5-6 frida12.8.0 --Python3.8–Android7-8 frida14–Python3.8–Android9 查看python版本 python --version 安装指定版本的frida 我用的夜神模拟器安卓9版本,所以安装14版

    2024年02月13日
    浏览(29)
  • android frida检测绕过

    Frida检测是一种常见的安卓逆向技术,常用于防止应用程序被反向工程。如果您遇到了Frida检测,您可以尝试以下方法来绕过它: 使用Magisk Hide模块:Magisk是一个强大的安卓root工具,它附带了一个Magisk Hide模块,可以帮助您隐藏root权限。这可以帮助您绕过Frida检测。 使用Xpos

    2024年02月15日
    浏览(38)
  • Android JNI3--JNI基础

    C 预处理器不是编译器的组成部分,但是它是编译过程中一个单独的步骤。简言之,C 预处理器只不过是一个文本替换工具而已,它们会指示编译器在实际编译之前完成所需的预处理。我们将把 C 预处理器(C Preprocessor)简写为 CPP。 所有的预处理器命令都是以井号(#)开头。

    2024年02月12日
    浏览(27)
  • 最新2023:Frida完美安装方案

    原文是安装最新frida的步骤。但是我在使用过程中,如果安卓版本比较低的话,最新版frida不是很稳定。推荐安卓7、8安装frida 12.8.0版本,安卓10/frida14,安卓12/frida16。 2023:Frida完美安装方案指路 这个是frida12.8.0安装教程 逆向第一步,从frida开始! 用我自己的理解,说一下fr

    2024年02月06日
    浏览(31)
  • so层检测frida绕过

    如果是在so层里开一个线程检测frida; 我们思路是可以frida加载那个so, 然后打印出检测线程的偏移; 然后干掉这个线程,完成!

    2024年02月12日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包