The obvious way to check is to look at embedded.mobileprovision ([[NSBundle mainBundle] pathForResource:@"embedded.mobileprovision" ofType:nil] or so). It's a bit of a pain to parse, but it contains all the information you'll need (App Store contains no UDIDs, Development has <key>get-task-allow</key><true/>
, and Ad Hoc contains UDIDs but has get-task-allow=false). Apart from that and the certificate it's signed with, there's no difference between Development/Ad Hoc/App Store apps.
It would help if you mentioned why you want to do this. If you want to enable different features for different things, the easiest way is to set compiler macros in your build configurations.
EDIT: The provisioning profile is signed in the code signature, so you can probably assume that it isn't removed (presumably you can set it as "ignored" in ResourceRules.plist). It's also integral to the code-signing.
An easy hack is is to check something like:
NSString * profilePath = [[NSBundle mainBundle] pathForResource:@"embedded.mobileprovision" ofType:nil];
NSString * profileAsString = [NSString stringWithContentsOfFile:profilePath encoding:NSISOLatin1StringEncoding error:NULL]
bool isDevelopmentOrAdHoc = [profileAsString rangeOfString:[[UIDevice currentDevice] uniqueIdentifier] options: NSCaseInsensitiveSearch].length;
Note that there are some false-negatives (e.g. the provisioning profile doesn't need to contain the device UDID as long as a "matching" profile installed on the device does), but in general it should work.