flat assembler
Message board for the users of flat assembler.

Index > Tutorials and Examples > AOXXX

Goto page Previous  1, 2, 3, 4
Author
Thread Post new topic Reply to topic
macomics



Joined: 26 Jan 2021
Posts: 1149
Location: Russia
macomics 25 Apr 2025, 13:41
In any case, only the operating system can find out if a debugger is available, not your program. It is very difficult without operations at the system level to avoid connecting a debugger to an already running process or to detect its presence. There are several simple options for detecting the presence of a debugging program, but they all do not guarantee anything.
Post 25 Apr 2025, 13:41
View user's profile Send private message Reply with quote
Mat-Quasar



Joined: 02 Mar 2025
Posts: 82
Mat-Quasar 25 Apr 2025, 14:12
Noted with thanks, macomics and revolution, I always learn something new on this message board.

The link of Solution #9 Flare-On 2021 has changed again, because now Mandiant is part of Google, the new link for the PDF is:
https://services.google.com/fh/files/misc/challenge-9-evil-en.pdf

In Page 6 of the said PDF, there is mention of IsTooSlow anti-debugging technique (see screenshot, or click the link above for softcopy)

Other anti-debugging technique mentioned are:
Quote:
• IsDebuggerPresent
o Determined by checking PEB.BeingDebugged (offset 0x02) to be set.

• IsRemoteDebuggerPresent
o Calls CheckRemoteDebuggerPresent on current process and checks if the return has a debug
port.

• IsNtGlobalFlag
o Checks the PEB.NtGlobalFlag (offset 0x68) for the following flags described in
Table 1: NtGlobalFlags.

• IsSeDebugPrivsEnabled
o This sample doesn’t enable DebugPrivs so if they are it is a red flag. Another test that is better
for this kind of test, but not implemented is to check the parent process and see if that process
has DebugPrivs enabled.

• IsHardwareBreakpointPresent
o This checks if any of the hardware breakpoints are set by checking the CONTEXT record for the
running thread.

• IsTooSlow
o This check is a simple timing check that does a simple back to back call to GetTickCount and
compares the delta and looks for a threshold of anything over two seconds constitutes debugging


Description: Is Too Slow anti-debugging technique
Filesize: 21.93 KB
Viewed: 1022 Time(s)

istooslow.PNG


Description: Extracted Page 5 & 6 from Solution #9 in Flare-On 2021
Download
Filename: 5_PDFsam_challenge-9-evil-en.pdf
Filesize: 105.6 KB
Downloaded: 32 Time(s)

Post 25 Apr 2025, 14:12
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20627
Location: In your JS exploiting you and your system
revolution 25 Apr 2025, 14:18
"anything over two seconds constitutes ..." any type of delay, which could be a debugger, or any of a multitude of reasons that an application isn't given a time slice to run.
Post 25 Apr 2025, 14:18
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20627
Location: In your JS exploiting you and your system
revolution 25 Apr 2025, 14:21
Code:
invoke GetTickCount
mov ebx,eax
invoke GetTickCount
sub eax,ebx ; what is the maximum possible value here? Is it always zero? One? Can it be infinity?    
The answer is it can be any value even with no debugger running.
Post 25 Apr 2025, 14:21
View user's profile Send private message Visit poster's website Reply with quote
Mat-Quasar



Joined: 02 Mar 2025
Posts: 82
Mat-Quasar 25 Apr 2025, 14:56
revolution wrote:
Code:
invoke GetTickCount
mov ebx,eax
invoke GetTickCount
sub eax,ebx ; what is the maximum possible value here? Is it always zero? One? Can it be infinity?    
The answer is it can be any value even with no debugger running.


revolution you are viewing it from the perspective of an author of operating system, but malware actor / author views are more limited, I guess. Cool
Post 25 Apr 2025, 14:56
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1149
Location: Russia
macomics 25 Apr 2025, 15:22
Mat-Quasar wrote:
revolution you are viewing it from the perspective of an author of operating system, but malware actor / author views are more limited, I guess.

Just "from the perspective of an author of operating system" more limited than "malware actor / author views". The former solve issues on a general level without paying attention to specific implementations and workarounds. The latter are just looking for vulnerabilities in the code of the former and are building more sophisticated solutions.

But even in the example
Code:
invoke GetTickCount
mov ebx,eax
invoke GetTickCount
sub eax,ebx ; what is the maximum possible value here? Is it always zero? One? Can it be infinity?     
can be at least two versions.
1) The code is executed without interruption and will be 0 in eax.
2) There was an interruption between two calls to the GetTickCount function to increment the counter of this function, and eax will be 1.

But there are no guarantees within the framework of the user program code that the code will regain control after an interruption.
Anything can happen, which is why the interrupt will not resume the program immediately and the eax value will be greater than 1 (but, as a rule, no more than 10 due to the system timer resolution settings). Although even this is not guaranteed. Let's say that after the interruption, the reboot command started and all processes began to be destroyed. Your process may not be the first to be resumed.

However the system will try to resume your process as soon as possible so that it finishes the interrupted handler and reaches the message processing cycle. There will already be a message waiting with a question about restarting the computer. This way the program can prevent a reboot.
Post 25 Apr 2025, 15:22
View user's profile Send private message Reply with quote
Mat-Quasar



Joined: 02 Mar 2025
Posts: 82
Mat-Quasar 25 Apr 2025, 15:48
I run an experiment, and you're right, macomics that the scenario #1 is 0, even if it is in milliseconds.

Modern CPU is fast enough. I hope nothing wrong in my experimental code below:
Code:
format PE console
entry start

include 'win32a.inc'

section '.data' data readable writable

buf     rb      10
        db      0
fmt     db      '%d'
len     dd      ?
dummy   dd      ?

section '.code' code readable executable

start:
        call    [GetTickCount]
        mov     ebx, eax
        call    [GetTickCount]
        sub     eax, ebx
        push    eax
        push    fmt
        push    buf
        call    [wsprintf]
        add     esp, 12
        mov     dword [len], eax
        push    -11
        call    [GetStdHandle]
        push    0
        push    dummy
        push    dword [len]
        push    buf
        push    eax
        call    [WriteConsole]
        push    0
        call    [ExitProcess]

section '.idata' import readable writable

 library kernel32, 'KERNEL32.DLL',\
         user32, 'USER32.DLL'

 import kernel32,\
        GetStdHandle, 'GetStdHandle', \
        WriteConsole, 'WriteConsoleA', \
        GetTickCount, 'GetTickCount', \
        ExitProcess,'ExitProcess'

 import user32,\
        wsprintf, 'wsprintfA'    
Post 25 Apr 2025, 15:48
View user's profile Send private message Reply with quote
Mat-Quasar



Joined: 02 Mar 2025
Posts: 82
Mat-Quasar 25 Apr 2025, 16:24
Mat-Quasar wrote:
Modern CPU is fast enough.


From my web search:

Quote:

A modern CPU can execute billions of instructions per second. The exact number depends on the CPU's clock speed (measured in GHz, or gigahertz) and the number of cores. A CPU with a clock speed of, for example, 3 GHz can process 3 billion cycles (and thus, potentially 3 billion instructions) per second. However, the number of instructions executed per clock cycle can vary due to factors like the complexity of the instructions and the CPU's architecture.


I don't know how many instructions are there in GetTickCount Win32 API, but certainly not many, since it took less than 1 ms to execute. My CPU is 1.7GHz, so can process 1.7 billion instructions per second!
Post 25 Apr 2025, 16:24
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1149
Location: Russia
macomics 25 Apr 2025, 17:31
1.7 billion cycle <> instructions. Even nop.

Try
Code:
invoke QueryPerformanceFrequency, addr [freq]
invoke QueryPerformanceCounter, addr [start]
mov ecx, 1700000000
@@:
  loop @b ; 1 instruction in a loop
invoke QueryPerformanceCounter, addr [ends]
mov rax, [ends]
sub rax, [start]
cqo
div [freq]    
Post 25 Apr 2025, 17:31
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1149
Location: Russia
macomics 25 Apr 2025, 19:18
The full code is based on your previous testing program via GetTickCount.
Code:
format PE console
entry start

include 'win32a.inc'

section '.data' data readable writable

buf        rb      100
           db      0
fmt        db      '%d', 0
len        dd      ?
dummy      dd      ?
freq       dq      ?
start_tick dq      ?
ends_tick  dq      ?

section '.code' code readable executable

start:
        mov     ecx, 100000000 ; Heat loop

  @@:
        loop    @b

        push    freq
        call    [QueryPerformanceFrequency]
        push    start_tick
        call    [QueryPerformanceCounter]
        mov     ecx, 1700000000 ; your CPU frequency (cycles)
;       mov     ecx, dword [freq]

  @@:
        loop    @b
        push    ends_tick
        call    [QueryPerformanceCounter]
        mov     eax, dword [ends_tick + 0]
        mov     edx, dword [ends_tick + 4]
        sub     eax, dword [start_tick + 0]
        sbb     edx, dword [start_tick + 4]
        jnz     @f
;       mov     ecx, 1000 ; more precise (up to one thousandth)
;       mul     ecx
        div     dword [freq]

  @@:
        push    eax
        push    fmt
        push    buf
        call    [wsprintf]
        add     esp, 12
        mov     dword [len], eax
        push    -11
        call    [GetStdHandle]
        push    0
        push    dummy
        push    dword [len]
        push    buf
        push    eax
        call    [WriteConsole]
        push    0
        call    [ExitProcess]

section '.idata' import readable writable

 library kernel32,                 'KERNEL32.DLL',\
         user32,                   'USER32.DLL'

 import kernel32,\
        GetStdHandle,              'GetStdHandle', \
        WriteConsole,              'WriteConsoleA', \
        GetTickCount,              'GetTickCount', \
        ExitProcess,               'ExitProcess',\
        QueryPerformanceCounter,   'QueryPerformanceCounter',\
        QueryPerformanceFrequency, 'QueryPerformanceFrequency'

 import user32,\
        wsprintf,                  'wsprintfA'
    
Post 25 Apr 2025, 19:18
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20627
Location: In your JS exploiting you and your system
revolution 25 Apr 2025, 22:14
macomics wrote:
However the system will try to resume your process as soon as possible so that it finishes the interrupted handler ...
"The system" is the OS. A multi-tasking OS gives no guarantee about timing. You can get any value, 0, 1, 123, 2^31-1, etc. "The system" does what it wants, a user program has no control over it, and no way to force it to behave in any specific way.
Post 25 Apr 2025, 22:14
View user's profile Send private message Visit poster's website Reply with quote
Mat-Quasar



Joined: 02 Mar 2025
Posts: 82
Mat-Quasar 26 Apr 2025, 06:13
macomics wrote:
The full code is based on your previous testing program via GetTickCount.


I got the value "4" printed. Does that mean "LOOP" command take 4 CPU cycles, or what does that mean?

ADD: This will show "5":

Code:
  @@:
        nop
        loop    @b       
Post 26 Apr 2025, 06:13
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1149
Location: Russia
macomics 26 Apr 2025, 06:21
revolution wrote:
"The system" is the OS. A multi-tasking OS gives no guarantee about timing. You can get any value, 0, 1, 123, 2^31-1, etc. "The system" does what it wants, a user program has no control over it, and no way to force it to behave in any specific way.
I described it in the context of a global system event - reboot. In this case, the system behaves in a completely understandable and well-known way - it polls all processes.

Mat-Quasar wrote:
I got the value "4" printed. Does that mean "LOOP" command take 4 CPU cycles, or what does that mean?
This is the number of seconds. If you add the multiplication by 1000, you will find out the number of milliseconds to complete this cycle.

In 4 seconds, in addition to running your program, a bunch of other events happen that can push your program. The timer increment event for GetTickCount is triggered at least 4000 times. Keyboard or mouse events also affect this indicator.
Post 26 Apr 2025, 06:21
View user's profile Send private message Reply with quote
Furs



Joined: 04 Mar 2016
Posts: 2624
Furs 26 Apr 2025, 20:53
Mat-Quasar wrote:
I don't know how many instructions are there in GetTickCount Win32 API, but certainly not many, since it took less than 1 ms to execute. My CPU is 1.7GHz, so can process 1.7 billion instructions per second!
No it can execute 1.7 billion cycles per second. A cycle can potentially execute many instructions at the same time, in parallel, if they don't depend on each other. We have complex out of order CPUs after all.
Post 26 Apr 2025, 20:53
View user's profile Send private message Reply with quote
Ali.Z



Joined: 08 Jan 2018
Posts: 819
Ali.Z 27 Apr 2025, 09:34
earlier i posted a message and deleted it as i dont remember the link to the source (probably somewhere in msdn)

i mentioned that QPC has some overhead, and it is advised to calculate that overhead and subtract it from your final time.

~

Mat-Quasar wrote:

I don't know how many instructions are there in GetTickCount Win32 API, but certainly not many, since it took less than 1 ms to execute. My CPU is 1.7GHz, so can process 1.7 billion instructions per second!


not really, in addition to what others said, not all instructions take 1 cycle to fetch, decode and execute, some can take more than 100 cycles, and some cannot be paralleled; and some like cpuid will force out of order execution to be disabled when when decoder realize it is cpuid, and cpu must finish everything it is doing in order to execute cpuid and then go back to normal. (not really everything tho, but at least a lot)

some instructions have similar effects too like fence instructions, but iirc not like cpuid.

_________________
Asm For Wise Humans
Post 27 Apr 2025, 09:34
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20627
Location: In your JS exploiting you and your system
revolution 27 Apr 2025, 09:50
Ali.Z wrote:
earlier i posted a message and deleted it as i dont remember the link to the source (probably somewhere in msdn)

i mentioned that QPC has some overhead, and it is advised to calculate that overhead and subtract it from your final time.
That is how all timing needs to be calibrated. Not just for QPC, but also for RDTSC, and any other ways that are trying to measure elapsed time.

But don't accept that first value as the truth, run the calibration in a loop and use the lowest measured value. This can help the code to avoid errant values due to other processes and system activities that cause the random delays.
Post 27 Apr 2025, 09:50
View user's profile Send private message Visit poster's website Reply with quote
avcaballero



Joined: 02 Feb 2004
Posts: 214
Location: Madrid - Spain
avcaballero 03 May 2025, 10:55
Hello. I haven't been able to read all the recent posts yet, which seem very interesting. Sorry about that. I'll look at them carefully when I can.

The reason for my post today was about an interesting tunneling effect that I managed to translate into C. I've replaced lines with stars. The original code is here: http://codepen.io/nicksheffield/pen/azqQVW .

Here an interesting song recently discovered by me. The setting is about a man in a hospital who reviews his life and decides to apologize to his wife.

https://youtu.be/pr3wlOkRHBg


Description:
Download
Filename: TunelWC02.7z
Filesize: 33.55 KB
Downloaded: 32 Time(s)


_________________
Siempre aprendiendo


Last edited by avcaballero on 03 May 2025, 10:58; edited 1 time in total
Post 03 May 2025, 10:55
View user's profile Send private message Visit poster's website Reply with quote
avcaballero



Joined: 02 Feb 2004
Posts: 214
Location: Madrid - Spain
avcaballero 03 May 2025, 10:56
Opps, sorry, this should have gone in the "AOXXX" thread.
Post 03 May 2025, 10:56
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4

< Last Thread | Next Thread >
Forum Rules:
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


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.