- 30 July 2023 (396 messages)
-
i have win11 on debugger
-
and win10 on debugee?
-
No, that should not be a problem.
-
this one.
-
one second.. working from release because i cant build it on laptop, il lsend over debug bins
-
length received: 0x18
buffer received seems to be 0x14 -
first packet was correct?
-
passed checksum too
-
next packets incorrect
-
next packets are the same
-
as the previous one
-
nvm
-
some packets pass through
-
just fine
-
but a few will still be invalid
-
if stepping through following are shown:
-
err, unknown packet action received from debugger
-
blank
-
err, checksum is invalid
-
err, unknown packet action received
-
4x
-
and then it stops and debuggee acts as if it's connected properly
-
dont mind the spam, it's because of bp
-
🤨🤨
-
debuggee becomes a process zombie waiting for object i think in COM comms
-
(can't kill it or anything, have to restart)
-
It shows that the debuggee is successfully connected.
-
Now, you can't control it over the debuggger?
-
nope
-
i never get popped into the "interactable prompt" again
-
You mean CTRL+C won't work.
-
ctrl c won't work on debugee
-
on debugger it will throw exception
-
on debugger
-
not debuggee
-
Exception?
-
In visual studio?
-
yep
-
but i can continue
-
but nothing really changes
-
You have to pass it to the application
-
Did you pass it to the application?
-
i think i did
-
Because visual studio debugger first intercepts CTRL+C events
-
i told it to ignore
-
no
-
🫠
-
Okay, run the debugger process without visual studio
-
well here's the thing
-
if i do that
-
run it directly by clicking on it
-
it's gonna go into that loop again :)
-
this stuff only happens if i step through it
-
and there's delay between processed packets
-
which may be a hint as to why it's fucked?
-
🤔🤔🤔
-
anyways; i had the debugee show success messages on previous builds too
-
but i could never interact via the debugger
-
You mean the delay solved the problem?
-
I think it let a couple packets get processed correctly
-
it's weird.. it's as if there's noise happening on the com port when it's running realtime
-
but most of the packets are right if yo ustep through it
-
some are still invalid, or invalid actions
-
this is what i examined before as well
-
that the debugger was getting weird actions
-
wait
-
i think i know what's the problem
-
i have a feeling the debugger is also reading it's own messages?
-
.
-
HyperDbg just checks for the checksum, it won't request the corrupted packet again.
-
What do you mean?
-
check the message
-
those packets were received
-
on the debugger
-
on previous version
-
behavior was the same; had a checksum error and spam of invalids, if i stepped through it, i got invalid action
-
but I never saw those packets being sent from debuggee to debugger
-
only other way around
-
"DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER"
-
this packet was received on debugger
-
so it looks like the debugger is also reading it's own packets?
-
You see invalid packet error in debugger?
-
not debuggee?
-
correct
-
i never saw invalid packet errors in the debugee
-
there were never any printed errors from that side
-
besides the new listening check
-
the debugee always displayed the bottom text after some time
-
so, you mean it's a kinda loopback ?
-
that was never a problem
-
yes
-
debugee always showed that it loaded succesfully
-
debugger was always stuck
-
with a hundred err prints from the packet handler
-
once they stopped, debuggee printed success
-
This is supposed to be received.
-
DEBUGGER_REMOTE_PACKET_TYPE_DEBUGGEE_TO_DEBUGGER
-
doesn't that mean
-
nvm
-
It seems that packets relating to sending the initial symbol messages is corrupted.
-
yup, but getting rid of those packets doesn't fix it
-
and same error messages are printed
-
i tried that already
-
This means that the debuggee sends a message which should be received in debugger.
-
The thing that I can conclude here is that some packets got corrupted (probably due to the serial's physical issues), and as I HyperDbg won't re-request the corrupted packets (it assumes every packet is received successfully), then this problem happens.
-
🤔
-
I wonder if the packets are in correct order
-
when moved thru the com port
-
-
Windows will send them in order. Why not in order?
-
-
I did not
-
Good point
-
Ill try
-
HyperDbg won't send anything simultaneously.
-
what about packets over 4096?
-
they are split, no?
-
I don't think so. Because WinDbg checks for packets to make sure they are not corrupted and if corrupted, will request to re-send the packets.
-
But, at the same time, might be a good thing to consider
-
to see whether there is an unrecoverable error in the physical serial or not. 🤔🤔🤔
-
i think i did it correctly and windbg is not connecting either?
-
nvm
-
system just froze and its loading
-
WinDbg has problem?
-
its just slow
-
🤔
-
waiting on executable search path is:
-
but same when i open dmp file
-
so i guess its just
-
Loading still
-
yep
-
What's the baudrate?
-
all good
-
115200
-
works fine
-
with windbg
-
I think I've got the problem. The problem here is that the COM connection is prone to errors (which is what we didn't considered in HyperDbg).
-
and it receives some bytes in error, and HyperDbg will lose the control.
-
Do you think the same about it?
-
🤔
-
i assume so, would make sense
-
first time using COM but we pretty much observed corrupted packet behavior
-
and we know some packets were correct
-
therefore there was probably some error in writing or reading
-
and windbg seems to compensate for that
-
Okay, thanks a lot for debugging it, I'll make changes once I'm done with current tasks and after that I will ask you to re-test it.
-
if i have some time, i'll write a test kit if i figure out how this com stuff works
-
just send data continuously, integrity check it
-
and see if this is the actual issue
-
-
I previously made something like this to recheck packets. But, then I realized it makes the connection substantially slower and it's not really needed because the VM connection is guaranteed to send/receive without error. So, it's not needed. But, yeah, kinda agree. We have to implement such an optional mechanism.
- 31 July 2023 (64 messages)
-
Here's the preview of a new feature that will be available starting from the next version (v0.5).
You can specify one of the following calling stages for the event:
- All
- Pre
- Post
It shows whether HyperDbg should trigger the event before the emulation, or after the emulation or both. By default and if you don't specify anything, HyperDbg will trigger the event in the 'pre' stage.
How can it be useful? Imagine you want to see the results of a specific event like a CPUID, RDMSR, WRMSR, etc., you can see the result of the emulation based in the post calling stage (and possibly modify it).
The main usage of it is for the '!monitor' command. For example, you're notified whenever the memory is modified at the target address. Using the 'pre' calling stage you can see the content of memory before 'MOV' instruction, and the 'post' calling stage shows the content of the memory after running 'MOV' or in other words, the modified memory contents. -
-
another example:
!monitor w $proc $proc+ff stage all script {
if ($stage == 1) {
curr_memory = dq($context);
printf("current memory: %llx\n", curr_memory);
}
else {
prev_memory = dq($context);
printf("thread id: %x , from (RIP): %llx modified address: %llx, previous memory: %llx ", $tid, @rip, $context, prev_memory);
}
} -
You can test it on the 'dev' branch right now. Let me know, if you guys have any feedback about these event calling stages.
-
-
-
Which one? Do you mean the new 'calling stage' mechanism?
-
-
Do you mean the changing context problem?
-
-
-
-
Do you need it only for the 'lm' and the '.sym reload' command?
-
-
-
-
-
-
-
-
-
It's a little bit complicated. I need some time researching this to see what I can do. Currently, the way that HyperDbg reads the user-mode modules can be easily changed to run without changing the context. But, the problem here is reading the kernel modules. HyperDbg reads it by using user-mode APIs. I'm pretty sure there should be some routines to get the same result in the kernel, but the problem here is that we need to find something HIGH_IRQL compatible. Because, if HyperDbg wants to read this information from an API where it accesses a paged-out page, then as paging (RFLAG's IF bit) is not set, HyperDbg cannot read that information and it will hang the entire computer.
-
-
-
The same is also applies to this command. In the 'lm' command, we physically read the target file to get the debug information (and send it to the debugger). Of course, reading file (ReadFile, CreateFile) and their equivalent kerenl-mode routines are not HIGH_IRQL compatible. So, it's not possible to read the file without changing context.
-
It's okay for user-mode modules, but where can I find the debug (symbol) information?
-
Is it also mapped in the target PE in the memory?
-
We cannot read files in VMX root-mode. We have to find other ways around it.
-
-
But, just asking, why don't you reload the symbols for the target binary module once you opened it? and again next time that you open the same binary file, the symbol information remains the same.
-
Did you test this trick? 🧐
-
Because, otherwise, I don't know if the debug symbol information is available in the memory or not and if it's available, we cannot guarantee that it's not paged-out. That's why we cannot preserve the state in the '.sym' command.
-
Do you need a command for it? I mean applying this trick?
-
-
-
No, I mean once you do that and then close the program.
-
After that, run the program again, using the '.start'.
-
-
The symbol information remains the same. Am I right?
-
-
-
I used this trick and it probably works.
-
-
That's okay 🙏
-
Once more, feel free to let me know if there are any other problems or concerns. I'll make every effort to address them all, as long as we're not limited with design constraints and limitations.
-
One important consideration here is the fundamental difference between WinDbg and HyperDbg in context preservation. When HyperDbg claims to guarantee system state preservation (context), it means that no other processes or threads will be allowed to execute. This is in contrast to WinDbg, where executing something like 'Reload /user' in WinDbg, it will continue all the cores and threads while preserving only the context of the current debugging process. This advantage in WinDbg comes from the fact that they have the ability to control the context-switching mechanism as WinDbg is compiled with the Windows Kernel source code, which is not something we can do.
If we attempt to manipulate thread context switching in Windows to preserve context, it could lead to complications, as Windows might easily modify it, potentially breaking HyperDbg entirely. As a result, we need to find other methods of context preservation, mainly based on Intel VT-x concepts rather than relying on Windows concepts. Although we can force system to block further execution at the current RIP (context), we cannot guarantee that no other threads from different processes will arrive at the same RIP during execution.
For instance, let's consider a scenario where we want to force the system to preserve context, and the target debuggee is running in the kernel32 function. If we prevent the system from executing any further instructions from that kernel32 function, we might disrupt other system critical processes, as they may arrive at the same location and cause system instabilities. -
-
-
-
-
How can we suspend the thread? This is one of my big dilemmas. How to suspend a running thread?
-
Previously for the uHyperDbg we've allocated a buffer in the target process. A 'nop' loop, we set the thread RIP to that 'nop' loop and once we want to resume it, we adjust the RIP again.
-
But that's not a good idea, it can be easily detected by anti-debugging methods.
-
-
-
-
-
-
-
-
-
-
If it's possible to suspend the thread with one flag, then it's a good way of fixing this problem. Let me know, whatever was the result.
-
Also, one thing that just came to my mind is setting an invalid RIP for the target thread and intecept and ignore page-faults on the target thread. That might be a good option for solving this issue. I'll test it.