Git Product home page Git Product logo

Comments (6)

GoGoOtaku avatar GoGoOtaku commented on June 11, 2024 2

The issue here is in libpe.
This executable has no sections (as everything is overlapping inside the header. It's more art than software; this exe does not run in wine btw).
The RVA for the export table is 0x55555555 which would be well outside the image. The issue is in pe_rva2ofs

        if (rva == 0 || ctx->pe.sections == NULL)
                return 0;

[...]
        // This is impossible to reach
        return rva; // PE with no sections, return RVA

pe.sections is always NULL when there are no sections as this is the code that allocates it:

        if (ctx->pe.num_sections > 0) {
                ctx->pe.sections = malloc(ctx->pe.num_sections
                        * sizeof(IMAGE_SECTION_HEADER *));

This causes pe_rva2ofs to always return 0 which is then used to check if the data directory can be reached which it obviously always can when the VA starts at 0 as well.

This doesn't really happen outside of artificial executables like this since virtually every executable will at least have a .text or similar section so code can be run.
Remember how I said that Wine doesn't run this? While I don't want to debug this exe in wine deeper, the exe (not wine) segfaulted instantly. My assumption is that the wine loader refuses to run code in the header "section"; as it frankly should and I would be shocked if a modern Windows would run this. Especially since the header is also used like .bss/.data which just begs for arbitrary code execution bugs.
I will let pe_rva2ofs return the RVA directly if pe.sections or pe.num_sections is zero, do some testing on it and submit a merge request within a couple of days. It should at least not segfault.

from readpe.

jweyrich avatar jweyrich commented on June 11, 2024

I haven't checked the code, but I suspect this is related to merces/libpe@5737a97 and merces/libpe#34.

from readpe.

saullocarvalho avatar saullocarvalho commented on June 11, 2024

I suspect this segmentation fault is happening because:

  1. calloc is called using a huge value (exp->NumberOfFunctions) as first argument at pe_exports function @ libpe which causes exports->functions being set to NULL;
─────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────
 ► 0x7ffff7f83b62 <pe_exports+386>    call   calloc@plt <calloc@plt>
        nmemb: 0x69703afb
        size: 0x20
 
   0x7ffff7f83b67 <pe_exports+391>    mov    qword ptr [r13 + 0x18], rax
   0x7ffff7f83b6b <pe_exports+395>    test   rax, rax
   0x7ffff7f83b6e <pe_exports+398>    je     pe_exports+1133 <pe_exports+1133>

https://github.com/merces/libpe/blob/5f44724e8fcdebf8a6b9fd009543c9dcfae4ea32/exports.c#L93-L98

Then, according to the above snippet, exports->err is set to LIBPE_E_ALLOCATION_FAILURE (the error is catched) and the function pe_exports returns exports.

  1. The main (actually print_exports) function does not handle the catched error from pe_exports and tries to dereference an invalid pointer, read the dword at 0x18 address.
────────────────────────────────────────────[ REGISTERS ]────────────────────────────────────────────
 RAX  0x69703afb
 RBX  0x0
 RCX  0x55555555f360 —▸ 0x555555560470 ◂— 0x0
 RDX  0x69703afb
 RDI  0x55555555f010 ◂— 0x1
 RSI  0x4
 R8   0x0
 R9   0x12
 R10  0x7ffff7fc1005 ◂— 0x3a7325732a25000a /* '\n' */
 R11  0x246
 R12  0x7fffffffdbd0 —▸ 0x55555555f310 ◂— '/usr/local/lib/pev/plugins'
 R13  0x555555560980 ◂— 0xffffffe9
 R14  0x7fffffffdcd0 ◂— 0x0
 R15  0x0
 RBP  0x55555555f410 ◂— 0x1000000000000
 RSP  0x7fffffffdba0 —▸ 0x7ffff7949460 (__fork_generation) ◂— 0x0
*RIP  0x555555558410 (main+7168) ◂— cmp    dword ptr [rbx + 0x18], 0
─────────────────────────────────────────────[ DISASM ]──────────────────────────────────────────────
   0x55555555840c <main+7164>    add    rbx, qword ptr [r13 + 0x18]
 ► 0x555555558410 <main+7168>    cmp    dword ptr [rbx + 0x18], 0
   0x555555558414 <main+7172>    je     main+7142 <main+7142>

https://github.com/merces/pev/blob/072085d5e656915f3e6c3107189233b4052a988b/src/readpe.c#L792-L794

The segmentation fault occurs when readpe tries to get the func->address value. As func is NULL, the code tries to dereference an invalid pointer (0x18).

from readpe.

saullocarvalho avatar saullocarvalho commented on June 11, 2024

How should the error be handled?
As print_export does not return any value, how the main fuction would be aware of an error in it?

Should errors in the print_* functions be ignored, they only return to main, or cause main to return EXIT_FAILURE as occurs at the following snippet?

https://github.com/merces/pev/blob/072085d5e656915f3e6c3107189233b4052a988b/src/readpe.c#L878-L891

from readpe.

merces avatar merces commented on June 11, 2024

Hi @saullocarvalho and @i0gan . Thanks for raising this issue. I believe we should print a warn to the user. This could be done in the print_export function itself. Does it sound coherent?

Thanks.

from readpe.

merces avatar merces commented on June 11, 2024

Another thing came to mind here.. we can also set a limit for, let's say 65535 exported functions. I can't imagine a valid PE with such a huge number of functions to be honest.

from readpe.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.