Payment of ₹ requested by HONEY VIG. Click the link to pay securely via Razorpay: Make 5000 payment Payment of ₹ requested by HONEY VIG. Click the link to pay securely via Razorpay: Make 5000 payment ⭐ If you would like to buy me a coffee, well thank you very much that is mega kind! : https://www.buymeacoffee.com/honeyvig
Hire a web Developer and Designer to upgrade and boost your online presence with cutting edge Technologies
Showing posts with label textbox. Show all posts
Showing posts with label textbox. Show all posts

Thursday, April 21, 2022

C# Protect the Password inside a TextBox

 

First of all, the TextBox Control is not a secure way to hold passwords - so don’t use it as it is by default. Even with a PasswordChar, the real password is still visible if you use a tool like Spy++.

The Flaw (Explained)

As an example, take a simple TextBox with PasswordChar = ‘*‘.
Now, if you use Spy++ and inspect this application, you can get the password.


But…why is this happening?

Spy++ sends the message WM_GETTEXT (0x000D) to the TextBox, and the control just returns its value. It’s actually working as intended and it reacts just like any other control, that obeys any message received.

Fixing this issue…

I found a way to solve this by not allowing the TextBox to process the ‘malicious’ messages. So the solution consists in blocking any WM_GETTEXT message unless it was sent by the Text property.

If the Text property is called, it will send an WM_GETTEXT message, so it will surely be an internal (safe) call. But if that message is received and the Text property wasn’t called, then it might be risky to return the password, so we’ll not process that message.

I wrote a “safer” TextBox here, just to show you the idea, feel free to write your own or simply improve this one.


class ProtectedTextBox : TextBox
{
    // the malicious message, that needs to be handled
    private const int WM_GETTEXT = 0x000D;

    // 'true' if the messages are sent from our program (from Text property)
    // 'false' if they're sent by anything else 
    bool allowAccess { get; set; }

    public override string Text   // overriding Text property
    {
        get
        {
            allowAccess = true;    // allow WM_GETTEXT (because it's an internal call)
            return base.Text;  //this sends the message above in order to retrieve the TextBox's value
        }
        set
        {
            base.Text = value;
        }
    }

    protected override void WndProc(ref Message m)
    {
        if (m.Msg == WM_GETTEXT)  // if the message is WM_GETTEXT 
        { 
            if (allowAccess)  // and it comes from the Text property
            {
                allowAccess = false;   //we temporary remove the access
                base.WndProc(ref m);  //and finally, process the message
            }
        }
        else
            base.WndProc(ref m);
    }
}

Sunday, April 17, 2022

C# Synchronize 2 RichTextBoxes' Scroll

 

I recently had a problem when I tried to synchronize the scrolling between 2 RichTextBoxes - that was because these controls behave different than normal TextBoxes. However I managed to solve this…after some time, and I decided to post the solution. The idea is based on overriding one RichTextBox’s WndProc() and then sending its scroll position to the other one.

The advantage of this method is that the synchronization is based on the RichTextBox’s real position - not on the thumb/scrollbar position.

1.Fixed problems

These 2 problems are fixed if you use this method:

  1. If you press enter, while the caret is on the last line, the RichTextBox scrolls a little bit more than it should while the other one scrolls normally.
  2. If you delete the last lines in a RichTextBox, it doesn’t scroll down - but the other one will keep scrolling.

2. How to

As I said before, you need to create a custom RichTextBox, based on the original one, so you can override WndProc().

A short schema:

syncRichTextBox (object)
1) scroll
2) tell anotherRichTextBox to scroll to my position

anotherRichTextBox
1) idle - doing nothing but waiting for messages from syncRichTextBox

First, include this function, from user32.dll


[DllImport("user32.dll", CharSet = CharSet.Auto)]
private static extern int SendMessage(IntPtr hWnd, int wMsg, IntPtr wParam, ref Point lParam);
  • notice the lParam argument is a Point - this will store the scroll’s position.

Then, add these WM contants, you’ll need them when you synchronize the scrolling:


private const int WM_VSCROLL = 0x115;  //tells the control to scroll

private const int WM_GETDLGCODE = 0x87;   //sent when the caret is going out of the 'visible area' (so scroll is needed)

private const int WM_MOUSEFIRST = 0x200;  //scrolls if the mouse leaves the 'visible area' (example when you select text)

private const int EM_GETSCROLLPOS = 0x4DD;  //you send this message and the control returns it's scroll position

private const int EM_SETSCROLLPOS = 0x4DE;//this is used to set the control's scroll position

Now, you only have to create the custom RichTextBox - if its scroll position is changed, it will send a message containing its new position to the other RichTextBox (anotherRichTextBox) - the 2nd one doesn’t require overriding.

The code would look like this:


public class syncRichTextBox : RichTextBox
{
      public syncRichTextBox()
      {
              protected override void WndProc(ref Message m)
              {
                    base.WndProc(ref m);

                    if (m.Msg == WM_VSCROLL || m.Msg == WM_GETDLGCODE || m.Msg == WM_MOUSEFIRST)
                    {
                          Point p = new Point();

                          //the scroll position is returned in the variable p (point)
                          SendMessage(this.Handle, EM_GETSCROLLPOS, IntPtr.Zero, ref p);  

                          //sends the position to the other richtextbox (remember to replace its name)
                          SendMessage(anotherRichTextBox.Handle, EM_SETSCROLLPOS, IntPtr.Zero, ref p);  

                    }

              }
      }
}