Hooking mit uallCollection

Ich habe die letzten Tage an einem Projekt gearbeitet, für das ich systemweit API-Aufrufe hooken können musste. Leider ist dieses Unterfangen nicht so einfach, wie das, was ich euch letztes Mal präsentiert habe.

Im Internet finden sich einige Lösungen für dieses Problem: Angefangen beim Schreiben von Systemtreibern, bis hin zum Injizieren von Threads in bereits laufende Prozesse. Besonders gut scheint das Paket madHookCode zu sein, das leider weder günstig noch einfach zu haben ist.
Glücklicherweise gibt es die uallCollection, die die gleiche Methode wie das Paket madHookCode zu benutzen scheint. Auch sonst scheinen die beiden Projekte eng miteinander verknüpft zu sein - für den Programmierer, der sich zwischen den beiden Paketen entscheiden muss, ist das jedenfalls ein Vorteil, da die uallCollection komplett kostenlos ist. 😉

Lediglich das Injizieren neu gestarteter Prozesse beherrscht die uallCollection nicht. Aber wozu hat man 10 gesunde Finger? Man kan sich relativ leicht eine Möglichkeit schaffen, um selber auf neue Prozesse zu reagieren:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
unit ProcessU;

interface

procedure HookProcess;
procedure UnhookProcess;

implementation

uses
  Windows,
  uallHook,
  MainU;

var
  VProcessLib : HMODULE = 0;

  VNewCreateProcessA : function (lpApplicationName: PChar; lpCommandLine: PChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;
  VOldCreateProcessA : function (lpApplicationName: PChar; lpCommandLine: PChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;
  VNewCreateProcessW : function (lpApplicationName: PWideChar; lpCommandLine: PWideChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;
  VOldCreateProcessW : function (lpApplicationName: PWideChar; lpCommandLine: PWideChar;
                         lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
                         bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
                         lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
                         var lpProcessInformation: TProcessInformation): BOOL; stdcall;

function CatchCreateProcessA(lpApplicationName: PChar; lpCommandLine: PChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall; forward;
function CatchCreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall; forward;

function CatchCreateProcessA(lpApplicationName: PChar; lpCommandLine: PChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall;
begin
  Result := VNewCreateProcessA(lpApplicationName, lpCommandLine, lpProcessAttributes,
                               lpThreadAttributes, bInheritHandles, dwCreationFlags,
                               lpEnvironment, lpCurrentDirectory, lpStartupInfo,
                               lpProcessInformation);

  if Result then
    InjectLibrary(lpProcessInformation.dwProcessId, PAnsiChar(GetDLLFileName));
end;
function CatchCreateProcessW(lpApplicationName: PWideChar; lpCommandLine: PWideChar;
  lpProcessAttributes, lpThreadAttributes: PSecurityAttributes;
  bInheritHandles: BOOL; dwCreationFlags: DWORD; lpEnvironment: Pointer;
  lpCurrentDirectory: PWideChar; const lpStartupInfo: TStartupInfo;
  var lpProcessInformation: TProcessInformation): BOOL; stdcall;
begin
  Result := VNewCreateProcessW(lpApplicationName, lpCommandLine, lpProcessAttributes,
                               lpThreadAttributes, bInheritHandles, dwCreationFlags,
                               lpEnvironment, lpCurrentDirectory, lpStartupInfo,
                               lpProcessInformation);

  if Result then
    InjectLibrary(lpProcessInformation.dwProcessId, PAnsiChar(GetDLLFileName));
end;

procedure HookProcess;
begin
  VProcessLib := GetModuleHandle(KERNEL32);
  if (VProcessLib <> 0) then
  begin
    @VOldCreateProcessA := GetProcAddress(VProcessLib, 'CreateProcessA');
    @VOldCreateProcessW := GetProcAddress(VProcessLib, 'CreateProcessW');

    HookCode(@VOldCreateProcessA, @CatchCreateProcessA, @VNewCreateProcessA);
    HookCode(@VOldCreateProcessW, @CatchCreateProcessW, @VNewCreateProcessW);
  end;
end;

procedure UnhookProcess;
begin
  if (VProcessLib <> 0) then
  begin
    VProcessLib := 0;

    UnhookCode(@VNewCreateProcessA);
    UnhookCode(@VNewCreateProcessW);
  end;
end;

end.

Für alle, die gerne mal sehen wollen, wie man dieses API-Hooking betreibt, habe ich ein einfaches Programm geschrieben. Mit RegRewrite ist es möglich, Einträge in der Registry durch andere Werte zu ersetzen. Sowohl die neuen Werte, als auch die Konfiguration des Programms werden in der Registry abgelegt 😉 .

Zum Schluss noch etwas Rechtliches:
Der Autor dieses Programms haftet nicht für Schäden an Soft- oder Hardware oder Vermögensschäden, die durch das Benutzen des Programms entstehen, es sei denn, diese beruhen auf einem grob fahrlässigen oder vorsätzlichen Handeln des Autors, seiner Erfüllungsgehilfen oder seiner gesetzlichen Vertreter.
Hookende Grüße, Kenny

Schreibe einen Kommentar

Um Ihnen beim weiteren Kommentieren auf dieser Webseite die erneute Eingabe Ihrer Daten zu ersparen, wird beim Absenden Ihres Kommentars ein Cookie an Ihren Browser gesendet und von diesem gespeichert. Mit dem Absenden eines Kommentars auf dieser Webseite stimmen Sie der Speicherung und Übertragung dieses Cookies explizit zu.

Pflichtfelder sind mit * markiert.