Disabling debug sessions on iOS - is that useful? - ios

I recently came around this article (http://www.splinter.com.au/2014/09/16/storing-secret-keys/) that talks about obfuscation on iOS.
I quote:
To somewhat mitigate the risk of crackers attacking your app with a debugger (LLDB or GDB), you can insert some code in your app that makes it crash as soon as it detects a debugger attached. The iTunes app uses this technique, you can read about it here.
This is achieved by calling the following code in main()
#import <dlfcn.h>
#import <sys/types.h>
typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
#if !defined(PT_DENY_ATTACH)
#define PT_DENY_ATTACH 31
#endif // !defined(PT_DENY_ATTACH)
void disable_gdb() {
void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
dlclose(handle);
}
I understand that these lines of code make the debugger crash when attached to the process but how does it achieve this behaviour?
Also, would that be impairing the stability of the app in any way?

Seems like a similar question on OS X has already been answered here: Implementing the PT_DENY_ATTACH anti-piracy code.
TL;DR - As Jim Ingham points out in the comments, it's a waste of time.

Related

How to set PT_DENY_ATTACH in Xamarin.iOS?

We recently had a pen tester audit our app and one of the findings was that a person with a jailbroken device can attach a local debugger.
The solution they suggested was to enable PT_DENY_ATTACH when starting up the app. This is fairly easy to do in a native app but I haven't been able to figure it out with our Xamarin app (not forms).
I've tried creating an objc framework in Xcode, binding that and pulling it in. I've also tried to create a shared c++ library but that isn't possible in VS Mac.
I know that PT_DENY_ATTACH has been circumvented but I'd still like to know how to implement it.
Thanks!
It turns out that my objc framework was behaving properly just not in the way I expected. For some reason I was still able to attach the Visual Studio debugger but when I move to Xcode and try to attach its debugger it fails when the framework is called.
To answer my question:
In Xcode I created a new static library with one class:
GDBManager.h
#import <Foundation/Foundation.h>
#interface GDBManager : NSObject
+(void)DisableGDB;
#end
GDBManager.m
#import "GDBManager.h"
#import <dlfcn.h>
#import <sys/types.h>
#implementation GDBManager
typedef int (*ptrace_ptr_t)(int _request, pid_t _pid, caddr_t _addr, int _data);
#define PT_DENY_ATTACH 31
+(void)DisableGDB {
void* handle = dlopen(0, RTLD_GLOBAL | RTLD_NOW);
ptrace_ptr_t ptrace_ptr = dlsym(handle, "ptrace");
ptrace_ptr(PT_DENY_ATTACH, 0, 0, 0);
dlclose(handle);
}
#end
I followed these instructions to create a fat file for my library and to use that in a binding project.
https://learn.microsoft.com/en-us/xamarin/ios/platform/binding-objective-c/walkthrough
I then add the generated dll to my Xamarin.iOS project and call it above UIApplication.Main(args, null, "AppDelegate"); in Main.cs

On iOS, are 0x0000000000000026, 0x000000000000001c, 0x000000000000005a examples of tagged pointers?

On iOS 11, when I intentionally create objects which would turn out to be tagged pointers, they start with 0xB, instead of the 0x0000000000000026, 0x000000000000001c, 0x000000000000005a values that are showing up in my crash reports as invalid addresses. I think these are likely tagged pointers, but they aren't formatted like tagged pointers that I see in the debugger.
What about 0x0000000000000010, 0x0000000000000020, 0x0000000000000030 ? They all have a trailing 0, but they sure look suspiciously small to be real pointers.
The implementation details of tagged pointers changes from release to release and architecture to architecture. With that said, those really don't look like tagged pointers.
What is most likely is that some piece of code is dereferencing into a struct or object that is unexpectedly NULL or nil.
Run this code:
struct bob {
void *a;
void *b;
void *c;
char d[42];
};
int main(int argc, const char * argv[]) {
struct bob *fred = NULL;
fred->d[2] = 'q';
return 0;
}
You'll get this crash (on x86_64): Thread 1: EXC_BAD_ACCESS (code=1, address=0x1a)
That is, it is trying to dereference through 0x0. So, more likely than not, you have a struct/object reference that is NULL and your code is trying to dereference an element or instance variable that is offset by the hex #s you listed from the beginning.

Access to iOS SDK constant via name (reflection)

Inside of iOS SDK, lots of constants defined by Apple can be found looking something like this:
extern const CFStringRef kSomeReallyNiceConstant
__OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_8_0);
If I check for presence of this constant standard way:
if (NULL == &kSomeReallyNiceConstant)
I am pretty much referencing it and in order for my code to compile properly, I need at least iOS SDK 8.0 or higher in this case.
When it comes to objects and methods, reflection approach works nicely with usage of NSClassFromString, respondsToSelector and performSelector.
Is there a chance to use some kind of reflection (access to string constant by name) in attempt to get it's value if it exists (or none if it doesn't)?
I know that I can use macros to check for iOS version and execute different code paths based on that information, but I don't want to use that approach.
I managed to do this with pointer:
#include <dlfcn.h>
// ...
int *pointer = dlsym(RTLD_SELF, "kSomeReallyNiceConstant");
if (pointer) {
NSLog(#"Thing exists!");
} else {
NSLog(#"Nope, doesn't exist!");
}
but I am not sure if this is something that would cause app rejection. Do you maybe know?
Regardless of this pointer approach, I'm curious to hear if there's any other way to achieve this?
Nothing better than suggested solution found on this topic.
#include <dlfcn.h>
// ...
int *pointer = dlsym(RTLD_SELF, "kSomeReallyNiceConstant");
if (pointer) {
NSLog(#"Thing exists!");
} else {
NSLog(#"Nope, doesn't exist!");
}

XCode 6 verificationController.m issues

I am using VerificationController.m provided by Raywenderlich for validating receipts for in ap purchase. It is working fine for XCode5 but in XCode6 it is giving number of errors. probably due to C++ code like:
Missing Code for Method declaration
#end must appear in objective-c
context Conflicting types for 'checkReiptSecurity'
can anyone tell me what is needed to be done ?
Edit : Here are errors screenshot
Have you fixed this? I was running in to the exact same problem so I'll leave my fix here for anyone that comes looking. It turns out in newer versions of Xcode you aren't allowed to put C/C++ code in objective-C context anymore. So I moved the declarations for unsigned int iTS_intermediate_der_len, unsigned char iTS_intermediate_der[], char* base64_encode(const void* buf, size_t size), and void * base64_decode(const char* s, size_t * data_len) to the top of the file, above the #implementation tag.
Have you downloaded sample code? I have downloaded sample code and its working fine at my side. It seems that you have missed or added an extra braket } or { in your code.
May be this happened when you was trying to comment this code [UIDevice currentDevice].uniqueIdentifier; because originally this line produce an error.

Objective-c-Keyboard input

I believe ive looked at every article related to keyboard input, but still cant get it to work. ALl i want is a output, using NSLog everytime i hit a key, in the app or not. Im currently using xcode 5. Ive tried many snippets of code such as
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *event)
NSLog(#"%#",event.characters);
and im not sure where to put his code. Do i put it in the main function like this
#import <Foundation/Foundation.h>
#import <appkit/NSEvent.h>
int main(int argc, char * argV[]) {
#autoreleasepool{
[NSEvent addGlobalMonitorForEventsMatchingMask:NSKeyDownMask handler:^(NSEvent *event)
NSLog(#"%#",event.characters);
}
}
Clearly im new to objective-C, and i dont plan on continuing with it unless i can get keyboard input to work. Ive tried tutorials, snippets from keyloggers, and the mac dev forums. Thanks.
Your code is pretty close but you're getting hung up on block syntax. Blocks are very powerful and useful, but the syntax is truly awful and I still struggle with it 2 years after starting to work with them. Blocks are much less readable than C function pointers, and that's saying a lot.
It should look like this:
int main(int argc, char * argV[])
{
#autoreleasepool
{
[NSEvent addGlobalMonitorForEventsMatchingMask: NSKeyDownMask
handler: ^(NSEvent *event)
{
NSLog(#"%#",event.characters);
}
];
}
}
I put all the opening and closing braces on separate lines for clarity. A block needs to be enclosed in braces, and you were missing braces, as well as the closing bracket on your call to addGlobalMonitorForEventsMatchingMask:handler:
BTW, it's very unusual to change the main() function on a Mac or iOS program. Usually you leave that alone, and then set up an application object, set up a delegate, and put your custom code in the app delegate.
You should start of using the normal Cocoa design patterns for applications, and not try to toss them.
If you want to work with main() in C style you should think about creating a command line tool intend of an interactive application. You're going to set yourself up for failure if you don't follow the standard patterns. There's just too many ways to get things wrong.
Your main is missing the housekeeping needed to create a working iOS or Mac application

Resources