Hooking library zu laufen bekommen

Mit welchem Generator?

Mit dem VS Generator.
Es hat jetzt funktioniert,
CodeBlocks Generator ausgewählt & anschließend make…,
obiges C mit APIENTRY usw. funktioniert auch, .dll fertig,
lediglich die Adresse zur Funktion ist falsch gewesen,
bzw. ist sie noch falsch (weil man da noch wieder etwas subtrahieren und addieren muss).

Mit dem dll-injector-hacker_v0.5.exe kann ich dll injecten, mit CheatEngine nicht :frowning: ,
aber es erscheint noch keine Ausgabe; nehme an, es liegt an der Funktionsadresse.

Also, schnell zusammengefasst: Es ist auch mit MinGW, CodeBlocks, CMake, make (, gcc) + Injector möglich, aber sehr lustig ist es auch nicht. :smile:

@martin123 , @Marco13 :

Ein professioneller Hook sieht nebenbei so aus:

:slight_smile:

Aber eigentlich… Mich nervt fOlgendes:
Man muss erst einen Ferrari (VisualStudio) bauenhabn, um einen Schraubendreher (hier: .dll) herzustellen.
Stimmt’s?
:slight_smile:

Muss man nicht, aber unter Windows sind alternative Compiler eben etwas dünn gesät (und mit dem MinGW/Cygwin-Zeug war ich zumindest nie so ganz zufrieden - auch wenn es ein paar ansonsten ganz gute IDEs gibt…).

@Marco13 , weißt du zufällig, ob man nicht exportierte DLL-Funktionen auch hooken kann, wie man an die genaue Adresse kommt, und an die genaue „proper“ Funktionssignatur?

Wegen der Adresse: IDA, CheatEngine, Squalr und x64dbg geben alle unterschiedliche Adressen an, man muss immer hin und her rechnen, und landet dann nicht an der richtigen Stelle.

Wegen der Signatur: Keines der Tools spuckt eine Signatur aus.

Aber nun weiß ich wenigstens, wie man ein Funktions-Traceback machen kann… Finde den jüngsten gemeinsamen Vorfahren von mehreren Funktionen, die bestimmte Variablen schreiben. Sozusagen. :no_mouth:

Mit den Details kenne ich mich nicht aus. Ich dachte irgendwann mal, dass neuere Windows-Versionen (als “Virenschutz”) irgendeine Magie verwenden, um die Adressen zu verschleiern, aber das kann auch falsch sein.

super - Du machst Dein Problem noch komplexer

Naja, das stimmt. Aber das war der Versuch vor CMake.(*)

Naja, das stimmt. Vielleicht.


Möchtet ihr die Alternative wissen für das, was ich vorhab?
Zweiter Laptop, Webcam des zweiten Laptops auf den Monitor/Display, OCR Software… Und gooo…
Elegant ist das aber nicht… (oder doch?)


(*): -D (ohne Weiteres) setzt einfach eine 1 ein. Dann wird daraus -1.

Das Thema ist auch very nice:

>dumpbin /exports SciLexer.dll
Microsoft (R) COFF/PE Dumper Version .....
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file SciLexer.dll

File Type: DLL

  Section contains the following exports for SciLexer.dll

    00000000 characteristics
    580D515C time date stamp Mon Oct 24 02:10:04 2016
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 0003D696 Scintilla_DirectFunction

  Summary

        6000 .data
       1F000 .rdata
        9000 .reloc
        1000 .rsrc
       D5000 .text

Die Ergebnisse lediglich einer Funktion (Scintilla_DirectFunction) sind genau wie bei den anderen auch. Da gibt es aber mind. 1001 Funktionen…


Auch mit dem dort erwähnten Tool scheint das problematisch zu sein:

Diese Funktion
möchte ich hooken:

bw_plus_8

Alles fängt hier an:

bw_plus_9

Die typedef steht hier:


#define SUB_10099541_ADR 0x9A541            // ist die Adresse richtig?
typedef int (* sub_10099541)(DWORD, DWORD); // diese Funktion ist zu hooken
sub_10099541 func1 = 0;                     // diese Funktion ist zu hooken

attach() steht hier:

void attach()
{
    // This will get the DLL base address (which can vary)
    HMODULE hMod = GetModuleHandle("SciLexer.dll");
    // Calcualte the acutal address
    DWORD_PTR funcAddress = (DWORD_PTR)hMod + SUB_10099541_ADR;
    // Cast the address to a function poniter
    func1 = (sub_10099541)funcAddress;
    // Call the function

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

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

Die .dll lässt sich compilieren(!) aber nicht injizieren,
was mache ich falsch?

Vermutung: DWORD kann nicht richtig sein?

(*): letzte Freeware-Version von IDA Pro

Bin ich zu dämmlich, oder basieren alle Hooking Libs nur darauf, nur Funktionen zu hooken welche über einen Namen referenziert sind?

Und irgendwie schaff ich es nicht, im VS einfach eine Lib zu includen…

Prozesse, die explizit mit einer DLL verknüpft werden, rufen GetProcAddress auf, um die Adresse einer exportierten Funktion in der DLL zu erhalten.

Was genau ist denn LPFNDLLFUNC1?
Was genau macht denn GetProcAddress?
Wie genau wird denn eine Hex- Adresse einer nicht exportierten Funktion einer Dll eines Prozesses einem Pointer zugewiesen?

Das muss möglich sein(!), ich bin mir nur noch nicht sicher wie. :thinking:


Oder auch etwas komplizierter, kann ich/ kann man eine nicht exportierte Funktion „zu einer exportierten Funktion machen“, und zwar NACHDEM die Dll geladen wurde?

Präambel (das klingt lustig :smile: ):
C scheint der richtige Werkzeugkasten (wie das klingt :smile: ) zu sein…
CheatEngine und autoit können zwar auch hooken, jedoch zu high level
Jedoch ist C ohne Hooking library zu low level,
und zu „Byteebene“ runter möchte ich nicht.


So… die .exe heißt notepad++.exe
die .dll heißt SciLexer.dll

die Funktion, mit den Adressen:

SciLexer.dll+986B9 - 55                    - push ebp
SciLexer.dll+986BA - 56                    - push esi
SciLexer.dll+986BB - 57                    - push edi
SciLexer.dll+986BC - 8B F9                 - mov edi,ecx
SciLexer.dll+986BE - 8B 87 B4000000        - mov eax,[edi+000000B4]
SciLexer.dll+986C4 - 8B 28                 - mov ebp,[eax]
// ...
SciLexer.dll+987AA - 5B                    - pop ebx
SciLexer.dll+987AB - 5F                    - pop edi
SciLexer.dll+987AC - 5E                    - pop esi
SciLexer.dll+987AD - 5D                    - pop ebp
SciLexer.dll+987AE - C3                    - ret 

soll gehooked werden.

Sie wird (als Erstes) immer aufgerufen, wenn ein Zeichen eingetippt wird,
wahrscheinlich hat sie 3 Parameter und whrs. gibt sie nix zurück (C3),
wahrscheinlich wird 1 Parameter das gesuchte Zeichen sein.


Hat jmd. eine Idee, wie es zwar mit Hooking library,
aber ohne Funktionsnamen, geht gehen könnte?


Und falls das alles nix bringt, vergesst das ganze Thema wieder.

lalala… ich hab es hinbekommen mit der MS Detours library…
(um sie zu compilieren, braucht man aber unbedingt das in VS enthaltene nmake…)

// dllmain.cpp : Definiert den Einstiegspunkt für die DLL-Anwendung.
#include "stdafx.h"

typedef int(*sub_100986B9)(void);
sub_100986B9 func_to_sub_100986B9 = (sub_100986B9)(0x724186B9);

int sub_1(void) {
	printf("Hallo5\n");
	// here you have to call func_to_sub_100986B9 ....
	return 0;
}

BOOL APIENTRY DllMain(HMODULE hModule,
	DWORD  ul_reason_for_call,
	LPVOID lpReserved)
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	{
		FILE* pCout;
		// The important lines:
		AllocConsole();
		AttachConsole(GetCurrentProcessId());
		freopen_s(&pCout, "conout$", "w", stdout);
	}
	{
		printf("Let begin....\n");
		// here you have to call the MS Detour functions :)
		// (disable thread, transaction, update thread, attach(!), transaction, and so on...)
	}
	break;
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

Was macht es? Wenn ein Buchstabe (nicht Leerzeile etc) eingegeben wird, wird Hallo… in der Konsole ausgegeben.

So schaut das:


Das Thema ist dann wohl gelöst, oder? Die library funktioniert, und als Nächstes muss ich ein paar Register in Variablen speichern (welcher Buchstabe wurde eingegeben ?), das hat aber nix mehr mit dem Thema zu tun…

Infiniter Regress (+ Programmabsturz)! Keine Ahnung, warum. Nach dem technical write up sollte das eigentlich nicht passieren! Kann jemand mal schauen?

typedef int( * sub_100986B9)(void);
typedef int( * sub_1009430B)(int);
sub_100986B9 func_to_sub_100986B9; // später
sub_1009430B func_to_sub_1009430B;

int sub_1(void) {
	printf("Hallo555\n");

	int data1 = 0;
	__asm
	{
		mov data1, ecx
	}

	printf("%p   %x %d %c\n", data1, data1, data1, data1);

	// here you have to call func_to_sub_100986B9...
	return func_to_sub_100986B9(); // infiniter Regress
}


// ist erst mal vorsichtshalber ungehooked
int sub_2(int myint) {
	printf("myint: %x %d\n", myint, myint);
	return 0;
}

Kann an typedef liegen,
kann an späte Zuweisung an func_to_sub_100986B9 liegen,
kann an inline Asm liegen,
kann an printf liegen,
ratlos.

Mit return 0; funktioniert es MANCHMAL.


Edit: Noch jemand das Problem:


.text:10001000
.text:10001000 ; ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦ S U B R O U T I N E ¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦¦
.text:10001000
.text:10001000 ; Attributes: bp-based frame
.text:10001000
.text:10001000 sub_10001000    proc near               ; DATA XREF: DllMain+87o
.text:10001000                                         ; DllMain+AEo
.text:10001000
.text:10001000 var_4           = dword ptr -4
.text:10001000
.text:10001000                 push    ebp
.text:10001001                 mov     ebp, esp
.text:10001003                 push    ecx
.text:10001004                 push    offset aHallo555 ; "Hallo555\n"
.text:10001009                 call    printf
.text:1000100E                 add     esp, 4
.text:10001011                 mov     [ebp+var_4], 0
.text:10001018                 mov     [ebp+var_4], ecx
.text:1000101B                 mov     eax, [ebp+var_4]
.text:1000101E                 push    eax
.text:1000101F                 push    eax
.text:10001020                 push    eax
.text:10001021                 push    eax
.text:10001022                 push    offset aPXDC    ; "%p   %x %d %c\n"
.text:10001027                 call    printf
.text:1000102C                 add     esp, 14h
.text:1000102F                 call    func_to_sub_100986B9
.text:10001035                 mov     esp, ebp
.text:10001037                 pop     ebp
.text:10001038                 retn
.text:10001038 sub_10001000    endp
.text:10001038
.text:10001038 ; ---------------------------------------------------------------------------

call func_to_sub_100986B9 springt wieder nach 10001000. :frowning:

Ich versuche mal ein Detach, vielleicht klappt’s dann.

@Marco13 et al. Ich nutze ja das VS (17) von MS und bin dort auch mit meinem MS Account angemeldet.
(Da das mit CodeBlocks, den Libs und den Compiler-Optionen doch nicht so leicht ist.)
Mir ist aufgefallen, dass neu eingefügte Zeilen grün markiert werden, und beim Speichern dann die grüne Markierung verschwindet. (Und vice versa entfernte Zeilen rot, geänderte Zeilen blau.)
Du weißt nicht zufällig, ob, und was ich gar nicht möchte, da automatisch etwas committed wird - oder?

(Ich entwickle nur lokal was für mich lokal…)

Committed wird da IIRC nichts. Er trackt nur irgendwie intern magisch mit, wo etwas geändert wurde. Die Details habe ich aber auch gerade nicht im Kopf.

1 „Gefällt mir“

Danke Marco, bin ich erst mal beruhigt…


Ich verstehe es nicht.
Der eine Disassembler/Debugger sagt, da ist eine Funktion, der andere, da ist keine Funktion, und der dritte: Das ist aber mitten in einer Funktion.
Zudem: Spuckt der eine Decompiler für dieselbe Funktion eine komplett andere Funktion + Funktionssignatur aus, als es der andere Decompiler tut!

Sobald ich etwas ‚hooken‘ möchte, was über typedef void (*my_very_funny_handler)(void); hinausgeht, fliegt mir alles um die Ohren. :neutral_face:
Da ich natürlich nicht beim Bau der .dll dabei war, kann ich natürlich auch nicht den Compiler (+ ~Maschine) angeben…

Also, um es mal abzurunden, ja das eigentliche Thema ist schon gegessen…
Aber hättet ihr noch eine Empfehlung für einen guten Disassembler/Debugger und Decompiler für mich nach C?