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 


Learning IAT Hooks

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

Joined: 09 Feb 2014
Posts: 18

PostPosted: Thu May 29, 2014 11:45 am    Post subject: Learning IAT Hooks Reply with quote

PLease i need help some one

I am learning IAT Hook For a simple messagebox, i am using visual studio 2013 and i have intellisense issues with it. i dont know what is wrong, please i need help.

Code:

#include<windows.h>
#include<conio.h>
#include<iostream>
#include<string>

#define TARGET_FUNCTION "MessageBoxW"
#define IMPORT_TABLE_OFFSET 1
using namespace std;
HMODULE __stdcall newFunc(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
bool IAThooking(HINSTANCE);
int main()
{
    char a;
    if(IAThooking(GetModuleHandleA(NULL)))
    {
        printf("\n\nHooked successfully!\nPress any key to call %s()",TARGET_FUNCTION);
        a=_getch();
        GetModuleHandleW(NULL);
    }

    return 0;
}
bool IAThooking(HINSTANCE hInstance)
{
    DWORD CurrentProtect;
    bool flag=false;
    IMAGE_DOS_HEADER *dosHeader;
    IMAGE_OPTIONAL_HEADER optionalHeader;
    IMAGE_NT_HEADERS *ntHeader;
    IMAGE_DATA_DIRECTORY dataDirectory;
    IMAGE_IMPORT_DESCRIPTOR *importedModule;
    IMAGE_THUNK_DATA *pThunk,*pTempThunk;
    IMAGE_IMPORT_BY_NAME *pOThunk;
   
    dosHeader=(PIMAGE_DOS_HEADER)hInstance;//cast hInstance to (IMAGE_DOS_HEADER *) - the MZ Header
    ntHeader=(IMAGE_NT_HEADERS *)((BYTE *)dosHeader+dosHeader->e_lfanew);//The PE Header begin after the MZ Header (which has size of e_lfanew)
    optionalHeader=(IMAGE_OPTIONAL_HEADER)(ntHeader->OptionalHeader); //Getting OptionalHeader
    dataDirectory=(IMAGE_DATA_DIRECTORY)(optionalHeader.DataDirectory[IMPORT_TABLE_OFFSET]);//Getting the import table of DataDirectory
    importedModule=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hInstance + dataDirectory.VirtualAddress);//ImageBase+RVA to import table
    //pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hInstance, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize); - You can just call this function to get the Import Table
    printf("%X\n",importedModule); //printing the address of the import table
    while(*(WORD*)importedModule!=0) //over on the modules (DLLs)
    {
        printf("%s:\n---------\n",(char*)((BYTE*)hInstance+importedModule->Name));//printing Module Name
        pThunk=(IMAGE_THUNK_DATA *)((BYTE*)hInstance+ importedModule->FirstThunk);//pointing to its IAT
        pTempThunk=(IMAGE_THUNK_DATA*)((BYTE*)hInstance+ importedModule->Characteristics);//pointing to OriginalThunk
        pOThunk=(IMAGE_IMPORT_BY_NAME *)((BYTE*)hInstance+ pTempThunk->u1.AddressOfData);// and to IMAGE_IMPORT_BY_NAME
        while(*(WORD*)pThunk!=0 && *(WORD*)pTempThunk!=0) //moving over IAT and over names' table
        {
            printf("%X %s\n",pThunk->u1.Function,pOThunk->Name);//printing function's name and addr
            if(strcmp(TARGET_FUNCTION,(char*)pOThunk->Name)==0)//checks if we are in the Target Function
            {
                VirtualProtect(pThunk,4096, PAGE_READWRITE, &CurrentProtect);//allow write to the page
                (pThunk->u1.Function)=(DWORD) newFunc; // rewrite the IAT to new function
                VirtualProtect(pThunk,4096, CurrentProtect,NULL);//return previous premissions
                printf("Hooked \n");
                flag=true; // hooked succeed!
            }
            pTempThunk++; // next node (function) in the array
            pOThunk=(IMAGE_IMPORT_BY_NAME *)((BYTE*)hInstance+ pTempThunk->u1.AddressOfData);
            pThunk++;// next node (function) in the array
        }
        importedModule++; //next module (DLL)
    }
    return flag;
}
HMODULE __stdcall newFunc(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
    MessageBoxA(NULL,"You are in func","hooked",0);
    return NULL;
}



What am i not doing correctly?
Back to top
View user's profile Send private message Yahoo Messenger
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 893

PostPosted: Thu May 29, 2014 1:20 pm    Post subject: Reply with quote

That's actually pretty nice code. Did you write it?

There are a few issues...

  • You are hooking the unicode messagebox, but for me (English language Win7) it isn't normally present in a console build.
  • You are trying to call messagebox after you hook it... maybe that's why you're using the ascii version in the newfunc after trying to hook the unicode version, but even if that's intentional I'm not certain that one doesn't call the other


The rest of the stuff is mostly stylistic (why not break the loop after finding our target, why mix C++ IO w/ C IO, etc).

Code:

#include<windows.h>
#include<conio.h>
#include <cstdio>
//#include<iostream> using printf, not iostreams
//#include<string> //not using strings

#define TARGET_FUNCTION "MessageBoxA"
#define IMPORT_TABLE_OFFSET 1
//using namespace std; not using std
HMODULE __stdcall newFunc(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
bool IAThooking(HINSTANCE);
int main()
{
    char a;
    if(IAThooking(GetModuleHandleA(NULL)))
    {
        printf("\n\nHooked successfully!\nPress any key to call %s()",TARGET_FUNCTION);
        a=_getch();
      MessageBoxA(NULL, "test", "test", MB_OK);
        GetModuleHandleW(NULL);
    }

    return 0;
}
bool IAThooking(HINSTANCE hInstance)
{
    DWORD CurrentProtect;
    bool flag=false;
    IMAGE_DOS_HEADER *dosHeader;
    IMAGE_OPTIONAL_HEADER optionalHeader;
    IMAGE_NT_HEADERS *ntHeader;
    IMAGE_DATA_DIRECTORY dataDirectory;
    IMAGE_IMPORT_DESCRIPTOR *importedModule;
    IMAGE_THUNK_DATA *pThunk,*pTempThunk;
    IMAGE_IMPORT_BY_NAME *pOThunk;
   
    dosHeader=(PIMAGE_DOS_HEADER)hInstance;//cast hInstance to (IMAGE_DOS_HEADER *) - the MZ Header
    ntHeader=(IMAGE_NT_HEADERS *)((BYTE *)dosHeader+dosHeader->e_lfanew);//The PE Header begin after the MZ Header (which has size of e_lfanew)
    optionalHeader=(IMAGE_OPTIONAL_HEADER)(ntHeader->OptionalHeader); //Getting OptionalHeader
    dataDirectory=(IMAGE_DATA_DIRECTORY)(optionalHeader.DataDirectory[IMPORT_TABLE_OFFSET]);//Getting the import table of DataDirectory
    importedModule=(IMAGE_IMPORT_DESCRIPTOR*)((BYTE*)hInstance + dataDirectory.VirtualAddress);//ImageBase+RVA to import table
    //pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hInstance, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize); - You can just call this function to get the Import Table
    printf("%p\n",importedModule); //printing the address of the import table (%p for pointer)
    while(*(WORD*)importedModule!=0) //over on the modules (DLLs)
    {
        printf("%s:\n---------\n",(char*)((BYTE*)hInstance+importedModule->Name));//printing Module Name
        pThunk=(IMAGE_THUNK_DATA *)((BYTE*)hInstance+ importedModule->FirstThunk);//pointing to its IAT
        pTempThunk=(IMAGE_THUNK_DATA*)((BYTE*)hInstance+ importedModule->Characteristics);//pointing to OriginalThunk
        pOThunk=(IMAGE_IMPORT_BY_NAME *)((BYTE*)hInstance+ pTempThunk->u1.AddressOfData);// and to IMAGE_IMPORT_BY_NAME
        while(*(WORD*)pThunk!=0 && *(WORD*)pTempThunk!=0) //moving over IAT and over names' table
        {
            printf("%p %s\n",pThunk->u1.Function,pOThunk->Name);//printing function's name and addr (%p for pointer)
            if(strcmp(TARGET_FUNCTION,(char*)pOThunk->Name)==0)//checks if we are in the Target Function
            {
                VirtualProtect(pThunk,4096, PAGE_READWRITE, &CurrentProtect);//allow write to the page
            if(4 == sizeof(int *))
               pThunk->u1.Function = (DWORD)newFunc; // rewrite the IAT to new function
            else
               pThunk->u1.Function = (ULONGLONG)newFunc; // rewrite the IAT to new function
                VirtualProtect(pThunk,4096, CurrentProtect,NULL);//return previous premissions
                printf("Hooked \n");
///                flag=true; // hooked succeed!
            return true;
            }
            pTempThunk++; // next node (function) in the array
            pOThunk=(IMAGE_IMPORT_BY_NAME *)((BYTE*)hInstance+ pTempThunk->u1.AddressOfData);
            pThunk++;// next node (function) in the array
        }
        importedModule++; //next module (DLL)
    }
    return flag;
}
HMODULE __stdcall newFunc(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType)
{
   printf("\nYou are in func\n");
//    MessageBoxA(NULL,"You are in func","hooked",0);
    return NULL;
}


works for me.

-cheers,
JD

_________________
A nagy kapu mellett, mindig van egy kis kapu.
----------------------
Come on...
Back to top
View user's profile Send private message
Anddos
How do I cheat?
Reputation: 0

Joined: 06 Jan 2013
Posts: 8

PostPosted: Sun Mar 01, 2015 7:10 pm    Post subject: Reply with quote

I am also using the IAT to hook functions but its not for the current process, its for a remote process,here is my source code

debugging is stopping on this line with a yellow arrow next to it

(IMAGE_OPTIONAL_HEADER *)((BYTE*)hMod + pDosHeader->e_lfanew + 24);

Code:

#include "stdafx.h"
    #include "stdafx.h" 
    #include <windows.h> 
    #include <TlHelp32.h>
    #include <stdio.h> 
    // hModMessageBoxA 
    HMODULE GetModuleBase();
    BOOL SetHookApi(HMODULE hMod); 
    // MessageBoxA 
    typedef int (WINAPI *PFNMESSAGEBOX)(HWND, LPCSTR, LPCSTR, UINT uType); 
    // MessageBoxA 
    PROC g_orgProc = (PROC)MessageBoxA; 
   
   int main() 
    { 
        // API 
        ::MessageBox(NULL, "", "HookDemo", 0); 
        //   
        //SetHookApi(::GetModuleHandle(NULL));
      SetHookApi(GetModuleBase()); 
         
        ::MessageBox(NULL, "", "HookDemo", 0); 
    } 
     
    // MessageBoxA 
    int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) 
    { 
        return ((PFNMESSAGEBOX)g_orgProc)(hWnd, "", "HookDemo", uType); 
    } 

   HMODULE GetModuleBase()
   {
      PROCESSENTRY32 pe32;
      pe32.dwSize = sizeof(PROCESSENTRY32);
      HANDLE  hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
      if(hSnap != INVALID_HANDLE_VALUE)
      {
            if (Process32First(hSnap, &pe32))
            {   
                while (Process32Next(hSnap, &pe32))
                {
               printf("%s\n",pe32.szExeFile);

                    if (strcmpi(pe32.szExeFile, "msgboxA_example.exe")==0)
                    {
                  HANDLE hModSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pe32.th32ProcessID);
                      if(hModSnap != INVALID_HANDLE_VALUE)
                  {
                     MODULEENTRY32 me32;
                          me32.dwSize = sizeof(MODULEENTRY32);
                     if(Module32First(hModSnap, &me32))
                     {
                        printf("%p\n",me32.hModule);
                        printf("%s\n",me32.szModule);
                        return me32.hModule;
                     }
                  }
                    }
                }
            }
      }
      CloseHandle(hSnap);
               
   }

    BOOL SetHookApi(HMODULE hMod) 
    { 
        IMAGE_DOS_HEADER* pDosHeader = (IMAGE_DOS_HEADER*)hMod; 
        IMAGE_OPTIONAL_HEADER * pOptHeader = 
            (IMAGE_OPTIONAL_HEADER *)((BYTE*)hMod + pDosHeader->e_lfanew + 24); 
         
        IMAGE_IMPORT_DESCRIPTOR* pImportDesc = (IMAGE_IMPORT_DESCRIPTOR*) 
            ((BYTE*)hMod + pOptHeader->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); 
         
        // user32.dll?MessageBoxAuser32.dll 
        while(pImportDesc->FirstThunk) 
        { 
            char* pszDllName = (char*)((BYTE*)hMod + pImportDesc->Name); 
            if(lstrcmpiA(pszDllName, "user32.dll") == 0) 
            { 
                break; 
            } 
            pImportDesc++; 
        } 
         
        if(pImportDesc->FirstThunk) 
        { 
            // IMAGE_THUNK_DATA? 
            // IMAGE_THUNK_DATA?DWORD 
            IMAGE_THUNK_DATA* pThunk = (IMAGE_THUNK_DATA*) 
                ((BYTE*)hMod + pImportDesc->FirstThunk); 
            while(pThunk->u1.Function) 
            { 
                // lpAddr 
                DWORD* lpAddr = (DWORD*)&(pThunk->u1.Function); 
                if(*lpAddr == (DWORD)g_orgProc) 
                {   
                    DWORD dwOldProtect; 
                    MEMORY_BASIC_INFORMATION mb; 
                    VirtualQuery(lpAddr, &mb, sizeof(mb)); 
                    VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect); 
                    // IAT??“*lpAddr = (DWORD)MyMessageBoxA;” 
                    DWORD* lpNewProc = (DWORD*)MyMessageBoxA; 
                    ::WriteProcessMemory(::GetCurrentProcess(),   
                        lpAddr, &lpNewProc, sizeof(DWORD), NULL); 
                    VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, 0); 
                    return TRUE; 
                } 
                 
                pThunk++; 
            } 
        } 
        return FALSE; 
    }   
Back to top
View user's profile Send private message
justa_dude
Grandmaster Cheater
Reputation: 23

Joined: 29 Jun 2010
Posts: 893

PostPosted: Mon Mar 02, 2015 4:11 pm    Post subject: Reply with quote

Anddos wrote:
I am also using the IAT to hook functions but its not for the current process, its for a remote process,here is my source code


I didn't spend much time examining what you're doing, so maybe I'm missing something... but I didn't notice that you wrote some binary trampoline into the remote process. At a glance, it looks like you're trying to give the address of the trampoline in LOCAL memory to the remote process with the expectation that your function will be available there. As for why you're crashing while debugging, I don't know... no offense, but since this is pretty clearly just an amalgamation of code you don't understand, it didn't seem worthy of study.

Better, IMHO, to just inject a DLL or do some CE-style injection.

_________________
A nagy kapu mellett, mindig van egy kis kapu.
----------------------
Come on...
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