Welcome to the iOS Reverse series.
- IOS reverse RSA theory
- IOS reverse hash theory
- IOS reverse application re-signature + wechat re-signature combat
- IOS reverse Shell script + script re-signature
- IOS reverse code injection +Hook
- IOS reverse MachO file
- IOS reverse dyLD process
- IOS reverse HOOK principle of Fishhook
- IOS reverse LLDB debugging
Writing in the front
Method Swizzling is a Hook solution that can dynamically change methods based on Runtime. However, Method Swizzling has its own limitations. This article will systematically introduce what HOOK and fishhook are
1. HOOK Overview
1. The HOOK definition
HOOK translated into Chinese “HOOK”, “HOOK”, in the field of iOS reverse refers to a technology to change the running process of the program, through HOOK can make other people’s program to execute their own code
The following schematic diagram is a visual interpretation of HOOK function:
- Inject malicious code to make users think that they have clocked in successfully, but they have not actually clocked in (only modify the intermediate process)
- Inject malicious code to fool users into thinking there is a problem with the network (open up a new branch of the process)
2. The HOOK
There are several HOOK technologies in iOS:
- Method Swizzling: Using the OC Runtime feature, dynamic change
SEL (Method Number)
andIMP (Method implementation)
To achieve the purpose of OC method call process change - Fishhook: this tool is used to dynamically modify machO files. It uses the machO file loading principle to modify the pointer to the lazy and non-lazy tables
- Cydia Substrate: formerly known as
Mobile Substrate
, its main function is to HOOK OC method, C function and function address, and Android can also use
Method Swizzling has been introduced before, but the OC Runtime feature gives it a “dark magic” reputation, but also a limitation
The differences are as follows:
Method Swizzling
Only for dynamic OC methods (runtime determines function implementation address)fishhook
For static C methods (determine the function implementation address at compile time)Cydia Substrate
Logos is a powerful framework that hooks only through the Logos language (similar to forward development) for OC methods, C functions, and function addresses
Second, the fishhook
1. The use of fishhook
Find the fishhook code on Github and drag fishhook. C, fishhook. H into the project
Fishhook opens up a structure rebinding and two functions
rebind_symbols
The names of all functions in a hook projectrebind_symbols_image
Hook only the function name of a repository
Steps to use Fishhook:
- Import header file
#import "fishhook.h"
Copy the code
- Specify the swap function —
rebinding
Structure object
struct rebinding nslog;
nslog.name = "NSLog";
nslog.replacement = fxNSlog;
nslog.replaced = (void *)&sys_nslog;
Copy the code
- call
rebind_symbols
Rebind symbol
struct rebinding rebs[] = {nslog};
rebind_symbols(rebs, 1);
Copy the code
The complete code is as follows:
#import "fishhook.h"
@interface ViewController(a)
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
struct rebinding nslog;
nslog.name = "NSLog";
nslog.replacement = fxNSlog;
nslog.replaced = (void *)&sys_nslog;
struct rebinding rebs[] = {nslog};
rebind_symbols(rebs, 1);
}
static void(*sys_nslog)(NSString*format, ...) ;void fxNSlog(NSString *format, ...) {
format = [format stringByAppendingFormat:@ "have hooks"];
sys_nslog(format);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@" Tap screen");
}
@end
Copy the code
- define
rebinding
To specify the swap functionname
The function name of the specified Hook (C string) inreplacement
Specifies the new function address in- The name of a C function is a function pointer — this is determined at compile time for static languages
replaced
To hold a pointer to the address of the original function- Due to the
NSLog
In the Foundation library, the memory address on each phone is different and cannot be passedCMD+B
I can determine its memory location - Here Fishhook is dynamically retrieved at run time
NSLog
So here we define a new function pointer to hold the function implementation - use
&
Modifies the value inside a variable - use
(void *)
Type conversion
- Due to the
rebind_symbols
Two parameters are required in- A parameter is
rebinding
An array of - Parameters of the two is
rebinding
Array length
- A parameter is
2. Limitations of Fishhook
Fishhook is designed to hook C functions, but it has a limitation — you can’t swap custom functions
C functions
Is static, the function address is determined at compile time (the function implementation address is in the MachO local file)System C function
There are dynamic parts
So why are system-level C functions ok? This brings us to PIC technology
3. The PIC technology
PIC technology (position-independent code), also known as position-independent code, is a technical means for system C functions to confirm an address during compilation
- Set aside a space in the MachO file at compile time — symbol table (in the DATA section)
- Dyld loads the application into memory
Load Commands
Will depend onFoundation
), found in the symbol tableNSLog
Function, will do the link binding — willFoundation
In theNSLog
Assigns the real address toThe DATA segment
theNSLog
On the symbol
A custom C function does not generate a symbol table, but is simply a function address. Fishhook’s limitation is that only symbols in the symbol table can hook (rebind symbols).
4. LLDB debugging
Because NSLog is a lazy loading symbol, we added the line endorsement code
- through
image list
Prints all image resources – the first is the memory header of the process
- Get the memory offset of NSLog in MachO
Using a calculator, head of memory + memory offset = symbolic address
- through
Memory read Memory address
Read symbol address
Since iOS is small endian mode, the memory address is read 8 bits backwards
- through
Dis-s Specifies the memory address
Check the assembly
The symbol is not bound at this point because it is not used yet
- Cross the breakpoint (using NSLog) and look again
The NSLog symbol is already bound
- Then skip to the next step (rebind symbol) to see
Now the NSLog symbol has been rebound
5. Fishhook principle exploration
There’s a working diagram on fishhook’s open source website
rebind_symbols
prepend_rebindings
willrebindings
Arrays are constantly being added to_rebindings_head
The head of the list becomes the new head node- Judge list
_rebindings_head->next
Null to determine if it is the first call- If called for the first time
_dyld_register_func_for_add_image
Perform callback listening - If not, the call is traversed
_rebind_symbols_for_image
- If called for the first time
- This function returns an Int
- Returns 0 if the redirect succeeded
- On failure -1 is returned
Next comes the _rebind_SYMBOLS_for_image operation on the MachO file: the address of the various tables and the offset of the pointer in the table are computed as a rule
As a final step, perform_rebinding_with_section finds the pointer in the symbol table to the shared library object function based on the calculated symbol table address and offset, and assigns the value of the pointer (the address of the object function) to the * replacement rebinding. Finally change the value of this pointer to replacement (the new function address)
6. Fishhook principle in action – find function implementations in MachO
The next step is to find the function implemented in the shared library based on the pointer to the string in the symbol table
- NSLog in
Lazy Symbol Pointers
, subscript 0
Dynamic System Table->Indirect Symbols
And the value ofLazy Symbol Pointers
In one-to-one correspondence, Data(0xA9=169) in this table is the subscript of the other table
- Take this subscript in
Symbol Table->Symbols
Find NSLog in, and the Data corresponds toString Table Index
Offset value in (0x0000009B)
- Finally, in
String Table
In, calculate the header (0x000061EC)+ offset (0x0000009B) and find the address of the NSLog function
7. Fishhook application scenario
Since Fishhook can swap C functions, then we can swap method_exchangeImplementations or something like that to prevent hooks, The project itself if you want to use method_exchangeImplementations you can use the new function address to do that
- Attack: You can insert a new dynamic library to HOOK the method ahead of time, and fishhook protection will no longer work
- Anti: You can also insert the dynamic library in advance for Fishhook exchange (the reverse injection of the dynamic library is usually placed after the original project dynamic library). In this case, the Fishhook code is prior to the hook code, so Fishhook is still effective
- Attack: Pull the plug — go directly to the fishhook function address, modify it, and run it again
- .
Write in the back
In the field of security attack and defense, hook principle plays a crucial role. Although it is not significant to use Fishhook for protection, it is still helpful to understand Fishhook principle for subsequent learning