Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
L
libplist
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
1
Issues
1
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
pwn
libplist
Commits
62bcedce
Commit
62bcedce
authored
Aug 05, 2008
by
Matt Colyer
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Zack's C. rewrite of usbmux (with a few additions by Matt Colyer).
parent
294f6080
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
277 additions
and
118 deletions
+277
-118
AFC.c
src/AFC.c
+40
-26
AFC.h
src/AFC.h
+5
-6
ifuse.c
src/ifuse.c
+3
-2
iphone.c
src/iphone.c
+2
-1
lockdown.c
src/lockdown.c
+24
-12
lockdown.h
src/lockdown.h
+1
-2
plist.h
src/plist.h
+1
-0
usbmux.c
src/usbmux.c
+186
-65
usbmux.h
src/usbmux.h
+13
-4
userpref.c
src/userpref.c
+2
-0
No files found.
src/AFC.c
View file @
62bcedce
...
@@ -34,7 +34,6 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
...
@@ -34,7 +34,6 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
else
{
else
{
client
->
afc_packet
=
(
AFCPacket
*
)
malloc
(
sizeof
(
AFCPacket
));
client
->
afc_packet
=
(
AFCPacket
*
)
malloc
(
sizeof
(
AFCPacket
));
if
(
client
->
afc_packet
)
{
if
(
client
->
afc_packet
)
{
client
->
phone
=
phone
;
client
->
afc_packet
->
packet_num
=
0
;
client
->
afc_packet
->
packet_num
=
0
;
client
->
afc_packet
->
unknown1
=
client
->
afc_packet
->
unknown2
=
client
->
afc_packet
->
unknown3
=
client
->
afc_packet
->
unknown4
=
client
->
afc_packet
->
entire_length
=
client
->
afc_packet
->
this_length
=
0
;
client
->
afc_packet
->
unknown1
=
client
->
afc_packet
->
unknown2
=
client
->
afc_packet
->
unknown3
=
client
->
afc_packet
->
unknown4
=
client
->
afc_packet
->
entire_length
=
client
->
afc_packet
->
this_length
=
0
;
client
->
afc_packet
->
header1
=
0x36414643
;
client
->
afc_packet
->
header1
=
0x36414643
;
...
@@ -42,7 +41,7 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
...
@@ -42,7 +41,7 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
client
->
file_handle
=
0
;
client
->
file_handle
=
0
;
return
client
;
return
client
;
}
else
{
}
else
{
mux_close_connection
(
client
->
phone
,
client
->
connection
);
mux_close_connection
(
client
->
connection
);
free
(
client
);
free
(
client
);
return
NULL
;
return
NULL
;
}
}
...
@@ -53,8 +52,8 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
...
@@ -53,8 +52,8 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port) {
void
afc_disconnect
(
AFClient
*
client
)
{
void
afc_disconnect
(
AFClient
*
client
)
{
// client and its members should never be NULL is assumed here.
// client and its members should never be NULL is assumed here.
if
(
!
client
||
!
client
->
connection
||
!
client
->
phone
||
!
client
->
afc_packet
)
return
;
if
(
!
client
||
!
client
->
connection
||
!
client
->
afc_packet
)
return
;
mux_close_connection
(
client
->
phone
,
client
->
connection
);
mux_close_connection
(
client
->
connection
);
free
(
client
->
afc_packet
);
free
(
client
->
afc_packet
);
free
(
client
);
free
(
client
);
}
}
...
@@ -67,10 +66,10 @@ int count_nullspaces(char *string, int number) {
...
@@ -67,10 +66,10 @@ int count_nullspaces(char *string, int number) {
return
nulls
;
return
nulls
;
}
}
int
dispatch_AFC_packet
(
AFClient
*
client
,
char
*
data
,
int
length
)
{
int
dispatch_AFC_packet
(
AFClient
*
client
,
c
onst
c
har
*
data
,
int
length
)
{
char
*
buffer
;
char
*
buffer
;
int
bytes
=
0
,
offset
=
0
;
int
bytes
=
0
,
offset
=
0
;
if
(
!
client
||
!
client
->
connection
||
!
client
->
phone
||
!
client
->
afc_packet
)
return
0
;
if
(
!
client
||
!
client
->
connection
||
!
client
->
afc_packet
)
return
0
;
if
(
!
data
||
!
length
)
length
=
0
;
if
(
!
data
||
!
length
)
length
=
0
;
client
->
afc_packet
->
packet_num
++
;
client
->
afc_packet
->
packet_num
++
;
...
@@ -91,7 +90,7 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
...
@@ -91,7 +90,7 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
}
}
if
(
debug
)
printf
(
"dispatch_AFC_packet: fucked-up packet method (probably a write)
\n
"
);
if
(
debug
)
printf
(
"dispatch_AFC_packet: fucked-up packet method (probably a write)
\n
"
);
memcpy
(
buffer
+
sizeof
(
AFCPacket
),
data
,
offset
);
memcpy
(
buffer
+
sizeof
(
AFCPacket
),
data
,
offset
);
bytes
=
mux_send
(
client
->
phone
,
client
->
connection
,
buffer
,
client
->
afc_packet
->
this_length
);
bytes
=
mux_send
(
client
->
connection
,
buffer
,
client
->
afc_packet
->
this_length
);
free
(
buffer
);
free
(
buffer
);
if
(
bytes
<=
0
)
{
return
0
;
}
if
(
bytes
<=
0
)
{
return
0
;
}
if
(
debug
)
{
if
(
debug
)
{
...
@@ -102,7 +101,7 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
...
@@ -102,7 +101,7 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
}
}
bytes
=
mux_send
(
client
->
phone
,
client
->
connection
,
data
+
offset
,
length
-
offset
);
bytes
=
mux_send
(
client
->
connection
,
data
+
offset
,
length
-
offset
);
if
(
bytes
<=
0
)
{
return
0
;
}
if
(
bytes
<=
0
)
{
return
0
;
}
else
{
return
bytes
;
}
else
{
return
bytes
;
}
}
else
{
}
else
{
...
@@ -114,7 +113,7 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
...
@@ -114,7 +113,7 @@ int dispatch_AFC_packet(AFClient *client, char *data, int length) {
if
(
length
>
0
)
{
memcpy
(
buffer
+
sizeof
(
AFCPacket
),
data
,
length
);
buffer
[
sizeof
(
AFCPacket
)
+
length
]
=
'\0'
;
}
if
(
length
>
0
)
{
memcpy
(
buffer
+
sizeof
(
AFCPacket
),
data
,
length
);
buffer
[
sizeof
(
AFCPacket
)
+
length
]
=
'\0'
;
}
if
(
debug
)
fwrite
(
buffer
,
1
,
client
->
afc_packet
->
this_length
,
stdout
);
if
(
debug
)
fwrite
(
buffer
,
1
,
client
->
afc_packet
->
this_length
,
stdout
);
if
(
debug
)
printf
(
"
\n
"
);
if
(
debug
)
printf
(
"
\n
"
);
bytes
=
mux_send
(
client
->
phone
,
client
->
connection
,
buffer
,
client
->
afc_packet
->
this_length
);
bytes
=
mux_send
(
client
->
connection
,
buffer
,
client
->
afc_packet
->
this_length
);
if
(
bytes
<=
0
)
return
0
;
if
(
bytes
<=
0
)
return
0
;
else
return
bytes
;
else
return
bytes
;
}
}
...
@@ -128,7 +127,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
...
@@ -128,7 +127,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
int
bytes
=
0
,
recv_len
=
0
,
current_count
=
0
;
int
bytes
=
0
,
recv_len
=
0
,
current_count
=
0
;
int
retval
=
0
;
int
retval
=
0
;
bytes
=
mux_recv
(
client
->
phone
,
client
->
connection
,
buffer
,
sizeof
(
AFCPacket
)
*
4
);
bytes
=
mux_recv
(
client
->
connection
,
buffer
,
sizeof
(
AFCPacket
)
*
4
);
if
(
bytes
<=
0
)
{
if
(
bytes
<=
0
)
{
free
(
buffer
);
free
(
buffer
);
printf
(
"Just didn't get enough.
\n
"
);
printf
(
"Just didn't get enough.
\n
"
);
...
@@ -151,10 +150,17 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
...
@@ -151,10 +150,17 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
uint32
param1
=
buffer
[
sizeof
(
AFCPacket
)];
uint32
param1
=
buffer
[
sizeof
(
AFCPacket
)];
free
(
buffer
);
free
(
buffer
);
if
(
r_packet
->
operation
==
0x01
&&
!
((
client
->
afc_packet
->
operation
==
AFC_DELETE
&&
param1
==
7
)))
{
if
(
r_packet
->
operation
==
AFC_ERROR
if
(
debug
)
printf
(
"Oops? Bad operation code received: 0x%0X
\n
"
,
r_packet
->
operation
);
&&
!
(
client
->
afc_packet
->
operation
==
AFC_DELETE
&&
param1
==
7
)
if
(
param1
==
0
)
{
)
{
if
(
debug
)
printf
(
"Oops? Bad operation code received: 0x%X, operation=0x%X, param1=%d
\n
"
,
r_packet
->
operation
,
client
->
afc_packet
->
operation
,
param1
);
recv_len
=
r_packet
->
entire_length
-
r_packet
->
this_length
;
if
(
debug
)
printf
(
"recv_len=%d
\n
"
,
recv_len
);
if
(
param1
==
0
)
{
if
(
debug
)
printf
(
"... false alarm, but still
\n
"
);
if
(
debug
)
printf
(
"... false alarm, but still
\n
"
);
*
dump_here
=
NULL
;
return
1
;
return
1
;
}
}
else
{
if
(
debug
)
printf
(
"Errno %i
\n
"
,
param1
);
}
else
{
if
(
debug
)
printf
(
"Errno %i
\n
"
,
param1
);
}
...
@@ -167,13 +173,17 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
...
@@ -167,13 +173,17 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
recv_len
=
r_packet
->
entire_length
-
r_packet
->
this_length
;
recv_len
=
r_packet
->
entire_length
-
r_packet
->
this_length
;
free
(
r_packet
);
free
(
r_packet
);
if
(
!
recv_len
)
return
bytes
;
if
(
!
recv_len
)
{
*
dump_here
=
NULL
;
return
0
;
}
// Keep collecting packets until we have received the entire file.
// Keep collecting packets until we have received the entire file.
buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
recv_len
<
MAXIMUM_PACKET_SIZE
)
?
recv_len
:
MAXIMUM_PACKET_SIZE
);
buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
recv_len
<
MAXIMUM_PACKET_SIZE
)
?
recv_len
:
MAXIMUM_PACKET_SIZE
);
final_buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
recv_len
);
final_buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
recv_len
);
while
(
current_count
<
recv_len
){
while
(
current_count
<
recv_len
){
bytes
=
mux_recv
(
client
->
phone
,
client
->
connection
,
buffer
,
recv_len
-
current_count
);
bytes
=
mux_recv
(
client
->
connection
,
buffer
,
recv_len
-
current_count
);
if
(
bytes
<
0
)
if
(
bytes
<
0
)
{
{
if
(
debug
)
printf
(
"receive_AFC_data: mux_recv failed: %d
\n
"
,
bytes
);
if
(
debug
)
printf
(
"receive_AFC_data: mux_recv failed: %d
\n
"
,
bytes
);
...
@@ -200,7 +210,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
...
@@ -200,7 +210,7 @@ int receive_AFC_data(AFClient *client, char **dump_here) {
return
current_count
;
return
current_count
;
}
}
char
**
afc_get_dir_list
(
AFClient
*
client
,
char
*
dir
)
{
char
**
afc_get_dir_list
(
AFClient
*
client
,
c
onst
c
har
*
dir
)
{
client
->
afc_packet
->
operation
=
AFC_LIST_DIR
;
client
->
afc_packet
->
operation
=
AFC_LIST_DIR
;
int
bytes
=
0
;
int
bytes
=
0
;
char
*
blah
=
NULL
,
**
list
=
NULL
;
char
*
blah
=
NULL
,
**
list
=
NULL
;
...
@@ -232,7 +242,7 @@ char **make_strings_list(char *tokens, int true_length) {
...
@@ -232,7 +242,7 @@ char **make_strings_list(char *tokens, int true_length) {
}
}
int
afc_delete_file
(
AFClient
*
client
,
const
char
*
path
)
{
int
afc_delete_file
(
AFClient
*
client
,
const
char
*
path
)
{
if
(
!
client
||
!
path
||
!
client
->
afc_packet
||
!
client
->
phone
||!
client
->
connection
)
return
0
;
if
(
!
client
||
!
path
||
!
client
->
afc_packet
||
!
client
->
connection
)
return
0
;
char
*
receive
=
NULL
;
char
*
receive
=
NULL
;
client
->
afc_packet
->
this_length
=
client
->
afc_packet
->
entire_length
=
0
;
client
->
afc_packet
->
this_length
=
client
->
afc_packet
->
entire_length
=
0
;
...
@@ -248,7 +258,7 @@ int afc_delete_file(AFClient *client, const char *path) {
...
@@ -248,7 +258,7 @@ int afc_delete_file(AFClient *client, const char *path) {
}
}
int
afc_rename_file
(
AFClient
*
client
,
const
char
*
from
,
const
char
*
to
)
{
int
afc_rename_file
(
AFClient
*
client
,
const
char
*
from
,
const
char
*
to
)
{
if
(
!
client
||
!
from
||
!
to
||
!
client
->
afc_packet
||
!
client
->
phone
||
!
client
->
connection
)
return
0
;
if
(
!
client
||
!
from
||
!
to
||
!
client
->
afc_packet
||
!
client
->
connection
)
return
0
;
char
*
receive
=
NULL
;
char
*
receive
=
NULL
;
char
*
send
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
strlen
(
from
)
+
strlen
(
to
)
+
1
+
sizeof
(
uint32
)));
char
*
send
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
strlen
(
from
)
+
strlen
(
to
)
+
1
+
sizeof
(
uint32
)));
...
@@ -271,7 +281,7 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {
...
@@ -271,7 +281,7 @@ int afc_rename_file(AFClient *client, const char *from, const char *to) {
AFCFile
*
afc_get_file_info
(
AFClient
*
client
,
char
*
path
)
{
AFCFile
*
afc_get_file_info
(
AFClient
*
client
,
c
onst
c
har
*
path
)
{
client
->
afc_packet
->
operation
=
AFC_GET_INFO
;
client
->
afc_packet
->
operation
=
AFC_GET_INFO
;
client
->
afc_packet
->
entire_length
=
client
->
afc_packet
->
this_length
=
0
;
client
->
afc_packet
->
entire_length
=
client
->
afc_packet
->
this_length
=
0
;
dispatch_AFC_packet
(
client
,
path
,
strlen
(
path
));
dispatch_AFC_packet
(
client
,
path
,
strlen
(
path
));
...
@@ -312,7 +322,7 @@ AFCFile *afc_get_file_info(AFClient *client, char *path) {
...
@@ -312,7 +322,7 @@ AFCFile *afc_get_file_info(AFClient *client, char *path) {
AFCFile
*
afc_open_file
(
AFClient
*
client
,
const
char
*
filename
,
uint32
file_mode
)
{
AFCFile
*
afc_open_file
(
AFClient
*
client
,
const
char
*
filename
,
uint32
file_mode
)
{
if
(
file_mode
!=
AFC_FILE_READ
&&
file_mode
!=
AFC_FILE_WRITE
)
return
NULL
;
if
(
file_mode
!=
AFC_FILE_READ
&&
file_mode
!=
AFC_FILE_WRITE
)
return
NULL
;
if
(
!
client
||!
client
->
connection
||
!
client
->
phone
||!
client
->
afc_packet
)
return
NULL
;
if
(
!
client
||!
client
->
connection
||
!
client
->
afc_packet
)
return
NULL
;
char
*
further_data
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
8
+
strlen
(
filename
)
+
1
));
char
*
further_data
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
8
+
strlen
(
filename
)
+
1
));
AFCFile
*
file_infos
=
NULL
;
AFCFile
*
file_infos
=
NULL
;
memcpy
(
further_data
,
&
file_mode
,
4
);
memcpy
(
further_data
,
&
file_mode
,
4
);
...
@@ -345,7 +355,7 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
...
@@ -345,7 +355,7 @@ AFCFile *afc_open_file(AFClient *client, const char *filename, uint32 file_mode)
}
}
int
afc_read_file
(
AFClient
*
client
,
AFCFile
*
file
,
char
*
data
,
int
length
)
{
int
afc_read_file
(
AFClient
*
client
,
AFCFile
*
file
,
char
*
data
,
int
length
)
{
if
(
!
client
||
!
client
->
afc_packet
||
!
client
->
phone
||
!
client
->
connection
||
!
file
)
return
-
1
;
if
(
!
client
||
!
client
->
afc_packet
||
!
client
->
connection
||
!
file
)
return
-
1
;
AFCFilePacket
*
packet
=
(
AFCFilePacket
*
)
malloc
(
sizeof
(
AFCFilePacket
));
AFCFilePacket
*
packet
=
(
AFCFilePacket
*
)
malloc
(
sizeof
(
AFCFilePacket
));
char
*
input
=
NULL
;
char
*
input
=
NULL
;
packet
->
unknown1
=
packet
->
unknown2
=
0
;
packet
->
unknown1
=
packet
->
unknown2
=
0
;
...
@@ -359,10 +369,14 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
...
@@ -359,10 +369,14 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
if
(
bytes
>
0
)
{
if
(
bytes
>
0
)
{
bytes
=
receive_AFC_data
(
client
,
&
input
);
bytes
=
receive_AFC_data
(
client
,
&
input
);
if
(
bytes
<
=
0
)
{
if
(
bytes
<
0
)
{
if
(
input
)
free
(
input
);
if
(
input
)
free
(
input
);
return
-
1
;
return
-
1
;
}
else
if
(
bytes
==
0
)
{
if
(
input
)
free
(
input
);
return
0
;
}
else
{
}
else
{
if
(
input
)
memcpy
(
data
,
input
,
(
bytes
>
length
)
?
length
:
bytes
);
memcpy
(
data
,
input
,
(
bytes
>
length
)
?
length
:
bytes
);
free
(
input
);
free
(
input
);
return
(
bytes
>
length
)
?
length
:
bytes
;
return
(
bytes
>
length
)
?
length
:
bytes
;
...
@@ -373,9 +387,9 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
...
@@ -373,9 +387,9 @@ int afc_read_file(AFClient *client, AFCFile *file, char *data, int length) {
return
0
;
return
0
;
}
}
int
afc_write_file
(
AFClient
*
client
,
AFCFile
*
file
,
char
*
data
,
int
length
)
{
int
afc_write_file
(
AFClient
*
client
,
AFCFile
*
file
,
c
onst
c
har
*
data
,
int
length
)
{
char
*
acknowledgement
=
NULL
;
char
*
acknowledgement
=
NULL
;
if
(
!
client
||!
client
->
afc_packet
||
!
client
->
phone
||
!
client
->
connection
||
!
file
)
return
-
1
;
if
(
!
client
||!
client
->
afc_packet
||
!
client
->
connection
||
!
file
)
return
-
1
;
client
->
afc_packet
->
this_length
=
sizeof
(
AFCPacket
)
+
8
;
client
->
afc_packet
->
this_length
=
sizeof
(
AFCPacket
)
+
8
;
client
->
afc_packet
->
entire_length
=
client
->
afc_packet
->
this_length
+
length
;
client
->
afc_packet
->
entire_length
=
client
->
afc_packet
->
this_length
+
length
;
client
->
afc_packet
->
operation
=
AFC_WRITE
;
client
->
afc_packet
->
operation
=
AFC_WRITE
;
...
...
src/AFC.h
View file @
62bcedce
...
@@ -35,8 +35,7 @@ typedef struct {
...
@@ -35,8 +35,7 @@ typedef struct {
}
AFCPacket
;
}
AFCPacket
;
typedef
struct
{
typedef
struct
{
usbmux_tcp_header
*
connection
;
usbmux_connection
*
connection
;
iPhone
*
phone
;
AFCPacket
*
afc_packet
;
AFCPacket
*
afc_packet
;
int
file_handle
;
int
file_handle
;
}
AFClient
;
}
AFClient
;
...
@@ -79,14 +78,14 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port);
...
@@ -79,14 +78,14 @@ AFClient *afc_connect(iPhone *phone, int s_port, int d_port);
void
afc_disconnect
(
AFClient
*
client
);
void
afc_disconnect
(
AFClient
*
client
);
int
count_nullspaces
(
char
*
string
,
int
number
);
int
count_nullspaces
(
char
*
string
,
int
number
);
char
**
make_strings_list
(
char
*
tokens
,
int
true_length
);
char
**
make_strings_list
(
char
*
tokens
,
int
true_length
);
int
dispatch_AFC_packet
(
AFClient
*
client
,
char
*
data
,
int
length
);
int
dispatch_AFC_packet
(
AFClient
*
client
,
c
onst
c
har
*
data
,
int
length
);
int
receive_AFC_data
(
AFClient
*
client
,
char
**
dump_here
);
int
receive_AFC_data
(
AFClient
*
client
,
char
**
dump_here
);
char
**
afc_get_dir_list
(
AFClient
*
client
,
char
*
dir
);
char
**
afc_get_dir_list
(
AFClient
*
client
,
c
onst
c
har
*
dir
);
AFCFile
*
afc_get_file_info
(
AFClient
*
client
,
char
*
path
);
AFCFile
*
afc_get_file_info
(
AFClient
*
client
,
c
onst
c
har
*
path
);
AFCFile
*
afc_open_file
(
AFClient
*
client
,
const
char
*
filename
,
uint32
file_mode
);
AFCFile
*
afc_open_file
(
AFClient
*
client
,
const
char
*
filename
,
uint32
file_mode
);
void
afc_close_file
(
AFClient
*
client
,
AFCFile
*
file
);
void
afc_close_file
(
AFClient
*
client
,
AFCFile
*
file
);
int
afc_read_file
(
AFClient
*
client
,
AFCFile
*
file
,
char
*
data
,
int
length
);
int
afc_read_file
(
AFClient
*
client
,
AFCFile
*
file
,
char
*
data
,
int
length
);
int
afc_write_file
(
AFClient
*
client
,
AFCFile
*
file
,
char
*
data
,
int
length
);
int
afc_write_file
(
AFClient
*
client
,
AFCFile
*
file
,
c
onst
c
har
*
data
,
int
length
);
int
afc_delete_file
(
AFClient
*
client
,
const
char
*
path
);
int
afc_delete_file
(
AFClient
*
client
,
const
char
*
path
);
int
afc_rename_file
(
AFClient
*
client
,
const
char
*
from
,
const
char
*
to
);
int
afc_rename_file
(
AFClient
*
client
,
const
char
*
from
,
const
char
*
to
);
src/ifuse.c
View file @
62bcedce
...
@@ -155,9 +155,10 @@ void *ifuse_init(struct fuse_conn_info *conn) {
...
@@ -155,9 +155,10 @@ void *ifuse_init(struct fuse_conn_info *conn) {
return
afc
;
return
afc
;
}
}
void
ifuse_cleanup
(
AFClient
*
afc
)
{
void
ifuse_cleanup
(
void
*
data
)
{
AFClient
*
afc
=
(
AFClient
*
)
data
;
if
(
afc
)
{
if
(
afc
)
{
iPhone
*
phone
=
afc
->
phone
;
iPhone
*
phone
=
afc
->
connection
->
phone
;
afc_disconnect
(
afc
);
afc_disconnect
(
afc
);
free_iPhone
(
phone
);
free_iPhone
(
phone
);
}
}
...
...
src/iphone.c
View file @
62bcedce
...
@@ -171,10 +171,11 @@ int send_to_phone(iPhone *phone, char *data, int datalen) {
...
@@ -171,10 +171,11 @@ int send_to_phone(iPhone *phone, char *data, int datalen) {
int
recv_from_phone
(
iPhone
*
phone
,
char
*
data
,
int
datalen
)
{
int
recv_from_phone
(
iPhone
*
phone
,
char
*
data
,
int
datalen
)
{
if
(
!
phone
)
return
-
1
;
if
(
!
phone
)
return
-
1
;
int
bytes
=
0
;
int
bytes
=
0
;
if
(
debug
)
printf
(
"recv_from_phone(): attempting to receive %i bytes
\n
"
,
datalen
);
bytes
=
usb_bulk_read
(
phone
->
device
,
BULKIN
,
data
,
datalen
,
3500
);
bytes
=
usb_bulk_read
(
phone
->
device
,
BULKIN
,
data
,
datalen
,
3500
);
if
(
bytes
<
0
)
if
(
bytes
<
0
)
{
{
if
(
debug
)
printf
(
"recv_from_
i
phone(): libusb gave me the error %d: %s (%s)
\n
"
,
bytes
,
usb_strerror
(),
strerror
(
-
bytes
));
if
(
debug
)
printf
(
"recv_from_phone(): libusb gave me the error %d: %s (%s)
\n
"
,
bytes
,
usb_strerror
(),
strerror
(
-
bytes
));
return
-
1
;
return
-
1
;
}
}
return
bytes
;
return
bytes
;
...
...
src/lockdown.c
View file @
62bcedce
...
@@ -39,7 +39,6 @@ lockdownd_client *new_lockdownd_client(iPhone *phone) {
...
@@ -39,7 +39,6 @@ lockdownd_client *new_lockdownd_client(iPhone *phone) {
control
->
ssl_session
=
(
gnutls_session_t
*
)
malloc
(
sizeof
(
gnutls_session_t
));
control
->
ssl_session
=
(
gnutls_session_t
*
)
malloc
(
sizeof
(
gnutls_session_t
));
control
->
in_SSL
=
0
;
control
->
in_SSL
=
0
;
control
->
iphone
=
phone
;
control
->
gtls_buffer_hack_len
=
0
;
control
->
gtls_buffer_hack_len
=
0
;
return
control
;
return
control
;
}
}
...
@@ -47,7 +46,7 @@ lockdownd_client *new_lockdownd_client(iPhone *phone) {
...
@@ -47,7 +46,7 @@ lockdownd_client *new_lockdownd_client(iPhone *phone) {
void
lockdown_close
(
lockdownd_client
*
control
)
{
void
lockdown_close
(
lockdownd_client
*
control
)
{
if
(
!
control
)
return
;
if
(
!
control
)
return
;
if
(
control
->
connection
)
{
if
(
control
->
connection
)
{
mux_close_connection
(
control
->
iphone
,
control
->
connection
);
mux_close_connection
(
control
->
connection
);
}
}
if
(
control
->
ssl_session
)
free
(
control
->
ssl_session
);
if
(
control
->
ssl_session
)
free
(
control
->
ssl_session
);
...
@@ -56,21 +55,23 @@ void lockdown_close(lockdownd_client *control) {
...
@@ -56,21 +55,23 @@ void lockdown_close(lockdownd_client *control) {
int
lockdownd_recv
(
lockdownd_client
*
control
,
char
**
dump_data
)
{
int
lockdownd_recv
(
lockdownd_client
*
control
,
char
**
dump_data
)
{
if
(
!
control
)
return
0
;
char
*
receive
;
char
*
receive
;
uint32
datalen
=
0
,
bytes
=
0
;
uint32
datalen
=
0
,
bytes
=
0
;
if
(
!
control
->
in_SSL
)
bytes
=
mux_recv
(
control
->
iphone
,
control
->
connection
,
&
datalen
,
sizeof
(
datalen
));
if
(
!
control
->
in_SSL
)
bytes
=
mux_recv
(
control
->
connection
,
(
char
*
)
&
datalen
,
sizeof
(
datalen
));
else
bytes
=
gnutls_record_recv
(
*
control
->
ssl_session
,
&
datalen
,
sizeof
(
datalen
));
else
bytes
=
gnutls_record_recv
(
*
control
->
ssl_session
,
&
datalen
,
sizeof
(
datalen
));
datalen
=
ntohl
(
datalen
);
datalen
=
ntohl
(
datalen
);
receive
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
datalen
);
receive
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
datalen
);
if
(
!
control
->
in_SSL
)
bytes
=
mux_recv
(
control
->
iphone
,
control
->
connection
,
receive
,
datalen
);
if
(
!
control
->
in_SSL
)
bytes
=
mux_recv
(
control
->
connection
,
receive
,
datalen
);
else
bytes
=
gnutls_record_recv
(
*
control
->
ssl_session
,
receive
,
datalen
);
else
bytes
=
gnutls_record_recv
(
*
control
->
ssl_session
,
receive
,
datalen
);
*
dump_data
=
receive
;
*
dump_data
=
receive
;
return
bytes
;
return
bytes
;
}
}
int
lockdownd_send
(
lockdownd_client
*
control
,
char
*
raw_data
,
uint32
length
)
{
int
lockdownd_send
(
lockdownd_client
*
control
,
char
*
raw_data
,
uint32
length
)
{
if
(
!
control
)
return
0
;
char
*
real_query
;
char
*
real_query
;
int
bytes
;
int
bytes
;
...
@@ -78,29 +79,39 @@ int lockdownd_send(lockdownd_client *control, char *raw_data, uint32 length) {
...
@@ -78,29 +79,39 @@ int lockdownd_send(lockdownd_client *control, char *raw_data, uint32 length) {
length
=
htonl
(
length
);
length
=
htonl
(
length
);
memcpy
(
real_query
,
&
length
,
sizeof
(
length
));
memcpy
(
real_query
,
&
length
,
sizeof
(
length
));
memcpy
(
real_query
+
4
,
raw_data
,
ntohl
(
length
));
memcpy
(
real_query
+
4
,
raw_data
,
ntohl
(
length
));
if
(
!
control
->
in_SSL
)
bytes
=
mux_send
(
control
->
iphone
,
control
->
connection
,
real_query
,
ntohl
(
length
)
+
sizeof
(
length
));
if
(
debug
)
{
printf
(
"lockdownd_send(): made the query, sending it along
\n
"
);
FILE
*
packet
=
fopen
(
"grpkt"
,
"w"
);
fwrite
(
real_query
,
1
,
ntohl
(
length
)
+
4
,
packet
);
fclose
(
packet
);
packet
=
NULL
;
}
if
(
!
control
->
in_SSL
)
bytes
=
mux_send
(
control
->
connection
,
real_query
,
ntohl
(
length
)
+
sizeof
(
length
));
else
gnutls_record_send
(
*
control
->
ssl_session
,
real_query
,
ntohl
(
length
)
+
sizeof
(
length
));
else
gnutls_record_send
(
*
control
->
ssl_session
,
real_query
,
ntohl
(
length
)
+
sizeof
(
length
));
if
(
debug
)
printf
(
"lockdownd_send(): sent it!
\n
"
);
free
(
real_query
);
return
bytes
;
return
bytes
;
}
}
int
lockdownd_hello
(
lockdownd_client
*
control
)
{
int
lockdownd_hello
(
lockdownd_client
*
control
)
{
if
(
!
control
)
return
0
;
xmlDocPtr
plist
=
new_plist
();
xmlDocPtr
plist
=
new_plist
();
xmlNode
*
dict
,
*
key
;
xmlNode
*
dict
,
*
key
;
char
**
dictionary
;
char
**
dictionary
;
int
bytes
=
0
,
i
=
0
;
int
bytes
=
0
,
i
=
0
;
if
(
debug
)
printf
(
"lockdownd_hello() called
\n
"
);
dict
=
add_child_to_plist
(
plist
,
"dict"
,
"
\n
"
,
NULL
,
0
);
dict
=
add_child_to_plist
(
plist
,
"dict"
,
"
\n
"
,
NULL
,
0
);
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Request"
,
"QueryType"
,
1
);
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Request"
,
"QueryType"
,
1
);
char
*
XML_content
;
char
*
XML_content
;
uint32
length
;
uint32
length
;
xmlDocDumpMemory
(
plist
,
&
XML_content
,
&
length
);
xmlDocDumpMemory
(
plist
,
(
xmlChar
**
)
&
XML_content
,
&
length
);
bytes
=
lockdownd_send
(
control
,
XML_content
,
length
);
bytes
=
lockdownd_send
(
control
,
XML_content
,
length
);
xmlFree
(
XML_content
);
xmlFree
(
XML_content
);
xmlFreeDoc
(
plist
);
plist
=
NULL
;
xmlFreeDoc
(
plist
);
plist
=
NULL
;
bytes
=
lockdownd_recv
(
control
,
&
XML_content
);
bytes
=
lockdownd_recv
(
control
,
&
XML_content
);
plist
=
xmlReadMemory
(
XML_content
,
bytes
,
NULL
,
NULL
,
0
);
plist
=
xmlReadMemory
(
XML_content
,
bytes
,
NULL
,
NULL
,
0
);
...
@@ -118,6 +129,7 @@ int lockdownd_hello(lockdownd_client *control) {
...
@@ -118,6 +129,7 @@ int lockdownd_hello(lockdownd_client *control) {
for
(
i
=
0
;
strcmp
(
dictionary
[
i
],
""
);
i
+=
2
)
{
for
(
i
=
0
;
strcmp
(
dictionary
[
i
],
""
);
i
+=
2
)
{
if
(
!
strcmp
(
dictionary
[
i
],
"Result"
)
&&
!
strcmp
(
dictionary
[
i
+
1
],
"Success"
))
{
if
(
!
strcmp
(
dictionary
[
i
],
"Result"
)
&&
!
strcmp
(
dictionary
[
i
+
1
],
"Success"
))
{
free_dictionary
(
dictionary
);
free_dictionary
(
dictionary
);
if
(
debug
)
printf
(
"lockdownd_hello(): success
\n
"
);
return
1
;
return
1
;
}
}
}
}
...
@@ -147,7 +159,7 @@ int lockdownd_start_SSL_session(lockdownd_client *control, const char *HostID) {
...
@@ -147,7 +159,7 @@ int lockdownd_start_SSL_session(lockdownd_client *control, const char *HostID) {
return
0
;
return
0
;
}
}
xmlDocDumpMemory
(
plist
,
&
what2send
,
&
len
);
xmlDocDumpMemory
(
plist
,
(
xmlChar
**
)
&
what2send
,
&
len
);
bytes
=
lockdownd_send
(
control
,
what2send
,
len
);
bytes
=
lockdownd_send
(
control
,
what2send
,
len
);
xmlFree
(
what2send
);
xmlFree
(
what2send
);
...
@@ -239,7 +251,7 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size
...
@@ -239,7 +251,7 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size
control
=
(
lockdownd_client
*
)
transport
;
control
=
(
lockdownd_client
*
)
transport
;
if
(
debug
)
printf
(
"lockdownd_secuwrite() called
\n
"
);
if
(
debug
)
printf
(
"lockdownd_secuwrite() called
\n
"
);
if
(
debug
)
printf
(
"pre-send
\n
length = %i
\n
"
,
length
);
if
(
debug
)
printf
(
"pre-send
\n
length = %i
\n
"
,
length
);
bytes
=
mux_send
(
control
->
iphone
,
control
->
connection
,
buffer
,
length
);
bytes
=
mux_send
(
control
->
connection
,
buffer
,
length
);
if
(
debug
)
printf
(
"post-send
\n
sent %i bytes
\n
"
,
bytes
);
if
(
debug
)
printf
(
"post-send
\n
sent %i bytes
\n
"
,
bytes
);
if
(
debug
)
{
if
(
debug
)
{
FILE
*
my_ssl_packet
=
fopen
(
"sslpacketwrite.out"
,
"w+"
);
FILE
*
my_ssl_packet
=
fopen
(
"sslpacketwrite.out"
,
"w+"
);
...
@@ -289,7 +301,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
...
@@ -289,7 +301,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
char
*
recv_buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
length
*
1000
));
// ensuring nothing stupid happens
char
*
recv_buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
length
*
1000
));
// ensuring nothing stupid happens
if
(
debug
)
printf
(
"pre-read
\n
client wants %i bytes
\n
"
,
length
);
if
(
debug
)
printf
(
"pre-read
\n
client wants %i bytes
\n
"
,
length
);
bytes
=
mux_recv
(
control
->
iphone
,
control
->
connection
,
recv_buffer
,
(
length
*
1000
));
bytes
=
mux_recv
(
control
->
connection
,
recv_buffer
,
(
length
*
1000
));
if
(
debug
)
printf
(
"post-read
\n
we got %i bytes
\n
"
,
bytes
);
if
(
debug
)
printf
(
"post-read
\n
we got %i bytes
\n
"
,
bytes
);
if
(
debug
&&
bytes
<
0
)
{
if
(
debug
&&
bytes
<
0
)
{
printf
(
"lockdownd_securead(): uh oh
\n
"
);
printf
(
"lockdownd_securead(): uh oh
\n
"
);
...
@@ -339,7 +351,7 @@ int lockdownd_start_service(lockdownd_client *control, const char *service) {
...
@@ -339,7 +351,7 @@ int lockdownd_start_service(lockdownd_client *control, const char *service) {
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Service"
,
service
,
1
);
key
=
add_key_str_dict_element
(
plist
,
dict
,
"Service"
,
service
,
1
);
if
(
!
key
)
{
xmlFreeDoc
(
plist
);
return
0
;
}
if
(
!
key
)
{
xmlFreeDoc
(
plist
);
return
0
;
}
xmlDocDumpMemory
(
plist
,
&
XML_query
,
&
length
);
xmlDocDumpMemory
(
plist
,
(
xmlChar
**
)
&
XML_query
,
&
length
);
lockdownd_send
(
control
,
XML_query
,
length
);
lockdownd_send
(
control
,
XML_query
,
length
);
free
(
XML_query
);
free
(
XML_query
);
...
...
src/lockdown.h
View file @
62bcedce
...
@@ -28,9 +28,8 @@
...
@@ -28,9 +28,8 @@
#include <string.h>
#include <string.h>
typedef
struct
{
typedef
struct
{
usbmux_
tcp_header
*
connection
;
usbmux_
connection
*
connection
;
gnutls_session_t
*
ssl_session
;
gnutls_session_t
*
ssl_session
;
iPhone
*
iphone
;
int
in_SSL
;
int
in_SSL
;
char
*
gtls_buffer_hack
;
char
*
gtls_buffer_hack
;
int
gtls_buffer_hack_len
;
int
gtls_buffer_hack_len
;
...
...
src/plist.h
View file @
62bcedce
...
@@ -29,5 +29,6 @@ xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *ke
...
@@ -29,5 +29,6 @@ xmlNode *add_key_str_dict_element(xmlDocPtr plist, xmlNode *dict, const char *ke
xmlNode
*
add_child_to_plist
(
xmlDocPtr
plist
,
const
char
*
name
,
const
char
*
content
,
xmlNode
*
to_node
,
int
depth
);
xmlNode
*
add_child_to_plist
(
xmlDocPtr
plist
,
const
char
*
name
,
const
char
*
content
,
xmlNode
*
to_node
,
int
depth
);
void
free_plist
(
xmlDocPtr
plist
);
void
free_plist
(
xmlDocPtr
plist
);
xmlDocPtr
new_plist
();
xmlDocPtr
new_plist
();
char
**
read_dict_element_strings
(
xmlNode
*
dict
);
void
free_dictionary
(
char
**
dictionary
);
void
free_dictionary
(
char
**
dictionary
);
#endif
#endif
src/usbmux.c
View file @
62bcedce
...
@@ -29,6 +29,9 @@
...
@@ -29,6 +29,9 @@
extern
int
debug
;
extern
int
debug
;
static
usbmux_connection
**
connlist
=
NULL
;
static
int
connections
=
0
;
usbmux_tcp_header
*
new_mux_packet
(
uint16
s_port
,
uint16
d_port
)
{
usbmux_tcp_header
*
new_mux_packet
(
uint16
s_port
,
uint16
d_port
)
{
usbmux_tcp_header
*
conn
=
(
usbmux_tcp_header
*
)
malloc
(
sizeof
(
usbmux_tcp_header
));
usbmux_tcp_header
*
conn
=
(
usbmux_tcp_header
*
)
malloc
(
sizeof
(
usbmux_tcp_header
));
conn
->
type
=
htonl
(
6
);
conn
->
type
=
htonl
(
6
);
...
@@ -54,6 +57,47 @@ usbmux_version_header *version_header() {
...
@@ -54,6 +57,47 @@ usbmux_version_header *version_header() {
return
version
;
return
version
;
}
}
// Maintenance functions.
/* delete_connection(connection)
* connection: the connection to delete from the tracking list.
* Removes a connection from the list of connections made.
* The list of connections is necessary for buffering.
*/
void
delete_connection
(
usbmux_connection
*
connection
)
{
usbmux_connection
**
newlist
=
(
usbmux_connection
**
)
malloc
(
sizeof
(
usbmux_connection
*
)
*
(
connections
-
1
));
int
i
=
0
,
j
=
0
;
for
(
i
=
0
;
i
<
connections
;
i
++
)
{
if
(
connlist
[
i
]
==
connection
)
continue
;
else
{
newlist
[
j
]
=
connlist
[
i
];
j
++
;
}
}
free
(
connlist
);
connlist
=
newlist
;
connections
--
;
if
(
connection
->
recv_buffer
)
free
(
connection
->
recv_buffer
);
if
(
connection
->
header
)
free
(
connection
->
header
);
connection
->
r_len
=
0
;
free
(
connection
);
}
/* add_connection(connection)
* connection: the connection to add to the global list of connections.
* Adds a connection to the list of connections made.
* The connection list is necessary for buffering.
*/
void
add_connection
(
usbmux_connection
*
connection
)
{
usbmux_connection
**
newlist
=
(
usbmux_connection
**
)
realloc
(
connlist
,
sizeof
(
usbmux_connection
*
)
*
(
connections
+
1
));
newlist
[
connections
]
=
connection
;
connlist
=
newlist
;
connections
++
;
}
/* mux_connect(phone, s_port, d_port)
/* mux_connect(phone, s_port, d_port)
* This is a higher-level USBMuxTCP-type function.
* This is a higher-level USBMuxTCP-type function.
* phone: the iPhone to initialize a connection on.
* phone: the iPhone to initialize a connection on.
...
@@ -64,27 +108,33 @@ usbmux_version_header *version_header() {
...
@@ -64,27 +108,33 @@ usbmux_version_header *version_header() {
* Returns a mux TCP header for the connection which is used for tracking and data transfer.
* Returns a mux TCP header for the connection which is used for tracking and data transfer.
*/
*/
usbmux_
tcp_header
*
mux_connect
(
iPhone
*
phone
,
uint16
s_port
,
uint16
d_port
)
{
usbmux_
connection
*
mux_connect
(
iPhone
*
phone
,
uint16
s_port
,
uint16
d_port
)
{
if
(
!
phone
||
!
s_port
||
!
d_port
)
return
NULL
;
if
(
!
phone
||
!
s_port
||
!
d_port
)
return
NULL
;
int
bytes
=
0
;
int
bytes
=
0
;
// Initialize connection stuff
// Initialize connection stuff
usbmux_
tcp_header
*
new_connection
;
usbmux_
connection
*
new_connection
=
(
usbmux_connection
*
)
malloc
(
sizeof
(
usbmux_connection
))
;
new_connection
=
new_mux_packet
(
s_port
,
d_port
);
new_connection
->
header
=
new_mux_packet
(
s_port
,
d_port
);
usbmux_tcp_header
*
response
;
usbmux_tcp_header
*
response
;
response
=
(
usbmux_tcp_header
*
)
malloc
(
sizeof
(
usbmux_tcp_header
));
response
=
(
usbmux_tcp_header
*
)
malloc
(
sizeof
(
usbmux_tcp_header
));
// blargg
// blargg
if
(
new_connection
)
{
if
(
new_connection
&&
new_connection
->
header
)
{
new_connection
->
tcp_flags
=
0x02
;
new_connection
->
header
->
tcp_flags
=
0x02
;
new_connection
->
length
=
htonl
(
new_connection
->
length
);
new_connection
->
header
->
length
=
htonl
(
new_connection
->
header
->
length
);
new_connection
->
length16
=
htons
(
new_connection
->
length16
);
new_connection
->
header
->
length16
=
htons
(
new_connection
->
header
->
length16
);
if
(
send_to_phone
(
phone
,
(
char
*
)
new_connection
,
sizeof
(
*
new_connection
))
>=
0
)
{
if
(
send_to_phone
(
phone
,
(
char
*
)
new_connection
->
header
,
sizeof
(
usbmux_tcp_header
))
>=
0
)
{
bytes
=
recv_from_phone
(
phone
,
(
char
*
)
response
,
sizeof
(
*
response
));
bytes
=
recv_from_phone
(
phone
,
(
char
*
)
response
,
sizeof
(
*
response
));
if
(
response
->
tcp_flags
!=
0x12
)
return
NULL
;
if
(
response
->
tcp_flags
!=
0x12
)
return
NULL
;
else
{
else
{
new_connection
->
tcp_flags
=
0x10
;
if
(
debug
)
printf
(
"mux_connect: connection success
\n
"
);
new_connection
->
scnt
=
1
;
new_connection
->
header
->
tcp_flags
=
0x10
;
new_connection
->
ocnt
=
1
;
new_connection
->
header
->
scnt
=
1
;
new_connection
->
header
->
ocnt
=
1
;
add_connection
(
new_connection
);
new_connection
->
phone
=
phone
;
new_connection
->
recv_buffer
=
NULL
;
new_connection
->
r_len
=
0
;
add_connection
(
new_connection
);
return
new_connection
;
return
new_connection
;
}
}
}
else
{
}
else
{
...
@@ -103,23 +153,24 @@ usbmux_tcp_header *mux_connect(iPhone *phone, uint16 s_port, uint16 d_port) {
...
@@ -103,23 +153,24 @@ usbmux_tcp_header *mux_connect(iPhone *phone, uint16 s_port, uint16 d_port) {
*
*
* Doesn't return anything; WILL FREE THE CONNECTION'S MEMORY!!!
* Doesn't return anything; WILL FREE THE CONNECTION'S MEMORY!!!
*/
*/
void
mux_close_connection
(
iPhone
*
phone
,
usbmux_tcp_header
*
connection
)
{
if
(
!
phone
||
!
connection
)
return
;
connection
->
tcp_flags
=
0x04
;
void
mux_close_connection
(
usbmux_connection
*
connection
)
{
connection
->
scnt
=
htonl
(
connection
->
scnt
);
if
(
!
connection
||
!
connection
->
phone
)
return
;
connection
->
ocnt
=
htonl
(
connection
->
ocnt
);
connection
->
header
->
tcp_flags
=
0x04
;
connection
->
header
->
scnt
=
htonl
(
connection
->
header
->
scnt
);
connection
->
header
->
ocnt
=
htonl
(
connection
->
header
->
ocnt
);
int
bytes
=
0
;
int
bytes
=
0
;
bytes
=
usb_bulk_write
(
phone
->
device
,
BULKOUT
,
(
char
*
)
connection
,
sizeof
(
*
connection
),
800
);
bytes
=
usb_bulk_write
(
connection
->
phone
->
device
,
BULKOUT
,
(
char
*
)
connection
->
header
,
sizeof
(
usbmux_tcp_header
),
800
);
if
(
debug
&&
bytes
<
0
)
if
(
debug
&&
bytes
<
0
)
printf
(
"mux_close_connection(): when writing, libusb gave me the error: %s
\n
"
,
usb_strerror
());
printf
(
"mux_close_connection(): when writing, libusb gave me the error: %s
\n
"
,
usb_strerror
());
bytes
=
usb_bulk_read
(
phone
->
device
,
BULKIN
,
(
char
*
)
connection
,
sizeof
(
*
connection
),
800
);
bytes
=
usb_bulk_read
(
connection
->
phone
->
device
,
BULKIN
,
(
char
*
)
connection
->
header
,
sizeof
(
usbmux_tcp_header
),
800
);
if
(
debug
&&
bytes
<
0
)
if
(
debug
&&
bytes
<
0
)
printf
(
"get_iPhone(): when reading, libusb gave me the error: %s
\n
"
,
usb_strerror
());
printf
(
"get_iPhone(): when reading, libusb gave me the error: %s
\n
"
,
usb_strerror
());
free
(
connection
);
delete_connection
(
connection
);
}
}
/* mux_send(phone, connection, data, datalen)
/* mux_send(phone, connection, data, datalen)
...
@@ -131,40 +182,46 @@ void mux_close_connection(iPhone *phone, usbmux_tcp_header *connection) {
...
@@ -131,40 +182,46 @@ void mux_close_connection(iPhone *phone, usbmux_tcp_header *connection) {
*
*
* Returns number of bytes sent, minus the header (28), or -1 on error.
* Returns number of bytes sent, minus the header (28), or -1 on error.
*/
*/
int
mux_send
(
iPhone
*
phone
,
usbmux_tcp_header
*
connection
,
char
*
data
,
uint32
datalen
)
{
int
mux_send
(
usbmux_connection
*
connection
,
const
char
*
data
,
uint32
datalen
)
{
if
(
!
phone
||
!
connection
||
!
data
||
datalen
==
0
)
return
-
1
;
if
(
!
connection
->
phone
||
!
connection
||
!
data
||
datalen
==
0
)
return
-
1
;
// connection->scnt and connection->ocnt should already be in host notation...
// connection->scnt and connection->ocnt should already be in host notation...
// we don't need to change them juuuust yet.
// we don't need to change them juuuust yet.
int
bytes
=
0
;
int
bytes
=
0
;
if
(
debug
)
printf
(
"mux_send(): client wants to send %i bytes
\n
"
,
datalen
);
if
(
debug
)
printf
(
"mux_send(): client wants to send %i bytes
\n
"
,
datalen
);
char
*
buffer
=
(
char
*
)
malloc
(
sizeof
(
*
connection
)
+
datalen
+
2
);
// allow 2 bytes of safety padding
char
*
buffer
=
(
char
*
)
malloc
(
sizeof
(
usbmux_tcp_header
)
+
datalen
+
2
);
// allow 2 bytes of safety padding
// Set the length and pre-emptively htonl/htons it
// Set the length and pre-emptively htonl/htons it
connection
->
length
=
htonl
(
sizeof
(
*
connection
)
+
datalen
);
connection
->
header
->
length
=
htonl
(
sizeof
(
usbmux_tcp_header
)
+
datalen
);
connection
->
length16
=
htons
(
sizeof
(
*
connection
)
+
datalen
);
connection
->
header
->
length16
=
htons
(
sizeof
(
usbmux_tcp_header
)
+
datalen
);
// Put scnt and ocnt into big-endian notation
// Put scnt and ocnt into big-endian notation
connection
->
scnt
=
htonl
(
connection
->
scnt
);
connection
->
header
->
scnt
=
htonl
(
connection
->
header
->
scnt
);
connection
->
ocnt
=
htonl
(
connection
->
ocnt
);
connection
->
header
->
ocnt
=
htonl
(
connection
->
header
->
ocnt
);
// Concatenation of stuff in the buffer.
// Concatenation of stuff in the buffer.
memcpy
(
buffer
,
connection
,
sizeof
(
*
connection
));
memcpy
(
buffer
,
connection
->
header
,
sizeof
(
usbmux_tcp_header
));
memcpy
(
buffer
+
sizeof
(
*
connection
)
/*+sizeof(datalen)*/
,
data
,
datalen
);
memcpy
(
buffer
+
sizeof
(
usbmux_tcp_header
)
,
data
,
datalen
);
// We have a buffer full of data, we should now send it to the phone.
// We have a buffer full of data, we should now send it to the phone.
if
(
debug
)
printf
(
"actually sending %i bytes of data at %x
\n
"
,
sizeof
(
*
connection
)
+
datalen
,
buffer
);
if
(
debug
)
printf
(
"actually sending %i bytes of data at %x
\n
"
,
sizeof
(
usbmux_tcp_header
)
+
datalen
,
buffer
);
bytes
=
send_to_phone
(
phone
,
buffer
,
sizeof
(
*
connection
)
+
datalen
);
bytes
=
send_to_phone
(
connection
->
phone
,
buffer
,
sizeof
(
usbmux_tcp_header
)
+
datalen
);
if
(
debug
)
printf
(
"mux_send: sent %i bytes!
\n
"
,
bytes
);
// Now that we've sent it off, we can clean up after our sloppy selves.
// Now that we've sent it off, we can clean up after our sloppy selves.
free
(
buffer
);
if
(
debug
)
{
FILE
*
packet
=
fopen
(
"packet"
,
"a+"
);
fwrite
(
buffer
,
1
,
bytes
,
packet
);
fclose
(
packet
);
printf
(
"
\n
"
);
}
if
(
buffer
)
free
(
buffer
);
// Re-calculate scnt and ocnt
// Re-calculate scnt and ocnt
connection
->
scnt
=
ntohl
(
connection
->
scnt
)
+
datalen
;
connection
->
header
->
scnt
=
ntohl
(
connection
->
header
->
scnt
)
+
datalen
;
connection
->
ocnt
=
ntohl
(
connection
->
ocnt
);
connection
->
header
->
ocnt
=
ntohl
(
connection
->
header
->
ocnt
);
// Revert lengths
// Revert lengths
connection
->
length
=
ntohl
(
connection
->
length
);
connection
->
header
->
length
=
ntohl
(
connection
->
header
->
length
);
connection
->
length16
=
ntohs
(
connection
->
length16
);
connection
->
header
->
length16
=
ntohs
(
connection
->
header
->
length16
);
// Now return the bytes.
// Now return the bytes.
if
(
bytes
<
sizeof
(
*
connection
)
+
datalen
)
{
if
(
bytes
<
sizeof
(
*
connection
)
+
datalen
)
{
...
@@ -186,39 +243,103 @@ int mux_send(iPhone *phone, usbmux_tcp_header *connection, char *data, uint32 da
...
@@ -186,39 +243,103 @@ int mux_send(iPhone *phone, usbmux_tcp_header *connection, char *data, uint32 da
* Returns: how many bytes were read, or -1 if something bad happens.
* Returns: how many bytes were read, or -1 if something bad happens.
*/
*/
int
mux_recv
(
iPhone
*
phone
,
usbmux_tcp_header
*
connection
,
char
*
data
,
uint32
datalen
)
{
int
mux_recv
(
usbmux_connection
*
connection
,
char
*
data
,
uint32
datalen
)
{
char
*
buffer
=
(
char
*
)
malloc
(
sizeof
(
*
connection
)
+
sizeof
(
datalen
)
+
datalen
);
/*
int
bytes
=
0
,
my_datalen
=
0
;
* Order of operation:
* 1.) Check if the connection has a pre-received buffer.
* 2.) If so, fill data with the buffer, as much as needed.
* a.) Return quickly if the buffer has enough
* b.) If the buffer is only part of the datalen, get the rest of datalen (and if we can't, just return)
* 3.) If not, receive directly from the phone.
* a.) Check incoming packet's ports. If proper, follow proper buffering and receiving operation.
* b.) If not, find the connection the ports belong to and fill that connection's buffer, then return mux_recv with the same args to try again.
*/
if
(
debug
)
printf
(
"mux_recv: datalen == %i
\n
"
,
datalen
);
if
(
debug
)
printf
(
"mux_recv: datalen == %i
\n
"
,
datalen
);
bytes
=
recv_from_phone
(
phone
,
buffer
,
sizeof
(
*
connection
)
+
datalen
);
int
bytes
=
0
,
i
=
0
,
complex
=
0
,
offset
=
0
;
if
(
debug
)
printf
(
"mux_recv: bytes == %i
\n
"
,
bytes
);
char
*
buffer
=
NULL
;
if
(
bytes
<
datalen
)
{
usbmux_tcp_header
*
header
=
NULL
;
if
(
connection
->
recv_buffer
)
{
if
(
connection
->
r_len
>=
datalen
)
{
memcpy
(
data
,
connection
->
recv_buffer
,
datalen
);
if
(
connection
->
r_len
==
datalen
)
{
// reset everything
free
(
connection
->
recv_buffer
);
connection
->
r_len
=
0
;
connection
->
recv_buffer
=
NULL
;
}
else
{
buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
(
connection
->
r_len
-
datalen
));
memcpy
(
buffer
,
connection
->
recv_buffer
+
datalen
,
(
connection
->
r_len
-
datalen
));
connection
->
r_len
-=
datalen
;
free
(
connection
->
recv_buffer
);
connection
->
recv_buffer
=
buffer
;
}
// Since we were able to fill the data straight from our buffer, we can just return datalen. See 2a above.
return
datalen
;
}
else
{
memcpy
(
data
,
connection
->
recv_buffer
,
connection
->
r_len
);
free
(
connection
->
recv_buffer
);
// don't need to deal with anymore, but...
offset
=
connection
->
r_len
;
// see #2b, above
connection
->
r_len
=
0
;
}
}
// End of what to do if we have a pre-buffer. See #1 and #2 above.
buffer
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
131072
);
// make sure we get enough ;)
// See #3.
bytes
=
recv_from_phone
(
connection
->
phone
,
buffer
,
131072
);
if
(
bytes
<
28
)
{
if
(
bytes
<
28
)
{
// if they didn't do that annoying thing, something else mighta happened.
if
(
debug
)
printf
(
"mux_recv: bytes too low anyway!
\n
"
);
free
(
buffer
);
free
(
buffer
);
if
(
debug
)
printf
(
"mux_recv: Did not even get the header.
\n
"
);
return
-
1
;
return
-
1
;
}
else
if
(
bytes
==
28
)
{
// no data...
}
free
(
buffer
);
return
0
;
header
=
(
usbmux_tcp_header
*
)
buffer
;
}
else
{
// bytes > 28
if
(
header
->
sport
!=
connection
->
header
->
dport
||
header
->
dport
!=
connection
->
header
->
sport
)
{
my_datalen
=
ntohl
(
buffer
[
4
])
-
28
;
// Ooooops -- we got someone else's packet.
connection
->
ocnt
+=
my_datalen
;
// We gotta stick it in their buffer. (Take that any old way you want ;) )
memcpy
(
data
,
buffer
+
28
,
bytes
-
28
);
for
(
i
=
0
;
i
<
connections
;
i
++
)
{
if
(
connlist
[
i
]
->
header
->
sport
==
header
->
dport
&&
connlist
[
i
]
->
header
->
dport
==
header
->
sport
)
{
// we have a winner.
connlist
[
i
]
->
r_len
+=
bytes
-
28
;
connlist
[
i
]
->
recv_buffer
=
(
char
*
)
realloc
(
connlist
[
i
]
->
recv_buffer
,
sizeof
(
char
)
*
connection
->
r_len
);
// grow their buffer
complex
=
connlist
[
i
]
->
r_len
-
(
bytes
-
28
);
memcpy
(
connlist
[
i
]
->
recv_buffer
+
complex
,
buffer
+
28
,
bytes
-
28
);
// paste into their buffer
connlist
[
i
]
->
header
->
ocnt
+=
bytes
-
28
;
}
}
// If it wasn't ours, it's been handled by this point... or forgotten.
// Free our buffer and continue.
free
(
buffer
);
free
(
buffer
);
if
(
debug
)
printf
(
"mux_recv: bytes received: %i
\n
"
,
bytes
-
28
)
;
buffer
=
NULL
;
return
bytes
-
28
;
return
mux_recv
(
connection
,
data
,
datalen
);
// recurse back in to try again
}
}
}
else
{
// all's good, they didn't do anything bonky.
my_datalen
=
ntohl
(
buffer
[
4
])
-
28
;
// The packet was absolutely meant for us if it hits this point.
connection
->
ocnt
+=
my_datalen
;
// The pre-buffer has been taken care of, so, again, if we're at this point we have to read from the phone.
if
(
bytes
==
(
datalen
+
28
))
memcpy
(
data
,
buffer
+
28
,
datalen
);
else
if
(
bytes
==
datalen
)
memcpy
(
data
,
buffer
+
28
,
datalen
-
28
);
if
((
bytes
-
28
)
>
datalen
)
{
// Copy what we need into the data, buffer the rest because we can.
memcpy
(
data
+
offset
,
buffer
+
28
,
datalen
);
// data+offset: see #2b, above
complex
=
connection
->
r_len
+
(
bytes
-
28
)
-
datalen
;
connection
->
recv_buffer
=
(
char
*
)
realloc
(
connection
->
recv_buffer
,
(
sizeof
(
char
)
*
complex
));
connection
->
r_len
=
complex
;
complex
=
connection
->
r_len
-
(
bytes
-
28
)
-
datalen
;
memcpy
(
connection
->
recv_buffer
+
complex
,
buffer
+
28
+
datalen
,
(
bytes
-
28
)
-
datalen
);
free
(
buffer
);
connection
->
header
->
ocnt
+=
bytes
-
28
;
return
datalen
;
}
else
{
// Fill the data with what we have, and just return.
memcpy
(
data
+
offset
,
buffer
+
28
,
bytes
-
28
);
// data+offset: see #2b, above
connection
->
header
->
ocnt
+=
bytes
-
28
;
free
(
buffer
);
free
(
buffer
);
if
(
debug
)
printf
(
"mux_recv: bytes received: %i
\n
"
,
bytes
-
28
);
return
(
bytes
-
28
);
return
bytes
-
28
;
}
}
return
bytes
;
// If we get to this point, 'tis probably bad.
if
(
debug
)
printf
(
"mux_recv: Heisenbug: bytes and datalen not matching up
\n
"
);
return
-
1
;
}
}
src/usbmux.h
View file @
62bcedce
...
@@ -43,6 +43,13 @@ typedef struct {
...
@@ -43,6 +43,13 @@ typedef struct {
uint16
window
,
nullnull
,
length16
;
uint16
window
,
nullnull
,
length16
;
}
usbmux_tcp_header
;
}
usbmux_tcp_header
;
typedef
struct
{
usbmux_tcp_header
*
header
;
iPhone
*
phone
;
char
*
recv_buffer
;
int
r_len
;
}
usbmux_connection
;
usbmux_tcp_header
*
new_mux_packet
(
uint16
s_port
,
uint16
d_port
);
usbmux_tcp_header
*
new_mux_packet
(
uint16
s_port
,
uint16
d_port
);
typedef
struct
{
typedef
struct
{
...
@@ -51,8 +58,10 @@ typedef struct {
...
@@ -51,8 +58,10 @@ typedef struct {
usbmux_version_header
*
version_header
();
usbmux_version_header
*
version_header
();
usbmux_tcp_header
*
mux_connect
(
iPhone
*
phone
,
uint16
s_port
,
uint16
d_port
);
usbmux_connection
*
mux_connect
(
iPhone
*
phone
,
uint16
s_port
,
uint16
d_port
);
void
mux_close_connection
(
iPhone
*
phone
,
usbmux_tcp_header
*
connection
);
void
mux_close_connection
(
usbmux_connection
*
connection
);
int
mux_send
(
iPhone
*
phone
,
usbmux_tcp_header
*
connection
,
char
*
data
,
uint32
datalen
);
int
mux_send
(
usbmux_connection
*
connection
,
const
char
*
data
,
uint32
datalen
);
int
mux_recv
(
iPhone
*
phone
,
usbmux_tcp_header
*
connection
,
char
*
data
,
uint32
datalen
);
int
mux_recv
(
usbmux_connection
*
connection
,
char
*
data
,
uint32
datalen
);
#endif
#endif
src/userpref.c
View file @
62bcedce
...
@@ -20,6 +20,8 @@
...
@@ -20,6 +20,8 @@
*/
*/
#include <glib.h>
#include <glib.h>
#include <stdio.h>
#include <string.h>
#include "userpref.h"
#include "userpref.h"
#define LIBIPHONE_CONF_DIR "libiphone"
#define LIBIPHONE_CONF_DIR "libiphone"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment