Update GC ToolKit name and pic0
This commit is contained in:
parent
325268db57
commit
f5e815ed26
|
@ -52,6 +52,7 @@ Module.symvers
|
|||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
build/*
|
||||
kern/build/*
|
||||
app/build/*
|
||||
pc/build/*
|
|
@ -8,11 +8,11 @@ if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
|
|||
endif()
|
||||
endif()
|
||||
|
||||
project(GCDUMP)
|
||||
project(GCToolKit)
|
||||
include("$ENV{VITASDK}/share/vita.cmake" REQUIRED)
|
||||
|
||||
set(VITA_APP_NAME "GC Toolkit")
|
||||
set(VITA_TITLEID "GCDUMPER0")
|
||||
set(VITA_APP_NAME "GC ToolKit")
|
||||
set(VITA_TITLEID "GCTK10000")
|
||||
|
||||
set(VITA_VERSION "01.00")
|
||||
|
||||
|
|
26
app/crypto.c
26
app/crypto.c
|
@ -17,28 +17,28 @@
|
|||
#include "log.h"
|
||||
|
||||
int key_dump_network(char* ip_address, unsigned short port, char* output_file) {
|
||||
GcKeys keys;
|
||||
GcKEYS keys;
|
||||
|
||||
int got_keys = extract_gc_keys(&keys);
|
||||
if(got_keys < 0) return got_keys;
|
||||
|
||||
SceUID fd = begin_file_send(ip_address, port, output_file, sizeof(GcKeys));
|
||||
SceUID fd = begin_file_send(ip_address, port, output_file, sizeof(GcKEYS));
|
||||
PRINT_STR("fd = %x\n", fd);
|
||||
if(fd < 0) return fd;
|
||||
|
||||
int wr = file_send_data(fd, &keys, sizeof(GcKeys));
|
||||
PRINT_STR("wr = %x (sizeof = %x)\n", wr, sizeof(GcKeys));
|
||||
int wr = file_send_data(fd, &keys, sizeof(GcKEYS));
|
||||
PRINT_STR("wr = %x (sizeof = %x)\n", wr, sizeof(GcKEYS));
|
||||
end_file_send(fd);
|
||||
|
||||
if(wr == 0) return -1;
|
||||
if(wr < 0) return wr;
|
||||
if(wr != sizeof(GcKeys)) return (wr * -1);
|
||||
if(wr != sizeof(GcKEYS)) return (wr * -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int key_dump(char* output_file) {
|
||||
GcKeys keys;
|
||||
GcKEYS keys;
|
||||
|
||||
int got_keys = extract_gc_keys(&keys);
|
||||
if(got_keys < 0) return got_keys;
|
||||
|
@ -47,13 +47,13 @@ int key_dump(char* output_file) {
|
|||
PRINT_STR("fd = %x\n", fd);
|
||||
if(fd < 0) return fd;
|
||||
|
||||
int wr = sceIoWrite(fd, &keys, sizeof(GcKeys));
|
||||
PRINT_STR("wr = %x (sizeof = %x)\n", wr, sizeof(GcKeys));
|
||||
int wr = sceIoWrite(fd, &keys, sizeof(GcKEYS));
|
||||
PRINT_STR("wr = %x (sizeof = %x)\n", wr, sizeof(GcKEYS));
|
||||
sceIoClose(fd);
|
||||
|
||||
if(wr == 0) return -1;
|
||||
if(wr < 0) return wr;
|
||||
if(wr != sizeof(GcKeys)) return (wr * -1);
|
||||
if(wr != sizeof(GcKEYS)) return (wr * -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -100,7 +100,7 @@ void wait_for_gc_auth() {
|
|||
while(!HasCmd20Captured()) { sceKernelDelayThread(1000); };
|
||||
}
|
||||
|
||||
uint8_t verify_klic_keys(GcKeys* keys) {
|
||||
uint8_t verify_klic_keys(GcKEYS* keys) {
|
||||
char got_final_keys[SHA256_BLOCK_SIZE];
|
||||
char expected_final_keys[SHA256_BLOCK_SIZE];
|
||||
int res = GetFinalKeys(got_final_keys);
|
||||
|
@ -110,7 +110,7 @@ uint8_t verify_klic_keys(GcKeys* keys) {
|
|||
SHA256_CTX ctx;
|
||||
|
||||
sha256_init(&ctx);
|
||||
sha256_update(&ctx, keys, sizeof(GcKeys));
|
||||
sha256_update(&ctx, keys, sizeof(GcKEYS));
|
||||
sha256_final(&ctx, expected_final_keys);
|
||||
|
||||
if(memcmp(got_final_keys, expected_final_keys, SHA256_BLOCK_SIZE) == 0) {
|
||||
|
@ -127,7 +127,7 @@ error:
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint8_t verify_rif_keys(GcKeys* keys) {
|
||||
uint8_t verify_rif_keys(GcKEYS* keys) {
|
||||
int ret = 0;
|
||||
char expected_final_rif_hash[SHA1_BLOCK_SIZE];
|
||||
char got_final_rif_hash[SHA1_BLOCK_SIZE];
|
||||
|
@ -195,7 +195,7 @@ error:
|
|||
|
||||
}
|
||||
|
||||
int extract_gc_keys(GcKeys* keys) {
|
||||
int extract_gc_keys(GcKEYS* keys) {
|
||||
if(HasCmd20Captured()) {
|
||||
// get captured cmd56 authentication data
|
||||
CommsData cmdData;
|
||||
|
|
13
app/crypto.h
13
app/crypto.h
|
@ -1,14 +1,5 @@
|
|||
#ifndef CRYPTO_H
|
||||
#define CRYPTO_H 1
|
||||
|
||||
typedef struct GcKeys{
|
||||
uint8_t rifbuf[0x20];
|
||||
uint8_t klic[0x20];
|
||||
} GcKeys;
|
||||
|
||||
#include "mbr.h"
|
||||
int key_dump_network(char* ip_address, unsigned short port, char* output_file);
|
||||
int key_dump(char* output_file);
|
||||
void wait_for_gc_auth();
|
||||
int extract_gc_keys(GcKeys* keys);
|
||||
|
||||
#endif
|
||||
int extract_gc_keys(GcKEYS* keys);
|
||||
|
|
298
app/device.c
298
app/device.c
|
@ -8,18 +8,66 @@
|
|||
#include "log.h"
|
||||
#include "f00dbridge.h"
|
||||
#include "device.h"
|
||||
#include "crypto.h"
|
||||
#include "mbr.h"
|
||||
#include "vci.h"
|
||||
#include "err.h"
|
||||
#include "net.h"
|
||||
|
||||
#define DO_CHECKED(var, func, ...) \
|
||||
int var = func(__VA_ARGS__); \
|
||||
PRINT_STR(#var " = %x\n", var); \
|
||||
if(var < 0) ERROR(var)
|
||||
|
||||
#define DEVICE_ACCESS_LOOP(rd_func, wr_func) \
|
||||
do { \
|
||||
int rd = rd_func(rd_fd, (void*)DEVICE_DUMP_BUFFER, sizeof(DEVICE_DUMP_BUFFER)); \
|
||||
if(rd == 0) ERROR(-2); \
|
||||
if(rd < 0) ERROR(rd); \
|
||||
\
|
||||
int wr = wr_func(wr_fd, (void*)DEVICE_DUMP_BUFFER, rd); \
|
||||
if(wr == 0) ERROR(-3); \
|
||||
if(wr < 0) ERROR(wr); \
|
||||
\
|
||||
total += wr; \
|
||||
if(progress_callback != NULL) progress_callback(block_device, path, total, device_size); \
|
||||
} while(total < device_size)
|
||||
|
||||
#define CREATE_VCI_HDR(wr_func) \
|
||||
if(keys != NULL) { \
|
||||
VciFile vci; \
|
||||
memset(&vci, 0x00, sizeof(VciFile)); \
|
||||
\
|
||||
memcpy(vci.magic, VCI_HDR, sizeof(vci.magic)); \
|
||||
vci.version = 1; \
|
||||
vci.devicesize = device_size; \
|
||||
memcpy(&vci.keys, keys, sizeof(GcKEYS)); \
|
||||
\
|
||||
int wr = wr_func(wr_fd, &vci, sizeof(VciFile)); \
|
||||
PRINT_STR("wr = %x\n", wr); \
|
||||
\
|
||||
if(wr == 0) ERROR(-1); \
|
||||
if(wr != sizeof(VciFile)) ERROR(wr * -1); \
|
||||
if(wr < 0) ERROR(wr); \
|
||||
}
|
||||
|
||||
#define CREATE_DEV_SZ(dev_fd) \
|
||||
uint64_t device_size = 0; \
|
||||
GetDeviceSize(dev_fd, &device_size); \
|
||||
PRINT_STR("device_size = %llx\n", device_size); \
|
||||
if(device_size == 0) ERROR(-1); \
|
||||
if(progress_callback != NULL) progress_callback(block_device, block_device, total, device_size)\
|
||||
|
||||
#define SAFE_CHK() if(memcmp(block_device, "sdstor0:gcd", 11) != 0) ERROR(-128)
|
||||
|
||||
// exfatfs does each 0x20000 reading internally - Princess of Sleeping
|
||||
static uint8_t DEVICE_DUMP_BUFFER[0x20000]__attribute__((aligned(0x40)));
|
||||
|
||||
uint8_t device_exist(char* block_device) {
|
||||
int dfd = OpenDevice(block_device, SCE_O_RDONLY);
|
||||
|
||||
if(dfd < 0)
|
||||
return 0;
|
||||
|
||||
CloseDevice(dfd);
|
||||
return 1;
|
||||
}
|
||||
|
@ -31,240 +79,148 @@ uint64_t device_size(char* block_device) {
|
|||
int dfd = OpenDevice(block_device, SCE_O_RDONLY);
|
||||
if(dfd < 0)
|
||||
return 0;
|
||||
|
||||
GetDeviceSize(dfd, &device_size);
|
||||
CloseDevice(dfd);
|
||||
|
||||
return device_size;
|
||||
|
||||
}
|
||||
int dump_device_network(char* ip_address, unsigned short port, char* block_device, char* output_path, GcKeys* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t)) {
|
||||
|
||||
// device dump/restore
|
||||
|
||||
int read_null(SceUID fd, char* data, int size) {
|
||||
memset(data, 0x00, size);
|
||||
return size;
|
||||
}
|
||||
|
||||
int read_data_from_image(SceUID fd, char* data, int size) {
|
||||
int rd = sceIoRead(fd, data, size);
|
||||
if(rd < 0) return rd;
|
||||
|
||||
// if there is remaining space, memset it to 0
|
||||
if(rd < size) {
|
||||
memset(data+rd, 0x00, size-rd);
|
||||
}
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
int dump_device_network(char* ip_address, unsigned short port, char* block_device, char* path, GcKEYS* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t)) {
|
||||
int ret = 0;
|
||||
uint64_t total_read = 0;
|
||||
uint64_t total = 0;
|
||||
|
||||
PRINT_STR("Begining NETWORK dump of %s to %s:%u\n", block_device, ip_address, port);
|
||||
|
||||
// open gc
|
||||
int device_fd = OpenDevice(block_device, SCE_O_RDONLY);
|
||||
PRINT_STR("device_fd = %x\n", device_fd);
|
||||
if(device_fd < 0) ERROR(device_fd);
|
||||
|
||||
// get gc size
|
||||
uint64_t device_size = 0;
|
||||
GetDeviceSize(device_fd, &device_size);
|
||||
PRINT_STR("device_size = %llx\n", device_size);
|
||||
if(device_size == 0) ERROR(-1);
|
||||
|
||||
if(progress_callback != NULL) progress_callback(block_device, output_path, total_read, device_size);
|
||||
// open device
|
||||
DO_CHECKED(rd_fd, OpenDevice, block_device, SCE_O_RDONLY);
|
||||
|
||||
// get device size
|
||||
CREATE_DEV_SZ(rd_fd);
|
||||
|
||||
// open socket
|
||||
SceUID gc_sock = begin_file_send(ip_address, port, output_path, (keys != NULL) ? device_size + sizeof(VciFile) : device_size);
|
||||
PRINT_STR("gc_sock = %x\n", gc_sock);
|
||||
if(gc_sock < 0) ERROR(gc_sock);
|
||||
|
||||
DO_CHECKED(wr_fd, begin_file_send, ip_address, port, path, (keys != NULL) ? device_size + sizeof(VciFile) : device_size);
|
||||
|
||||
if(keys != NULL) {
|
||||
// generate VCI header
|
||||
VciFile vci;
|
||||
memset(&vci, 0x00, sizeof(VciFile));
|
||||
|
||||
memcpy(vci.magic, VCI_HDR, sizeof(vci.magic));
|
||||
vci.version = 1;
|
||||
vci.devicesize = device_size;
|
||||
memcpy(&vci.keys, keys, sizeof(GcKeys));
|
||||
|
||||
// write VCI header to file
|
||||
int wr = file_send_data(gc_sock, &vci, sizeof(VciFile));
|
||||
PRINT_STR("wr = %x\n", wr);
|
||||
|
||||
if(wr == 0) ERROR(-1);
|
||||
if(wr != sizeof(VciFile)) ERROR(wr * -1);
|
||||
if(wr < 0) ERROR(wr);
|
||||
}
|
||||
// write vci header
|
||||
CREATE_VCI_HDR(file_send_data);
|
||||
|
||||
// enter read/write loop
|
||||
do {
|
||||
int rd = ReadDevice(device_fd, DEVICE_DUMP_BUFFER, sizeof(DEVICE_DUMP_BUFFER)); // read raw from device
|
||||
if(rd == 0) ERROR(-2);
|
||||
if(rd < 0) ERROR(rd);
|
||||
|
||||
int wr = file_send_data(gc_sock, DEVICE_DUMP_BUFFER, rd); // send raw data
|
||||
if(wr == 0) ERROR(-3);
|
||||
if(wr < 0) ERROR(wr);
|
||||
|
||||
total_read += wr;
|
||||
if(progress_callback != NULL) progress_callback(block_device, output_path, total_read, device_size);
|
||||
} while(total_read < device_size);
|
||||
DEVICE_ACCESS_LOOP(ReadDevice, file_send_data);
|
||||
|
||||
error:
|
||||
if(gc_sock >= 0)
|
||||
end_file_send(gc_sock);
|
||||
if(device_fd >= 0)
|
||||
CloseDevice(device_fd);
|
||||
if(wr_fd >= 0)
|
||||
end_file_send(wr_fd);
|
||||
if(rd_fd >= 0)
|
||||
CloseDevice(rd_fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int dump_device(char* block_device, char* output_path, GcKeys* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t)) {
|
||||
int ret = 0;
|
||||
uint64_t total_read = 0;
|
||||
|
||||
PRINT_STR("Begining dump of %s to %s\n", block_device, output_path);
|
||||
int dump_device(char* block_device, char* path, GcKEYS* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t)) {
|
||||
int ret = 0;
|
||||
uint64_t total = 0;
|
||||
|
||||
PRINT_STR("Begining dump of %s to %s\n", block_device, path);
|
||||
|
||||
// open device
|
||||
DO_CHECKED(rd_fd, OpenDevice, block_device, SCE_O_RDONLY);
|
||||
|
||||
// open image file
|
||||
SceUID img_fd = sceIoOpen(output_path, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777);
|
||||
PRINT_STR("img_fd = %x\n", img_fd);
|
||||
if(img_fd < 0) ERROR(img_fd);
|
||||
|
||||
// open device
|
||||
int device_fd = OpenDevice(block_device, SCE_O_RDONLY);
|
||||
PRINT_STR("device_fd = %x\n", device_fd);
|
||||
if(device_fd < 0) ERROR(device_fd);
|
||||
DO_CHECKED(wr_fd, sceIoOpen, path, SCE_O_WRONLY | SCE_O_CREAT | SCE_O_TRUNC, 0777);
|
||||
|
||||
// get device size
|
||||
uint64_t device_size = 0;
|
||||
GetDeviceSize(device_fd, &device_size);
|
||||
PRINT_STR("device_size = %llx\n", device_size);
|
||||
if(device_size == 0) ERROR(-1);
|
||||
|
||||
if(progress_callback != NULL) progress_callback(block_device, output_path, total_read, device_size);
|
||||
CREATE_DEV_SZ(rd_fd);
|
||||
|
||||
if(keys != NULL) {
|
||||
// generate VCI header
|
||||
VciFile vci;
|
||||
memset(&vci, 0x00, sizeof(VciFile));
|
||||
|
||||
memcpy(vci.magic, VCI_HDR, sizeof(vci.magic));
|
||||
vci.version = 1;
|
||||
vci.devicesize = device_size;
|
||||
memcpy(&vci.keys, keys, sizeof(GcKeys));
|
||||
|
||||
// write VCI header to file
|
||||
int wr = sceIoWrite(img_fd, &vci, sizeof(VciFile));
|
||||
PRINT_STR("wr = %x\n", wr);
|
||||
|
||||
if(wr == 0) ERROR(-1);
|
||||
if(wr != sizeof(VciFile)) ERROR(wr * -1);
|
||||
if(wr < 0) ERROR(wr);
|
||||
}
|
||||
// write vci header
|
||||
CREATE_VCI_HDR(sceIoWrite);
|
||||
|
||||
// enter read/write loop
|
||||
do {
|
||||
int rd = ReadDevice(device_fd, DEVICE_DUMP_BUFFER, sizeof(DEVICE_DUMP_BUFFER)); // read raw from device
|
||||
if(rd == 0) ERROR(-2);
|
||||
if(rd < 0) ERROR(rd);
|
||||
|
||||
int wr = sceIoWrite(img_fd, DEVICE_DUMP_BUFFER, rd); // write raw data
|
||||
if(wr == 0) ERROR(-3);
|
||||
if(wr < 0) ERROR(wr);
|
||||
|
||||
total_read += wr;
|
||||
if(progress_callback != NULL) progress_callback(block_device, output_path, total_read, device_size);
|
||||
} while(total_read < device_size);
|
||||
DEVICE_ACCESS_LOOP(ReadDevice, sceIoWrite);
|
||||
|
||||
error:
|
||||
if(img_fd >= 0)
|
||||
sceIoClose(img_fd);
|
||||
if(device_fd >= 0)
|
||||
CloseDevice(device_fd);
|
||||
if(wr_fd >= 0)
|
||||
sceIoClose(wr_fd);
|
||||
if(rd_fd >= 0)
|
||||
CloseDevice(rd_fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int restore_device(char* block_device, char* input_path, void (*progress_callback)(char*, char*, uint64_t, uint64_t)) {
|
||||
int restore_device(char* block_device, char* path, void (*progress_callback)(char*, char*, uint64_t, uint64_t)) {
|
||||
int ret = 0;
|
||||
uint64_t total_write = 0;
|
||||
uint64_t total = 0;
|
||||
|
||||
// sanity safety check
|
||||
if(memcmp(block_device, "sdstor0:gcd", strlen("sdstor0:gcd")) != 0)
|
||||
return -1;
|
||||
|
||||
PRINT_STR("Begining restore of %s to %s\n", input_path, block_device);
|
||||
SAFE_CHK();
|
||||
PRINT_STR("Begining restore of %s to %s\n", path, block_device);
|
||||
|
||||
// get image file size
|
||||
uint64_t img_file_sz = get_file_size(input_path);
|
||||
uint64_t img_file_sz = get_file_size(path);
|
||||
PRINT_STR("img_file_sz = %llx\n", img_file_sz);
|
||||
|
||||
// open image file
|
||||
SceUID img_fd = sceIoOpen(input_path, SCE_O_RDONLY, 0777);
|
||||
PRINT_STR("img_fd = %x\n", img_fd);
|
||||
if(img_fd < 0) ERROR(img_fd);
|
||||
DO_CHECKED(rd_fd, sceIoOpen, path, SCE_O_RDONLY, 0777);
|
||||
|
||||
// open device
|
||||
int device_fd = OpenDevice(block_device, SCE_O_WRONLY);
|
||||
PRINT_STR("device_fd = %x\n", device_fd);
|
||||
if(device_fd < 0) ERROR(device_fd);
|
||||
DO_CHECKED(wr_fd, OpenDevice, block_device, SCE_O_WRONLY);
|
||||
|
||||
// get device size
|
||||
uint64_t device_size = 0;
|
||||
GetDeviceSize(device_fd, &device_size);
|
||||
PRINT_STR("device_size = %llx\n", device_size);
|
||||
if(device_size == 0) ERROR(-1);
|
||||
CREATE_DEV_SZ(wr_fd);
|
||||
if(img_file_sz > device_size) ERROR(-2);
|
||||
|
||||
if(progress_callback != NULL) progress_callback(block_device, input_path, total_write, device_size);
|
||||
|
||||
// enter read/write loop
|
||||
do {
|
||||
memset(DEVICE_DUMP_BUFFER, 0x00, sizeof(DEVICE_DUMP_BUFFER));
|
||||
int rd = sceIoRead(img_fd, DEVICE_DUMP_BUFFER, sizeof(DEVICE_DUMP_BUFFER)); // Read img data
|
||||
if(rd < 0) ERROR(rd);
|
||||
|
||||
int wr = WriteDevice(device_fd, DEVICE_DUMP_BUFFER, sizeof(DEVICE_DUMP_BUFFER)); // Write raw data to device
|
||||
if(wr == 0) ERROR(-3);
|
||||
if(wr < 0) ERROR(wr);
|
||||
|
||||
|
||||
total_write += wr;
|
||||
if(progress_callback != NULL) progress_callback(block_device, input_path, total_write, device_size);
|
||||
} while(total_write < device_size);
|
||||
DEVICE_ACCESS_LOOP(read_data_from_image, WriteDevice);
|
||||
|
||||
error:
|
||||
if(img_fd >= 0)
|
||||
sceIoClose(img_fd);
|
||||
if(device_fd >= 0)
|
||||
CloseDevice(device_fd);
|
||||
if(rd_fd >= 0)
|
||||
sceIoClose(rd_fd);
|
||||
if(wr_fd >= 0)
|
||||
CloseDevice(wr_fd);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wipe_device(char* block_device, void (*progress_callback)(char*, char*, uint64_t, uint64_t)) {
|
||||
int ret = 0;
|
||||
uint64_t total_write = 0;
|
||||
|
||||
// sanity safety check
|
||||
if(memcmp(block_device, "sdstor0:gcd", strlen("sdstor0:gcd")) != 0)
|
||||
return -1;
|
||||
|
||||
uint64_t total = 0;
|
||||
|
||||
int rd_fd = 0;
|
||||
char* path = NULL;
|
||||
|
||||
SAFE_CHK();
|
||||
PRINT_STR("Begining wipe of %s\n", block_device);
|
||||
|
||||
// open device
|
||||
int device_fd = OpenDevice(block_device, SCE_O_WRONLY); // SCARY
|
||||
PRINT_STR("device_fd = %x\n", device_fd);
|
||||
if(device_fd < 0) ERROR(device_fd);
|
||||
DO_CHECKED(wr_fd, OpenDevice, block_device, SCE_O_WRONLY);
|
||||
|
||||
// get device size
|
||||
uint64_t device_size = 0;
|
||||
GetDeviceSize(device_fd, &device_size);
|
||||
PRINT_STR("device_size = %llx\n", device_size);
|
||||
if(device_size == 0) ERROR(-1);
|
||||
CREATE_DEV_SZ(wr_fd);
|
||||
|
||||
if(progress_callback != NULL) progress_callback(block_device, block_device, total_write, device_size);
|
||||
memset(DEVICE_DUMP_BUFFER, 0x00, sizeof(DEVICE_DUMP_BUFFER));
|
||||
|
||||
// enter write loop
|
||||
do {
|
||||
int wr = WriteDevice(device_fd, DEVICE_DUMP_BUFFER, sizeof(DEVICE_DUMP_BUFFER)); // write raw to device
|
||||
if(wr == 0) ERROR(-2);
|
||||
if(wr < 0) ERROR(wr);
|
||||
|
||||
total_write += wr;
|
||||
|
||||
if(progress_callback != NULL) progress_callback(block_device, block_device, total_write, device_size);
|
||||
} while(total_write < device_size);
|
||||
// enter read/write loop
|
||||
DEVICE_ACCESS_LOOP(read_null, WriteDevice);
|
||||
|
||||
error:
|
||||
if(device_fd >= 0)
|
||||
CloseDevice(device_fd);
|
||||
if(wr_fd >= 0)
|
||||
CloseDevice(wr_fd);
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -6,8 +6,8 @@
|
|||
#define BLOCK_DEVICE_GRO0 "sdstor0:gcd-lp-ign-gamero"
|
||||
|
||||
uint64_t device_size(char* block_device);
|
||||
int dump_device_network(char* ip_address, unsigned short port, char* block_device, char* output_path, GcKeys* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t));
|
||||
int dump_device(char* block_device, char* output_path, GcKeys* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t));
|
||||
int dump_device_network(char* ip_address, unsigned short port, char* block_device, char* output_path, GcKEYS* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t));
|
||||
int dump_device(char* block_device, char* output_path, GcKEYS* keys, void (*progress_callback)(char*, char*, uint64_t, uint64_t));
|
||||
int wipe_device(char* block_device, void (*progress_callback)(char*, char*, uint64_t, uint64_t));
|
||||
int restore_device(char* block_device, char* input_path, void (*progress_callback)(char*, char*, uint64_t, uint64_t));
|
||||
uint8_t device_exist(char* block_device);
|
|
@ -107,7 +107,7 @@ void handle_menu_set_output(char* fmt, int what) {
|
|||
PRINT_STR("output_filename: %s\n", output_filename);
|
||||
|
||||
// get total size
|
||||
uint64_t total_device_size = sizeof(GcKeys);
|
||||
uint64_t total_device_size = sizeof(GcKEYS);
|
||||
if(block_device != NULL)
|
||||
total_device_size = device_size(block_device);
|
||||
PRINT_STR("total_device_size %llx\n", total_device_size);
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
#ifndef MBR_H
|
||||
#define MBR_H
|
||||
#define SECTOR_SIZE (0x200)
|
||||
|
||||
enum GcCODE {
|
||||
GcCODE_EMPTY = 0x00,
|
||||
GcCODE_IDSTORAGE = 0x01,
|
||||
GcCODE_SLB2 = 0x02,
|
||||
GcCODE_OS0 = 0x03,
|
||||
GcCODE_VS0 = 0x04,
|
||||
GcCODE_VD0 = 0x05,
|
||||
GcCODE_TM0 = 0x06,
|
||||
GcCODE_UR0 = 0x07,
|
||||
GcCODE_UX0 = 0x08,
|
||||
GcCODE_GRO0 = 0x09,
|
||||
GcCODE_GRW0 = 0x0A,
|
||||
GcCODE_UD0 = 0x0B,
|
||||
GcCODE_SA0 = 0x0C,
|
||||
GcCODE_MEDIAID = 0x0D,
|
||||
GcCODE_PD0 = 0x0E,
|
||||
GcCODE_UNUSED = 0x0F
|
||||
};
|
||||
|
||||
enum GcTYPE {
|
||||
GcTYPE_FAT16 = 0x06,
|
||||
GcTYPE_EXFAT = 0x07,
|
||||
GcTYPE_RAW = 0xDA
|
||||
};
|
||||
|
||||
typedef struct GcKEYS{
|
||||
uint8_t rifbuf[0x20];
|
||||
uint8_t klic[0x20];
|
||||
} GcKEYS;
|
||||
|
||||
typedef struct GcPART {
|
||||
uint32_t off;
|
||||
uint32_t sz;
|
||||
uint8_t code;
|
||||
uint8_t type;
|
||||
uint8_t active;
|
||||
uint32_t flags;
|
||||
uint16_t unk;
|
||||
} GcPART;
|
||||
|
||||
typedef struct GcMBR {
|
||||
char magic[0x20];
|
||||
uint32_t version;
|
||||
uint32_t devicesize;
|
||||
char unk1[0x28];
|
||||
GcPART partitions[0x10];
|
||||
char unk2[0x5e];
|
||||
char unk3[0x10 * 4];
|
||||
uint16_t sig;
|
||||
} GcMBR;
|
||||
|
||||
|
||||
#endif
|
92
app/menu.c
92
app/menu.c
|
@ -24,7 +24,7 @@ static uint8_t options[0x1000];
|
|||
int increment_y = 20; \
|
||||
int total = 0; \
|
||||
memset(options, 0x00, sizeof(options))
|
||||
#define ADDOPT(cond,x)if(cond) { \
|
||||
#define ADDOPT(cond,x) if(cond) { \
|
||||
draw_option(opt_y, x, option == *selected); \
|
||||
opt_y += increment_y; \
|
||||
total++; \
|
||||
|
@ -88,6 +88,22 @@ static uint8_t options[0x1000];
|
|||
PRINT_STR("window: %x\n", window); \
|
||||
}
|
||||
|
||||
#define RESTORE_MENU(title, what, dev, to) start_draw(); \
|
||||
draw_background(); \
|
||||
\
|
||||
char output_txt[128]; \
|
||||
snprintf(output_txt, sizeof(output_txt), title " %.30s ...", dev); \
|
||||
draw_title(output_txt); \
|
||||
\
|
||||
snprintf(output_txt, sizeof(output_txt), what " \"%.30s\" ...", to); \
|
||||
draw_text_center(200, output_txt); \
|
||||
\
|
||||
draw_progress_bar(210, progress, total); \
|
||||
snprintf(output_txt, sizeof(output_txt), "%llu / %llu (%i%%)", progress, total, (int)( (((float)progress) / ((float)total)) * 100.0)); \
|
||||
draw_text_center(260, output_txt); \
|
||||
\
|
||||
end_draw()
|
||||
|
||||
void init_menus() {
|
||||
insertgc_tex = load_texture("app0:/res/insertgc.png");
|
||||
|
||||
|
@ -98,6 +114,21 @@ void term_menus() {
|
|||
}
|
||||
|
||||
|
||||
|
||||
|
||||
void draw_wipe_progress(char* device, char* unused, uint64_t progress, uint64_t total) {
|
||||
RESTORE_MENU("Formatting", "Writing", device, device);
|
||||
}
|
||||
|
||||
void draw_restore_progress(char* device, char* input_filename, uint64_t progress, uint64_t total) {
|
||||
RESTORE_MENU("Restoring", "Reading", device, input_filename);
|
||||
}
|
||||
|
||||
void draw_dump_progress(char* device, char* output_filename, uint64_t progress, uint64_t total) {
|
||||
RESTORE_MENU("Backing up", "Writing", device, output_filename);
|
||||
}
|
||||
|
||||
|
||||
int draw_gc_options(int* selected, int* window, char* title, uint8_t has_grw0, uint8_t has_mediaid) {
|
||||
start_draw();
|
||||
draw_background();
|
||||
|
@ -242,63 +273,6 @@ int draw_network_settings(int* selected, int* window, char* ip_address, unsigned
|
|||
RETURNOPT();
|
||||
}
|
||||
|
||||
void draw_wipe_progress(char* device, char* output_filename, uint64_t progress, uint64_t total) {
|
||||
|
||||
start_draw();
|
||||
draw_background();
|
||||
|
||||
char output_txt[128];
|
||||
snprintf(output_txt, sizeof(output_txt), "Formatting %s ...", device);
|
||||
draw_title(output_txt);
|
||||
|
||||
snprintf(output_txt, sizeof(output_txt), "Writing \"%.30s\" ...", device);
|
||||
draw_text_center(200, output_txt);
|
||||
|
||||
draw_progress_bar(210, progress, total);
|
||||
snprintf(output_txt, sizeof(output_txt), "%llu / %llu (%i%%)", progress, total, (int)( (((float)progress) / ((float)total)) * 100.0));
|
||||
draw_text_center(260, output_txt);
|
||||
|
||||
end_draw();
|
||||
}
|
||||
|
||||
void draw_restore_progress(char* device, char* input_filename, uint64_t progress, uint64_t total) {
|
||||
|
||||
start_draw();
|
||||
draw_background();
|
||||
|
||||
char output_txt[128];
|
||||
snprintf(output_txt, sizeof(output_txt), "Restoring %.30s ...", device);
|
||||
draw_title(output_txt);
|
||||
|
||||
snprintf(output_txt, sizeof(output_txt), "Reading \"%.30s\" ...", input_filename);
|
||||
draw_text_center(200, output_txt);
|
||||
|
||||
draw_progress_bar(210, progress, total);
|
||||
snprintf(output_txt, sizeof(output_txt), "%llu / %llu (%i%%)", progress, total, (int)( (((float)progress) / ((float)total)) * 100.0));
|
||||
draw_text_center(260, output_txt);
|
||||
|
||||
end_draw();
|
||||
}
|
||||
|
||||
void draw_dump_progress(char* device, char* output_filename, uint64_t progress, uint64_t total) {
|
||||
|
||||
start_draw();
|
||||
draw_background();
|
||||
|
||||
char output_txt[128];
|
||||
snprintf(output_txt, sizeof(output_txt), "Backing up %s ...", device);
|
||||
draw_title(output_txt);
|
||||
|
||||
snprintf(output_txt, sizeof(output_txt), "Writing \"%.30s\" ...", output_filename);
|
||||
draw_text_center(200, output_txt);
|
||||
|
||||
draw_progress_bar(210, progress, total);
|
||||
snprintf(output_txt, sizeof(output_txt), "%llu / %llu (%i%%)", progress, total, (int)( (((float)progress) / ((float)total)) * 100.0));
|
||||
draw_text_center(260, output_txt);
|
||||
|
||||
end_draw();
|
||||
}
|
||||
|
||||
void draw_ime() {
|
||||
start_draw();
|
||||
draw_background();
|
||||
|
@ -428,7 +402,7 @@ int do_device_restore(char* block_device, char* input_file) {
|
|||
|
||||
int do_device_dump(char* block_device, char* output_file, uint8_t vci, char* ip_address, unsigned short port) {
|
||||
|
||||
GcKeys keys;
|
||||
GcKEYS keys;
|
||||
if(vci){
|
||||
int res = extract_gc_keys(&keys);
|
||||
if(res < 0) return res;
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 109 KiB |
10
app/vci.h
10
app/vci.h
|
@ -1,3 +1,6 @@
|
|||
#ifndef VCI_H
|
||||
#define VCI_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "crypto.h"
|
||||
|
||||
|
@ -7,6 +10,9 @@ typedef struct VciFile {
|
|||
char magic[0x4];
|
||||
int version;
|
||||
uint64_t devicesize;
|
||||
GcKeys keys;
|
||||
GcKEYS keys;
|
||||
uint8_t padding[0x1B0];
|
||||
} VciFile;
|
||||
} VciFile;
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,57 @@
|
|||
#!/bin/sh
|
||||
|
||||
# Install PSP2SPL library
|
||||
cp kern/psp2spl/libSKPLForKernel_stub.a $VITASDK/arm-vita-eabi/lib/libSKPLForKernel_stub.a
|
||||
|
||||
# Build Kern
|
||||
cd kern
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make install
|
||||
|
||||
if [ $? -eq 1 ]
|
||||
then
|
||||
echo "error building kern"
|
||||
exit
|
||||
fi
|
||||
|
||||
|
||||
# Back to root
|
||||
cd ../..
|
||||
|
||||
# Build App
|
||||
cd app
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
if [ $? -eq 1 ]
|
||||
then
|
||||
echo "error building app"
|
||||
exit
|
||||
fi
|
||||
|
||||
# Back to root
|
||||
cd ../..
|
||||
|
||||
# Build backup_gc_network pc app
|
||||
cd pc
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
make
|
||||
|
||||
if [ $? -eq 1 ]
|
||||
then
|
||||
echo "error building pc"
|
||||
exit
|
||||
fi
|
||||
|
||||
cd ../..
|
||||
|
||||
mkdir build
|
||||
cp app/build/GCToolKit.vpk build/GCToolKit.vpk
|
||||
cp pc/build/gc_backup_network.exe build/gc_backup_network.exe
|
||||
cp pc/build/gc_backup_network build/gc_backup_network
|
Loading…
Reference in New Issue