If a packer or crypter is used to obfuscate a piece of executable code, it seems that calls and references made in that code will not be updated at load-time and will be incorrect when the code is unpacked or unencrypted! How does a packer or crypter deal with this problem?
Modern packers will handle this in the same way as the Windows PE loader: by implementing relocations.
.reloc section in a PE file (documentation here) holds details about which addresses need to be “fixed up” if the image cannot be loaded at the preferred address. This is referenced in the standard PE header.
A packer can read this data and implement relocations. How the packer handles this will be implementation specific. Perhaps it will store the original relocations somewhere in the packed executable, or store them in a custom format.
It is also possible to strip relocations, leaving a PE file that is not ASLR aware, as if it were never compiled with
/DYNAMICBASE. A packer could choose to do this instead of implementing relocations.
You can read a lot more details in this ReverseEngineering.SE post about the layout in the PE section.