API Hook Engine Module (Windows)

Share your advanced PureBasic knowledge/code with the community.
Peyman
Enthusiast
Enthusiast
Posts: 203
Joined: Mon Dec 24, 2007 4:15 pm
Location: Iran

Re: API Hook Engine Module (Windows)

Post by Peyman »

Kwai chang caine wrote:For me that not works on v5.40 and W7 :|
Error in Injecting DLL to program
Perhaps a problem to translate something in french ?
in these cases you see errors :
1 - Target process and the DLL you want to inject is not in same family arch (X64 and X86).
2 - The Injector is X86 and the target process is X64. (this is the limit of my code)

in your case i think maybe target process and the DLL you are using have different Bin Code (X86 or X64), DLL and target must be same. you cant load a X64 Dll to a X86 Process or vice versa.

please check it and post again, thx.
Sorry for my bad english.
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: API Hook Engine Module (Windows)

Post by Kwai chang caine »

I don't understand, i try another time and that works now :shock:
It's strange because i have create the DLL and run the injector with the same x86 machine....

Thanks a lot for your answer, and obviously for your great code 8)
ImageThe happiness is a road...
Not a destination
digital
New User
New User
Posts: 5
Joined: Tue May 24, 2016 10:38 am

Re: API Hook Engine Module (Windows)

Post by digital »

From my test this didn't look work on Windows 10 32 bit while he work fine under windows 7. :cry:
Look a great snippet, but sad that don't work on last OS of Windows 10


EDIT: Infact just put a delay in main Thread() when you load DLL did the job and work now on windows 10
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Re: API Hook Engine Module (Windows)

Post by xakep »

@Peyman
Thanks for sharing, great work.

One quick question:

If with my hook i allways want to return 1, is it necesary to UnHook + Hook?

Like:

Code: Select all

Procedure My_Hook1(hwnd)
  Protected func.i
  
  func = UnHook(*Hook1)
  
  *Hook1 = Hook(func, @My_Hook1())
  
  ProcedureReturn 1
EndProcedure
OR

Code: Select all

Procedure My_Hook1(hwnd)
  ProcedureReturn 1

EndProcedure
Peyman
Enthusiast
Enthusiast
Posts: 203
Joined: Mon Dec 24, 2007 4:15 pm
Location: Iran

Re: API Hook Engine Module (Windows)

Post by Peyman »

@xakep,

your welcome. UnHook + call func + Hook again is for the MitM attack (Man in the Middle) or something like it, where you want to get the arguments and then pass it to real function and again hook that function.
in your situation you dont need it, even you can free *Hook1 with FreeMemory function if dont want to unhook again.
Sorry for my bad english.
xakep
User
User
Posts: 40
Joined: Fri Mar 25, 2016 2:02 pm
Location: Europe

Re: API Hook Engine Module (Windows)

Post by xakep »

Thanks for your reply.

I'm "just" looking to make my implementation fast & clean.
Mistrel
Addict
Addict
Posts: 3415
Joined: Sat Jun 30, 2007 8:04 pm

Re: API Hook Engine Module (Windows)

Post by Mistrel »

I have not looked into this closely but would I be able to inject and modify SetWindowsHookEx() on a per-process basis? I've encountered some poorly written programs over the years which set global hooks against the mouse instead of utilizing dinput or raw input and injects cursor lag onto the system. I would LOVE to be able to tweak that out.
Peyman
Enthusiast
Enthusiast
Posts: 203
Joined: Mon Dec 24, 2007 4:15 pm
Location: Iran

Re: API Hook Engine Module (Windows)

Post by Peyman »

@xakep,

np. Certainly its cleaner & faster if you dont use unhook and hook again.

@Mistrel,

yes its possible, in two phase you must create a dll with hooked procedures and force all processes to load that dll.
for phase two you can enumerate all processes and inject the dll to them, or use Windows Registry trick https://en.wikipedia.org/wiki/DLL_injection
Sorry for my bad english.
SeregaZ
Enthusiast
Enthusiast
Posts: 617
Joined: Fri Feb 20, 2009 9:24 am
Location: Almaty (Kazakhstan. not Borat, but Triple G)
Contact:

Re: API Hook Engine Module (Windows)

Post by SeregaZ »

can this code hide serial number of hdd from some programm?
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

Re: API Hook Engine Module (Windows)

Post by omnikam »

Sorry to start this thread up again, but it seems better than starting a new thread for the same subject.
This is not working for me on Win 8.1 64bit
i get the dll inject fail message
i changed my code to

Code: Select all

Define program = RunProgram("C:\Windows\SysWOW64\notepad.exe", "", "", #PB_Program_Open)
Define *func
Define DLL$ = "C:\Windows\SysWOW64\NotepadHook.dll"
Notepad loads but dll inject fails, is this a secure boot issue?
Does anyone have any idea`s ?
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: API Hook Engine Module (Windows)

Post by chi »

API_HookEngine.pbi change:

Code: Select all

BufferSize = Len(Dll$) * 2 + 1
to:

Code: Select all

BufferSize = Len(Dll$) * 2 + 2
Et cetera is my worst enemy
omnikam
User
User
Posts: 27
Joined: Sat Apr 15, 2017 10:58 am

Re: API Hook Engine Module (Windows)

Post by omnikam »

chi wrote:API_HookEngine.pbi change:

Code: Select all

BufferSize = Len(Dll$) * 2 + 1
to:

Code: Select all

BufferSize = Len(Dll$) * 2 + 2
Thanks for the quick reply :D I ended up getting it to work :lol: Not sure how though :P
I think it was a compiler issue, your change is for extra memory allocation?
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: API Hook Engine Module (Windows)

Post by chi »

omnikam wrote:your change is for extra memory allocation?
The InjectDll-demo (from Update 1.1) crashed with PB 5.60 + Debugger. Had the same issue with GetWindowTextLength_() the other day, so I knew where to fix the overflow ;). Thought it might also solve your problem...

Kudos to Peyman for this awesome hook engine!
Et cetera is my worst enemy
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: API Hook Engine Module (Windows)

Post by chi »

Better late than never... Fixed Unicode BufferSize (InjectDLL) and made it Win2k compatible :D

Code: Select all

; ====================================================================================================
; 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 parameter
;               1.3 (15 APR 2017) [by chi] fixed Unicode BufferSize (InjectDLL), made Win2k compatible
; Platform:     Windows (X64 And X86) Unicode And Ansi
; License:      Free But Any improvements to be shared with the community.
; ====================================================================================================
EnableExplicit

DeclareModule API_HookEngine
  Declare Hook(*OldFunctionAddress, *NewFunctionAddress)
  Declare UnHook(*hook_ptr)
  Declare ProcAddress(ModuleName$, ProcName$)
  Declare InjectDLL(PID, DLL$)
  Declare EjectDLL(PID, DLL$, *_Module = #Null)
  Declare IsInjected(PID, _Module$)
  Declare CallRemoteFunction(PID, *Func, Proc2Call$, WaitForReturn = #False, *retValue = #Null, *Parameter = #Null, nSize = #Null)
EndDeclareModule

Module API_HookEngine
  
  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
  
  Procedure _GetNativeSystemInfo(*info.SYSTEM_INFO) : EndProcedure
  Prototype _GetNativeSystemInfo(*info.SYSTEM_INFO)
  Global GetNativeSystemInfo__._GetNativeSystemInfo
  Define kernel32 = OpenLibrary(#PB_Any, "kernel32.dll")
  If kernel32
    GetNativeSystemInfo__ = GetFunction(kernel32, "GetNativeSystemInfo")
    If GetNativeSystemInfo__ = 0
      GetNativeSystemInfo__ = @_GetNativeSystemInfo()
    EndIf
    CloseLibrary(kernel32)
  Else
    GetNativeSystemInfo__ = @_GetNativeSystemInfo()
  EndIf
  
  Procedure 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 *OldFunctionAddress=0
      ProcedureReturn #Null
    EndIf
    
    *hook_ptr = AllocateMemory(SizeOf(hookstruct), #PB_Memory_NoClear)
    *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 WriteProcessMemory_(GetCurrentProcess_(), *OldFunctionAddress, @*hook_ptr\hook, SizeOf(opcode), #Null)=0
      FreeMemory(*hook_ptr)
      ProcedureReturn #Null
    Else
      ProcedureReturn *hook_ptr
    EndIf
  EndProcedure
  
  Procedure 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)
    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
        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
      ProcessHandle = OpenProcess_(#PROCESS_CREATE_THREAD | #PROCESS_QUERY_INFORMATION | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE | #PROCESS_VM_READ, #False, PID)
      If ProcessHandle
        BufferSize = Len(Dll$) * 2 + 2
        *dll_unicode = AllocateMemory(BufferSize, #PB_Memory_NoClear)
        PokeS(*dll_unicode, Dll$, -1, #PB_Unicode)
        *buffer = VirtualAllocEx_(ProcessHandle, #Null, BufferSize, #MEM_COMMIT, #PAGE_READWRITE)
        If *buffer
          WriteProcessMemory_(ProcessHandle, *buffer, *dll_unicode, BufferSize, #Null)
          ThreadHandle = CreateRemoteThread_(ProcessHandle, #Null, #Null, address, *buffer, #Null, #Null)
          If ThreadHandle
            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 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 IsInjected(PID, _Module$)
    Protected modules.MODULEENTRY32
    Protected snapshot, m_ok, retvalue = #False
    
    snapshot = CreateToolhelp32Snapshot_(#TH32CS_SNAPMODULE | #TH32CS_SNAPMODULE32, PID)
    If snapshot
      modules\dwSize = SizeOf(MODULEENTRY32)
      m_ok = Module32First_(snapshot, modules)
      While m_ok
        If FindString(PeekS(@modules\szModule), GetFilePart(_Module$), 1, #PB_String_NoCase)
          retvalue = #True
          Break
        EndIf
        m_ok = Module32Next_(snapshot, modules)
      Wend
      CloseHandle_(snapshot)
    EndIf
    
    ProcedureReturn retvalue
  EndProcedure
  
  Procedure CallRemoteFunction(PID, *Func, Proc2Call$, WaitForReturn = #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

;UseModule API_HookEngine

;DisableExplicit

Et cetera is my worst enemy
firace
Addict
Addict
Posts: 899
Joined: Wed Nov 09, 2011 8:58 am

Re: API Hook Engine Module (Windows)

Post by firace »

Trying it with LoadLibraryW (just to log each call), but no success (x64). Any idea why?

Code: Select all

; Simple Sample
IncludeFile "API_HookEngine.pbi"

Global *MessageBoxW

UseModule API_HookEngine

Procedure My_LoadLibrary(lpText$)
  Protected func.i
  Protected ret_value.i
  
  Debug "You Called LoadLibrary("+     lpText$  + ")"
  
;   func = UnHook(*MessageBoxW)
;   OpenLibrary(22, "kernel32.dll")
;   *abc = GetFunction(22, "LoadLibraryW")
;   ret_value = CallFunctionFast(*abc,@lpText$)
;   *MessageBoxW = Hook(func, *abc)
;   
  ProcedureReturn ret_value
EndProcedure



*MessageBoxW = Hook(ProcAddress("kernel32.dll", "LoadLibraryW"), @My_LoadLibrary())

Debug *MessageBoxW

OpenWindow(0, 100, 100, 140, 80, "")
EditorGadget(1,100,100,100,100)
Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow 
UnHook(*MessageBoxW)
Post Reply