AutorÃa | Ultima modificación | Ver Log |
// Copyright 2019 Google//// Licensed under the Apache License, Version 2.0 (the "License");// you may not use this file except in compliance with the License.// You may obtain a copy of the License at//// http://www.apache.org/licenses/LICENSE-2.0//// Unless required by applicable law or agreed to in writing, software// distributed under the License is distributed on an "AS IS" BASIS,// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.// See the License for the specific language governing permissions and// limitations under the License.#include "Crashlytics/Crashlytics/Helpers/FIRCLSUtility.h"#include <mach/mach.h>#include <dlfcn.h>#include "Crashlytics/Crashlytics/Components/FIRCLSGlobals.h"#include "Crashlytics/Crashlytics/Helpers/FIRCLSFeatures.h"#include "Crashlytics/Crashlytics/Helpers/FIRCLSFile.h"#import "Crashlytics/Shared/FIRCLSByteUtility.h"#import "Crashlytics/Shared/FIRCLSUUID.h"#import <CommonCrypto/CommonHMAC.h>void FIRCLSLookupFunctionPointer(void* ptr, void (^block)(const char* name, const char* lib)) {Dl_info info;if (dladdr(ptr, &info) == 0) {block(NULL, NULL);return;}const char* name = "unknown";const char* lib = "unknown";if (info.dli_sname) {name = info.dli_sname;}if (info.dli_fname) {lib = info.dli_fname;}block(name, lib);}uint8_t FIRCLSNybbleFromChar(char c) {if (c >= '0' && c <= '9') {return c - '0';}if (c >= 'a' && c <= 'f') {return c - 'a' + 10;}if (c >= 'A' && c <= 'F') {return c - 'A' + 10;}return FIRCLSInvalidCharNybble;}bool FIRCLSReadMemory(vm_address_t src, void* dest, size_t len) {if (!FIRCLSIsValidPointer(src)) {return false;}vm_size_t readSize = len;return vm_read_overwrite(mach_task_self(), src, len, (pointer_t)dest, &readSize) == KERN_SUCCESS;}bool FIRCLSReadString(vm_address_t src, char** dest, size_t maxlen) {char c;vm_address_t address;if (!dest) {return false;}// Walk the entire string. Not certain this is perfect...for (address = src; address < src + maxlen; ++address) {if (!FIRCLSReadMemory(address, &c, 1)) {return false;}if (c == 0) {break;}}*dest = (char*)src;return true;}const char* FIRCLSDupString(const char* string) {#if CLS_MEMORY_PROTECTION_ENABLEDchar* buffer;size_t length;if (!string) {return NULL;}length = strlen(string);buffer = FIRCLSAllocatorSafeAllocate(_firclsContext.allocator, length + 1, CLS_READONLY);memcpy(buffer, string, length);buffer[length] = 0; // null-terminatereturn buffer;#elsereturn strdup(string);#endif}void FIRCLSDispatchAfter(float timeInSeconds, dispatch_queue_t queue, dispatch_block_t block) {dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(timeInSeconds * NSEC_PER_SEC)), queue,block);}bool FIRCLSUnlinkIfExists(const char* path) {if (unlink(path) != 0) {if (errno != ENOENT) {return false;}}return true;}NSString* FIRCLSNormalizeUUID(NSString* value) {return [[value stringByReplacingOccurrencesOfString:@"-" withString:@""] lowercaseString];}NSString* FIRCLSGenerateNormalizedUUID(void) {return FIRCLSNormalizeUUID(FIRCLSGenerateUUID());}// Redacts a UUID wrapped in parenthesis from a char* using strchr, which is async safe.// Ex.// "foo (bar) (45D62CC2-CFB5-4E33-AB61-B0684627F1B6) baz"// becomes// "foo (bar) (********-****-****-****-************) baz"void FIRCLSRedactUUID(char* value) {if (value == NULL) {return;}char* openParen = value;// find the index of the first parenwhile ((openParen = strchr(openParen, '(')) != NULL) {// find index of the matching close parenconst char* closeParen = strchr(openParen, ')');if (closeParen == NULL) {break;}// if the distance between them is 37, traverse the characters// and replace anything that is not a '-' with '*'if (closeParen - openParen == 37) {for (int i = 1; i < 37; ++i) {if (*(openParen + i) != '-') {*(openParen + i) = '*';}}break;}openParen++;}}NSString* FIRCLSNSDataToNSString(NSData* data) {NSString* string;char* buffer;size_t size;NSUInteger length;// we need 2 hex char for every byte of data, plus one more spot for a// null terminatorlength = [data length];size = (length * 2) + 1;buffer = malloc(sizeof(char) * size);if (!buffer) {FIRCLSErrorLog(@"Unable to malloc in FIRCLSNSDataToNSString");return nil;}FIRCLSSafeHexToString([data bytes], length, buffer);string = [NSString stringWithUTF8String:buffer];free(buffer);return string;}void FIRCLSAddOperationAfter(float timeInSeconds, NSOperationQueue* queue, void (^block)(void)) {dispatch_queue_t afterQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);FIRCLSDispatchAfter(timeInSeconds, afterQueue, ^{[queue addOperationWithBlock:block];});}#if DEBUGvoid FIRCLSPrintAUUID(const uint8_t* value) {CFUUIDRef uuid = CFUUIDCreateFromUUIDBytes(kCFAllocatorDefault, *(CFUUIDBytes*)value);NSString* string = CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, uuid));CFRelease(uuid);FIRCLSDebugLog(@"%@", [[string stringByReplacingOccurrencesOfString:@"-"withString:@""] lowercaseString]);}#endif