Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Crashlogsupport #9

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions afc/afc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package afc

// #cgo pkg-config: libimobiledevice-1.0
// #include <stdlib.h>
// #include <libimobiledevice/afc.h>
// int afc_length(char **arr)
// {
// int length = 0;
// int k = 0;
// for (k = 0; arr[k] != NULL; k++) {
// length = length + 1;
// }
// return length;
// }
import "C"
import (
"unsafe"

"github.com/nowsecure/goidevice/idevice"
"github.com/nowsecure/goidevice/lockdown"
)

type AFC struct {
a C.afc_client_t
}

func NewClient(device idevice.Device, svc *lockdown.Service) (*AFC, error) {
var a C.afc_client_t
err := resultToError(
C.afc_client_new(
(C.idevice_t)(idevice.GetPointer(device)),
(C.lockdownd_service_descriptor_t)(svc.GetDescriptor()),
&a,
),
)
return &AFC{a}, err
}

func (a *AFC) WalkDirectory(path string) ([]SourceFile, error) {
dir, err := a.ReadDirectory(path)
if err != nil {
return []SourceFile{}, err
}

files := []SourceFile{}
for _, f := range dir {
if f.format == "S_IFDIR" {
childDir, err := a.WalkDirectory(f.Name)
if err != nil {
return []SourceFile{}, err
}
files = append(files, childDir...)
continue
}
files = append(files, f)
}
return files, nil
}

type SourceFile struct {
Name string

format string
}

func (a *AFC) ReadDirectory(path string) ([]SourceFile, error) {
var directoryC **C.char
defer C.afc_dictionary_free(directoryC)

sourceFiles := []SourceFile{}
pathC := C.CString(path)
defer C.free(unsafe.Pointer(pathC))

err := resultToError(C.afc_read_directory(a.a, pathC, &directoryC))
if err != nil {
return []SourceFile{}, err
}

directory := unsafe.Slice(directoryC, C.afc_length(directoryC))
for i := range directory {
file := SourceFile{
Name: C.GoString(directory[i]),
}
if file.Name == ".." || file.Name == "." {
continue
}

var fileInfoC **C.char
C.afc_get_file_info(a.a, directory[i], &fileInfoC)
if fileInfoC != nil {
fileInfo := unsafe.Slice(fileInfoC, C.afc_length(fileInfoC))

for j := 0; j < len(fileInfo); j += 2 {
if C.GoString(fileInfo[j]) == "st_ifmt" {
file.format = C.GoString(fileInfo[j+1])
}
}
}
C.afc_dictionary_free(fileInfoC)
sourceFiles = append(sourceFiles, file)
}
return sourceFiles, nil
}
20 changes: 20 additions & 0 deletions afc/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package afc

// #cgo pkg-config: libimobiledevice-1.0
// #include <stdlib.h>
// #include <libimobiledevice/afc.h>
import "C"
import (
"errors"
"fmt"
)

func resultToError(result C.afc_error_t) error {
switch result {
case 0:
return nil
default:
fmt.Println(result)
return errors.New("unknown")
}
}
2 changes: 1 addition & 1 deletion installation/installation.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ package installation
//
// void instproxy_client_options_add_pair(plist_t client_opts, char * key, char * value)
// {
// instproxy_client_options_add(client_opts, key, value, NULL);
// instproxy_client_options_add(client_opts, key, value, NULL);
// }
import "C"
import (
Expand Down
22 changes: 22 additions & 0 deletions lockdown/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package lockdown

// #cgo pkg-config: libimobiledevice-1.0
// #include <libimobiledevice/lockdown.h>
// #include <libimobiledevice/service.h>
import "C"
import (
"errors"
Expand Down Expand Up @@ -174,3 +175,24 @@ func resultToError(result C.lockdownd_error_t) error {
return ErrUnknown
}
}

func serviceResultToError(result C.service_error_t) error {
switch result {
case 0:
return nil
case -1:
return errors.New("invalid args")
case -3:
return errors.New("mux error")
case -4:
return errors.New("ssl error")
case -5:
return errors.New("start service error")
case -6:
return errors.New("not enough data error")
case -7:
return errors.New("timeout")
default:
return errors.New("unknown")
}
}
91 changes: 85 additions & 6 deletions lockdown/lockdown.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ package lockdown

// #cgo pkg-config: libimobiledevice-1.0
// #include <stdlib.h>
// #include <libimobiledevice/libimobiledevice.h>
// #include <libimobiledevice/lockdown.h>
// #include <libimobiledevice/service.h>
import "C"
import (
"errors"
"unsafe"

"github.com/nowsecure/goidevice/idevice"
Expand All @@ -18,7 +21,10 @@ type Client interface {
ValidatePair() error
DeviceName() (string, error)
PList(domain string) (*plist.PList, error)
Close() error
Free() error
GetClient() unsafe.Pointer
StartService(d idevice.Device, serviceName string) (*Service, error)
StartServiceClient(d idevice.Device, serviceName string) (*Service, error)
}

type client struct {
Expand Down Expand Up @@ -95,10 +101,83 @@ func (s *client) PList(domain string) (*plist.PList, error) {
return list, nil
}

func (s *client) Close() error {
err := resultToError(C.lockdownd_client_free(s.p))
if err == nil {
s.p = nil
func (s *client) Free() error {
return resultToError(C.lockdownd_client_free(s.p))
}

func (s *client) GetClient() unsafe.Pointer {
return unsafe.Pointer(s.p)
}

// GetDescriptor gets the lockdown descriptor for the service
func (s *Service) GetDescriptor() unsafe.Pointer {
return unsafe.Pointer(s.descriptor)
}

func (s *Service) FreeDescriptor() {
C.lockdownd_service_descriptor_free(s.descriptor)
}

func (s *Service) Free() {
C.lockdownd_service_descriptor_free(s.descriptor)
C.service_client_free(s.s)
}

func (s *client) StartService(d idevice.Device, serviceName string) (*Service, error) {
var p C.lockdownd_service_descriptor_t
svc := C.CString(serviceName)
defer C.free(unsafe.Pointer(svc))
err := resultToError(C.lockdownd_start_service(s.p, svc, &p))
if err != nil {
return nil, err
}

return &Service{descriptor: p}, nil
}

type Service struct {
s C.service_client_t
descriptor C.lockdownd_service_descriptor_t
}

const (
CRASH_REPORT_MOVER_SERVICE = "com.apple.crashreportmover"
CRASH_REPORT_COPY_MOBILE_SERVICE = "com.apple.crashreportcopymobile"
)

func (s *client) StartServiceClient(d idevice.Device, serviceName string) (*Service, error) {
svc, err := s.StartService(d, serviceName)
if err != nil {
return nil, err
}

err = serviceResultToError(
C.service_client_new((C.idevice_t)(idevice.GetPointer(d)),
svc.descriptor,
&svc.s,
),
)
return svc, err
}

func (s *Service) ReadPing() error {
var msg [4]int8
var n C.uint32_t

var attempts = 0
for {
res := C.service_receive_with_timeout(s.s, (*C.char)(&msg[0]), 4, &n, 2000)
switch res {
case 0:
return nil
case -7:
attempts++
if attempts == 10 {
return errors.New("failed 10 attempts to ping")
}
continue
default:
return errors.New(":(((")
}
}
return err
}
47 changes: 47 additions & 0 deletions thing/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package main

import (
"fmt"
"log"

"github.com/nowsecure/goidevice/afc"
"github.com/nowsecure/goidevice/idevice"
"github.com/nowsecure/goidevice/lockdown"
)

func main() {
device, err := idevice.New("bd133240a37062e545bbbbf664f0011c9f45895d")
if err != nil {
log.Fatal(err)
}
lock, err := lockdown.NewClientWithHandshake(device, "thingy")
if err != nil {
log.Fatal(err)
}
client, err := lock.StartServiceClient(device, lockdown.CRASH_REPORT_MOVER_SERVICE)
if err != nil {
log.Fatal(err)
}
defer client.Free()
err = client.ReadPing()
if err != nil {
log.Fatal(err)
}

service, err := lock.StartService(device, lockdown.CRASH_REPORT_COPY_MOBILE_SERVICE)
if err != nil {
log.Fatal(err)
}
defer service.Free()

afc, err := afc.NewClient(device, service)
if err != nil {
log.Fatal(err)
}
k, _ := afc.WalkDirectory(".")
for _, v := range k {
fmt.Println(v)
}

log.Println("yay we did it")
}
7 changes: 7 additions & 0 deletions thing/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package main

import "testing"

func Test_ke(t *testing.T) {
main()
}