最初发布在QQ空间: http://user.qzone.qq.com/31731705/blog/1305821803
函数指针的值不是函数地址? 介绍了内部的函数是如何通过ILT调用的,这次说说那些使用DLL import 进来的函数又是怎样调用的?
typedef HANDLE (FAR WINAPI *PLL)( LPCWSTR );
HANDLE WINAPI TestFunctionPointer( PLL pll, LPCWSTR wstr )
{
HANDLE h = (*pll)(wstr);
return h;
}
void TestImportFunction()
{
static const wchar_t dll[] = L"kernel32";
HANDLE (FAR WINAPI *pll)( LPCWSTR ) = 0;
HANDLE (WINAPI *pTest)( PLL, LPCWSTR ) = 0;
DWORD_PTR pfun = 0;
// call import function directly
HANDLE h = LoadLibraryW( dll );
FreeLibrary( h );
// call my function directly
h = TestFunctionPointer( LoadLibraryW, dll );
FreeLibrary( h );
// call my function by pointer
pTest = TestFunctionPointer;
h = (*pTest)( LoadLibraryW, dll );
FreeLibrary( h );
// call import funciton by GetProcAddress
pll = GetProcAddress( GetModuleHandleW( dll ), "LoadLibraryW" );
h = (*pll)( dll );
//DWORD_PTR
pfun = TerminateProcess;
pfun = GetProcAddress( h, "TerminateProcess" );
FreeLibrary( h );
}
写了上述代码进行观察,首先看看最开始的2个函数调用,
00411d83 8bf4 mov esi,esp
00411d85 686c6b4100 push offset testC!dll (00416b6c)
00411d8a ff15eca14100 call dword ptr [testC!_imp__LoadLibraryW (0041a1ec)]
00411d90 3bf4 cmp esi,esp
00411d92 e808f4ffff call testC!ILT+410(__RTC_CheckEsp) (0041119f)
00411d97 8945d4 mov dword ptr [ebp-2Ch],eax
00411d9a 8bf4 mov esi,esp
00411d9c 8b45d4 mov eax,dword ptr [ebp-2Ch]
00411d9f 50 push eax
00411da0 ff15e8a14100 call dword ptr [testC!_imp__FreeLibrary (0041a1e8)]
00411da6 3bf4 cmp esi,esp
00411da8 e8f2f3ffff call testC!ILT+410(__RTC_CheckEsp) (0041119f)
最关键的是2条call指令,取一条分析一下call指令的目标,