Injected Dll Test in Notepad

Windows specific forum
tatanas
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Injected Dll Test in Notepad

Post by tatanas »

Hi there !

I'm trying to make it work an injected dll inside Notepad.exe. For now, the injection is OK but I can't get the handle of the notepad window.
I don't want to use FindWindow_(). Tested on Windows 7 64 bits, compiled in 64 bits

Dll code :

Code: Select all

Global hSASWnd.l, OldSASProc.l 


ProcedureDLL myWinProc(hWnd, uMsg, wParam, lParam)

	Select uMsg
		
		Case #WM_NCLBUTTONDBLCLK

			Select wParam			
				Case #HTCAPTION
					RunProgram("calc.exe")

			EndSelect

		Case #WM_NCLBUTTONDOWN
			
	EndSelect
	
	ProcedureReturn CallWindowProc_(OldSASProc, hWnd, uMsg, wParam, lParam)
	
EndProcedure


ProcedureDLL EnumProc(hwnd, lParam)
  *hwnd.LONG = lParam
  *hwnd\l = hwnd
  ProcedureReturn 0
EndProcedure

ProcedureDLL GetCallingHwnd() 
  EnumThreadWindows_(GetCurrentThreadId_(), @EnumProc(), @hwnd)
  ProcedureReturn hwnd
EndProcedure 


ProcedureDLL AttachProcess(hInstance)

	hSASWnd = GetCallingHwnd()
	MessageRequester("hSASWnd=", Str(hSASWnd))

	OldSASProc = GetWindowLong_(hSASWnd, #GWL_WNDPROC)
	SetWindowLong_(hSASWnd, #GWL_WNDPROC, @myWinProc())

EndProcedure

ProcedureDLL DetachProcess(hInstance)
	SetWindowLong_(hSASWnd, #GWL_WNDPROC, OldSASProc)
EndProcedure
Main code (to inject dll) :

Code: Select all

EnableExplicit

Procedure GetPidByName(pName.s)
	
	Protected.s processName.s = Space(#MAX_PATH)
	Protected pEntry.PROCESSENTRY32
	Protected.i hTool32, pId
	
	pEntry\dwSize = SizeOf(PROCESSENTRY32)
	hTool32 = CreateToolhelp32Snapshot_(#TH32CS_SNAPPROCESS, 0)
	pName = UCase(pName)
	
	Process32First_(hTool32, @pEntry)
	CopyMemory(@pEntry\szExeFile, @processName, #MAX_PATH)
	
	If UCase(processName) = pName
		pId = pEntry\th32ProcessID
	Else
		While Process32Next_(hTool32, @pEntry) > 0
			CopyMemory(@pEntry\szExeFile, @processName, #MAX_PATH)
			If UCase(processName) = pName
				pId = PEntry\th32ProcessID
				Break
			EndIf
		Wend
	EndIf
	
	CloseHandle_(hTool32)
	
	ProcedureReturn pId
	
EndProcedure

; Inject Library To A Target Process
; Both DLL And Process Must Be Unicode
; For ASCII: Change LoadLibraryW > LoadLibraryA And Modify Strings Related To pszLibFile
Procedure LoadLibrary(dwProcessId.i, pszLibFile.s)
	
	Protected.i hProcess, hThread, lzLibFileRemote, endSize, lsThreadRtn
	
	hProcess = OpenProcess_(#PROCESS_QUERY_INFORMATION | #PROCESS_CREATE_THREAD | #PROCESS_VM_OPERATION | #PROCESS_VM_WRITE, 0, dwProcessId)
	
	If hProcess = 0 : Goto ErrHandle : EndIf
	endSize = 1 + StringByteLength(pszLibFile)
	
	lzLibFileRemote = VirtualAllocEx_(hProcess, #Null, endSize, #MEM_COMMIT, #PAGE_READWRITE)
	
	If lzLibFileRemote = 0 : Goto ErrHandle : EndIf
	
	If WriteProcessMemory_(hProcess, lzLibFileRemote, pszLibFile, endSize, #Null) = 0 : Goto ErrHandle : EndIf
	
	CompilerIf #PB_Compiler_Unicode
		OpenLibrary(0, "Kernel32.dll") : lsThreadRtn = GetFunction(0, "LoadLibraryW") : CloseLibrary(0)
	CompilerElse
		OpenLibrary(0, "Kernel32.dll") : lsThreadRtn = GetFunction(0, "LoadLibraryA") : CloseLibrary(0)
	CompilerEndIf
	
	If lsThreadRtn = 0 : Goto ErrHandle : EndIf
	
	hThread = CreateRemoteThread_(hProcess, #Null, #Null, lsThreadRtn, lzLibFileRemote, #Null, #Null)
	
	If hThread = 0 : Goto ErrHandle : EndIf
	
	WaitForSingleObject_(hThread, #INFINITE)
	
	If lzLibFileRemote <> 0
		VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE)
		MessageRequester("Inject Status", "Injection Suceeded!", #MB_ICONINFORMATION)
	Else
		VirtualFreeEx_(hProcess, lzLibFileRemote, 0, #MEM_RELEASE)
		MessageRequester("Inject Status", "Injection Failed!", #MB_ICONERROR)
	EndIf
	End
	
	ErrHandle:
	CloseHandle_(hThread)
	CloseHandle_(hProcess)
	
EndProcedure

; ----- Main Program -----

CompilerIf #PB_Compiler_IsMainFile
	
	Define.s nDLL, procName = InputRequester("Simple DLL Injector", "Enter Target Process Name (*.exe):", "")
	Define.i pId = GetPidByName(procName)

	If pId
		nDLL = OpenFileRequester("Choose DLL File To Inject", "C:\", "DLL File (*.dll)|*.dll;*.dll", 0)
		If nDLL
			LoadLibrary(pId, nDLL)
		EndIf
	Else
		MessageRequester("Error", "Process ID Not Found!", #MB_ICONERROR)
	EndIf
	
CompilerEndIf
PS : Is there a way to pass the handle of the notepad window from the main program to the injected dll ?
Windows 10 Pro x64
PureBasic 6.04 x64
tatanas
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: Injected Dll Test in Notepad

Post by tatanas »

It seems I get the right handle with this code :

Code: Select all

Global hWinWnd.l, OldWinProc.l 

Procedure myWinProc(hWnd, uMsg, wParam, lParam)

	Select uMsg
		
		Case #WM_NCLBUTTONDBLCLK

			Select wParam			
				Case #HTCAPTION
					RunProgram("calc.exe")

			EndSelect

		Case #WM_NCLBUTTONDOWN
			
	EndSelect
	
	ProcedureReturn CallWindowProc_(OldWinProc, hWnd, uMsg, wParam, lParam)
	
EndProcedure

Procedure EnumWindowsProc(hWnd,lParam)
   GetWindowThreadProcessId_(hWnd,@lpProc)
   If lpProc=PeekL(lParam) ; process passed to EnumWindows is process found at this hwnd
      PokeL(lParam,hWnd) ; set ptr to hwnd
      ProcedureReturn 0
   EndIf
   ProcedureReturn 1
EndProcedure

Procedure GetProcHwnd()
   Protected pid = GetCurrentProcessId_()
   ptr=pid
   Repeat : Until EnumWindows_(@EnumWindowsProc(),@ptr)
   If ptr=pid ; if no handle is returned no matching process was found
      ProcedureReturn 0
   EndIf
   ; some form of GetWindow_() here for top-level window..
   ProcedureReturn ptr
EndProcedure


ProcedureDLL AttachProcess(hInstance)

	hWinWnd  = GetProcHwnd()

	OldWinProc = GetWindowLong_(hWinWnd, #GWL_WNDPROC)
	SetWindowLong_(hWinWnd, #GWL_WNDPROC, @myWinProc())

EndProcedure

ProcedureDLL DetachProcess(hInstance)
	SetWindowLong_(hWinWnd, #GWL_WNDPROC, OldWinProc)
EndProcedure

But NotePad is crashing as soons as the SetWindowLong_(hWinWnd, #GWL_WNDPROC, @myWinProc())...
Any idea ?
Last edited by tatanas on Tue Jan 28, 2020 10:54 am, edited 1 time in total.
Windows 10 Pro x64
PureBasic 6.04 x64
tatanas
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: Injected Dll Test in Notepad

Post by tatanas »

FOUND !

I just have to replace the type of the global variables "hWinWnd.l" and "OldWinProc.l" from long to integer (32 bits/64 bits I guess).
Windows 10 Pro x64
PureBasic 6.04 x64
User avatar
chi
Addict
Addict
Posts: 1028
Joined: Sat May 05, 2007 5:31 pm
Location: Linz, Austria

Re: Injected Dll Test in Notepad

Post by chi »

Never use SetWindowLong/GetWindowLong, use SetWindowLongPtr/GetWindowLongPtr instead!
GWL_WNDPROC returns a pointer to the window procedure and needs to be 8 bytes on x64.

Code: Select all

Global hWinWnd.l, OldWinProc.i

Procedure myWinProc(hWnd, uMsg, wParam, lParam)  
  Select uMsg
      
    Case #WM_NCLBUTTONDBLCLK      
      Select wParam
        Case #HTCAPTION
          RunProgram("calc.exe")          
      EndSelect
      
    Case #WM_NCDESTROY
      SetWindowLongPtr_(hWnd, #GWL_WNDPROC, @OldWinProc)
      
  EndSelect  
  ProcedureReturn CallWindowProc_(OldWinProc, hWnd, uMsg, wParam, lParam)  
EndProcedure

Procedure EnumWindowsProc(hWnd, lParam)
  GetWindowThreadProcessId_(hWnd, @lpProc)
  If lpProc = PeekL(lParam) ; process passed to EnumWindows is process found at this hwnd
    PokeL(lParam, hWnd)     ; set ptr to hwnd
    ProcedureReturn 0
  EndIf
  ProcedureReturn 1
EndProcedure

Procedure GetProcHwnd()
  Protected pid = GetCurrentProcessId_()
  ptr = pid
  Repeat : Until EnumWindows_(@EnumWindowsProc(), @ptr)
  If ptr = pid ; if no handle is returned no matching process was found
    ProcedureReturn 0
  EndIf
  ; some form of GetWindow_() here for top-level window..
  ProcedureReturn ptr
EndProcedure

ProcedureDLL AttachProcess(hInstance)
  
  hWinWnd  = GetProcHwnd()
  
  OldWinProc = SetWindowLongPtr_(hWinWnd, #GWL_WNDPROC, @myWinProc())
  
EndProcedure

ProcedureDLL DetachProcess(hInstance)
  
EndProcedure
[/size]
Et cetera is my worst enemy
tatanas
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: Injected Dll Test in Notepad

Post by tatanas »

I see. Thanks for the tip !
Windows 10 Pro x64
PureBasic 6.04 x64
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Injected Dll Test in Notepad

Post by Kwai chang caine »

It's not the first time i see this style of function in the forum, but always too much complex for me for use :oops:
And this time, it's reduced at the minimum and it's the first time i understand it :D

And miracle....furthermore ....that works for KCC too :shock:

Image

Thanks a lot at you two MASTERS, for this piece of code, who can be very usefull for me 8)
ImageThe happiness is a road...
Not a destination
tatanas
Enthusiast
Enthusiast
Posts: 198
Joined: Wed Nov 06, 2019 10:28 am
Location: France

Re: Injected Dll Test in Notepad

Post by tatanas »

De rien ;)
En rassemblant plusieurs bouts de code j'ai fini par y arriver.
Windows 10 Pro x64
PureBasic 6.04 x64
User avatar
Kwai chang caine
Always Here
Always Here
Posts: 5342
Joined: Sun Nov 05, 2006 11:42 pm
Location: Lyon - France

Re: Injected Dll Test in Notepad

Post by Kwai chang caine »

Tatanas wrote:De rien ;)
En rassemblant plusieurs bouts de code j'ai fini par y arriver.
En plus tu me répond en Français, merci 8) , si tu n'est pas Francophone, c'est encore plus fort :shock:
In english wrote:In addition you answer me in French, if you are not Francophone, it's even stronger: shock:
What would I give to be able to one day have this kind of conversation with you one day :oops:
Very interesting subject, sometimes masters are able to do real magic tricks on this forum, and what do I like that, this is surely one of the reasons that make us addicts of this language and his creator and masters users 8)
ImageThe happiness is a road...
Not a destination
Post Reply