Last year, I released an IDB for a piece of large, complex malware written in C++, which made regular use of virtual functions, which produce patterns of indirect call instructions like the ones your question discusses. I conducted that analysis purely statically, and I may release more IDBs like it later this year that were also done via static analysis.
The short answer to your question is that you need to figure out where the indirect calls will resolve at runtime. C++ VTables make this process especially simple. If you can figure out the base type that is being used at the site of the indirect call, then according to the rules of the C++ type system, any class derived from that base type might legally be substituted for that base type at runtime. In other words:
- Reconstruct the inheritance hierarchy for the program under analysis.
- For each class with a VTable, determine the address of its corresponding VTable.
- While analyzing the program, determine the reach of the types used in the program.
- At the call site of any given indirect call, combine all of the above information to determine the set of types that might be used, the addresses of the VTables for those types, and consequently the set of destinations for the indirect call.