当前位置:网站首页>[Android reverse] function interception instance (③ refresh CPU cache | ④ process interception function | ⑤ return specific results)
[Android reverse] function interception instance (③ refresh CPU cache | ④ process interception function | ⑤ return specific results)
2022-07-04 11:33:00 【Programmer community】
List of articles
- Preface
- One 、 Refresh CPU Cache
- Two 、 Handle interceptor function
- 1、 Pile function
- 2、 Handle interceptor function
- 3、 ... and 、 Return specific results
- Four 、 Relevant complete code
Preface
【Android reverse 】 Function intercept instance ( Function interception process | ① Locate the dynamic library and function location ) The blog briefly introduces hook function ( Function interception ) The process of , This blog series introduces function interception examples ;
Intercept clock_gettime
function ;
#include <time.h>int clock_gettime(clockid_t clk_id,struct timespec *tp);
【Android reverse 】 Function intercept instance ( ② Pile insertion operation | Save the actual function entry 6 Bytes of data | Write a jump instruction at the function entry of the plug-in | Construct the splice pile function ) The blog has carried out the pile insertion operation ,
One 、 Refresh CPU Cache
perform cache_flush
System call function Refresh CPU The cache of ; This step Only in ARM Architecturally CPU In the implementation of , x86 Architecturally CPU There is no need to refresh the cache ;
x86 There is no need to refresh the cache , But you can also perform system call operations syscall
To refresh the cache ;
Refresh CPU Cache Code example :pApi
Is the function pointer actually called , size
yes 6 byte , That is, refresh (int)pApi
Address to (int)pApi + size
Between
6
6
6 Byte corresponding CPU Just cache ;
/* Empty CPU Cache */#if !defined(__i386__) /* stay arm The schema must be refreshed CPU Cache , x86 No need to execute */ cacheflush((int)pApi, (int)pApi + size, ICACHE|DCACHE);#else /* x86 The system call can be executed under */ syscall(0xF002, (int)pApi,(int)pApi + sizeE);
Two 、 Handle interceptor function
1、 Pile function
stay 【Android reverse 】 Function intercept instance ( ② Pile insertion operation | Save the actual function entry 6 Bytes of data | Write a jump instruction at the function entry of the plug-in | Construct the splice pile function ) 3、 ... and 、 Write a jump instruction at the function entry of the plug-in | Construct the splice pile function Blog chapter , The splicing function is introduced do_clock_gettime
function , Implemented the call do_clock_gettime
function With the call clock_gettime
Function has the same effect ;
Construct the splice pile function : front 6 Bytes are saved clock_gettime
Front of function 6 Byte order , Up to the third day 6 Byte time , Jump directly to clock_gettime
function perform , This performs the spliced function Equivalent to the execution of clock_gettime
function ;
take do_clock_gettime
The function is constructed as clock_gettime
Function flow : perform do_clock_gettime
Methods the first 6 Byte instruction , Jump to clock_gettime
The function of the first 6 Byte instruction position , do_clock_gettime
Of 0 ~ 6 The byte instruction is clock_gettime
Before the actual function 6 byte , The reason for this definition , Because clock_gettime
Before 6 Bytes are overwritten with Jump command ;
2、 Handle interceptor function
Handle interceptor function :
When the function executes to clock_gettime
after , Will execute the inserted jump instruction , Jump to dn_clock_gettime
Function ;
In this function , You can call do_clock_gettime
function , Execute the original instructions ;
do_clock_gettime
Before and after function execution , Can insert their own business logic , Monitoring or modification can ;
Handle interceptor function Code example :
/* Intercept function , Intercept clock_gettime After the function , Jump here */int dn_clock_gettime(clockid_t id, struct timespec* ts) {
/*if (ts == NULL) { return -1; }*/ /* If the device implements a system call , You can call the original... Through this code clock_gettime function */ //int ret = syscall(__NR_clock_gettime, id, ts); /* What is actually called here is the original clock_gettime function If the system call is not implemented on the device , Use the following method to call the original clock_gettime function */ do_clock_gettime(id, ts); /* clock_gettime After the function is executed , Continue to implement some of your own implementation */ /* The code above is hook Live real code We can in real code front / Back Perform some customization */ if (id > CLOCK_MONOTONIC)return 0; if (clock_base[id] == 0.0) {
clock_base[id] = ts->tv_sec * 1000000000.0 + ts->tv_nsec; clock_new[id] = clock_base[id]; } else {
//mutex.lock(); double tick = ts->tv_sec * 1000000000.0 + ts->tv_nsec; //printf("tick : %f base: %f delta: %f\n", tick, clock_base[id], tick - clock_base[id]); if (tick > clock_base[id]) {
clock_new[id] += (tick - clock_base[id]) * time_scale; ts->tv_sec = (time_t)(clock_new[id] / 1000000000.0); ts->tv_nsec = (long)(fmod(clock_new[id], 1000000000.0)); clock_base[id] = tick; } //mutex.unlock(); } return 0;}
3、 ... and 、 Return specific results
Carry out the above dn_clock_gettime
The return value of the function , Is the final return result ;
Four 、 Relevant complete code
Here's the code , Only the function in the reverse code intercepts part of the code :
Calling code :
/* This is a hook In the standard library clock_gettime Function entry method , Jump to custom dn_clock_gettime In the method */hook_func((uint8_t*)clock_gettime, (uint8_t*)dn_clock_gettime, (uint8_t*)do_clock_gettime, 6);
Function intercept code :
/* hook The complete flow of the function , Jump instruction size yes 6 byte *//* This is a hook In the standard library clock_gettime Function entry method , Jump to custom dn_clock_gettime In the method *//* hook_func((uint8_t*)clock_gettime, (uint8_t*)dn_clock_gettime, (uint8_t*)do_clock_gettime, 6); */void hook_func(uint8_t* pApi, uint8_t* pUser, uint8_t* pStub, size_t size){
unsigned char code[64] = {
0 }; /* Save the entry of the function before inserting the pile 6 Bytes of data , Because then insert a pile , * Can use jump code 0xE9,0,0,0,0 Overwrite function entry memory * The function will eventually execute , You need to copy , For subsequent actual function calls */ memcpy(code, pApi, size); /* Function stakes , pApi Is the actual function , pUser Is the interception function that jumps to after inserting the pile */ write_code(pApi, pUser); /* perform size + pStub Position command , Jump directly to size + pApi Location Such as : perform do_clock_gettime Methods the first 6 Byte instruction , Jump to clock_gettime The function of the first 6 Byte instruction position do_clock_gettime Of 0 ~ 6 The byte instruction is clock_gettime Before the actual function 6 byte , The reason for this definition , Because clock_gettime Before 6 Bytes are overwritten with Jump command call do_clock_gettime Method , It's like calling */ write_code(size + pStub, size + pApi); /* Will duplicate 6 byte The code is stored in pStub Function 0 ~ 6 Byte position */ memcpy(pStub, code, size); /* Empty CPU Cache */#if !defined(__i386__) /* stay arm The schema must be refreshed CPU Cache , x86 No need to execute */ cacheflush((int)pApi, (int)pApi + size, ICACHE|DCACHE);#else /* x86 The system call can be executed under */ syscall(0xF002, (int)pApi,(int)pApi + sizeE);#endif}/* * unsigned char* pFunc * unsigned char* pStub * The above two parameters are two function pointers * * Be careful : Refresh after writing CPU Cache , call cache_flush System call function */int write_code(unsigned char* pFunc, unsigned char* pStub) {
/* obtain pFunc Function entrance , First get the address of the memory page where the function is located */ void* pBase = (void*)(0xFFFFF000 & (int)pFunc); /* Modify the properties of the entire memory page , It is amended as follows Can be read | Can write | Executable , * Avoid operation failure due to memory access problems * mprotect Function can only modify the properties of the entire page memory * Every Memory page It's big and small 4KB */ int ret = mprotect(pBase, 0x1000, PROT_WRITE | PROT_READ | PROT_EXEC); /* Failure to modify memory page properties */ if (ret == -1) {
perror("mprotect:"); return -1; }#if defined(__i386__) // arm Situation handling /* E9 yes JMP An unconditional jump order , Back 4 Byte is the address of the jump */ unsigned char code[] = {
0xE9,0,0,0,0 }; /* Calculation pStub Function jump address , Objective function pStub Address - The current function pFunc Address - 5 * Jump instruction The jump is Offset , Not an absolute address value */ *(unsigned*)(code + 1) = pStub - pFunc - 5; /* Copy the jump code to pFunc address , This is a pFunc Function's entry address */ memcpy(pFunc, code, sizeof(code));#else // arm Situation handling /* B An unconditional jump order */ unsigned char code[] = {
0x04,0xF0,0x1F,0xE5,0x00,0x00,0x00,0x00 }; /* arm The jump is an absolute address jump , Pass in pStub Function pointer is enough */ *(unsigned*)(code + 4) = (unsigned)pStub; /* Copy the machine code to the beginning of the function */ memcpy(pFunc, code, sizeof(code));#endif return 0;}/* Intercept function , Intercept clock_gettime After the function , Jump here */int dn_clock_gettime(clockid_t id, struct timespec* ts) {
/*if (ts == NULL) { return -1; }*/ /* If the device implements a system call , You can call the original... Through this code clock_gettime function */ //int ret = syscall(__NR_clock_gettime, id, ts); /* What is actually called here is the original clock_gettime function If the system call is not implemented on the device , Use the following method to call the original clock_gettime function */ do_clock_gettime(id, ts); /* clock_gettime After the function is executed , Continue to implement some of your own implementation */ /* The code above is hook Live real code We can in real code front / Back Perform some customization */ if (id > CLOCK_MONOTONIC)return 0; if (clock_base[id] == 0.0) {
clock_base[id] = ts->tv_sec * 1000000000.0 + ts->tv_nsec; clock_new[id] = clock_base[id]; } else {
//mutex.lock(); double tick = ts->tv_sec * 1000000000.0 + ts->tv_nsec; //printf("tick : %f base: %f delta: %f\n", tick, clock_base[id], tick - clock_base[id]); if (tick > clock_base[id]) {
clock_new[id] += (tick - clock_base[id]) * time_scale; ts->tv_sec = (time_t)(clock_new[id] / 1000000000.0); ts->tv_nsec = (long)(fmod(clock_new[id], 1000000000.0)); clock_base[id] = tick; } //mutex.unlock(); } return 0;}int do_clock_gettime(clockid_t which_clock, struct timespec* tp){
// not used , The actual code of this function in the kernel , Disassembly libc.so obtain /* These instructions are not important Will be covered , These instructions are mainly used to occupy the pit It's actually calling theta clock_gettime function The following assembly code will be overwritten as Jump code , Jump to clock_gettime function , Be careful , clock_gettime function Before 6 Byte instructions are copied to the function entry , Execution section 6 Byte position , Jump to clock_gettime function Of the 6 Byte position */ //return syscall(__NR_clock_gettime, which_clock, tp); __asm__ __volatile__("push %%ebx"::: "ebx"); __asm__ __volatile__("push %%ecx\n"::: "ecx"); __asm__ __volatile__("mov 12(%%esp),%%ebx"::: "ebx"); __asm__ __volatile__("mov 16(%%esp),%%ecx"::: "ecx"); __asm__ __volatile__("mov $0x109,%%eax"::: "eax"); __asm__ __volatile__("int $0x80"); __asm__ __volatile__("pop %%ecx":::"ecx"); __asm__ __volatile__("pop %%ebx":::"ebx"); __asm__ __volatile__("retn");}
边栏推荐
- QQ get group member operation time
- Practical dry goods: deploy mini version message queue based on redis6.0
- Canoe - the third simulation project - bus simulation - 2 function introduction, network topology
- Iptables cause heartbeat brain fissure
- 三立期货安全么?期货开户怎么开?目前期货手续费怎么降低?
- Dos and path
- Video analysis
- Elevator dispatching (pairing project) ④
- Solaris 10网络服务
- Summary of collection: (to be updated)
猜你喜欢
Reptile learning 4 winter vacation series (3)
Introduction to Lichuang EDA
[Yunju entrepreneurial foundation notes] Chapter II entrepreneur test 19
QQ group collection
[Yunju entrepreneurial foundation notes] Chapter II entrepreneur test 6
Post man JSON script version conversion
Attributes and methods in math library
[Yunju entrepreneurial foundation notes] Chapter II entrepreneur test 7
Some summaries of the 21st postgraduate entrance examination 823 of network security major of Shanghai Jiaotong University and ideas on how to prepare for the 22nd postgraduate entrance examination pr
Analysis function in SQL
随机推荐
CAPL: on sysVar_ Update difference on sysvar
Elevator dispatching (pairing project) ②
Post man JSON script version conversion
Function introduction of canbedded component
2021 annual summary - it seems that I have done everything except studying hard
Common built-in modules
[Yunju entrepreneurial foundation notes] Chapter II entrepreneur test 6
Install freeradius3 in the latest version of openwrt
Definition and method of string
Four sorts: bubble, select, insert, count
3W word will help you master the C language as soon as you get started - the latest update is up to 5.22
re. Sub() usage
No response after heartbeat startup
OSI model notes
QQ set group information
QQ get group settings
Games101 Lesson 8 shading 2 Notes
Application of slice
Common tips
Here, the DDS tutorial you want | first experience of fastdds - source code compilation & Installation & Testing