So based on my knowledge on windows apps, as far as i know the IAT gets filled with correct addresses when the library gets loaded (correct me if I'm wrong)

now in linux, they use GOT, and again based on my knowledge the GOT gets filled in run time by default, meaning first we jump into PLT, then the first time i use a function (for example puts) we first call the dynamic loader by jumping in the beginning of PLT and that fills the corresponding address in GOT, and next time i call puts then i directly jump into it after going into PLT

so this means that by default, windows fills all the addresses in the IAT in load time but linux doesn't, correct?

and if so, then isn't this a security risk for linux? because in windows IAT is inside the rdata section and is read only, but in linux is read and write! and for example if we have a format string exploit then we can write on GOT but this doesnt happen in windows, am i missing something here?

1 Answer 1


You understanding is correct:

  • PE's IAT is resolved by the system loader and can be made read-only afterwards.

  • ELF's GOT entries initially point to PLT stubs and are overwritten with the final address on the first call.. meaning GOT needs to remain writable.

Writable GOT is indeed a known source of vulnerabilities which is why mitigations like RELRO have been introduced.

Note that PEs can also use delay-loaded imports which work similar to GOT+PLT (resolution on first call) and may be subject to similar issue.

  • 1
    But why they didn't load the entire thing by default? considering windows does it and there is no big performance impact, why not just do it and improve security?
    – OneAndOnly
    Commented Nov 14, 2019 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.