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