Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


C++: How restore inline hooks?

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming
View previous topic :: View next topic  
Author Message
flashcoder
Newbie cheater
Reputation: 0

Joined: 29 Jan 2017
Posts: 14

PostPosted: Sun Jan 29, 2017 9:59 am    Post subject: C++: How restore inline hooks? Reply with quote

I'm needing restore some inline hooks in a app made by a third party program.

Searching on web i have found one good code ( that apparently seemed work ), but this code don't is working for me.

The code below, try restore inline hooks based on EAT table, but he never finds any api hooked in modules loaded on app.

Code:

#include "stdafx.h"

#define makeptr( Base, Increment, Typecast ) ((Typecast)( (ULONG)(Base) + (ULONG)(Increment) ))
#define incptr( Base, Increment, Typecast ) ((Typecast)RVAToVA( (ULONG)(Base), (ULONG)(Increment) ))

ULONG RVAToVA( ULONG Base, ULONG Increment )
{
 PIMAGE_NT_HEADERS    Nt = makeptr( Base, ((PIMAGE_DOS_HEADER)Base)->e_lfanew, PIMAGE_NT_HEADERS );
 USHORT          SCount = Nt->FileHeader.NumberOfSections;
 PIMAGE_SECTION_HEADER  Sections = makeptr( Nt, sizeof(*Nt), PIMAGE_SECTION_HEADER );

 for ( USHORT i = 0; i < SCount; i++ )
 {
   if ( (Increment >= Sections[i].VirtualAddress ) && (Increment <= (Sections[i].VirtualAddress + Sections[i].SizeOfRawData)) )
   {
     return ( (Increment - Sections[i].VirtualAddress) + Sections[i].PointerToRawData + Base);
   }
 }
 return Base + Increment;
}

void UnhookModule( HMODULE Module )
{
 char MFileName[MAX_PATH];
 GetModuleFileName( Module, MFileName, sizeof(MFileName) );

 HANDLE hFile = CreateFile( MFileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL );
 SetFilePointer( hFile, 0, NULL, FILE_BEGIN );

 ULONG dwTemp;

 dwTemp = GetFileSize( hFile, NULL );
 BYTE *Base = new BYTE[dwTemp];
 ReadFile( hFile, Base, dwTemp, &dwTemp, NULL );
 CloseHandle( hFile );

 PIMAGE_NT_HEADERS    Nt = makeptr( Base, ((PIMAGE_DOS_HEADER)Base)->e_lfanew, PIMAGE_NT_HEADERS );
 PIMAGE_EXPORT_DIRECTORY Exports =
   incptr( Base, Nt->OptionalHeader.DataDirectory[0].VirtualAddress, PIMAGE_EXPORT_DIRECTORY );

 PBYTE FuncHooked = NULL;
 PBYTE FuncOriginal = NULL;

 char **Names = incptr( Base, Exports->AddressOfNames, char ** );
 ULONG *Functions = incptr( Base, Exports->AddressOfFunctions, ULONG * );

 ULONG RVA;
 ULONG VA;

 ULONG  EATProtect;
 char  *FunctionName;

 MEMORY_BASIC_INFORMATION  Info;
 ULONG            OldProtection;
 int              x;
 for ( ULONG i = 0; i < Exports->NumberOfNames;i++ )
 {
   FunctionName = makeptr( Module, Names[i], char * );
   FuncOriginal = incptr( Base, Functions[i], PBYTE );
   FuncHooked = (PBYTE)GetProcAddress( Module, FunctionName );

   RVA = Functions[i];   
   VA = (ULONG)FuncHooked - (ULONG)Module;
   if ( VA != RVA )
   {
     ULONG *EATFunc =
       makeptr(
         Module,
         makeptr(
           Module,
           makeptr( Module, ((PIMAGE_DOS_HEADER)Module)->e_lfanew, PIMAGE_NT_HEADERS )->OptionalHeader.DataDirectory[0].VirtualAddress,
           PIMAGE_EXPORT_DIRECTORY )->AddressOfFunctions,
         PULONG
         );
     VirtualProtect( &EATFunc[i], sizeof(RVA), PAGE_EXECUTE_READWRITE, &EATProtect );
     EATFunc[i] = RVA;
     VirtualProtect( &EATFunc[i], sizeof(RVA), EATProtect, 0 );
   }

   if ( FuncHooked[0] != 0xE9 )
   {
     continue; // this line is always executed, so never is found any hooked api, but exists hooked api on "real life"
   }
   VirtualQuery( FuncHooked, &Info, sizeof(Info) );
   VirtualProtect( FuncHooked, Info.RegionSize, PAGE_EXECUTE_READWRITE, &OldProtection );

   x = 0;
   while ( FuncHooked[x] != FuncOriginal[x] )
   {
     FuncHooked[x] = FuncOriginal[x];
     x++;
   }
   VirtualProtect( FuncHooked, Info.RegionSize, OldProtection, NULL );
 }
 delete []Base;
}

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        UnhookModule(GetModuleHandle("Gdi32.dll"));
        break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}



I have saw this feature in PC Hunter and now want implement it in a separated dll.

Someone have idea why this code don't finds none api hooked in none module loaded on app?

Any suggestion or help will welcome.



gc4T8.png
 Description:
I have saw this feature in PC Hunter.
 Filesize:  106.07 KB
 Viewed:  9327 Time(s)

gc4T8.png




Last edited by flashcoder on Sun Jan 29, 2017 2:06 pm; edited 1 time in total
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8517
Location: 127.0.0.1

PostPosted: Sun Jan 29, 2017 1:44 pm    Post subject: Reply with quote

If it is an inline hook it is not going to something you restore at the IAT or EAT. It is going to be hooked directly at the start of the API call or within a certain range from its start. For a hook like this, you are going to need to load the target module for reading (You cannot LoadLibrary again you will just get the handle of the already loaded module.) and calculate the offset to the target API, for example BitBlit in your example.

You can do that via calculating the information of the current loaded module via:

Code:

// Get the module handle and function address..
auto modGdi32 = ::GetModuleHandle("GDI32.dll");
auto funcBitBlit = ::GetProcAddress(modGdi32, "BitBlit");

// Calculate the function offset..
auto offBitBlit = (uintptr_t)funcBitBlit - (uintptr_t)modGdi32;


So now you know the offset to the function, you can use that to calculate and read the original function data directly from the file that you loaded to get the original data then restore it to the loaded modules data.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
flashcoder
Newbie cheater
Reputation: 0

Joined: 29 Jan 2017
Posts: 14

PostPosted: Sun Jan 29, 2017 2:04 pm    Post subject: Reply with quote

atom0s wrote:
If it is an inline hook it is not going to something you restore at the IAT or EAT. It is going to be hooked directly at the start of the API call or within a certain range from its start. For a hook like this, you are going to need to load the target module for reading (You cannot LoadLibrary again you will just get the handle of the already loaded module.) and calculate the offset to the target API, for example BitBlit in your example.

You can do that via calculating the information of the current loaded module via:

Code:

// Get the module handle and function address..
auto modGdi32 = ::GetModuleHandle("GDI32.dll");
auto funcBitBlit = ::GetProcAddress(modGdi32, "BitBlit");

// Calculate the function offset..
auto offBitBlit = (uintptr_t)funcBitBlit - (uintptr_t)modGdi32;


So now you know the offset to the function, you can use that to calculate and read the original function data directly from the file that you loaded to get the original data then restore it to the loaded modules data.



So, this code in my question restores apis only in EAT table?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8517
Location: 127.0.0.1

PostPosted: Sun Jan 29, 2017 2:41 pm    Post subject: Reply with quote

Yes the code you posted is only trying to restore EAT entries. Which is not what you need for fixing inline hooks.
_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
flashcoder
Newbie cheater
Reputation: 0

Joined: 29 Jan 2017
Posts: 14

PostPosted: Sun Jan 29, 2017 3:11 pm    Post subject: Reply with quote

atom0s wrote:
Yes the code you posted is only trying to restore EAT entries. Which is not what you need for fixing inline hooks.


Okay @atom0s,

You could show a complete code about how could be for BitBlt api in this case, please?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 198

Joined: 25 Jan 2006
Posts: 8517
Location: 127.0.0.1

PostPosted: Sun Jan 29, 2017 7:18 pm    Post subject: Reply with quote

I explained in my first post everything you need to do. I am not going to just hand you things to copy paste.
_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
flashcoder
Newbie cheater
Reputation: 0

Joined: 29 Jan 2017
Posts: 14

PostPosted: Sun Jan 29, 2017 7:22 pm    Post subject: Reply with quote

atom0s wrote:
I explained in my first post everything you need to do. I am not going to just hand you things to copy paste.


I need to understand how works.
Help me, please.
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> General programming All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites