1
- // (c) Copyright Cory Plotts.
2
- // This source is subject to the Microsoft Public License (Ms-PL).
3
- // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
4
- // All other rights reserved.
5
-
6
- #include " stdafx.h"
7
-
8
- #include " Injector.h"
9
- #include < vcclr.h>
10
-
11
- using namespace ManagedInjector ;
12
-
13
- static unsigned int WM_GOBABYGO = ::RegisterWindowMessage(L" Injector_GOBABYGO!" );
14
- static HHOOK _messageHookHandle;
15
-
16
- // -----------------------------------------------------------------------------
17
- // Spying Process functions follow
18
- // -----------------------------------------------------------------------------
19
- void Injector::Launch (System::IntPtr windowHandle, System::String^ assembly, System::String^ className, System::String^ methodName)
20
- {
21
- System::String^ assemblyClassAndMethod = assembly + " $" + className + " $" + methodName;
22
- pin_ptr<const wchar_t > acmLocal = PtrToStringChars (assemblyClassAndMethod);
23
-
24
- HINSTANCE hinstDLL;
25
-
26
- if (::GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&MessageHookProc, &hinstDLL))
27
- {
28
- LogMessage (" GetModuleHandleEx successful" , true );
29
- DWORD processID = 0 ;
30
- DWORD threadID = ::GetWindowThreadProcessId ((HWND)windowHandle.ToPointer (), &processID);
31
-
32
- if (processID)
33
- {
34
- LogMessage (" Got process id" , true );
35
- HANDLE hProcess = ::OpenProcess (PROCESS_ALL_ACCESS, FALSE , processID);
36
- if (hProcess)
37
- {
38
- LogMessage (" Got process handle" , true );
39
- int buffLen = (assemblyClassAndMethod->Length + 1 ) * sizeof (wchar_t );
40
- void * acmRemote = ::VirtualAllocEx (hProcess, NULL , buffLen, MEM_COMMIT, PAGE_READWRITE);
41
-
42
- if (acmRemote)
43
- {
44
- LogMessage (" VirtualAllocEx successful" , true );
45
- ::WriteProcessMemory (hProcess, acmRemote, acmLocal, buffLen, NULL );
46
-
47
- _messageHookHandle = ::SetWindowsHookEx (WH_CALLWNDPROC, &MessageHookProc, hinstDLL, threadID);
48
-
49
- if (_messageHookHandle)
50
- {
51
- LogMessage (" SetWindowsHookEx successful" , true );
52
- ::SendMessage ((HWND)windowHandle.ToPointer(), WM_GOBABYGO, (WPARAM)acmRemote, 0);
53
- ::UnhookWindowsHookEx (_messageHookHandle);
54
- }
55
-
56
- ::VirtualFreeEx (hProcess, acmRemote, buffLen, MEM_RELEASE);
57
- }
58
-
59
- ::CloseHandle (hProcess);
60
- }
61
- }
62
- ::FreeLibrary (hinstDLL);
63
- }
64
- }
65
-
66
- void Injector::LogMessage (System::String^ message, bool append)
67
- {
68
- System::String ^ applicationDataPath = Environment::GetFolderPath (Environment::SpecialFolder::ApplicationData);
69
- applicationDataPath += " \\ Snoop" ;
70
-
71
- if (!System::IO::Directory::Exists (applicationDataPath))
72
- {
73
- System::IO::Directory::CreateDirectory (applicationDataPath);
74
- }
75
-
76
- System::String ^ pathname = applicationDataPath + " \\ SnoopLog.txt" ;
77
-
78
- if (!append)
79
- {
80
- System::IO::File::Delete (pathname);
81
- }
82
-
83
- System::IO::FileInfo ^ fi = gcnew System::IO::FileInfo (pathname);
84
-
85
- System::IO::StreamWriter ^ sw = fi->AppendText ();
86
- sw->WriteLine (System::DateTime::Now.ToString (" MM/dd/yyyy HH:mm:ss" ) + " : " + message);
87
- sw->Close ();
88
- }
89
-
90
- __declspec (dllexport)
91
- LRESULT __stdcall MessageHookProc(int nCode, WPARAM wparam, LPARAM lparam)
92
- {
93
- if (nCode == HC_ACTION)
94
- {
95
- CWPSTRUCT* msg = (CWPSTRUCT*)lparam;
96
- if (msg != NULL && msg->message == WM_GOBABYGO)
97
- {
98
- System::Diagnostics::Debug::WriteLine (" Got WM_GOBABYGO message" );
99
-
100
- wchar_t * acmRemote = (wchar_t *)msg->wParam ;
101
-
102
- String^ acmLocal = gcnew System::String (acmRemote);
103
- System::Diagnostics::Debug::WriteLine (System::String::Format (" acmLocal = {0}" , acmLocal));
104
- cli::array<System::String^>^ acmSplit = acmLocal->Split (' $' );
105
-
106
- System::Diagnostics::Debug::WriteLine (String::Format (" About to load assembly {0}" , acmSplit[0 ]));
107
- System::Reflection::Assembly^ assembly = System::Reflection::Assembly::LoadFile (acmSplit[0 ]);
108
- if (assembly != nullptr )
109
- {
110
- System::Diagnostics::Debug::WriteLine (String::Format (" About to load type {0}" , acmSplit[1 ]));
111
- System::Type^ type = assembly->GetType (acmSplit[1 ]);
112
- if (type != nullptr )
113
- {
114
- System::Diagnostics::Debug::WriteLine (String::Format (" Just loaded the type {0}" , acmSplit[1 ]));
115
- System::Reflection::MethodInfo^ methodInfo = type->GetMethod (acmSplit[2 ], System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::Public);
116
- if (methodInfo != nullptr )
117
- {
118
- System::Diagnostics::Debug::WriteLine (System::String::Format (" About to invoke {0} on type {1}" , methodInfo->Name , acmSplit[1 ]));
119
- Object ^ returnValue = methodInfo->Invoke (nullptr , nullptr );
120
- if (nullptr == returnValue)
121
- returnValue = " NULL" ;
122
- System::Diagnostics::Debug::WriteLine (String::Format (" Return value of {0} on type {1} is {2}" , methodInfo->Name , acmSplit[1 ], returnValue));
123
- }
124
- }
125
- }
126
- }
127
- }
128
- return CallNextHookEx (_messageHookHandle, nCode, wparam, lparam);
1
+ // (c) Copyright Cory Plotts.
2
+ // This source is subject to the Microsoft Public License (Ms-PL).
3
+ // Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
4
+ // All other rights reserved.
5
+
6
+ #include " stdafx.h"
7
+
8
+ #include " Injector.h"
9
+ #include < vcclr.h>
10
+
11
+ using namespace ManagedInjector ;
12
+
13
+ static unsigned int WM_GOBABYGO = ::RegisterWindowMessage(L" Injector_GOBABYGO!" );
14
+ static HHOOK _messageHookHandle;
15
+
16
+ // -----------------------------------------------------------------------------
17
+ // Spying Process functions follow
18
+ // -----------------------------------------------------------------------------
19
+ void Injector::Launch (System::IntPtr windowHandle, System::String^ assembly, System::String^ className, System::String^ methodName)
20
+ {
21
+ System::String^ assemblyClassAndMethod = assembly + " $" + className + " $" + methodName;
22
+ pin_ptr<const wchar_t > acmLocal = PtrToStringChars (assemblyClassAndMethod);
23
+
24
+ HINSTANCE hinstDLL;
25
+
26
+ if (::GetModuleHandleEx (GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&MessageHookProc, &hinstDLL))
27
+ {
28
+ LogMessage (" GetModuleHandleEx successful" , true );
29
+ DWORD processID = 0 ;
30
+ DWORD threadID = ::GetWindowThreadProcessId ((HWND)windowHandle.ToPointer (), &processID);
31
+
32
+ if (processID)
33
+ {
34
+ LogMessage (" Got process id" , true );
35
+ HANDLE hProcess = ::OpenProcess (PROCESS_ALL_ACCESS, FALSE , processID);
36
+ if (hProcess)
37
+ {
38
+ LogMessage (" Got process handle" , true );
39
+ int buffLen = (assemblyClassAndMethod->Length + 1 ) * sizeof (wchar_t );
40
+ void * acmRemote = ::VirtualAllocEx (hProcess, NULL , buffLen, MEM_COMMIT, PAGE_READWRITE);
41
+
42
+ if (acmRemote)
43
+ {
44
+ LogMessage (" VirtualAllocEx successful" , true );
45
+ ::WriteProcessMemory (hProcess, acmRemote, acmLocal, buffLen, NULL );
46
+
47
+ _messageHookHandle = ::SetWindowsHookEx (WH_CALLWNDPROC, &MessageHookProc, hinstDLL, threadID);
48
+
49
+ if (_messageHookHandle)
50
+ {
51
+ LogMessage (" SetWindowsHookEx successful" , true );
52
+ ::SendMessage ((HWND)windowHandle.ToPointer(), WM_GOBABYGO, (WPARAM)acmRemote, 0);
53
+ ::UnhookWindowsHookEx (_messageHookHandle);
54
+ }
55
+
56
+ ::VirtualFreeEx (hProcess, acmRemote, buffLen, MEM_RELEASE);
57
+ }
58
+
59
+ ::CloseHandle (hProcess);
60
+ }
61
+ }
62
+ ::FreeLibrary (hinstDLL);
63
+ }
64
+ }
65
+
66
+ void Injector::LogMessage (System::String^ message, bool append)
67
+ {
68
+ System::String ^ applicationDataPath = Environment::GetFolderPath (Environment::SpecialFolder::ApplicationData);
69
+ applicationDataPath += " \\ Snoop" ;
70
+
71
+ if (!System::IO::Directory::Exists (applicationDataPath))
72
+ {
73
+ System::IO::Directory::CreateDirectory (applicationDataPath);
74
+ }
75
+
76
+ System::String ^ pathname = applicationDataPath + " \\ SnoopLog.txt" ;
77
+
78
+ if (!append)
79
+ {
80
+ System::IO::File::Delete (pathname);
81
+ }
82
+
83
+ System::IO::FileInfo ^ fi = gcnew System::IO::FileInfo (pathname);
84
+
85
+ System::IO::StreamWriter ^ sw = fi->AppendText ();
86
+ sw->WriteLine (System::DateTime::Now.ToString (" MM/dd/yyyy HH:mm:ss" ) + " : " + message);
87
+ sw->Close ();
88
+ }
89
+
90
+ __declspec (dllexport)
91
+ LRESULT __stdcall MessageHookProc(int nCode, WPARAM wparam, LPARAM lparam)
92
+ {
93
+ if (nCode == HC_ACTION)
94
+ {
95
+ CWPSTRUCT* msg = (CWPSTRUCT*)lparam;
96
+ if (msg != NULL && msg->message == WM_GOBABYGO)
97
+ {
98
+ System::Diagnostics::Debug::WriteLine (" Got WM_GOBABYGO message" );
99
+
100
+ wchar_t * acmRemote = (wchar_t *)msg->wParam ;
101
+
102
+ String^ acmLocal = gcnew System::String (acmRemote);
103
+ System::Diagnostics::Debug::WriteLine (System::String::Format (" acmLocal = {0}" , acmLocal));
104
+ cli::array<System::String^>^ acmSplit = acmLocal->Split (' $' );
105
+
106
+ System::Diagnostics::Debug::WriteLine (String::Format (" About to load assembly {0}" , acmSplit[0 ]));
107
+ System::Reflection::Assembly^ assembly = System::Reflection::Assembly::LoadFile (acmSplit[0 ]);
108
+ if (assembly != nullptr )
109
+ {
110
+ System::Diagnostics::Debug::WriteLine (String::Format (" About to load type {0}" , acmSplit[1 ]));
111
+ System::Type^ type = assembly->GetType (acmSplit[1 ]);
112
+ if (type != nullptr )
113
+ {
114
+ System::Diagnostics::Debug::WriteLine (String::Format (" Just loaded the type {0}" , acmSplit[1 ]));
115
+ System::Reflection::MethodInfo^ methodInfo = type->GetMethod (acmSplit[2 ], System::Reflection::BindingFlags::Static | System::Reflection::BindingFlags::Public);
116
+ if (methodInfo != nullptr )
117
+ {
118
+ System::Diagnostics::Debug::WriteLine (System::String::Format (" About to invoke {0} on type {1}" , methodInfo->Name , acmSplit[1 ]));
119
+ Object ^ returnValue = methodInfo->Invoke (nullptr , nullptr );
120
+ if (nullptr == returnValue)
121
+ returnValue = " NULL" ;
122
+ System::Diagnostics::Debug::WriteLine (String::Format (" Return value of {0} on type {1} is {2}" , methodInfo->Name , acmSplit[1 ], returnValue));
123
+ }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ return CallNextHookEx (_messageHookHandle, nCode, wparam, lparam);
129
129
}
0 commit comments