frida hook svc调用_babytiger的博客-程序员ITS301_svc调用

技术标签: c++  android  lineageOS  frida  

如下图所示,当别人在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的博客-程序员ITS301一、目标现在很多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-程序员ITS3010x0 简述: 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

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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/babytiger/article/details/120778317

智能推荐

七年级 电子计算机 教材分析,七年级计算机教学计划_weixin_39955938的博客-程序员ITS301

根据计划内容的明确性指标,可以将计划分具体性计划和指导性计划。以下是小编收集的计算机教学计划相关内容,欢迎查看!一、指导思想当今人类社会已经进入21世纪,以计算机、网络和通信技术为核心的现代信息技术在社会各个领域都得到了广泛的应用,并逐渐改变着人们的学习、工作和生活方式。信息的获取、传输、处理和应用能力已经成为现代新人类最基本的能力与文化水平的标志。在这种大环境下,本学期的信息技术教学工作,将严格...

Java-lambda表达式入门看这一篇就够了_吾仄lo咚锵的博客-程序员ITS301

Lambda表达式,也可称为闭包,是JDK8的新特性。Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中),可以使代码变的更加简洁紧凑。Lambda表达式是一个可传递的代码块,可以在以后执行一次或多次。文章目录概述语法函数式接口方法引用构造器引用变量作用域处理lambda表达式

如何调出手机信任计算机的指令,苹果手机怎么连接到电脑上面去发(苹果在哪设置信任电脑)..._艺空的博客-程序员ITS301

iphone怎么连接到电脑?现在iphone的普及率还算是比较高的,但是现在让很多网友郁闷的是不知道自己的iphone怎么链接到电脑上去。iPhone和其他Android智能手机不一样,连接电脑以后,如果不安装PC端的管理软件,并不能对其进行任何的操作。iPhone6连接电脑的方法有很多,可以在电脑上安装iTunes最新版,大家百度一下iTunes的安装使用方法即可。但根据多数用户的体验,用iTu...

iPhone 12 Pro Max详尽拆解:物料成本竟都不到2900元!_北极网络的博客-程序员ITS301_iphone12max拆解

虽然在10月14日苹果就正式发布了iPhone 12系列,但是直到本月初,苹果iPhone 12 Pro Max才正式开售,而且由于供应问题,在线下单后可能也要等到3-4周才会发货。近日,专业拆解机构iFixit在拿到iPhone 12 Pro Max之后,也对这款手机进行了专业的拆解。首先我们来回顾一下iPhone 12 Pro Max的配置。与之前拆解过的iPhone 12 Pro相比,iPhone 12 Pro Max的屏幕尺寸进一步提高到了6.7英寸,分辨率为2778 x 1284。另一

DatabaseMetaData之获取数据库所有表_猿_area的博客-程序员ITS301

获取数据库的所有表:(以MySQL和Oracle为例,其他类型的数据库接触不过,不做解释)Connection接口中提供了DatabaseMetaData接口:提供:getTables()方法,该方法需要传进4个参数:第一个是数据库名称,对于MySQL,则对应相应的数据库,对于Oracle来说,则是对应相应的数据库实例,可以不填,也可以直接使用Connection的实例对象

Cheat Engine 保姆级教程(官方 1 - 12 关)_cheat engine官网_三鱼子的博客-程序员ITS301

本文讲解很详细,都为本人亲身实践软件下载链接Cheat Engine 软件可直接在官网下载(英文版)官网链接:https://cheatengine.org/本文使用 Cheat Engine 7.3 汉化版链接:https://pan.baidu.com/s/1QnPvvN00ghiUHCOYs-Zj3Q提取码:f4se1:准备工作2 - 9 为文字关,10 - 12 为图形关,软件下载解压后打开即可使用教程点击此处打开,此处我们打开 64 位教程然后添加进程,如下图2:精确值

随便推点

OOBInline属性为false,server接收了client通过sendUrgentData 发送的紧急数据包_lingjun_yang的博客-程序员ITS301

前几天前置上线遇到一问题,大体情况是这样有一个加密服务,对外暴露tcp通讯接口,client端建立连接池,启N个连接(长连接),每次报文通讯之前先通过client端的sendUrgentData(0XFF)方法发送心跳包,用以检测信路是否正常.然后计算待发送报文的长度,将其转换成byte拼在发送报文前面(3字节长)发送报文,服务端read3字节报文并将其转换成报文长度,再根据该长度read

linux socketpair(UNIX domain socket)_win_lin的博客-程序员ITS301_linux socketpair

/*g++ sp_block.cpp -g -O0 -o sp_block*/#include #include // socketpair#include #include // fork#include #include // atoi#include // errno#include // strerror#include int RecvFD(i

Ubuntu Linux 永久挂载(mount)分区_齐格Insight的博客-程序员ITS301

一般情况下,我们想挂载一个分区的办法就是用mount命令,如我想把/dev/sda3挂载到/media/aborn/data下使用以下命令即可sudo mount /dev/sda3 /media/aborn/data但这种方法有个不好的都方是机器重启后变又得手工重新挂载.那么永久性挂载分区的办法是修改分区表/etc/fstab我的分区文件/etc/fstab如下:首先我

冯·诺依曼计算机特点_白芷加茯苓的博客-程序员ITS301_冯诺依曼计算机的特点

冯·诺依曼计算机特点冯·诺依曼,20世纪最重要的数学家之一。在现代计算机、博弈论、核武器和生化武器等众多领域内有杰出建树的最伟大的科学全才之一,被后人称为“计算机之父”和“博弈论之父”。一、冯·诺依曼计算机结构二、冯·诺依曼计算机的特点计算机由五大部件组成:存储器,运算器,控制器,输入设备,输出设备。指令和数据以同等地位存于存储器,可按地址顺序访问。指令和数据用二进制表示。指令由操作码和地址码组成。存储程序,程序在计算机中顺序存放。以运算器为中心。(不合理:花大量的时间进行数据传输,降

Itext笔记1_myjavax的博客-程序员ITS301

在Web应用中动态创建PDF文件原文:Sean C. Sullivan    翻译:gagaghost  在一个最近的后勤项目中,客户要求我们建一个能让用户能从一个遗留系统查询出货信息的Web站点,有三个主要的需求:  1.出货信息必须以PDF文档的格式返回;  2.PDF文件必须能通过浏览器下载;  3.PDF文件必须能用Adobe Acrobat Reader阅读;尽管我们的团队...

linux网络编程之inet_pton和inet_ntop函数_码莎拉蒂 .的博客-程序员ITS301

Linux下这2个IP地址转换函数,可以在将IP地址在“点分十进制”和“整数”之间转换  而且,inet_pton和inet_ntop这2个函数能够处理ipv4和ipv6。算是比较新的函数了。  1、inet_pton函数原型如下[将“点分十进制” -> “整数”]  #include   #include   #include   int inet_p

推荐文章

热门文章

相关标签