首页
社区
课程
招聘
[求助]请大伙帮忙看看,到底是哪个地方有逻辑错误?DLL&Hook
发表于: 2008-3-28 13:43 5246

[求助]请大伙帮忙看看,到底是哪个地方有逻辑错误?DLL&Hook

2008-3-28 13:43
5246
我的程序是想挂一个消息钩子,让所有的程序调用::MessageBox的时候,调用我的程序
应用程序的代码如下:
typedef	void (*FunPtr)(void);

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	HMODULE hMod = ::LoadLibrary("MsgDll.dll");
	if (hMod == NULL)
	{
		::MessageBox(NULL, "Load MsgDll.dll Wrong!", "Wrong", MB_OK);
		::ExitProcess(0);
	}
	FunPtr myfunction = (FunPtr)::GetProcAddress(hMod,"InstallHook");
	if (myfunction != NULL)
	{
		myfunction();
	}

	::MessageBox(NULL, "gg", "gg", MB_OK);

	return 0;
}


DLL的代码如下:
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case	DLL_PROCESS_ATTACH:
		hModHandle = hModule;
		
		hInstance = ::GetModuleHandle(NULL);
		hProcess = ::GetCurrentProcess();

		InlineHookApi("user32.dll", "MessageBoxA", "MyLoadLibAddress");
		InlineHookApi("user32.dll", "MessageBoxW", "MyLoadLibAddress");
		break;
	}
    return TRUE;
}

//调用LoadLibraryA函数时要执行的函数
HMODULE MyLoadLibAddress(LPCTSTR str)
{
	//现在只测试是否成功的Hook了
	Beep(500, 3000);

	::ExitProcess(0);
	return NULL;
}

//用Inline Hook掉API,传入参数为模块名称和函数名称以及目标函数的名字
BOOL InlineHookApi(const char *modName, const char *funName, const char *goalFunName)
{
	//取得目标模块的句柄,若获取模块句柄时出错,说明该DLL还没有被本进程加载
	HMODULE	hHookMod = ::GetModuleHandle(modName);
	if (hHookMod == NULL)
	{
		hHookMod = ::LoadLibrary(modName);
	}

	//获得要Hook掉的函数的虚拟地址
	loadLibAddr = ::GetProcAddress(hHookMod, funName);
	if (loadLibAddr == NULL)
	{
		return FALSE;
	}
	//初始化要覆盖结构的值
	replaceApi.a = 0xB8;
	replaceApi.d = 0xFF;
	replaceApi.e = 0xE0;
	replaceApi.pMyAPI = MyLoadLibAddress;

	//保存被更改函数的前8个字节
	::ReadProcessMemory(hProcess, loadLibAddr, saveByte, 8, &numRead);

	//更改原函数的前8个字节,以实现Inline Hook
	ChangeCode(hProcess, loadLibAddr, (unsigned char *)&replaceApi, 8);

	//::CloseHandle(hHookMod);
	return TRUE;
}

LRESULT CALLBACK HookProc(int nCode, unsigned int wParam, long lParam)
{
	::CallNextHookEx(hHook, nCode, wParam, lParam);
	return NULL;
}

void InstallHook()
{
	hHook = ::SetWindowsHookEx(WH_GETMESSAGE, HookProc, hInstance, NULL);
	return;
}

void UninstallHook()
{
	::UnhookWindowsHookEx(hHook);
	return;
}

//改变程序代码的函数
void ChangeCode(HANDLE hPro, LPVOID Addr, unsigned char *lpBuffer, DWORD codeSize)
{
	MEMORY_BASIC_INFORMATION	mbi = {0};
	
	//将相应的内存地址设为可读写
	::VirtualQueryEx(hProcess, Addr, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
	::VirtualProtectEx(hProcess, mbi.BaseAddress, codeSize, PAGE_EXECUTE_READWRITE, &pOldFlag);
	
	//改写LoadLibrary的前8个字节
	::WriteProcessMemory(hProcess, mbi.BaseAddress, lpBuffer, codeSize, &numWrite);
	if (numWrite != codeSize)
	{
		::MessageBox(NULL, "It's Wrong When Changing Program's Code!", "Error!", MB_OK | MB_ICONWARNING);
		::ExitProcess(0);
	}
	
	//将内存属性改回原来的属性
	::VirtualProtectEx(hProcess, mbi.BaseAddress, codeSize, pOldFlag, &mbi.Protect);
}



我的目的就是在程序安装完钩子之后,然后自己调用一下MessageBox,看看能否正常的被Hook掉,但是没反应,而那个对话框正常出现!!!
我用工具查看了一下当前系统的钩子,没有我的…………

我估计是我程序的问题,第一次写代码…………,对我的自信是毁灭性的打击性…………
我开始想用AppInit_Dlls把DLL载入所有的程序中,失败了……
第二次,我用远程线程的方法,想把DLL注入到进程中,又失败了……
第三次,我想用消息钩子的方法把DLL注入到进程中,再次失败了……

无奈了~~~~~~~
不知道哪儿错了?

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (7)
雪    币: 454
活跃值: (1673)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
2
看错代码,不好意思……
2008-3-28 14:06
0
雪    币: 224
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
3
我跟踪了一下,发现DLL中的SetWindowsHookEx正常执行了!
但是系统中却没有我的钩子!!!
2008-3-28 14:41
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
4
  MEMORY_BASIC_INFORMATION  mbi = {0};
  
  //将相应的内存地址设为可读写
  ::VirtualQueryEx(hProcess, Addr, &mbi, sizeof(MEMORY_BASIC_INFORMATION));
  ::VirtualProtectEx(hProcess, mbi.BaseAddress, codeSize, PAGE_EXECUTE_READWRITE, &pOldFlag);

  
  //改写LoadLibrary的前8个字节
  ::WriteProcessMemory(hProcess, mbi.BaseAddress, lpBuffer, codeSize, &numWrite);
  if (numWrite != codeSize)
  {
    ::MessageBox(NULL, "It's Wrong When Changing Program's Code!", "Error!", MB_OK | MB_ICONWARNING);
    ::ExitProcess(0);
  }
  
  //将内存属性改回原来的属性
  ::VirtualProtectEx(hProcess, mbi.BaseAddress, codeSize, pOldFlag, &mbi.Protect);
说点题外话

红色的代码是多余的.
2008-3-28 16:49
0
雪    币: 224
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
5
不会吧!
代码段一般不能写呀~
要改写他的内容一定要先把代码段的属性更改一下吧~
我去试试~~~
2008-3-28 16:57
0
雪    币: 224
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
6
额……
执行成功~~~
但是我这代码有问题,还不能太说明问题~
呵呵
2008-3-28 17:00
0
雪    币: 224
活跃值: (10)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
7
再顶上去~~~~
问题至今未解决~~~~
2008-3-30 13:09
0
雪    币: 325
活跃值: (97)
能力值: ( LV13,RANK:530 )
在线值:
发帖
回帖
粉丝
8
自己翻阅WriteProcessMemory代码  .
2008-3-30 18:12
0
游客
登录 | 注册 方可回帖
返回
//