As we all know, security attack and defense is a process of mutual game. Only by knowing the enemy and knowing the friend can you win a hundred battles with no danger of defeat. If you want to do a good job in defense, you must naturally know how the enemy attacks. So we’re trying toThe reverse(For learning purposes)Others’AppIn addition to first carry out the necessaryHit a shell.Heavy signatureAfter such steps, the first work to be carried out is certainly throughDynamic debuggingThe way to try to findThe breakthrough pointSince it is debugging, it is natural to thinkLLDBWhen we do normal development, we can passXcode breakpointThe way to debug your ownAppHow do we debug someone else’sApp? That’s what you need to knowLLDBThe principle.

LLDBdebugserver

  • XcodeCan passLLDBdebuggingAppBecause,XcodeandiPhonebothdebugserverThe environment
    • XcodeWithin thedebugserverinDeviceSupportFolder, the specific path is/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/DeviceSupport/, in any version pathDeveloperDiskImage.dmgWithin the file/usr/binBelow, as shown below:
    • iPhoneWithin thedebugserverNeed to be inPrison break the environmentIn order to see it, and you need to go throughXcodeRun and install the phone, the specific path is/Developer/usr/binAs shown in figure:
    • inPrison break the environmentWell, we can use itterminalthroughLLDBConnected to the phonedebugserverOn the jailbroken phoneAppdebug
    • throughXcodeAttaching processes makes debugging easier, and even easierThe UI debugging.
  • debugserverTo debugAppIs by a system functionptrace
    • ptracenamelyprocess trace, process tracing.
    • debugserverTo attach to another process, you must passptraceFunction to get permission from the system.
    • ptraceIs a system function that allows one process to listen to and control another process (The App being debugged)
    • ptraceYou can even read and modify the controlled processmemoryandregisterThe data in the
    • By modifying thePC registerTo enable breakpoint debugging

usingptraceprotectivedebugserverDynamic debugging

  • We got itDynamic debuggingThe principle isdebugserverAnd thedebugserverUse againptraceFunction, then it’s obvious that it has to passptraceFunction to protect.
  • ptraceFunction in themacPlatforms can be used directly by referencing header files#import <sys/ptrace.h>After use, but iniOSThere is no direct reference to this header file in the environment, but in factptraceiniOSThere are implementations in the environment, so we can declare or create one ourselvesxxx.hHeader file and then willmacthesys/ptrace.hThe content of the header file is directcopyCome here, you can callptraceThe implementation of the header file is as follows:
  • ptraceFunction description
    • Function declaration:
    int ptrace(int _request, pid_t _pid, caddr_t _addr, int _data);
    Copy the code
    • _request: What you need ptrace to do, the value can view the macro definition in the header file
      • #define PT_DENY_ATTACH  31saidRefused to add
    • _pid: Indicates the process to be operatedid.0Represents the current process
    • _addr & _data: Address and data, according to parameters_requestDecide if you want to pass it. No default pass is required0
  • ptraceUse of functions
    • inloadIn the call
      • At this point inXcodeAdditional debugging disconnects the connection directly
    • inconstructorIn the call
      • At this point inXcodeAdditional debugging disconnects the connection directly
    • inmainCall in a function
      • At this point inXcodeAdditional debugging disconnects the connection directly
    • indidFinishLaunchingWithOptionsIn the call
      • At this point inXcodeAdditional debugging will flash out directly
    • conclusion
      • Due to theloadandconstructorWill be inmainFunction, so we know from the above verification that,ptraceinmainFunction called before willStop process attachmentIn themainA subsequent call to theAppdirectlyFlash back.
      • callptraceOnly affectsdebugserver LLDBDebug, does not affectAppNormal use.

usingfishhookkillptraceprotective

  • fishhookisFacebookA dynamic modification link is providedmachOFile tools. usingmachOBy modifying the lazy load table (Lazy Symbol Pointers) and non-lazily loaded tables (Non-Lazy Symbol Pointers) the pointer to the two tables reachesHook C functionThe purpose of.
  • Since the callptraceFunction can preventDynamic debuggingThen we just have toptracefunctionhookIf you drop it, it will be abolishedptraceprotective
  • throughframeworkThe targetAppforCode injectionTo realizeptrace hook:
  • To increase theframeworkWill bedyldLoad together inloadMethod byfishhookreplaceptraceFunction, can beptraceFailure.

usingsysctlFor protection

Fishhook is so easy to disable ptrace protection. Is there any way to avoid fishhook? Sysctl. sysctl is in usr/include > sys > A function in sysctl.h allows you to access partial process information based on the parameters passed. Sysctl allows you to check whether ptrace is being invoked and whether or not someone is debugging your program.

  • int sysctl(int *, u_int, void *, size_t *, void *, size_t);
    • int *Query an array of information
    • u_intThe size of the data type in the array
    • void *Pointer to the structure to receive information
    • size_t *The size of the structure that receives the information
    • void *The default is 0. What do I pass based on the previous argument
    • size_t *The default is 0. What do I pass based on the previous argument
  • sysctlExample usage:
  • Through the graph aboveisDebugger()Function, you can tell whether the current process is being debugged because thesysctlFunction, we can pass the structure pointerinfoReceived the information we want to query, let’s take a look at itkinfo_procStructure, and explore how to get throughp_flag & P_TRACEDTo see if the current process is debugged:
    • The first iskinfo_procStructure:
    • Among themextern_procThe structure of the bodykp_procIs what we need to focus on:
    • inkp_procIn the structure, we see that there is onep_flagLet’s take a look at the values it can set to get a clear idea of what it can do:
    • We know from the comments,extern_proc.p_flagYou can configure the values defined by many macros in the figure, which are byAn operationOf which the one we’re looking for is exactly#define P_TRACED, as can be seen from the comments, whenp_flagValue containsP_TRACEDWhen our process is beingDebug!
  • So, the and operationinfo.kp_proc.p_flag & P_TRACEDThat can be detectedptrace()Since dynamic debugging can be detected when a function is called, we can design the corresponding defense logic at will!
  • Supplement: The debug logic can be detected intermittently by means of timers, which is more secure, andGCDBlock of code can make the function call stack more ambiguous when the other party wants to find our callsysctlFunction, will be more difficult, as follows:

killsysctl

There is no absolute security protection, and so is sysctl. An experienced reverse engineer can know that the sysctl function has been called by the current process through symbolic breakpoints, and then simply inject code,hook up sysctl, and tamper with p_flag to invalidate the detected logic, as follows:

Preemption, restraintfishhook

  • And what we found is that bothptraceAll right,sysctlIt doesn’t matter whether it’s a straight shotdebugThe process is still rightdebugBehaviors are detected and processed, and can be passed by experienced reverse personnelfishhookIn a simple way, sincefishhookThis is awesome. Why don’t we just standReverse AngleTo think, how did we get killed? The answer isA pre-emptive strike.
  • fishhookTo be able tohookWe get to our function byframeworkCode injection, andframworkindyldThe load process is loaded first and executedloadMethod, our protection function is executed beforefishhookTampered with!
  • The countermeasures are self-evident. We willptraceorsysctlTo our ownframeworkIn, load and execute first, even if the reverse person can get throughfishhookorMonkey Project (also known as Fishhook)Make things happen, but we’re already in each other’s codeBefore the injectionI knew there was someonedebugOur progress.

Never ending offense and defense

Are we sure we can secure the protection code (PTrace and SYscTL) by moving it to the framework? The answer is no, there is no end to attack and defense, and our program code and framework will eventually be built into Mach-O files. In the reverse domain, there are many tools that can be used to analyze and modify binary files.

  • A symbolic breakpoint is used to discover that the current process is passingptraceorsysctlTry to protect
  • btInstruction to look at the current function call stack and find the current function’sThe dynamic libraryName and Address
  • image listOrder to get the first address, subtract by twoOffset value
  • throughHooperorIDAEtc tool analysisframeworkthemach-OFile, throughOffset valueFind the currentassemblyCall instruction
  • What you can see right now is something likebl ptraceThis particularly obvious assembly jump function instruction!
  • Change the instruction tonop“, that is, empty command, do not do any operation, directly disabledptraceandsysctl!

Bottom line: Concealment is important, discovery is victory

After several games, we found that the attack and defense are like two snipers, who first found the position of the other side, can find a way to pre-empt, or around! Therefore, hiding is also an extremely important means of protection. If we hide well, we can make the reverse personnel spend more energy, greatly improve the difficulty of reverse, and our procedures will naturally be safer. And about how to hide themselves, we follow up another to explore, endless attack and defense, everyone encourage!