Reputation: 91
I have a binary file analyzed with IDA where the function calls look like this:
.text:0000000180063039 48 FF 15 90 78 11 00 call cs:__imp_CopyFileW
I'm trying to understand how does IDA convert the sequence of bytes 48 FF 15 90 78 11 00
into the call instruction of the specific function. I guess that 48
stands for far call opcode and the last 6 bytes is something like an offset counted by the compiler in a special way.
So what do other 6 bytes actually stand for and how to manually count the needed function offset?
P.S. Please, let me know if any additional information (function offset, segment start address, etc.) is needed to clarify the topic
Upvotes: 0
Views: 329
Reputation: 13689
Looks like it is an indirect call by a pointer from import address table.
In an executable image (exe or dll), there's a part that contains pointers to all imported functions, called IMAGE_DIRECTORY_ENTRY_IAT
. The call uses indirect address from that table.
Usually¹ this information is filled on load time, when this module is loaded. The loader uses IMAGE_DIRECTORY_ENTRY_IMPORT
to know module names and function names² for pointers in IMAGE_DIRECTORY_ENTRY_IAT
. So marking the part with pointers as IMAGE_DIRECTORY_ENTRY_IAT
is optional, as it can be reached via IMAGE_DIRECTORY_ENTRY_IMPORT
.
A disassembler can use the same information from IMAGE_DIRECTORY_ENTRY_IMPORT
to know the function name for each imported pointer.
(There's an official spec for Portable Executable file format; linked some parts of this answer to it)
¹ There can be delay imports (when these pointers resolved later than load time) or bound imports (when these pointers have expected value based on assumption that a specific module is likely to load at specific address), but they don't make much difference.
² If functions are imported by name. They can be imported by ordinal number instead.
Upvotes: 4