frida hook svc调用

如下图所示,当别人在rom上改写了open.cpp函数,当发现打开/proc/cpuinfo文件时,会将其重定向到/system/ubin/cpuinfo 基我们自己定义的cpu ,同理内存/proc/memoryinfo,存储,也可以这样改写,比如某多多上的12G,512M的骁龙865,价格600多的平板,很可能就是这样改的。他会根据UID

if ((uid >= MINUID && uid <= MAXUID)) 来针对第三方的检测,当识别是第三方程序访问这些硬件变量时,就会重定向到一个指定的文件位置来实现模拟。

为了能检测出真实的设备,要在cpp文件中增加了svc的调用,相当于不通过libc的open函数打开/proc/cpuinfo,这样在libc中实现对openat的hook函数就无效了。见下面代码 

这个函数更新时要运行一下ndk-build
app\src\main>ndk-build
如果增加了函数
要用\app\src\main>javah -d jni -classpath ./com.rom.cpptest
重新生成一下或者将鼠标放在新加的函数上,会有提示自动生成函数
#include <jni.h>
#include <string>
#include <fcntl.h>
#include "unistd.h"
#include <asm/unistd.h>
#include <android/log.h>
#define MAX_LINE 512
#define MAX_LENGTH 256
static const char *APPNAME = "MyReceiver";
#define LIBC "libc.so"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, APPNAME, __VA_ARGS__)
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, APPNAME, __VA_ARGS__)
using namespace std;
#define __SYSCALL_LL_E(x) (x)
#define __SYSCALL_LL_O(x) (x)

#define __asm_syscall(...) do { \
	__asm__ __volatile__ ( "svc 0" \
	: "=r"(x0) : __VA_ARGS__ : "memory", "cc"); \
	return x0; \
	} while (0)

__attribute__((always_inline))
static inline long __syscall1(long n, long a)
{
    register long x8 __asm__("x8") = n;
    register long x0 __asm__("x0") = a;
    __asm_syscall("r"(x8), "0"(x0));
}

__attribute__((always_inline))
static inline long __syscall3(long n, long a, long b, long c)
{
    register long x8 __asm__("x8") = n;
    register long x0 __asm__("x0") = a;
    register long x1 __asm__("x1") = b;
    register long x2 __asm__("x2") = c;
    __asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2));
}

__attribute__((always_inline))
static inline long __syscall4(long n, long a, long b, long c, long d)
{
    register long x8 __asm__("x8") = n;
    register long x0 __asm__("x0") = a;
    register long x1 __asm__("x1") = b;
    register long x2 __asm__("x2") = c;
    register long x3 __asm__("x3") = d;
    __asm_syscall("r"(x8), "0"(x0), "r"(x1), "r"(x2), "r"(x3));
}
__attribute__((always_inline))
static inline int  my_openat(int __dir_fd, const void* __path, int __flags, int __mode ){
    return (int)__syscall4(__NR_openat, __dir_fd, (long)__path, __flags, __mode);
}

__attribute__((always_inline))
static inline ssize_t my_read(int __fd, void* __buf, size_t __count){
    return __syscall3(__NR_read, __fd, (long)__buf, (long)__count);
}

__attribute__((always_inline))
static inline int my_close(int __fd){
    return (int)__syscall1(__NR_close, __fd);
}

static inline int  add_inline(int a,int b ){
    return (int) a+b+1;
}

__attribute__((always_inline))
static inline bool  isRooted_use_svc_open( ){
    string a="/system";
    string b="bin";
    char infor[10];
    sprintf(infor,"/%s",b.c_str());
    string c="/su";
    string e=a+infor+c ;
    string d="/system/bin/su";
    int fd = my_openat(AT_FDCWD,e.c_str() , O_RDONLY | O_CLOEXEC, 0);
    if (fd > 0) {
        LOGI("root detect ");
        return true;
    } else
    {
        LOGI("root not detect ");
        return false;
    }
}

__attribute__((always_inline))
static inline bool  isRooted_use_libc_open( ){


    string d="/system/bin/su";
    int fd = open( d.c_str() , O_RDONLY | O_CLOEXEC );
    if (fd > 0) {
        LOGI("root detect in isRooted_use_libc_open");
        return true;
    } else
    {
        LOGI("root not detect ");
        return false;
    }
}
__attribute__((always_inline))
static inline string  get_cpuinfor_svc( ){


    string path="/proc/cpuinfo";
    //libc 调用
    // int fd = open( d.c_str() , O_RDONLY | O_CLOEXEC );
    // svc 调用
    long fd = my_openat(AT_FDCWD, path.c_str(), O_RDONLY | O_CLOEXEC, 0);

    if (fd > 0) {
        char buffer[8];
        memset(buffer, 0, 8);
        std::string str;
        //int fd = open(path, O_RDONLY);

        //失败 -1;成功:>0 读出的字节数  =0文件读完了
        while (my_read(fd, buffer, 1) != 0) {
            //LOGI("读取文件内容  %s" ,buffer);
            str.append(buffer);
        }
        my_close(fd);
        return str;
    } else
    {
        LOGI("root not detect ");
        return "null";
    }
}

__attribute__((always_inline))
static  string  get_cpuinfor_libc( ){


    string d="/proc/cpuinfo";
    int fd = open( d.c_str() , O_RDONLY | O_CLOEXEC );
    //int fd = my_openat(AT_FDCWD, d.c_str(), O_RDONLY | O_CLOEXEC, 0);
    if (fd > 0) {
        char buffer[1024];
        memset(buffer, 0, 1024);
        std::string str;
        //int fd = open(path, O_RDONLY);

        //失败 -1;成功:>0 读出的字节数  =0文件读完了
        //while (my_read(fd, buffer, 1) != 0) {
        while (read(fd, buffer, 1) != 0) {
            LOGI("读取文件内容  %s" ,buffer);
            str.append(buffer);
        }
        close(fd);
        return str;
    } else
    {
        LOGI("root not detect ");
        return "null";
    }
}

extern "C" JNIEXPORT jstring JNICALL
Java_com_rom_cpptest_MainActivity_stringFromJNI(
        JNIEnv* env,
        jobject /* this */) {
    std::string hello = "Hello from C++ 你好中国";
    int fd = my_openat(AT_FDCWD, "/system/bin/su", O_RDONLY | O_CLOEXEC, 0);
    if (fd > 0) {
        LOGI("root detect ");
    } else
    {
        LOGI("root not detect ");
    }
    return env->NewStringUTF(hello.c_str());
}


extern "C"
JNIEXPORT jint JNICALL
Java_com_rom_cpptest_MainActivity_add(JNIEnv *env, jobject thiz, jint a, jint b) {
    if(isRooted_use_libc_open())
    {
        LOGI("add函数中检测到root,可以进行上报,进行追封");
    }
    return  a+b;
}


extern "C"
JNIEXPORT jboolean JNICALL
Java_com_rom_cpptest_MainActivity_detectRoot_1svc(JNIEnv *env, jobject thiz) {


    return isRooted_use_svc_open();
}

extern "C"
JNIEXPORT jboolean JNICALL
Java_com_rom_cpptest_MainActivity_detectRoot_1libC(JNIEnv *env, jobject thiz) {
    // TODO: implement detectRoot_libC()
    return isRooted_use_libc_open();
}


extern "C"
JNIEXPORT jstring JNICALL
Java_com_rom_cpptest_MainActivity_get_1cpuinfo_1svc(JNIEnv *env, jobject thiz) {
    // TODO: implement get_cpuinfo()
    return env->NewStringUTF(get_cpuinfor_svc().c_str());
}


extern "C"
JNIEXPORT jstring JNICALL
Java_com_rom_cpptest_MainActivity_get_1cpuinfo_1libc(JNIEnv *env, jobject thiz) {
    // TODO: implement get_cpuinfo_libc()
    return env->NewStringUTF(get_cpuinfor_libc().c_str());
}

编译后,用ida发现static inline string get_cpuinfor_svc( )的汇编代码如下 

而 static  string  get_cpuinfor_libc( )的汇编代码如下

 当我们只hooki libc 函数open2时,是无法拦截到get_cpuinfor_svc()的,所以要基于svc代码进行拦截处理。

代码如下 

svc_call_demo: 演示使用svc 调用openat和 libc下的openat的区别用于检测硬件的篡改信息

参考了

Frida-syscall-interceptor_fenfei331的博客-CSDN博客一、目标现在很多App不讲武德了,为了防止 openat 、read、kill 等等底层函数被hook,干脆就直接通过syscall的方式来做系统调用,导致无法hook。应对这种情况有两种方案:刷机重写系统调用表来拦截内核调用inline Hook SWI/SVC指令我们今天采用第二种方法,用frida来实现内联汇编SWI/SVC做系统调用, syscallfrida inline hookhook syscallfrida ArmWriterfrida typescript prhttps://blog.csdn.net/fenfei331/article/details/117920733Android 系统调用实现函数功能--SVC指令的实现与检测_Rorschach:Blog-CSDN博客0x0 简述: arm android中通过一些反编译的工具分析ELF文件时,根据一些导入的系统函数可以很轻松的找到一些功能代码的实现:查看libc中分析这些函数的实现: arm中通过SVC指令实现的系统调用因此利用这一点应用中加入了类似的实现操作,隐蔽掉调用系统函数的符号,增加分析难度: 0x1 实现: 以getpid为例修改调用方式,获取pid原本通过系统API getpid获取,修https://blog.csdn.net/u011247544/article/details/76427571

时间关系没太深入研究

附上python调用代码和 js代码

import frida
import sys
import time
import io
#代码可以直接写入下面,但是可读性不好
jscode = """
Java.perform(function () {

 });
"""
def printMessage(message,data):
    if message['type'] == 'send':
        print('[*] {0}'.format(message['payload']))
        # file_object = open("e:\\log.txt", 'ab+')
        # file_object.write(message['payload'].encode())
        # file_object.write('\n'.encode())
        # file_object.close()
    else:
        print(message)


device = frida.get_usb_device()
front_app = device.get_frontmost_application()
#下面要输入你应用的包名
pid = device.spawn(["com.rom.cpptest"])
device.resume(pid)
#这里必须要有个延迟不然获取不到front_app,时间跟据自己机型调整
time.sleep(18)
front_app = device.get_frontmost_application()


if front_app is  None:
    print("请运行要hook的应用")
    exit(0)


print(front_app)
print(front_app.name)
process = device.attach(front_app.name)

#process = frida.get_usb_device().attach('cpptest')
#直接读入sotest.js,在pycharm中代码有颜色感知,易于编辑
with open('./_agent.js',encoding='utf-8') as f:
    jscode = f.read()
script = process.create_script(jscode)

#script = process.create_script(jscode)
script.on('message',printMessage)
script.load()
sys.stdin.read()
(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i<t.length;i++)o(t[i]);return o}return r})()({1:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const logger_1 = require("./logger");
const frida_syscall_interceptor_1 = require("../../frida-syscall-interceptor");
const frida_syscall_interceptor_2 = require("../../frida-syscall-interceptor");
/*
const header = Memory.alloc(16);
header
    .writeU32(0xdeadbeef).add(4)
    .writeU32(0xd00ff00d).add(4)
    .writeU64(uint64("0x1122334455667788"));
log(hexdump(header.readByteArray(16) as ArrayBuffer, { ansi: true }));

Process.getModuleByName("libSystem.B.dylib")
    .enumerateExports()
    .slice(0, 16)
    .forEach((exp, index) => {
        log(`export ${index}: ${exp.name}`);
    });

Interceptor.attach(Module.getExportByName(null, "open"), {
    onEnter(args) {
        const path = args[0].readUtf8String();
        log(`open() path="${path}"`);
    }
});
*/
// Somewhere in your code.
//*
let baseAddr = Module.findBaseAddress('libnative-lib.so');
//指令的地址 这个地址会随着你自己编译的apk变化的,
// 如果hook一次后备份的地址会变化,要重新启动一下应用
// let address = baseAddr.add('0x81F8'); //  00 00 00 EF <= SVC  0

// hook openat /system/bin/su
let address1 = baseAddr.add('0xf1cc');
 //hook openat /system/bin/su
logger_1.log("cpu "+Process.arch);
frida_syscall_interceptor_1.hookSyscall(address1, new NativeCallback(function (dirfd, pathname, mode, flags) {
    let path = pathname.readCString();
    logger_1.log(`Called openat hook` );
    logger_1.log('- R0: ' + dirfd);
    logger_1.log('- R1: ' + path);
    logger_1.log('- R2: ' + mode);
    logger_1.log('- R3: ' + flags);
    return 0;
}, 'int', ['int', 'pointer', 'int', 'int']));

//如果出异常,重启动一下手机,一次只能hook一个函数
//__NR_read, __fd, (long)__buf, (long)__count
// let address2 = baseAddr.add('0x8520');
// let address2 = baseAddr.add('0xF588');
// frida_syscall_interceptor_2.hookSyscall(address2, new NativeCallback(function (dirfd, __buf, __count) {
//     let infor = __buf.readCString();
//     logger_1.log(`Called read hook` );
//     logger_1.log('- R0: ' + dirfd);
//     logger_1.log('- R1: ' + __buf +" string=> "+infor);
//     logger_1.log('- R2: ' + __count);
//     return 0;
// }, 'int', ['int', 'pointer', 'int']));

// frida -U -l _agent.js com.fenfei.syscalldemo

},{"../../frida-syscall-interceptor":4,"./logger":2}],2:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.log = void 0;
function log(message) {
    console.log(message);
}
exports.log = log;

},{}],3:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
class SyscallCallback {
    constructor(frida, native) {
        this.frida = frida;
        this.native = native;
    }
}
exports.SyscallCallback = SyscallCallback;

},{}],4:[function(require,module,exports){
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const callback_1 = require("./callback");
let callbacks = [];
function hookSyscall(syscallAddress, callback) {
    if (Process.arch == 'arm') {
        const address = syscallAddress.sub(8);
        const instructions = address.readByteArray(20);
        if (instructions == null) {
            throw new Error(`Unable to read instructions at address ${address}.`);
        }
        console.log(" ==== old instructions ==== " + address);
        console.log(instructions);
        Memory.patchCode(address, 20, function (code) {
            let writer = null;
            writer = new ArmWriter(code, { pc: address });
            writer.putBranchAddress(createCallback(callback, instructions, address.add(20), syscallAddress));
            writer.flush();
        });
        console.log(" ==== new instructions ==== " + address);
        const instructionsNew = address.readByteArray(20);
        console.log(instructionsNew);
    }
    else {
        const address = syscallAddress.sub(12);
        const instructions = address.readByteArray(12);
        if (instructions == null) {
            throw new Error(`Unable to read instructions at address ${address}.`);
        }
        console.log(" ==== old instructions ==== " + address);
        console.log(instructions);
        Memory.patchCode(address, 16, function (code) {
            let writer = null;
            writer = new Arm64Writer(code, { pc: address });
            writer.putBranchAddress(createCallback(callback, instructions, address.add(16), syscallAddress));
            writer.flush();
        });
        console.log(" ==== new instructions ==== " + address);
        const instructionsNew = address.readByteArray(12);
        console.log(instructionsNew);
    }
}
exports.hookSyscall = hookSyscall;
function createCallback(callback, instructions, retAddress, syscallAddress) {
    // Create custom instructions.
    let frida = Memory.alloc(Process.pageSize);
    Memory.patchCode(frida, Process.pageSize, function (code) {
        let writer = null;
        if (Process.arch == 'arm') {
            writer = new ArmWriter(code, { pc: frida });
            // Restore argument instructions.            
            writer.putBytes(instructions);
            // FE 5F 2D E9 STMFD  SP!, {R1-R12,LR} 寄存器入栈 不存 r0
            // FF 5F 2D E9 STMFD  SP!, {R0-R12,LR} 寄存器入栈  
            writer.putInstruction(0xE92D5FFF);
            // 00 A0 0F E1 MRS R10, CPSR
            // 00 04 2D E9 STMFD SP!, {R10}    // 状态寄存器入栈
            writer.putInstruction(0xE10FA000);
            writer.putInstruction(0xE92D0400);
            // instructions.size = 20  + 5条指令
            writer.putLdrRegAddress("lr", frida.add(20 + 5 * 4));
            writer.putBImm(callback);
            // 00 04 BD E8  LDMFD SP!, {R10}   // 状态寄存器出栈     
            // 0A F0 29 E1  MSR CPSR_cf, R10
            writer.putInstruction(0xE8BD0400);
            writer.putInstruction(0xE129F00A);
            // FE 9F BD E8 LDMFD  SP!, {R1-R12,PC}    寄存器出栈 不存 r0
            // FF 5F BD E8 LDMFD  SP!, {R0-R12,LR}    寄存器出栈 
            writer.putInstruction(0xE8BD5FFF);
        }
        else {
            writer = new Arm64Writer(code, { pc: frida });
            // Restore argument instructions.
            writer.putBytes(instructions);
            // Push all registers except x0.
            writer.putPushRegReg('x15', 'x1');
            writer.putPushRegReg('x2', 'x3');
            writer.putPushRegReg('x4', 'x5');
            writer.putPushRegReg('x6', 'x7');
            writer.putPushRegReg('x8', 'x9');
            writer.putPushRegReg('x10', 'x11');
            writer.putPushRegReg('x12', 'x13');
            writer.putPushRegReg('x14', 'x15');
            writer.putPushRegReg('x16', 'x17');
            writer.putPushRegReg('x18', 'x19');
            writer.putPushRegReg('x20', 'x21');
            writer.putPushRegReg('x22', 'x23');
            writer.putPushRegReg('x24', 'x25');
            writer.putPushRegReg('x26', 'x27');
            writer.putPushRegReg('x28', 'x29');
            writer.putInstruction(0xd53b420f); // 保存状态寄存器
            writer.putPushRegReg('x30', 'x15');
            // Call native.
            writer.putLdrRegAddress('x16', callback);
            writer.putBlrReg('x16');
            // Pop all registers, except x0, so x0 from native call gets used.
            writer.putPopRegReg('x30', 'x15');
            writer.putInstruction(0xd51b420f); // 还原状态寄存器
            writer.putPopRegReg('x28', 'x29');
            writer.putPopRegReg('x26', 'x27');
            writer.putPopRegReg('x24', 'x25');
            writer.putPopRegReg('x22', 'x23');
            writer.putPopRegReg('x20', 'x21');
            writer.putPopRegReg('x18', 'x19');
            writer.putPopRegReg('x16', 'x17');
            writer.putPopRegReg('x14', 'x15');
            writer.putPopRegReg('x12', 'x13');
            writer.putPopRegReg('x10', 'x11');
            writer.putPopRegReg('x8', 'x9');
            writer.putPopRegReg('x6', 'x7');
            writer.putPopRegReg('x4', 'x5');
            writer.putPopRegReg('x2', 'x3');
            writer.putPopRegReg('x15', 'x1');
        }
        // Call syscall.
        // writer.putInstruction(0xd4000001);
        writer.putBranchAddress(retAddress);
        writer.flush();
    });
    console.log("==== frida ====");
    console.log(frida);
    console.log("==== retAddress ====");
    console.log(retAddress);
    // Store callback so it doesn't get garbage collected.
    callbacks.push(new callback_1.SyscallCallback(frida, callback));
    // Return pointer to the instructions.
    return callbacks[callbacks.length - 1].frida;
}

},{"./callback":3}]},{},[1])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJhZ2VudC9pbmRleC50cyIsImFnZW50L2xvZ2dlci50cyIsIi4uL2ZyaWRhLXN5c2NhbGwtaW50ZXJjZXB0b3IvZGlzdC9jYWxsYmFjay5qcyIsIi4uL2ZyaWRhLXN5c2NhbGwtaW50ZXJjZXB0b3IvZGlzdC9pbmRleC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7O0FDQUEscUNBQStCO0FBQy9CLCtFQUE4RDtBQUc5RDs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0VBcUJFO0FBRUYsMEJBQTBCO0FBRTFCLEdBQUc7QUFDSCxJQUFJLFFBQVEsR0FBRyxNQUFNLENBQUMsZUFBZSxDQUFDLGtCQUFrQixDQUFFLENBQUM7QUFDM0QsSUFBSSxPQUFPLEdBQUcsUUFBUSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFHLDhCQUE4QjtBQUV0RSxZQUFHLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO0FBRWxCLHVDQUFXLENBQUMsT0FBTyxFQUFFLElBQUksY0FBYyxDQUFDLFVBQVUsS0FBSyxFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsS0FBSztJQUMxRSxJQUFJLElBQUksR0FBRyxRQUFRLENBQUMsV0FBVyxFQUFFLENBQUM7SUFFbEMsWUFBRyxDQUFDLG9CQUFvQixDQUFDLENBQUM7SUFDMUIsWUFBRyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsQ0FBQztJQUN0QixZQUFHLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxDQUFDO0lBQ3JCLFlBQUcsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLENBQUM7SUFDckIsWUFBRyxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsQ0FBQztJQUV0QixPQUFPLENBQUMsQ0FBQztBQUNiLENBQUMsRUFBRSxLQUFLLEVBQUUsQ0FBQyxLQUFLLEVBQUUsU0FBUyxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7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QztZQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxNQUFNLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVTtZQUM3QyxNQUFNLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNuQyxlQUFlO1lBQ2YsTUFBTSxDQUFDLGdCQUFnQixDQUFDLEtBQUssRUFBRSxRQUFRLENBQUMsQ0FBQztZQUN6QyxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hCLGtFQUFrRTtZQUNsRSxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsY0FBYyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsVUFBVTtZQUM3QyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUNsQyxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNoQyxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNoQyxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNoQyxNQUFNLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUNoQyxNQUFNLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztTQUNwQztRQUNELGdCQUFnQjtRQUNoQixxQ0FBcUM7UUFDckMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3BDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQztJQUNuQixDQUFDLENBQUMsQ0FBQztJQUNILE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUMsQ0FBQztJQUMvQixPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ25CLE9BQU8sQ0FBQyxHQUFHLENBQUMsc0JBQXNCLENBQUMsQ0FBQztJQUNwQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3hCLHNEQUFzRDtJQUN0RCxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksVUFBVSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQztJQUNoRSxzQ0FBc0M7SUFDdEMsT0FBTyxTQUFTLENBQUMsU0FBUyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7QUFDakQsQ0FBQyIsImZpbGUiOiJnZW5lcmF0ZWQuanMiLCJzb3VyY2VSb290IjoiIn0=

结果图

 缺点是不能对每一个inline的svc进行拦截,一次只能拦截一个

另外SVC的一些补充,在arm v8架构下SVC调用一定是把调用函数方法存在了x8寄存器上了,如下,scv #0 对应上面的x8寄存器的mov 值就是svc的调用方法。如下图close()函数对应的就是

 mov     x8, __NR_close

 如下所示如下图openat()函数对应的就是

mov     x8, __NR_openat

所以我们找到svc 0,x8寄存器最后一次值就是SVC调用的函数名

如下图所示 #0x38对应的是56,

在unistd.h中找到56对应的值就是_NR_openat

下图中找到svc 0,x8寄存器最后一次值 为#0x3f

 

 在unistd.h中找到0x3f=63对应的值就是_NR_read

 这个要想自动解析出调用哪些值,实现起来还是要一定难度的。

Supongo que te gusta

Origin blog.csdn.net/babytiger/article/details/120778317
Recomendado
Clasificación