merge flasher in client

This commit is contained in:
Philippe Teuwen
2019-09-09 01:07:46 +02:00
parent fe0fe0d65b
commit afe891647f
14 changed files with 231 additions and 222 deletions

View File

@@ -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;
}