Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

[SOLVED]get other process's working dir


  • Please log in to reply
61 replies to this topic
HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

Main Script for AutoHotkey.exe (!!! Note this may crash your remote application e.g. Notepad !!!)

Process,Exist, notepad.exe
If !PID:=ErrorLevel
  Run notepad.exe,,,PID
Loop % A_AhkPath
  A_AhkDir:=A_LoopFileDir
FileRead,HookScript,HookScript.ahk
rThread:=InjectAhkDll(PID,A_AhkDir "\AutoHotkeyMini.dll",HookScript)
MsgBox Press Ok to unload AutoHotkey.dll from Remote Process

 

HookScript.ahk for AutoHotkey.dll

#Persistent
OnExit,UnHook
If !HookFunction("user32.dll", "MessageBoxExW", MyMessageBoxExW:=RegisterCallback("MessageBoxExW","",5), hMessageBoxExW)
  MsgBox Function could not be hooked
Return

UnHook:
UnHookFunction("user32.dll", "MessageBoxExW", hMessageBoxExW)
ExitApp


MessageBoxExW(hwnd,lpText,lpCaption,uType,uId){
  global MyMessageBoxExW,hMessageBoxExW
  title:=StrGet(lpCaption,"UTF-16")
  text:=StrGet(lpText,"UTF-16")
  UnHookFunction("user32.dll", "MessageBoxExW", hMessageBoxExW)
  ret:=DllCall("MessageBoxExW","PTR",hwnd,"Str",text "`n`nYour MessageBoxExW has been hooked!","Str",title,"UInt",uType,"Short",uId)
  HookFunction("user32.dll", "MessageBoxExW", MyMessageBoxExW, hMessageBoxExW)
  return ret
}


HookFunction(lpModule, lpFuncName, lpFunction, ByRef lpBackup){
  static MEM_FREE:=65536,MEM_COMMIT:=4096,MEM_RESERVE:=8192,PAGE_EXECUTE_READWRITE:=64,MEM_DECOMMIT:=16384
  
  hProcess:=DllCall("GetCurrentProcess","PTR")    ,   hModule := DllCall("GetModuleHandle","Str",lpModule,"PTR")
  ; Get module and function address
	hFunc := DllCall("GetProcAddress","PTR",hModule,"AStr", lpFuncName,"PTR")
  
  ; Create jmp to use
	jmp:=Struct("Byte[6]",[0xe9,0x00,0x00,0x00,0x00,0xc3])
  
  VarSetCapacity(lpBackup,6) ; make sure we have enough memory allocated
  ; Backup current jmp
	DllCall("ReadProcessMemory","PTR",hProcess,"PTR", hFunc, "PTR", &lpBackup,"UInt", 6,"PTR", 0)

  ; Set addres in jmp
	NumPut((lpFunction - hFunc - 5) & 0xFFFFFFFF ,jmp[]+1,"Uint")
  
  ; allocate memory for jmp
  If !hMem:=DllCall("VirtualAlloc","PTR",0,"Uint",6,"Uint",MEM_COMMIT|MEM_RESERVE,"Uint",PAGE_EXECUTE_READWRITE)
    Return
  
  ;	copy new jmp
  DllCall("RtlMoveMemory","PTR",hMem,"PTR", jmp[],"PTR", 6) 
  
  ; overwrite jmp
	if !DllCall("WriteProcessMemory","PTR",hProcess,"PTR", hFunc,"PTR", hMem,"Uint", 6,"UInt", 0){
    DllCall("VirtualFree","PTR",hMem,"Uint",6,"Uint",MEM_FREE|MEM_DECOMMIT)
    return
  }
  DllCall("VirtualFree","PTR",hMem,"Uint",6,"Uint",MEM_FREE|MEM_DECOMMIT)
	return hFunc
}

UnHookFunction(lpModule, lpFuncName, ByRef lpBackup){
  static MEM_FREE:=65536,MEM_COMMIT:=4096,MEM_RESERVE:=8192,PAGE_EXECUTE_READWRITE:=64
	hFunc := DllCall("GetProcAddress","PTR",DllCall("GetModuleHandle","Str",lpModule,"PTR"),"AStr", lpFuncName,"PTR")
  ; allocate memory for backup jmp
  If !hMem:=DllCall("VirtualAlloc","PTR",0,"Uint",6,"Uint",MEM_COMMIT|MEM_RESERVE,"Uint",PAGE_EXECUTE_READWRITE)
    Return
  DllCall("RtlMoveMemory","PTR",hMem,"PTR", &lpBackup,"PTR", 6) 
  
  ret :=DllCall("WriteProcessMemory","PTR",DllCall("GetCurrentProcess","PTR"),"PTR", hFunc,"PTR", hMem,"Uint", 6,"PTR", 0)
  DllCall("VirtualFree","PTR",hMem,"Uint",6,"Uint",MEM_FREE|MEM_DECOMMIT)
  
	return FALSE
}


guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011

awesome HotKeyIT that is exactly what i was looking to do,

 

( first, i had to change d to A_ScriptDir in the main script. dunno what that d variable is )

 

however, i have tried to trigger a MessageBox by using the Edit menu in Notepad, and then using the Replace feature. i typed in a random string that would not be found. i got a MessageBox but it was all Chinese characters. maybe the chars changed due to unicode. i tried to Find again and this time the MessageBox displayed correctly, but was not hooked. this was using AHK_La. saving the scripts in ANSI or UTF-8 doesnt seem to change the Chinese chars

 

if i try using AHK_Lw, i get an error from AutoHotkeyMini.dll:

 

"Error at Line 1.

Line text: #

This line does not contain a recognized action"

 

 

and as you said, Notepad would crash, but only after i try to press Ok to unload the dll 



HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

d should have been A_AhkDir, I have updated above, thanks.

Generally it should not matter whether you use a or w of AHK version.

The error looks odd are you using AutoHotkeyMini.dll from Win32w folder too?

 

What OS are you using?

 

Btw. you can use IsUnicodeWindow to find out what exe/dll to use.

#u::Msgbox % DllCall("IsUnicodeWindow","Ptr",WinExist("a"))


guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011

that was the problem, i was using Win32a/Mini.dll

 

looks like when i use the Win32w/Mini.dll, the messagebox works with no chinese chars smile.png although Notepad does crash upon unhooking/closing the script

 

great work



guest3456
  • Members
  • 1704 posts
  • Last active: Nov 19 2015 11:58 AM
  • Joined: 10 Mar 2011

found another related link for ppl doing research

http://www.codeproje...I-Hooking-Libra



Verdlin
  • Members
  • 256 posts
  • Last active: Apr 29 2016 06:46 PM
  • Joined: 21 Dec 2012

Strange. I have only been able to get this to work by using Win32a/multi-threaded DLL...


Scripts are written and tested using AHK_H 64w (unless otherwise specified).

CFlyout. EasyIni. Dynamic Label Execution (No Reload). Word Lookup.


RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

I'm trying to inject ahk into another process, and then call one of the processes functions passing a dword array containing [1, 0] as the parameter.
The process was written in c++, so the function should be compiled to machine code, which can be run via a dll call? 

 

I've tried this, but couldn't get it to work. Is this actually possible? The injection part works. Is what im attempting even possible?

 

InjectAhkDll is awesome!

 

Thanks.

 

The injected script. It always gives an errorlevel of 0xC0000005 (access violation)

#include D:\My Computer\My Documents\GitHub\Class_CStruct.ahk
VisEnable :=  new cVisEnable
funtionAddress := 0x00AD1950


msgbox % DllCall(funtionAddress 
		, "Ptr", VisEnable.Ptr)
msgbox % ErrorLevel

/*
Also tried 
VarSetCapacity(params, 8, 0)
numput(1, &params)
numput(0, &params, 4)
msgbox % DllCall(funtionAddress 
		, "Ptr", &params)
*/



class cVisEnable extends CStruct_Base
{
	__New()
	{
		this.AddStructVar("c_visTypeFog", "UINT")
		this.AddStructVar("state", "UINT")
		this.SetStructCapacity()
		this.c_visTypeFog := 1
		this.state := 0		
	}
}



HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

Where have you got funtionAddress from gshouldn't it be functionAddress?

Also why don't you use internal Struct() function.

s:=Struct("UInt a,UInt b",[1,0])
DllCall(functionAddress,"PTR",s[])


RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

Thanks for the reply. This was code from the first time I attempted this a few months ago, before I discovered struct.

 

The function address is from IDA, and that was actually incorrect. I'm definitely using the correct one now, but still can't get it to work. Error level is set to A4.

The function uses "__FastCall". Is this compatible with AHK DLLCall? I know there are three types of call,s fast, cdecl and std. When you ommit the "cdecl" parameter in DLLcall, does it use fastcall or std?

 

Thanks.



HotKeyIt
  • Moderators
  • 7439 posts
  • Last active: Jun 22 2016 09:14 PM
  • Joined: 18 Jun 2008

Can you upload a full example injecting into Notepad or similar.



Verdlin
  • Members
  • 256 posts
  • Last active: Apr 29 2016 06:46 PM
  • Joined: 21 Dec 2012

A few points about DllCall

  • Most functions use std calling convention; by default, so does DllCall.
  • Cdecl has no effect on 64-bit builds
  • thiscall is not supported by AutoHotkey.

Scripts are written and tested using AHK_H 64w (unless otherwise specified).

CFlyout. EasyIni. Dynamic Label Execution (No Reload). Word Lookup.


RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006

Can you upload a full example injecting into Notepad or similar.

 

That's a bit hard. I'm just mucking around in a computer game. Against an AI I should be able to influence the game by calling these functions.

 

The injection part definitely works, and I can actually read in-game values directly by using pointers and memory offsets.

 

 

 

A few points about DllCall

  • Most functions use std calling convention; by default, so does DllCall.
  • Cdecl has no effect on 64-bit builds
  • thiscall is not supported by AutoHotkey.

 

 

Thanks. Is FastCall supported??



Verdlin
  • Members
  • 256 posts
  • Last active: Apr 29 2016 06:46 PM
  • Joined: 21 Dec 2012

Sorry! I missed that question. It looks like, no, but you may find a workaround. Here's a post I found by Sean

 

 

You mean RtlUshortByteSwap? (: it seems also to be fastcall)
BTW, there also exist similar ones for Ulong and Ulonglong, however, their calling convention is the rare case of fastcall, which is not supported by AHK's DllCall(). Although I succeeded using Cdecl instead, I'm not sure if it's safe to use ...
 

DllCall("ntdll\RtlUshortByteSwap", "Ushort", 0x1020, "Cdecl Ushort")

DllCall("ntdll\RtlUlongByteSwap", "Uint", 0x10203040, "Cdecl Uint")

 


Scripts are written and tested using AHK_H 64w (unless otherwise specified).

CFlyout. EasyIni. Dynamic Label Execution (No Reload). Word Lookup.


RHCP
  • Members
  • 1228 posts
  • Last active: Apr 08 2017 06:17 PM
  • Joined: 29 May 2006
objWMIService := ComObjGet( "winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2" )

I know very little about COM and VB. What is the "{impersonationLevel=impersonate}!\\.\root\cimv2"  part of the ComObjGet doing? And why is it required/not required.

 

Within the AHK manual it just uses "winmgmts:", but the MSDN pages use the above syntax.

 

Many Thanks.



j4hangir
  • Members
  • 6 posts
  • Last active: Sep 02 2015 12:26 AM
  • Joined: 16 Apr 2014

I ended up using handle.exe for this: http://technet.micro...s/bb896655.aspx

 

 

You can easily query your desired program with its PID and regex out its Working Directory in return:

>>> handle.exe -p 5668

Handle v3.51
Copyright (C) 1997-2013 Mark Russinovich
Sysinternals - www.sysinternals.com

    C: File  (RW-)   C:\... * WORKING DIRECTORY *
   58: File  (---)   \FileSystem\Filters\FltMgrMsg
...