merge flasher in client
This commit is contained in:
@@ -83,7 +83,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||
ctx->segments = calloc(sizeof(flash_seg_t) * num_phdrs, sizeof(uint8_t));
|
||||
if (!ctx->segments) {
|
||||
PrintAndLogEx(ERR, "Out of memory");
|
||||
return -1;
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
ctx->num_segs = 0;
|
||||
seg = ctx->segments;
|
||||
@@ -113,19 +113,19 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||
if (filesz != memsz) {
|
||||
PrintAndLogEx(ERR, "Error: PHDR file size does not equal memory size\n"
|
||||
"(DATA+BSS PHDRs do not make sense on ROM platforms!)");
|
||||
return -1;
|
||||
return PM3_EFILE;
|
||||
}
|
||||
if (paddr < last_end) {
|
||||
PrintAndLogEx(ERR, "Error: PHDRs not sorted or overlap");
|
||||
return -1;
|
||||
return PM3_EFILE;
|
||||
}
|
||||
if (paddr < FLASH_START || (paddr + filesz) > flash_end) {
|
||||
PrintAndLogEx(ERR, "Error: PHDR is not contained in Flash");
|
||||
return -1;
|
||||
return PM3_EFILE;
|
||||
}
|
||||
if (vaddr >= FLASH_START && vaddr < flash_end && (flags & PF_W)) {
|
||||
PrintAndLogEx(ERR, "Error: Flash VMA segment is writable");
|
||||
return -1;
|
||||
return PM3_EFILE;
|
||||
}
|
||||
|
||||
uint8_t *data;
|
||||
@@ -133,12 +133,12 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||
data = calloc(filesz + BLOCK_SIZE, sizeof(uint8_t));
|
||||
if (!data) {
|
||||
PrintAndLogEx(ERR, "Error: Out of memory");
|
||||
return -1;
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
if (fseek(fd, offset, SEEK_SET) < 0 || fread(data, 1, filesz, fd) != filesz) {
|
||||
PrintAndLogEx(ERR, "Error while reading PHDR payload");
|
||||
free(data);
|
||||
return -1;
|
||||
return PM3_EFILE;
|
||||
}
|
||||
|
||||
uint32_t block_offset = paddr & (BLOCK_SIZE - 1);
|
||||
@@ -157,7 +157,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||
if (!new_data) {
|
||||
PrintAndLogEx(ERR, "Error: Out of memory");
|
||||
free(data);
|
||||
return -1;
|
||||
return PM3_EMALLOC;
|
||||
}
|
||||
memset(new_data, 0xff, new_length);
|
||||
memcpy(new_data, prev_seg->data, prev_seg->length);
|
||||
@@ -191,7 +191,7 @@ static int build_segs_from_phdrs(flash_file_t *ctx, FILE *fd, Elf32_Phdr *phdrs,
|
||||
last_end = paddr + filesz;
|
||||
phdr++;
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Sanity check segments and check for bootloader writes
|
||||
@@ -201,26 +201,26 @@ static int check_segs(flash_file_t *ctx, int can_write_bl, uint32_t flash_end) {
|
||||
|
||||
if (seg->start & (BLOCK_SIZE - 1)) {
|
||||
PrintAndLogEx(ERR, "Error: Segment is not aligned");
|
||||
return -1;
|
||||
return PM3_EFILE;
|
||||
}
|
||||
if (seg->start < FLASH_START) {
|
||||
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
|
||||
return -1;
|
||||
return PM3_EFILE;
|
||||
}
|
||||
if (seg->start + seg->length > flash_end) {
|
||||
PrintAndLogEx(ERR, "Error: Segment is outside of flash bounds");
|
||||
return -1;
|
||||
return PM3_EFILE;
|
||||
}
|
||||
if (!can_write_bl && seg->start < BOOTLOADER_END) {
|
||||
PrintAndLogEx(ERR, "Attempted to write bootloader but bootloader writes are not enabled");
|
||||
return -1;
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
if (can_write_bl && seg->start < BOOTLOADER_END && (seg->start + seg->length > BOOTLOADER_END)) {
|
||||
PrintAndLogEx(ERR, "Error: Segment is outside of bootloader bounds");
|
||||
return -1;
|
||||
return PM3_EFILE;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Load an ELF file and prepare it for flashing
|
||||
@@ -230,11 +230,12 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||
Elf32_Phdr *phdrs = NULL;
|
||||
uint16_t num_phdrs;
|
||||
uint32_t flash_end = FLASH_START + flash_size;
|
||||
int res;
|
||||
int res = PM3_EUNDEF;
|
||||
|
||||
fd = fopen(name, "rb");
|
||||
if (!fd) {
|
||||
PrintAndLogEx(ERR, _RED_("Could not open file") "%s >>> ", name);
|
||||
res = PM3_EFILE;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
@@ -242,28 +243,34 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||
|
||||
if (fread(&ehdr, sizeof(ehdr), 1, fd) != 1) {
|
||||
PrintAndLogEx(ERR, "Error while reading ELF file header");
|
||||
res = PM3_EFILE;
|
||||
goto fail;
|
||||
}
|
||||
if (memcmp(ehdr.e_ident, elf_ident, sizeof(elf_ident))
|
||||
|| le32(ehdr.e_version) != 1) {
|
||||
PrintAndLogEx(ERR, "Not an ELF file or wrong ELF type");
|
||||
res = PM3_EFILE;
|
||||
goto fail;
|
||||
}
|
||||
if (le16(ehdr.e_type) != ET_EXEC) {
|
||||
PrintAndLogEx(ERR, "ELF is not executable");
|
||||
res = PM3_EFILE;
|
||||
goto fail;
|
||||
}
|
||||
if (le16(ehdr.e_machine) != EM_ARM) {
|
||||
PrintAndLogEx(ERR, "Wrong ELF architecture");
|
||||
res = PM3_EFILE;
|
||||
goto fail;
|
||||
}
|
||||
if (!ehdr.e_phnum || !ehdr.e_phoff) {
|
||||
PrintAndLogEx(ERR, "ELF has no PHDRs");
|
||||
res = PM3_EFILE;
|
||||
goto fail;
|
||||
}
|
||||
if (le16(ehdr.e_phentsize) != sizeof(Elf32_Phdr)) {
|
||||
// could be a structure padding issue...
|
||||
PrintAndLogEx(ERR, "Either the ELF file or this code is made of fail");
|
||||
res = PM3_EFILE;
|
||||
goto fail;
|
||||
}
|
||||
num_phdrs = le16(ehdr.e_phnum);
|
||||
@@ -271,28 +278,31 @@ int flash_load(flash_file_t *ctx, const char *name, int can_write_bl, int flash_
|
||||
phdrs = calloc(le16(ehdr.e_phnum) * sizeof(Elf32_Phdr), sizeof(uint8_t));
|
||||
if (!phdrs) {
|
||||
PrintAndLogEx(ERR, "Out of memory");
|
||||
res = PM3_EMALLOC;
|
||||
goto fail;
|
||||
}
|
||||
if (fseek(fd, le32(ehdr.e_phoff), SEEK_SET) < 0) {
|
||||
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
|
||||
res = PM3_EFILE;
|
||||
goto fail;
|
||||
}
|
||||
if (fread(phdrs, sizeof(Elf32_Phdr), num_phdrs, fd) != num_phdrs) {
|
||||
res = PM3_EFILE;
|
||||
PrintAndLogEx(ERR, "Error while reading ELF PHDRs");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
res = build_segs_from_phdrs(ctx, fd, phdrs, num_phdrs, flash_end);
|
||||
if (res < 0)
|
||||
if (res != PM3_SUCCESS)
|
||||
goto fail;
|
||||
res = check_segs(ctx, can_write_bl, flash_end);
|
||||
if (res < 0)
|
||||
if (res != PM3_SUCCESS)
|
||||
goto fail;
|
||||
|
||||
free(phdrs);
|
||||
fclose(fd);
|
||||
ctx->filename = name;
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
|
||||
fail:
|
||||
if (phdrs)
|
||||
@@ -300,7 +310,7 @@ fail:
|
||||
if (fd)
|
||||
fclose(fd);
|
||||
flash_free(ctx);
|
||||
return -1;
|
||||
return res;
|
||||
}
|
||||
|
||||
// Get the state of the proxmark, backwards compatible
|
||||
@@ -326,22 +336,23 @@ static int get_proxmark_state(uint32_t *state) {
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(ERR, _RED_("Error:") "Couldn't get Proxmark3 state, bad response type: 0x%04x", resp.cmd);
|
||||
return -1;
|
||||
return PM3_EFATAL;
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// Enter the bootloader to be able to start flashing
|
||||
static int enter_bootloader(char *serial_port_name) {
|
||||
uint32_t state;
|
||||
int ret;
|
||||
|
||||
if (get_proxmark_state(&state) < 0)
|
||||
return -1;
|
||||
if ((ret = get_proxmark_state(&state)) != PM3_SUCCESS)
|
||||
return ret;
|
||||
|
||||
/* Already in flash state, we're done. */
|
||||
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_BOOTROM)
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
|
||||
if (state & DEVICE_INFO_FLAG_CURRENT_MODE_OS) {
|
||||
PrintAndLogEx(SUCCESS, _BLUE_("Entering bootloader..."));
|
||||
@@ -364,15 +375,15 @@ static int enter_bootloader(char *serial_port_name) {
|
||||
|
||||
if (OpenProxmark(serial_port_name, true, 60, true, FLASHMODE_SPEED)) {
|
||||
PrintAndLogEx(NORMAL, " " _GREEN_("Found"));
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
} else {
|
||||
PrintAndLogEx(ERR, _RED_("Error:") "Proxmark3 not found.");
|
||||
return -1;
|
||||
return PM3_ETIMEOUT;
|
||||
}
|
||||
}
|
||||
|
||||
PrintAndLogEx(ERR, _RED_("Error:") "Unknown Proxmark3 mode");
|
||||
return -1;
|
||||
return PM3_EFATAL;
|
||||
}
|
||||
|
||||
static int wait_for_ack(PacketResponseNG *ack) {
|
||||
@@ -383,9 +394,9 @@ static int wait_for_ack(PacketResponseNG *ack) {
|
||||
ack->cmd,
|
||||
(ack->cmd == CMD_NACK) ? "NACK" : ""
|
||||
);
|
||||
return -1;
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static void flash_suggest_update_bootloader(void) {
|
||||
@@ -401,12 +412,15 @@ static void flash_suggest_update_flasher(void) {
|
||||
int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t *max_allowed) {
|
||||
uint32_t state;
|
||||
uint32_t chipinfo = 0;
|
||||
int ret;
|
||||
|
||||
if (enter_bootloader(serial_port_name) < 0)
|
||||
return -1;
|
||||
ret = enter_bootloader(serial_port_name);
|
||||
if (ret != PM3_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (get_proxmark_state(&state) < 0)
|
||||
return -1;
|
||||
ret = get_proxmark_state(&state);
|
||||
if (ret != PM3_SUCCESS)
|
||||
return ret;
|
||||
|
||||
if (state & DEVICE_INFO_FLAG_UNDERSTANDS_CHIP_INFO) {
|
||||
SendCommandBL(CMD_CHIP_INFO, 0, 0, 0, NULL, 0);
|
||||
@@ -485,7 +499,7 @@ int flash_start_flashing(int enable_bl_writes, char *serial_port_name, uint32_t
|
||||
PrintAndLogEx(ERR, _RED_("Note: Your bootloader does not understand the new " _YELLOW_("START_FLASH") _RED_("command")));
|
||||
flash_suggest_update_bootloader();
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int write_block(uint32_t address, uint8_t *data, uint32_t length) {
|
||||
@@ -531,7 +545,7 @@ int flash_write(flash_file_t *ctx) {
|
||||
|
||||
if (write_block(baddr, data, block_size) < 0) {
|
||||
PrintAndLogEx(ERR, "Error writing block %d of %u", block, blocks);
|
||||
return -1;
|
||||
return PM3_EFATAL;
|
||||
}
|
||||
|
||||
data += block_size;
|
||||
@@ -544,7 +558,7 @@ int flash_write(flash_file_t *ctx) {
|
||||
PrintAndLogEx(NORMAL, " " _GREEN_("OK"));
|
||||
fflush(stdout);
|
||||
}
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// free a file context
|
||||
@@ -564,5 +578,5 @@ void flash_free(flash_file_t *ctx) {
|
||||
int flash_stop_flashing(void) {
|
||||
SendCommandBL(CMD_HARDWARE_RESET, 0, 0, 0, NULL, 0);
|
||||
msleep(100);
|
||||
return 0;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user