Как я исправил драйвер тачпада Alps

в 17:32, , рубрики: Песочница, метки:

В официальном драйвере Alps-pointing-device для Lenovo-G550 под Windows 7 есть такой баг: в настройках тачпада присутствует опция «использовать кнопки Назад/Вперёд», и она работает, но только в Проводнике Windows, а ведь так хотелось, чтобы это работало во всех приложениях.

В общем, используя догадки и приложения для отслеживания вызовов API-функций Windows, выяснил, что процесс Apoint.exe при каждом жесте Вперёд/Назад вызывает функции GetForegroundWindow и GetClassNameA.

И вот оно решение → перехватывать вызов GetClassNameA и всегда возвращать класс окон проводника, а именно — «CabinetWClass».

Перехватывать API я уже давно могу при помощи моего перехватчика:

#pragma pack(1)
class DETOUR
{
	struct JMP
	{
		BYTE instr;
		#ifdef WIN32
			DWORD
		#else
			long long
		#endif
		addr;
	}
	body_orig,*proc_body;
	#ifdef WIN32
		DWORD
	#else
		long long
	#endif
	addr_my_relative_to_orig;
public:
	template<typename T>
	void InitAndSet(T hooked_addr,T my_proc)
	{
		Init(hooked_addr,my_proc);
		Set();
	}
	template<typename T>
	void Init(T hooked_addr,T my_proc)
	{
		proc_body = (JMP*)hooked_addr;
		body_orig = *proc_body;
		#ifdef WIN32
			addr_my_relative_to_orig = DWORD(my_proc)-DWORD(hooked_addr)-5;
		#else
			???????
		#endif
		DWORD trash;
		VirtualProtect(hooked_addr,5,PAGE_EXECUTE_READWRITE,&trash);
	}
	__forceinline void Set()
	{
		#ifdef WIN32
			proc_body->instr = 0xE9;
		#else
			?????
		#endif
		proc_body->addr = addr_my_relative_to_orig;
	}
	__forceinline void Restore()
	{
		*proc_body = body_orig;
	}
};
#pragma pack()

И код в DLL'ке, которую нужно inject в целевой процесс:

DETOUR detGetClassNameA;
int _stdcall myGetClassNameA(HWND hwnd,LPSTR buf,int buf_len)
{
	static char str[] = "CabinetWClass";
	lstrcpyA(buf,str);
	return (sizeof str) - 1;
}

BOOL __stdcall myMain(HINSTANCE hModule,DWORD  reason,LPVOID lpReserved)  // точка входа DllMain
{
	if(reason==DLL_PROCESS_ATTACH)
		detGetClassNameA.InitAndSet(GetClassNameA,myGetClassNameA);
	return TRUE;
}

И радость, работает! Но только в 32-битной Windows, для 64-битной ещё не разобрался какую иструкцию процессора использовать.

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js