0

I'm doing some functions to facilitate making hooks. I want to leave these functions in a file and include it when you need it.

I do not know if it's working yet but that's not the problem. When I compile, I get this error. I believe it is a mistake to import.

Error:

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

Hook.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);
}
User.1
  • 2,562
  • 3
  • 33
  • 40
Jorge Rossi
  • 95
  • 1
  • 11
  • Where is declared `tpAddr`. See the use of [`extern`](http://www.geeksforgeeks.org/understanding-extern-keyword-in-c/) – NetVipeC Sep 08 '14 at 19:56
  • 2
    Why are you #including a `.cpp` file? – NPE Sep 08 '14 at 19:56
  • So what better way to organize? – Jorge Rossi Sep 08 '14 at 19:57
  • possible duplicate of [GCC not resolving automatically .cpp from .h class include](http://stackoverflow.com/questions/19256114/gcc-not-resolving-automatically-cpp-from-h-class-include) – πάντα ῥεῖ Sep 08 '14 at 20:00
  • 1
    Put declarations in `.hpp` files, then `#include` them and link against the `.o` files created from your `.cpp`s – TartanLlama Sep 08 '14 at 20:00
  • 1
    Normally the included files are `.h`, `.hpp`, or like (header files). Including `.cpp` is most of the times not necessary. Put the definition of functions in `.hpp` and the implementation in `.cpp`, if global variables are used in multiple `.cpp`, declared in one and in the other add the `extern` linkage. – NetVipeC Sep 08 '14 at 20:01
  • 1
    i renamed noxHook.cpp to noxHook.h and 0 errors ! – Jorge Rossi Sep 08 '14 at 20:08
  • 2
    Having large implementation details in header files is almost always a bad idea. You'd really be better off separating your interface from your implementation; separate compilation is there for a reason. – TartanLlama Sep 08 '14 at 20:11
  • possible duplicate of [Error: Class computer comp is already defined in computer.obj](http://stackoverflow.com/questions/23979783/error-class-computer-comp-is-already-defined-in-computer-obj) – Niall Sep 09 '14 at 07:30

1 Answers1

2

For sake of a better understanding:

You were most likely getting multiple-definition errors because you were both #includeing and linking against the same file.

The standard way to fix this is to split up your interface and implementation, placing declarations in a guarded header file which you #include, and definitions into a .cpp file which you compile and link against.

For your example, this might look like:

Hook.cpp

#include "noxHook.hpp"


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 <stdio.h>
#include "noxHook.hpp"

extern DWORD tpAddr = 0;

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);
}

noxHook.hpp

#include <windows.h>

#define Naked __declspec( naked )

struct cHook
{
    BYTE newBytes[6];;
    BYTE oldBytes[6];
    DWORD fromAddr;
    LPVOID toAddr;
};

Naked void tpHook();
struct cHook SetupHook(DWORD fromAddr, LPVOID toAddr, LPVOID *oAddr);
void StartHook(struct cHook tmpHook);
void StopHook(struct cHook tmpHook);
TartanLlama
  • 63,752
  • 13
  • 157
  • 193