求助,64位下的应用程序dll hook

csh20140320 2015-07-27 08:26:21
劳烦各位
一个win2012-64位下的程序,在调用它本身的dll的函数,我想得到传入该函数的参数,怎么搞?

重点是64位,而且该函数的地址怎么取得?

下面是32位的可以由此修改吗,还是怎么弄?
// 将add()中的入口代码保存入OldCode[]
_asm
{
lea edi,OldCode
mov esi,pfadd
cld
movsd
movsb
}

NewCode[0]=0xe9;//实际上0xe9就相当于jmp指令
//获取Myadd()的相对地址
_asm
{
lea eax,Myadd
mov ebx,pfadd
sub eax,ebx
sub eax,5
mov dword ptr [NewCode+1],eax
}


对不起,刚才的发错版面了
拜托了,本人菜鸟积分无多,拜托了。
...全文
221 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
csh20140320 2015-07-29
  • 打赏
  • 举报
回复
引用 14 楼 Saleayas 的回复:
你自己写一个同名的 dll 文件。导出符号和原来的一致。 把这个同名的文件替换到原来的文件所在的位置。 在这个 dll 里面,你可以看到所有导出函数被呼叫的参数。 在这个 dll 你手动加载原来的 dll,并且动态导出原来的函数,当你的函数需要调用原来的函数的时候,直接使用。
对于不清楚的导出函数的参数 是不是可以用LPVOID代替?
csh20140320 2015-07-29
  • 打赏
  • 举报
回复
引用 15 楼 u014251975 的回复:
[quote=引用 14 楼 Saleayas 的回复:] 你自己写一个同名的 dll 文件。导出符号和原来的一致。 把这个同名的文件替换到原来的文件所在的位置。 在这个 dll 里面,你可以看到所有导出函数被呼叫的参数。 在这个 dll 你手动加载原来的 dll,并且动态导出原来的函数,当你的函数需要调用原来的函数的时候,直接使用。
引用 14 楼 Saleayas 的回复:
你自己写一个同名的 dll 文件。导出符号和原来的一致。 把这个同名的文件替换到原来的文件所在的位置。 在这个 dll 里面,你可以看到所有导出函数被呼叫的参数。 在这个 dll 你手动加载原来的 dll,并且动态导出原来的函数,当你的函数需要调用原来的函数的时候,直接使用。
啊,我感觉明白了,是不是这样写
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

//相同的导出函数
extern "C" __declspec(dllexport) int coutb1(char *a,char *b)
{
	//把参数写出来
	cout<<b<<a<<endl;
	//调用原dll
	HINSTANCE hdll;
	hdll=LoadLibrary("target.dll");
	if(hdll==NULL)
	{
		FreeLibrary(hdll);  
		return 1;
	}
	typedef int(*Dllfun)(char *,char*);
	Dllfun maopao1;
	maopao1=(Dllfun)GetProcAddress(hdll,"maopao"); 
	if(maopao1==NULL)  
	{
		FreeLibrary(hdll); 
		return 1;
	} 

	return 0;
}
[/quote] 忘了些执行了
maopao1(a,b);
csh20140320 2015-07-29
  • 打赏
  • 举报
回复
引用 14 楼 Saleayas 的回复:
你自己写一个同名的 dll 文件。导出符号和原来的一致。 把这个同名的文件替换到原来的文件所在的位置。 在这个 dll 里面,你可以看到所有导出函数被呼叫的参数。 在这个 dll 你手动加载原来的 dll,并且动态导出原来的函数,当你的函数需要调用原来的函数的时候,直接使用。
引用 14 楼 Saleayas 的回复:
你自己写一个同名的 dll 文件。导出符号和原来的一致。 把这个同名的文件替换到原来的文件所在的位置。 在这个 dll 里面,你可以看到所有导出函数被呼叫的参数。 在这个 dll 你手动加载原来的 dll,并且动态导出原来的函数,当你的函数需要调用原来的函数的时候,直接使用。
啊,我感觉明白了,是不是这样写
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

//相同的导出函数
extern "C" __declspec(dllexport) int coutb1(char *a,char *b)
{
	//把参数写出来
	cout<<b<<a<<endl;
	//调用原dll
	HINSTANCE hdll;
	hdll=LoadLibrary("target.dll");
	if(hdll==NULL)
	{
		FreeLibrary(hdll);  
		return 1;
	}
	typedef int(*Dllfun)(char *,char*);
	Dllfun maopao1;
	maopao1=(Dllfun)GetProcAddress(hdll,"maopao"); 
	if(maopao1==NULL)  
	{
		FreeLibrary(hdll); 
		return 1;
	} 

	return 0;
}
赵4老师 2015-07-28
  • 打赏
  • 举报
回复
Saleayas 2015-07-28
  • 打赏
  • 举报
回复
自己做一个同名的 dll,自己导出其导出符号,当呼叫你指定的函数的时,就可以看到参数了。
Saleayas 2015-07-28
  • 打赏
  • 举报
回复
你自己写一个同名的 dll 文件。导出符号和原来的一致。 把这个同名的文件替换到原来的文件所在的位置。 在这个 dll 里面,你可以看到所有导出函数被呼叫的参数。 在这个 dll 你手动加载原来的 dll,并且动态导出原来的函数,当你的函数需要调用原来的函数的时候,直接使用。
赵4老师 2015-07-28
  • 打赏
  • 举报
回复
引用 8 楼 u014251975 的回复:
引用 5 楼 zhao4zhong1 的回复:
WinAPIOverride http://jacquelin.potier.free.fr/winapioverride32/
好高端的感觉,我研究一下,谢谢。
csh20140320 2015-07-28
  • 打赏
  • 举报
回复
引用 11 楼 Saleayas 的回复:
如果你的 dll 导出的函数不是很多,你可以手动写每一个导出符号。 当很多的时候,才需要使用自动的函数。此时才需要替换函数入口,否则根本不需要处理你说的情况。
大神,能否给一个完整点的例子,我是真的很菜,多谢。
Saleayas 2015-07-28
  • 打赏
  • 举报
回复
如果你的 dll 导出的函数不是很多,你可以手动写每一个导出符号。 当很多的时候,才需要使用自动的函数。此时才需要替换函数入口,否则根本不需要处理你说的情况。
csh20140320 2015-07-28
  • 打赏
  • 举报
回复
引用 9 楼 linjiagao052 的回复:

// 长跳转说明:
	// 0x0: 0xff2500000000	;jump to the address immediately following this address
	// 0x6: the address to be jumped	;64 bits address of hooking function
	// 参考 AMD x64体系指令结构
	*((unsigned char *)mi2.mappedAddr) = 0xff;
	*((unsigned char *)mi2.mappedAddr + 1) = 0x25;
	*((uint32_t *)((ULONG_PTR)mi2.mappedAddr + 2)) = 0x0;
	*((ULONG_PTR *)((ULONG_PTR)mi2.mappedAddr + 6)) = (ULONG_PTR)(pHook->newFunc);
修改页面属性,直接写入跳转指令
看不懂啊
linjiagao052 2015-07-28
  • 打赏
  • 举报
回复

// 长跳转说明:
	// 0x0: 0xff2500000000	;jump to the address immediately following this address
	// 0x6: the address to be jumped	;64 bits address of hooking function
	// 参考 AMD x64体系指令结构
	*((unsigned char *)mi2.mappedAddr) = 0xff;
	*((unsigned char *)mi2.mappedAddr + 1) = 0x25;
	*((uint32_t *)((ULONG_PTR)mi2.mappedAddr + 2)) = 0x0;
	*((ULONG_PTR *)((ULONG_PTR)mi2.mappedAddr + 6)) = (ULONG_PTR)(pHook->newFunc);
修改页面属性,直接写入跳转指令
csh20140320 2015-07-28
  • 打赏
  • 举报
回复
引用 5 楼 zhao4zhong1 的回复:
WinAPIOverride http://jacquelin.potier.free.fr/winapioverride32/
好高端的感觉,我研究一下,谢谢。
csh20140320 2015-07-28
  • 打赏
  • 举报
回复
引用 4 楼 Saleayas 的回复:
自己做一个同名的 dll,自己导出其导出符号,当呼叫你指定的函数的时,就可以看到参数了。
不明白,64位不支持内联汇编啊,这是一个32位下工具导出的dll部分代码,假设是32位下该怎末写



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 头文件
#include <Windows.h>
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
PVOID pfnPicFreeFileInfo;
PVOID pfnPicRetrieveFileInfo;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	// 获取原始函数地址
	FARPROC WINAPI GetAddress(PCSTR pszProcName)
{
pfnPicFreeFileInfo=GetAddress("PicFreeFileInfo");
pfnPicRetrieveFileInfo=GetAddress("PicRetrieveFileInfo");
	}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 宏定义
#define EXTERNC extern "C"
#define NAKED __declspec(naked)
#define EXPORT __declspec(dllexport)

#define ALCPP EXPORT NAKED
#define ALSTD EXTERNC EXPORT NAKED void __stdcall
#define ALCFAST EXTERNC EXPORT NAKED void __fastcall
#define ALCDECL EXTERNC NAKED void __cdecl
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// AheadLib 命名空间
namespace AheadLib
{
	HMODULE m_hModule = NULL;	// 原始模块句柄
	DWORD m_dwReturn[2] = {0};	// 原始函数返回地址


	// 加载原始模块
	inline BOOL WINAPI Load()
	{
		TCHAR tzPath[MAX_PATH];
		TCHAR tzTemp[MAX_PATH * 2];

		lstrcpy(tzPath, TEXT("aepicOrg"));
		m_hModule = LoadLibrary(tzPath);
		if (m_hModule == NULL)
		{
			wsprintf(tzTemp, TEXT("无法加载 %s,程序无法正常运行。"), tzPath);
			MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
		}

		return (m_hModule != NULL);	
	}
		
	// 释放原始模块
	inline VOID WINAPI Free()
	{
		if (m_hModule)
		{
			FreeLibrary(m_hModule);
		}
	}

	// 获取原始函数地址
	FARPROC WINAPI GetAddress(PCSTR pszProcName)
	{
		FARPROC fpAddress;
		CHAR szProcName[16];
		TCHAR tzTemp[MAX_PATH];

		fpAddress = GetProcAddress(m_hModule, pszProcName);
		if (fpAddress == NULL)
		{
			if (HIWORD(pszProcName) == 0)
			{
				wsprintf(szProcName, "%d", pszProcName);
				pszProcName = szProcName;
			}

			wsprintf(tzTemp, TEXT("无法找到函数 %hs,程序无法正常运行。"), pszProcName);
			MessageBox(NULL, tzTemp, TEXT("AheadLib"), MB_ICONSTOP);
			ExitProcess(-2);
		}

		return fpAddress;
	}
}
using namespace AheadLib;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 入口函数
BOOL WINAPI DllMain(HMODULE hModule, DWORD dwReason, PVOID pvReserved)
{
	if (dwReason == DLL_PROCESS_ATTACH)
	{
		DisableThreadLibraryCalls(hModule);

		return Load();
	}
	else if (dwReason == DLL_PROCESS_DETACH)
	{
		Free();
	}

	return TRUE;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_PicFreeFileInfo(void)
{
	// 保存返回地址
	__asm POP m_dwReturn[0 * TYPE long];

	// 调用原始函数
	GetAddress("PicFreeFileInfo")();

	// 转跳到返回地址
	__asm JMP m_dwReturn[0 * TYPE long];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////



////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 导出函数
ALCDECL AheadLib_PicRetrieveFileInfo(void)
{
	// 保存返回地址
	__asm POP m_dwReturn[1 * TYPE long];

	// 调用原始函数
	GetAddress("PicRetrieveFileInfo")();

	// 转跳到返回地址
	__asm JMP m_dwReturn[1 * TYPE long];
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
csh20140320 2015-07-28
  • 打赏
  • 举报
回复
引用 3 楼 dustpg 的回复:
引用 2 楼 u014251975 的回复:
[quote=引用 1 楼 dustpg 的回复:] 替换dll不就行了, 仿照导出函数自己实现, 再调用原dll, 还不用修改
有考虑过,64位的输入输出表没弄下来,仿照的导出函数不知道怎么写啊,请指教一下,十分感谢。
有dll的说明就直接了当,没有的话, 网上应该有dll的导出分析软件, 能分析导出的函数名称和函数地址,反汇编一下,猜测函数的调用约定和参数, 我对这方面就没研究了, lz得自己网上搜一下[/quote]谢谢,我再看看
dustpg 2015-07-27
  • 打赏
  • 举报
回复
引用 2 楼 u014251975 的回复:
引用 1 楼 dustpg 的回复:
替换dll不就行了, 仿照导出函数自己实现, 再调用原dll, 还不用修改
有考虑过,64位的输入输出表没弄下来,仿照的导出函数不知道怎么写啊,请指教一下,十分感谢。
有dll的说明就直接了当,没有的话, 网上应该有dll的导出分析软件, 能分析导出的函数名称和函数地址,反汇编一下,猜测函数的调用约定和参数, 我对这方面就没研究了, lz得自己网上搜一下
csh20140320 2015-07-27
  • 打赏
  • 举报
回复
引用 1 楼 dustpg 的回复:
替换dll不就行了, 仿照导出函数自己实现, 再调用原dll, 还不用修改
有考虑过,64位的输入输出表没弄下来,仿照的导出函数不知道怎么写啊,请指教一下,十分感谢。
dustpg 2015-07-27
  • 打赏
  • 举报
回复
替换dll不就行了, 仿照导出函数自己实现, 再调用原dll, 还不用修改

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧