【发布时间】:2014-11-02 03:17:05
【问题描述】:
我正在做一些函数来帮助制作钩子。我想将这些函数保留在一个文件中,并在需要时包含它。
我不知道它是否还在工作,但这不是问题。当我编译时,我得到这个错误。我认为导入是错误的。
错误:
1>noxHook.obj : error LNK2005: "unsigned long tpAddr" (?tpAddr@@3KA) already defined in Hook.obj
1>noxHook.obj : error LNK2005: "void __cdecl StopHook(struct cHook)" (?StopHook@@YAXUcHook@@@Z) already defined in Hook.obj
1>noxHook.obj : error LNK2005: "void __cdecl StartHook(struct cHook)" (?StartHook@@YAXUcHook@@@Z) already defined in Hook.obj
1>noxHook.obj : error LNK2005: "struct cHook __cdecl SetupHook(unsigned long,void *,void * *)" (?SetupHook@@YA?AUcHook@@KPAXPAPAX@Z) already defined in Hook.obj
1>noxHook.obj : error LNK2005: "void __cdecl tpHook(void)" (?tpHook@@YAXXZ) already defined in Hook.obj
1>C:\Users\JorgeFranzon\Documents\Visual Studio 2008\Projects\Hook\Release\Hook.dll : fatal error LNK1169: one or more multiply defined symbols found
钩子.cpp:
#include "noxHook.cpp"
int(*tFunc)(int a, int b) = NULL;
int hkFunc(int a, int b)
{
printf("\n Hook: Original parameters: %d and %d\n", a, b);
return tFunc(98, 99);
}
void Main()
{
struct cHook hk1 = SetupHook(0x4016B0, hkFunc, &(PVOID&)tFunc);
StartHook(hk1);
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
Main();
break;
}
return TRUE;
}
noxHook.cpp:
#include <windows.h>
#include <stdio.h>
#define Naked __declspec( naked )
extern DWORD tpAddr = 0;
struct cHook
{
BYTE newBytes[6];;
BYTE oldBytes[6];
DWORD fromAddr;
LPVOID toAddr;
};
Naked void tpHook()
{
__asm NOP;
__asm NOP;
__asm NOP;
__asm NOP;
__asm NOP;
__asm NOP;
__asm PUSH tpAddr;
__asm RET;
}
struct cHook SetupHook(DWORD fromAddr, LPVOID toAddr, LPVOID *oAddr)
{
struct cHook tmpHook;
tmpHook.fromAddr = fromAddr;
tmpHook.toAddr = toAddr;
DWORD oldProt;
VirtualProtect((void*)fromAddr, 6, PAGE_EXECUTE_READWRITE, &oldProt);
tmpHook.newBytes[0] = 0x68;
memcpy(&tmpHook.newBytes[1], &toAddr, 4);
tmpHook.newBytes[5] = 0xC3;
memcpy(&tmpHook.oldBytes[0], &fromAddr, 6);
tpAddr = fromAddr + 6;
memcpy(&tpHook, &tmpHook.oldBytes[0], 6);
*oAddr = tpHook;
return tmpHook;
}
void StartHook(struct cHook tmpHook)
{
memcpy((void*)tmpHook.fromAddr, (void*)&tmpHook.newBytes, 6);
}
void StopHook(struct cHook tmpHook)
{
memcpy((void*)tmpHook.fromAddr, tmpHook.oldBytes, 6);
}
【问题讨论】:
-
你为什么要#include一个
.cpp文件? -
将声明放入
.hpp文件,然后将#include放入它们并链接到从您的.cpps 创建的.o文件 -
通常包含的文件是
.h、.hpp或类似(头文件)。包括.cpp在大多数情况下是不必要的。函数的定义放在.hpp中,实现放在.cpp中,如果全局变量在多个.cpp中使用,则在一个中声明,在另一个中添加extern链接。 -
我将 noxHook.cpp 重命名为 noxHook.h 和 0 个错误!
-
在头文件中包含大量的实现细节几乎总是一个坏主意。最好将接口与实现分开;单独编译是有原因的。
标签: c++ c windows visual-c++ assembly