잊지 않겠습니다.

'Win32'에 해당되는 글 2건

  1. 2010.11.11 WindowsIdentify 를 이용한 인증
  2. 2010.01.05 0008. CSWindowsHook
Network Copy등을 하기 위해서 ID와 Password를 알고 있는데, code 상으로 구현하는 방법을 한번 정리.

일단, WindowsIdentify는 win32 dll을 이용하고, Windows Token을 사용한다. Windows Token은 어떤 시스템에 Logon한 이후에, 일정시간 유지가 되는 Windows의 memory안에 자신의 Identity를 저장하게 된다. 

먼저, Win32의 [DllImport("advapi32.dll", SetLastError = true)] 를 이용해서 LogonUser method를 dll import 시켜온다.

        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);


마지막 값인 phToken값을 이용해서 WindowsIdentify를 얻어 내면 타 시스템에 접근이 가능하다. 여기에서 userName은 upn형태로 넣어져야지 되며, 이 형식은 ykyoon@vplex.net 과 같은 email과 같은 형식으로 입력이 되어야지 된다.

다음은 NetworkCopy를 하는 Test code이다. 




[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
[DllImport("kernel32.dll", CharSet = System.Runtime.InteropServices.CharSet.Auto)]
private unsafe static extern int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref String lpBuffer, int nSize, IntPtr* Arguments);

[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public extern static bool DuplicateToken(IntPtr ExistingTokenHandle, int SECURITY_IMPERSONATION_LEVEL, ref IntPtr DuplicateTokenHandle);

public unsafe static string GetErrorMessage(int errorCode)
{
    int FORMAT_MESSAGE_ALLOCATE_BUFFER = 0x00000100;
    int FORMAT_MESSAGE_IGNORE_INSERTS = 0x00000200;
    int FORMAT_MESSAGE_FROM_SYSTEM = 0x00001000;

    int messageSize = 255;
    String lpMsgBuf = "";
    int dwFlags = FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS;

    IntPtr ptrlpSource = IntPtr.Zero;
    IntPtr prtArguments = IntPtr.Zero;

    int retVal = FormatMessage(dwFlags, ref ptrlpSource, errorCode, 0, ref lpMsgBuf, messageSize, &prtArguments);
    if(0 == retVal)
    {
        throw new Exception("Failed to format message for error code " + errorCode + ". ");
    }

    return lpMsgBuf;
}

static void Main(string[] args)
{
    const int LOGON32_PROVIDER_DEFAULT = 0;
    const int LOGON32_LOGON_INTERACTIVE = 2;
    const int SecurityImpersonation = 2;

    var tokenHandle = IntPtr.Zero;
    bool returnValue = LogonUser(@"Administrator@vplex.net", "network ip in here", "this is password", 9, 0, ref tokenHandle);
    Console.WriteLine("LogonUser called.");
    if(false == returnValue)
    {
        int ret = Marshal.GetLastWin32Error();
        Console.WriteLine("LogonUser failed with error code : {0}", ret);
        Console.WriteLine("\nError: [{0}] {1}\n", ret, GetErrorMessage(ret));
        int errorCode = 0x5; //ERROR_ACCESS_DENIED
        throw new System.ComponentModel.Win32Exception(errorCode);
    }
    else
    {
        var ykyoonAdmin = new WindowsIdentity(tokenHandle);
        var wic = ykyoonAdmin.Impersonate();
        File.Copy("C:\\System.Web.Mvc.dll", "\\\\10.30.3.24\\c$\\abc.dll", true);
        wic.Undo();
        wic.Dispose();
    }
    CloseHandle(tokenHandle);
}
Posted by Y2K
,

0008. CSWindowsHook

Sample Codes 2010. 1. 5. 16:26
Windows Hooking의 경우에는 Windows message queue에 대한 이해가 좀 필요하다.
Windows는 Windows Message Queue를 통해서 각각의 Message를 전달하고, 그 Message에 따라 각기 다른 Action을 행한다.
WM_PAINT의 경우에는 화면을 그리라는 Message가 되고, WM_MOUSE의 경우에는 Mouse의 움직임에 따라 발생되는 Windows
Message이다.

Hooking은 이런 WIndows Message Queue에 Hook을 걸어서, 원래 처리되어야지 되는 함수가 아닌, 사용자 지정 Method에서
처리하게 하는 방법이다. 이것을 이용하면 Ctrl+Alt+Del의 기능도 막아버릴 수 있으며, 마우스를 움직여서 다른 동작을 하는 것도
막는 것이 가능하다. 또한 Mouse나 Keyboard의 모든 기록들을 저장할 수 있기 때문에 Windows에서 Cracking을 하는 경우에
왕왕 사용되는 방법이다.

먼저, WIN32 함수인 SetWindowsHookEx 함수를 DllImport시켜서 가지고 온다. 필요한 Native method의 선언은 다음과 같다.

internal delegate int HookProc(int nCode, IntPtr wParam, IntPtr lParam);

internal class NativeMethods
{
    /// 
    /// Hooking WIN32 API
    /// dwThreadId가 0인 경우에는 전역 hook
    /// 특정 handler안에서 Hooking을 하는 경우에는 Handle 값을 넣어준다.
    /// 
    /// 
    /// Hooking을 한 이후에 받을 method의 주소값 delegate된 method를 넣어줄수 있다.
    /// 
    /// 
    /// 
    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern IntPtr SetWindowsHookEx(HookType hookType, HookProc callback, IntPtr hMod, uint dwThreadId);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern bool UnhookWindowsHookEx(IntPtr hhk);

    [DllImport("user32.dll", CharSet = CharSet.Auto)]
    public static extern int CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
}

internal static class HookCodes
{
    public const int HC_ACTION = 0;
    public const int HC_GETNEXT = 1;
    public const int HC_SKIP = 2;
    public const int HC_NOREMOVE = 3;
    public const int HC_NOREM = HC_NOREMOVE;
    public const int HC_SYSMODALON = 4;
    public const int HC_SYSMODALOFF = 5;
}

internal enum HookType
{
    WH_KEYBOARD = 2,
    WH_MOUSE = 7,
    WH_KEYBOARD_LL = 13,
    WH_MOUSE_LL = 14
}

[StructLayout(LayoutKind.Sequential)]
internal class POINT
{
    public int x;
    public int y;
}

/// 
/// The MSLLHOOKSTRUCT structure contains information about a low-level keyboard 
/// input event. 
/// 
[StructLayout(LayoutKind.Sequential)]
internal struct MOUSEHOOKSTRUCT
{
    public POINT pt;        // The x and y coordinates in screen coordinates
    public int hwnd;        // Handle to the window that'll receive the mouse message
    public int wHitTestCode;
    public int dwExtraInfo;
}

/// 
/// The MOUSEHOOKSTRUCT structure contains information about a mouse event passed 
/// to a WH_MOUSE hook procedure, MouseProc. 
/// 
[StructLayout(LayoutKind.Sequential)]
internal struct MSLLHOOKSTRUCT
{
    public POINT pt;        // The x and y coordinates in screen coordinates. 
    public int mouseData;   // The mouse wheel and button info.
    public int flags;
    public int time;        // Specifies the time stamp for this message. 
    public IntPtr dwExtraInfo;
}

internal enum MouseMessage
{
    WM_MOUSEMOVE = 0x0200,
    WM_LBUTTONDOWN = 0x0201,
    WM_LBUTTONUP = 0x0202,
    WM_LBUTTONDBLCLK = 0x0203,
    WM_RBUTTONDOWN = 0x0204,
    WM_RBUTTONUP = 0x0205,
    WM_RBUTTONDBLCLK = 0x0206,
    WM_MBUTTONDOWN = 0x0207,
    WM_MBUTTONUP = 0x0208,
    WM_MBUTTONDBLCLK = 0x0209,

    WM_MOUSEWHEEL = 0x020A,
    WM_MOUSEHWHEEL = 0x020E,

    WM_NCMOUSEMOVE = 0x00A0,
    WM_NCLBUTTONDOWN = 0x00A1,
    WM_NCLBUTTONUP = 0x00A2,
    WM_NCLBUTTONDBLCLK = 0x00A3,
    WM_NCRBUTTONDOWN = 0x00A4,
    WM_NCRBUTTONUP = 0x00A5,
    WM_NCRBUTTONDBLCLK = 0x00A6,
    WM_NCMBUTTONDOWN = 0x00A7,
    WM_NCMBUTTONUP = 0x00A8,
    WM_NCMBUTTONDBLCLK = 0x00A9
}

/// 
/// The structure contains information about a low-level keyboard input event. 
/// 
[StructLayout(LayoutKind.Sequential)]
internal struct KBDLLHOOKSTRUCT
{
    public int vkCode;      // Specifies a virtual-key code
    public int scanCode;    // Specifies a hardware scan code for the key
    public int flags;
    public int time;        // Specifies the time stamp for this message
    public int dwExtraInfo;
}

internal enum KeyboardMessage
{
    WM_KEYDOWN = 0x0100,
    WM_KEYUP = 0x0101,
    WM_SYSKEYDOWN = 0x0104,
    WM_SYSKEYUP = 0x0105
}

여기에서 구성된 Hooking method들은 다음과 같다.

private bool SetGlobalLLMouseHook()
{
    // Create an instance of HookProc.
    globalLLMouseHookCallback = new HookProc(this.LowLevelMouseProc);

    hGlobalLLMouseHook = NativeMethods.SetWindowsHookEx(
        HookType.WH_MOUSE_LL,  // Must be LL for the global hook
        globalLLMouseHookCallback,
        // Get the handle of the current module
        Marshal.GetHINSTANCE(Assembly.GetExecutingAssembly().GetModules()[0]),
        // The hook procedure is associated with all existing threads running 
        // in the same desktop as the calling thread.
        0);
    return hGlobalLLMouseHook != IntPtr.Zero;
}

public int LowLevelMouseProc(int nCode, IntPtr wParam, IntPtr lParam)
{
    if(nCode >= 0)
    {
        // Marshal the MSLLHOOKSTRUCT data from the callback lParam
        MSLLHOOKSTRUCT mouseLLHookStruct = (MSLLHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(MSLLHOOKSTRUCT));

        // Get the mouse WM from the wParam parameter
        MouseMessage wmMouse = (MouseMessage)wParam;

        // Display the current mouse coordinates and the message
        String log = String.Format("X = {0} Y = {1}  ({2})\r\n", mouseLLHookStruct.pt.x, mouseLLHookStruct.pt.y, wmMouse);
        tbLog.AppendText(log);
    }

    // Pass the hook information to the next hook procedure in chain
    return NativeMethods.CallNextHookEx(hGlobalLLMouseHook, nCode, wParam, lParam);
}
Posted by Y2K
,