Register for your free account! | Forgot your password?

Go Back   elitepvpers > Coders Den > General Coding > Coding Tutorials
You last visited: Today at 01:57

  • Please register to post and access all features, it's quick, easy and FREE!

Advertisement



[Code / C++] Basic hooking of API Functions

Discussion on [Code / C++] Basic hooking of API Functions within the Coding Tutorials forum part of the General Coding category.

Reply
 
Old   #1


 
buFFy!'s Avatar
 
elite*gold: 1826
Join Date: Mar 2009
Posts: 4,310
Received Thanks: 6,287
[Code / C++] Basic hooking of API Functions

Global:

Code:
typedef BOOL (__stdcall * ReadProcessMemory_t)(HANDLE hProcess,LPVOID lpBaseAddress,LPCVOID lpBuffer,SIZE_T nSize,SIZE_T *lpNumberOfBytesRead);
ReadProcessMemory_t pReadProcessMemory;
Functions:
Code:
//Credits to GD ; You can do it manually, too.
void* detourFunc(BYTE *src, const BYTE *dst, const int len)
{
	BYTE *jmp = (BYTE*)malloc(len+5);
	DWORD dwback;

	VirtualProtect(src, len, PAGE_READWRITE, &dwback);

	memcpy(jmp, src, len);	jmp += len;

	jmp[0] = 0xE9;
	*(DWORD*)(jmp+1) = (DWORD)(src+len - jmp) - 5;

	src[0] = 0xE9;
	*(DWORD*)(src+1) = (DWORD)(dst - src) - 5;

	VirtualProtect(src, len, dwback, &dwback);

	return (jmp-len);
}
The Hook:
Code:
DWORD dwReadProcessMemory = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "ReadProcessMemory");
pReadProcessMemory = (ReadProcessMemory_t)detourFunc((BYTE*)dwReadProcessMemory, (BYTE*)&hkReadProcessMemory, 5);
The Hooked Function:
Code:
BOOL __stdcall hkReadProcessMemory(HANDLE hProcess,LPVOID lpBaseAddress,LPCVOID lpBuffer,SIZE_T nSize,SIZE_T *lpNumberOfBytesRead)
{
        //your code goes here
	return pReadProcessMemory(hProcess, lpBaseAddress, lpBuffer, nSize, lpNumberOfBytesRead);
}
buFFy! is offline  
Old 07/18/2010, 22:11   #2
 
Bl@ze!'s Avatar
 
elite*gold: 240
Join Date: Dec 2006
Posts: 1,579
Received Thanks: 1,609
Also, ich kenne diese Methode zum hooken, ich finde sie aber fehleranfällig und nicht gut. Es gibt ja wirklich mehere Methoden zum Hooken.

Mit Detours geht es ganz gut und auch leicht, das schöne ist einfach es gibt eine ordentliche Fehlerbehandlung, die bei dir nicht da ist.

Ich habe auch mal eine Klasse geschrieben um DLL Funktionen zu Hooken.

HookManager.hpp
Code:
#pragma once

// C++/STL Header Files:
#include <list>
#include <string>
#include <exception>

// Windows Header Files:
#include <windows.h>
#include <tlhelp32.h>

// Project Header Files:
#include "EnsureClosure.hpp"

namespace Utilities
{
   /*!-------------------------------------------------------------------------
   |      author: Unkn0wn0x
   |      brief : Hook helper Utilitie class.
   |
   |      example usage:
   |
   |         HookManager *sendPacketHook = new HookManager(
   |            "ws2_32.dll", "send", (DWORD)&sendPacketCallBack);
   |   
   |         int (WINAPI*RealSendPacket)(SOCKET, const char *, int, int);
   |         RealSendPacket = 
   |           (int(WINAPI*)(SOCKET, const char*, int, int))
   |              sendPacketHook->callAddress();
   |
   |-------------------------------------------------------------------------*/
	template < typename pfunction_t >
   class HookManager
   {
      public:
			HookManager(const std::string& moduleName, const std::string& apiCallName, pfunction_t callBack)
         {
            m_lpdwExportTableAddress = 0;

	         //Get module handle of import and export module.
				HMODULE thisModule	= ::GetModuleHandle(NULL);
				HMODULE targetModule	= ::GetModuleHandleA(moduleName.c_str());
            if(targetModule == NULL)
               std::runtime_error("GetModuleHandle");

            //Get the API call address
				FARPROC apiCallAddress = GetProcAddress(hModule, apiCallName.c_str());
            if (apiCallAddress == NULL)
					throw std::runtime_error("GetProcAddress");

				//Get a snapshot of all modules
            SafeHandle modSnapshot(CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, 0));
				if (!modSnapshot.isValid())
               throw std::runtime_error("CreateToolhelp32Snapshot");

            DWORD dwProtect;

            // Iterate the complete module list
				MODULEENTRY32 modEntry = { sizeof(modEntry) };
            for(BOOL moreModuleEntries = Module32First(modSnapshot, &modEntry); moreModuleEntries; moreModuleEntries = Module32Next(modSnapshot, &modEntry)) 
            {
               if (targetModule == modEntry.hModule)
					{
                  PIMAGE_DOS_HEADER lpsDOS   = (PIMAGE_DOS_HEADER)sME32.modBaseAddr;
                  PIMAGE_NT_HEADERS lpsNT    = (PIMAGE_NT_HEADERS)(sME32.modBaseAddr+lpsDOS->e_lfanew);
                  PIMAGE_EXPORT_DIRECTORY lpsExport = (PIMAGE_EXPORT_DIRECTORY)(sME32.modBaseAddr + lpsNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);

                  DWORD dwBase = (DWORD)sME32.modBaseAddr;
                  DWORD *lpdwAddressTable = (DWORD*)(lpsExport->AddressOfFunctions + dwBase);
                  
                  for (DWORD i = 0; i < lpsExport->NumberOfFunctions; ++i)
						{
                     if( (DWORD)hAPI == (lpdwAddressTable[i]+dwBase))
							{
                        //Save export address before changing it!
                        m_dwExportAddress = lpdwAddressTable[i];
                        VirtualProtect(&lpdwAddressTable[i],4,PAGE_EXECUTE_READWRITE,&dwProtect);
                        lpdwAddressTable[i] = dwHook - (DWORD)hOwnModule;
                        VirtualProtect(&lpdwAddressTable[i],4,dwProtect,&dwProtect);
                     }
                  }
					}
					else
					{
			         //Change imports for our API (if available)
			         PIMAGE_DOS_HEADER lpsDOS   = (PIMAGE_DOS_HEADER)sME32.modBaseAddr;
			         PIMAGE_NT_HEADERS lpsNT    = (PIMAGE_NT_HEADERS)(sME32.modBaseAddr+lpsDOS->e_lfanew);
			         
                  if (lpsNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size == 0)
				         continue;

                  PIMAGE_IMPORT_DESCRIPTOR lpsImport = (PIMAGE_IMPORT_DESCRIPTOR)(sME32.modBaseAddr + lpsNT->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
                  DWORD dwBase = (DWORD)sME32.modBaseAddr;

                  while (lpsImport->Name)
						{
				         PIMAGE_THUNK_DATA lpsThunk = (PIMAGE_THUNK_DATA)(lpsImport->FirstThunk + sME32.modBaseAddr);

                     while (lpsThunk->u1.AddressOfData)
							{
                        if (lpsThunk->u1.AddressOfData == (DWORD)hAPI)
								{
                           // Store import adderss, before changing
                           m_dwImportAddress = lpsThunk->u1.AddressOfData;

                           // Store the import address poitner
                           m_liImportTable.push_back(&lpsThunk->u1.AddressOfData);

                           // Store table address
                           m_lpdwExportTableAddress = &lpsThunk->u1.AddressOfData;

                           VirtualProtect(&lpsThunk->u1.AddressOfData, 4, PAGE_EXECUTE_READWRITE, &dwProtect);
                           lpsThunk->u1.AddressOfData = dwHook;
                           VirtualProtect(&lpsThunk->u1.AddressOfData,4,dwProtect,&dwProtect);
                        }
                        lpsThunk++;
                     }
                     lpsImport++;
                  }
               }
            }
         }

         ~HookManager()
         {
            DWORD dwProtect;

            // Restore the export address
            if (m_lpdwExportTableAddress) {
               VirtualProtect(
                  m_lpdwExportTableAddress,
                  4,
                  PAGE_EXECUTE_READWRITE,
                  &dwProtect);
               
               *m_lpdwExportTableAddress = m_dwExportAddress;
               
               VirtualProtect(
                  m_lpdwExportTableAddress,
                  4,
                  dwProtect,
                  &dwProtect);
            }

            // Restore our old import addresses
            for (tImportTable::iterator cPos = m_liImportTable.begin();
               cPos != m_liImportTable.end(); ++cPos) {
                  VirtualProtect(
                     *cPos,
                     4,
                     PAGE_EXECUTE_READWRITE,
                     &dwProtect);

                  **cPos = m_dwImportAddress;

                  VirtualProtect(
                     *cPos,
                     4,
                     dwProtect,
                     &dwProtect);
            }
         }

         DWORD callAddress()
         {
            return m_dwImportAddress;
         }

      private:
         DWORD m_dwImportAddress;
         DWORD m_dwExportAddress;

         DWORD *m_lpdwExportTableAddress;

         typedef std::list<DWORD*> tImportTable;
         tImportTable m_liImportTable;
   };
}
EnsureClosure.hpp
Code:
#pragma once

// Windows Header Files:
#include <windows.h>

namespace Utilities
{
	class SafeHandle
	{
	public:
		SafeHandle() : handle_(NULL)
		{
			/* VOID */
		}

		SafeHandle(HANDLE handle) : handle_(handle)
		{
			/* VOID */
		}

		~SafeHandle()
		{
			close();
		}

		HANDLE operator=(HANDLE handle)
		{
			close();
			handle_ = handle;
			return *this;
		}

		operator HANDLE() const
		{
			return handle_;
		}

		bool isValid() const
		{
			return (handle_ != NULL && handle_ != INVALID_HANDLE_VALUE);
		}

		void close()
		{
			if(isValid())
				CloseHandle(handle_);
		}

	private:
		HANDLE handle_;
	};
}
Die tuts natürlich auch. (Beispiel zur Benutzung im Kommentar vorhanden)
Aber wie gesagt, letzendlich zum normalen Hooken bevorzuge ich Detours.

Edit: Außerdem habe ich gerade gesehen, dass dein Code nichts anderes macht als dieser hier: , der besser beschrieben ist. *g*
Bl@ze! is offline  
Thanks
1 User
Old 07/19/2010, 01:41   #3


 
buFFy!'s Avatar
 
elite*gold: 1826
Join Date: Mar 2009
Posts: 4,310
Received Thanks: 6,287
Ich habs heut irgendwo beim Platte aufräumen gefunden und dachte mir ich klatsch das hier einfach mal lieblos rein.
Btw stehe ich nicht so auf MS Detours ;P
buFFy! is offline  
Reply


Similar Threads Similar Threads
Visuabl Basic Code - Virtueller openfiledialog
08/27/2010 - WarRock Trading - 5 Replies
Was bringt mir ein : Visuabl Basic Code - Virtueller openfiledialog kommt jetzt blos nicht mit falsche section. Ist bewusst hier drin, da ich das ding auch verkaufe. http://www.elitepvpers.com/theblackmarket/treasure /3426
[Release]Code´s für AutoIt V3, Visual Basic und CMD
06/11/2010 - Coding Tutorials - 3 Replies
Tutorial @Bei falscher Sektion ..sry Auto IT V3 Was es ist : _Date_Time_FileTimeToLocalFileTime #include <GuiConstantsEx.au3> #include <Date.au3> #include <WindowsConstants.au3>
Visual Basic - Code aufrufen?
03/24/2010 - .NET Languages - 2 Replies
Tag, ich habe mal ne kleine Frage zu VB: Wenn ich eine Form erstelle gibt es ja einen Code dazu. Bisher habe ich es nur geschafft diesen aufzurufen, in dem ich die Form abgespeichert habe und dann auf "Form1.Designer.vb" geklickt habe. Nun möchte ich wissen, ob das auch schneller geht, dass ich nicht immer alles abspeichern muss. Danke im Vorraus.
Code in C# or visual basic with nuconnector
12/15/2008 - Silkroad Online - 8 Replies
Hi all, Im new in this forum but not in silkroad :) I 've looking for tutorials or some example to make an application with C# or visual basic, using nuconnector to get some info from the game. I've searched in the forum, in google too but I can't find anything. I will agree any info :) thanks a lot :)
Disconect code for Visual Basic
06/24/2007 - Conquer Online 2 - 2 Replies
.



All times are GMT +2. The time now is 01:57.


Powered by vBulletin®
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
SEO by vBSEO ©2011, Crawlability, Inc.

Support | Contact Us | FAQ | Advertising | Privacy Policy | Terms of Service | Abuse
Copyright ©2026 elitepvpers All Rights Reserved.