LLDB debugging principle: DebugServer
- The LLDB of Xcode can debug app because the LLDB will send debugging instructions to the debugServer of the mobile phone when the app is running. The debugServer is installed on the mobile phone by Xcode for the first time.
View the debugServer in Xcode:
Hold down the Command key and click on Xcode to find xcode.app to display the package contents/ Applications/Xcode. App/Contents/Developer/Platforms/iPhoneOS platform/DeviceSupport / 11.3
Go to usr -> bin -> debugServer in developerDiskimage.dmg
You can find the debugServer in Developer -> usr -> bin in the root directory of the mobile phone. You can view the debugServer on the jailbroken mobile phone - In the jailbreak environment, the LLDB connects to the mobile phone’s DebugServer, and then you can debug an APP through the DebugServer
- How does the DebugServer debug the APP? The debugServer debugs app through the ptrace function. Ptrace is a system function, which provides a process to monitor and control another process, and can detect the data in the memory and registers of the controlled process. Ptrace can be used for breakpoint debugging and system call tracing.
Recommended books: Self-Cultivation of Programmers
2 Use PTrace to protect the debugServer
-
#import
go to ptrace.h and copy all the contents to myptrace. h. If your project wants to call ptrace, you can import myptrace.h and call it directly
-
Ptrace protection ptrace (< # int _request # >, < # pid_t _pid # >, < # caddr_t _addr # >, <#int _data#>) has four parameters: parameter 1: the thing to do parameter 2: the process ID to control Parameter 3: address parameter 4: data parameter 3 and parameter 4 are determined by parameter 1: the address to pass parameter 1 and the list of data parameters 1:
#define PT_TRACE_ME 0 /* child declares it’s being traced / #define PT_READ_I 1 / read word in child’s I space / #define PT_READ_D 2 / read word in child’s D space / #define PT_READ_U 3 / read word in child’s user structure / #define PT_WRITE_I 4 / write word in child’s I space / #define PT_WRITE_D 5 / write word in child’s D space / #define PT_WRITE_U 6 / write word in child’s user structure / #define PT_CONTINUE 7 / continue the child / #define PT_KILL 8 / kill the child process / #define PT_STEP 9 / single step the child / #define PT_ATTACH ePtAttachDeprecated / trace some running process / #define PT_DETACH 11 / stop tracing a process / #define PT_SIGEXC 12 / signals as exceptions for current_proc / #define PT_THUPDATE 13 / signal for thread# / #define PT_ATTACHEXC 14 / attach to running process with signal exception */
#define PT_FORCEQUOTA 30 /* Enforce quota for root */ #define PT_DENY_ATTACH 31
#define PT_FIRSTMACH 32 /* for machine-specific requests */
To undebug, simply set parameter 1 to PT_DENY_ATTACH and parameter 2 to itself
#import "MyPtrace. H "// PT_DENY_ATTACH (0, 0, 0);Copy the code
So your app can’t be debugged with Xcode
Three reverse pTrace, make someone else’s Ptrace invalid
If someone else’s app has pTrace protection, how do you debug their app so that their pTrace doesn’t work? Since ptrace is a system function, we can hook the ptrace function with FishHook and have its app call our own ptrace function
-
Inject the dynamic library meryinDylib
-
Hook the ptrace function in meryinDylib
#import “fishhook.h” #import “MyPtrace.h”
@implementation meryinDylib int (*ptrace_p)(int _request, pid_t _pid, caddr_t _addr, int _data); int myPtrace(int _request, pid_t _pid, caddr_t _addr, int _data){ if (_request ! = PT_DENY_ATTACH) { return ptrace_p(_request,_pid,_addr,_data); } return 0; }
- (void)load
{ struct rebinding ptraceBind; PtraceBind. Name = “ptrace”; // The new function address ptracebind.replacement = myPtrace; // The pointer to the variable that holds the original function address ptraceBind. Struct rebinding rebs[] = {ptraceBind}; / arg1: array of rebinding objects arg2: array length */ rebind_symbols(rebs, 1); }
Four for three, to hook others to their app ptrace failure
Create a framework library and write ptrace(PT_DENY_ATTACH, 0, 0, 0) in the library.
-
Libraries should be loaded in the same order as Link Binary Libraries
Five for four reverse debugging
Even if his pTrace doesn’t own Fishhook, he can disable his PTrace by modifying macho’s binary and then debug it.
-
Open it with MonkeyDev, trace, LLDB debug bt, find antiDebug library of pTrace and its address 0x0000000102165d98, Find antiDebug address 0x0000000102160000 from image list, so the real address is 0x5d98;
-
Then display the package contents, in Frameworks, go to antiDebug library macho, open it with Hopper, and find 0x5d98
-
Change binary can be directly after bl __NSlog function end, remove BL __ptrace, do not call ptrace function copy ptrace next instruction 0000000000005d94 BL imp___stubs__ptrace, Click on the next line of bl __NSlog and then Alt+ A to write the code BL 0X 0000000000005D94
-
Export the New macho File –> Produce New Executable and then run it
I don’t want to expose my system methods like ptrace, don’t want to be broken by symbolic breakpoints, can use assembly to call pTrace
/ / safety protection - the debugging asm (" mov x0, # 31 \ n "" mov x1, # 0 \ n" "mov x2, # 0 \ n" "mov x3, # 0 \ n" "mov w16, # 26 \ n" / / 26 ptrace "SVC # 0 x80" //0x80 triggers an interrupt to find w16 to execute);Copy the code
- Where do you find 26 is ptrace?
在#import <sys/syscall.h>
There are more than 500 system functions, all numbered
Look at the original