Beispiel #1
0
static int is_prd_supported(void)
{
	char *path;
	int rc;
	int len;
	char *buf;

	rc = asprintf(&path, "%s/ibm,opal/diagnostics/compatible",
		      devicetree_base);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'compatible' node path: %m");
		return -1;
	}

	rc = open_and_read(path, (void *) &buf, &len);
	if (rc)
		goto out_free;

	if (buf[len - 1] != '\0')
		pr_log(LOG_INFO, "FW: node %s is not nul-terminated", path);

	rc = find_string(buf, len, "ibm,opal-prd") ? 0 : -1;

	free(buf);
out_free:
	free(path);
	return rc;
}
Beispiel #2
0
int pe2obj(int argc, char **argv)
{
    // decleration before more meaningful initialization for cleanup
    int     ret   = EXIT_SUCCESS;
    FILE   *fh    = NULL;
    int8_t *image = NULL;

    FAIL_IF(argc != 3, "usage: petool pe2obj <in> <out>\n");

    uint32_t length;
    FAIL_IF_SILENT(open_and_read(&fh, &image, &length, argv[1], "rb"));


    fclose(fh);
    fh = NULL; // for cleanup

    PIMAGE_DOS_HEADER dos_hdr = (void *)image;
    PIMAGE_NT_HEADERS nt_hdr = (void *)(image + dos_hdr->e_lfanew);

    FAIL_IF(length < 512,                            "File too small.\n");
    FAIL_IF(dos_hdr->e_magic != IMAGE_DOS_SIGNATURE, "File DOS signature invalid.\n");
    FAIL_IF(nt_hdr->Signature != IMAGE_NT_SIGNATURE, "File NT signature invalid.\n");

    for (int i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++)
    {
        const PIMAGE_SECTION_HEADER cur_sct = IMAGE_FIRST_SECTION(nt_hdr) + i;
        if (cur_sct->PointerToRawData)
        {
            cur_sct->PointerToRawData -= dos_hdr->e_lfanew + 4;
        }

        if (cur_sct->Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA && !(cur_sct->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA))
        {
            cur_sct->PointerToRawData = 0;
            cur_sct->SizeOfRawData = 0;
        }
    }

    fh = fopen(argv[2], "wb");
    FAIL_IF_PERROR(!fh, "Error opening output file");

    FAIL_IF_PERROR(fwrite((char *)image + (dos_hdr->e_lfanew + 4),
                         length - (dos_hdr->e_lfanew + 4),
                         1,
                         fh) != 1,
                  "Failed to write object file to output file\n");

cleanup:
    if (image) free(image);
    if (fh)    fclose(fh);
    return ret;
}
Beispiel #3
0
int setvs(int argc, char **argv)
{
    // decleration before more meaningful initialization for cleanup
    int     ret   = EXIT_SUCCESS;
    FILE   *fh    = NULL;
    int8_t *image = NULL;

    FAIL_IF(argc != 4, "usage: petool setvs <image> <section> <VirtualSize>\n");

    uint32_t vs   = strtol(argv[3], NULL, 0);

    uint32_t length;
    FAIL_IF_SILENT(open_and_read(&fh, &image, &length, argv[1], "r+b"));

    PIMAGE_DOS_HEADER dos_hdr = (void *)image;
    PIMAGE_NT_HEADERS nt_hdr  = (void *)(image + dos_hdr->e_lfanew);

    FAIL_IF(length < sizeof (IMAGE_DOS_HEADER),         "File too small.\n");
    FAIL_IF(dos_hdr->e_magic != IMAGE_DOS_SIGNATURE,    "File DOS signature invalid.\n");
    FAIL_IF(dos_hdr->e_lfanew == 0,                     "NT header missing.\n");
    FAIL_IF(nt_hdr->Signature != IMAGE_NT_SIGNATURE,    "File NT signature invalid.\n");
    FAIL_IF(vs == 0,                                    "VirtualSize can't be zero.\n");

    for (int32_t i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++)
    {
        PIMAGE_SECTION_HEADER sct_hdr = IMAGE_FIRST_SECTION(nt_hdr) + i;

        if (strcmp(argv[2], (char *)sct_hdr->Name) == 0)
        {
            FAIL_IF(vs < sct_hdr->SizeOfRawData,"VirtualSize can't be smaller than raw size.\n");
            sct_hdr->Misc.VirtualSize = vs;      // update section size
                                                 // update total virtual size of image
            nt_hdr->OptionalHeader.SizeOfImage += vs - sct_hdr->Misc.VirtualSize;
            nt_hdr->OptionalHeader.CheckSum = 0; // FIXME: implement checksum calculation
            rewind(fh);                          // write to file
            FAIL_IF_PERROR(fwrite(image, length, 1, fh) != 1, "Error writing executable");
            goto cleanup;                        // done
        }
    }

    fprintf(stderr, "No '%s' section in given PE image.\n", argv[2]);

cleanup:
    if (image) free(image);
    if (fh)    fclose(fh);
    return ret;
}
Beispiel #4
0
static int prd_init_one_range(struct opal_prd_ctx *ctx, const char *path,
		struct dirent *dirent)
{
	char *label_path, *reg_path, *instance_path;
	struct prd_range *range;
	int label_len, len, rc;
	__be64 *reg;
	char *label;
	void *buf;

	rc = asprintf(&label_path, "%s/%s/ibm,prd-label", path, dirent->d_name);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'ibm,prd-label' path "
				"node: %m");
		return -1;
	}
	rc = asprintf(&instance_path, "%s/%s/ibm,prd-instance",
			path, dirent->d_name);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'ibm,prd-instance' path "
				"node: %m");
		return -1;
	}
	rc = asprintf(&reg_path, "%s/%s/reg", path, dirent->d_name);
	if (rc < 0) {
		pr_log(LOG_ERR, "FW: error creating 'reg' path "
				" node: %m");
		return -1;
	}

	reg = NULL;
	label = NULL;
	rc = -1;

	rc = open_and_read(label_path, &buf, &label_len);
	if (rc)
		goto out_free;

	label = buf;

	if (label[label_len-1] != '\0')
		pr_log(LOG_INFO, "FW: node %s has invalid ibm,prd-label - "
				"not nul-terminated",
				dirent->d_name);

	rc = open_and_read(reg_path, &buf, &len);
	if (rc)
		goto out_free;

	reg = buf;

	if (len != 2 * sizeof(*reg)) {
		pr_log(LOG_ERR, "FW: node %s has invalid 'reg' size: %d",
				dirent->d_name, len);
		goto out_free;
	}


	ctx->ranges = realloc(ctx->ranges, ++ctx->n_ranges * sizeof(*range));
	range = &ctx->ranges[ctx->n_ranges - 1];
	range->name = strndup(label, label_len);
	range->physaddr = be64toh(reg[0]);
	range->size = be64toh(reg[1]);
	range->buf = NULL;
	range->multiple = false;
	range->instance = 0;

	/* optional instance */
	rc = open_and_read(instance_path, &buf, &len);
	if (!rc && len == sizeof(uint32_t)) {
		range->multiple = true;
		range->instance = be32toh(*(uint32_t *)buf);
		ctx->fw_range_instances = true;
	}
	rc = 0;

out_free:
	free(reg);
	free(label);
	free(instance_path);
	free(reg_path);
	free(label_path);
	return rc;
}
Beispiel #5
0
int genmak(int argc, char **argv)
{
    int     ret   = EXIT_SUCCESS;
    FILE   *fh    = NULL;
    int8_t *image = NULL;
    FILE   *ofh   = stdout;
    char   base[256] = { '\0' };

    FAIL_IF(argc < 2, "usage: petool genmak <image> [ofile]\n");

    if (argc > 2)
    {
        FAIL_IF(file_exists(argv[2]), "%s: output file already exists.\n", argv[2]);
        ofh = fopen(argv[2], "w");
        FAIL_IF_PERROR(ofh == NULL, "%s");
    }

    uint32_t length;
    FAIL_IF_SILENT(open_and_read(&fh, &image, &length, argv[1], "rb"));

    fclose(fh);
    fh = NULL; // for cleanup

    PIMAGE_DOS_HEADER dos_hdr = (void *)image;
    PIMAGE_NT_HEADERS nt_hdr = (void *)(image + dos_hdr->e_lfanew);

    FAIL_IF(length < 512,                            "File too small.\n");
    FAIL_IF(dos_hdr->e_magic != IMAGE_DOS_SIGNATURE, "File DOS signature invalid.\n");
    FAIL_IF(nt_hdr->Signature != IMAGE_NT_SIGNATURE, "File NT signature invalid.\n");

    strcpy(base, file_basename(argv[1]));
    char *p = strrchr(base, '.');
    if (p)
    {
        *p = '\0';
    }

    fprintf(ofh, "-include config.mk\n\n");
    fprintf(ofh, "INPUT       = %s\n", file_basename(argv[1]));
    fprintf(ofh, "OUTPUT      = %sp.exe\n", base);
    fprintf(ofh, "LDS         = %sp.lds\n", base);

    fprintf(ofh, "IMPORTS     =");
    if (nt_hdr->OptionalHeader.DataDirectory[1].VirtualAddress)
    {
        fprintf(ofh, " 0x%"PRIX32" %d", nt_hdr->OptionalHeader.DataDirectory[1].VirtualAddress, nt_hdr->OptionalHeader.DataDirectory[1].Size);
    }
    fprintf(ofh, "\n");

    fprintf(ofh, "LDFLAGS     = --section-alignment=0x%"PRIX32, nt_hdr->OptionalHeader.SectionAlignment);

    if (nt_hdr->OptionalHeader.Subsystem == 2)
        fprintf(ofh, " --subsystem=windows");

    fprintf(ofh, "\n\n");

    fprintf(ofh, "OBJS        = rsrc.o\n\n");

    fprintf(ofh, "PETOOL     ?= petool\n");
    fprintf(ofh, "STRIP      ?= strip\n\n");

    fprintf(ofh, "all: $(OUTPUT)\n\n");

    fprintf(ofh, "rsrc.o: $(INPUT)\n");
    fprintf(ofh, "\t$(PETOOL) re2obj $(INPUT) $@\n\n");

    fprintf(ofh, "$(OUTPUT): $(LDS) $(INPUT) $(OBJS)\n");
    fprintf(ofh, "\t$(LD) $(LDFLAGS) -T $(LDS) -o $@ $(OBJS)\n");
    fprintf(ofh, "ifneq (,$(IMPORTS))\n");
    fprintf(ofh, "\t$(PETOOL) setdd $@ 1 $(IMPORTS) || ($(RM) $@ && exit 1)\n");
    fprintf(ofh, "endif\n");
    fprintf(ofh, "\t$(PETOOL) patch $@ || ($(RM) $@ && exit 1)\n");
    fprintf(ofh, "\t$(STRIP) -R .patch $@ || ($(RM) $@ && exit 1)\n");
    fprintf(ofh, "\t$(PETOOL) dump $@\n\n");

    fprintf(ofh, "clean:\n");
    fprintf(ofh, "\t$(RM) $(OUTPUT) $(OBJS)\n");

cleanup:
    if (argc > 2)
    {
        if (ofh)   fclose(ofh);
    }

    if (image) free(image);
    if (fh)    fclose(fh);
    return ret;
}
Beispiel #6
0
int patch(int argc, char **argv)
{
    // decleration before more meaningful initialization for cleanup
    int     ret   = EXIT_FAILURE;
    FILE   *fh    = NULL;
    int8_t *image = NULL;

    FAIL_IF(argc < 2, "usage: petool patch <image> [section]\n");

    uint32_t length;
    FAIL_IF_SILENT(open_and_read(&fh, &image, &length, argv[1], "r+b"));

    PIMAGE_DOS_HEADER dos_hdr = (void *)image;
    PIMAGE_NT_HEADERS nt_hdr = (void *)(image + dos_hdr->e_lfanew);

    char *section = argc > 2 ? (char *)argv[2] : ".patch";
    int8_t *patch = NULL;
    int32_t patch_len = 0;

    for (int32_t i = 0; i < nt_hdr->FileHeader.NumberOfSections; i++)
    {
        PIMAGE_SECTION_HEADER sct_hdr = IMAGE_FIRST_SECTION(nt_hdr) + i;

        if (strcmp(section, (char *)sct_hdr->Name) == 0)
        {
            patch = image + sct_hdr->PointerToRawData;
            patch_len = sct_hdr->Misc.VirtualSize;
            break;
        }

        sct_hdr++;
    }

    if (patch == NULL)
    {
        fprintf(stderr, "Warning: No '%s' section in given PE image.\n", section);
        ret = EXIT_SUCCESS;
        goto cleanup;
    }

    for (int8_t *p = patch; p < patch + patch_len;)
    {
        uint32_t paddress = get_uint32(&p);
        if (paddress == 0)
        {
            fprintf(stderr, "Warning: Trailing zero address in '%s' section.\n", section);
            break;
        }

        uint32_t plength = get_uint32(&p);
        FAIL_IF_SILENT(patch_image(image, paddress, p, plength) == EXIT_FAILURE);

        p += plength;
    }

    /* FIXME: implement checksum calculation */
    nt_hdr->OptionalHeader.CheckSum = 0;

    rewind(fh);
    FAIL_IF_PERROR(fwrite(image, length, 1, fh) != 1, "Error writing executable");

    ret = EXIT_SUCCESS;
cleanup:
    if (image) free(image);
    if (fh)    fclose(fh);
    return ret;
}