Skip to content

Commit

Permalink
Merge pull request #213 from redspot/master
Browse files Browse the repository at this point in the history
Fix bug in libpe ordinal mask handling
  • Loading branch information
GoGoOtaku committed Apr 27, 2024
2 parents 3c4163e + c4fda31 commit b5a9a9f
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 29 deletions.
1 change: 1 addition & 0 deletions .github/workflows/multi-os-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ on:
branches: [ master ]
pull_request:
branches: [ master ]
workflow_dispatch:

jobs:
build-linux:
Expand Down
32 changes: 16 additions & 16 deletions lib/libpe/hashes.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
libpe - the PE library
Copyright (C) 2010 - 2017 libpe authors
This file is part of libpe.
libpe is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -298,11 +298,11 @@ pe_hash_sections_t *pe_get_sections_hash(pe_ctx_t *ctx) {
// TODO(jweyrich): Should we report an error? If yes, we need a redesign.
return NULL;
}

result->err = LIBPE_E_OK;

const size_t num_sections = pe_sections_count(ctx);

// Allocate an array of pointers once so we can store each pe_hash_t pointer in the
// respective result->sections[i].
result->sections = calloc(num_sections, sizeof(pe_hash_t *));
Expand Down Expand Up @@ -362,7 +362,7 @@ pe_hash_t *pe_get_file_hash(pe_ctx_t *ctx) {
if (status != LIBPE_E_OK)
abort();
return hash;
}
}

typedef struct element {
char *dll_name;
Expand Down Expand Up @@ -423,15 +423,15 @@ static void imphash_load_imported_functions(pe_ctx_t *ctx, uint64_t offset, char
if (thunk_type == 0)
return;

is_ordinal = (thunk_type & IMAGE_ORDINAL_FLAG32) != 0;
is_ordinal = (thunk_type & (IMAGE_ORDINAL_MASK(ctx))) != 0;

if (is_ordinal) {
errcode = asprintf(&hint_str, "%"PRIu32,
thunk->u1.Ordinal & ~IMAGE_ORDINAL_FLAG32);
errcode = asprintf(&hint_str, "%"PRIu32,
thunk->u1.Ordinal & ~((uint32_t)IMAGE_ORDINAL_MASK(ctx)));

// FIX-ME: devemos abortar a execucao?
PEV_ABORT_IF(errcode == -1);

} else {
const uint64_t imp_ofs = pe_rva2ofs(ctx, thunk->u1.AddressOfData);
const IMAGE_IMPORT_BY_NAME *imp_name = LIBPE_PTR_ADD(ctx->map_addr, imp_ofs);
Expand Down Expand Up @@ -469,12 +469,12 @@ static void imphash_load_imported_functions(pe_ctx_t *ctx, uint64_t offset, char
if (thunk_type == 0)
return;

is_ordinal = (thunk_type & IMAGE_ORDINAL_FLAG64) != 0;
is_ordinal = (thunk_type & (IMAGE_ORDINAL_MASK(ctx))) != 0;

if (is_ordinal) {
errcode = asprintf(&hint_str, "%"PRIu64,
(uint64_t)(thunk->u1.Ordinal & ~IMAGE_ORDINAL_FLAG64));
(uint64_t)(thunk->u1.Ordinal & ~(IMAGE_ORDINAL_MASK(ctx))));

PEV_ABORT_IF(errcode == -1);

} else {
Expand Down Expand Up @@ -568,8 +568,8 @@ static void imphash_load_imported_functions(pe_ctx_t *ctx, uint64_t offset, char
pe_get_all_ord_lkp_func_name_with_hint(el, oleaut32_arr, hint);
} else if (strncmp(dll_name, "ws2_32", 6) == 0 && is_ordinal) {
pe_get_all_ord_lkp_func_name_with_hint(el, ws2_32_arr, hint);
}
else
}
else
{
if (is_ordinal) {
char* ord_str = NULL;
Expand Down Expand Up @@ -617,7 +617,7 @@ char *pe_imphash(pe_ctx_t *ctx, pe_imphash_flavor_e flavor) {
}

uint64_t ofs = pe_rva2ofs(ctx, va);

element_t *elt, *tmp, *head = NULL;
int count = 0;

Expand Down Expand Up @@ -666,7 +666,7 @@ char *pe_imphash(pe_ctx_t *ctx, pe_imphash_flavor_e flavor) {
free(dll_name);

// Restore previous ofs
ofs = aux;
ofs = aux;
}

LL_COUNT(head, elt, count);
Expand Down
24 changes: 12 additions & 12 deletions lib/libpe/imports.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
libpe - the PE library
Copyright (C) 2010 - 2017 libpe authors
This file is part of libpe.
libpe is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -54,7 +54,7 @@ static uint32_t get_dll_count(pe_ctx_t *ctx) {
break;

ofs += sizeof(IMAGE_IMPORT_DESCRIPTOR);

const uint64_t aux = ofs; // Store current ofs
ofs = pe_rva2ofs(ctx, id->Name);
if (ofs == 0)
Expand All @@ -70,7 +70,7 @@ static uint32_t get_dll_count(pe_ctx_t *ctx) {
ofs = aux; // Restore previous ofs
}

return count;
return count;
}

static uint32_t get_functions_count(pe_ctx_t *ctx, uint64_t offset) {
Expand All @@ -90,7 +90,7 @@ static uint32_t get_functions_count(pe_ctx_t *ctx, uint64_t offset) {
if (thunk_type == 0)
return count;

bool is_ordinal = (thunk_type & IMAGE_ORDINAL_FLAG32) != 0;
bool is_ordinal = (thunk_type & (IMAGE_ORDINAL_MASK(ctx))) != 0;

if (!is_ordinal) {
const uint64_t imp_ofs = pe_rva2ofs(ctx, thunk->u1.AddressOfData);
Expand All @@ -112,8 +112,8 @@ static uint32_t get_functions_count(pe_ctx_t *ctx, uint64_t offset) {
if (thunk_type == 0)
return count;

bool is_ordinal = (thunk_type & IMAGE_ORDINAL_FLAG32) != 0;
bool is_ordinal = (thunk_type & (IMAGE_ORDINAL_MASK(ctx))) != 0;

if (!is_ordinal) {
uint64_t imp_ofs = pe_rva2ofs(ctx, thunk->u1.AddressOfData);
const IMAGE_IMPORT_BY_NAME *imp_name = LIBPE_PTR_ADD(ctx->map_addr, imp_ofs);
Expand Down Expand Up @@ -169,11 +169,11 @@ static pe_err_e parse_imported_functions(pe_ctx_t *ctx, pe_imported_dll_t *impor
}

// If the MSB of the member is 1, the function is exported by ordinal.
is_ordinal = (thunk_type & IMAGE_ORDINAL_FLAG32) != 0;
is_ordinal = (thunk_type & (IMAGE_ORDINAL_MASK(ctx))) != 0;

if (is_ordinal) {
hint = 0;
ordinal = (thunk->u1.Ordinal & ~IMAGE_ORDINAL_FLAG32) & 0xffff;
ordinal = (thunk->u1.Ordinal & ~(IMAGE_ORDINAL_MASK(ctx))) & 0xffff;
} else {
const uint64_t imp_ofs = pe_rva2ofs(ctx, thunk->u1.AddressOfData);
const IMAGE_IMPORT_BY_NAME *imp_name = LIBPE_PTR_ADD(ctx->map_addr, imp_ofs);
Expand Down Expand Up @@ -209,11 +209,11 @@ static pe_err_e parse_imported_functions(pe_ctx_t *ctx, pe_imported_dll_t *impor
}

// If the MSB of the member is 1, the function is exported by ordinal.
is_ordinal = (thunk_type & IMAGE_ORDINAL_FLAG64) != 0;
is_ordinal = (thunk_type & (IMAGE_ORDINAL_MASK(ctx))) != 0;

if (is_ordinal) {
hint = 0; // No hint
ordinal = (thunk->u1.Ordinal & ~IMAGE_ORDINAL_FLAG64) & 0xffff;
ordinal = (thunk->u1.Ordinal & ~(IMAGE_ORDINAL_MASK(ctx))) & 0xffff;
} else {
uint64_t imp_ofs = pe_rva2ofs(ctx, thunk->u1.AddressOfData);
const IMAGE_IMPORT_BY_NAME *imp_name = LIBPE_PTR_ADD(ctx->map_addr, imp_ofs);
Expand Down Expand Up @@ -261,7 +261,7 @@ pe_imports_t *pe_imports(pe_ctx_t *ctx) {
}

imports->err = LIBPE_E_OK;

imports->dll_count = get_dll_count(ctx);
if (imports->dll_count == 0)
return imports;
Expand Down Expand Up @@ -330,7 +330,7 @@ pe_imports_t *pe_imports(pe_ctx_t *ctx) {
if (ofs == 0) {
break;
}

pe_err_e parse_err = parse_imported_functions(ctx, dll, ofs);
if (parse_err != LIBPE_E_OK) {
imports->err = parse_err;
Expand Down
5 changes: 4 additions & 1 deletion lib/libpe/include/libpe/pe.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
libpe - the PE library
Copyright (C) 2010 - 2017 libpe authors
This file is part of libpe.
libpe is free software: you can redistribute it and/or modify
Expand Down Expand Up @@ -57,6 +57,9 @@ extern "C" {

static const uint32_t IMAGE_ORDINAL_FLAG32 = 0x80000000;
static const uint64_t IMAGE_ORDINAL_FLAG64 = 0x8000000000000000;
#define IMAGE_ORDINAL_MASK(ctx) \
((ctx->pe.optional_hdr.type == MAGIC_PE32) ? \
IMAGE_ORDINAL_FLAG32 : IMAGE_ORDINAL_FLAG64)

#define SIGNATURE_PE 0x00004550 // PE\0\0 in little-endian

Expand Down

0 comments on commit b5a9a9f

Please sign in to comment.