Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Parser::parse crashes for PE files on Windows 7 #998

Closed
rdbo opened this issue Nov 20, 2023 · 5 comments
Closed

Parser::parse crashes for PE files on Windows 7 #998

rdbo opened this issue Nov 20, 2023 · 5 comments
Assignees
Labels
bug Parser PE Premium This is a premium issue

Comments

@rdbo
Copy link
Contributor

rdbo commented Nov 20, 2023


Description

When calling Parser::parse on Windows 7 for a PE file, the program crashes, giving the error:

cannot seek array iterator after end

I need this fixed because my memory library relies on LIEF for dumping symbols.

Context

LIEF version: latest commit as of now: df97777
OS: Windows 7 x64
Visual Studio Build Tools 2022 (building for x86)
My contribution to get this premium issue (merged PR that fixes compilation error on Windows): #949


Code that crashes (from my rdbo/libmem repo):

#include <LIEF/PE.hpp>

using namespace LIEF::PE;

LM_PRIVATE lm_bool_t
_LM_EnumPeSyms(lm_module_t *pmod,
	       lm_bool_t  (*callback)(lm_symbol_t *psymbol,
				      lm_void_t   *arg),
	       lm_void_t *arg)
{
	lm_symbol_t sym;
	std::unique_ptr<const Binary> binary;

	if (!is_pe(pmod->path))
		return LM_FALSE;

	binary = Parser::parse(pmod->path); /* <----- CRASH HERE, pmod->path is a valid PE */

	for (const ExportEntry &symbol : binary->get_export()->entries()) {
		sym.name = (lm_cstring_t)symbol.name().c_str();
		sym.address = (lm_address_t)LM_OFFSET(pmod->base, symbol.value());
		if (!callback(&sym, arg))
			break;
	}

	return LM_TRUE;
}

Error:
2023-11-19_21-31-18

@rdbo rdbo added the Premium This is a premium issue label Nov 20, 2023
@romainthomas
Copy link
Member

Can you attach the binary?

@rdbo
Copy link
Contributor Author

rdbo commented Nov 20, 2023

@romainthomas Minimal reproducible exemple below, already compiled.
main.cpp:

#include <LIEF/PE.hpp>

using namespace LIEF::PE;

typedef struct {
        char *name;
        void *address;
} symbol_t;

bool enum_symbols(char *path, bool callback(symbol_t *, void *), void *arg)
{
        symbol_t sym;
        std::unique_ptr<const Binary> binary;

        if (!is_pe(path))
                return false;

        binary = Parser::parse(path);

        for (const ExportEntry &symbol : binary->get_export()->entries()) {
                sym.name = (char *)symbol.name().c_str();
                sym.address = (void *)symbol.value();
                if (!callback(&sym, arg))
                        break;
        }

        return true;
}

bool callback(symbol_t *sym, void *arg)
{
        printf("  %s %p\n", sym->name, sym->address);
        return true;
}

int main(int argc, char **argv)
{
        if (argc < 2) {
                printf("missing binary path argument\n");
                return -1;
        }

        printf("Symbols: \n");
        enum_symbols(argv[1], callback, NULL);

        return 0;
}

NOTE: The file extension is tar.xz, GitHub won't let me upload tar.xz and tar.gz is too big.
Extract with: tar -xvf <file>.tar.gz
lief-test.tar.gz

@rdbo
Copy link
Contributor Author

rdbo commented Nov 20, 2023

@romainthomas Even in this example, it just crashes upon calling Parser::parse with a valid path (main.exe).

@romainthomas
Copy link
Member

It has been fixed [...]

@rdbo
Copy link
Contributor Author

rdbo commented Nov 21, 2023

I just tested and the fix worked, but I had to change my code a bit.
binary->get_export() will return NULL if there are no exports, so I had to add a check for that.
Anyways, thank you for the fix 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Parser PE Premium This is a premium issue
Projects
None yet
Development

No branches or pull requests

2 participants