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

output command More...

#include "pch.h"

Functions

VOID CommandOutputHelp ()
 help of the output command
VOID CommandOutput (vector< CommandToken > CommandTokens, string Command)
 output command handler

Variables

LIST_ENTRY g_OutputSources
 Holds a list of output sources created by output command.
BOOLEAN g_OutputSourcesInitialized
 it shows whether the debugger started using output sources or not or in other words, is g_OutputSources initialized with a variable or it is empty

Detailed Description

output command

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

Function Documentation

◆ CommandOutput()

VOID CommandOutput ( vector< CommandToken > CommandTokens,
string Command )

output command handler

Parameters
CommandTokens
Command
Returns
VOID
59{
60 PDEBUGGER_EVENT_FORWARDING EventForwardingObject;
63 string DetailsOfSource;
64 UINT32 IndexToShowList;
65 PLIST_ENTRY TempList = 0;
66 BOOLEAN OutputSourceFound = FALSE;
67 HANDLE SourceHandle = INVALID_HANDLE_VALUE;
68 SOCKET Socket = NULL;
69 HMODULE Module = NULL;
70
71 if ((CommandTokens.size() != 1 && CommandTokens.size() <= 2) || CommandTokens.size() >= 6)
72 {
73 ShowMessages("incorrect use of the '%s'\n\n",
74 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
76 return;
77 }
78
79 //
80 // Check if the user needs a list of outputs or not
81 //
82 if (CommandTokens.size() == 1)
83 {
84 IndexToShowList = 0;
85
87 {
88 TempList = &g_OutputSources;
89
90 while (&g_OutputSources != TempList->Blink)
91 {
92 TempList = TempList->Blink;
93
94 PDEBUGGER_EVENT_FORWARDING CurrentOutputSourceDetails =
95 CONTAINING_RECORD(TempList, DEBUGGER_EVENT_FORWARDING, OutputSourcesList);
96
97 //
98 // Increase index
99 //
100 IndexToShowList++;
101
102 string TempStateString = "";
103 string TempTypeString = "";
104
105 if (CurrentOutputSourceDetails->State ==
107 {
108 TempStateString = "not opened";
109 }
110 else if (CurrentOutputSourceDetails->State ==
112 {
113 TempStateString = "opened ";
114 }
115 else if (CurrentOutputSourceDetails->State ==
117 {
118 TempStateString = "closed ";
119 }
120
121 if (CurrentOutputSourceDetails->Type == EVENT_FORWARDING_NAMEDPIPE)
122 {
123 TempTypeString = "namedpipe";
124 }
125 else if (CurrentOutputSourceDetails->Type == EVENT_FORWARDING_FILE)
126 {
127 TempTypeString = "file ";
128 }
129 else if (CurrentOutputSourceDetails->Type == EVENT_FORWARDING_TCP)
130 {
131 TempTypeString = "tcp ";
132 }
133 else if (CurrentOutputSourceDetails->Type == EVENT_FORWARDING_MODULE)
134 {
135 TempTypeString = "module ";
136 }
137
138 ShowMessages("%x %s %s\t%s\n", IndexToShowList, TempTypeString.c_str(), TempStateString.c_str(), CurrentOutputSourceDetails->Name);
139 }
140 }
141 else
142 {
143 ShowMessages("output forwarding list is empty\n");
144 }
145
146 return;
147 }
148
149 //
150 // Check if it's a create, open, or close
151 //
152 if (CompareLowerCaseStrings(CommandTokens.at(1), "create"))
153 {
154 //
155 // It's a create
156 //
157
158 //
159 // check if the parameters are okay for a create or not
160 //
161 if (CommandTokens.size() <= 4)
162 {
163 ShowMessages("incorrect use of the '%s'\n\n",
164 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
166 return;
167 }
168
169 //
170 // Check for the type of the output source
171 //
172 if (CompareLowerCaseStrings(CommandTokens.at(3), "file"))
173 {
175 }
176 else if (CompareLowerCaseStrings(CommandTokens.at(3), "namedpipe"))
177 {
179 }
180 else if (CompareLowerCaseStrings(CommandTokens.at(3), "tcp"))
181 {
183 }
184 else if (CompareLowerCaseStrings(CommandTokens.at(3), "module"))
185 {
187 }
188 else
189 {
190 ShowMessages("incorrect type near '%s'\n\n",
191 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(3)).c_str());
193 return;
194 }
195
196 //
197 // Check to make sure that the name doesn't exceed the maximum character
198 //
199 if (GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).size() >=
201 {
202 ShowMessages("name of the output cannot exceed form %d characters\n\n",
205 return;
206 }
207
208 //
209 // Search to see if there is another output source with the
210 // same name which we don't want to create two or more output
211 // sources with the same name
212 //
214 {
215 TempList = &g_OutputSources;
216
217 while (&g_OutputSources != TempList->Flink)
218 {
219 TempList = TempList->Flink;
220
221 PDEBUGGER_EVENT_FORWARDING CurrentOutputSourceDetails =
222 CONTAINING_RECORD(TempList, DEBUGGER_EVENT_FORWARDING, OutputSourcesList);
223
224 if (strcmp(CurrentOutputSourceDetails->Name,
225 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str()) == 0)
226 {
227 //
228 // Indicate that we found this item
229 //
230 OutputSourceFound = TRUE;
231
232 //
233 // No need to search through the list anymore
234 //
235 break;
236 }
237 }
238
239 //
240 // Check whether the entered name already exists
241 //
242 if (OutputSourceFound)
243 {
244 ShowMessages("err, the name you entered, already exists, please choose "
245 "another name\n");
246 return;
247 }
248 }
249
250 //
251 // try to open the source and get the handle
252 //
253 DetailsOfSource = GetCaseSensitiveStringFromCommandToken(CommandTokens.at(4));
254
255 SourceHandle = ForwardingCreateOutputSource(Type, DetailsOfSource, &Socket, &Module);
256
257 //
258 // Check if it's a valid handle or not
259 //
260 if (SourceHandle == INVALID_HANDLE_VALUE)
261 {
262 ShowMessages(
263 "err, invalid address or cannot open or find the address\n");
264 return;
265 }
266
267 //
268 // allocate the buffer for storing the event forwarding details
269 //
270 EventForwardingObject =
272
273 if (EventForwardingObject == NULL)
274 {
275 ShowMessages("err, in allocating memory for event forwarding\n");
276 return;
277 }
278
279 RtlZeroMemory(EventForwardingObject, sizeof(DEBUGGER_EVENT_FORWARDING));
280
281 //
282 // Set the state
283 //
284 EventForwardingObject->State = EVENT_FORWARDING_STATE_NOT_OPENED;
285
286 //
287 // Set the type
288 //
289 EventForwardingObject->Type = Type;
290
291 //
292 // Get a new tag
293 //
294 EventForwardingObject->OutputUniqueTag = ForwardingGetNewOutputSourceTag();
295
296 //
297 // Set the handle or in the case of TCP, set the socket
298 // or if it's a module the set the module handle
299 //
300 if (Type == EVENT_FORWARDING_TCP)
301 {
302 EventForwardingObject->Socket = Socket;
303 }
304 else if (Type == EVENT_FORWARDING_MODULE)
305 {
306 EventForwardingObject->Module = Module;
307
308 //
309 // Handle is the function address
310 //
311 EventForwardingObject->Handle = SourceHandle;
312 }
313 else
314 {
315 EventForwardingObject->Handle = SourceHandle;
316 }
317
318 //
319 // Move the name of the output source to the buffer
320 //
321 strcpy_s(EventForwardingObject->Name,
322 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str());
323
324 //
325 // Check if list is initialized or not
326 //
328 {
330 InitializeListHead(&g_OutputSources);
331 }
332
333 //
334 // Add the source to the trace list
335 //
336 InsertHeadList(&g_OutputSources,
337 &(EventForwardingObject->OutputSourcesList));
338 }
339 else if (CompareLowerCaseStrings(CommandTokens.at(1), "open"))
340 {
341 //
342 // It's an open
343 //
345 {
346 ShowMessages("err, the name you entered, not found\n");
347 return;
348 }
349
350 //
351 // Now we should find the corresponding object in the memory and
352 // pass it to the global open functions
353 //
354 TempList = &g_OutputSources;
355
356 while (&g_OutputSources != TempList->Flink)
357 {
358 TempList = TempList->Flink;
359
360 PDEBUGGER_EVENT_FORWARDING CurrentOutputSourceDetails = CONTAINING_RECORD(
361 TempList,
363 OutputSourcesList);
364
365 if (strcmp(CurrentOutputSourceDetails->Name,
366 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str()) == 0)
367 {
368 //
369 // Indicate that we found this item
370 //
371 OutputSourceFound = TRUE;
372
373 //
374 // Open the output
375 //
376 Status = ForwardingOpenOutputSource(CurrentOutputSourceDetails);
377
379 {
380 ShowMessages("err, the name you entered was already closed\n");
381 return;
382 }
384 {
385 ShowMessages("err, the name you entered was already opened\n");
386 return;
387 }
388 else if (Status !=
390 {
391 ShowMessages("err, unable to open the output source\n");
392 return;
393 }
394
395 //
396 // No need to search through the list anymore
397 //
398 break;
399 }
400 }
401
402 if (!OutputSourceFound)
403 {
404 ShowMessages("err, the name you entered, not found\n");
405 return;
406 }
407 }
408 else if (CompareLowerCaseStrings(CommandTokens.at(1), "close"))
409 {
410 //
411 // It's a close
412 //
414 {
415 ShowMessages("err, the name you entered, not found\n");
416 return;
417 }
418
419 //
420 // Now we should find the corresponding object in the memory and
421 // pass it to the global close functions
422 //
423 TempList = &g_OutputSources;
424
425 while (&g_OutputSources != TempList->Flink)
426 {
427 TempList = TempList->Flink;
428
429 PDEBUGGER_EVENT_FORWARDING CurrentOutputSourceDetails = CONTAINING_RECORD(
430 TempList,
432 OutputSourcesList);
433
434 if (strcmp(CurrentOutputSourceDetails->Name,
435 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(2)).c_str()) == 0)
436 {
437 //
438 // Indicate that we found this item
439 //
440 OutputSourceFound = TRUE;
441
442 //
443 // Close the output if it's not already closed
444 //
445 Status = ForwardingCloseOutputSource(CurrentOutputSourceDetails);
446
448 {
449 ShowMessages("err, the name you entered was already closed\n");
450 return;
451 }
453 {
454 ShowMessages("err, unable to close the source\n");
455 return;
456 }
457 else if (Status !=
459 {
460 ShowMessages("err, unable to close the source\n");
461 return;
462 }
463
464 //
465 // No need to search through the list anymore
466 //
467 break;
468 }
469 }
470
471 if (!OutputSourceFound)
472 {
473 ShowMessages("err, the name you entered, not found\n");
474 return;
475 }
476 }
477 else
478 {
479 //
480 // Invalid argument
481 //
482 ShowMessages("incorrect option at '%s'\n\n",
483 GetCaseSensitiveStringFromCommandToken(CommandTokens.at(0)).c_str());
485 return;
486 }
487}
UCHAR BOOLEAN
Definition BasicTypes.h:35
#define TRUE
Definition BasicTypes.h:114
#define FALSE
Definition BasicTypes.h:113
unsigned int UINT32
Definition BasicTypes.h:54
std::string GetCaseSensitiveStringFromCommandToken(CommandToken TargetToken)
Get case sensitive string from command token.
Definition common.cpp:467
BOOLEAN CompareLowerCaseStrings(CommandToken TargetToken, const CHAR *StringToCompare)
Compare lower case strings.
Definition common.cpp:503
DEBUGGER_OUTPUT_SOURCE_STATUS ForwardingCloseOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor)
Closes the output source.
Definition forwarding.cpp:110
DEBUGGER_OUTPUT_SOURCE_STATUS ForwardingOpenOutputSource(PDEBUGGER_EVENT_FORWARDING SourceDescriptor)
Opens the output source.
Definition forwarding.cpp:40
UINT64 ForwardingGetNewOutputSourceTag()
Get the output source tag and increase the global variable for tag.
Definition forwarding.cpp:28
PVOID ForwardingCreateOutputSource(DEBUGGER_EVENT_FORWARDING_TYPE SourceType, const string &Description, SOCKET *Socket, HMODULE *Module)
Create a new source (create handle from the source).
Definition forwarding.cpp:215
struct _DEBUGGER_EVENT_FORWARDING DEBUGGER_EVENT_FORWARDING
structures hold the detail of event forwarding
@ EVENT_FORWARDING_STATE_OPENED
Definition forwarding.h:54
@ EVENT_FORWARDING_CLOSED
Definition forwarding.h:55
@ EVENT_FORWARDING_STATE_NOT_OPENED
Definition forwarding.h:53
enum _DEBUGGER_EVENT_FORWARDING_TYPE DEBUGGER_EVENT_FORWARDING_TYPE
event forwarding type
#define MAXIMUM_CHARACTERS_FOR_EVENT_FORWARDING_NAME
maximum characters for event forwarding source names
Definition forwarding.h:32
@ DEBUGGER_OUTPUT_SOURCE_STATUS_SUCCESSFULLY_OPENED
Definition forwarding.h:67
@ DEBUGGER_OUTPUT_SOURCE_STATUS_UNKNOWN_ERROR
Definition forwarding.h:71
@ DEBUGGER_OUTPUT_SOURCE_STATUS_ALREADY_OPENED
Definition forwarding.h:69
@ DEBUGGER_OUTPUT_SOURCE_STATUS_SUCCESSFULLY_CLOSED
Definition forwarding.h:68
@ DEBUGGER_OUTPUT_SOURCE_STATUS_ALREADY_CLOSED
Definition forwarding.h:70
enum _DEBUGGER_OUTPUT_SOURCE_STATUS DEBUGGER_OUTPUT_SOURCE_STATUS
output source status
@ EVENT_FORWARDING_TCP
Definition forwarding.h:42
@ EVENT_FORWARDING_MODULE
Definition forwarding.h:43
@ EVENT_FORWARDING_FILE
Definition forwarding.h:41
@ EVENT_FORWARDING_NAMEDPIPE
Definition forwarding.h:40
struct _DEBUGGER_EVENT_FORWARDING * PDEBUGGER_EVENT_FORWARDING
NULL()
Definition test-case-generator.py:530
#define CONTAINING_RECORD(address, type, field)
Definition nt-list.h:36
VOID CommandOutputHelp()
help of the output command
Definition output.cpp:26
LIST_ENTRY g_OutputSources
Holds a list of output sources created by output command.
Definition globals.h:427
BOOLEAN g_OutputSourcesInitialized
it shows whether the debugger started using output sources or not or in other words,...
Definition globals.h:418
LIST_ENTRY OutputSourcesList
Definition forwarding.h:88
DEBUGGER_EVENT_FORWARDING_TYPE Type
Definition forwarding.h:81
DEBUGGER_EVENT_FORWARDING_STATE State
Definition forwarding.h:82
CHAR Name[MAXIMUM_CHARACTERS_FOR_EVENT_FORWARDING_NAME]
Definition forwarding.h:89
SOCKET Socket
Definition forwarding.h:84
HMODULE Module
Definition forwarding.h:85
UINT64 OutputUniqueTag
Definition forwarding.h:86
VOID * Handle
Definition forwarding.h:83

◆ CommandOutputHelp()

VOID CommandOutputHelp ( )

help of the output command

Returns
VOID
27{
28 ShowMessages("output : creates an output instance that can be used in event "
29 "forwarding.\n\n");
30
31 ShowMessages("syntax : \toutput\n");
32 ShowMessages("syntax : \toutput [create Name (string)] [file|namedpipe|tcp|module Address (string)]\n");
33 ShowMessages("syntax : \toutput [open|close Name (string)]\n");
34
35 ShowMessages("\n");
36 ShowMessages("\t\te.g : output\n");
37 ShowMessages("\t\te.g : output create MyOutputName1 file "
38 "c:\\rev\\output.txt\n");
39 ShowMessages("\t\te.g : output create MyOutputName1 file "
40 "\"c:\\rev\\output file.txt\"\n");
41 ShowMessages("\t\te.g : output create MyOutputName2 tcp 192.168.1.10:8080\n");
42 ShowMessages("\t\te.g : output create MyOutputName3 namedpipe "
43 "\\\\.\\Pipe\\HyperDbgOutput\n");
44 ShowMessages("\t\te.g : output create MyOutputName1 module "
45 "c:\\rev\\event_forwarding.dll\n");
46 ShowMessages("\t\te.g : output open MyOutputName1\n");
47 ShowMessages("\t\te.g : output close MyOutputName1\n");
48}

Variable Documentation

◆ g_OutputSources

LIST_ENTRY g_OutputSources
extern

Holds a list of output sources created by output command.

user-mode events and output sources are two separate things in HyperDbg

427{0};

◆ g_OutputSourcesInitialized

BOOLEAN g_OutputSourcesInitialized
extern

it shows whether the debugger started using output sources or not or in other words, is g_OutputSources initialized with a variable or it is empty