Comments (6)
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.
I haven't checked the code, but I suspect this is related to merces/libpe@5737a97 and merces/libpe#34.
from readpe.
I suspect this segmentation fault is happening because:
calloc
is called using a huge value (exp->NumberOfFunctions
) as first argument atpe_exports
function @libpe
which causesexports->functions
being set toNULL
;
─────────────────────────────────────────────[ 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
.
- The
main
(actuallyprint_exports
) function does not handle the catched error frompe_exports
and tries to dereference an invalid pointer, read the dword at0x18
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.
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.
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.
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)
- Crud in sourceforge tarball HOT 12
- Peres -v shows a lot of useless (debug) info. Is this intentional? HOT 4
- build failed in windows HOT 2
- Compiling with flat namespace causes build for Homebrew to fail HOT 6
- It occurred ERROR when I make pev in Linux. HOT 4
- AVX / AVX2 / AVX512 support HOT 1
- Project name change? HOT 6
- readpe: garbage in Date/time stamp output HOT 1
- Update list of known machine types HOT 3
- Truncated section names HOT 3
- lib/libpe/hashes.c: `pe_err_e get_headers_optional_hash()` calls `exit()` instead of returning a proper return value.
- pesec: fails to properly read PE file on s390x HOT 3
- readpe: symbol lookup error: /usr/lib/libpe.so.1: undefined symbol: _ZGVdN4v_log2 HOT 12
- Support for NE files HOT 3
- _FORTIFY_SOURCE level downgrading HOT 1
- Broken tests HOT 1
- Version bump HOT 1
- Windows binary included in readpe with no source HOT 4
- v0.83 re-release? HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from readpe.