HyperDbg Debugger
Loading...
Searching...
No Matches
namedpipe.cpp File Reference

Server and Client communication over NamedPipes. More...

#include "pch.h"

Functions

UINT32 NamedPipeConnectingAndTransferringBuffers ()
 Connect and transfer buffers via named pipe.
HANDLE NamedPipeServerCreatePipe (LPCSTR PipeName, UINT32 OutputBufferSize, UINT32 InputBufferSize)
 Create a named pipe server.
BOOLEAN NamedPipeServerWaitForClientConnection (HANDLE PipeHandle)
 wait for client connection
UINT32 NamedPipeServerReadClientMessage (HANDLE PipeHandle, CHAR *BufferToSave, INT32 MaximumReadBufferLength)
 read client message from the named pipe
BOOLEAN NamedPipeServerSendMessageToClient (HANDLE PipeHandle, CHAR *BufferToSend, INT32 BufferSize)
 Send a message to the client over named pipe.
VOID NamedPipeServerCloseHandle (HANDLE PipeHandle)
 Close handle of server's named pipe.
HANDLE NamedPipeClientCreatePipe (LPCSTR PipeName)
 Create a client named pipe.
BOOLEAN NamedPipeClientSendMessage (HANDLE PipeHandle, CHAR *BufferToSend, INT32 BufferSize)
 Send client message over named pipe.
UINT32 NamedPipeClientReadMessage (HANDLE PipeHandle, CHAR *BufferToRead, INT32 MaximumSizeOfBuffer)
 Read a message from the server over named pipe.
VOID NamedPipeClientClosePipe (HANDLE PipeHandle)
 close named pipe handle of client
INT32 NamedPipeServerExample ()
 An example of how to use named pipe as a server.
INT32 NamedPipeClientExample ()
 An example of how to use named pipe as a client.

Detailed Description

Server and Client communication over NamedPipes.

Author
Sina Karvandi (sina@.nosp@m.hype.nosp@m.rdbg..nosp@m.org)
Version
0.1
Date
2020-07-15

Function Documentation

◆ NamedPipeClientClosePipe()

VOID NamedPipeClientClosePipe ( HANDLE PipeHandle)

close named pipe handle of client

Parameters
PipeHandle
Returns
VOID
465{
466 CloseHandle(PipeHandle);
467}

◆ NamedPipeClientCreatePipe()

HANDLE NamedPipeClientCreatePipe ( LPCSTR PipeName)

Create a client named pipe.

Pipe name format - \servername\pipe\pipename This pipe is for server on the same computer, however, pipes can be used to connect to a remote server

Parameters
PipeName
Returns
HANDLE
337{
338 HANDLE hPipe;
339
340 //
341 // Connect to the server pipe using CreateFile()
342 //
343 hPipe = CreateFileA(PipeName, // pipe name
344 GENERIC_READ | // read and write access
345 GENERIC_WRITE,
346 0, // no sharing
347 NULL, // default security attributes
348 OPEN_EXISTING, // opens existing pipe
349 0, // default attributes
350 NULL); // no template file
351
352 if (INVALID_HANDLE_VALUE == hPipe)
353 {
354 printf("err, occurred while connecting to the server (%x)\n",
355 GetLastError());
356 //
357 // One might want to check whether the server pipe is busy
358 // This sample will error out if the server pipe is busy
359 // Read on ERROR_PIPE_BUSY and WaitNamedPipe() for that
360 //
361
362 //
363 // Error
364 //
365 return NULL;
366 }
367 else
368 {
369 return hPipe;
370 }
371}
printf("ho")
NULL()
Definition test-case-generator.py:530

◆ NamedPipeClientExample()

INT32 NamedPipeClientExample ( )

An example of how to use named pipe as a client.

Returns
INT32
560{
561 HANDLE PipeHandle;
562 BOOLEAN SentMessageResult;
563 UINT32 ReadBytes;
564 const INT32 BufferSize = 1024;
565 CHAR Buffer[BufferSize] = "test message to send from client !!!";
566 PipeHandle = NamedPipeClientCreatePipe("\\\\.\\Pipe\\HyperDbgTests");
567
568 if (!PipeHandle)
569 {
570 //
571 // Unable to create handle
572 //
573 return 1;
574 }
575
576 SentMessageResult =
577 NamedPipeClientSendMessage(PipeHandle, Buffer, (INT32)strlen(Buffer) + 1);
578
579 if (!SentMessageResult)
580 {
581 //
582 // Sending error
583 //
584 return 1;
585 }
586
587 ReadBytes = NamedPipeClientReadMessage(PipeHandle, Buffer, BufferSize);
588
589 if (!ReadBytes)
590 {
591 //
592 // Nothing to read
593 //
594 return 1;
595 }
596
597 printf("Server sent the following message: %s\n", Buffer);
598
599 NamedPipeClientClosePipe(PipeHandle);
600
601 return 0;
602}
signed int INT32
Definition BasicTypes.h:50
UCHAR BOOLEAN
Definition BasicTypes.h:35
unsigned int UINT32
Definition BasicTypes.h:54
char CHAR
Definition BasicTypes.h:33
BOOLEAN NamedPipeClientSendMessage(HANDLE PipeHandle, CHAR *BufferToSend, INT32 BufferSize)
Send client message over named pipe.
Definition namedpipe.cpp:382
HANDLE NamedPipeClientCreatePipe(LPCSTR PipeName)
Create a client named pipe.
Definition namedpipe.cpp:336
UINT32 NamedPipeClientReadMessage(HANDLE PipeHandle, CHAR *BufferToRead, INT32 MaximumSizeOfBuffer)
Read a message from the server over named pipe.
Definition namedpipe.cpp:430
VOID NamedPipeClientClosePipe(HANDLE PipeHandle)
close named pipe handle of client
Definition namedpipe.cpp:464

◆ NamedPipeClientReadMessage()

UINT32 NamedPipeClientReadMessage ( HANDLE PipeHandle,
CHAR * BufferToRead,
INT32 MaximumSizeOfBuffer )

Read a message from the server over named pipe.

Parameters
PipeHandleHandle of the named pipe
BufferToReadBuffer to store the received message
MaximumSizeOfBufferMaximum size of the receive buffer
Returns
UINT32 number of bytes read, or 0 on failure
431{
432 DWORD BytesTransferred;
433
434 //
435 // Read server response
436 //
437 BOOLEAN Result = ReadFile(PipeHandle, // handle to pipe
438 BufferToRead, // buffer to receive data
439 MaximumSizeOfBuffer, // size of buffer
440 &BytesTransferred, // number of bytes read
441 NULL); // not overlapped I/O
442
443 if ((!Result) || (0 == BytesTransferred))
444 {
445 printf("err, occurred while reading from the server (%x)\n",
446 GetLastError());
447 CloseHandle(PipeHandle);
448 return 0; // Error
449 }
450
451 //
452 // Success
453 //
454 return BytesTransferred;
455}
unsigned long DWORD
Definition BasicTypes.h:38

◆ NamedPipeClientSendMessage()

BOOLEAN NamedPipeClientSendMessage ( HANDLE PipeHandle,
CHAR * BufferToSend,
INT32 BufferSize )

Send client message over named pipe.

Parameters
PipeHandleHandle of the named pipe
BufferToSendBuffer containing the message to send
BufferSizeSize of the buffer to send
Returns
BOOLEAN TRUE if successful, FALSE otherwise
383{
384 //
385 // We are done connecting to the server pipe,
386 // we can start communicating with
387 // the server using ReadFile()/WriteFile()
388 // on handle - hPipe
389 //
390
391 DWORD BytesTransferred;
392
393 //
394 // Send the message to server
395 //
396 BOOLEAN Result =
397 WriteFile(PipeHandle, // handle to pipe
398 BufferToSend, // buffer to write from
399 BufferSize, // number of bytes to write, include the NULL
400 &BytesTransferred, // number of bytes written
401 NULL); // not overlapped I/O
402
403 if ((!Result) || (BufferSize != (INT32)BytesTransferred))
404 {
405 printf("err, occurred while writing to the server (%x)\n",
406 GetLastError());
407 CloseHandle(PipeHandle);
408
409 //
410 // Error
411 //
412 CloseHandle(PipeHandle);
413 return FALSE;
414 }
415 else
416 {
417 return TRUE;
418 }
419}
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113

◆ NamedPipeConnectingAndTransferringBuffers()

UINT32 NamedPipeConnectingAndTransferringBuffers ( )

Connect and transfer buffers via named pipe.

Returns
UINT32
21{
22 // HANDLE PipeHandle;
23 // BOOLEAN SentMessageResult;
24 // UINT32 ReadBytes;
25 // char * Buffer;
26 //
27 // Buffer = (char *)malloc(TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
28 //
29 // if (!Buffer)
30 // {
31 // printf("err, could not allocate communication buffer\n");
32 // _getch();
33 // return 1;
34 // }
35 //
36 // RtlZeroMemory(Buffer, TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
37 // strcpy_s(Buffer, TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE, "Hey there, Are you HyperDbg?");
38 //
39 // //
40 // // Perform our shaking with HyperDbg
41 // //
42 //
43 // //
44 // // It's not called directly, it's probably from HyperDbg
45 // //
46 // PipeHandle = NamedPipeClientCreatePipe("\\\\.\\Pipe\\HyperDbgTests");
47 //
48 // if (!PipeHandle)
49 // {
50 // //
51 // // Unable to create handle
52 // //
53 // free(Buffer);
54 //
55 // printf("err, unable to create handle\n");
56 // _getch();
57 // return 1;
58 // }
59 //
60 // SentMessageResult =
61 // NamedPipeClientSendMessage(PipeHandle, Buffer, (int)strlen(Buffer) + 1);
62 //
63 // if (!SentMessageResult)
64 // {
65 // //
66 // // Sending error
67 // //
68 // free(Buffer);
69 //
70 // printf("err, unable to send message\n");
71 // _getch();
72 // return 1;
73 // }
74 //
75 // ReadBytes = NamedPipeClientReadMessage(PipeHandle, Buffer, TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
76 //
77 // if (!ReadBytes)
78 // {
79 // //
80 // // Nothing to read
81 // //
82 // free(Buffer);
83 //
84 // printf("err, unable to read message\n");
85 // _getch();
86 // return 1;
87 // }
88 //
89 // if (strcmp(Buffer,
90 // "Hello, Dear Test Process... Yes, I'm HyperDbg Debugger :)") ==
91 // 0)
92 // {
93 // //
94 // // *** Connected to the HyperDbg debugger ***
95 // //
96 //
97 // //
98 // // Now we should request the test case number from the HyperDbg Debugger
99 // //
100 // RtlZeroMemory(Buffer, TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
101 //
102 // strcpy_s(
103 // Buffer,
104 // TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE,
105 // "Wow! I miss you... Would you plz send test cases?");
106 //
107 // SentMessageResult =
108 // NamedPipeClientSendMessage(PipeHandle, Buffer, (int)strlen(Buffer) + 1);
109 //
110 // if (!SentMessageResult)
111 // {
112 // //
113 // // Sending error
114 // //
115 // free(Buffer);
116 //
117 // printf("err, sending error\n");
118 // _getch();
119 // return 1;
120 // }
121 //
122 // //
123 // // Read the test case number
124 // //
125 // RtlZeroMemory(Buffer, TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
126 // ReadBytes = NamedPipeClientReadMessage(PipeHandle, Buffer, TEST_CASE_MAXIMUM_BUFFERS_TO_COMMUNICATE);
127 //
128 // if (!ReadBytes)
129 // {
130 // //
131 // // Nothing to read
132 // //
133 // free(Buffer);
134 //
135 // printf("err, nothing to read\n");
136 // _getch();
137 // return 1;
138 // }
139 //
140 // //
141 // // Dispatch the test case number
142 // //
143 //
144 // /// TestCreateLookupTable(PipeHandle, (PVOID)Buffer, ReadBytes);
145 // printf("!!!! Read to run the test cases !!!!");
146 // _getch();
147 //
148 // //
149 // // Close the pipe connection
150 // //
151 // NamedPipeClientClosePipe(PipeHandle);
152 //
153 // //
154 // // Make sure to exit the test program
155 // //
156 // exit(0);
157 // }
158 //
159 // free(Buffer);
160 return 0;
161}

◆ NamedPipeServerCloseHandle()

VOID NamedPipeServerCloseHandle ( HANDLE PipeHandle)

Close handle of server's named pipe.

Parameters
PipeHandle
Returns
VOID
314{
315 CloseHandle(PipeHandle);
316}

◆ NamedPipeServerCreatePipe()

HANDLE NamedPipeServerCreatePipe ( LPCSTR PipeName,
UINT32 OutputBufferSize,
UINT32 InputBufferSize )

Create a named pipe server.

Parameters
PipeName
OutputBufferSize
InputBufferSize
Returns
HANDLE
177{
178 HANDLE hPipe;
179
180 hPipe = CreateNamedPipeA(PipeName, // pipe name
181 PIPE_ACCESS_DUPLEX, // read/write access
182 PIPE_TYPE_MESSAGE | // message type pipe
183 PIPE_READMODE_MESSAGE | // message-read mode
184 PIPE_WAIT, // blocking mode
185 PIPE_UNLIMITED_INSTANCES, // max. instances
186 OutputBufferSize, // output buffer size
187 InputBufferSize, // input buffer size
188 NMPWAIT_USE_DEFAULT_WAIT, // client time-out
189 NULL); // default security attribute
190
191 if (INVALID_HANDLE_VALUE == hPipe)
192 {
193 printf("err, occurred while creating the pipe (%x)\n",
194 GetLastError());
195 return NULL;
196 }
197 return hPipe;
198}

◆ NamedPipeServerExample()

INT32 NamedPipeServerExample ( )

An example of how to use named pipe as a server.

Returns
INT32
482{
483 HANDLE PipeHandle;
484 BOOLEAN SentMessageResult;
485 UINT32 ReadBytes;
486 const INT32 BufferSize = 1024;
487 CHAR BufferToRead[BufferSize] = {0};
488 CHAR BufferToSend[BufferSize] = "test message to send from server !!!";
489
490 printf("create name pipe\n");
491 PipeHandle = NamedPipeServerCreatePipe("\\\\.\\Pipe\\HyperDbgTests",
492 BufferSize,
493 BufferSize);
494 if (!PipeHandle)
495 {
496 //
497 // Error in creating handle
498 //
499 return 1;
500 }
501
502 printf("success!\n");
503 printf("wait for the client connection\n");
504
506 {
507 //
508 // Error in connection
509 //
510 return 1;
511 }
512
513 printf("client connected\n");
514 printf("read client message\n");
515
516 ReadBytes =
517 NamedPipeServerReadClientMessage(PipeHandle, BufferToRead, BufferSize);
518
519 if (!ReadBytes)
520 {
521 //
522 // Nothing to read
523 //
524 return 1;
525 }
526
527 printf("Message from client : %s\n", BufferToRead);
528
529 SentMessageResult = NamedPipeServerSendMessageToClient(
530 PipeHandle,
531 BufferToSend,
532 (INT32)strlen(BufferToSend) + 1);
533
534 if (!SentMessageResult)
535 {
536 //
537 // error in sending
538 //
539 return 1;
540 }
541
542 NamedPipeServerCloseHandle(PipeHandle);
543
544 return 0;
545}
BOOLEAN NamedPipeServerWaitForClientConnection(HANDLE PipeHandle)
wait for client connection
Definition namedpipe.cpp:207
HANDLE NamedPipeServerCreatePipe(LPCSTR PipeName, UINT32 OutputBufferSize, UINT32 InputBufferSize)
Create a named pipe server.
Definition namedpipe.cpp:176
BOOLEAN NamedPipeServerSendMessageToClient(HANDLE PipeHandle, CHAR *BufferToSend, INT32 BufferSize)
Send a message to the client over named pipe.
Definition namedpipe.cpp:280
VOID NamedPipeServerCloseHandle(HANDLE PipeHandle)
Close handle of server's named pipe.
Definition namedpipe.cpp:313
UINT32 NamedPipeServerReadClientMessage(HANDLE PipeHandle, CHAR *BufferToSave, INT32 MaximumReadBufferLength)
read client message from the named pipe
Definition namedpipe.cpp:237

◆ NamedPipeServerReadClientMessage()

UINT32 NamedPipeServerReadClientMessage ( HANDLE PipeHandle,
CHAR * BufferToSave,
INT32 MaximumReadBufferLength )

read client message from the named pipe

Parameters
PipeHandle
BufferToSave
MaximumReadBufferLength
Returns
UINT32
238{
239 DWORD BytesTransferred;
240
241 //
242 // We are connected to the client.
243 // To communicate with the client
244 // we will use ReadFile()/WriteFile()
245 // on the pipe handle - hPipe
246 //
247
248 //
249 // Read client message
250 //
251 BOOLEAN Result = ReadFile(PipeHandle, // handle to pipe
252 BufferToSave, // buffer to receive data
253 MaximumReadBufferLength, // size of buffer
254 &BytesTransferred, // number of bytes read
255 NULL); // not overlapped I/O
256
257 if ((!Result) || (0 == BytesTransferred))
258 {
259 printf("err, occurred while reading from the client (%x)\n",
260 GetLastError());
261 CloseHandle(PipeHandle);
262 return 0;
263 }
264
265 //
266 // Number of bytes that the client sends to us
267 //
268 return BytesTransferred;
269}

◆ NamedPipeServerSendMessageToClient()

BOOLEAN NamedPipeServerSendMessageToClient ( HANDLE PipeHandle,
CHAR * BufferToSend,
INT32 BufferSize )

Send a message to the client over named pipe.

Parameters
PipeHandleHandle of the named pipe
BufferToSendBuffer containing the message to send
BufferSizeSize of the buffer to send
Returns
BOOLEAN TRUE if successful, FALSE otherwise
283{
284 DWORD BytesTransferred;
285
286 //
287 // Reply to client
288 //
289 BOOLEAN Result =
290 WriteFile(PipeHandle, // handle to pipe
291 BufferToSend, // buffer to write from
292 BufferSize, // number of bytes to write, include the NULL
293 &BytesTransferred, // number of bytes written
294 NULL); // not overlapped I/O
295
296 if ((!Result) || (BufferSize != (INT32)BytesTransferred))
297 {
298 printf("err, occurred while writing to the client (%x)\n",
299 GetLastError());
300 CloseHandle(PipeHandle);
301 return FALSE;
302 }
303 return TRUE;
304}

◆ NamedPipeServerWaitForClientConnection()

BOOLEAN NamedPipeServerWaitForClientConnection ( HANDLE PipeHandle)

wait for client connection

Parameters
PipeHandle
Returns
BOOLEAN
208{
209 //
210 // Wait for the client to connect
211 //
212 BOOLEAN ClientConnected = ConnectNamedPipe(PipeHandle, NULL);
213
214 if (FALSE == ClientConnected)
215 {
216 printf("err, occurred while connecting to the client (%x)\n",
217 GetLastError());
218 CloseHandle(PipeHandle);
219 return FALSE;
220 }
221
222 //
223 // Client connected
224 //
225 return TRUE;
226}