Add iOS proxy source code
This commit is contained in:
@@ -14,3 +14,6 @@ _internalblue.hist
|
||||
_internalblue.log
|
||||
btsnoop.log
|
||||
|
||||
# xcode
|
||||
xcuserdata
|
||||
*.xcworkspace
|
||||
|
||||
@@ -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 <port-number>`. 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.
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>platform-application</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
||||
@@ -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 = "<group>"; };
|
||||
BB958F24227BA4580029C2D6 /* internalblue-ios-proxy.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = "internalblue-ios-proxy.c"; sourceTree = "<group>"; };
|
||||
/* 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 = "<group>";
|
||||
};
|
||||
551A88C5208E671F0048DFA0 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
551A88C4208E671F0048DFA0 /* internalblue-ios-proxy */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
551A88C6208E671F0048DFA0 /* internalblue-ios-proxy */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
BB958F23227BA4580029C2D6 /* internalblue-ios-proxy.h */,
|
||||
BB958F24227BA4580029C2D6 /* internalblue-ios-proxy.c */,
|
||||
);
|
||||
path = "internalblue-ios-proxy";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* 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 */;
|
||||
}
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "1020"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "551A88C3208E671F0048DFA0"
|
||||
BuildableName = "internalblue-ios-proxy"
|
||||
BlueprintName = "internalblue-ios-proxy"
|
||||
ReferencedContainer = "container:internalblue-ios-proxy.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "551A88C3208E671F0048DFA0"
|
||||
BuildableName = "internalblue-ios-proxy"
|
||||
BlueprintName = "internalblue-ios-proxy"
|
||||
ReferencedContainer = "container:internalblue-ios-proxy.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "551A88C3208E671F0048DFA0"
|
||||
BuildableName = "internalblue-ios-proxy"
|
||||
BlueprintName = "internalblue-ios-proxy"
|
||||
ReferencedContainer = "container:internalblue-ios-proxy.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
||||
@@ -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 <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/select.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
#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 <port_number>\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;
|
||||
}
|
||||
@@ -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 <stdio.h>
|
||||
|
||||
#endif /* internalblue_ios_proxy_h */
|
||||
Reference in New Issue
Block a user