Inline Hooking

Hi,

also ich hab mir grad überlegt, ( nachdem ich mir mal die habo wiki übers api hooking durchgelesen habe ), man könnte ja z.B. eine funktion übers inline hooking hooken, und dann in ne leere sektion direkt assembly reinkopieren um dorthin zu springen ( hook halt. )

aber wie erkennbar ist das ganze für programme die dagegen arbeiten? wird sowas i.d.r. genutzt?
 
Hallo,

den Artikel den du gelesen hast kommt wohl von mir, ist aber schon uralt :)

Ja du kannst in eine Funktion springen die direkt im Speicher des Programms liegt, am besten du allokierst
Speicher im Ziel Prozess und schreibst dann alles da rein.

Du kannst so komplett auf DLLs verzichten, ich hab den Winter Code geschrieben der genau das macht,
einen Hook setzen ohne DLL, das ganze is aber doch relativ komplex (die Funktionen die du injectest, die dann die original Funktionen ersetzen, müssen z.B komplett addressunabhängig sein etc etc.)

Wenn du also noch nicht gut programmieren kannst oder dich mit dem Speichermanagement von C Programmen nicht auskennst solltest du erstmal was anderes machen ;)

mfg,
Xalon
 
Nah, ich werds mal probieren und seh ja dann wie weit ich komme, mein problem sind dabei nicht die fehlenden programmierkenntnisse, jedoch eher das verständniss für die speicherverwaltung ( soo viell was man lernen will.. ) :) ( falls man diese nicht zu programmierkentnissen zählt, was man wohl aber teilweise auch tun kann ^.^ ).. man sieht sich dann wenns net klappt xD ( lange form für bald ! )
 
Original von Schurke
[...]
aber wie erkennbar ist das ganze für programme die dagegen arbeiten? wird sowas i.d.r. genutzt?

In der Regel genauso gut erkennbar wie übliche Hooks. Der einzige Unterschied besteht ja auch nur darin, dass der Callback sich in dem Fall nicht innerhalb einer Memory-Region eines registrierten Moduls befindet.
Diesen Unterschied kann man aber auch anders herstellen. Und zwar dadurch, dass man das Modul, was man in den Prozessraum injeziert, versteckt, indem man den Modul-Eintrag aus den 3 prozessinternen Modul-Listen löscht. Meine Implementation dazu sieht so aus [1].
Weitaus sicherer ist es aber das Modul manuell in dem fremden Prozessraum zu mappen. Also alles das was LoadLibrary macht selber machen. Von darawk gibt es da einen ganz guten Beispielcode (ManualMap) [2].

Das erkennen von Inline-Hooks geht ziemlich einfach. Und zwar vergleicht man einfach die Code-Section von dem Image auf der Festplatte mit seinem Pendant im Speicher. Ich habe dazu mal ein Tool (HookShark) geschrieben, welches das erledigt. [3]
HookShark kann auch Dlls verstecken und versteckte Dlls erkennen.



[1]
Code:
//============================================================================//
type
  pModNode = ^_ModNode;
  _ModNode = record
	  LoadOrder:    LIST_ENTRY;
	  InitOrder:    LIST_ENTRY;
	  MemoryOrder:  LIST_ENTRY;
	  baseAddress:  HMODULE;
	  entryPoint:   DWORD;
	  size:         DWORD;
	  fullPath:     UNICODE_STRING;
	  name:         UNICODE_STRING;
	  flags:        DWORD;
	  LoadCount:    DWORD;
	  TlsIndex:     DWORD;
	  HashTable:    LIST_ENTRY;
	  timestamp:    DWORD;
  end; 

type
  pLdrInfo = ^_LdrInfo;
  _LdrInfo = record
    size:         DWORD;
    initialized:  DWORD;
    SsHandle:     THandle;
    LoadOrder:    LIST_ENTRY;
    InitOrder:    LIST_ENTRY;
    MemoryOrder:  LIST_ENTRY;
  end;
  
//============================================================================//
function UnlinkAndWipeModEntry(Module: hModule): Boolean; stdcall;
var
  pMod:   pModNode;
  pmInfo: pLdrInfo;
begin
  result := False;
  asm
		mov eax, fs:[$18]		// TEB
		mov eax, [eax + $30]	// PEB
		mov eax, [eax + $0C]	// PROCESS_MODULE_INFO
		mov pmInfo, eax
	end;
 pMod := pModNode(pmInfo.LoadOrder.Flink);

 while ((pMod.baseAddress <> 0) and (pMod.baseAddress <> Module)) do
  pMod := pModNode(pMod.LoadOrder.Flink);

 if (pMod.baseAddress = 0) then
  Exit;

 pMod.LoadOrder.Blink.Flink := pMod.LoadOrder.Flink;
 pMod.LoadOrder.Flink.Blink := pMod.LoadOrder.Blink;

 pMod.InitOrder.Blink.Flink := pMod.InitOrder.Flink;
 pMod.InitOrder.Flink.Blink := pMod.InitOrder.Blink;

 pMod.MemoryOrder.Blink.Flink := pMod.MemoryOrder.Flink;
 pMod.MemoryOrder.Flink.Blink := pMod.MemoryOrder.Blink;

 ZeroMemory(pMod,sizeOf(_ModNode));

 result := True;
end;

[2] http://www.rootkit.com/newsread.php?newsid=360
[3] http://home.arcor.de/neotracer/hookshark.html
 
also ich hab mir dazu mal eben selbst was kleines gecoded...

http://pastebin.com/f66810c8a

ist noch nicht ganz fehlerfrei.. aber das soll nicht das problem sein,

was ich mich hier frage.

die gedumpte funktion, kommt in den allokierten bereich, und wenn ich mir das ganze dann in ollydbg anschaue dann wurde ein call falsch kopiert, ich versteh aber nicht ganz wieso.


Code:
00401290   - E9 6BEDD4FF          JMP 00150000 ; Vom Programm geschriebener jump
00401295     E8 46120000          CALL opfer.004024E0
0040129A     59                   POP ECX                                                       ; ntdll.7C961E40
0040129B     5D                   POP EBP                                                       ; ntdll.7C961E40
0040129C     C3                   RETN
0040129D     90                   NOP
0040129E     90                   NOP
0040129F     90                   NOP

funktion im allokiertem funktionsbereich
Code:
00150000     90                   NOP
00150001     90                   NOP
00150002     90                   NOP
00150003     90                   NOP
00150004     90                   NOP
00150005     90                   NOP
00150006     90                   NOP
00150007     90                   NOP
00150008     90                   NOP
00150009     90                   NOP
0015000A   - E9 F1FFFEFF          JMP 00140000

Gedumpte
Code:
00140000     55                   PUSH EBP
00140001     8BEC                 MOV EBP,ESP
00140003     6A 04                PUSH 4
00140005     E8 46120000          CALL 00141250 ; eindeutig falsch !
0014000A     59                   POP ECX                                                       ; ntdll.7C961E40
0014000B     5D                   POP EBP                                                       ; ntdll.7C961E40
0014000C     C3                   RETN

der hex code ist ja eindeutig gleich, nur ... wieso wird hier auf etwas anderes verlinkt?

--edit Funktioniert Call vll. genauso wie jmp mit offsets?
 
Wie du selbst bemerkt hast, gibt es bei SHORT und NEAR Branches entweder indirekte absolute oder direkte relative CALLs und JMPs.
 
Zurück
Oben