Autor Beitrag
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 07.01.05 14:13 
Ich hab für eine Debug-Unit vor, die Windows-Funktion RaiseExcept, die ja in der Windows.pas deklariert ist, zu hooken. Das Überschreiben des Zeigers in der Windows.pas geht auch ganz gut, bis auf eine winzigkeit:

RaiseExcept wird in er System.pas im Implementation-Bereich auch bereits importiert, was dazu führt, dass der Delphi-Compiler einen doppelten Import anlegt.

Mein Problem ist nun, dass ich den allgemeinen Raise-Handler für ein eigenes Projekt überschreiben will und dafür beide Pointer (und evtl. auch alle weiteren) patchen muss.

Wie kann ich diese allgemeine Speicherersetzung möglichst effizient erledigen?

Laut meinen Forschungen gbt es einen Bereich, in dem alle Einsprungpunkte der statischen Funktionen aufgeführt sind. Wie kann ich diessen Größe und Basisadresse ermitteln?

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
raziel
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 2453

Arch Linux
JS (WebStorm), C#, C++/CLI, C++ (VS2013)
BeitragVerfasst: Fr 07.01.05 14:28 
BenBE hat folgendes geschrieben:
Laut meinen Forschungen gbt es einen Bereich, in dem alle Einsprungpunkte der statischen Funktionen aufgeführt sind. Wie kann ich diessen Größe und Basisadresse ermitteln?


Über den PE-Header ;)
Google mal nach Suche bei Google PEVIEW (okee, will mal nich so sein ;)). Lad eine Exe und schaus dir mal an, v.a. Import Table, den PE-Header und den optional Header. Irgendwo hab ich hier auch noch eine Doku zum PE-Format rumliegen, bei Interesse könnt ich dir ggf. noch schicken.


raziel

_________________
JSXGraph
BenBE Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 07.01.05 14:35 
Danke schonmal für die Info. Hab meinen Source aber grad net in der Schule ... PE-Header-Format habsch auch schon erstmal Infos da. Ich poste mal, wenn ich was neues hab.

Aber erstmal: THX :D

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
BenBE Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 07.01.05 20:52 
Ich hab durch Zufall nochmal einen alten Source von Aphex gefunden und für meine Zwecke angepasst. Funzt einwandfrei und nutz u.a. auch das PE-Format aus:

ausblenden volle Höhe Delphi-Quelltext
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:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
Unit Protection;
{
  Based on code by Aphex, 
  adapted and simplified by BenBE.

  Delphi Hooking Library by Aphex
  http://www.iamaphex.cjb.net/
  unremote@knology.net

  Now works on all versions thanks
  to help from Blacksoulman & madshi!

  madshi: dear@madshi.net
  Blacksoulman: blacksoulman@eml.cc
}


Interface

Uses
    Windows,
    Messages,
    SysUtils,
    Classes,
    Graphics,
    Controls,
    Forms,
    Dialogs, 
    StdCtrls;

Type
    TForm1 = Class(TForm)
        Procedure FormCreate(Sender: TObject);
    Private
        { Private-Deklarationen }
    Public
        { Public-Deklarationen }
    End;

Var
    Form1: TForm1;

Implementation

{$R *.DFM}

Type
    TImportFunction = Packed Record
        JumpInstr: Word;
        AddrOfPtr2Func: ^Pointer;
    End;

    TImageImportEntry = Record
        Characteristics: DWORD;
        TimeDateStamp: DWORD;
        MajorVersion: Word;
        MinorVersion: Word;
        Name: DWORD;
        LookupTable: DWORD;
    End;

Const                                                                           { copied from xx.h, recopied from System.pas }
    cContinuable = 0;
    cNonContinuable = 1;
    cUnwinding = 2;
    cUnwindingForExit = 4;
    cUnwindInProgress = cUnwinding Or cUnwindingForExit;
    cDelphiException = $0EEDFADE;
    cDelphiReRaise = $0EEDFADF;
    cDelphiExcept = $0EEDFAE0;
    cDelphiFinally = $0EEDFAE1;
    cDelphiTerminate = $0EEDFAE2;
    cDelphiUnhandled = $0EEDFAE3;
    cNonDelphiException = $0EEDFAE4;
    cDelphiExitFinally = $0EEDFAE5;
    cCppException = $0EEFFACE;                                                  { used by BCB }

Var
    PatchHandle: THandle;
    PatchOld: Pointer;

Function HookCode(TargetModule, TargetProc: String; NewProc: Pointer; Var OldProc: Pointer): Integer;

    Function FunctionAddress(Code: Pointer): Pointer;
    Begin
        Result := Code;
        If TImportFunction(Code^).JumpInstr = $25FF Then
            Result := TImportFunction(Code^).AddrOfPtr2Func^;
    End;

    Function HookModules(ImgDOSHdr: PImageDosHeader; TAddr, NAddr: Pointer; Var OAddr: Pointer): Integer;
    Var
        ImgNTHdr: PImageNtHeaders;
        ImgImportEntry: ^TImageImportEntry;
        ImportCode: ^Pointer;
        OldProtect: DWORD;
        EndofImports: DWORD;
    Begin
        Result := 0;

        OAddr := TAddr;
        If ImgDOSHdr.e_magic <> IMAGE_DOS_SIGNATURE Then
            Exit;

        ImgNTHdr := Pointer(Integer(ImgDOSHdr) + ImgDOSHdr._lfanew);
        If DWORD(ImgNTHdr) <> DWORD(ImgDOSHdr) Then
        Begin
            With ImgNTHdr^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT] Do
            Begin
                ImgImportEntry := Pointer(DWORD(ImgDOSHdr) + VirtualAddress);
                EndofImports := VirtualAddress + Size;
            End;

            If ImgImportEntry <> Nil Then
            Begin
                While ImgImportEntry^.Name <> 0 Do
                Begin
                    If ImgImportEntry^.LookupTable > EndofImports Then
                        Break;

                    If ImgImportEntry^.LookupTable <> 0 Then
                    Begin
                        ImportCode := Pointer(DWORD(ImgDOSHdr) + ImgImportEntry^.LookupTable);
                        While ImportCode^ <> Nil Do
                        Begin
                            If VirtualProtect(ImportCode, 4, PAGE_EXECUTE_READWRITE, @OldProtect) Then
                            Try
                                If ImportCode^ = TAddr Then
                                Begin
                                    ImportCode^ := NAddr;
                                    Inc(Result);
                                end;
                            Finally
                                VirtualProtect(ImportCode, 4, OldProtect, Nil);
                            End;
                            Inc(ImportCode);
                        End;
                    End;
                    Inc(ImgImportEntry);
                End;
            End;
        End;
    End;

Var
    Target: Pointer;
    Module, Base: Pointer;
    lpModuleName: Array[0..MAX_PATH] Of Char;
    MemInfo: TMemoryBasicInformation;

Begin
    Result := 0;
    OldProc := Nil;

    If GetVersion And $80000000 <> 0 Then
    Begin
        ShowMessage('Bad OS Version!');
        Exit;
    End;

    Module := Pointer(GetModuleHandle(PChar(TargetModule)));
    If Module = Nil Then
    Begin
        ShowMessage('Target Module not found!');
        Module := Pointer(LoadLibrary(PChar(TargetModule)));
    End;

    Target := GetProcAddress(HINST(Module), PChar(TargetProc));
    If Target = Nil Then
    Begin

        ShowMessage('Target Function not found!');
        Exit;
    End;

    Module := Nil;
    Base := Nil;

    While VirtualQueryEx(GetCurrentProcess, Module, MemInfo, SizeOf(MemInfo)) = SizeOf(MemInfo) Do
    Begin
        If (MemInfo.State = MEM_COMMIT) And (MemInfo.AllocationBase <> Base) And (MemInfo.AllocationBase = MemInfo.BaseAddress) And (GetModuleFilename(DWORD(MemInfo.AllocationBase), lpModuleName, MAX_PATH) > 0Then
        Begin
            If DWORD(MemInfo.AllocationBase) < $80000000 Then
                Inc(Result, HookModules(MemInfo.AllocationBase, Target, NewProc, OldProc));
        End;
        Base := MemInfo.AllocationBase;
        DWORD(Module) := DWORD(Module) + MemInfo.RegionSize;
    End;
End;

Procedure LocalRaiseExcept; Stdcall;
//Parameters:
//  dwExceptionCode: DWORD;
//  dwExceptionFlags: DWORD;
//  nNumberOfArguments: DWORD;
//  lpArguments: PDWORD;
Asm
    PUSHAD

    MOV     EBP, ESP

    MOV     EAX, DWORD PTR [EBP+$0C]
    CMP     DWORD PTR [EAX+$04], cDelphiException
    JNZ     @SkipHanding

    PUSH    0
    PUSH    OFFSET @Caption
    PUSH    OFFSET @Text
    CALL    GetDesktopWindow
    PUSH    EAX
    CALL    MessageBox

@SkipHanding:
    POPAD
    JMP     DWORD PTR [PatchOld]

@Text:
    DB      'Bereiten Sie sich auf eine schreckliche Exception vor!!!'0
@Caption:
    DB      'Warnung vor Fehler'0
End;

Procedure TForm1.FormCreate(Sender: TObject);
Begin
    PatchHandle := GetModuleHandle('RunException.exe');
    If HookCode('kernel32.dll''RaiseException', @LocalRaiseExcept, PatchOld) <> 0 Then
        MessageDlg('Raise Exception Hook successfully patched!', mtInformation, [mbOK], 0)
    Else
        MessageDlg('Raise Exception Hook failed patching!', mtError, [mbOK], 0);

    Raise Exception.Create('Test-Exception');
End;

End.


Bei Verwendung in eigenen Projekten bitte bei mir melden!

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.