hook sendmessage without DLL

This is a example hooking windows api messages normally i must to use dll. Example:
Injector.
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
#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <Tlhelp32.h>
#include <wchar.h>
#include <iostream>
using namespace std;

void error(char *err);

HANDLE myProc = NULL;

void error(char *err)
{
 if (myProc != NULL) CloseHandle(myProc);
 printf("%s", err);
 exit(0);
}

HANDLE Startpausedprocess( char* cmd, PHANDLE ptr_thread ) // cleaned up a bit, but no RAII
{
    if( ptr_thread == nullptr ) return nullptr ;

    PROCESS_INFORMATION pi;
    STARTUPINFOA si {} ; // initialize with zeroes.
    si.cb = sizeof(STARTUPINFOA);

    if( !CreateProcessA( nullptr, cmd, nullptr, nullptr, false, CREATE_SUSPENDED,
                         nullptr, nullptr, std::addressof(si), std::addressof(pi) ) )
    {
        std::cerr << "CreateProcess failed, " << GetLastError() << '\n' ;
        *ptr_thread = nullptr ;
        return nullptr;
    }

    *ptr_thread = pi.hThread;
    return pi.hProcess;
}


int main(int argc, char *argv[])
{
 char cmd[] = "taskmgr.exe" ; // note: non-const (writeable array)
    HANDLE thread = nullptr ;
    auto myProc=Startpausedprocess( cmd, std::addressof(thread) ) ;
  if(myProc)
    {
        std::cout << "press enter to resume process... " && std::cin.get() ;
        ResumeThread(thread) ;

        //CloseHandle(thread) ;
        //CloseHandle(myProc) ;
    }

  // Reservar memoria para el argumento (ruta de la DLL)
  char thData[] = "dllmain.dll";
  LPVOID dirToArg = VirtualAllocEx(myProc, NULL, strlen(thData), MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
  if (dirToArg == NULL)
   error("[-] Error reservando memoria para argumento.\n");
  else
   printf("[+] Memoria reservada para argumento (%i bytes).\n", strlen(thData));


  // Escribir la ruta de la DLL en la memoria reservada
  SIZE_T written = 0;
  if (WriteProcessMemory(myProc, dirToArg, (LPVOID)&thData, strlen(thData), &written) == 0)
   error("[-] Error escribiendo memoria.\n");
  else
   printf("[+] Memoria escrita (arg %i bytes).\n", written);
  //Lanzar un hilo con LoadLibrary
  //Load the DLL
  //Load the DLL
  HANDLE rThread = CreateRemoteThread(myProc, NULL, NULL, (LPTHREAD_START_ROUTINE)GetProcAddress(LoadLibrary(L"Kernel32.dll"), "LoadLibraryA"), dirToArg, NULL, NULL);
  if (rThread == NULL)
   error("[-] Error creando el hilo.\n");
  else
   printf("[+] Hilo creado.\n");
  CloseHandle(rThread);
}


Dll file:
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
#include "stdafx.h"
#include "cabecera minhook"//MHook header
#include <iostream>
#include <windows.h>
#include <Commctrl.h>
#include <conio.h>

using namespace std;

typedef void (*SENDMESSAGEW)();//Typedef for the hooked function
static SENDMESSAGEW Basewritefoobar;//Backup of the originak fonction

static wchar_t pwned[]=L"PWNED";

LRESULT WINAPI BSSSendMessageW(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    if ( msg == LVM_INSERTITEMW || msg == LVM_SETITEMW)//Intercepts LVM_INSERTITEM and LVM_SETITEM messages
    {
        ((LVITEMW*)lparam)->pszText=pwned;//Replace the item text with our text.
    }
    return SendMessage(hwnd, msg, wparam, lparam);//Calls the real SendMessage function.
}

static bool Hook();

template <typename T>
inline MH_STATUS MH_CreateHookEx(void* target, void* const base, T** original)
{
    return MH_CreateHook(target, base, reinterpret_cast<void**>(original));
}


extern "C" __declspec (dllexport) void __cdecl SendWrite()
{ 
 
}

BOOL WINAPI DllMain(HINSTANCE hInst, ULONG ul_reason_for_call, LPVOID lpReserved)
{
 //Different behaviors depending on the reason why DllMain is called
 switch (ul_reason_for_call) {
  case DLL_PROCESS_ATTACH:
   if (!Hook())//Hook "Writefoobar"
   {
    cout << "Hook failed" << endl;
    return 1;
   }
   break;
  case DLL_PROCESS_DETACH:
   break;
  case DLL_THREAD_ATTACH:
   break;
  case DLL_THREAD_DETACH:
   break;
 }

 return TRUE;
}

bool Hook()
{
    if (MH_Initialize() != MH_OK)
    {
        return false;
    }

    if (MH_CreateHookEx((void*)&SendMessageW, (void*)&BSSSendMessageW, &Basewritefoobar) != MH_OK)
    {
        return FALSE;
    }
    return MH_EnableHook((void*)&SendMessageW) == MH_OK;
}

It's possible hooking a windows api message without using a dynamic link library *only with the executable and starting paused process* or the only way is this? The dll will intercept the message of windows api.. but i want to do without injection. Purposes? educational purposes only.
Last edited on
You can copy executable code directly into the other process' address space, but it's way harder than using a DLL.

Deviare lets you write the hook code in C# in your own process and uses IPC to communicate with the hookee. You don't need to write a separate DLL.
https://github.com/nektra/Deviare2
Full disclosure: I work for the company that develops it.
Topic archived. No new replies allowed.