Page 1 of 1

Dll Injection (Pipe Server & Client) Tutorial

Posted: Sun Mar 10, 2019 8:18 am
by supMarco
First of all what's a pipe ? and why am I using a pipe server?

A pipe is a section of shared memory that processes use for communication. The process that creates a pipe is the pipe server.
A process that connects to a pipe is a pipe client. One process writes information to the pipe, then the other process reads the information from the pipe.
This overview describes how to create, manage, and use pipes. (https://docs.microsoft.com/en-us/window ... /ipc/pipes)

I'm about to inject a DLL with a few functions (Including the one that starts a pipe server in the target process), then I'm going to use a pipe client in order to call the DLL's functions from the outside:

DLL (Server):

Code: Select all

#include "stdafx.h"
#include <stdlib.h>

#define STRSIZE 256

bool Compare(const BYTE*, const BYTE*, const char*);
DWORD Pattern(DWORD, DWORD, BYTE *, const char *);

BOOL money_flag = FALSE;
DWORD moneyHook = NULL;

_declspec(dllexport) void PipeServerStart(); //This is the only function I need to export
void init();
void money();

_declspec(dllexport) void PipeServerStart()
{
	HANDLE hPipe;
	char cheatName[STRSIZE];
	DWORD bytesRead;

	hPipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\Test"), PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 1024 * 16, 1024 * 16, INFINITE, NULL);
	if (hPipe != INVALID_HANDLE_VALUE)
	{
		if (ConnectNamedPipe(hPipe, NULL)) //Waits for a client to connect
		{
			while (ReadFile(hPipe, cheatName, STRSIZE - 1, &bytesRead, NULL)) //This will constantly read the client's "command" I will send
			{
				cheatName[bytesRead] = '\0';
				//We will call a certain DLL function accortding to the "command"
				if (!strcmp(cheatName, "money"))
				{
					money();
				}
				else if (!strcmp(cheatName, "init"))
				{
					init();
				}
			}
		}
		DisconnectNamedPipe(hPipe);
	}

}
void init()
{
	DWORD vpTemp;
	moneyHook = Pattern((DWORD)GetModuleHandleA("DKII.EXE"), 0x7fffffffffff, (BYTE *)"\x74\x03\x89\x6F\x7E", "xxxxx"); //Fetches the Hook location in the target
	VirtualProtect((LPVOID)moneyHook, 0x64, PAGE_EXECUTE_READWRITE, &vpTemp); //Makes the page that contains the code I want to modify writeable
}

void money()
{
	__asm {
	  cmp byte ptr [money_flag],0
	  jne l_disable
	  mov eax, [moneyHook]
      mov byte ptr [eax], 0xEB //Changes "je" (0x74) to "jmp" (0xEB)
	  mov byte ptr[money_flag], 1
	  jmp l_exit
	  l_disable:
	  mov eax, [moneyHook]
	  mov byte ptr[eax], 0x74 //Changes "jmp" (0xEB) back to "je" (0x74)
	  mov byte ptr[money_flag], 0
	  l_exit:
	}
}

//AOB Scanning Functions

bool Compare(const BYTE* pData, const BYTE* bMask, const char* szMask)
{
	for (; *szMask; ++szMask, ++pData, ++bMask)
		if (*szMask == 'x' && *pData != *bMask)   return 0;
	return (*szMask) == NULL;
}

DWORD Pattern(DWORD dwAddress, DWORD dwLen, BYTE *bMask, const char * szMask)
{
	for (DWORD i = 0; i < dwLen; i++)
		if (Compare((BYTE*)(dwAddress + i), bMask, szMask))  return (DWORD)(dwAddress + i);
	return 0
Client:

Code: Select all

#define STRSIZE 256

#include <Windows.h>
#include <stdio.h>

int main(void)
{
	HANDLE hPipe;
	DWORD bytesWritten;
	char buffer[STRSIZE];

	hPipe = CreateFile(TEXT("\\\\.\\pipe\\Test"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); //Connects to the pipe server
	if (hPipe != INVALID_HANDLE_VALUE)
	{
		while (1)
		{
			scanf("%s", buffer);
			if (!strcmp(buffer, "exit"))
				break;
			WriteFile(hPipe, buffer, STRSIZE - 1, &bytesWritten, NULL); //Sends your "command" to the server
		}

		CloseHandle(hPipe);
	}

	return (0);
}
Result:
https://youtu.be/5lujwFZp-KU

Re: Dll Injection (Pipe Server & Client) Tutorial

Posted: Mon Mar 11, 2019 6:10 pm
by supMarco
Update #1:

Added more examples
Added basic injection
Added some checks
Added various improvements
Added a github repo: https://github.com/supMarco/PipeServer

Result:
https://youtu.be/PWHGYDW1rmc
(the song you will hear in the video is powered by SunBeam :P )

Credits: I was inspired by a DB tip

Re: Dll Injection (Pipe Server & Client) Tutorial

Posted: Wed Mar 20, 2019 10:39 am
by supMarco
Update #3:

Added a GUI (pure win32 API )
Added more features
Github repo: https://github.com/supMarco/PipeServer

Result:
https://youtu.be/pRBIKJ3hrts

Re: Dll Injection (Pipe Server & Client) Tutorial

Posted: Wed Nov 20, 2019 1:26 pm
by vcaqxmyr
That is very interesting. Can you tell how to learn more about injecting functions ?

Re: Dll Injection (Pipe Server & Client) Tutorial

Posted: Tue Nov 26, 2019 1:20 pm
by JohnFK
then I'm going to use a pipe client in order to call the DLL's functions from the outside
Why not simply export your dll functions and call them via createremotethread ? The only benefit and reason to use a pipe (against a memory mapped file) for inter process communication is when you have lots of different objects to transport in BOTH directions. Or over network or if access right matters. However if you just share known data types such as bytes or a single object you should use a memory mapped file as its faster. And if you only call functions of your DLL without any real return value (except of true/false) forget a pipe and use export functions.

Your idea is great, as well as writing a tutorial about but your example is bad for the reason above. I think the CE mono pipe is a good example and the CE veh debugger for choosing a memory mapped file and the CE speedhack for choosing export functions instead. Each of them have a specific purpose and specific data to transport so always choose the right method for your project based on what you are going to do.