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 感谢分享 大神啊,学习了, 我就是来看看。 谢谢分享
谢谢分享 学习了!感谢 大神 请收下我的膝盖
看不懂 先顶帖真大佬
页:
[1]
2