Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; ====================================================================================================
- ; Title: API_HookEngine Module
- ; Description: With this module you can hook procedures and api in windows
- ; Author: Peyman
- ; Version: 1.0 (02 FEB 2016) initial version
- ; 1.1 (07 FEB 2016) added Inject DLL
- ; 1.2 (11 FEB 2016) improved injector, added Eject DLL & CallRemoteFunction with parrameter
- ; Platform: Windows (X64 And X86) Unicode And Ansi
- ; License: Free But Any improvements to be shared with the community.
- ; ====================================================================================================
- Import "Kernel32.lib";Hotfix
- GetProcAddress_(hMod.i, Name.p-ascii) As "_GetProcAddress@8"
- EndImport
- DeclareModule API_HookEngine
- Declare.i Hook(*OldFunctionAddress, *NewFunctionAddress)
- Declare.i UnHook(*hook_ptr)
- Declare.i ProcAddress(ModuleName$, ProcName$)
- Declare.i InjectDLL(PID, DLL$)
- Declare.b EjectDLL(PID, DLL$, *_Module = #Null)
- Declare.i CallRemoteFunction(PID, *Func, Proc2Call$, WaitForReturn.b = #False, *retValue = #Null, *Parameter = #Null, nSize = #Null)
- EndDeclareModule
- Module API_HookEngine
- EnableExplicit
- CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
- #INJECTOR_IS_64 = #True
- CompilerElse
- #INJECTOR_IS_64 = #False
- CompilerEndIf
- Structure opcode
- CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
- mov.u
- CompilerElse
- mov.a
- CompilerEndIf
- addr.i
- push.a
- ret.a
- EndStructure
- Structure hookstruct
- addr.i
- hook.opcode
- orig.a[SizeOf(opcode)]
- EndStructure
- CompilerIf #PB_Compiler_Unicode
- Import "kernel32.lib"
- GetProcAddress(hModule, lpProcName.p-ascii)
- EndImport
- CompilerElse
- Import "kernel32.lib"
- GetProcAddress(hModule, lpProcName.s)
- EndImport
- CompilerEndIf
- Import ""
- GetNativeSystemInfo(*info)
- EndImport
- Procedure.i ProcAddress(ModuleName$, ProcName$)
- Protected moduleH.i
- moduleH = GetModuleHandle_(ModuleName$)
- If moduleH = #Null
- moduleH = LoadLibrary_(ModuleName$)
- If moduleH = #Null
- ProcedureReturn #Null
- EndIf
- EndIf
- ProcedureReturn GetProcAddress(moduleH, ProcName$)
- EndProcedure
- Procedure Hook(*OldFunctionAddress, *NewFunctionAddress)
- Protected *hook_ptr.hookstruct
- If Not *OldFunctionAddress
- ProcedureReturn #Null
- EndIf
- *hook_ptr = AllocateMemory(SizeOf(hookstruct))
- *hook_ptr\addr = *OldFunctionAddress
- CompilerIf #PB_Compiler_Processor = #PB_Processor_x64
- *hook_ptr\hook\mov = $B848
- CompilerElse
- *hook_ptr\hook\mov = $B8
- CompilerEndIf
- *hook_ptr\hook\addr = *NewFunctionAddress
- *hook_ptr\hook\push = $50
- *hook_ptr\hook\ret = $C3
- CopyMemory(*OldFunctionAddress, @*hook_ptr\orig, SizeOf(opcode))
- If Not WriteProcessMemory_(GetCurrentProcess_(), *OldFunctionAddress, @*hook_ptr\hook, SizeOf(opcode), #Null)
- FreeMemory(*hook_ptr)
- ProcedureReturn #Null
- Else
- ProcedureReturn *hook_ptr
- EndIf
- EndProcedure
- Procedure.i UnHook(*hook_ptr.hookstruct)
- Protected retValue.i
- If *hook_ptr
- If *hook_ptr\addr
- If WriteProcessMemory_(GetCurrentProcess_(), *hook_ptr\addr, @*hook_ptr\orig, SizeOf(opcode), #Null)
- retValue = *hook_ptr\addr
- FreeMemory(*hook_ptr)
- ProcedureReturn retValue
- EndIf
- EndIf
- EndIf
- ProcedureReturn #Null
- EndProcedure
- Procedure Is64Process(PID); is the Process is 64;
- Protected *IsWow64Process, retvalue, hProcess
- Protected Info.SYSTEM_INFO, is_64 = #False
- GetNativeSystemInfo(Info)
- If info\wProcessorArchitecture = 9 ; is a X64 os
- *IsWow64Process = ProcAddress("kernel32.dll", "IsWow64Process")
- If *IsWow64Process
- hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION, #False, PID)
- If hProcess
- CallFunctionFast(*IsWow64Process, hProcess, @retvalue)
- CloseHandle_(hProcess)
- If retvalue = #False
- is_64 = #True
- EndIf
- EndIf
- EndIf
- EndIf
- ProcedureReturn is_64
- EndProcedure
- Procedure TraverseRemoteModules(PID, _Module$)
- Protected modules.MODULEENTRY32
- Protected snapshot, m_ok, modBaseAddr
- snapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPMODULE | #TH32CS_SNAPMODULE32, PID)
- If snapshot
- modules\dwSize = SizeOf(MODULEENTRY32)
- m_ok = Module32First_(snapshot, modules)
- While m_ok
- Debug PeekS(@modules\szModule)
- If FindString(PeekS(@modules\szModule), _Module$, 1, #PB_String_NoCase)
- modBaseAddr = modules\modBaseAddr
- Break
- EndIf
- m_ok = Module32Next_(snapshot, modules)
- Wend
- CloseHandle_(snapshot)
- EndIf
- ProcedureReturn modBaseAddr
- EndProcedure
- Procedure TraverseRemoteProcs(PID, _Module$, ProcName$, *_Module = #Null)
- Protected hProcess, modBaseAddr, retValue = #Null
- Protected index, index2, TempChar.a, TempFunctionName.s
- Protected DosHeader.IMAGE_DOS_HEADER
- Protected Signature.l
- Protected FileHeader.IMAGE_FILE_HEADER
- Protected Is64Bit.b
- Protected OptHeader64.IMAGE_OPTIONAL_HEADER64
- Protected OptHeader32.IMAGE_OPTIONAL_HEADER32
- Protected ExportDirectory.IMAGE_DATA_DIRECTORY
- Protected ExportTable.IMAGE_EXPORT_DIRECTORY
- Protected Dim ExportFunctionTable.l(0)
- Protected Dim ExportNameTable.l(0)
- Protected Dim ExportOrdinalTable.w(0)
- hProcess = OpenProcess_(#PROCESS_VM_READ, #False, PID)
- If hProcess
- If *_Module
- modBaseAddr = *_Module
- Else
- modBaseAddr = TraverseRemoteModules(PID, _Module$)
- EndIf
- If Not modBaseAddr
- Goto TRM_END
- EndIf
- If ReadProcessMemory_(hProcess, modBaseAddr, @DosHeader, SizeOf(IMAGE_DOS_HEADER), #Null) And DosHeader\e_magic <> $5A4D
- Goto TRM_END
- EndIf
- If ReadProcessMemory_(hProcess, modBaseAddr + DosHeader\e_lfanew, @Signature, SizeOf(Signature), #Null) And Signature <> $4550
- Goto TRM_END
- EndIf
- If Not ReadProcessMemory_(hProcess, modBaseAddr + DosHeader\e_lfanew + SizeOf(Signature), @FileHeader, SizeOf(IMAGE_FILE_HEADER), #Null)
- Goto TRM_END
- EndIf
- If FileHeader\SizeOfOptionalHeader = SizeOf(IMAGE_OPTIONAL_HEADER64)
- Is64Bit = #True
- ElseIf FileHeader\SizeOfOptionalHeader = SizeOf(IMAGE_OPTIONAL_HEADER32)
- Is64Bit = #False
- Else
- Goto TRM_END
- EndIf
- If Is64Bit
- If ReadProcessMemory_(hProcess, modBaseAddr + DosHeader\e_lfanew + SizeOf(Signature) + SizeOf(IMAGE_FILE_HEADER), @OptHeader64, FileHeader\SizeOfOptionalHeader, #Null) And OptHeader64\Magic <> $020B
- Goto TRM_END
- EndIf
- Else
- If ReadProcessMemory_(hProcess, modBaseAddr + DosHeader\e_lfanew + SizeOf(Signature) + SizeOf(IMAGE_FILE_HEADER), @OptHeader32, FileHeader\SizeOfOptionalHeader, #Null) And OptHeader32\Magic <> $010B
- Goto TRM_END
- EndIf
- EndIf
- If Is64Bit And OptHeader64\NumberOfRvaAndSizes >= #IMAGE_DIRECTORY_ENTRY_EXPORT + 1
- ExportDirectory\VirtualAddress = OptHeader64\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\VirtualAddress
- ExportDirectory\Size = OptHeader64\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\Size
- ElseIf OptHeader32\NumberOfRvaAndSizes >= #IMAGE_DIRECTORY_ENTRY_EXPORT + 1
- ExportDirectory\VirtualAddress = OptHeader32\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\VirtualAddress
- ExportDirectory\Size = OptHeader32\DataDirectory[#IMAGE_DIRECTORY_ENTRY_EXPORT]\Size
- Else
- Goto TRM_END
- EndIf
- If Not ReadProcessMemory_(hProcess, modBaseAddr + ExportDirectory\VirtualAddress, @ExportTable, SizeOf(IMAGE_EXPORT_DIRECTORY), #Null)
- Goto TRM_END
- EndIf
- ReDim ExportFunctionTable(ExportTable\NumberOfFunctions)
- ReDim ExportNameTable(ExportTable\NumberOfNames)
- ReDim ExportOrdinalTable.w(ExportTable\NumberOfNames)
- If Not ReadProcessMemory_(hProcess, modBaseAddr + ExportTable\AddressOfFunctions, @ExportFunctionTable(), ExportTable\NumberOfFunctions * SizeOf(Long), #Null)
- Goto TRM_END
- EndIf
- If Not ReadProcessMemory_(hProcess, modBaseAddr + ExportTable\AddressOfNames, @ExportNameTable(), ExportTable\NumberOfNames * SizeOf(Long), #Null)
- Goto TRM_END
- EndIf
- If Not ReadProcessMemory_(hProcess, modBaseAddr + ExportTable\AddressOfNameOrdinals, @ExportOrdinalTable(), ExportTable\NumberOfNames * SizeOf(Word), #Null)
- Goto TRM_END
- EndIf
- For index = 0 To ExportTable\NumberOfNames - 1
- TempFunctionName = ""
- index2 = 0
- Repeat
- If Not ReadProcessMemory_(hProcess, modBaseAddr + ExportNameTable(index) + index2, @TempChar, SizeOf(TempChar), #Null)
- Break 2
- EndIf
- If TempChar = #Null
- Break
- Else
- TempFunctionName + Chr(TempChar)
- EndIf
- index2 + 1
- ForEver
- If TempFunctionName = ProcName$
- retValue = modBaseAddr + ExportFunctionTable(ExportOrdinalTable(index))
- Break
- EndIf
- Next
- TRM_END:
- CloseHandle_(hProcess)
- FreeArray(ExportFunctionTable())
- FreeArray(ExportNameTable())
- FreeArray(ExportOrdinalTable())
- EndIf
- ProcedureReturn retValue
- EndProcedure
- Procedure InjectDLL(PID.i, DLL$)
- Protected address, ThreadHandle, BufferSize, *buffer
- Protected ProcessHandle.i, retvalue = #Null, *dll_unicode
- Protected is_target_64.b = #False
- If FileSize(Dll$) > 0
- is_target_64 = Is64Process(PID)
- If #INJECTOR_IS_64 = is_target_64
- address = ProcAddress("kernel32.dll", "LoadLibraryW")
- ElseIf #INJECTOR_IS_64
- address = TraverseRemoteProcs(PID, "kernel32.dll", "LoadLibraryW")
- Else
- Debug "X86 Injector --> X64 Target not Supported yet!!"
- ProcedureReturn #Null
- EndIf
- Debug address
- ProcessHandle = OpenProcess_(#PROCESS_CREATE_THREAD | #PROCESS_QUERY_INFORMATION | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE | #PROCESS_VM_READ, #False, PID)
- If ProcessHandle
- Debug "A"
- BufferSize = Len(Dll$) * 2 + 1
- *dll_unicode = AllocateMemory(BufferSize)
- PokeS(*dll_unicode, Dll$, -1, #PB_Unicode)
- *buffer = VirtualAllocEx_(ProcessHandle, #Null, BufferSize, #MEM_COMMIT, #PAGE_READWRITE)
- If *buffer
- Debug "B"
- WriteProcessMemory_(ProcessHandle, *buffer, *dll_unicode, BufferSize, #Null)
- ThreadHandle = CreateRemoteThread_(ProcessHandle, #Null, #Null, address, *buffer, #Null, #Null)
- If ThreadHandle
- Debug "C"
- WaitForSingleObject_(ThreadHandle, #INFINITE)
- CloseHandle_(ThreadHandle)
- retvalue = TraverseRemoteModules(PID, GetFilePart(Dll$))
- EndIf
- VirtualFreeEx_(ProcessHandle, *buffer, #Null, #MEM_RELEASE)
- EndIf
- CloseHandle_(ProcessHandle)
- FreeMemory(*dll_unicode)
- EndIf
- EndIf
- ProcedureReturn retvalue
- EndProcedure
- Procedure.b EjectDLL(PID, DLL$, *_Module = #Null)
- Protected address, ThreadHandle
- Protected ProcessHandle, retvalue = #False
- Protected is_target_64.b = #False
- If FileSize(Dll$) > 0 Or *_Module
- is_target_64 = Is64Process(PID)
- If #INJECTOR_IS_64 = is_target_64
- address = ProcAddress("kernel32.dll", "FreeLibrary")
- ElseIf #INJECTOR_IS_64
- address = TraverseRemoteProcs(PID, "kernel32.dll", "FreeLibrary")
- Else
- Debug "X86 Ejector --> X64 Target not Supported yet!!"
- ProcedureReturn #False
- EndIf
- If Not *_Module
- *_Module = TraverseRemoteModules(PID, GetFilePart(DLL$))
- If Not *_Module
- ProcedureReturn #False
- EndIf
- EndIf
- ProcessHandle = OpenProcess_(#PROCESS_CREATE_THREAD | #PROCESS_QUERY_INFORMATION | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE | #PROCESS_VM_READ, #False, PID)
- If ProcessHandle
- ThreadHandle = CreateRemoteThread_(ProcessHandle, #Null, #Null, address, *_Module, #Null, #Null)
- If ThreadHandle
- WaitForSingleObject_(ThreadHandle, #INFINITE)
- CloseHandle_(ThreadHandle)
- retvalue = #True
- EndIf
- CloseHandle_(ProcessHandle)
- EndIf
- EndIf
- ProcedureReturn retvalue
- EndProcedure
- Procedure CallRemoteFunction(PID, *Func, Proc2Call$, WaitForReturn.b = #False, *retValue = #Null, *Parameter = #Null, nSize = #Null)
- Protected ret, ProcessHandle, address, *buffer
- Protected ThreadHandle
- ProcessHandle = OpenProcess_(#PROCESS_CREATE_THREAD | #PROCESS_QUERY_INFORMATION | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE | #PROCESS_VM_READ, #False, PID)
- If ProcessHandle
- address = TraverseRemoteProcs(PID, "", Proc2Call$, *Func)
- If address
- *buffer = #Null
- If *Parameter And nSize
- *buffer = VirtualAllocEx_(ProcessHandle, #Null, nSize, #MEM_COMMIT, #PAGE_READWRITE)
- WriteProcessMemory_(ProcessHandle, *buffer, *Parameter, nSize, #Null)
- EndIf
- ThreadHandle = CreateRemoteThread_(ProcessHandle, #Null, #Null, address, *buffer, #Null, #Null)
- If ThreadHandle
- If WaitForReturn
- WaitForSingleObject_(ThreadHandle, #INFINITE)
- If *retValue
- GetExitCodeThread_(ProcessHandle, *retValue)
- EndIf
- EndIf
- CloseHandle_(ThreadHandle)
- ret = #True
- EndIf
- If *buffer
- VirtualFreeEx_(ProcessHandle, *buffer, #Null, #MEM_RELEASE)
- EndIf
- CloseHandle_(ProcessHandle)
- EndIf
- EndIf
- ProcedureReturn ret
- EndProcedure
- EndModule
- #PROCESS_ALL_ACCESS_VISTA_WIN7 = $1FFFFF
- Prototype.i PFNCreateToolhelp32Snapshot(dwFlags.i, th32ProcessID.i) ;
- Prototype.b PFNProcess32First(hSnapshot.i, *lppe.PROCESSENTRY32) ;
- Prototype.b PFNProcess32Next(hSnapshot.i, *lppe.PROCESSENTRY32) ;
- Procedure GetPidByName(p_name$)
- Protected hDLL.i, process_name$
- Protected PEntry.PROCESSENTRY32, hTool32.i
- Protected pCreateToolhelp32Snapshot.PFNCreateToolhelp32Snapshot
- Protected pProcess32First.PFNProcess32First
- Protected pProcess32Next.PFNProcess32Next
- Protected pid.i
- hDLL = OpenLibrary(#PB_Any,"kernel32.dll")
- If hDLL
- pCreateToolhelp32Snapshot = GetFunction(hDLL,"CreateToolhelp32Snapshot")
- pProcess32First = GetFunction(hDLL,"Process32FirstW")
- pProcess32Next = GetFunction(hDLL,"Process32NextW")
- Else
- ProcedureReturn 0
- EndIf
- PEntry\dwSize = SizeOf(PROCESSENTRY32)
- hTool32 = pCreateToolhelp32Snapshot(#TH32CS_SNAPPROCESS, 0)
- pProcess32First(hTool32, @PEntry)
- process_name$ = PeekS(@PEntry\szExeFile,#PB_Unicode)
- Debug GetFilePart(UCase(process_name$))
- If GetFilePart(UCase(process_name$)) = GetFilePart(UCase(p_name$) )
- ProcedureReturn PEntry\th32ProcessID
- EndIf
- While pProcess32Next(hTool32, @PEntry) > 0
- process_name$ = PeekS(@PEntry\szExeFile,#PB_Unicode)
- If GetFilePart(UCase(process_name$)) = GetFilePart(UCase(p_name$) )
- ProcedureReturn PEntry\th32ProcessID
- EndIf
- Wend
- CloseLibrary(hDLL)
- ProcedureReturn 0
- EndProcedure
- UseModule API_HookEngine
- Debug GetPidByName("LinkEngKM.exe")
- Debug InjectDLL( GetPidByName("LinkEngKM.exe"), "D:\io8.dll")
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement