Implement Inline hook and inlinehook under existing software shelling Protection

Source: Internet
Author: User

Implement Inline hook and inlinehook under existing software shelling Protection
If not, please forgive me. I am at a limited level.

Resume and level :. Http://www.cnblogs.com/hackdragon/p/3662599.html

Normal situation:

After receiving a project to obtain the screen output content, the OD is loaded and XX shelling protection is discovered, normally, use jmp to jump to your own code and use the CHookApi_Jmp class source code used by the predecessors at http://www.cnblogs.com/showna/articles/850279.html. (I changed CHookApi_Jmp to CHookApi when I used it.) Of course, I intercepted the rendering function TextOutA of the target program, so the code is as follows:

// Original function declaration // _ gdi_entry wingdiapi bool winapi TextOutA (_ in HDC hdc, _ in int x, _ in int y, _ in_ecount (c) lpstr lpString, _ in int c); // global initialization class CHookApi m_HookTextOutA; // your own function bool winapi FuncJMP_TextOutA (HDC hdc, int x, int y, lpstr lpString, int c) {m_HookTextOutA.SetHookOff (); // close the HOOK and call the original WINAPI by yourself {// Do What You Want} int Func_Ret = TextOutA (hdc, x, y, lpString, c); m_HookTextOutA.SetHookOn (); // enable the HOOK function to intercept the callback function return Func_Ret;} // initialize void Func_Init () // {m_HookTextOutA.Initialize (_ T ("Gdi32.dll"), "TextOutA", (FARPROC) Hook_FuncTextOutA); m_HookTextOutA.SetHookOn ();}

Under normal circumstances, the Inline hook has been completed, but because the software shelling protects the first five bytes of the TextOutA function, our jmp transfer method will not work. After you finish the modification, he will modify it back for you, cause program exceptions.

Find a solution:

So OD tracked down and found that the other DLL he continued to call was under software protection. Only dynamic links were not protected. I was too lazy and did not like to continue tracking. So I thought for a moment, he protected the first few bytes, but he could not protect them all. So he looked down at the assembly code (GDI32.dll of win7 ).

Now that the next function is called, the E8 (CALL) is followed by four bytes. Now, I think I can tamper with this address to my function, I have read the GDI32 code of Version X.

They found that the position from TextOutA function header to E8 is not the same. Specifically

WIN7 089D-0878 = 0x25 (offset)

XP BA7C-BA4F = 0x2D (offset)

The offset of the two is obviously different. What should we do? If there are other versions of GDI32, isn't it the same. Therefore, we thought of the following solutions.

Solution:

To implement inline hook, first we need to know the memory address we want to modify, and then the original function address. The following function is used to obtain our address.

DWORD GetGDI32_TextOutAEx (DWORD & dwHook, DWORD & dwCall) {// obtain the address of the TextOutA function or directly TextOutA DWORD dwGDI32TextOutA = (DWORD) getProcAddress (GetModuleHandle (_ T ("Gdi32.dll"), "TextOutA"); // convert BYTE * lpBuf = (BYTE *) dwGDI32TextOutA; // compare each byte for (int I = 0; I <0x30; I ++) {DWORD dwAddress = (DWORD) (& lpBuf [I]); // byte address DWORD dwFind = * (DWORD *) (dwAddress ); // convert and obtain the content. // Why is 0xE80875FF? The memory content can be viewed on the OD. // the previous part of this function is push. Dword ptr ss: [ebp + 0x8] followed by CALL // the corresponding memory binary is 0xE80875FF. if (dwFind = 0xE80875FF) {// The current address + 3 is the E8 dwHook = dwAddress + 3; // because the calculation method of "CALL to where" is to calculate the difference between two addresses // we need to take the four bytes of content after the CALL // The current address + 4 that is DWORD dwNow = dwAddress + 4 after E8; // read this value DWORD dwOff = * (DWORD *) (dwNow); // Add it to the current address + (think about why it is +) // In + 4, the actual memory address of the CALL is obtained because it occupies 4 Bytes: dwCall = dwNow + dwOff + 4. Return 1 ;}} return 0 ;}

Add a function to our CHookApi.

BOOL CHookApi::InitializeE8(FARPROC lpOldFunc, FARPROC lpNewFunc){    m_lpHookFunc = lpOldFunc;    hProc = GetCurrentProcess();    DWORD dwOldFlag;    if(VirtualProtectEx(hProc,m_lpHookFunc,5,PAGE_READWRITE,&dwOldFlag))     {          memcpy_s(m_OldFunc,5,m_lpHookFunc,5);        //if(ReadProcessMemory(hProc,m_lpHookFunc,m_OldFunc,5,0))          {               if(VirtualProtectEx(hProc,m_lpHookFunc,5,dwOldFlag,&dwOldFlag))               {                    m_NewFunc[0]=0xE8;                    DWORD *pNewFuncAddress;                    pNewFuncAddress=(DWORD*)&m_NewFunc[1];                    *pNewFuncAddress=(DWORD)lpNewFunc-(DWORD)m_lpHookFunc-5;                    return TRUE;               }          }    }    return FALSE;}

He used to be E9 (JMP), so we need to implement our own CALL, so we use E8, in fact, I am just lazy. Because it turns out to be E8, we only need to write the offset of our function.

Implementation process:
// Global initialization class CHookApi m_HookTextOutAEx; // address to be hooked DWORD dwHook; // address of the original call dword dwCall; // function int WINAPI FuncJMP_TextOutEx (HDC hdc, int x, int y, int A, int B, LPCSTR lpString, int c, int C, int D) {// processing function form typedef int (_ stdcall * MyTextOut) (HDC hdc, int x, int y, int A, int B, LPCSTR lpString, int c, int C, int D); // function pointer MyTextOut TextOutStr = (MyTextOut) dwCall; // call int Ret = TextOutStr (hdc, x, y, A, B, lpString, c, C, D ); // obtain the returned address DWORD * Ptr = (DWORD *) & D; if (Ptr [2] = 0x12345678) // you can add it here to improve performance, determine whether the output content you want to intercept depends on the returned address {// Do What You Want} return Ret;} // initialize void Func_Init2 () at an appropriate location () // {GetGDI32_TextOutAEx (dwHook, dwCall); m_HookTextOutAEx.InitializeE8 (FARPROC) dwHook, (FARPROC) FuncJMP_TextOutEx); callback ();}

Function parameter judgment can be handled by myself based on the push situation, and I will handle it at will. I don't know what to do with several parameters.

Conclusion:

For protected software, if it is not shelled, you can achieve your own goal through a curve. For other software with memory verification, you can insert code based on its corresponding calls to other unprotected APIs. It is the second technical article on my cnblog. Correct the incorrect description. My QQ: 78486367


Questions about inline hook and hook meanings

In a hook computer, a function is usually used to replace the original function.

The inline hook directly modifies the instruction in the previous function replace and uses one jump or other instruction to achieve the hook purpose.
This is a relatively common hook, because a common hook only modifies the call address of the function, rather than modifying it in the original function body.

In general, General hooks are relatively stable to use. The inline hook is more advanced and generally difficult to detect. Therefore, many people, such as virus makers, advocate inline hook.

After VC injects dll, how can I use code to implement inline hook?

Key points ......
1. To restore the site, the number of bytes to be stored depends on the number of bytes occupied by the jmp you entered. jmp rel32 is 5 bytes.
2. You can use the memory applied by malloc for program operations, not necessarily the value of 0 in exe.
3. VirtualProtect call can make the code segment writable (otherwise, a write exception occurs during modification and the program crashes)
4. The jmp rel32 command machine code is E9 rel32, a total of five bytes. You can also use jmp mem32 if it is difficult to calculate the relative address. The machine command is FF 25 mem32 (if you remember wrong ...... It may also be FF 15 ). But I think this is more troublesome.
5. In the jmp rel32 command, rel32 is the eip after jmp is executed. For example
40000: E9 11 22 33 44
40005 :......
Then the translation is
40000: jmp 44372216
6. If you are not sure about the instruction length of the Code to be hooked, you may need an disassembly database to determine the length of the instruction. Of course, the easier (but less common) way is to manually view the instruction ...... Jump to jump remember to jump to the boundary of the machine code, such as
40000: E9 11 22 33 44
You cannot jump to any address in the range (40000,400 05), but you can jump to the address 40000 or 40005.

Related Article

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.