mirror of
https://github.com/palera1n/palera1n.git
synced 2026-10-23 18:49:48 +02:00
feat(usb): pongoOS booting
This commit is contained in:
6 files changed
+249
-94
No files matched your search
+50
-25
@@ -9,19 +9,27 @@
|
||||
|
||||
#include "../utils.h"
|
||||
#include "../usb/shim.h"
|
||||
#include "../pongo/pongo_helper.h"
|
||||
#include "../usb/pongo_helper.h"
|
||||
|
||||
#include "checkm8.h"
|
||||
#include "dfu.h"
|
||||
#include "payload.h"
|
||||
|
||||
#include "../gen/payloads/checkra1n-kpf-pongo.h"
|
||||
#include "../gen/payloads/ramdisk.h"
|
||||
#include "../gen/payloads/binpack.h"
|
||||
|
||||
typedef struct {
|
||||
atomic_bool stop;
|
||||
atomic_int result;
|
||||
atomic_bool stop;
|
||||
|
||||
atomic_bool exploit_done;
|
||||
atomic_bool pongo_done;
|
||||
} shared_t;
|
||||
|
||||
static void *exploit_thread(void *arg)
|
||||
{
|
||||
LOG("Waiting for DFU devices...");
|
||||
shared_t *s = (shared_t *)arg;
|
||||
|
||||
usb_handle_t handle;
|
||||
@@ -45,14 +53,14 @@ static void *exploit_thread(void *arg)
|
||||
char *sn = get_usb_serial_number(&handle);
|
||||
if (!sn) goto fail;
|
||||
|
||||
if (!checkm8_find_device_configuration_for_cpid(
|
||||
dfu_serial_number_get_cpid(sn), &deviceConfig)) {
|
||||
uint64_t cpid = dfu_serial_number_get_cpid(sn);
|
||||
|
||||
if (!checkm8_find_device_configuration_for_cpid(cpid, &deviceConfig)) {
|
||||
free(sn);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!checkm8_find_payload_configuration_for_cpid(
|
||||
dfu_serial_number_get_cpid(sn), &payloadConfig)) {
|
||||
if (!checkm8_find_payload_configuration_for_cpid(cpid, &payloadConfig)) {
|
||||
free(sn);
|
||||
goto fail;
|
||||
}
|
||||
@@ -66,10 +74,12 @@ static void *exploit_thread(void *arg)
|
||||
stage = STAGE_RESET;
|
||||
break;
|
||||
}
|
||||
|
||||
case STAGE_RESET:
|
||||
ret = checkm8_stage_reset(&handle);
|
||||
stage = ret ? STAGE_SETUP : STAGE_RESET;
|
||||
break;
|
||||
|
||||
case STAGE_SETUP:
|
||||
LOG("Setting up the device for exploitation");
|
||||
ret = checkm8_stage_setup(&handle, &deviceConfig);
|
||||
@@ -81,19 +91,23 @@ static void *exploit_thread(void *arg)
|
||||
stage = ret ? STAGE_PATCH : STAGE_RESET;
|
||||
break;
|
||||
case STAGE_PATCH:
|
||||
LOG("Right before trigger (this is the real bug setup)");
|
||||
LOG("Right before trigger (bug setup)");
|
||||
ret = checkm8_stage_patch(&handle, &deviceConfig, &payloadConfig);
|
||||
if (!ret) goto fail;
|
||||
stage = STAGE_PONGO;
|
||||
break;
|
||||
case STAGE_PONGO:
|
||||
LOG("Booting pongoOS");
|
||||
|
||||
close_usb_handle(&handle);
|
||||
sleep_ms(3000);
|
||||
|
||||
checkm8_boot_pongo(&handle);
|
||||
stage = STAGE_DONE;
|
||||
|
||||
atomic_store(&s->result, 1);
|
||||
atomic_store(&s->stop, true);
|
||||
atomic_store(&s->exploit_done, true);
|
||||
|
||||
stage = STAGE_DONE;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
@@ -101,18 +115,19 @@ static void *exploit_thread(void *arg)
|
||||
|
||||
reset_usb_handle(&handle);
|
||||
continue;
|
||||
|
||||
fail:
|
||||
atomic_store(&s->result, -1);
|
||||
atomic_store(&s->stop, true);
|
||||
break;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
fail:
|
||||
atomic_store(&s->result, -1);
|
||||
atomic_store(&s->stop, true);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void *pongo_thread(void *arg)
|
||||
{
|
||||
LOG("Waiting for Pongo devices...");
|
||||
shared_t *s = (shared_t *)arg;
|
||||
|
||||
usb_handle_t handle;
|
||||
@@ -129,31 +144,39 @@ static void *pongo_thread(void *arg)
|
||||
|
||||
if (!seen) {
|
||||
LOG("Pongo device detected!");
|
||||
seen = true;
|
||||
|
||||
char paleinfo[64];
|
||||
snprintf(paleinfo, sizeof(paleinfo), "palera1n_flags 0x%" PRIx64, palerain_flags);
|
||||
|
||||
issue_pongo_command(&handle, "fuse lock", NULL);
|
||||
issue_pongo_command(&handle, "sep auto", NULL);
|
||||
// issue_pongo_command(&handle, paleinfo, NULL);
|
||||
// issue_pongo_command(&handle, "bootx", NULL);
|
||||
issue_pongo_command(&handle, "fuse lock");
|
||||
issue_pongo_command(&handle, "sep auto");
|
||||
upload_buffer_to_pongo(&handle, payloads_checkra1n_kpf_pongo, payloads_checkra1n_kpf_pongo_len);
|
||||
issue_pongo_command(&handle, "modload");
|
||||
issue_pongo_command(&handle, paleinfo);
|
||||
upload_buffer_to_pongo(&handle, payloads_ramdisk_dmg, payloads_ramdisk_dmg_len);
|
||||
issue_pongo_command(&handle, "ramdisk");
|
||||
upload_buffer_to_pongo(&handle, payloads_binpack_dmg, payloads_binpack_dmg_len);
|
||||
issue_pongo_command(&handle, "overlay");
|
||||
issue_pongo_command(&handle, "bootx");
|
||||
|
||||
atomic_store(&s->result, 1);
|
||||
atomic_store(&s->stop, true);
|
||||
break;
|
||||
}
|
||||
|
||||
reset_usb_handle(&handle);
|
||||
}
|
||||
|
||||
close_usb_handle(&handle);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool exploit(void) {
|
||||
bool exploit(void)
|
||||
{
|
||||
pthread_t t1, t2;
|
||||
|
||||
shared_t state;
|
||||
shared_t state = {0};
|
||||
atomic_init(&state.result, 0);
|
||||
atomic_init(&state.stop, false);
|
||||
atomic_init(&state.exploit_done, false);
|
||||
atomic_init(&state.pongo_done, false);
|
||||
|
||||
pthread_create(&t1, NULL, exploit_thread, &state);
|
||||
pthread_create(&t2, NULL, pongo_thread, &state);
|
||||
@@ -161,5 +184,7 @@ bool exploit(void) {
|
||||
pthread_join(t1, NULL);
|
||||
pthread_join(t2, NULL);
|
||||
|
||||
return atomic_load(&state.result) == 1;
|
||||
return atomic_load(&state.result) == 1 &&
|
||||
atomic_load(&state.exploit_done) &&
|
||||
atomic_load(&state.pongo_done);
|
||||
}
|
||||
+124
-12
@@ -22,22 +22,83 @@ static void cf_dictionary_set_int16(CFMutableDictionaryRef dict, const void *key
|
||||
|
||||
bool query_usb_interface(io_service_t serv, CFUUIDRef plugin_type, CFUUIDRef interface_type, LPVOID *interface) {
|
||||
IOCFPlugInInterface **plugin_interface;
|
||||
bool ret = false;
|
||||
SInt32 score;
|
||||
bool ret = false;
|
||||
|
||||
if(IOCreatePlugInInterfaceForService(serv, plugin_type, kIOCFPlugInInterfaceID, &plugin_interface, &score) == kIOReturnSuccess) {
|
||||
ret = (*plugin_interface)->QueryInterface(plugin_interface, CFUUIDGetUUIDBytes(interface_type), interface) == kIOReturnSuccess;
|
||||
IODestroyPlugInInterface(plugin_interface);
|
||||
}
|
||||
|
||||
IOObjectRelease(serv);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool open_usb_interface(usb_handle_t *handle) {
|
||||
IOUSBFindInterfaceRequest req;
|
||||
io_iterator_t iter;
|
||||
io_service_t intfServ;
|
||||
IOReturn kr;
|
||||
|
||||
req.bInterfaceClass = kIOUSBFindInterfaceDontCare;
|
||||
req.bInterfaceSubClass = kIOUSBFindInterfaceDontCare;
|
||||
req.bInterfaceProtocol = kIOUSBFindInterfaceDontCare;
|
||||
req.bAlternateSetting = kIOUSBFindInterfaceDontCare;
|
||||
|
||||
kr = (*handle->device)->CreateInterfaceIterator(handle->device, &req, &iter);
|
||||
if(kr != kIOReturnSuccess) return false;
|
||||
|
||||
while((intfServ = IOIteratorNext(iter)) != IO_OBJECT_NULL) {
|
||||
IOCFPlugInInterface **plugin = NULL;
|
||||
IOUSBInterfaceInterface245 **intf = NULL;
|
||||
SInt32 score = 0;
|
||||
HRESULT res;
|
||||
|
||||
kr = IOCreatePlugInInterfaceForService(intfServ, kIOUSBInterfaceUserClientTypeID, kIOCFPlugInInterfaceID, &plugin, &score);
|
||||
|
||||
IOObjectRelease(intfServ);
|
||||
|
||||
if(kr != kIOReturnSuccess || !plugin) continue;
|
||||
|
||||
res = (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBInterfaceInterfaceID245), (LPVOID *)&intf);
|
||||
|
||||
(*plugin)->Release(plugin);
|
||||
|
||||
if(res != S_OK || !intf) continue;
|
||||
|
||||
kr = (*intf)->USBInterfaceOpen(intf);
|
||||
if(kr != kIOReturnSuccess) {
|
||||
(*intf)->Release(intf);
|
||||
continue;
|
||||
}
|
||||
|
||||
handle->interface = intf;
|
||||
IOObjectRelease(iter);
|
||||
return true;
|
||||
}
|
||||
|
||||
IOObjectRelease(iter);
|
||||
return false;
|
||||
}
|
||||
|
||||
void close_usb_device(usb_handle_t *handle) {
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), handle->async_event_source, kCFRunLoopDefaultMode);
|
||||
CFRelease(handle->async_event_source);
|
||||
(*handle->device)->USBDeviceClose(handle->device);
|
||||
(*handle->device)->Release(handle->device);
|
||||
if(handle->async_event_source) {
|
||||
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), handle->async_event_source, kCFRunLoopDefaultMode);
|
||||
CFRelease(handle->async_event_source);
|
||||
handle->async_event_source = NULL;
|
||||
}
|
||||
|
||||
if(handle->interface) {
|
||||
(*handle->interface)->USBInterfaceClose(handle->interface);
|
||||
(*handle->interface)->Release(handle->interface);
|
||||
handle->interface = NULL;
|
||||
}
|
||||
|
||||
if(handle->device) {
|
||||
(*handle->device)->USBDeviceClose(handle->device);
|
||||
(*handle->device)->Release(handle->device);
|
||||
handle->device = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void close_usb_handle(usb_handle_t *handle) {
|
||||
@@ -51,15 +112,23 @@ bool open_usb_device(io_service_t serv, usb_handle_t *handle) {
|
||||
if((*handle->device)->USBDeviceOpen(handle->device) == kIOReturnSuccess) {
|
||||
if((*handle->device)->SetConfiguration(handle->device, 1) == kIOReturnSuccess && (*handle->device)->CreateDeviceAsyncEventSource(handle->device, &handle->async_event_source) == kIOReturnSuccess) {
|
||||
CFRunLoopAddSource(CFRunLoopGetCurrent(), handle->async_event_source, kCFRunLoopDefaultMode);
|
||||
ret = true;
|
||||
|
||||
if(open_usb_interface(handle)) {
|
||||
ret = true;
|
||||
} else {
|
||||
(*handle->device)->USBDeviceClose(handle->device);
|
||||
}
|
||||
} else {
|
||||
(*handle->device)->USBDeviceClose(handle->device);
|
||||
}
|
||||
}
|
||||
|
||||
if(!ret) {
|
||||
(*handle->device)->Release(handle->device);
|
||||
handle->device = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -72,6 +141,7 @@ bool wait_usb_handle(usb_handle_t *handle) {
|
||||
while((matching_dict = IOServiceMatching(kUSBDeviceClassName)) != NULL) {
|
||||
cf_dictionary_set_int16(matching_dict, CFSTR(kUSBVendorID), handle->vid);
|
||||
cf_dictionary_set_int16(matching_dict, CFSTR(kUSBProductID), handle->pid);
|
||||
|
||||
if(IOServiceGetMatchingServices(0, matching_dict, &iter) == kIOReturnSuccess) {
|
||||
while((serv = IOIteratorNext(iter)) != IO_OBJECT_NULL) {
|
||||
if(open_usb_device(serv, handle)) {
|
||||
@@ -79,19 +149,23 @@ bool wait_usb_handle(usb_handle_t *handle) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
IOObjectRelease(iter);
|
||||
if(ret) {
|
||||
break;
|
||||
}
|
||||
|
||||
if(ret) break;
|
||||
|
||||
sleep_ms(USB_TIMEOUT);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void reset_usb_handle(usb_handle_t *handle) {
|
||||
(*handle->device)->ResetDevice(handle->device);
|
||||
(*handle->device)->USBDeviceReEnumerate(handle->device, 0);
|
||||
if(handle->device) {
|
||||
(*handle->device)->ResetDevice(handle->device);
|
||||
(*handle->device)->USBDeviceReEnumerate(handle->device, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void usb_async_cb(void *refcon, IOReturn ret, void *arg) {
|
||||
@@ -99,6 +173,7 @@ static void usb_async_cb(void *refcon, IOReturn ret, void *arg) {
|
||||
|
||||
if(transfer_ret != NULL) {
|
||||
memcpy(&transfer_ret->sz, &arg, sizeof(transfer_ret->sz));
|
||||
|
||||
if(ret == kIOReturnSuccess) {
|
||||
transfer_ret->ret = USB_TRANSFER_OK;
|
||||
} else if(ret == kUSBPipeStalled) {
|
||||
@@ -107,6 +182,7 @@ static void usb_async_cb(void *refcon, IOReturn ret, void *arg) {
|
||||
transfer_ret->ret = USB_TRANSFER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||
}
|
||||
|
||||
@@ -122,7 +198,9 @@ bool send_usb_control_request(const usb_handle_t *handle, uint8_t bm_request_typ
|
||||
req.wValue = OSSwapLittleToHostInt16(w_value);
|
||||
req.wIndex = OSSwapLittleToHostInt16(w_index);
|
||||
req.completionTimeout = req.noDataTimeout = USB_TIMEOUT;
|
||||
|
||||
ret = (*handle->device)->DeviceRequestTO(handle->device, &req);
|
||||
|
||||
if(transfer_ret != NULL) {
|
||||
if(ret == kIOReturnSuccess) {
|
||||
transfer_ret->sz = req.wLenDone;
|
||||
@@ -133,6 +211,7 @@ bool send_usb_control_request(const usb_handle_t *handle, uint8_t bm_request_typ
|
||||
transfer_ret->ret = USB_TRANSFER_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -150,6 +229,7 @@ bool send_usb_control_request_async(const usb_handle_t *handle, uint8_t bm_reque
|
||||
|
||||
if((*handle->device)->DeviceRequestAsyncTO(handle->device, &req, usb_async_cb, transfer_ret) == kIOReturnSuccess) {
|
||||
sleep_ms(usb_abort_timeout);
|
||||
|
||||
if((*handle->device)->USBDeviceAbortPipeZero(handle->device) == kIOReturnSuccess) {
|
||||
CFRunLoopRun();
|
||||
return true;
|
||||
@@ -159,10 +239,42 @@ bool send_usb_control_request_async(const usb_handle_t *handle, uint8_t bm_reque
|
||||
return false;
|
||||
}
|
||||
|
||||
bool send_interface_control_request(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, transfer_ret_t *transfer_ret) {
|
||||
if(!handle || !handle->interface) return false;
|
||||
|
||||
IOUSBDevRequest req = {
|
||||
.bmRequestType = bm_request_type,
|
||||
.bRequest = b_request,
|
||||
.wValue = w_value,
|
||||
.wIndex = w_index,
|
||||
.wLength = (UInt16)w_len,
|
||||
.pData = p_data,
|
||||
};
|
||||
|
||||
IOReturn ret = (*handle->interface)->ControlRequest(handle->interface, 0, &req);
|
||||
|
||||
if(transfer_ret) {
|
||||
transfer_ret->ret = (ret == kIOReturnSuccess)
|
||||
? USB_TRANSFER_OK
|
||||
: USB_TRANSFER_ERROR;
|
||||
transfer_ret->sz = req.wLenDone;
|
||||
}
|
||||
|
||||
return ret == kIOReturnSuccess;
|
||||
}
|
||||
|
||||
bool send_interface_bulk_transfer(const usb_handle_t *handle, void *data, uint32_t len) {
|
||||
if(!handle || !handle->interface) return false;
|
||||
IOReturn ret = (*handle->interface)->WritePipe(handle->interface, 2, data, len);
|
||||
return ret == kIOReturnSuccess;
|
||||
}
|
||||
|
||||
void init_usb_handle(usb_handle_t *handle, uint16_t vid, uint16_t pid) {
|
||||
handle->vid = vid;
|
||||
handle->pid = pid;
|
||||
handle->device = NULL;
|
||||
handle->interface = NULL;
|
||||
handle->async_event_source = NULL;
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
#endif
|
||||
@@ -41,6 +41,7 @@ typedef struct {
|
||||
uint16_t vid, pid;
|
||||
io_service_t serv;
|
||||
IOUSBDeviceInterface320 **device;
|
||||
IOUSBInterfaceInterface245 **interface;
|
||||
CFRunLoopSourceRef async_event_source;
|
||||
} usb_handle_t;
|
||||
|
||||
@@ -52,6 +53,8 @@ bool wait_usb_handle(usb_handle_t *handle);
|
||||
void reset_usb_handle(usb_handle_t *handle);
|
||||
bool send_usb_control_request(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, transfer_ret_t *transfer_ret);
|
||||
bool send_usb_control_request_async(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, unsigned usb_abort_timeout, transfer_ret_t *transfer_ret);
|
||||
bool send_interface_control_request(const usb_handle_t *handle, uint8_t bm_request_type, uint8_t b_request, uint16_t w_value, uint16_t w_index, void *p_data, size_t w_len, transfer_ret_t *transfer_ret);
|
||||
bool send_interface_bulk_transfer(const usb_handle_t *handle, void *data, uint32_t len);
|
||||
void init_usb_handle(usb_handle_t *handle, uint16_t vid, uint16_t pid);
|
||||
|
||||
#endif // IOKIT_BACKEND_H
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include <lz4.h>
|
||||
#include <lz4hc.h>
|
||||
|
||||
#include "../usb/shim.h"
|
||||
#include "shim.h"
|
||||
|
||||
#include "../utils.h"
|
||||
#include "../m8/dfu.h"
|
||||
@@ -66,62 +66,75 @@ void checkm8_boot_pongo(usb_handle_t *handle) {
|
||||
LOG("pongoOS sent, should be booting");
|
||||
}
|
||||
|
||||
int issue_pongo_command(usb_handle_t *handle, char *command, char *outBuffer) {
|
||||
bool ret;
|
||||
uint8_t inProgress = 1;
|
||||
uint32_t outPosition = 0;
|
||||
uint32_t outLength = 0;
|
||||
transfer_ret_t transferRet;
|
||||
char stdoutBuffer[0x2000];
|
||||
if (command == NULL) goto fetch_output;
|
||||
size_t length = strlen(command);
|
||||
char commandBuffer[0x200];
|
||||
if (length > (CMD_LENGTH_MAX - 2))
|
||||
{
|
||||
LOG("Pongo command %s too long (max %d)", command, CMD_LENGTH_MAX - 2);
|
||||
return -1;
|
||||
}
|
||||
LOG("Executing PongoOS command: '%s'", command);
|
||||
snprintf(commandBuffer, 512, "%s\n", command);
|
||||
length = strlen(commandBuffer);
|
||||
ret = send_usb_control_request_no_data(handle, 0x21, 4, 1, 0, 0, NULL);
|
||||
if (!ret)
|
||||
goto bad;
|
||||
ret = send_usb_control_request(handle, 0x21, 3, 0, 0, commandBuffer, (uint32_t)length, NULL);
|
||||
fetch_output:
|
||||
while (inProgress) {
|
||||
ret = send_usb_control_request(handle, 0xA1, 2, 0, 0, &inProgress, (uint32_t)sizeof(inProgress), NULL);
|
||||
if (ret) {
|
||||
ret = send_usb_control_request(handle, 0xA1, 1, 0, 0, stdoutBuffer + outPosition, 0x1000, &transferRet);
|
||||
outLength = transferRet.sz;
|
||||
if (transferRet.ret == USB_TRANSFER_OK) {
|
||||
outPosition += outLength;
|
||||
if (outPosition > 0x1000) {
|
||||
memmove(stdoutBuffer, stdoutBuffer + outPosition - 0x1000, 0x1000);
|
||||
outPosition = 0x1000;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (transferRet.ret != USB_TRANSFER_OK) {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
bad:
|
||||
if (transferRet.ret != USB_TRANSFER_OK)
|
||||
{
|
||||
if (!strncmp("boot", command, 4)) {
|
||||
return 0;
|
||||
} else if (command != NULL) {
|
||||
LOG("USB transfer error: 0x%x, wLength out 0x%x.", transferRet.ret, transferRet.sz);
|
||||
return transferRet.ret;
|
||||
} else {
|
||||
int issue_pongo_command(const usb_handle_t *handle, const char *command) {
|
||||
uint32_t outpos = 0;
|
||||
uint32_t outlen = 0;
|
||||
transfer_ret_t tx_status;
|
||||
uint8_t in_progress = 1;
|
||||
|
||||
char command_buf[512];
|
||||
char stdout_buf[0x2000];
|
||||
|
||||
memset(stdout_buf, 0, sizeof(stdout_buf));
|
||||
|
||||
if (command != NULL) {
|
||||
size_t len = strlen(command);
|
||||
|
||||
if (len > 510) {
|
||||
LOG("Pongo command too long: %s", command);
|
||||
return -1;
|
||||
}
|
||||
|
||||
LOG("Executing PongoOS command: '%s'", command);
|
||||
|
||||
snprintf(command_buf, sizeof(command_buf), "%s\n", command);
|
||||
len = strlen(command_buf);
|
||||
|
||||
if (!send_interface_control_request(handle, 0x21, 4, 1, 0, NULL, 0, &tx_status)) return -1;
|
||||
if (!send_interface_control_request(handle, 0x21, 3, 0, 0, command_buf, len, &tx_status)) return -1;
|
||||
}
|
||||
else {
|
||||
if (outBuffer) {
|
||||
memcpy(outBuffer, stdoutBuffer, outPosition);
|
||||
fetch_output:
|
||||
while (in_progress) {
|
||||
if (!send_interface_control_request(handle, 0xA1, 2, 0, 0, &in_progress, sizeof(in_progress), &tx_status)) goto bad;
|
||||
|
||||
if (in_progress == 0) break;
|
||||
|
||||
if (outpos + 0x1000 >= sizeof(stdout_buf)) {
|
||||
memmove(stdout_buf, stdout_buf + 0x1000, sizeof(stdout_buf) - 0x1000);
|
||||
outpos -= 0x1000;
|
||||
}
|
||||
return ret;
|
||||
|
||||
if (!send_interface_control_request(handle, 0xA1, 1, 0, 0, stdout_buf + outpos, 0x1000, &tx_status)) goto bad;
|
||||
|
||||
outlen = 0x1000;
|
||||
outpos += outlen;
|
||||
}
|
||||
bad:
|
||||
if (tx_status.ret != USB_TRANSFER_OK) {
|
||||
if (command != NULL && strncmp(command,"boot",4) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOG("Pongo USB error: %d", tx_status.ret);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool upload_buffer_to_pongo(usb_handle_t *handle, const void *data, size_t length) {
|
||||
if (data == NULL || length == 0) {
|
||||
LOG("Invalid data buffer or length.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
LOG("Uploading %zu bytes to PongoOS...\n", length);
|
||||
|
||||
bool ret = false;
|
||||
transfer_ret_t tx_status = {0};
|
||||
|
||||
ret = send_interface_control_request(handle, 0x21, DFU_DNLOAD, 0, 0, (void *)&length, 4, &tx_status);
|
||||
ret = send_interface_bulk_transfer(handle, (void *)data, (uint32_t)length);
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,12 +1,13 @@
|
||||
#ifndef USB_PONGO_H
|
||||
#define USB_PONGO_H
|
||||
|
||||
#include "../usb/shim.h"
|
||||
#include "shim.h"
|
||||
|
||||
#define CMD_LENGTH_MAX 512
|
||||
|
||||
void compress_pongo(void *out, size_t *out_len);
|
||||
void checkm8_boot_pongo(usb_handle_t *handle);
|
||||
int issue_pongo_command(usb_handle_t *handle, char *command, char *outBuffer);
|
||||
int issue_pongo_command(const usb_handle_t *handle, const char *command);
|
||||
bool upload_buffer_to_pongo(usb_handle_t *handle, const void *data, size_t length);
|
||||
|
||||
#endif // USB_PONGO_H
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "DevicePanel.hpp"
|
||||
#include "../state.hpp"
|
||||
#include "../utils.h"
|
||||
#include "../m8/run.h"
|
||||
|
||||
ExploitPanel::ExploitPanel(MainFrame* frame, wxWindow* parent)
|
||||
: DevicePanel(frame, parent)
|
||||
@@ -64,7 +65,7 @@ void ExploitPanel::StartExploit()
|
||||
const auto state = GetDeviceState();
|
||||
if (!state.connected || state.mode != DeviceMode::DFU)
|
||||
return;
|
||||
// TODO: EXPLOOT
|
||||
exploit();
|
||||
}).detach();
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user