diff --git a/.gitignore b/.gitignore index a6cc8f7..3e94486 100644 --- a/.gitignore +++ b/.gitignore @@ -14,3 +14,6 @@ _internalblue.hist _internalblue.log btsnoop.log +# xcode +xcuserdata +*.xcworkspace diff --git a/ios-proxy/README.md b/ios-proxy/README.md new file mode 100644 index 0000000..5a5c52f --- /dev/null +++ b/ios-proxy/README.md @@ -0,0 +1,20 @@ +# internalblue-ios-proxy +This project is a proxy that redirects iOS's bluetooth socket and exposes it as a TCP socket which can be used to send HCI commands to the bluetooth controller of the device. A jailbroken device is required. To compile the project, a Mac with xcode is required. + +## Building internalblue-ios-proxy +Open the project with xcode and compile it. Xcode will create a single binary that can then be transferred onto the device. + +## Installing internalblue-ios-proxy +1. Right-click the `internalblue-ios-proxy` binary and click "Show in Finder". This will open the location the compiled binary resides in. +2. Move the binary onto the device (e.g. with scp) at a location where applications are allowed to be executed (e.g. `/bin` or `/sbin`). +3. The binary needs the `platform-binary` entitlement. This is achieved by signing the binary with the included `entitlements.xml` file. Sign it using `ldid -Sentitlements.xml internalblue-ios-proxy`. `ldid` should be on a jailbroken device with Cydia by default. + +## Running internalblue-ios-proxy +Run the proxy by executing `internalblue-ios-proxy `. The phone will then listen on this port and can be accessed either when on the same WiFi or by proxying the port through USB (using [usbmuxd](https://iphonedevwiki.net/index.php/SSH_Over_USB)). + +A few things to note: +- to increase reliability of the proxy, bluetooth should be disabled (either by manually stopping the bluetoothd daemon or by shutting of bluetooth in the settings on the phone) +- in case the bluetooth chip crashes or does not respond anymore over the proxy, the proxy should be stopped and bluetooth should be turned off and on again in the UI +- sometimes the bluetooth socket will not respond anymore after establishing a second connection, just restart the proxy then. + +This project is based on Brandon Azad's [iOS command line tool](https://github.com/bazad/ios-command-line-tool) template. diff --git a/ios-proxy/entitlements.xml b/ios-proxy/entitlements.xml new file mode 100644 index 0000000..f42020d --- /dev/null +++ b/ios-proxy/entitlements.xml @@ -0,0 +1,8 @@ + + + + + platform-application + + + diff --git a/ios-proxy/internalblue-ios-proxy.xcodeproj/project.pbxproj b/ios-proxy/internalblue-ios-proxy.xcodeproj/project.pbxproj new file mode 100644 index 0000000..de9424b --- /dev/null +++ b/ios-proxy/internalblue-ios-proxy.xcodeproj/project.pbxproj @@ -0,0 +1,285 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + BB958F25227BA4580029C2D6 /* internalblue-ios-proxy.c in Sources */ = {isa = PBXBuildFile; fileRef = BB958F24227BA4580029C2D6 /* internalblue-ios-proxy.c */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 551A88C4208E671F0048DFA0 /* internalblue-ios-proxy */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = "internalblue-ios-proxy"; sourceTree = BUILT_PRODUCTS_DIR; }; + BB958F23227BA4580029C2D6 /* internalblue-ios-proxy.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "internalblue-ios-proxy.h"; sourceTree = ""; }; + BB958F24227BA4580029C2D6 /* internalblue-ios-proxy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "internalblue-ios-proxy.c"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 551A88C1208E671F0048DFA0 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 551A88BB208E671F0048DFA0 = { + isa = PBXGroup; + children = ( + 551A88C6208E671F0048DFA0 /* internalblue-ios-proxy */, + 551A88C5208E671F0048DFA0 /* Products */, + ); + sourceTree = ""; + }; + 551A88C5208E671F0048DFA0 /* Products */ = { + isa = PBXGroup; + children = ( + 551A88C4208E671F0048DFA0 /* internalblue-ios-proxy */, + ); + name = Products; + sourceTree = ""; + }; + 551A88C6208E671F0048DFA0 /* internalblue-ios-proxy */ = { + isa = PBXGroup; + children = ( + BB958F23227BA4580029C2D6 /* internalblue-ios-proxy.h */, + BB958F24227BA4580029C2D6 /* internalblue-ios-proxy.c */, + ); + path = "internalblue-ios-proxy"; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 551A88C3208E671F0048DFA0 /* internalblue-ios-proxy */ = { + isa = PBXNativeTarget; + buildConfigurationList = 551A88CD208E671F0048DFA0 /* Build configuration list for PBXNativeTarget "internalblue-ios-proxy" */; + buildPhases = ( + 551A88C0208E671F0048DFA0 /* Sources */, + 551A88C1208E671F0048DFA0 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "internalblue-ios-proxy"; + productName = "ios-command-line-tool"; + productReference = 551A88C4208E671F0048DFA0 /* internalblue-ios-proxy */; + productType = "com.apple.product-type.library.dynamic"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 551A88BC208E671F0048DFA0 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0930; + ORGANIZATIONNAME = ttdennis; + TargetAttributes = { + 551A88C3208E671F0048DFA0 = { + CreatedOnToolsVersion = 9.3; + }; + }; + }; + buildConfigurationList = 551A88BF208E671F0048DFA0 /* Build configuration list for PBXProject "internalblue-ios-proxy" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + ); + mainGroup = 551A88BB208E671F0048DFA0; + productRefGroup = 551A88C5208E671F0048DFA0 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 551A88C3208E671F0048DFA0 /* internalblue-ios-proxy */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 551A88C0208E671F0048DFA0 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + BB958F25227BA4580029C2D6 /* internalblue-ios-proxy.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 551A88CB208E671F0048DFA0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + }; + name = Debug; + }; + 551A88CC208E671F0048DFA0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 551A88CE208E671F0048DFA0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RSU3RMH9UZ; + DYLIB_COMPATIBILITY_VERSION = ""; + DYLIB_CURRENT_VERSION = ""; + EXECUTABLE_PREFIX = ""; + EXECUTABLE_SUFFIX = ""; + MACH_O_TYPE = mh_execute; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 551A88CF208E671F0048DFA0 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = RSU3RMH9UZ; + DYLIB_COMPATIBILITY_VERSION = ""; + DYLIB_CURRENT_VERSION = ""; + EXECUTABLE_PREFIX = ""; + EXECUTABLE_SUFFIX = ""; + MACH_O_TYPE = mh_execute; + OTHER_LDFLAGS = "-ObjC"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 551A88BF208E671F0048DFA0 /* Build configuration list for PBXProject "internalblue-ios-proxy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 551A88CB208E671F0048DFA0 /* Debug */, + 551A88CC208E671F0048DFA0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 551A88CD208E671F0048DFA0 /* Build configuration list for PBXNativeTarget "internalblue-ios-proxy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 551A88CE208E671F0048DFA0 /* Debug */, + 551A88CF208E671F0048DFA0 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 551A88BC208E671F0048DFA0 /* Project object */; +} diff --git a/ios-proxy/internalblue-ios-proxy.xcodeproj/xcshareddata/xcschemes/internalblue-ios-proxy.xcscheme b/ios-proxy/internalblue-ios-proxy.xcodeproj/xcshareddata/xcschemes/internalblue-ios-proxy.xcscheme new file mode 100644 index 0000000..db9236c --- /dev/null +++ b/ios-proxy/internalblue-ios-proxy.xcodeproj/xcshareddata/xcschemes/internalblue-ios-proxy.xcscheme @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ios-proxy/internalblue-ios-proxy/internalblue-ios-proxy.c b/ios-proxy/internalblue-ios-proxy/internalblue-ios-proxy.c new file mode 100644 index 0000000..4cd7e67 --- /dev/null +++ b/ios-proxy/internalblue-ios-proxy/internalblue-ios-proxy.c @@ -0,0 +1,282 @@ +// +// internalblue-ios-proxy.c +// internalblue-ios-proxy +// +// Created by ttdennis on 03.05.19. +// Copyright © 2019 ttdennis. All rights reserved. +// + +#include "internalblue-ios-proxy.h" + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#define IOAOSSKYSETCHANNELSPEC 0x800C5414 +#define IOAOSSKYGETCHANNELUUID 0x40105412 + +#define CTLIOCGINFO 0xC0644E03 + +typedef struct ctl_info { + uint32_t ctl_id; + char ctl_name[96]; +} ctl_info_t; + +int btwake_fd, bt_fd; + +/* + This code has been put together by reverse-engineering BlueTool and bluetoothd on + iOS. Some of the things that happen here are not completely understood but the goal + was to just get it to work. + */ +int connect_bt_device() { + int socket_fd = socket(32, 1, 2); + int error = 0; + int ret = 0; + + struct sockaddr sock_addr; + struct termios term; + + if (socket_fd == 0) { + printf("unable to get bluetooth socket\n"); + return -1; + } + + ctl_info_t *ctl_inf = malloc(sizeof(ctl_info_t)); + ctl_inf->ctl_id = 0; + strcpy(ctl_inf->ctl_name, "com.apple.uart.bluetooth"); + if ((error = ioctl(socket_fd, CTLIOCGINFO, ctl_inf))) { + printf("ioctl(CTLIOCGINFO) = %d - errno: %d\n", error, errno); + printf("error: %s\n", strerror(errno)); + return -1; + } + + *(int *)&sock_addr.sa_len = 0x22020; + *(int *)&sock_addr.sa_data[2] = ctl_inf->ctl_id; + ret = connect(socket_fd, &sock_addr, 0x20); + if (ret != 0) { + printf("connect() = %d - errno: %d\n", ret, errno); + printf("error: %s\n", strerror(errno)); + return -1; + } + + printf("Connected to bt device\n"); + + socklen_t len = 72; + + ret = getsockopt(socket_fd, 2, TIOCGETA, &term, &len); + if (ret != 0) { + printf("getsockopt(TIOCGETA) = %d - errno: %d\n", ret, errno); + printf("error: %s\n", strerror(errno)); + return -1; + } + + cfmakeraw(&term); + ret = cfsetspeed(&term, 3000000); + if (ret != 0) { + printf("cfsetspeed() = %d - errno: %d\n", ret, errno); + printf("error: %s\n", strerror(errno)); + return -1; + } + + term.c_iflag |= 4; + term.c_cflag = 232192; + ret = setsockopt(socket_fd, 2, TIOCSETA, &term, 0x48); + if (ret != 0) { + printf("setsockopt() = %d - errno: %d\n", ret, errno); + printf("error: %s\n", strerror(errno)); + return -1; + } + + tcflush(socket_fd, 3); + + free(ctl_inf); + + return socket_fd; +} + +int create_server(int port) { + int server_fd; + struct sockaddr_in server; + int on = 1; + int addrlen; + + server_fd = socket(AF_INET, SOCK_STREAM, 0); + if (server_fd < 0) { + printf("Unable to create server socket\n"); + return -1; + } + + addrlen = sizeof(server); + memset(&server, '\0', addrlen); + server.sin_family = AF_INET; + server.sin_addr.s_addr = INADDR_ANY; + server.sin_port = htons(port); + + setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, 4); + if (bind(server_fd, (struct sockaddr *)&server, sizeof(server)) < 0) { + printf("Error binding socket\n"); + return -1; + } + + if (listen(server_fd, 5) < 0) { + printf("Failed listening: %s\n", strerror(errno)); + return -1; + } + + printf("Listening on port %d\n", port); + + return server_fd; +} + +int wait_for_connection(int server_fd) { + int client_fd; + socklen_t len; + struct sockaddr_in client; + + len = sizeof(struct sockaddr_in); + client_fd = accept(server_fd, (struct sockaddr *)&client, (socklen_t *)&len); + + if (client_fd < 0) { + printf("Accepting connection failed\n"); + return -1; + } + + return client_fd; +} + +size_t buffered_write(int fd, char *buf, int *len) +{ + size_t x = write(fd, buf, *len); + if (x < 0) + return x; + if (x == 0) + return x; + if (x != *len) + memmove(buf, buf+x, (*len)-x); + *len -= x; + return x; +} + +void proxy_bt_socket(int client, int bt) { + char *client_buf, *bt_buf; + int nfds; + fd_set R; + int client_out = 0; + int bt_out = 0; + int x; + size_t n; + + client_buf = malloc(1024); + bt_buf = malloc(1024); + + nfds = client > bt ? client : bt; + nfds++; + + while(1) { + struct timeval to; + if (client_out) { + buffered_write(bt, client_buf, &client_out); + } + if (bt_out) { + buffered_write(client, bt_buf, &bt_out); + } + FD_ZERO(&R); + if (client_out < 1024) + FD_SET(client, &R); + if (bt_out < 1024) + FD_SET(bt, &R); + + to.tv_sec = 0; + to.tv_usec = 1000; + x = select(nfds+1, &R, 0, 0, &to); + if (x > 0) { + if (FD_ISSET(client, &R)) { + n = read(client, client_buf+client_out, 1024-client_out); + if (n > 0) { + client_out += n; + } else { + close(client); + printf("Client read failed\n"); + return; + } + } + + if (FD_ISSET(bt, &R)) { + n = read(bt, bt_buf+bt_out, 1024-bt_out); + if (n > 0) { + bt_out += n; + } else { + close(client); + printf("BT read failed\n"); + return; + } + } + } else if (x < 0 && errno != EINTR){ + printf("Select failed with %s\n", strerror(errno)); + close(client); + return; + } + + } +} + +void __exit(int sig) { + close(bt_fd); + close(btwake_fd); + exit(0); +} + +int main(int argc, char **argv) { + int server_fd, client_fd; + int port; + + if (argc != 2) { + printf("Usage: %s \n", argv[0]); + return 1; + } + + port = atoi(argv[1]); + + // wake BT device + btwake_fd = open("/dev/btwake", 0); + + bt_fd = connect_bt_device(); + if (bt_fd < 0) { + printf("Error connecting to bluetooth device\n"); + return -1; + } + + server_fd = create_server(port); + if (server_fd < 0) { + printf("Unable to create server\n"); + return -1; + } + printf("Created server\n"); + + signal(SIGINT, __exit); + + while (1) { + printf("Waiting for connection\n"); + client_fd = wait_for_connection(server_fd); + if (client_fd < 0) + continue; + // currently only one connection is supported + proxy_bt_socket(client_fd, bt_fd); + close(client_fd); + } + + return 0; +} diff --git a/ios-proxy/internalblue-ios-proxy/internalblue-ios-proxy.h b/ios-proxy/internalblue-ios-proxy/internalblue-ios-proxy.h new file mode 100644 index 0000000..a569d47 --- /dev/null +++ b/ios-proxy/internalblue-ios-proxy/internalblue-ios-proxy.h @@ -0,0 +1,14 @@ +// +// internalblue-ios-proxy.h +// internalblue-ios-proxy +// +// Created by ttdennis on 03.05.19. +// Copyright © 2019 ttdennis. All rights reserved. +// + +#ifndef internalblue_ios_proxy_h +#define internalblue_ios_proxy_h + +#include + +#endif /* internalblue_ios_proxy_h */