It is currently Sat Dec 05, 2020 3:58 pm

All times are UTC + 1 hour




Post new topic Reply to topic  [ 32 posts ]  Go to page Previous  1, 2, 3
Author Message
 Post subject: Re: intercept API
PostPosted: Tue Mar 08, 2016 4:13 pm 
Offline
Addict
Addict
User avatar

Joined: Thu Feb 09, 2006 11:27 pm
Posts: 2551
DarkDragon wrote:
Well I've done a hooking-code which works on Windows 7 x64 compiled with 64bit and 32bit. It is basic hooking and uses the disassembler of purebasic, which sometimes really works wrong. And you can't call the old method at the moment.

http://www.bradan.eu/files/hook.zip (Your antivirus will recognize it as a virus, sorry)


I had a working tool to debug network traffic for a network game written in purebasic (4.x), but meantime (windows 8.1 instead of xp, purebasic version 5+) it doesn't work anymore...
...so I try to find an alternative to write a log file showing the network data of the program. I tried to modify your code but I wasn't able to hook the winsock functions receive and send...

TestDll.dll:
Code:

#HookMessages=   0
#HookWinsock=   1

; Define

   Declare MessageBoxAHook(Parent.i,*Text,*Title,Type.i)
   Declare WinsockSend(s.l,*buf,len.l,flags.l)
   Declare WinsockRecv(s.l,*buf,len.l,flags.l)

   Structure SFunction
      *OldAddress
      *NewAddress
      *Buffer
      BufferSize.i
      OldProtect.i
   EndStructure

   Global NewList Functions.SFunction()
   Global *WinsockSend
   Global *WinsockRecv
   Global Logging

   Procedure.s Disassemble(*Buffer,Length)
      Protected Result.s=""

      If ExamineAssembly(*Buffer,*Buffer+Length)
         Result=""
         While NextInstruction()
            If FindString(LCase(InstructionString()),"invalid",1) <= 0
               Result+InstructionString()+#CRLF$
            EndIf
         Wend
      EndIf

      ProcedureReturn Result
   EndProcedure
   Procedure.s HexMemory(*Buffer,Length)

      Protected k.i
      Protected Result.s=""

      For k=0 To Length-1
         Result+RSet(Hex(PeekA(*Buffer+k),#PB_Ascii),2,"0")+" "
      Next k

      ProcedureReturn Result

   EndProcedure
   Procedure Hook(*OldAddress,*NewAddress)

      Protected ProcessHandle.i
      Protected MemoryInfo.MEMORY_BASIC_INFORMATION
      Protected Length.i
      Protected i.i
      Protected Bytes.i
      Protected Disassembly.s
      Protected OldDisassembly.s

      CompilerIf #PB_Compiler_Processor=#PB_Processor_x64
         Protected JMP.u=$E0FF
         Protected MOV.u=$B848
      CompilerElse
         Protected JMP.u=$E0FF
         Protected MOV.a=$B8
      CompilerEndIf
      Protected NOP.a=$90
      Protected JumpAddress.i

      ProcessHandle=OpenProcess_(#PROCESS_ALL_ACCESS,#False,GetCurrentProcessId_())
      If ProcessHandle
         AddElement(Functions())
         Functions()\OldAddress=*OldAddress
         Functions()\NewAddress=*NewAddress
         Functions()\Buffer=AllocateMemory(64)

         VirtualQuery_(Functions()\OldAddress,@MemoryInfo,SizeOf(MEMORY_BASIC_INFORMATION))
         VirtualProtect_(MemoryInfo\BaseAddress,MemoryInfo\RegionSize,#PAGE_EXECUTE_READWRITE,@Functions()\OldProtect)

         ; read the memory block
         Length=SizeOf(JumpAddress)+SizeOf(JMP)+SizeOf(MOV)-1
         ReadProcessMemory_(ProcessHandle,Functions()\OldAddress,Functions()\Buffer,Length,@Bytes)
         Disassembly=Disassemble(Functions()\Buffer,Length)
         OldDisassembly=Disassembly
         While Length <= MemorySize(Functions()\Buffer) And OldDisassembly=Disassembly
            Length+1
            ReadProcessMemory_(ProcessHandle,Functions()\OldAddress,Functions()\Buffer,Length,@Bytes)

            OldDisassembly=Disassembly
            Disassembly=Disassemble(Functions()\Buffer,Length)
         Wend

         Functions()\Buffer=ReAllocateMemory(Functions()\Buffer,Length)
         Functions()\BufferSize=Length

         ; write our jump command to it
         JumpAddress=Functions()\NewAddress

         i=0
         WriteProcessMemory_(ProcessHandle,Functions()\OldAddress,@MOV,SizeOf(MOV),@Bytes)
         i+SizeOf(MOV)

         WriteProcessMemory_(ProcessHandle,Functions()\OldAddress+i,@JumpAddress,SizeOf(JumpAddress),@Bytes)
         i+SizeOf(JumpAddress)

         WriteProcessMemory_(ProcessHandle,Functions()\OldAddress+i,@JMP,SizeOf(JMP),@Bytes)
         i+SizeOf(JMP)

         ; fill the rest with NOP
         While i < Functions()\BufferSize
            WriteProcessMemory_(ProcessHandle,Functions()\OldAddress+i,@NOP,1,@Bytes)
            i+1
         Wend

         ; debug it
         *Buffer=AllocateMemory(SizeOf(JumpAddress)+5)
         ReadProcessMemory_(ProcessHandle,Functions()\OldAddress,*Buffer,SizeOf(JumpAddress)+5,@Bytes)
         CloseHandle_(ProcessHandle)
      EndIf

   EndProcedure
   Procedure Unhook(*NewAddress)
      Protected Result=#False
      Protected ProcessHandle.i
      Protected MemoryInfo.MEMORY_BASIC_INFORMATION
      Protected Protection.i
      Protected Bytes.i

      ForEach Functions()
         If Functions()\NewAddress=*NewAddress
            ProcessHandle=OpenProcess_(#PROCESS_ALL_ACCESS,#False,GetCurrentProcessId_())
            If ProcessHandle <> 0
               WriteProcessMemory_(ProcessHandle,Functions()\OldAddress,Functions()\Buffer,Functions()\BufferSize,@Bytes)

               VirtualQuery_(Functions()\OldAddress,@MemoryInfo,SizeOf(MEMORY_BASIC_INFORMATION))
               VirtualProtect_(MemoryInfo\BaseAddress,MemoryInfo\RegionSize,Functions()\OldProtect,@Protection)

               DeleteElement(Functions())
               Result=#True

               CloseHandle_(ProcessHandle)
            EndIf
            Break
         EndIf
      Next

      ProcedureReturn Result
   EndProcedure

   ProcedureDLL AttachProcess(Instance)
      
      ; MessageRequester("Start",Str(Instance))

      Protected *OldAddress
      Protected *NewAddress

      CompilerIf #HookMessages
         Library=OpenLibrary(#PB_Any,"user32.dll")
         If Library
            *OldAddress=GetFunction(Library,"MessageBoxA")
            *NewAddress=@MessageBoxAHook()
            If *OldAddress And *NewAddress
               ;MessageRequester("!","Message hooked")
               Hook(*OldAddress,*NewAddress)
            EndIf
            CloseLibrary(Library)
         EndIf
      CompilerEndIf

      CompilerIf #HookWinsock
         Library=LoadLibrary_("wsock32.dll")
         If Library
            MessageRequester("...",Str(Library))
            *WinsockSend=GetFunction(Library,"send")
            *WinsockRecv=GetFunction(Library,"recv")

            If *WinsockSend And *WinsockRecv
               *NewAddress=@WinsockSend()
               If *NewAddress
                  Hook(*WinsockSend,*NewAddress)
                  MessageRequester("Send hooked",Str(*WinsockSend)+#CR$+Str(*NewAddress))
               EndIf

               *NewAddress=@WinsockRecv()
               If *NewAddress
                  Hook(*WinsockRecv,*NewAddress)
                  MessageRequester("Receive hooked",Str(*WinsockRecv)+#CR$+Str(*NewAddress))
               EndIf
            EndIf

         EndIf

         If OpenFile(0,"Sniffer.log")
            Logging=#True
         EndIf
      CompilerEndIf

   EndProcedure
   ProcedureDLL DetachProcess(Instance)

      Unhook(@MessageBoxAHook())

      If Logging
         CloseFile(0)
      EndIf

   EndProcedure

; EndDefine

ProcedureDLL WinsockSend(s.l,*buf,len.l,flags.l)

   Result.l=CallFunctionFast(*WinsockSend,s.l,*buf,len.l,flags.l)

   If Logging
      WriteString(0,"> ")
      WriteData(0,*buf,len)
      WriteStringN(0,"")
   EndIf

   ProcedureReturn Result

EndProcedure
ProcedureDLL WinsockRecv(s.l,*buf,len.l,flags.l)

   Result.l = CallFunctionFast(*WinsockRecv,s.l,*buf,len.l,flags.l)

   If Logging
      WriteStringN(0, "< ")
      WriteData(0,*buf,len)
      WriteStringN(0,"")
   EndIf

   ProcedureReturn Result

EndProcedure
ProcedureDLL MessageBoxAHook(Parent.i,*Text,*Title,Type.i)

   Protected Window

   Window=OpenWindow(#PB_Any,0,0,320,240,"Information",#PB_Window_SystemMenu | #PB_Window_TitleBar,Parent)

   TextGadget(#PB_Any,10,10,300,220,"Hooked!")

   Repeat : Until WaitWindowEvent(5)=#PB_Event_CloseWindow
   CloseWindow(Window)

EndProcedure



TryMe.exe:
Code:
Procedure InjectLibary(ProcessID.i, Library.s)
   Protected ProcessHandle.i = 0
   Protected ThreadHandle.i = 0
   Protected *FilenameExtern
   Protected *FilenameIntern
   Protected KernelLibrary.i = 0
   Protected *LoadLibraryA = #Null
   Protected Result.i = #False

   ProcessHandle = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_CREATE_THREAD | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE, 0, ProcessID)

   If ProcessHandle = 0
      ProcedureReturn #False
   EndIf

   Size = StringByteLength(Library, #PB_Ascii) + 1
   If Size <= 0
      CloseHandle_(ProcessHandle)
      ProcedureReturn #False
   EndIf

   *FilenameExtern = VirtualAllocEx_(ProcessHandle, #Null, Size, #MEM_COMMIT, #PAGE_READWRITE)
   *FilenameIntern = AllocateMemory(Size)

   If *FilenameIntern <> #Null And *FilenameExtern <> #Null
      PokeS(*FilenameIntern, Library, -1, #PB_Ascii)

      If WriteProcessMemory_(ProcessHandle, *FilenameExtern, *FilenameIntern, Size, #Null) <> 0
         KernelLibrary = OpenLibrary(#PB_Any, "kernel32.dll")
         If KernelLibrary
            *LoadLibraryA = GetFunction(KernelLibrary, "LoadLibraryA")
            CloseLibrary(KernelLibrary)
         EndIf

         If *LoadLibraryA <> #Null
            ThreadHandle = CreateRemoteThread_(ProcessHandle, #Null, #Null, *LoadLibraryA, *FilenameExtern, #Null, #Null)

            If ThreadHandle <> 0
               WaitForSingleObject_(ThreadHandle, #INFINITE)

               Result = #True

               CloseHandle_(ThreadHandle)
               ThreadHandle = 0
            EndIf
         EndIf
      EndIf
   EndIf

   If *FilenameIntern <> #Null
      FreeMemory(*FilenameIntern)
      *FilenameIntern = #Null
   EndIf

   If *FilenameExtern <> #Null
      VirtualFreeEx_(ProcessHandle, *FilenameExtern, 0, #MEM_RELEASE)
      *FilenameExtern = #Null
   EndIf

   If ProcessHandle <> 0
      CloseHandle_(ProcessHandle)
      ProcessHandle = 0
   EndIf

   ProcedureReturn Result
EndProcedure

Process = RunProgram("TestEXE.exe", "", GetCurrentDirectory(), #PB_Program_Open)
If Process
   InjectLibary(ProgramID(Process),GetCurrentDirectory()+"TestDLL.dll")
EndIf


TestExe.exe:
Code:
Delay(2000)

OpenWindow(0,0,0,500,500,"")
WebGadget(0,0,0,500,500,"http://www.purebasic.com")

MessageRequester("Information",": (")


Top
 Profile  
Reply with quote  
 Post subject: Re: intercept API
PostPosted: Sun Apr 03, 2016 10:51 am 
Offline
Addict
Addict
User avatar

Joined: Mon Jun 02, 2003 9:16 am
Posts: 2111
Location: Germany
Michael Vogel wrote:
DarkDragon wrote:
Well I've done a hooking-code which works on Windows 7 x64 compiled with 64bit and 32bit. It is basic hooking and uses the disassembler of purebasic, which sometimes really works wrong. And you can't call the old method at the moment.

http://www.bradan.eu/files/hook.zip (Your antivirus will recognize it as a virus, sorry)


I had a working tool to debug network traffic for a network game written in purebasic (4.x), but meantime (windows 8.1 instead of xp, purebasic version 5+) it doesn't work anymore...
...so I try to find an alternative to write a log file showing the network data of the program. I tried to modify your code but I wasn't able to hook the winsock functions receive and send...
I haven't used windows and purebasic in a while now, but problems which could occur:

- the winsock libraries are not all loaded when you inject the hook
- the disassembler might still not be bugfree (I remember having problems with it)
- there is a jump/branch instruction right at the beginning of the functions which leads to really wrong behavior
- the functions use some anti-hook mechanisms (checking own memory or similar)

_________________
bye,
Daniel


Top
 Profile  
Reply with quote  
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 32 posts ]  Go to page Previous  1, 2, 3

All times are UTC + 1 hour


Who is online

Users browsing this forum: Majestic-12 [Bot] and 64 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
Jump to:  

 


Powered by phpBB © 2008 phpBB Group
subSilver+ theme by Canver Software, sponsor Sanal Modifiye