home *** CD-ROM | disk | FTP | other *** search
- comment % A Windows NT pseudo resident Patcher - sourcecodes by Stone / UCF '98
- Thanks to Patriarch the almight.
- Jammer/UCF, Acp/UCF and Net Walker/Brazil :)
-
- A lot of the concepts and some of the code here is adopted from
- APISPY by Matt Pietrek 1995.
-
-
- email: stone@one.se
- http://www.one.se/~stone
-
- 2nd&mi!
-
- %
-
- CHUNKVA EQU 40305ch
- AbusePage EQU 402000h
-
- reg_Eip EQU 0b8h
-
- .386P
- Locals
- jumps
-
- .Model Flat ,StdCall
- Extrn ReadProcessMemory : PROC
- Extrn WriteProcessMemory : PROC
- Extrn LoadLibrary : PROC
- Extrn WaitForDebugEvent : PROC
- Extrn LoadLibraryA : PROC
- Extrn ContinueDebugEvent : PROC
- Extrn GetProcAddress : PROC
- Extrn GetThreadContext : PROC
- Extrn SetThreadContext : PROC
-
- UNICODE=0
- include w32.inc
-
- ;──────────────────────────────────────────────────────────────────────────────
- .Data
- FileName db "target.exe",0
- LibName db "flaf.dll",0
- Kernel db "kernel32.dll",0
- GetProcA db "GetProcAddress",0
- LoadLib db "LoadLibraryA",0
-
- hProcess dd 0 ; Process Info Structure
- hThread dd 0
- dwProcessID dd 0
- dwThreadID dd 0
-
- continueflags dd 010002h
-
- dwDebugEventCode dd 0 ; DebugEvent Structure
- _dwProcessID dd 0
- _dwThreadID dd 0
- U db 63h dup (0) ; space for structures
-
- ; The context structure *MUST* be at an address A so that (A and 3) = 0
- ; Why? - don't ask me why.. WIndows NT if fucked up wierd on that account!
- ; took me a couple of hours debugging to find that out!
- Context dd 00010001h ; Context flags.
- dd 33 dup (0) ; Space for Thread registers
-
- StartUpInfo dd 44h ; size of startup info-structure
- db 44h dup (0)
-
- NumberOfBytes dd 0 ; this many bytes written
- PatchThisOff dd AbusePage ; patch at this offset
-
-
-
- MoooH db "FLAF",0 ; name of function in DLL
- SaveEip dd 0
- ReadBuffer db 1000h dup (0) ; one full page.
- FirstEvent db TRUE
-
- .Code
- ;──────────────────────────────────────────────────────────────────────────────
- Main:
-
- call CreateProcessA, 0, offset FileName, 0, 0, FALSE, DEBUG_ONLY_THIS_PROCESS, 0, 0, offset StartUpInfo, offset hProcess
- test eax,eax
- jz abort
-
- RunProgram:
- call WaitForDebugEvent, offset dwDebugEventCode, -1
-
- cmp dword ptr [dwDebugEventCode],3
- jnz RunOn1
- lea edi, U ; delete U
- mov ecx, 40
- mov al,0
- rep stosb
- jmp RunOn
- RunOn1:
- cmp dword ptr [dwDebugEventCode],1
- jnz RunOn
- cmp dword ptr [U], STATUS_BREAKPOINT
- jnz RunOn
- call BreakPointEncountered
-
- RunOn:
- cmp dword ptr [dwDebugEventCode], 5 ; Exit_Process (Program terminated)
- jz ProgramTerminated
-
-
- push dword ptr [continueflags]
- push dword ptr [_dwThreadID]
- push dword ptr [_dwProcessID]
- call ContinueDebugEvent ; let the Program run on
-
-
- jmp RunProgram
-
- ProgramTerminated:
-
-
- abort:
- Push LARGE-1
- Call ExitProcess ; can't you guess? :)
-
- BreakPointEncountered PROC
-
- cmp byte ptr [FirstEvent], TRUE ; first time we inject the DLL
- jz FirstTime
-
- Call RestoreProcess ; second time we extract our code
- ret
-
- FirstTime:
- mov [FirstEvent], FALSE
- call CalculateCode ; calculate the code that loads the DLL
- ; and "hooks the API"
- call InjectDLL ; inject the DLL
-
- ret
- BreakPointEncountered EndP
-
- RestoreProcess PROC
- push offset NumberOfBytes ; Bytes written
- push 1000h
- push offset ReadBuffer
- push [PatchThisOff] ; write to here
- push [hProcess] ; using this handle
- call WriteProcessMemory
-
- mov eax, [SaveEip] ; restore EIP
- mov [Context+reg_Eip],eax
-
- push offset Context ; reSet Registers of child
- push [hThread]
- call SetThreadContext
-
- ret
- RestoreProcess ENDP
-
- InjectDLL PROC
- push offset NumberOfBytes ; Bytes written
- push 1000h ; [HowManyToPatch]
- push offset ReadBuffer
- push [PatchThisOff] ; Read From here
- push [hProcess] ; using this handle
- call ReadProcessMemory
-
- push offset NumberOfBytes ; Bytes written
- push AppEnd-AppStart
- push offset AppStart
- push [PatchThisOff] ; write to here
- push [hProcess] ; using this handle
- call WriteProcessMemory
-
-
- push offset Context ; Get Registers of child
- push [hThread]
- call GetThreadContext
-
- mov eax, [Context+reg_Eip] ; save EIP
- mov [SaveEip], eax
-
- mov eax, [PatchThisOff] ; Get Entrypoint - and set it as ThreadID
- mov [Context+reg_Eip],eax
-
- push offset Context ; Get Registers of child
- push [hThread]
- call SetThreadContext
-
- ret
- InjectDLL ENDP
-
- CalculateCode PROC
- ;----- Fetch addresses for LoadLib og GetProcAddress
- push offset Kernel ; find the Handle of Kernel32.dll
- call GetModuleHandleA
-
- push eax
-
- push offset LoadLib ; find the LoadLibraryA entrypoint
- push eax
- call GetProcAddress
- mov Dword ptr [AppLoadLib], eax ; save it
-
- pop eax
- push offset GetProcA ; get the GetProcessAddress ep
- push eax
- call GetProcAddress
- mov dword ptr [AppGetProc], eax ; save it
-
- ret
- CalculateCode ENDP
-
-
- .data
- WriteThis PROC
- AppStart:
- call Next ; Calculate "Delta offset"
- Next: pop ebp ; Not really need - because we know
- sub ebp, offset Next ; the VA of this code - but it's
- ; a convinient way of dealing with
- ; delta-problems
- mov eax, offset AppKernel
- add eax, ebp ; Adjust for Delta
- push eax
-
- mov edx, offset AppLoadLib
- add edx, ebp
-
-
- call dword ptr [EDX] ; Call LoadLibraryA
-
- mov ebx, offset AppFlaf
- add ebx, ebp
-
- push ebx
- push eax
- mov edx, offset AppGetProc
- add edx, ebp
- call dword ptr [EDX] ; call GetProcessAddress
-
- mov edx, [eax+2]
-
- mov ebx, offset ChunkVA
- add ebx, ebp
- mov ebx, [ebx] ; EBX = ChunkVA
- mov ecx, [ebx]
-
- mov [EDX],ecx ; IAT entry to "Own IAT" in DLL
- mov [ebx], eax ; DLL Function to IAT
-
- int 3 ; return to debugger
-
- AppKernel db "flaf.dll",0
- AppFlaf db "FLAF",0
-
- AppGetProc dd 0
- AppLoadLib dd 0
- ChunkVA dd CHUNKVA ; Chunk VA of Function to intercept
-
- AppEnd:
-
- WriteThis EndP
-
- ;──────────────────────────────────────────────────────────────────────────────
- End Main
-