Files

307 lines
12 KiB
Objective-C

//
// ios-proxy.m
// ios-proxy
//
// Copyright © 2019 ttdennis. All rights reserved.
//
#include "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>
#include <dlfcn.h>
#include <sys/poll.h>
void *AppleConvergedTransport_handle;
void (*AppleConvergedTransportInitParameters)(int64_t[11]);
int (*AppleConvergedTransportCreate)(int64_t[11], uint64_t*);
int (*AppleConvergedTransportWrite)(uint64_t,char*, uint64_t, uint64_t*, uint64_t, void*);
int (*AppleConvergedTransportRead)(uint64_t,char*, uint64_t, uint64_t*, uint64_t, void*);
void (*AppleConvergedTransportFree)(uint64_t);
dispatch_queue_attr_t qos;
dispatch_queue_t recordingQueue;
void load_AppleConvergedTransport() {
static int guard = 0; // poor mans dispatch_once?
if (guard >= 1) return;
guard++;
AppleConvergedTransport_handle = dlopen("/usr/lib/AppleConvergedTransport.dylib", RTLD_LOCAL);
AppleConvergedTransportInitParameters = dlsym(AppleConvergedTransport_handle, "AppleConvergedTransportInitParameters");
AppleConvergedTransportCreate = dlsym(AppleConvergedTransport_handle, "AppleConvergedTransportCreate");
AppleConvergedTransportWrite = dlsym(AppleConvergedTransport_handle, "AppleConvergedTransportWrite");
AppleConvergedTransportRead = dlsym(AppleConvergedTransport_handle, "AppleConvergedTransportRead");
AppleConvergedTransportFree = dlsym(AppleConvergedTransport_handle, "AppleConvergedTransportFree");
//If you want to use an event block Reader: Add Queue For Reading here
//Then: Register Event Block Queue
qos = dispatch_queue_attr_make_with_qos_class(0,0x15,0);
recordingQueue = dispatch_queue_create("com.internalblue.actbt.queue", qos);
}
int connect_bti_transport(my_connection_t * my_conn) {
//NSLog(@"ios-proxy.m:connect_bti_transport -> Starting");
int64_t pciparams[11];
AppleConvergedTransportInitParameters(pciparams);
pciparams[0] = 1; //BTI
pciparams[1] = (int64_t)recordingQueue;// dispatchQ
//pciparams[2] = (int64_t)&_NSConcreteStackBlock; // Maybe fix this?
void (^myBlock)() = ^(){NSLog(@"block called");};
pciparams[2] = (int64_t)&myBlock;
pciparams[3] = 1000;
pciparams[4] = 0;
//NSLog(@"ios-proxy.m:connect_bti_transport -> Returning");
return AppleConvergedTransportCreate(pciparams, &my_conn->bti_transport); // THE PROBLEM IS IN HERE
}
int connect_hci_transport(my_connection_t * my_conn) {
//NSLog(@"ios-proxy.m:connect_hci_transport -> Starting");
int64_t pciparams[11];
AppleConvergedTransportInitParameters(pciparams);
//dispatch_queue_attr_t qos = dispatch_queue_attr_make_with_qos_class(0,0x15,0);
//dispatch_queue_t rQueue = dispatch_queue_create("com.internalblue.actbt.hci", qos);
pciparams[0] = 2; //HCI
//pciparams[1] = (int64_t)rQueue;
pciparams[1] = (int64_t)recordingQueue;// dispatchQ
void (^myBlock)() = ^(){NSLog(@"block called");};
pciparams[2] = (int64_t)&myBlock;
pciparams[3] = 1000;
pciparams[4] = 8;
//pciparams[4] = 12;
//pciparams[10] = 25;
//NSLog(@"ios-proxy.m:connect_hci_transport -> Returning");
return AppleConvergedTransportCreate(pciparams, &my_conn->hci_transport); // returns 1 on success
}
int connect_acl_transport(my_connection_t * my_conn) {
//NSLog(@"ios-proxy.m:connect_acl_transport -> Starting");
int64_t pciparams[11];
AppleConvergedTransportInitParameters(pciparams);
pciparams[0] = 3; //ACL
pciparams[1] = 0;
pciparams[1] = (int64_t)recordingQueue;// dispatchQ
void (^myBlock)() = ^(){NSLog(@"block called");};
pciparams[2] = (int64_t)&myBlock;
pciparams[3] = 1000;
pciparams[4] = 4;
pciparams[10] = 33;
//NSLog(@"ios-proxy.m:connect_acl_transport -> Returning");
return AppleConvergedTransportCreate(pciparams, &my_conn->acl_transport); // returns 1 on success
}
int connect_sco_transport(my_connection_t * my_conn) {
//NSLog(@"ios-proxy.m:connect_sco_transport -> Starting");
int64_t pciparams[11];
AppleConvergedTransportInitParameters(pciparams);
pciparams[0] = 4; //SCO
pciparams[1] = 0;
pciparams[1] = (int64_t)recordingQueue;// dispatchQ
//pciparams[2] = (int64_t)&_NSConcreteStackBlock;
void (^myBlock)() = ^(){NSLog(@"block called");};
pciparams[2] = (int64_t)&myBlock;
pciparams[3] = 1000;
pciparams[4] = 4;
pciparams[10] = 33;
//NSLog(@"ios-proxy.m:connect_sco_transport -> Returning");
return AppleConvergedTransportCreate(pciparams, &my_conn->sco_transport); // returns 1 on success
}
my_connection_t * connect_bt_pcie() {
//NSLog(@"ios-proxy.m:connect_bt_pcie -> Entered");
// This function will create 4 transports on PCIe, and return them in a struct.
load_AppleConvergedTransport();
NSLog(@"ios-proxy.m:connect_bt_pcie -> AppleConvergedTransport.dylib Loaded");
my_connection_t *my_connection = malloc(sizeof(my_connection_t));
my_connection->bti_transport = 0;
my_connection->hci_transport = 0;
my_connection->acl_transport = 0;
my_connection->sco_transport = 0;
//NSLog(@"ios-proxy.m:connect_bt_pcie -> Starting transport initialization");
if (!connect_bti_transport(my_connection)) // should return 1 on success
NSLog(@"InternalBlue: PCIe Error creating BTI Transport");
if (!connect_hci_transport(my_connection))
NSLog(@"InternalBlue: PCIe Error creating HCI Transport");
if (!connect_acl_transport(my_connection))
NSLog(@"InternalBlue: PCIe Error creating ACL Transport");
if (!connect_sco_transport(my_connection))
NSLog(@"InternalBlue: PCIe Error creating SCO Transport");
NSLog(@"Transports Initialized:");
NSLog(@"BTI: %u", (unsigned int) my_connection->bti_transport);
NSLog(@"HCI: %u", (unsigned int) my_connection->hci_transport);
NSLog(@"ACL: %u", (unsigned int) my_connection->acl_transport);
NSLog(@"SCO: %u", (unsigned int) my_connection->sco_transport);
if (!(my_connection->bti_transport||my_connection->hci_transport||my_connection->acl_transport||my_connection->sco_transport))
NSLog(@"ERROR: All Transports Failed! Did you forget to turn Bluetooth OFF?");
return my_connection;
}
void proxy_bt_pcie(int client, my_connection_t * my_conn) {
//NSLog(@"Allocating Buffers for Proxy Data");
// this function establishes the relay connection between the transports(bt chip) and the client socket
// only one fd and a ?
char *client_buf, *bti_buf, *hci_buf, *acl_buf, *sco_buf; // buffers for incoming data
client_buf = malloc(0x2000);
bti_buf = malloc(0x2000);
hci_buf = malloc(0x2000);
acl_buf = malloc(0x2000);
sco_buf = malloc(0x2000);
int ret;
uint64_t x = 0;
int check_hci_event = 0;
struct pollfd pfds[1];
NSLog(@"Starting Proxy Loop");
while(1){
pfds[0].fd = client;
pfds[0].events = POLLIN;
poll(pfds, 1, 100);
if(pfds[0].revents & POLLIN) {
ret = read(pfds[0].fd, client_buf, 4096);
//NSLog(@"Read Data from client. Size: %u", ret);
if (!ret) {
// This means that the client probably closed the connection
NSLog(@"!!! Client read error");
NSLog(@"Freeing Transports!");
AppleConvergedTransportFree(my_conn->bti_transport);
AppleConvergedTransportFree(my_conn->hci_transport);
AppleConvergedTransportFree(my_conn->acl_transport);
AppleConvergedTransportFree(my_conn->sco_transport);
return;
}
//send stuff to bt
//NSLog(@"Sending Data to BT Chip");
//NSLog(@"H4 Message Type: 0x%x", ((char *)client_buf)[0]);
switch(((char*)client_buf)[0]) {
case 1:
ret = AppleConvergedTransportWrite(my_conn->hci_transport, client_buf+1, ret-1, &x, -1, 0); //+1, because we strip the H4 tag
check_hci_event = 1;
break;
case 2:
ret = AppleConvergedTransportWrite(my_conn->acl_transport, client_buf+1, ret-1, &x, -1, 0);
break;
case 3:
ret = AppleConvergedTransportWrite(my_conn->sco_transport, client_buf+1, ret-1, &x, -1, 0);
break;
case 4:
ret = AppleConvergedTransportWrite(my_conn->hci_transport, client_buf+1, ret-1, &x, -1, 0);
break;
case 7:
if (my_conn->bti_transport){
//NSLog(@"sending to bti");
ret = AppleConvergedTransportWrite(my_conn->bti_transport, client_buf+1, ret-1, &x, -1, 0);}
break;
}
}
//NSLog(@"+ Done sending data to chip");
// HCI
if (check_hci_event){
ret = 0;
ret = AppleConvergedTransportRead(my_conn->hci_transport, hci_buf+1, 0x102, &x, -1, 0); // if first byte is not 0xe, do another read for more data
if (hci_buf[1] == (char) 0xe)
check_hci_event = 0;
*hci_buf = (char)4; // 1 or 4? (Command or Event)
NSLog(@"ACTRead (HCI) Returned %u", ret);
NSLog(@"ATCRead (HCI) to x: %u", (unsigned int)x);
if (ret != 0) {
write(pfds[0].fd, hci_buf, x+1);
}
}
//ACL
ret = 0;
ret = AppleConvergedTransportRead(my_conn->acl_transport, acl_buf+1, 0x102, &x, -1, 0); // if first byte is not 0xe, do another read for more data
*acl_buf = (char)2;
if (ret != 0) {
NSLog(@"ACTRead (ACL) Returned %u", ret);
NSLog(@"ATCRead (ACL) to x: %u", (unsigned int)x);}
if (ret != 0) {
write(pfds[0].fd, acl_buf, x+1);
}
//SCO
ret = 0;
ret = AppleConvergedTransportRead(my_conn->sco_transport, sco_buf+1, 0x102, &x, -1, 0); // if first byte is not 0xe, do another read for more data
*sco_buf = (char)3;
if (ret != 0) {
NSLog(@"ACTRead (SCO) Returned %u", ret);
NSLog(@"ATCRead (SCO) to x: %u", (unsigned int)x);}
if (ret != 0) {
write(pfds[0].fd, sco_buf, x+1);
}
//BTI
ret = 0;
ret = AppleConvergedTransportRead(my_conn->bti_transport, bti_buf+1, 0x102, &x, -1, 0); // if first byte is not 0xe, do another read for more data
*bti_buf = (char)7;
if (ret != 0) {
NSLog(@"ACTRead (BTI) Returned %u", ret);
NSLog(@"ATCRead (BTI) to x: %u", (unsigned int)x);
}
if (ret != 0) {
write(pfds[0].fd, bti_buf, x+1);
}
}
}
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) {
NSLog(@"[!] 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 = inet_addr("127.0.0.1");
server.sin_port = htons(port);
setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &on, 4);
if (bind(server_fd, (struct sockaddr *)&server, sizeof(server)) < 0) {
NSLog(@"[!] Error binding socket\n");
return -1;
}
if (listen(server_fd, 5) < 0) {
NSLog(@"[!] Failed listening on port %d, Error: %s\n", port, strerror(errno));
return -1;
}
NSLog(@"[*] 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) {
NSLog(@"[!] Accepting connection failed\n");
return -1;
}
return client_fd;
}