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

PE: handle empty import address table #371

Open
Tracked by #434
williballenthin opened this issue Jun 6, 2023 · 2 comments
Open
Tracked by #434

PE: handle empty import address table #371

williballenthin opened this issue Jun 6, 2023 · 2 comments

Comments

@williballenthin
Copy link

williballenthin commented Jun 6, 2023

This PE file has a valid import lookup table but the pointer to the import address table is 0x0:

image

goblin currently supports handling empty import lookup tables but not empty import address tables:

goblin/src/pe/import.rs

Lines 189 to 191 in 9f7fb6b

pub import_lookup_table: Option<ImportLookupTable<'a>>,
/// Computed
pub import_address_table: ImportAddressTable,

Could we extend goblin to handle the above case (parse synthentic entries from the import lookup table when the import address table is 0x0)?

@m4b
Copy link
Owner

m4b commented Jul 5, 2023

If you understand the issue and might be willing to fix, a PR would be appreciated :)

@kkent030315
Copy link
Contributor

kkent030315 commented Nov 4, 2024

@williballenthin Hi there, I'm addressing this issue in #430. Due to the fact that I do not have an access to VT memberships, so if you do not mind, mind share the sample 0000bab1a3b04d3013d126e4621abfe7ec87ba0eafac01a53ac51c4db747f65a privately so I could take a look into this issue more deeply?

It looks like a malware which I am capable to handle and at the time I assume the import entries in question are added intentionally by something other than generic linkers, since OFTs from the last valid FT entry 0x2D2B0 and the next zero-FT entry 0x2F0C8 gap (0x1E18) is too far (even different pages, for just 18 entries?) from what it should be calculated in how generic linkers do (the rest entries as well). So I assume it is not what generic linkers do and it looks like how "bad" PE packers do.

My asseumption could be probed by looking at the real use of those entries (__imp_* in IDA) maybe, if you cannot share the sample, that is what I want to know, to know 1) if this fix is actually valuable and effective in minor patches, and 2) to know if this could be reproducible in generic toolchains (or PE packers do).

Please do not heistate to point out if I am wrong. Please correct me :). Thanks!


TODO: CRT never generates only 5 entries in IAT and only OFTs are valid are weird at all, so I am pretty sure it is PE packers work where it is purposely puts IAT stubs around the first imports and let Windows loader load the dependencies at the mapping time so the image will be guaranteed to be loaded at the code executes and it can do like Peb()->Ldr and GetProcAddress to dynamically resolve imports.

For similar cases, VMProtect do the similar, it leaves only one import entries for each DLLs to keep the original behaviours as possible as it can for compatibility. I guess similar but more "bad" PE packers like how idiot malware developers do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants