首页
社区
课程
招聘
[原创]Ring3下Inline Hook MessageBox(演示)
发表于: 2008-7-30 20:45 13211

[原创]Ring3下Inline Hook MessageBox(演示)

2008-7-30 20:45
13211
这是学习Ring3 下Inline Hook 的代码,写的很菜,部分代码参考了邪8中“我非我”的代码,在此表示感谢。
原文中有二处错误,后面好多人都说运行不成功,不知道原作者是怎样编译成功的,原代码参见ring3 inline hook demo
由于在邪8中等级太低,不能发贴,借用宝地说明下

提前声明下,我调试的VC++为6.0的,
在VC++编译器生成EXE中,函数也像API一样进行了中间跳转
如下
0040100F   $ /E9 CC020000   jmp     MyFunc
00401014   $ |E9 37000000   jmp     main
00401019   $ |E9 B2000000   jmp     Hook

在40100F中,原文中的意思是此处即为MyFunc的入口地址,但此处只为一中转跳转,要计算真正函数的入口地址,还要再次进行重定位。另外一处,原文开头为替换为5个字节,在这里正好将一条完整的指令拆开了,这是在调试过程中发现的,正确的在原文中应替换6个字节,这就不详说了,有不对的地方,希望指正


#include "stdafx.h"
#include <windows.h>
#include <stdio.h>
#include <iostream.h>
//using namespace std;

DWORD head;//保存API返回地址
int nRet;
BYTE orig_code[5] = {0x90, 0x90, 0x90, 0x90, 0x90};//存放原始的指令
BYTE hook_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到MyMessageBoxA的指令
BYTE jmp_org_code[5] = {0xe9, 0, 0, 0, 0};//存放跳转到原起始地址后5字节的指令

int MyMessageBoxA(
				HWND hWnd,          // handle to owner window
				LPCTSTR lpText,     // text in message box
				LPCTSTR lpCaption,  // message box title
				UINT uType          // message box style
				);
int MyMessageBoxAA(
				  HWND hWnd,          // handle to owner window
				  LPCTSTR lpText,     // text in message box
				  LPCTSTR lpCaption,  // message box title
				  UINT uType          // message box style
				);
int MyFunc();
void Hook();
int jmp_back();

ULONG OldFuncAddr;
ULONG MyFuncAddr;
ULONG jmp_backAddr;

//在修改前几个字节时,注意:取出的指令为完整的

int main()
{
	Hook();

	int rt = MessageBoxA(NULL, "Hello World", "Title", MB_OK);
//	cout << rt << endl;//查看返回值是否已修改成功

	system("pause");

	return 0;
}

void Hook()
{
	DWORD dwOldProtect;	
	OldFuncAddr = (ULONG)MessageBoxA;

	// MyFuncAddr = MyMessageBoxA的实际地址
	MyFuncAddr = *(ULONG *)((BYTE *)MyMessageBoxA+1) + (ULONG)MyMessageBoxA + 5;
	// jmp_backAddr = jmp_back的实际地址
	jmp_backAddr = *(ULONG *)((BYTE *)jmp_back+1) + (ULONG)jmp_back + 5;
    //修改内存为PAGE_EXECUTE_READWRITE
	VirtualProtect((LPVOID)jmp_backAddr, 10, PAGE_EXECUTE_READWRITE, &dwOldProtect);

	VirtualProtect((LPVOID)OldFuncAddr, 5, PAGE_EXECUTE_READWRITE, &dwOldProtect);
	//计算跳转地址
	*((ULONG*)(hook_code+1)) = (ULONG)MyFuncAddr - (ULONG)OldFuncAddr - 5;
	
	memcpy(orig_code,(BYTE *)OldFuncAddr, 5);

	memcpy((BYTE*)OldFuncAddr, hook_code, 5);
	//计算返回地址
	*((ULONG*)(jmp_org_code+1)) = (ULONG)OldFuncAddr - (ULONG)jmp_backAddr - 5;

	memcpy((BYTE *)jmp_backAddr, orig_code, 5);

	memcpy((BYTE *)jmp_backAddr + 5, jmp_org_code, 5);
}

__declspec(naked) int jmp_back()
{
	__asm
	{
		_emit 0x90
		_emit 0x90
		_emit 0x90
		_emit 0x90
		_emit 0x90
		_emit 0x90
		_emit 0x90
		_emit 0x90
		_emit 0x90
		_emit 0x90
	}
}

//MyMessageBoxA:在函数执行前进行自己的处理
__declspec(naked) int MyMessageBoxA(
									 HWND hWnd,          // handle to owner window
									 LPCTSTR lpText,     // text in message box
									 LPCTSTR lpCaption,  // message box title
									 UINT uType          // message box style
									)
{ 	
	printf("MyMessageBoxA is called\r\n"); 
	 __asm
	{
		pop head
		pop hWnd
		pop lpText
		pop lpCaption
		pop uType
	}
	MyFunc();////可以加入函数过程
	__asm
	{
		//压栈过程
		push uType
		push lpCaption
		push lpText
		push hWnd
		push head
		//跳回MessageBoxA入口点
		jmp jmp_back;
		ret;
	}
}


//MyMessageBoxA:在函数执行后进行自己的处理
__declspec(naked) int MyMessageBoxAA(
									HWND hWnd,          // handle to owner window
									LPCTSTR lpText,     // text in message box
									LPCTSTR lpCaption,  // message box title
									UINT uType          // message box style
									)
{ 	
	printf("MyMessageBoxAA is called\r\n"); 
	__asm
	{
		pop head
		push offset s1;//返回地址为S1:
		//跳回MessageBoxA入口点
		jmp jmp_back;
s1:		nop	
	}

	MyFunc();
	
	__asm
	{
		;//将原返回地址压栈
		mov eax, 0;////演示:将返回结果改为0,也可由MyFunc返回
		push head
		ret;
	}
}

int MyFunc()
{
	printf("Hello World\r\n");
	return 1;
}

[课程]FART 脱壳王!加量不加价!FART作者讲授!

收藏
免费 7
支持
分享
最新回复 (12)
雪    币: 22
活跃值: (423)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
沙发 强帖留名!!
2008-7-30 21:15
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
似乎这样的代码网上有一大堆```
2008-7-31 09:45
0
雪    币: 8865
活跃值: (2379)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
4
一时看成ring0下inline hook messagebox
2008-7-31 10:46
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
5
如果ring0下hook的话,我是这么想的,设置LoadImageNofity,然后检测到模块载入后就检查其输入表是否有user32.dll,若有再判断是否有MessageBox,若有就hook之.最多也就是一个在进程空间中,一个在内核空间,读写和修改方式不太一样而已吧,不过应该也差不多.

 不知说得对不对?还没实践~
2008-7-31 13:21
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
6
detour.
2008-7-31 14:55
0
雪    币: 205
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
这样代码网上很多的
2008-8-1 08:33
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
网上也找过,但没有这么清楚的啊,新手想找的只是一个简单的DEMO,而网上的那些可长了,都看不清哪是哪的,注释也很简
想想和我一样水平的人,呵呵,就贴出来了
2008-8-1 08:39
0
雪    币: 709
活跃值: (2420)
能力值: ( LV12,RANK:1010 )
在线值:
发帖
回帖
粉丝
9
嗯,谢谢分享你的学习成果~
有交流才有进步嘛
2008-8-1 08:46
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
__declspec(naked) int jmp_back()
{
  __asm
  {
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
    _emit 0x90
  }
}
我用CB编译的时候提示我   _emit 0x90语法错误,各位大侠怎么回事?
2008-8-11 12:17
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
CB?
没研究过,可能在内联汇编时有不同吧
VC下通过
2008-8-15 10:50
0
雪    币: 66
活跃值: (25)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
12
内联的和修改IAT的两种方法的差异是不是效率呢?
2008-8-15 10:59
0
雪    币: 239
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
在RING3下全局HOOK的话,还是IAT吧,方便
INLINE也有一种方法是直接可以写入物理空间,一次性修改,全局通用
2008-8-17 18:36
0
游客
登录 | 注册 方可回帖
返回
//