Cheat Engine Forum Index Cheat Engine
The Official Site of Cheat Engine
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 


Dll Injection (Pipe Server & Client) Tutorial

 
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials
View previous topic :: View next topic  
Author Message
supMarco
How do I cheat?
Reputation: 1

Joined: 10 Mar 2019
Posts: 3

PostPosted: Sun Mar 10, 2019 2:33 am    Post subject: Dll Injection (Pipe Server & Client) Tutorial This post has 1 review(s) Reply with quote

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. (docs. microsoft. com / en-us/windows/desktop/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:
#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:
#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:
youtu.be / 5lujwFZp-KU
Back to top
View user's profile Send private message
supMarco
How do I cheat?
Reputation: 1

Joined: 10 Mar 2019
Posts: 3

PostPosted: Mon Mar 11, 2019 12:32 pm    Post subject: Reply with quote

Update #1:

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

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

Credits: I was inspired by a DB tip
Back to top
View user's profile Send private message
animesaga
How do I cheat?
Reputation: 0

Joined: 19 Oct 2019
Posts: 1

PostPosted: Sat Oct 19, 2019 1:18 am    Post subject: Reply with quote

Hey, thanks for the update.
Back to top
View user's profile Send private message
Csimbi
I post too much
Reputation: 72

Joined: 14 Jul 2007
Posts: 2271

PostPosted: Sat Oct 19, 2019 5:45 am    Post subject: Reply with quote

What are the practical applications?
Back to top
View user's profile Send private message
atom0s
Moderator
Reputation: 152

Joined: 25 Jan 2006
Posts: 7830
Location: 127.0.0.1

PostPosted: Sat Oct 19, 2019 7:07 pm    Post subject: Reply with quote

From personal experience in the past, I would not recommend the use of pipes for any serious/major communication between two processes. They are very unreliable if you are sending large data or requiring to send lots of data fast.

When I worked for a certain company in the past, we were building a packet-based bot for an MMO which had large packet chunks sent 10-1000 times a second. Chunks could range from a few bytes to upwards of 10k bytes. Using pipes was our first option but was quickly thrown out because of how unstable they were with this kind of workload.

I opt'd instead to use memory-mapped files (MMF) and wrote my own mini-protocol to handle the send/recv flow between the two sides of the communication which was rock solid and worked flawlessly for us.

With newer tech available now, things like local sockets are also an option and preferred now over things like pipes, MMFs, mailslots, etc.

_________________
- Retired.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    Cheat Engine Forum Index -> Cheat Engine Tutorials All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group

CE Wiki   IRC (#CEF)   Twitter
Third party websites