nikolatesla20
November 2nd, 2003, 10:38
What I usually do is note down the address that ImpREC says the import is in the table.
Now, run the program again, and go into SoftICE. Switch to the program's context using the ADDR command in softice (ADDR <processname>

. Then go to the address that ImpREC reported (DD <address>

. The value you now see in the data window at the first location on the top left is the value stored at the location ImpREC reported. This is ANOTHER address, which points the the "imported" function. However, it probably points to a protector routine instead.
So, just go to THIS address now, so you can see what the code looks like. If it's not being resolved, it's obviously another type of routine in the protector, right? Well, you can just look at the code and figure out where it goes eventually !
Do a (U <address from import table>

. Now you're looking at the code thats gets called when this import runs. How does it look? Does it jump somewhere else? Does it simply move in a value from another memory location and return? Having some knowledge of ASM is necessary for this work. If it's moving a value in from another location you can sometimes just (DD <location>

to see what the value is. From that you can extrapolate what the routine should be, most windows API's, like GetCurrentThreadId(), return a specific value. For example, suppose you see a weird value. It COULD be a value from GetCurrentThreadId(). Well, you can type the PROC command in SoftICE and it will list all processes and their thread ID's - so you can see what your program's thread ID is and compare it with that value you saw to see if that's what it is! That's just one example. To find out if it's the GetCommandLine(), simply follow the value one more time like it's an address (cause GetCommandLine returns a pointer). Type in (DD <value found again>

and see if you land in a text string for the command line. If so, the API should be GetCommandLineA(), etc.
Note the above examples are for when the "Import" is simply a register or memory value being moved into EAX and then returning. If not, you can look at the ASM and figure out what it's doing before the routine does a RET. Some routines, you can simply look at the last API called before the RET. Others calculate where to go, so you have to grab a hex calculator and figure out where it's gonna land.
Those are the techniques I use all the time for unresolved imports.
-nt20