Hooking library zu laufen bekommen


#1

Abend, weiß jemand, wie ich diese Library zum Laufen bekommen kann (das Basisbeispiel): https://github.com/Zeex/subhook#basic-usage ?

Er sagt mir, foo sei nicht deklariert. Wenn ich foo definiere, dann kommt eine andere Fehlermeldung.

Eigentlich ist foo die zu hookende Funktion (zumindest, wenn ich das richtig verstanden hab).


Wahrscheinlich mach ich das alles falsch. Also ich injiziere einem Prozess eine dll mit exportierten Funktionen; mit der Hoffnung, dass statt der originalen die neuen Funktionen called werden. Das ist falsch, oder?


Fragt mich bloß nicht warum? :wink:


#2

Möchte gern Folgendes: Ich öffne einen Texteditor und zum Beispiel wenn ein ‘a’ eingegeben wird, soll ein ‘b’ eingegeben werden.
Daher compiliere und injiziere ich dann eine dll.
Aber irgendwie muss ich die dll ja “compilieren”.


Adresse der zu hookenden Funktion ist auch bekannt.


Keiner 'ne Idee?


#3

Idee nein. Aber es könnte helfen genauer zu erklären, wie du das genau einbindest … und welche IDE/Toolchain du nutzt.

Lange her das ich was mit C++ gemacht hab (:smiley:), aber ich erinnere mich daran, dass es durchaus sehr komplex sein kann, eine dll einzubinden. (Zumindest erschien mir das so bei meinem letzten Arbeitgeber).


#4

Ja, bin da auch “eingerostet”.

Es funktioniert jetzt fast:

#include "main.h"

#include <stdio.h>
#include <subhook.h>

subhook_t foo_hook;

typedef int __stdcall sub_1004EDFE(int, int, int, int, int); // diese Funktion ist zu hooken

int my_foo(int a, int b, int c, int d, int e)
{
    /* Remove the hook so that you can call the original function. */
    subhook_remove(foo_hook);

    printf("sub_1004EDFE (%d) (%d) (%d) (%d) (%d) called\n", a,b,c,d,e);
    sub_1004EDFE(a,b,c,d,e);

    /* Install the hook back to intercept further calls. */
    subhook_install(foo_hook);
}

// a sample exported function
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
    MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);

    /* Create a hook that will redirect all foo() calls to to my_foo(). */
    foo_hook = subhook_new((void *)sub_1004EDFE, (void *)my_foo, 0);

    /* Install it. */
    subhook_install(foo_hook);

    /* Remve the hook and free memory when you're done. */
    subhook_remove(foo_hook);
    subhook_free(foo_hook);
}

extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        // attach to process
        // return FALSE to fail DLL load
        SomeFunction("hallo2");
        break;

    case DLL_PROCESS_DETACH:
        // detach from process
        break;

    case DLL_THREAD_ATTACH:
        // attach to thread
        break;

    case DLL_THREAD_DETACH:
        // detach from thread
        break;
    }
    return TRUE; // succesful
}

Code::Blocks


#5

Hier hat jemand Minesweeper(*) gehackt. Und hat es so beschrieben, dass man es verstehen kann

(*): Ihr kennt das Spielchen, sehr beliebt und oft gewinnt man nicht. :frowning:

Und hier steht, wie man eine Funktion ihre Adresse anspricht:


Ich kann mir noch nicht vorstellen, da ich das im vorherigen Beitrag richtig gemacht hab.

Der Texteditor lädt eine dll nach. Diese möchte ich aber vor start(*) unberührt lassen…

(*): Das liegt auf der Hand, denke ich.


Und YT-Videos hab ich auch noch dazu - wenn von Interesse…


#6

Der Code war falsch:

#include "main.h"

#include <stdio.h>
#include <subhook.h>

subhook_t foo_hook;

#define ORI_ADR 0x1004EDFE
int (__stdcall* original)(int, int, int, int, int); // diese Funktion ist zu hooken

int my_foo(int a, int b, int c, int d, int e)
{
    /* Remove the hook so that you can call the original function. */
    subhook_remove(foo_hook);

    printf("sub_1004EDFE (%d) (%d) (%d) (%d) (%d) called\n", a,b,c,d,e);
    int tr = original(a,b,c,d,e);

    /* Install the hook back to intercept further calls. */
    subhook_install(foo_hook);

    return tr;
}

void attach()
{
    /* Create a hook that will redirect all foo() calls to to my_foo(). */
    foo_hook = subhook_new((void *)ORI_ADR, (void *)my_foo, SUBHOOK_OPTION_64BIT_OFFSET);

    /* Install it. */
    subhook_install(foo_hook);


}

void detach()
{
    /* Remve the hook and free memory when you're done. */
    subhook_remove(foo_hook);
    subhook_free(foo_hook);
}

// a sample exported function
void DLL_EXPORT SomeFunction(const LPCSTR sometext)
{
    MessageBoxA(0, sometext, "DLL Message", MB_OK | MB_ICONINFORMATION);
}

extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        // attach to process
        // return FALSE to fail DLL load
        SomeFunction("hallo2");
        attach();
        break;

    case DLL_PROCESS_DETACH:
        // detach from process
        detach();
        break;

    case DLL_THREAD_ATTACH:
        // attach to thread
        break;

    case DLL_THREAD_DETACH:
        // detach from thread
        break;
    }
    return TRUE; // succesful
}

… dann kann ich das mit Code::Blocks(*) nicht compilen, da subhook.h ein Precompiled header file ist, und darin ist ein Marcro nicht definiert ist, schreibe ich aber 0 oder -1, gibt es andere Fehler mit der Reihenfolge.

Und außerdem finde ich bei der Lib nirgends Compile Anweisungen.

Habt ihr vielleicht noch eine Idee?

(*): http://wiki.codeblocks.org/index.php/Precompiled_headers .


#7
>gcc -o subhook.so *.c
In file included from subhook.c:64:0:
subhook_x86.c: In function 'subhook_make_jmp32':
subhook_x86.c:290:13: error: 'EOVERFLOW' undeclared (first use in this function)
     return -EOVERFLOW;
             ^~~~~~~~~
subhook_x86.c:290:13: note: each undeclared identifier is reported only once for each function it appears in
subhook_unix.c:28:22: fatal error: sys/mman.h: No such file or directory
 #include <sys/mman.h>
                      ^
compilation terminated.
subhook_x86.c: In function 'subhook_make_jmp32':
subhook_x86.c:290:13: error: 'EOVERFLOW' undeclared (first use in this function)
     return -EOVERFLOW;
             ^~~~~~~~~
subhook_x86.c:290:13: note: each undeclared identifier is reported only once for each function it appears in

\subhook> Get-ChildItem -Recurse -File | Resolve-Path -Relative
.editorconfig
.gitattributes
.travis.yml
.\appveyor.yml
.\CMakeLists.txt
.\README.md
.\subhook.c
.\subhook.h
.\subhook_private.h
.\subhook_unix.c
.\subhook_windows.c
.\subhook_x86.c
.\test\asm_test.c
.\test\CMakeLists.txt
.\test\foo_32.asm
.\test\foo_64.asm
.\test\test.c

Bitte helfen


#8

Naja… eigentlich wollte ich hier nix schreiben, weil das Thema einfach zu “künstlich” ist. Auf die Geburtstagsverwaltung kann man bestimmt auch ewig und drei Tage warten, weil TO einfach von einem Stöckchen auf nächste kommt…

Man sollte hier ein Problem nach dem anderen lösen.

Der GCC sagt ja exakt, was ihm nicht gefällt. Ich habe mal die not found Fehlermeldung gegoogelt. Hat jetzt wenige Sekunden gekostet:

Hier hat einer das Gleiche Problem und es wird eine mögliche Lösung erläutert. Da hier einfach nur die Fehlermeldung gepostet wird, gehe ich davon aus, dass keine eigene Vorarbeit einhergegangen ist.

error: ‘EOVERFLOW’ undeclared

Ist ja eigentlich auch klar, was das bedeutet, da dies ein Fehler der Abhängigkeit ist, würde ich eher dazu tendieren herauszufinden, wie diese entsprechend zu kompilieren ist. Deine *.so Datei impliziert eine kompilierte Form von subhook. Vermutlich hast du die Sourcen davon aber auch da liegen und dann versuchst er das doppelt zu kompilieren, obwohl du dafür keine Abhängigkeiten hast.

Einfach so irgendwas und dann auch noch sowas mit c++ zu machen ist nicht der richtige weg, um das zu lernen. Ich schlage dir dringend vor sich EINE Sprache auszusuchen und dann diese zu meistern. Ansonsten postet du nur Fragemente ohne weiteren Sinn. Und trotz des Hinweises von so vielen Leuten hier, wie man es besser machen kann, ignorierst du es vollkommen.

Schöne Grüße

Martin


#9

Jetzt beruhige dich mal wieder…

der wie auch meine zweite App (mit Vokabeln), ist fertig.


Naheliegend wäre es doch, subhook_unix.c wegzulassen und nicht zu compilen.

Das löst aber noch nicht das, dass ich bei EOVERFLOW wild herumraten muss!


Ja in Java hab ich nix Neues mehr zu lernen… Du etwa?



#10

Jo, würde ich mal auf einen der Links klicken und mal durchlesen, was da steht :wink:


#11

Vorsichtig formuliert, eigentlich kann man sich das ewig und 5 Tage durchlesen, und ist hinterher genauso schlau wie… Das ist mehr so an Compilerbauer gedacht… Wenn man nicht genau weiß, wonach man sucht, hat man das Problem


ALLE Kombinationen funktionieren nicht:

run:
\subhook>gcc -o subhook.so -D EOVERFLOW subhook.c subhook_windows.c subhook_x86.c 
: multiple definition of `subhook_unprotect'
: first defined here
: multiple definition of `subhook_new'
: first defined here
: multiple definition of `subhook_free'
: first defined here
: multiple definition of `subhook_install'
: first defined here
: multiple definition of `subhook_remove'
: first defined here
: multiple definition of `subhook_read_dst'
: first defined here
: undefined reference to `WinMain@16'
: ld returned 1 exit status

\subhook>gcc -o subhook.so -D EOVERFLOW subhook.c subhook_windows.c 
: multiple definition of `subhook_unprotect'
: first defined here
: undefined reference to `WinMain@16'
: ld returned 1 exit status

\subhook>gcc -o subhook.so -D EOVERFLOW subhook.c subhook_x86.c 
: multiple definition of `subhook_new'
: first defined here
: multiple definition of `subhook_free'
: first defined here
: multiple definition of `subhook_install'
: first defined here
: multiple definition of `subhook_remove'
: first defined here
: multiple definition of `subhook_read_dst'
: first defined here
: undefined reference to `WinMain@16'
: ld returned 1 exit status

\subhook>gcc -o subhook.so -D EOVERFLOW subhook.c 
: undefined reference to `WinMain@16'
: ld returned 1 exit status

\subhook>gcc -o subhook.so -D EOVERFLOW subhook_windows.c subhook_x86.c 
: undefined reference to `WinMain@16'
: ld returned 1 exit status

\subhook>gcc -o subhook.so -D EOVERFLOW subhook_windows.c 
: undefined reference to `WinMain@16'
: ld returned 1 exit status

\subhook>gcc -o subhook.so -D EOVERFLOW subhook_x86.c 
: undefined reference to `subhook_unprotect'
: undefined reference to `subhook_unprotect'
: undefined reference to `WinMain@16'
: ld returned 1 exit status

BUILD SUCCESSFUL (total time: 5 seconds)


#12

Die Diskussion dreht sich im Kreis ;))

Du nimmst an, es handelt sich ei dem EOVERFLOW um ein Compiler Flag…

Daher googelst du danach und findest keine Ergebnisse.

https://www.google.com/search?q=error%3A+‘EOVERFLOW’

Nimmt man da einfach den Fehlertext, erhält man schon deutlich bessere Ergebnisse. In der Zeit, in der du ein Bild + entsprechende Hinweise gegeben hast, wie du googelst, sollte man eher Zeit darin investieren seine Suchkriterien besser zu wählen.


#13

EOVERFLOW ist durch -D EOVERFLOW überhaupt kein Problem mehr.

Wenn ich das mit -c kompiliere, kann ich zumindest subhook.h kompilieren.


Meld dich einfach, wenn du weißt, wie man Hooking library zu laufen bekommen compilieren kann.


#14

Wenn das kompilieren funktioniert, welchen Fehler betrachten wir jetzt?


#16

3 Beiträge editiert. Contenance.


#17

Drehe mich mit den Fehlermeldungen im Kreis. :frowning:


#18

*seufz*

Was ist denn jetzt die Frage? Wie man irgendein Programm compiliert? MUSS es CodeBlocks sein? Hab’ das subhook gerade mal geclont, CMake laufen lassen, in Visual Studio compiliert, und den Test gestartet, und es geht. Noch irgendwas?


#19

CMake funktioniert bei mir nicht, was hast du angegeben?

Allgemein funktioniert es mit CodeBlocks bei mir gar nicht, egal was ich versuche.
Aktuell:

-------------- Build: Release in my dll (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -O2 -Wall -DEOVERFLOW -DBUILD_DLL -I"..\my dll" -c ".....\my dll\main.cpp" -o obj\Release\main.o
mingw32-g++.exe -shared -Wl,--output-def="bin\Release\libmy dll.def" -Wl,--out-implib="bin\Release\libmy dll.a" -Wl,--dll  obj\Release\main.o  -o "bin\Release\my dll.dll" -s  -luser32
obj\Release\main.o:main.cpp:(.text+0x21): undefined reference to `_imp__subhook_remove'
obj\Release\main.o:main.cpp:(.text+0x75): undefined reference to `_imp__subhook_install'
obj\Release\main.o:main.cpp:(.text+0xac): undefined reference to `_imp__subhook_new'
obj\Release\main.o:main.cpp:(.text+0xba): undefined reference to `_imp__subhook_install'
obj\Release\main.o:main.cpp:(.text+0xdd): undefined reference to `_imp__subhook_remove'
obj\Release\main.o:main.cpp:(.text+0xeb): undefined reference to `_imp__subhook_free'
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
7 error(s), 0 warning(s) (0 minute(s), 0 second(s))


-------------- Build: Release in my dll (compiler: GNU GCC Compiler)---------------

mingw32-g++.exe -O2 -Wall -DEOVERFLOW -DBUILD_DLL -I"..\my dll" -c ".....\my dll\main.cpp" -o obj\Release\main.o
mingw32-gcc.exe -O2 -Wall -DEOVERFLOW -DBUILD_DLL -I"..\my dll" -c ".....\my dll\subhook.c" -o obj\Release\subhook.o
mingw32-g++.exe -shared -Wl,--output-def="bin\Release\libmy dll.def" -Wl,--out-implib="bin\Release\libmy dll.a" -Wl,--dll  obj\Release\main.o obj\Release\subhook.o  -o "bin\Release\my dll.dll" -s  -luser32
In file included from .....\mydllinj\my dll\subhook.c:64:0:
.....\my dll\subhook_x86.c: In function 'subhook_disasm':
.....\my dll\subhook_x86.c:165:10: warning: variable 'address_size' set but not used [-Wunused-but-set-variable]
   size_t address_size = 4;
          ^~~~~~~~~~~~
obj\Release\main.o:main.cpp:(.text+0x21): undefined reference to `_imp__subhook_remove'
obj\Release\main.o:main.cpp:(.text+0x75): undefined reference to `_imp__subhook_install'
obj\Release\main.o:main.cpp:(.text+0xac): undefined reference to `_imp__subhook_new'
obj\Release\main.o:main.cpp:(.text+0xba): undefined reference to `_imp__subhook_install'
obj\Release\main.o:main.cpp:(.text+0xdd): undefined reference to `_imp__subhook_remove'
obj\Release\main.o:main.cpp:(.text+0xeb): undefined reference to `_imp__subhook_free'
collect2.exe: error: ld returned 1 exit status
Process terminated with status 1 (0 minute(s), 0 second(s))
7 error(s), 1 warning(s) (0 minute(s), 0 second(s))

("… …" = vollständigen Pfad weggelassen)

Hast du bitte noch eine Idee?
Erklärs für “Dummies” :blush:


#20

Aaalso: Das rechteckige Ding mit dem bunten Punkten, wo du gerade draufstarrst, nennt man “Bildschirm”.

:clown_face:

Jaja, mal im Ernst, schon klar: Irgendeine C-Lib schon zum Compilieren zu bringen, kann ein Krampf sein. (Einer von einer ganzen Liste von Gründen, warum Java einfach besser ist …).

Aber mal ganz oben angefangen:

cmake-gui (sollte bei der CMake-Installation dabei sein) starten. Dort kann man das Verzeichnis auswählen, wo die CMakeList.txt drin liegt. (D.h. z.B. subhook). Dann ein Build-Verzeichnis angeben. Ich nenne das normalerweise nach dem Muster subhook.build direkt nebenan. Dann auf “Generate” klicken. Er fragt dann, welcher Compiler es sein darf. Ich würde Visual Studio empfehlen. Wenn man unbedingt etwas anderes will, was auf makefiles/gcc aufsetzt, kann es halt krampfig werden, weil man sich dann mit mingw, cygwin und dem ganzen anderen Kram rumärgern muss, und wenn es um irgendwelchen low-level-Shyce wie DLL-Injection geht, wird das doppelt wackelig. Die Visual Studio Solution sollte man dann jedenfalls direkt aufmachen und Compilieren können, um seine subhook.dll zu erhalten. Die eigentlich zu injectende DLL ist dann nochmal was anderes, aber eine test.exe wird bei subhook schon mitgebaut.

Das ganze undefined reference bedeutet im wesentlichen, dass ihm eine library fehlt. Wenn du deine eigene library compilieren willst, musst du ihm irgendwo noch die subhook.lib im Linker-Aufruf mitgeben. Wie das (bei gcc) geht müßt’ ich auch erst nachsehen, aber jede IDE sollte ein UI dafür anbieten. Dafür sind die Dinger ja da.


#21

Danke.

Configuring incomplete, errors occurred!
See also ".../subhook/build/CMakeFiles/CMakeOutput.log".

Und dort steht nur eine einzige Zeile:
The system is: Windows - 10... - AMD64
:joy:

Heute wird das wohl nix.