 |
Cheat Engine The Official Site of Cheat Engine
|
| View previous topic :: View next topic |
| Author |
Message |
rovnix Newbie cheater
Reputation: 0
Joined: 09 Feb 2014 Posts: 18
|
Posted: Thu May 29, 2014 11:45 am Post subject: Learning IAT Hooks |
|
|
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 |
|
 |
justa_dude Grandmaster Cheater
Reputation: 23
Joined: 29 Jun 2010 Posts: 893
|
Posted: Thu May 29, 2014 1:20 pm Post subject: |
|
|
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 |
|
 |
Anddos How do I cheat?
Reputation: 0
Joined: 06 Jan 2013 Posts: 8
|
Posted: Sun Mar 01, 2015 7:10 pm Post subject: |
|
|
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 |
|
 |
justa_dude Grandmaster Cheater
Reputation: 23
Joined: 29 Jun 2010 Posts: 893
|
Posted: Mon Mar 02, 2015 4:11 pm Post subject: |
|
|
| 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 |
|
 |
|
|
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
|
|