“This is the 10th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021.”
Hi 👋
- Wechat: RyukieW
- Wechat official account: LabLawliet
- 📦 Archive of technical articles
- 🐙 making
My personal project | Minesweeper Elic Endless Ladder | Dream of books | Privacy Access Record |
---|---|---|---|
type | The game | financial | tool |
AppStore | Elic | Umemi | Privacy Access Record |
More columns:
The independent development of Lawliet
Lawliet’s iOS garden party
Lawliet’s underlying iOS lab
Lawliet’s iOS Reverse lab
Lawliet’s brush book
Lawliet’s Flutter Lab
A, Dobby
GitHub:Dobby
Generate an Xcode project from the document. Get DobbyX framework. A cross-platform framework for the Hook static language.
cd Dobby && mkdir build_for_ios_arm64 && cd build_for_ios_arm64 cmake .. -G Xcode \ -DCMAKE_TOOLCHAIN_FILE=cmake/ios.toolchain.cmake \ -DPLATFORM=OS64 -DARCHS="arm64" -dcmake_system_processor =arm64 \ -denable_bitcode =0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=1 -DDEPLOYMENT_TARGET=9.3 \ -DDynamicBinaryInstrument=ON -DNearBranch=ON -DPlugin.SymbolResolver=ON -DPlugin.Darwin.HideLibrary=ON -DPlugin.Darwin.ObjectiveC=ONCopy the code
Second, integrate the framework into the project
- Get the above
DobbyX.framework
Drag into the project. Build Phases
addCopy file
To addDobbyX.framework
That type offramework
Three, use,
3.1 int DobbyHook(void *address, void *replace_call, void **origin_call)
- address
- The address of the function that needs the hook
- replace_call
- New function address
- origin_call
- The address of the original function pointer
Since static languages have no symbols, hook directly through addresses
3.2 Try it out
Here’s a simple way to use it
#import "ViewController.h"
#import "DobbyX.framework/Headers/dobby.h"
@interface ViewController (a)
@end
@implementation ViewController
int test_sum(int a, int b) {
return a + b;
}
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor redColor];
DobbyHook(test_sum, new_sum, (void *)&old_sum_p);
}
/// the original function pointer
static int (*old_sum_p)(int a, int b);
// Address of the new function
int new_sum(int a, int b) {
int right = old_sum_p(a, b);
NSLog(@"Hook! The correct result is: %d",right);
return right + 1;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@Result: %d".test_sum(1.1));
}
@end
Copy the code
Console output:
[*] ================================ [*] Dobby [*] ================================ [*] dobby in debug log mode, disable with cmake flag "-DDOBBY_DEBUG=OFF" [*] [DobbyHook] Initialize at 0x104d31d90 [*] [trampoline] Generate trampoline buffer 0x104d31d90 -> 0x104d31e74 [*] [insn relocate] origin 0x104d31d90 - 12 [*] [insn relocate] relocated 0x10D2C0000-32 [*] [Intercept Routing] Active Patch 0x104D31d90 2021-05-19 08:314:00.081796 +0800 DobbyDemo [4207-1785806] Hook! Correct result: 2 2021-05-19 08:33:00.081972+0800 DobbyDemo[4207:1785806] result :3Copy the code
Iv. Process analysis
4.1 Assembly analysis of test_sum
A. A compilation of original functions
DobbyDemo`test_sum:
0x104a71dc4 <+0>: sub sp, sp, #0x10 ; =0x10
0x104a71dc8 <+4>: str w0, [sp, #0xc]
0x104a71dcc <+8>: str w1, [sp, #0x8]
-> 0x104a71dd0 <+12>: ldr w8, [sp, #0xc]
0x104a71dd4 <+16>: ldr w9, [sp, #0x8]
0x104a71dd8 <+20>: add w0, w8, w9
0x104a71ddc <+24>: add sp, sp, #0x10 ; =0x10
0x104a71de0 <+28>: ret
Copy the code
B. Compilation after Hook
DobbyDemo`test_sum:
0x104c7dd90 <+0>: adrp x17, 0
0x104c7dd94 <+4>: add x17, x17, #0xe74 ; =0xe74
0x104c7dd98 <+8>: br x17
-> 0x104c7dd9c <+12>: ldr w8, [sp, #0xc]
0x104c7dda0 <+16>: ldr w9, [sp, #0x8]
0x104c7dda4 <+20>: add w0, w8, w9
0x104c7dda8 <+24>: add sp, sp, #0x10 ; =0x10
0x104c7ddac <+28>: ret
Copy the code
C. analysis
We can see that the first three lines of instructions are different. Let’s start debugging by calling the method breakpoint
touchbegin
. 0x102b7df1c <+76>: bl 0x102b7e554 ; symbol stub for: objc_storeStrong 0x102b7df20 <+80>: mov w10, #0x1 0x102b7df24 <+84>: mov x0, x10 0x102b7df28 <+88>: mov x1, x10 -> 0x102b7df2c <+92>: bl 0x102b7dd90 ; test_sum at ViewController.m:17 ...Copy the code
test_sum
DobbyDemo`test_sum:
0x102b7dd90 <+0>: adrp x17, 0
0x102b7dd94 <+4>: add x17, x17, #0xe74 ; =0xe74
-> 0x102b7dd98 <+8>: br x17
0x102b7dd9c <+12>: ldr w8, [sp, #0xc]
0x102b7dda0 <+16>: ldr w9, [sp, #0x8]
0x102b7dda4 <+20>: add w0, w8, w9
0x102b7dda8 <+24>: add sp, sp, #0x10 ; =0x10
0x102b7ddac <+28>: ret
Copy the code
(lldb) register read x17
x17 = 0x0000000102b7de74 DobbyDemo`new_sum at ViewController.m:31
Copy the code
X17 is already programmed with new_sum! I’m in new_sum.
The following instruction is continued when the original function pointer is called
Principle of d.
- This is actually a Text replacement (in memory)!
- Text segment cannot be modified!
- Original MachO unchanged!
5. Replace symbols with addresses
In practice, more often than not we can’t simply get the method to make the substitution as shown in the above Demo.
So we need to replace the symbol with the city address!
5.1 Locating function Addresses
-> 0x1025f1f3c <+84>: mov x0, x10
0x1025f1f40 <+88>: mov x1, x10
0x1025f1f44 <+92>: bl 0x1025f1dc4 ; test_sum at ViewController.m:17
Copy the code
A. Function address
By assembling the breakpoint we see that the actual function address is 0x1025f1dc4
B. Offset in Macho
We can locate its offset in MachO by the function address
ASLR
(lldb) image list [ 0] 6B1471FE-409A-37F0-93ED-86FDFDEE421E 0x00000001025ec000 /Users/RyukieW/Library/Developer/Xcode/DerivedData/DobbyDemo-fyyzoosecpnxmcakyfrtrxocpawl/Build/Products/Debug-iphoneos/ DobbyDemo.app/DobbyDemoCopy the code
offset 0x1025f1dc4 – 0x00000001025ec000 = 0x5DC4
Verify with MachOView that our calculation is ok.
5.2 Code to achieve the above reverse process
A. Obtain ASLR by code
uintptr_t aslr = _dyld_get_image_vmaddr_slide(0);
Copy the code
You may encounter the following questions
Implicit declaration of function '_dyld_get_image_vmaddr_slide' is invalid in C99
# import < Mach – o/dyld. H >
B. Get function Offset in MachO
Calculate the offset through breakpoint debugging and record it
static uintptr_t addrSum = 0x100005D40;
Copy the code
C. Hook by address
Complete HOOK code:
static uintptr_t addrSum = 0x100005D40;
uintptr_t aslr = _dyld_get_image_vmaddr_slide(0);
addrSum += aslr;
DobbyHook((void *)addrSum, new_sum, (void *)&old_sum_p);
Copy the code
D. the results
2021-05-21 11:30:34.318180+0800 DobbyDemo[5521:2140764] Hook! Correct result :2 2021-05-21 11:30:34.318525+0800 DobbyDemo[5521:2140764] result :3Copy the code
5.3 pay attention to the point
- For my own project, every time I modify the code, the offset in MachO will change, so I need to pay attention to debugging
- The content of the adjustment variable does not change
- For IPA packets, the same IPA packet is not changed, but the IPA packets of different versions are different
- So plugins can only be used for a particular version