Function call mystery

Source: Internet
Author: User

Initially released in the QQ space: http://user.qzone.qq.com/31731705/blog/1305821803

Isn't the value of the function pointer A function address?This article introduces how internal functions are called through ILT. How are the functions imported Using DLL called?

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 );}

Write the above Code to observe, first look at the first two function calls,

00411d83 8bf4 mov ESI, ESP
00411d85 686c6b4100 push offset testc! DLL (00416b6c)
00411d8aFf15Eca14100Call 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
00411da0Ff15E8a14100Call dword ptr [testc! _ Imp _ freelibrary (0041a1e8)]
00411da6 3bf4 cmp esi, ESP
00411da8 e8f2f3ffff call testc! ILT + 410 (_ rtc_checkesp) (0041119f)

The most important thing is two call commands, which take one to analyze the target of the Call Command,

0: 000> ln 0041a1ec
(0041a1ec) testc! _ Imp _ loadlibraryw | (0041a1f0) testc! _ Imp _ getmodulefilenamew
Exact matches:
0: 000> dd 0041a1ec L1
0041a1ec 77153c01
0: 000> ln 77153c01
(77153c01) Kernel32! Loadlibraryw | (77153c1b) Kernel32! Getenvironmentvariablew
Exact matches:
Kernel32! Loadlibraryw = <no type information>

Visible,[Testc! _ Imp _ loadlibraryw (0041a1ec)]AndDword ptr [testc! _ Imp _ freelibrary (0041a1e8)]In fact, they are all addresses in the. idata section, and their content isLoadlibrarywAndFreelibraryThe actual function address.

Next is an internal function, which is called directly and through the function pointer,

00411dad 686c6b4100 push offset testc! DLL (00416b6c)
00411db2 a1eca14100 mov eax,Dword ptr [testc! _ Imp _ loadlibraryw (0041a1ec)]
00411db7 50 push eax
00411db8E8B4f4ffffCall testc! ILT + 620 (_ testfunctionpointer (00411271)
00411dbd 8945d4 mov dword ptr [ebp-2Ch], eax
......
00411dd3 c745ec71124100 movDword ptr [ebp-14h], offset testc! ILT + 620 (_ testfunctionpointer (00411271)
00411dda 8bf4 mov ESI, ESP
00411ddc 686c6b4100 push offset testc! DLL (00416b6c)
00411de1 a1eca14100 mov eax,Dword ptr [testc! _ Imp _ loadlibraryw (0041a1ec)]
00411de6 50 push eax
00411de7Ff55ECCall dword ptr [ebp-14h]
00411dea 3bf4 cmp esi, ESP
00411dec e8aef3ffff call testc! ILT + 410 (_ rtc_checkesp) (0041119f)
......

AsThe value of the function pointer is not the Function address.FunctionTestfunctionpointerWhether it is direct or indirect call through the function pointer, ILT is used.

Note that the data in. idata section (Dword ptr [testc! _ Imp _ loadlibraryw (0041a1ec)]). That is to say, the direct call or pointer call of the imported functions are all accessed. data in the idata Section Address ,. the idata section is equivalent to a transit and stores the corresponding real function address. However, the position of the idata section itself is obviously module-related.

However, there are still 3rd calling methods, getprocaddress, continue to analyze the remaining code,

00411e07 8bf4 mov ESI, ESP
00411e09 68706c4100 push offset testc! 'String' (00416c70)
00411e0e 8bfc mov EDI, ESP
00411e10 686c6b4100 push offset testc! DLL (00416b6c)
00411e15Ff1548a24100Call dword ptr [testc! Kernel32_null_thunk_data (0041a248)]
00411e1b 3bfc cmp edi, ESP
00411e1d e87df3ffff call testc! ILT + 410 (_ rtc_checkesp) (0041119f)
00411e22 50 push eax
00411e23Ff15E4a14100Call dword ptr [testc! _ Imp _ getprocaddress (0041a1e4)]
00411e29 3bf4 cmp esi, ESP
00411e2b e86ff3ffff call testc! ILT + 410 (_ rtc_checkesp) (0041119f)
00411e30 8945f8 mov dword ptr [ebp-8], eax
00411e33 8bf4 mov ESI, ESP
00411e35 686c6b4100 push offset testc! DLL (00416b6c)
00411e3aFf55F8Call dword ptr [ebp-8]
00411e3d 3bf4 cmp esi, ESP
00411e3f e85bf3ffff call testc! ILT + 410 (_ rtc_checkesp) (0041119f)
00411e44 8945d4 mov dword ptr [ebp-2Ch], eax

The call at the beginning of the Code is called.GetmodulehandlewBecause it is an import function, the call is still transitioned from. idata.

0: 000> ln 0041a248
(0041a248) testc! Kernel32_null_thunk_data | (0041a28c) testc! _ Imp ___ crtsetcheckcount
0: 000> D 0041a248 L4
0041a248 7715374d 00000000 00000000 00000000
0: 000> ln 7715374d
(7715374d) Kernel32! Getmodulehandlewstub | (7715375d) Kernel32! Createthreadstub
Exact matches:
Kernel32! Getmodulehandlewstub = <no type information>

Run the following command to check the returned value,

0: 000> dd [ebp-8] L1
0012fe54 77153c01

0: 000> dv
PLL = 0x77153c01

0: 000> ln poi (PLL)
(77153c01) Kernel32! Loadlibraryw | (77153c1b) Kernel32! Getenvironmentvariablew
Exact matches:
Kernel32! Loadlibraryw = <no type information>

VisibleGetprocaddressWhat we get is the real address of the function, and the function call or pointer call are all intermediate in the. idata section.

Some interesting things are also found throughout the process,

0: 000> X testc! Loadli *
00412d24 testc! Loadlibraryw = <no type information>
0: 000> X testc! Term *
00414d56 testc! Terminate = <no type information>
00412d12Testc! Terminateprocess = <no type information>
0: 000> U 412d12 L4
Testc! Terminateprocess:
00412d12 ff25e0a14100 jmp dword ptr [testc! _ Imp _ terminateprocess (0041a1e0)]
Testc! Getprocaddress:
00412d18 ff25e4a14100 jmp dword ptr [testc! _ Imp _ getprocaddress (0041a1e4)]
Testc! Freelibrary:
00412d1e ff25e8a14100 jmp dword ptr [testc! _ Imp _ freelibrary (0041a1e8)]
Testc! Loadlibraryw:
00412d24 ff25eca14100 jmp dword ptr [testc! _ Imp _ loadlibraryw (0041a1ec)]

That is to say, the testc module also implements these functions, although the content is a simple JMP command.

I tried to use some commands to find out who was using them, but it was a pity.

0: 000> LM test
Start end module name
00400000 0041c000 testc Thu May 19 13:47:03 2011 (4dd4aed7)
0: 000> s-d 400000 l1c000 412d12
0: 000> s-d 400000 l1c000 412d24

Later I found that this method was futile because of the complexity of the x86 commands, and the simple search target address could not achieve my goal. After observing it with Ida, we found a new one,

. Text: 00412d24
. Text: 00412d24; ================== s u B r o u t I n e ====================== ======================================
. Text: 00412d24
. Text: 00412d24; attributes: thunk
. Text: 00412d24
. Text: 00412d24; hmodule _ stdcall loadlibraryw (lpcwstr lplibfilename)
. Text: 00412d24 _ loadlibraryw @ 4 proc near;Code xref: loadlibraryw (x) j
. Text: 00412d24
. Text: 00412d24 lplibfilename = dword ptr 4
. Text: 00412d24
. Text: 00412d24 000FF 25 EC A1 41 00Jmp ds :__ imp _ loadlibraryw @ 4; loadlibraryw (X)
. Text: 00412d24 _ loadlibraryw @ 4 endp
. Text: 00412d24
This code is used by someone. The code that uses this code is actually,

. Text: 004110f5
. Text: 004110f5; ================== s u B r o u t I n e ====================== ======================================
. Text: 004110f5
. Text: 004110f5; attributes: thunk
. Text: 004110f5
. Text: 004110f5; hmodule _ stdcall loadlibraryw (lpcwstr lplibfilename)
. Text: 004110f5 J _ loadlibraryw @ 4 proc near
. Text: 004110f5 000 E9 2a 1C 00 00 JMP _ loadlibraryw @ 4; loadlibraryw (X)
. Text: 004110f5 J _ loadlibraryw @ 4 endp
. Text: 004110f5
Is an ILT code,

0: 000> ln 4110f5
(004110f5) testc! ILT + 240 (_ loadlibraryw | (004110fa) testc! ILT + 245 (_ heapsetinformation
Exact matches:
0: 000> U 4110f5
Testc! ILT + 240 (_ loadlibraryw:
004110f5E92a1c0000 JMP testc! Loadlibraryw (00412d24)
Testc! ILT + 245 (_ heapsetinformation:
004110faE98d3c0000 JMP testc! Heapsetinformation (00414d8c)
......

The compiler also implements ILT for these functions, but even from IDA, there is no trace of these ILT being used.

Finally, let's make a summary,

  1. Directly calling the import function or indirectly calling the import function through a pointer is essentially calling the real function by accessing the data in the. idata section. HoweverGetprocaddressYou can obtain the actual function address.
  2. The execution module itself also defines some corresponding import functions and their ilts, But it is strange that no code uses them.

Finally, it is quite complicated to mention the x86 commands. if you carefully observe the assembly code above, you will find that the same call command has a variety of machine codes, from ff15, E8, such as ff55 and JMP commands, such as ff25 and E9. This is a good article,How to crack x86 commands.

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.