Announcement

Collapse
No announcement yet.

MemoryEx: GetWindowThreadProcessId

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • MemoryEx: GetWindowThreadProcessId

    GetWindowThreadProcessId lpdwProcessId is a LPDWORD pointer, how do I deal with that, will be running in a loop so I need to define it then grab the value then cfhck it?

    And Bas, can we get the option for callback function pointers?

  • #2
    Here is some code for what I'm trying to do:

    Code:
    --- Global
    
    User32 = Library.Load("user32.dll");
    Kernel32 = Library.Load("Kernel32.dll");
    
    Exe = {}
    Exe.Pid = 0;
    Exe.hdl = 0;
    Exe.Path = "my.exe";
    Exe.StartExe = function()
     System.TerminateProcess(Exe.Pid)
     local STARTUPINFO = MemoryEx.DefineStruct{
      DWORD "cb";
      STRING ("lpReserved",256,1,MEMEX_ASCII);
      STRING ("lpDesktop",256,1,MEMEX_ASCII);
      STRING ("lpTitle",256,1,MEMEX_ASCII);
      DWORD "dwX";
      DWORD "dwY";
      DWORD "dwXSize";
      DWORD "dwYSize";
      DWORD "dwXCountChars";
      DWORD "dwYCountChars";
      DWORD "dwFillAttribute";
      DWORD "dwFlags";
      WORD "wShowWindow";
      WORD "cbReserved2";
      BYTE "lpReserved2";
      INT "hStdInput";
      INT "hStdOutput";
      INT "hStdError";
     }
     local PROCESS_INFORMATION = MemoryEx.DefineStruct{
      INT "hProcess";
      INT "hThread";
      DWORD "dwProcessId";
      DWORD "dwThreadId";
     }
     local P = PROCESS_INFORMATION:New()
     local S = STARTUPINFO:New()
     S.cb = S:Size()
     S.lpReserved = 0
     S.dwFlags = 0x00002000 + 0x00000001
     S.wShowWindow = 7
     Exe.hdl = 0
     if Kernel32.CreateProcessA(Exe.Path,0,0,0,0,0,0,0,S:GetPointer(),P:GetPointer()) ~= 0 then
      User32.WaitForInputIdle(P.dwThreadId,20000)
      Exe.Pid = P.dwProcessId
      local proc = Window.EnumerateProcesses(false)
      for hdl,path in pairs(proc) do
       if path == Exe.Path then
        Exe.hdl = hdl
        break
       end
      end
      if Exe.hdl == 0 then
       System.TerminateProcess(Exe.Pid)
       P:Free();S:Free();
       return false
      else
       P:Free();S:Free();
       return true
      end
     else
      P:Free();S:Free();
      return false
     end
    end;
    
    
    -- Button Click
    
    StartExe()
    -- Do something with the window here (Exe.hdl), MoveWindow etc
    -- Handle returned doesn't work though!
    Basically the handle AMS gives for the window is invalid so I'm looking to try to get the handle.

    Comment


    • #3
      Originally posted by Shrek View Post
      GetWindowThreadProcessId lpdwProcessId is a LPDWORD pointer, how do I deal with that, will be running in a loop so I need to define it then grab the value then cfhck it?

      And Bas, can we get the option for callback function pointers?
      LPDWORD is a pointer to a dword, so allocate 4 bytes and pass the pointer to GetWindowThreadProcessId as lpdwProcessId. You can then read the UDWORD from that buffer afterwards.

      Also, callback function pointers are possible in MemoryEx, when you use the ASM library. You can assemble a proc real-time and access its pointer. Lua functions are not C functions, so they don't have a pointer to a stdcall function. It's rather difficult to get that feature in MemoryEx.
      Bas Groothedde
      Imagine Programming :: Blog

      AMS8 Plugins
      IMXLH Compiler

      Comment


      • #4
        Code:
        --- Global
        
        User32 = Library.Load("user32.dll");
        Kernel32 = Library.Load("Kernel32.dll");
        
        Exe = {}
        Exe.Pid = 0;
        Exe.hdl = 0
        Exe.Path = "my.exe";
        Exe.StartExe = function()
         System.TerminateProcess(Exe.Pid)
         local STARTUPINFO = MemoryEx.DefineStruct{
          DWORD "cb";
          STRING ("lpReserved",256,1,MEMEX_ASCII);
          STRING ("lpDesktop",256,1,MEMEX_ASCII);
          STRING ("lpTitle",256,1,MEMEX_ASCII);
          DWORD "dwX";
          DWORD "dwY";
          DWORD "dwXSize";
          DWORD "dwYSize";
          DWORD "dwXCountChars";
          DWORD "dwYCountChars";
          DWORD "dwFillAttribute";
          DWORD "dwFlags";
          WORD "wShowWindow";
          WORD "cbReserved2";
          BYTE "lpReserved2";
          INT "hStdInput";
          INT "hStdOutput";
          INT "hStdError";
         }
         local PROCESS_INFORMATION = MemoryEx.DefineStruct{
          INT "hProcess";
          INT "hThread";
          DWORD "dwProcessId";
          DWORD "dwThreadId";
         }
         local P = PROCESS_INFORMATION:New()
         local S = STARTUPINFO:New()
         S.cb = S:Size()
         S.lpReserved = 0
         S.dwFlags = 0x00002000 + 0x00000001
         S.wShowWindow = 7
         Exe.hdl = 0
         if Kernel32.CreateProcessA(Exe.Path,0,0,0,0,0,0,0,S:GetPointer(),P:GetPointer()) ~= 0 then
          User32.WaitForInputIdle(P.hProcess,20000)
          Exe.Pid = P.dwProcessId
          local rp = Window.EnumerateTitles(false)
          for hdl,tit in pairs(rp) do
           local B = MemoryEx.Allocate(4)
           User32.GetWindowThreadProcessId(hdl,B)
           Debug.Print(tostring("Error: "..Kernel32.GetLastError().. " : "..MemoryEx.DWORD(B)).."   "..tostring(Exe.Pid).."   "..tit .."\r\n")
           if tostring(MemoryEx.DWORD(B)) == tostring(Exe.Pid) then
            Exe.hdl = hdl
            MemoryEx.Free(B)
            break
           else
            MemoryEx.Free(B)
           end
          end
          if Exe.hdl == 0 then
           System.TerminateProcess(Exe.Pid)
           P:Free();S:Free();
           return false
          else
           P:Free();S:Free();
           return true
          end
         else
          P:Free();S:Free();
          return false
         end
        end;
        
        
        -- Button Click
        Debug.ShowWindow(true)
        Dialog.Message("",tostring(StartExe()))
        I think I'm doing that right but every handle returned from Window.EnumerateTitles according to Windows is invalid!

        Comment


        • #5
          Code:
          Dialog.Message(Application.GetWndHandle(),tostring(Exe.StartExe()))
          Running that one can see the application handle does not appear in the list of handles gained by Window.EnumerateTitles, Window.EnumerateProcesses also gives handles that are 4 digits long instead of the typical 7/8.

          I'm using the older free version can anyone confirm this is happening on newer builds?

          Comment


          • #6
            here's some old code of mine-- in there is a standard dll call.
            looks like might need a different buffer ?

            Code:
            function Debug.GetWindowHandle(...)
            	--[[function to get the Application's Debug window Handle,
            		optional set(change) the Title of the Debug Window
            		by upvalue ... nb: Debug window is a child of the Desktop.
            		you 'can' call this from globals or on pre-start actions]]
            				
            local function Hwnd(...)				
            	
            	local pParent = MemoryEx.Allocate(1024); local pBuffer = MemoryEx.Allocate(1024);
            	--set some local vars	
            	local HwndDebug, HwndThread, ParentPid, MnAppPid = 0,0,0,0
            	local tHwnds = Window.EnumerateTitles(false); --all possible hwnds
            	local name = "Debug"; --target window title(assumes not changed)
            	if tHwnds == nil or not pParent or not pBuffer then return 0, 'failed to retrieve the Debug handle'; end
            	--cycle hwnds look'n for windows with title Debug (could be more than one...)	
            	for h, t in pairs(tHwnds) do    	
                	local res = String.Find(t, name, 1, false); --not case sensitive
                	if (res ~= -1) then        	
                    	if (pParent and pBuffer) then
                    		-- 'clean' memory buffers
                    		MemoryEx.Zero(pParent, 1024); MemoryEx.Zero(pBuffer, 1024);
                    		--get the Application's Proccess ID via its Window Handle (Win2K compat)
                    		--MnAppPid = tonumber(DLL.CallFunction(_SystemFolder.."\\Kernel32.dll", "GetCurrentProcessId", "", 1, 1)); --winxp and 2k3 or later
                    		local HwndThread = DLL.CallFunction(_SystemFolder.."\\user32.dll", "GetWindowThreadProcessId", Application.GetWndHandle()..","..pParent , 1, 1); --win2k or later
                    		MnAppPid = tonumber(MemoryEx.DWORD(pParent)); --This is this App's Proccess Id (PID)
                    	end
            			--MSDN: Retrieves the identifier of the thread that created the specified window and, optionally, the identifier of the process(ID) that created the window.
                    	HwndThread = tonumber(DLL.CallFunction(_SystemFolder.."\\user32.dll", "GetWindowThreadProcessId", h..","..pBuffer, 1, 1));
                    	ParentPid = tonumber(MemoryEx.DWORD(pBuffer)); --parent proccess ID        		
                    	--confirm found 'Debug' window handle belongs to This Application(match process Id's (PIDs)
                    	if ParentPid == MnAppPid then
                    		HwndDebug = h; --confirmed Debug window handle
                    		--set window text if arg passed
                    		if ... ~= nil then Window.SetText(HwndDebug, tostring(...)); end				
            				break; --found it, bug out now 
                    	end
                	end
            	end
            	
            	if pParent then MemoryEx.Free(pParent); end
            	if pBuffer then MemoryEx.Free(pBuffer); end
            	return HwndDebug, HwndThread, ParentPid;
            end		
            	--Dependency: requires the 'MemoryEx' action plugin created by Imagine Programming, active in Globals - if not bug out with an error	
            	if (MemoryEx == nil or type(MemoryEx) ~= "table") then return 0, 'requires the MemoryEx plugin active in Globals'; end
            	--otherwise let's try and get the Application's Debug window handle:
            	return Hwnd(...); -- pass on any upvalue	
            	
            end
            
            local hwndDebug, DebugThreadID, MnAppPid = Debug.GetWindowHandle("Info Log"); --change the title
            if hwndDebug ~= 0 then
            	Dialog.Message("App Debug handle: "..hwndDebug, "debug thread: "..DebugThreadID.."\r\nApplication process PID: "..MnAppPid);
            Window.Show(hwndDebug);
            else
            	Dialog.Message('error information', 'failed to retrieve the Debug handle' );	
            end
            have play and might help getting the parent buffer correct when using
            MemoryEx loaded library call

            the code is not refined it was a proof of concept at the time (the refined code is included in upcoming ThreadApiEx (not long now either)

            btw returned handles via both emumerate methods are as they should be and have been since AMS v7x
            you may have something else going on. just try things without memoryex actions to test enumeration of proccesses or window titles
            Last edited by Eagle; 07-09-2014, 12:31 PM. Reason: comment

            Comment


            • #7
              Thank's Eagle, don't no what was going on there but got it sorted now with some of your code, cheers :yes

              Bas, care to give me a few pointers with a small callback function in ASM?

              Code:
              EnumChildWindows = function(Parent)
               local ChildHdls = {}
               -- CB = Pointer to call back
               -- Callback returns true always and puts each child handle in ChildHdls
               User32.EnumChildWindows(Parent,CB,0)
               return ChildHdls
              end;

              Comment


              • #8
                I'll see what I can do for ya Shrek!
                Bas Groothedde
                Imagine Programming :: Blog

                AMS8 Plugins
                IMXLH Compiler

                Comment


                • #9
                  Try this, I tried explaining the assembly code as much as I could, but these two procedures do the trick. There's a Window.CountChildWindows and a Window.EnumerateChildWindows in here which use assembled code as callbacks for user32.EnumerateChildWindows().
                  Attached Files
                  Bas Groothedde
                  Imagine Programming :: Blog

                  AMS8 Plugins
                  IMXLH Compiler

                  Comment


                  • #10
                    thanks [Forum Anti Thanks Hack]

                    Comment


                    • #11
                      np! the hack can be invisible too
                      Bas Groothedde
                      Imagine Programming :: Blog

                      AMS8 Plugins
                      IMXLH Compiler

                      Comment

                      Working...
                      X