微风吹胖次 发表于 2020-12-28 23:53

arm64 inline hook

本帖最后由 微风吹胖次 于 2021-1-3 17:07 编辑

0.前言(来自菜鸟的挣扎)
代码写的很烂,海涵
希望各位大佬有建议请提出来
(排版好难)


2021.1.2更新指令修复
2021.1.3修复多函数hook
(代码在github上看吧)
1.方案

2.代码
汇编实现类

/*
实现汇编指令的头文件,实现我就不放这里了,有点长
*/
#ifndef WFCPC_REGISTERS_ARM64_H_
#define WFCPC_REGISTERS_ARM64_H_
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include <cstdlib>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include <iomanip>

namespace wfcpc
{
    namespace arm64
    {
      
      enum registers
      {
            q0 = 0,
            q1 = 1,
            q2 = 2,
            q3 = 3,
            q4 = 4,
            q5 = 5,
            q6 = 6,
            q7 = 7,
            q8 = 8,
            q9 = 9,
            q10 = 10,
            q11 = 11,
            q12 = 12,
            q13 = 13,
            q14 = 14,
            q15 = 15,
            x0 = 0,
            x1 = 1,
            x2 = 2,
            x3 = 3,
            x4 = 4,
            x5 = 5,
            x6 = 6,
            x7 = 7,
            x8 = 8,
            x9 = 9,
            x10 = 10,
            x11 = 11,
            x12 = 12,
            x13 = 13,
            x14 = 14,
            x15 = 15,
            x16 = 16,
            x17 = 17,
            x18 = 18,
            x19 = 19,
            x20 = 20,
            x21 = 21,
            x22 = 22,
            x23 = 23,
            x24 = 24,
            x25 = 25,
            x26 = 26,
            x27 = 27,
            x28 = 28,
            x29 = 29,
            x30 = 30,
            fp = 29,
            lr = 30,
            sp = 31,
      };
      uint32_t binToCode(bool* boo);
      void insertDec(bool * boo,int number,int pos,int width);
      uint32_t ldrImmi(uint32_t offset, enum registers rt, bool x64Ins);
      void insertReg(bool* boo, enum registers register_, int pos);
      void insertReg(bool* boo, int reg, int pos);
      uint32_t ldrImmi(uint32_t offset, int rt, bool x64Ins);
      uint32_t ldr_immi_unsigned_offst(uint32_t offset,enum registers rn,enum registers rt,bool x64);
      uint32_t br(enum registers rn);
      uint64_t reverseAddr(uint64_t addr);
      uint32_t binToCode2(bool* boo);
      uint32_t prfm_immi(uint32_t offset,enum registers rn,int rt);
      uint32_tblr(enum registers rn);
      uint32_t ldr_immi_unsigned_offst(uint32_t offset,enum registers rn,int rt,bool x64);
      uint32_t ret();
      uint32_t ldp_signed_offset(int32_t imm, enum registers rt2, enum registers rn, enum registers rt1, bool x64Ins);
      uint32_t ldr_immi_SIMD_FP_unsigned_offset(uint32_t offset,enum registers rn,int rt,int size);
      uint32_t sub(uint16_t imm,enum registers rn,enum registers rd);
      void insertOffset(bool* boo, int number, int pos, int width, bool x64Ins);
      uint32_t stp(int32_t imm, enum registers rt2, enum registers rn, enum registers rt1, bool x64Ins);
      uint32_t ldp(int8_t imm,enum registers rt2,enum registers rn,enum registers rt1,bool x64Ins);
      uint32_t add(uint16_t imm,enum registers rn,enum registers rd);
      uint32_t mov(uint16_t imm,enum registers rn,enum registers rd,bool x64Ins);
      void insertOffset2(bool* boo, int number, int pos, int width, bool x64Ins);
      uint32_t mrs_NZCV(enum registers rt);
      uint32_t msr_NZCV(enum registers rt);
      uint32_t mov_Reg(enum registers rn,enum registers rd,bool Reg64);
      uint32_t b(uint32_t offset);
      uint32_t bl(uint32_t offset);
      uint32_t nop();

      int get_need_fix_Ins_offset(uint32_t ins);
      uint32_t fix_ins(uint32_t ins,int offset);
    } // namespace arm64
}
#endif


临时保存代码的类

/*
临时保存代码段的类
*/
#ifndef CODES_ARM64_H_
#define CODES_ARM64_H_
#include "registers_arm64.h"
#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <sys/mman.h>
#include <errno.h>
#include <unistd.h>
#include <cstdlib>
#include <math.h>
#include <string.h>
#include <unistd.h>
#include <iomanip>

namespace wfcpc
{
      namespace arm64
      {
                class Codes
                {
               
                public:
                        Codes(int size_);
                        Codes();
                        int position=0;
                        int size;
                        uint8_t *code;
                        void emit(uint32_t c);
                        void emit(uint32_t c,int offset);
                        void emit(uint64_t c);
                        void emit(uint64_t c,int offset);
                        void * code_address;
                        void show_code_addr();
                };
      }
}
#endif // !CODES_ARM64_H_



主要实现类

#include "build_code.h"

namespace wfcpc
{
      namespace arm64
      {
                uint64_t Normal_Registers;
                long double Neon_Registers;
                uint64_t (*template_new_func)(uint64_t a,uint64_t b,uint64_t c,uint64_t d,uint64_t e,
                                                                        uint64_t f,uint64_t g,uint64_t h,long double i,long double j,long double k,long double l
                              ,long double m,long double n,long double o,long double p);//最多支持8个普通参数+8个浮点参数
                uint64_t template_orig_func();
                uint64_t (*template_orig_func_pointer)();

                //函数执行前获取寄存器值
                void get_args();
                void (*get_args_pointer)()=get_args;
                void check_register();

                //保存sp指针
                uint64_t sp_value=0,fake_sp_value=0;
                //保存lr值
                uint64_t lr_value=0;
                //保存的指针
                void *q0_pointer;
                void *x0_pointer;
                void *lr_pointer;
                //启动自己定义的函数
                uint64_t set_new_func();
                uint64_t (*set_new_func_pointer)()=set_new_func;
               
                //保存的原来函数的返回值
                uint64_t orig_x0_value;
                long double orig_q0_value;



      
                BuildCode::BuildCode()
                {}
                BuildCode::BuildCode(void* hook_addr_, void* new_address_, void** orig_addr_)
                {

                        this->hook_addr = hook_addr_;
                        this->orig_addr = orig_addr_;
                        this->new_addr = new_address_;
                }
                void BuildCode::hook_start()
                {
                        this->pagesize = sysconf(_SC_PAGE_SIZE);
                        if (this->pagesize == -1)
                        {
                              exit(errno);
                        }
                        this->func_before = mmap(nullptr, this->pagesize, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
                        this->func_after = mmap(nullptr, this->pagesize, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);

                        template_new_func=(uint64_t (*)(uint64_t a,uint64_t b,uint64_t c,uint64_t d,uint64_t e,
                                                                                        uint64_t f,uint64_t g,uint64_t h,long double i,long double j,long double k,long double l
                                        ,long double m,long double n,long double o,long double p))(this->new_addr);
                        template_orig_func_pointer=template_orig_func;
                        *(this->orig_addr)=*(void **)&template_orig_func_pointer;
                        this->set_mem_RWE();
                        this->build_step_1();//函数开头跳转
                        this->build_step_2();//函数执行前函数
                        this->build_step_3();//函数执行后函数
                        sleep(1.5);
      
                        this->set_mem_RE();
                }
               

                void BuildCode::build_step_1()
                {
                        this->jmp_code.emit(ldrImmi(2, x28, true));
                        this->jmp_code.emit(br(x28));
                        this->jmp_code.emit((uint64_t)this->func_before);
                        memcpy(this->back_up.code,this->hook_addr,sizeof(uint8_t)*16);
                }
                void BuildCode::build_step_2()
                {
                        this->code_before.emit(mrs_NZCV(x28));
                        this->code_before.emit(sub(0xf0, sp, sp));
                        this->code_before.emit(stp(0x0, x1, sp, x0, false));
                        this->code_before.emit(stp(0x10, x3, sp, x2, false));
                        this->code_before.emit(stp(0x20, x5, sp, x4, false));
                        this->code_before.emit(stp(0x30, x7, sp, x6, false));
                        this->code_before.emit(stp(0x40, x9, sp, x8, false));
                        this->code_before.emit(stp(0x50, x11, sp, x10, false));
                        this->code_before.emit(stp(0x60, x13, sp, x12, false));
                        this->code_before.emit(stp(0x70, x15, sp, x14, false));
                        this->code_before.emit(stp(0x80, x17, sp, x16, false));
                        this->code_before.emit(stp(0x90, x19, sp, x18, false));
                        this->code_before.emit(stp(0xA0, x21, sp, x20, false));
                        this->code_before.emit(stp(0xB0, x23, sp, x22, false));
                        this->code_before.emit(stp(0xC0, x25, sp, x24, false));
                        this->code_before.emit(stp(0xD0, x27, sp, x26, false));
                        this->code_before.emit(stp(0xE0, lr, sp, fp, false));
                        this->code_before.emit(sub(0x80, sp, sp));
                        this->code_before.emit(stp(0x0, q1, sp, q0, true));
                        this->code_before.emit(stp(0x20, q3, sp, q2, true));
                        this->code_before.emit(stp(0x40, q5, sp, q4, true));
                        this->code_before.emit(stp(0x60, q7, sp, q6, true));
      
                        this->code_before.emit(ldrImmi(25, x28, true));
                        this->code_before.emit(blr(x28));

                        this->code_before.emit(ldp_signed_offset(0x0, q1, sp, q0, true));
                        this->code_before.emit(ldp_signed_offset(0x20, q3, sp, q2, true));
                        this->code_before.emit(ldp_signed_offset(0x40, q5, sp, q4, true));
                        this->code_before.emit(ldp_signed_offset(0x60, q7, sp, q6, true));
                        this->code_before.emit(add(0x80, sp, sp));
                        this->code_before.emit(ldp_signed_offset(0x0, x1, sp, x0, false));
                        this->code_before.emit(ldp_signed_offset(0x10, x3, sp, x2, false));
                        this->code_before.emit(ldp_signed_offset(0x20, x5, sp, x4, false));
                        this->code_before.emit(ldp_signed_offset(0x30, x7, sp, x6, false));
                        this->code_before.emit(ldp_signed_offset(0x40, x9, sp, x8, false));
                        this->code_before.emit(ldp_signed_offset(0x50, x11, sp, x10, false));
                        this->code_before.emit(ldp_signed_offset(0x60, x13, sp, x12, false));
                        this->code_before.emit(ldp_signed_offset(0x70, x15, sp, x14, false));
                        this->code_before.emit(ldp_signed_offset(0x80, x17, sp, x16, false));
                        this->code_before.emit(ldp_signed_offset(0x90, x19, sp, x18, false));
                        this->code_before.emit(ldp_signed_offset(0xA0, x21, sp, x20, false));
                        this->code_before.emit(ldp_signed_offset(0xB0, x23, sp, x22, false));
                        this->code_before.emit(ldp_signed_offset(0xC0, x25, sp, x24, false));
                        this->code_before.emit(ldp_signed_offset(0xD0, x27, sp, x26, false));
                        this->code_before.emit(ldp_signed_offset(0xE0, lr, sp, fp, false));
                        this->code_before.emit(add(0xf0, sp, sp));
                        this->code_before.emit(msr_NZCV(x28));
               
                        this->code_before.emit(b(3));
                        this->code_before.emit((uint64_t)get_args_pointer);//获取函数开始时寄存器
                        this->code_before.emit(ldrImmi(2,lr,true));//修改lr寄存器,指向after
                        this->code_before.emit(b(3));
                        this->code_before.emit((uint64_t)this->func_after);//指向函数执行完成后函数
                        //指令修复
                        uint32_t *temp=(uint32_t*)this->hook_addr;
                        Fix f1=Fix(&this->code_before,temp,(uint64_t)(this->hook_addr),20);
               
                        Fix f2=Fix(&this->code_before,temp,(uint64_t)(this->hook_addr)+4,20+f1.addition_size);
                        
                        Fix f3=Fix(&this->code_before,temp,(uint64_t)(this->hook_addr)+8,20+f1.addition_size+f2.addition_size);
               
                        Fix f4=Fix(&this->code_before,temp,(uint64_t)(this->hook_addr)+12,20+f1.addition_size+f2.addition_size+f3.addition_size);
      
               
                        
                        this->code_before.emit(ldrImmi(2, x28, true));//跳转回原函数
                        this->code_before.emit(br(x28));
                        this->code_before.emit((uint64_t)hook_addr + 16);//返回函数继续执行
                        

                        memcpy(this->hook_addr, this->jmp_code.code_address, sizeof(uint8_t) * 16);
                        memcpy(this->func_before, this->code_before.code_address, sizeof(uint8_t) * this->code_before.size);
      

                }
      
                void BuildCode::build_step_3()
                {
                        this->code_after.emit(mrs_NZCV(x28));
                        this->code_after.emit(sub(0xf0, sp, sp));
                        this->code_after.emit(stp(0x0, x1, sp, x0, false));
                        this->code_after.emit(stp(0x10, x3, sp, x2, false));
                        this->code_after.emit(stp(0x20, x5, sp, x4, false));
                        this->code_after.emit(stp(0x30, x7, sp, x6, false));
                        this->code_after.emit(stp(0x40, x9, sp, x8, false));
                        this->code_after.emit(stp(0x50, x11, sp, x10, false));
                        this->code_after.emit(stp(0x60, x13, sp, x12, false));
                        this->code_after.emit(stp(0x70, x15, sp, x14, false));
                        this->code_after.emit(stp(0x80, x17, sp, x16, false));
                        this->code_after.emit(stp(0x90, x19, sp, x18, false));
                        this->code_after.emit(stp(0xA0, x21, sp, x20, false));
                        this->code_after.emit(stp(0xB0, x23, sp, x22, false));
                        this->code_after.emit(stp(0xC0, x25, sp, x24, false));
                        this->code_after.emit(stp(0xD0, x27, sp, x26, false));
                        this->code_after.emit(stp(0xE0, lr, sp, fp, false));
                        this->code_after.emit(sub(0x80, sp, sp));
                        this->code_after.emit(stp(0x0, q1, sp, q0, true));
                        this->code_after.emit(stp(0x20, q3, sp, q2, true));
                        this->code_after.emit(stp(0x40, q5, sp, q4, true));
                        this->code_after.emit(stp(0x60, q7, sp, q6, true));

                        this->code_after.emit(ldrImmi(25,x28,true));
                        this->code_after.emit(blr(x28));

                        this->code_after.emit(ldp_signed_offset(0x0, q1, sp, q0, true));
                        this->code_after.emit(ldp_signed_offset(0x20, q3, sp, q2, true));
                        this->code_after.emit(ldp_signed_offset(0x40, q5, sp, q4, true));
                        this->code_after.emit(ldp_signed_offset(0x60, q7, sp, q6, true));
                        this->code_after.emit(add(0x80, sp, sp));
                        this->code_after.emit(ldp_signed_offset(0x0, x1, sp, x0, false));
                        this->code_after.emit(ldp_signed_offset(0x10, x3, sp, x2, false));
                        this->code_after.emit(ldp_signed_offset(0x20, x5, sp, x4, false));
                        this->code_after.emit(ldp_signed_offset(0x30, x7, sp, x6, false));
                        this->code_after.emit(ldp_signed_offset(0x40, x9, sp, x8, false));
                        this->code_after.emit(ldp_signed_offset(0x50, x11, sp, x10, false));
                        this->code_after.emit(ldp_signed_offset(0x60, x13, sp, x12, false));
                        this->code_after.emit(ldp_signed_offset(0x70, x15, sp, x14, false));
                        this->code_after.emit(ldp_signed_offset(0x80, x17, sp, x16, false));
                        this->code_after.emit(ldp_signed_offset(0x90, x19, sp, x18, false));
                        this->code_after.emit(ldp_signed_offset(0xA0, x21, sp, x20, false));
                        this->code_after.emit(ldp_signed_offset(0xB0, x23, sp, x22, false));
                        this->code_after.emit(ldp_signed_offset(0xC0, x25, sp, x24, false));
                        this->code_after.emit(ldp_signed_offset(0xD0, x27, sp, x26, false));
                        this->code_after.emit(ldp_signed_offset(0xE0, lr, sp, fp, false));
                        this->code_after.emit(add(0xf0, sp, sp));
                        this->code_after.emit(msr_NZCV(x28));

                        this->code_after.emit(ret());
                        this->code_after.emit((uint64_t)set_new_func_pointer);
      
                        memcpy(this->func_after,this->code_after.code_address,sizeof(uint8_t) * this->code_after.size);
                }


                void BuildCode::set_mem_RWE()
                {
                        uint64_t p = (uint64_t)(void *)(this->func_before);
                        void* p1 = (void*)(p - p % this->pagesize);
                        if (mprotect(p1, this->pagesize, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
                        {
                              perror("mprotect error1");
                              exit(errno);
                        }
                        p = (uint64_t)this->hook_addr;
                        void* p2= (void*)(p - p % this->pagesize);
                        if (mprotect(p2, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
                        {
                              perror("mprotect error2");
                              exit(errno);
                        }
                        p=(uint64_t)(void *)(this->func_after);
                        void* p3= (void*)(p - p % this->pagesize);
                        if (mprotect(p3, pagesize, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
                        {
                              perror("mprotect error3");
                              exit(errno);
                        }

                }
                void BuildCode::set_mem_RE()
                {
                        uint64_t p = (uint64_t)this->func_before;
                        void* p1 = (void*)(p - p % this->pagesize);
                        if (mprotect(p1, pagesize, PROT_READ | PROT_EXEC) == -1)
                        {
                              perror("mprotect error4");
                              exit(errno);
                        }
                        p = (uint64_t)this->hook_addr;
                        void* p2 = (void*)(p - p % this->pagesize);
                        if (mprotect(p2, pagesize,PROT_READ|PROT_EXEC) == -1)
                        {
                              perror("mprotect error5");
                              exit(errno);
                        }
                        p=(uint64_t)(void *)(this->func_after);
                        void* p3= (void*)(p - p % this->pagesize);
                        if (mprotect(p3, pagesize, PROT_READ | PROT_EXEC) == -1)
                        {
                              perror("mprotect error6");
                              exit(errno);
                        }
                }




                void get_args()
                {
#if defined(__aarch64__)
                        __asm__ __volatile__(
                        "mov %0,sp\n"
                        :"+&r"(fake_sp_value)
                        :
                        :"memory"
                        );
#endif
                        check_register();
                        return;

                }
                void check_register()
                {
      
                        sp_value=fake_sp_value+0x10;
               
                        q0_pointer=(void *)sp_value;
                        x0_pointer=(void *)(sp_value+0x80);
                        lr_pointer=(void *)(sp_value+0x80+29*0x8);
                        for(int i=0;i<8;i++)
                        {
                              Neon_Registers=((long double*)sp_value);
                              Normal_Registers=((uint64_t*)(sp_value+0x80));
                        }
                        lr_value=((uint64_t*)(sp_value+0x80));
                        
                        return;
                }
               
                uint64_t set_new_func()
                {
               
                        
                        orig_x0_value=*((uint64_t*)x0_pointer);
                        //调用自己定义的函数
                        uint64_t temp_ret_value=(*template_new_func)(Normal_Registers,Normal_Registers
                                        ,Normal_Registers,Normal_Registers,Normal_Registers,Normal_Registers
                                        ,Normal_Registers,Normal_Registers,Neon_Registers,Neon_Registers
                                        ,Neon_Registers,Neon_Registers,Neon_Registers,Neon_Registers
                                        ,Neon_Registers,Neon_Registers);
      
#if defined(__aarch64__)
                        __asm__ __volatile__(
                        "str q0,[%0]\n"//push q0
                        "str %1,[%2]\n"//push x0
                        "str %3,[%4]"//push lr
                        :
                        :"r"(q0_pointer),"r"(temp_ret_value),"r"(x0_pointer),"r"(lr_value),"r"(lr_pointer)
                        :"memory"
                        );
#endif
                        return temp_ret_value;
                }

                uint64_t template_orig_func()
                {
#if defined(__aarch64__)
                        __asm__ __volatile__(
                        "ldr q0,[%0]\n"
                        :
                        :"r"(q0_pointer)
                        :
                        );
#endif
                        return orig_x0_value;
                }
      
      }
}


指令修复类

#include "fix.h"
namespace wfcpc
{
    namespace arm64
    {
      
      
         
      
            
            uint32_t ins;
            uint64_t pc;
            bool pc_bin={0};
            bool ins_bin={0};
            int offset;
            int local_size=0;
            int addition_size=0;
            Fix::Fix(Codes *_code,uint32_t _ins,uint64_t _pc,int _offset)
            {
                this->code=_code;
                this->ins=_ins;
                this->pc=_pc;
                this->offset=_offset;
               
                for (int i = 63; i >= 0; i--)
                {
                  pc_bin = bool((ins >> i) & 1);
                }
                set_ins_bin();
                enum InsType instype=check_ins();
                int ins_type=int(instype);
                switch (ins_type)
                {
                case 0:
                  fix_ADR();
                  break;
                case 1:
                  fix_ADRP();
                  break;
                case 2:
                  fix_B_Cond();
                  break;
                case 3:
                  fix_B();
                  break;
                case 4:
                  fix_BL();
                  break;
                case 5:
                  fix_BLR();
                  break;
                case 6:
                  fix_BLRAAZ();
                  break;
                case 7:
                  fix_BLRAA();
                  break;
                case 8:
                  fix_BLRABZ();
                  break;
                case 9:
                  fix_BLRAB();
                  break;
                case 10:
                  fix_CBNZ();
                  break;
                case 11:
                  fix_CBZ();
                  break;
                case 12:
                  fix_LDR_LITERAL();
                  break;
                case 13:
                  fix_LDRSW_LITERAL();
                  break;
                case 14:
                  fix_PRFM_LITERAL();
                  break;
                case 15:
                  fix_TBNZ();
                  break;
                case 16:
                  fix_TBZ();
                  break;
                case 17:
                  fix_LDR_LITERAL_SIMD_FP();
                  break;
                case 99:
                  set_orig();
                  break;
                default:
                  set_orig();
                  break;
                }

            }

            void Fix::set_orig()
            {
                this->code->emit(this->ins);
            }
            void Fix::set_ins_bin()
            {
                bool temp={0};
                for (int i = 31; i >= 0; i--)
                {
                  temp = bool((ins >> i) & 1);
                }
                for (int i = 0; i < 4; i++)
                {
                  for (int j = 0; j < 8; j++)
                  {
                        ins_bin = temp;
                  }
                }
            }
            void Fix::fix_ADR()
            {
                int rd=0;
                bool xd_bin={0};
                uint64_t xd=0;
                bool imm={0};
                int immhi=19,immlo=2,i=63,j=2;
                while(immlo--)
                {
                  imm=ins_bin;
                }
                j=26;
                while(immhi--)
                {
                  imm=ins_bin;
                }
                int loop=64;
                bool up=false;
                for(int i=0;i<12;i++)
                {
                  pc_bin=0;
                }
                while(loop--)
                {
                  int add=ins_bin+pc_bin;
                  if(up)
                  {
                        add++;
                        up=false;
                  }
                  if (add>=2)
                  {
                        up=true;
                        xd_bin=add%2;
                  }else
                  {
                        xd_bin=add;
                  }
                }
                loop=64;
                int n=0;
                while(loop--)
                {
                  xd+=xd_bin*pow(2,n++);
                }
                loop=5,n=0;
                while(loop--)
                {
                  rd+=xd_bin*pow(2,n++);
                }
                code->emit(ldrImmi(this->offset,rd,true));
                this->local_size=1;
                code->emit(xd,this->offset);
                this->addition_size=2;

            }
            void Fix::fix_ADRP()
            {
                int rd=0;
                bool xd_bin={0};
                uint64_t xd=0;
                bool imm={0};
                int immhi=19,immlo=2,i=63,j=2,loop=12;
                while(loop--)
                {
                  imm=0;
                }
                while(immlo--)
                {
                  imm=ins_bin;
                }
                j=26;
                while(immhi--)
                {
                  imm=ins_bin;
                }

                loop=64;
                bool up=false;
                while(loop--)
                {
                  int add=ins_bin+pc_bin;
                  if(up)
                  {
                        add++;
                        up=false;
                  }
                  if (add>=2)
                  {
                        up=true;
                        xd_bin=add%2;
                  }else
                  {
                        xd_bin=add;
                  }
                }
                loop=64;
                int n=0;
                while(loop--)
                {
                  xd+=xd_bin*pow(2,n++);
                }
                loop=5,n=0;
                while(loop--)
                {
                  rd+=xd_bin*pow(2,n++);
                }
                code->emit(ldrImmi(this->offset,rd,true));
                this->local_size=1;
                code->emit(xd,this->offset);
                this->addition_size=2;
            }
            void Fix::fix_B_Cond()
            {
                int pos=26,loop=19,immi19=0,times=0;
                while(loop--)
                {
                  immi19+=ins_bin*pow(2,times++);
                }
                uint64_t pc_fixed=this->pc+immi19*4;
                loop=19,pos=26;
                while(loop!=0&&this->offset!=0)
                {
                  ins_bin=this->offset%2;
                  this->offset/=2;
                  loop--;
                }
                uint32_t ins_fixed=binToCode2(ins_bin);
                code->emit(ins_fixed);
                code->emit(ldrImmi(2,x28,true),this->offset);
                code->emit(br(x28),this->offset+1);
                code->emit(pc_fixed,this->offset+2);
                this->local_size=1;
                this->addition_size=4;

            }
            void Fix::fix_B()
            {
                int pos=31,loop=26,immi26=0,times=0;
                while(loop--)
                {
                  immi26+=ins_bin*pow(2,times++);
                }
                uint64_t pc_fixed=this->pc+immi26*4;
                loop=26,pos=31;
                while(loop!=0&&this->offset!=0)
                {
                  ins_bin=this->offset%2;
                  this->offset/=2;
                  loop--;
                }
                uint32_t ins_fixed=binToCode2(ins_bin);
                code->emit(ins_fixed);
                code->emit(ldrImmi(2,x28,true),this->offset);
                code->emit(br(x28),this->offset+1);
                code->emit(pc_fixed,this->offset+2);
                this->local_size=1;
                this->addition_size=4;
            }
            void Fix::fix_BL()
            {
                int pos=31,loop=26,immi26=0,times=0;
                while(loop--)
                {
                  immi26+=ins_bin*pow(2,times++);
                }
                uint64_t pc_fixed=this->pc+immi26*4;
                loop=26,pos=31;
                while(loop!=0&&this->offset!=0)
                {
                  ins_bin=this->offset%2;
                  this->offset/=2;
                  loop--;
                }
                uint32_t ins_fixed=binToCode2(ins_bin);
                code->emit(ins_fixed);
                code->emit(ldrImmi(3,lr,true),this->offset);
                code->emit(ldrImmi(4,x28,true),this->offset+1);
                code->emit(br(x28),this->offset+2);
                code->emit(this->pc+4,this->offset+3);
                code->emit(pc_fixed,this->offset+5);
                this->local_size=1;
                this->addition_size=7;
            }
            void Fix::fix_BLR()
            {
                int op1=9,op2=10;
                ins_bin=0,ins_bin=0;
                uint32_t ins_fixed=binToCode2(ins_bin);
                code->emit(ldrImmi(offset,lr,true));
                code->emit(ins_fixed);
                code->emit(this->pc+4,this->offset);
                this->local_size=2;
                this->addition_size=2;
            }
            void Fix::fix_BLRAAZ()
            {
                this->fix_BLR();
            }
            void Fix::fix_BLRAA()
            {
                this->fix_BLR();
            }
            void Fix::fix_BLRABZ()
            {
                this->fix_BLR();;
            }
            void Fix::fix_BLRAB()
            {
                this->fix_BLR();
            }
            void Fix::fix_CBNZ()
            {
                this->fix_B_Cond();

            }
            void Fix::fix_CBZ()
            {
                this->fix_B_Cond();
            }
            void Fix::fix_LDR_LITERAL()
            {
                bool x64=ins_bin;
                int immi19=0,rd=0;
                int pos=26,loop=19;
                while(loop--)
                {
                  immi19+=ins_bin*pow(2,immi19++);
                }
                uint64_t pc_fixed=this->pc+immi19*4;
                pos=31,loop=5;
                while(loop--)
                {
                  rd+=ins_bin*pow(2,rd++);
                }
                code->emit(ldrImmi(offset,x28,true));
                code->emit(ldr_immi_unsigned_offst(0,x28,rd,x64));
                code->emit(pc_fixed,this->offset);
                this->local_size=2;
                this->addition_size=2;
            }
            void Fix::fix_LDRSW_LITERAL()
            {
                bool x64=true;
                int immi19=0,rd=0;
                int pos=26,loop=19;
                while(loop--)
                {
                  immi19+=ins_bin*pow(2,immi19++);
                }
                uint64_t pc_fixed=this->pc+immi19*4;
                pos=31,loop=5;
                while(loop--)
                {
                  rd+=ins_bin*pow(2,rd++);
                }
                code->emit(ldrImmi(offset,x28,true));
                code->emit(ldr_immi_unsigned_offst(0,x28,rd,x64));
                code->emit(pc_fixed,this->offset);
                this->local_size=2;
                this->addition_size=2;
            }
            void Fix::fix_PRFM_LITERAL()
            {
                int immi19=0,rd=0;
                int pos=26,loop=19;
                while(loop--)
                {
                  immi19+=ins_bin*pow(2,immi19++);
                }
                uint64_t pc_fixed=this->pc+immi19*4;
                pos=31,loop=5;
                while(loop--)
                {
                  rd+=ins_bin*pow(2,rd++);
                }
                code->emit(ldrImmi(offset,x28,true));
                code->emit(prfm_immi(0,x28,rd));
                code->emit(pc_fixed,this->offset);
                this->local_size=2;
                this->addition_size=2;
            }
            void Fix::fix_TBNZ()
            {
                int pos=26,loop=14,immi14=0,times=0;
                while(loop--)
                {
                  immi14+=ins_bin*pow(2,times++);
                }
                uint64_t pc_fixed=this->pc+immi14*4;
                pos=26,loop=14,times=0;
                while(loop--)
                {
                  offset+=ins_bin*pow(2,times++);
                }
                loop=14,pos=26;
                while(loop!=0&&this->offset!=0)
                {
                  ins_bin=this->offset%2;
                  this->offset/=2;
                  loop--;
                }
                uint32_t ins_fixed=binToCode2(ins_bin);
                code->emit(ins_fixed);
                code->emit(ldrImmi(2,x28,true),this->offset);
                code->emit(br(x28),this->offset+1);
                code->emit(pc_fixed,this->offset+2);
                this->local_size=1;
                this->addition_size=4;
            }
            void Fix::fix_TBZ()
            {
                fix_TBNZ();
            }
            void Fix::fix_LDR_LITERAL_SIMD_FP()
            {
                bool opc1,opc2;
                opc1=ins_bin;
                opc2=ins_bin;
                int size=0;
                if(!opc1&&!opc2)
                  size=32;
                else if(!opc1&&opc2)
                  size=64;
                else if(opc1&&!opc2)
                  size=128;
                int rd=0;
                int pos=26,loop=19,immi19=0,times=0;
                while(loop--)
                {
                  immi19+=ins_bin*pow(2,times++);
                }
                uint64_t pc_fixed=this->pc+immi19*4;
                loop=19,pos=26;
                while(loop!=0&&this->offset!=0)
                {
                  ins_bin=this->offset%2;
                  this->offset/=2;
                  loop--;
                }
                pos=31,loop=5;
                while(loop--)
                {
                  rd+=ins_bin*pow(2,rd++);
                }
                uint32_t ins_fixed=binToCode2(ins_bin);
                code->emit(ldrImmi(offset,x28,true));
                code->emit(ldr_immi_SIMD_FP_unsigned_offset(0,x28,rd,size));
                code->emit(pc_fixed,this->offset);
                this->local_size=2;
                this->addition_size=2;
            }
            enum Fix::InsType Fix::check_ins()
            {
                bool temp = { 0 };
                for (int i = 31; i >= 0; i--)
                {
                  temp = bool((ins >> i) & 1);
                }
                for (int i = 0; i < 4; i++)
                {
                  for (int j = 0; j < 8; j++)
                  {
                        ins_bin = temp;
                  }
                }
                if (ins_bin==1&&ins_bin==0&&ins_bin==0&&ins_bin==0&&ins_bin==0)
                {
                  if(ins_bin==0)
                        return ADR;
                  else
                        return ADRP;
                }

                if (ins_bin==0&&ins_bin==1&&ins_bin==1&&ins_bin==1&&
                ins_bin==1&&ins_bin==1&&ins_bin==1&&ins_bin==1&&ins_bin==0)
                  return B_Cond;

                if(ins_bin==0&&ins_bin==0&&ins_bin==1&&
                ins_bin==0&&ins_bin==1)
                {
                  if(ins_bin==0)
                        return B;
                  else
                        return BL;
                }
               
                if(ins_bin==1&&ins_bin==1&&ins_bin==0&&ins_bin==1
                &&ins_bin==0&&ins_bin==1&&ins_bin==1&&ins_bin==0
                &&ins_bin==0&&ins_bin==0&&ins_bin==1&&ins_bin==1
                &&ins_bin==1&&ins_bin==1&&ins_bin==1&&ins_bin==1
                &&ins_bin==0&&ins_bin==0&&ins_bin==0&&ins_bin==0
                &&ins_bin==0&&ins_bin==0
                &&ins_bin==0
                &&ins_bin==0&&ins_bin==0&&ins_bin==0&&ins_bin==0)
                  return BLR;

                if(ins_bin==1&&ins_bin==1&&ins_bin==0&&ins_bin==1
                &&ins_bin==0&&ins_bin==1&&ins_bin==1
                &&ins_bin==0&&ins_bin==0&&ins_bin==1&&ins_bin==1
                &&ins_bin==1&&ins_bin==1&&ins_bin==1&&ins_bin==1
                &&ins_bin==0&&ins_bin==0&&ins_bin==0&&ins_bin==0
                &&ins_bin==1)
                {
                  if(ins_bin==0&&ins_bin==0
                  &&ins_bin==1&&ins_bin==1&&ins_bin==1&&ins_bin==1
                  &&ins_bin==1)
                        return BLRAAZ;
                  else if(ins_bin==1&&ins_bin==0)
                        return BLRAA;
                  else if(ins_bin==1&&ins_bin==1)
                        return BLRAB;
                }

                if(ins_bin==0&&ins_bin==1&&ins_bin==1
                &&ins_bin==0&&ins_bin==1&&ins_bin==0)
                {
                  if(ins_bin==1)
                        return CBNZ;
                  else
                        return CBZ;
                }
               
                if(ins_bin==0&&ins_bin==1
                &&ins_bin==1&&ins_bin==0&&ins_bin==0&&ins_bin==0)
                {
                  if(ins_bin==0)
                        return LDR_LITERAL;
                  else if(ins_bin==1&&ins_bin==0)
                        return LDRSW_LITERAL;
                  else if(ins_bin==1&&ins_bin==1)
                        return PRFM_LITERAL;
                }
               
                if(ins_bin==0&&ins_bin==1&&ins_bin==1
                &&ins_bin==0&&ins_bin==1&&ins_bin==1&&ins_bin==1)
                {
                  if(ins_bin==1)
                        return TBNZ;
                  else
                        return TBZ;
                }
               
                if(ins_bin==0&&ins_bin==1
                &&ins_bin==1&&ins_bin==1&&ins_bin==0&&ins_bin==0)
                {
                  if (ins_bin==0&&ins_bin==0)
                        return LDR_LITERAL_SIMD_FP;
                  else if(ins_bin==0&&ins_bin==1)   
                        return LDR_LITERAL_SIMD_FP;
                  else if(ins_bin==1&&ins_bin==0)   
                        return LDR_LITERAL_SIMD_FP;
                }
                return NONE;
            }
      
      
      
    } // namespace arm64
   
} // namespace wfcpc





编译运行

(放到majisk模块测试过,某日服的某非洲抽卡游戏)


3.github
github.com/wfcpc/ARM64InlineHook

lingyinGR 发表于 2020-12-29 00:07

感谢分享

请叫我老龚 发表于 2020-12-29 00:35

gcode 发表于 2020-12-29 08:18

大神啊,学习了,

Bruce_HD 发表于 2020-12-29 10:05

我就是来看看。

诗雨晴天 发表于 2020-12-29 10:12

谢谢分享

tabirs 发表于 2020-12-29 10:39


谢谢分享

mdhexplorer 发表于 2020-12-29 10:41

学习了!感谢

wjs998 发表于 2020-12-29 15:41

大神   请收下我的膝盖

一剑封侯人 发表于 2020-12-29 17:43

看不懂 先顶帖真大佬
页: [1] 2
查看完整版本: arm64 inline hook