HyperDbg Debugger
Loading...
Searching...
No Matches
Transparency.c File Reference

try to hide the debugger from anti-debugging and anti-hypervisor methods More...

#include "pch.h"

Macros

#define MY_RAND_MAX   32768
 maximum random value
 

Functions

UINT32 TransparentGetRand ()
 Generate a random number by utilizing RDTSC instruction.
 
int TransparentPow (int x, int p)
 Integer power function definition.
 
int TransparentLog (int x)
 Integer Natural Logarithm function estimation.
 
int TransparentSqrt (int x)
 Integer root function estimation.
 
int TransparentRandn (int Average, int Sigma)
 Integer Gaussian Random Number Generator(GRNG) based on Box-Muller method. A Float to Integer mapping is used in the function.
 
BOOLEAN TransparentAddNameOrProcessIdToTheList (PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE Measurements)
 Add name or process id of the target process to the list of processes that HyperDbg should apply transparent-mode on them.
 
NTSTATUS TransparentHideDebugger (PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE Measurements)
 Hide debugger on transparent-mode (activate transparent-mode)
 
NTSTATUS TransparentUnhideDebugger ()
 Deactivate transparent-mode.
 
BOOLEAN TransparentModeStart (VIRTUAL_MACHINE_STATE *VCpu, UINT32 ExitReason)
 VM-Exit handler for different exit reasons.
 

Variables

int TransparentTableLog []
 pre-defined log result
 

Detailed Description

try to hide the debugger from anti-debugging and anti-hypervisor methods

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

Macro Definition Documentation

◆ MY_RAND_MAX

#define MY_RAND_MAX   32768

maximum random value

Function Documentation

◆ TransparentAddNameOrProcessIdToTheList()

BOOLEAN TransparentAddNameOrProcessIdToTheList ( PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE Measurements)

Add name or process id of the target process to the list of processes that HyperDbg should apply transparent-mode on them.

Parameters
Measurements
Returns
BOOLEAN
271{
272 SIZE_T SizeOfBuffer;
273 PTRANSPARENCY_PROCESS PidAndNameBuffer;
274
275 //
276 // Check whether it's a process id or it's a process name
277 //
278 if (Measurements->TrueIfProcessIdAndFalseIfProcessName)
279 {
280 //
281 // It's a process Id
282 //
283 SizeOfBuffer = sizeof(TRANSPARENCY_PROCESS);
284 }
285 else
286 {
287 //
288 // It's a process name
289 //
290 SizeOfBuffer = sizeof(TRANSPARENCY_PROCESS) + Measurements->LengthOfProcessName;
291 }
292
293 //
294 // Allocate the Buffer
295 //
296 PidAndNameBuffer = PlatformMemAllocateZeroedNonPagedPool(SizeOfBuffer);
297
298 if (PidAndNameBuffer == NULL)
299 {
300 return FALSE;
301 }
302
303 //
304 // Save the address of the buffer for future de-allocation
305 //
306 PidAndNameBuffer->BufferAddress = PidAndNameBuffer;
307
308 //
309 // Check again whether it's a process id or it's a process name
310 // then fill the structure
311 //
312 if (Measurements->TrueIfProcessIdAndFalseIfProcessName)
313 {
314 //
315 // It's a process Id
316 //
317 PidAndNameBuffer->ProcessId = Measurements->ProcId;
318 PidAndNameBuffer->TrueIfProcessIdAndFalseIfProcessName = TRUE;
319 }
320 else
321 {
322 //
323 // It's a process name
324 //
326
327 //
328 // Move the process name string to the end of the buffer
329 //
330 RtlCopyBytes((void *)((UINT64)PidAndNameBuffer + sizeof(TRANSPARENCY_PROCESS)),
331 (const void *)((UINT64)Measurements + sizeof(DEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE)),
332 Measurements->LengthOfProcessName);
333
334 //
335 // Set the process name location
336 //
337 PidAndNameBuffer->ProcessName = (PVOID)((UINT64)PidAndNameBuffer + sizeof(TRANSPARENCY_PROCESS));
338 }
339
340 //
341 // Link it to the list of process that we need to transparent
342 // vm-exits for them
343 //
345
346 return TRUE;
347}
#define TRUE
Definition BasicTypes.h:55
#define FALSE
Definition BasicTypes.h:54
unsigned __int64 UINT64
Definition BasicTypes.h:21
TRANSPARENCY_MEASUREMENTS * g_TransparentModeMeasurements
holds the measurements from the user-mode and kernel-mode
Definition GlobalVariables.h:56
PVOID PlatformMemAllocateZeroedNonPagedPool(SIZE_T NumberOfBytes)
Allocate a non-paged buffer (zeroed)
Definition Mem.c:69
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ PLIST_ENTRY Entry)
Definition Windows.h:115
struct _TRANSPARENCY_PROCESS TRANSPARENCY_PROCESS
The ProcessList of TRANSPARENCY_MEASUREMENTS is from this architecture.
request for enable or disable transparent-mode
Definition RequestStructures.h:549
UINT32 LengthOfProcessName
Definition RequestStructures.h:562
BOOLEAN TrueIfProcessIdAndFalseIfProcessName
Definition RequestStructures.h:560
UINT32 ProcId
Definition RequestStructures.h:561
LIST_ENTRY ProcessList
Definition Transparency.h:55
The ProcessList of TRANSPARENCY_MEASUREMENTS is from this architecture.
Definition Transparency.h:64
PVOID BufferAddress
Definition Transparency.h:67
UINT32 ProcessId
Definition Transparency.h:65
LIST_ENTRY OtherProcesses
Definition Transparency.h:69
BOOLEAN TrueIfProcessIdAndFalseIfProcessName
Definition Transparency.h:68
PVOID ProcessName
Definition Transparency.h:66

◆ TransparentGetRand()

UINT32 TransparentGetRand ( )

Generate a random number by utilizing RDTSC instruction.

Masking 16 LSB of the measured clock time.

Returns
UINT32
135{
136 UINT64 Tsc;
137 UINT32 Rand;
138
139 Tsc = __rdtsc();
140 Rand = Tsc & 0xffff;
141
142 return Rand;
143}
unsigned int UINT32
Definition BasicTypes.h:48

◆ TransparentHideDebugger()

NTSTATUS TransparentHideDebugger ( PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE Measurements)

Hide debugger on transparent-mode (activate transparent-mode)

Parameters
Measurements
Returns
NTSTATUS
357{
358 //
359 // Check whether the transparent-mode was already initialized or not
360 //
362 {
363 //
364 // Allocate the measurements buffer
365 //
367
369 {
370 return STATUS_INSUFFICIENT_RESOURCES;
371 }
372
373 //
374 // Initialize the lists
375 //
377
378 //
379 // Fill the transparency details CPUID
380 //
384
385 //
386 // Fill the transparency details RDTSC
387 //
391
392 //
393 // add the new process name or Id to the list
394 //
396
397 //
398 // Enable RDTSC and RDTSCP exiting on all cores
399 //
401
402 //
403 // Finally, enable the transparent-mode
404 //
406 }
407 else
408 {
409 //
410 // It's already initialized, we just need to
411 // add the new process name or Id to the list
412 //
414 }
415
416 return STATUS_SUCCESS;
417}
VOID BroadcastEnableRdtscExitingAllCores()
a broadcast that causes vm-exit on all execution of rdtsc/rdtscp
Definition Broadcast.c:132
BOOLEAN g_TransparentMode
Shows whether the debugger transparent mode is enabled (true) or not (false)
Definition GlobalVariables.h:75
BOOLEAN TransparentAddNameOrProcessIdToTheList(PDEBUGGER_HIDE_AND_TRANSPARENT_DEBUGGER_MODE Measurements)
Add name or process id of the target process to the list of processes that HyperDbg should apply tran...
Definition Transparency.c:270
FORCEINLINE VOID InitializeListHead(_Out_ PLIST_ENTRY ListHead)
Definition Windows.h:41
struct _TRANSPARENCY_MEASUREMENTS * PTRANSPARENCY_MEASUREMENTS
UINT64 CpuidStandardDeviation
Definition RequestStructures.h:553
UINT64 RdtscStandardDeviation
Definition RequestStructures.h:557
UINT64 CpuidAverage
Definition RequestStructures.h:552
UINT64 RdtscAverage
Definition RequestStructures.h:556
UINT64 CpuidMedian
Definition RequestStructures.h:554
UINT64 RdtscMedian
Definition RequestStructures.h:558
The measurements from user-mode and kernel-mode.
Definition Transparency.h:46
UINT64 RdtscStandardDeviation
Definition Transparency.h:52
UINT64 CpuidStandardDeviation
Definition Transparency.h:48
UINT64 RdtscAverage
Definition Transparency.h:51
UINT64 CpuidAverage
Definition Transparency.h:47
UINT64 RdtscMedian
Definition Transparency.h:53
UINT64 CpuidMedian
Definition Transparency.h:49

◆ TransparentLog()

int TransparentLog ( int x)

Integer Natural Logarithm function estimation.

@params x input value

Returns
int
171{
172 int n = x;
173 int Digit = 0;
174
175 while (n >= 100)
176 {
177 n = n / 10;
178 Digit++;
179 }
180
181 //
182 // Use pre-defined values of logarithms and estimate the total value
183 //
184 return TransparentTableLog[n] / 100 + (Digit * 23) / 10;
185}
x
Definition 01-expressions-correct.txt:2
int TransparentTableLog[]
pre-defined log result
Definition Transparency.c:24

◆ TransparentModeStart()

BOOLEAN TransparentModeStart ( VIRTUAL_MACHINE_STATE * VCpu,
UINT32 ExitReason )

VM-Exit handler for different exit reasons.

Should be called from vmx-root

Parameters
VCpuThe virtual processor's state
ExitReasonExit Reason
Returns
BOOLEAN Return True we should emulate RDTSCP or return false if we should not emulate RDTSCP
494{
495 UINT32 Aux = 0;
496 PLIST_ENTRY TempList = 0;
497 PCHAR CurrentProcessName = 0;
498 UINT32 CurrentProcessId;
499 UINT64 CurrrentTime;
500 HANDLE CurrentThreadId;
501 BOOLEAN Result = TRUE;
502 BOOLEAN IsProcessOnTransparencyList = FALSE;
503
504 //
505 // Save the current time
506 //
507 CurrrentTime = __rdtscp(&Aux);
508
509 //
510 // Save time of vm-exit on each logical processor separately
511 //
512 VCpu->TransparencyState.PreviousTimeStampCounter = CurrrentTime;
513
514 //
515 // Find the current process id and name
516 //
517 CurrentProcessId = HANDLE_TO_UINT32(PsGetCurrentProcessId());
518 CurrentProcessName = CommonGetProcessNameFromProcessControlBlock(PsGetCurrentProcess());
519
520 //
521 // Check for process id and process name, if not match then we don't emulate it
522 //
524 while (&g_TransparentModeMeasurements->ProcessList != TempList->Flink)
525 {
526 TempList = TempList->Flink;
527 PTRANSPARENCY_PROCESS ProcessDetails = (PTRANSPARENCY_PROCESS)CONTAINING_RECORD(TempList, TRANSPARENCY_PROCESS, OtherProcesses);
528 if (ProcessDetails->TrueIfProcessIdAndFalseIfProcessName)
529 {
530 //
531 // This entry is process id
532 //
533 if (ProcessDetails->ProcessId == CurrentProcessId)
534 {
535 //
536 // Let the transparency handler to handle it
537 //
538 IsProcessOnTransparencyList = TRUE;
539 break;
540 }
541 }
542 else
543 {
544 //
545 // This entry is a process name
546 //
547 if (CurrentProcessName != NULL && CommonIsStringStartsWith(CurrentProcessName, ProcessDetails->ProcessName))
548 {
549 //
550 // Let the transparency handler to handle it
551 //
552 IsProcessOnTransparencyList = TRUE;
553 break;
554 }
555 }
556 }
557
558 //
559 // Check whether we find this process on transparency list or not
560 //
561 if (!IsProcessOnTransparencyList)
562 {
563 //
564 // No, we didn't let's do the normal tasks
565 //
566 return TRUE;
567 }
568
569 //
570 // Get current thread Id
571 //
572 CurrentThreadId = PsGetCurrentThreadId();
573
574 //
575 // Check whether we are in new thread or in previous thread
576 //
577 if (VCpu->TransparencyState.ThreadId != CurrentThreadId)
578 {
579 //
580 // It's a new thread Id reset everything
581 //
582 VCpu->TransparencyState.ThreadId = CurrentThreadId;
585 }
586
587 //
588 // Now, it's time to check and play with RDTSC/P and CPUID
589 //
590
591 if (ExitReason == VMX_EXIT_REASON_EXECUTE_RDTSC || ExitReason == VMX_EXIT_REASON_EXECUTE_RDTSCP)
592 {
594 {
595 //
596 // It's a timing and the previous time for the thread is null
597 // so we need to save the time (maybe) for future use
598 //
600 }
602 {
603 //
604 // Someone tries to know about the hypervisor
605 // let's play with them
606 //
607
608 // LogInfo("Possible RDTSC+CPUID+RDTSC");
609 }
612 {
613 //
614 // It's a new rdtscp, let's save the new value
615 //
619 ;
620 }
621
622 //
623 // Adjust the rdtsc based on RevealedTimeStampCounterByRdtsc
624 //
625 VCpu->Regs->rax = 0x00000000ffffffff &
627
628 VCpu->Regs->rdx = 0x00000000ffffffff &
630
631 //
632 // Check if we need to adjust rcx as a result of rdtscp
633 //
634 if (ExitReason == VMX_EXIT_REASON_EXECUTE_RDTSCP)
635 {
636 VCpu->Regs->rcx = 0x00000000ffffffff & Aux;
637 }
638 //
639 // Shows that vm-exit handler should not emulate the RDTSC/P
640 //
641 Result = FALSE;
642 }
643 else if (ExitReason == VMX_EXIT_REASON_EXECUTE_CPUID &&
645 {
646 //
647 // The guy executed one or more CPUIDs after an rdtscp so we
648 // need to add new cpuid value to previous timer and also
649 // we need to store it somewhere to remember this behavior
650 //
654
656 }
657
658 return Result;
659}
UCHAR BOOLEAN
Definition BasicTypes.h:39
#define NULL64_ZERO
Definition BasicTypes.h:52
#define HANDLE_TO_UINT32(_var)
Definition MetaMacros.h:39
int TransparentRandn(int Average, int Sigma)
Integer Gaussian Random Number Generator(GRNG) based on Box-Muller method. A Float to Integer mapping...
Definition Transparency.c:232
BOOLEAN CommonIsStringStartsWith(const char *pre, const char *str)
Detects whether the string starts with another string.
Definition Common.c:69
PCHAR CommonGetProcessNameFromProcessControlBlock(PEPROCESS Eprocess)
Get process name by eprocess.
Definition Common.c:48
struct _TRANSPARENCY_PROCESS * PTRANSPARENCY_PROCESS
GUEST_REGS * Regs
Definition State.h:305
VM_EXIT_TRANSPARENCY TransparencyState
Definition State.h:330
UINT64 RevealedTimeStampCounterByRdtsc
Definition State.h:141
UINT64 PreviousTimeStampCounter
Definition State.h:138
HANDLE ThreadId
Definition State.h:140
BOOLEAN CpuidAfterRdtscDetected
Definition State.h:142
UINT64 rax
Definition BasicTypes.h:75
UINT64 rcx
Definition BasicTypes.h:76
UINT64 rdx
Definition BasicTypes.h:77

◆ TransparentPow()

int TransparentPow ( int x,
int p )

Integer power function definition.

@params x Base Value @params p Power Value

Returns
int
154{
155 int Res = 1;
156 for (int i = 0; i < p; i++)
157 {
158 Res = Res * x;
159 }
160 return Res;
161}

◆ TransparentRandn()

int TransparentRandn ( int Average,
int Sigma )

Integer Gaussian Random Number Generator(GRNG) based on Box-Muller method. A Float to Integer mapping is used in the function.

@params Average Mean @parans Sigma Standard Deviation of the targeted Gaussian Distribution

Returns
int
233{
234 int U1, r1, U2, r2, W, Mult;
235 int X1, X2 = 0, XS1;
236 int LogTemp = 0;
237
238 do
239 {
240 r1 = TransparentGetRand();
241 r2 = TransparentGetRand();
242
243 U1 = (r1 % MY_RAND_MAX) - (MY_RAND_MAX / 2);
244
245 U2 = (r2 % MY_RAND_MAX) - (MY_RAND_MAX / 2);
246
247 W = U1 * U1 + U2 * U2;
248 } while (W >= MY_RAND_MAX * MY_RAND_MAX / 2 || W == 0);
249
251
252 Mult = TransparentSqrt((-2 * LogTemp) * (MY_RAND_MAX * MY_RAND_MAX / W));
253
254 X1 = U1 * Mult / MY_RAND_MAX;
255 XS1 = U1 * Mult;
256
257 X2 = U2 * Mult / MY_RAND_MAX;
258
259 return (Average + (Sigma * XS1) / MY_RAND_MAX);
260}
int TransparentLog(int x)
Integer Natural Logarithm function estimation.
Definition Transparency.c:170
int TransparentSqrt(int x)
Integer root function estimation.
Definition Transparency.c:193
UINT32 TransparentGetRand()
Generate a random number by utilizing RDTSC instruction.
Definition Transparency.c:134
#define MY_RAND_MAX
maximum random value
Definition Transparency.c:17
T Average(const vector< T > &vec)
get the average of a vector
Definition gaussian-rng.cpp:53

◆ TransparentSqrt()

int TransparentSqrt ( int x)

Integer root function estimation.

@params x input value

Returns
int
194{
195 int Res = 0;
196 int Bit;
197
198 //
199 // The second-to-top bit is set.
200 //
201 Bit = 1 << 30;
202
203 //
204 // "Bit" starts at the highest power of four <= the argument.
205 //
206 while (Bit > x)
207 Bit >>= 2;
208
209 while (Bit != 0)
210 {
211 if (x >= Res + Bit)
212 {
213 x -= Res + Bit;
214 Res = (Res >> 1) + Bit;
215 }
216 else
217 Res >>= 1;
218 Bit >>= 2;
219 }
220 return Res;
221}

◆ TransparentUnhideDebugger()

NTSTATUS TransparentUnhideDebugger ( )

Deactivate transparent-mode.

Returns
NTSTATUS
426{
427 PLIST_ENTRY TempList = 0;
428 PVOID BufferToDeAllocate = 0;
429
431 {
432 //
433 // Disable the transparent-mode
434 //
436
437 //
438 // Disable RDTSC and RDTSCP emulation
439 //
441
442 //
443 // Free list of allocated buffers
444 //
445 // Check for process id and process name, if not match then we don't emulate it
446 //
448 while (&g_TransparentModeMeasurements->ProcessList != TempList->Flink)
449 {
450 TempList = TempList->Flink;
451 PTRANSPARENCY_PROCESS ProcessDetails = (PTRANSPARENCY_PROCESS)CONTAINING_RECORD(TempList, TRANSPARENCY_PROCESS, OtherProcesses);
452
453 //
454 // Save the buffer so we can de-allocate it
455 //
456 BufferToDeAllocate = ProcessDetails->BufferAddress;
457
458 //
459 // We have to remove the event from the list
460 //
461 RemoveEntryList(&ProcessDetails->OtherProcesses);
462
463 //
464 // Free the buffer
465 //
466 PlatformMemFreePool(BufferToDeAllocate);
467 }
468
469 //
470 // Deallocate the measurements buffer
471 //
474
475 return STATUS_SUCCESS;
476 }
477 else
478 {
479 return STATUS_UNSUCCESSFUL;
480 }
481}
VOID BroadcastDisableRdtscExitingAllCores()
a broadcast that causes for disabling rdtsc/p exiting
Definition Broadcast.c:145
VOID PlatformMemFreePool(PVOID BufferAddress)
Free (dellocate) a non-paged buffer.
Definition Mem.c:86
#define STATUS_UNSUCCESSFUL
Definition Windows.h:172
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition Windows.h:56
NULL()
Definition test-case-generator.py:530

Variable Documentation

◆ TransparentTableLog

int TransparentTableLog[]

pre-defined log result

we used this because we want to avoid using floating-points in kernel

25 {
26 0,
27 69,
28 110,
29 139,
30 161,
31 179,
32 195,
33 208,
34 220,
35 230,
36 240,
37 248,
38 256,
39 264,
40 271,
41 277,
42 283,
43 289,
44 294,
45 300,
46 304,
47 309,
48 314,
49 318,
50 322,
51 326,
52 330,
53 333,
54 337,
55 340,
56 343,
57 347,
58 350,
59 353,
60 356,
61 358,
62 361,
63 364,
64 366,
65 369,
66 371,
67 374,
68 376,
69 378,
70 381,
71 383,
72 385,
73 387,
74 389,
75 391,
76 393,
77 395,
78 397,
79 399,
80 401,
81 403,
82 404,
83 406,
84 408,
85 409,
86 411,
87 413,
88 414,
89 416,
90 417,
91 419,
92 420,
93 422,
94 423,
95 425,
96 426,
97 428,
98 429,
99 430,
100 432,
101 433,
102 434,
103 436,
104 437,
105 438,
106 439,
107 441,
108 442,
109 443,
110 444,
111 445,
112 447,
113 448,
114 449,
115 450,
116 451,
117 452,
118 453,
119 454,
120 455,
121 456,
122 457,
123 458,
124 460,
125 461};