Microsoft Detours

Acest forum este dedicat intrebarilor de Windows API, folosing C/C++
Post Reply
User avatar
vali29
Junior
Junior
Posts: 4
Joined: 31 Oct 2012, 14:37
Judet: Bucureşti
Location: Bucuresti

Microsoft Detours

Post by vali29 »

Salut!
Se da urm. problema:

Code: Select all

EXECUTABIL.EXE--->DLL1.DLL
              --->DLL2.DLL
              --->DLL3.DLL
EXECUTABIL.EXE incarca(LoadLibrary) DLL-urile 1,2,3. Pentru DLL-urile 1 si 2 cat si EXECUTABIL.EXE nu exista codul sursa.
In DLL3.DLL:

Code: Select all

include <windows.h>
#include <Shlwapi.h>
#include <Psapi.h>
#include <intrin.h>
#include <winternl.h>
#include "detours\include\detours.h"
#pragma comment(lib, "detours.lib")

void(WINAPI *True_GetSystemTime)(OUT LPSYSTEMTIME lpSystemTime) = GetSystemTime;

void WINAPI HookedGetSystemTime(OUT LPSYSTEMTIME lpSystemTime)
{
         //...
	True_GetSystemTime(lpSystemTime);
}
extern "C"
{
	BOOL WINAPI DllMain(HINSTANCE hInst, DWORD dwReason, LPVOID lpvReserved)
	{
		switch (dwReason)
		{
			case DLL_PROCESS_ATTACH: {
				DisableThreadLibraryCalls(hInst);
				DetourTransactionBegin();
				DetourUpdateThread(GetCurrentThread());
				DetourAttach(&(PVOID&)True_GetSystemTime, HookedGetSystemTime);
				LONG lError = DetourTransactionCommit();

				if (lError != NO_ERROR) {
					::MessageBox(HWND_DESKTOP, "Failed to CRACK", "ERROR:", MB_OK);
					return FALSE;
				}
			}
			break;
			case DLL_THREAD_ATTACH:
			{
			}
			break;
			case DLL_THREAD_DETACH:
			{
			}
			break;
			case DLL_PROCESS_DETACH: {
				DetourTransactionBegin();
				DetourUpdateThread(GetCurrentThread());
				DetourDetach(&(PVOID&)True_GetSystemTime, HookedGetSystemTime);
				LONG lError = DetourTransactionCommit();

				if (lError != NO_ERROR) {
					MessageBox(HWND_DESKTOP, "Failed to remove CRACK", "ERROR:", MB_OK);
					return FALSE;
				}
			}
			break;
		}
	}
}
La incarcarea DLL2.DLL, Detours instaleaza HOOK-ul la nivel global in EXECUTABIL.EXE, astfel, toate cererile GetSystemTime din DLL1.DLL, DLL2.DLL, DLL3.DLL cat si EXECUTABIL.EXE vor fi directionate catre HookedGetSystemTime.

Cum fac sa filtrez cererile in interiorul HookedGetSystemTime, sau poate nu, astfel incat doar DLL3.DLL sa poata accesa HookedGetSystemTime, celealte cereri catre functia HookedGetSystemTime sa fie respinse?
Multumesc


Viorel
Microsoft MVP
Microsoft MVP
Posts: 293
Joined: 13 Jul 2007, 12:26

Re: Microsoft Detours

Post by Viorel »

Dacă sursele pentru DLL3 există, atunci poate e posibilă înlocuirea lui GetSystemTime cu un MyGetSystemTime, care apelează True_GetSystemTime. Poate ar merge un ‘#define GetSystemTime MyGetSystemTime’.

Dacă asta nu funcționează, atunci se poate încerca analiza adresei de revenire și a modulului apelant. Ceva de genul:

Code: Select all

#include <intrin.h>

void WINAPI HookedGetSystemTime( OUT LPSYSTEMTIME lpSystemTime )
{
    void* return_address = _ReturnAddress( );

    HMODULE caller_module;
    if( GetModuleHandleEx( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)return_address, &caller_module ) )
    {
        if( caller_module == dll3_module)
        { 
            // . . .
        }
    }
}
unde dll3_module este GetModuleHandle("DLL3") sau hInst din DllMain (variabilă globală).
User avatar
vali29
Junior
Junior
Posts: 4
Joined: 31 Oct 2012, 14:37
Judet: Bucureşti
Location: Bucuresti

Re: Microsoft Detours

Post by vali29 »

Merge varianta cu intrinsic _ReturnAddress() dar la hook GetVolumeInformation din Kernel32.dll nu reusesc:
_ReturnAddress() returneaza cred adresa EXECUTABIL.EXE

Code: Select all

BOOL WINAPI HookedGetVolumeInformationA(_In_opt_   LPCTSTR lpRootPathName,
	_Out_opt_  LPTSTR lpVolumeNameBuffer,
	_In_       DWORD nVolumeNameSize,
	_Out_opt_  LPDWORD lpVolumeSerialNumber,
	_Out_opt_  LPDWORD lpMaximumComponentLength,
	_Out_opt_  LPDWORD lpFileSystemFlags,
	_Out_opt_  LPTSTR lpFileSystemNameBuffer,
	_In_       DWORD nFileSystemNameSize)
{

	BOOL status = True_GetVolumeInformationA(lpRootPathName, lpVolumeNameBuffer, nVolumeNameSize,
		lpVolumeSerialNumber, lpMaximumComponentLength, lpFileSystemFlags,
		lpFileSystemNameBuffer, nFileSystemNameSize);

	if (status) {
		void* return_address = _ReturnAddress();
		HMODULE caller_module;
		CHAR    wszModuleName[MAX_PATH];
		::GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)return_address, &caller_module);
		::GetModuleBaseName(GetCurrentProcess(), caller_module, wszModuleName, _countof(wszModuleName));

#ifdef _DEBUG
		odprintf("HookedGetVolumeInformationA: %s\n", wszModuleName); // wszModuleName -> EXECUTABIL.EXE
#endif // _DEBUG
		return true;
	}
	else {
		return status;
	}
}
Multumesc mult!
Post Reply