The MASM Forum

General => The Campus => Topic started by: bluedevil on September 27, 2022, 12:57:21 AM

Title: Accessing Union elements inside a Structure in MASM64
Post by: bluedevil on September 27, 2022, 12:57:21 AM
Hello,

There is DEBUG_EVENT structure  (https://learn.microsoft.com/en-us/windows/win32/api/minwinbase/ns-minwinbase-debug_event)which describes a debug event.

In MASM32 SDK this structure was defined like this:

DEBUGSTRUCT UNION
  Exception         EXCEPTION_DEBUG_INFO <{?,?,?,?,?,EXCEPTION_MAXIMUM_PARAMETERS dup(?)},?>
  CreateThread      CREATE_THREAD_DEBUG_INFO <?,?,?>
  CreateProcessInfo CREATE_PROCESS_DEBUG_INFO <?,?,?,?,?,?,?,?,?,?>
  ExitThread        EXIT_THREAD_DEBUG_INFO <?>
  ExitProcess       EXIT_PROCESS_DEBUG_INFO <?>
  LoadDll           LOAD_DLL_DEBUG_INFO <?,?,?,?,?,?>
  UnloadDll         UNLOAD_DLL_DEBUG_INFO <?>
  DebugString       OUTPUT_DEBUG_STRING_INFO <?,?,?>
  RipInfo           RIP_INFO <?,?>
DEBUGSTRUCT ENDS

DEBUG_EVENT STRUCT
  dwDebugEventCode  DWORD       ?
  dwProcessId       DWORD       ?
  dwThreadId        DWORD       ?
  u                 DEBUGSTRUCT <>
DEBUG_EVENT ENDS



In MASM64 SDK it was defined like this:

  DEBUG_EVENT STRUCT
    dwDebugEventCode DWORD ?
    dwProcessId   DWORD ?
    dwThreadId   DWORD ?
       DWORD ?
      UNION
       Exception        EXCEPTION_DEBUG_INFO <>
       CreateThread     CREATE_THREAD_DEBUG_INFO <>
       CreateProcessInfo CREATE_PROCESS_DEBUG_INFO <>
       ExitThread       EXIT_THREAD_DEBUG_INFO <>
       ExitProcess      EXIT_PROCESS_DEBUG_INFO <>
       LoadDll          LOAD_DLL_DEBUG_INFO <>
       UnloadDll        UNLOAD_DLL_DEBUG_INFO <>
       DebugString      OUTPUT_DEBUG_STRING_INFO <>
       RipInfo          RIP_INFO <>
      ENDS
  DEBUG_EVENT ENDS


Thanks to MASM32 SDK one can use `.` notation to access union elements inside a structure:

DBEvent.u.Exception.pExceptionRecord.ExceptionCode


But in MASM64 SDK I couldn't manage to use dot notation to access union elements inside a structure(in our case DEBUG_EVENT elements), so I have to manually access the union elements:

mov r15, qword ptr [DBEvent + 16]           ; DBEvent.u.Exception.pExceptionRecord.ExceptionCode
; or another example
mov r15, qword ptr [DBEvent + 16 + 48]      ; DBEvent.u.CreateProcessInfo.lpStartAddress


I wonder If I can still use dot notation in such cases?
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: greenozon on October 02, 2022, 06:25:10 AM
Hello bluedevil
I spent some time exploring your code and my suggestions as well as optimisations are attached
one idea is about using ofn struct predefined (thus moved from .data -> .data)
another one - drop using rXX registers and start using directly DBEvent var members...

Are you planning to write a kind of mini-debugger?
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: bluedevil on October 04, 2022, 08:53:32 AM
@greenozon thanks for your reply. I have updated my code thanks to you. I have attached my latest code.

My code seems working but I have one issue: the image base and entry point values are wrong if i select a 64bit binary. But it is ok if I select a 32 bit binary.

I am filling the buffer with wsprintf

                invoke wsprintf, addr buffer, addr ProcessInfo, \
                        DBEvent.CreateProcessInfo.hFile,\           ; image file handle
                        DBEvent.CreateProcessInfo.hProcess, \       ; process handle
                        DBEvent.CreateProcessInfo.hThread,\         ; thread handle
                        DBEvent.CreateProcessInfo.lpBaseOfImage, \  ; imagebase
                        DBEvent.CreateProcessInfo.lpStartAddress    ; entrypoint
                invoke MessageBox, NULL, addr buffer, addr AppName, MB_OK or MB_I


But the real problem resides in WaitForDebugEvent api. When this function runs, it fills the DEBUG_EVENT structure. And the entrypoint and imagebase values are wrong if the executable is 64bit binary


.data?
    <snip>
    DBEvent             DEBUG_EVENT <>

.code
<snip>
    invoke WaitForDebugEvent, addr DBEvent, INFINITE
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: bluedevil on October 07, 2022, 09:02:56 PM
Folks, If you have time and help me on this issue I will be very happy!

Quote from: bluedevil on October 04, 2022, 08:53:32 AM

But the real problem resides in WaitForDebugEvent api. When this function runs, it fills the DEBUG_EVENT structure. And the entrypoint and imagebase values are wrong if the executable is 64bit binary


.data?
    <snip>
    DBEvent             DEBUG_EVENT <>

.code
<snip>
    invoke WaitForDebugEvent, addr DBEvent, INFINITE


I really dont't get that WaitForDebugEvent API fills DEBUG_EVENT structure true if I open a 32 bit executable, but worng on If i open a 64bit executable.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: zedd151 on October 07, 2022, 09:24:16 PM
This is what I get when running the program with TUTE02 as the debugee:
Is this also what you are getting for imagebase and start address?

edit = Removed attached image as it has served its purpose
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: zedd151 on October 07, 2022, 09:34:30 PM
The debugger and debuggee appear to have the same load address and entry point as specified in their PE headers. So, when the debugger (TUTE28) loads the debuggee it must use a different address than that in the PE header (for TUTE02), if my suspicions are correct.
There is a link option that allows to specify the load address, rather than the default iirc. Try changing that for TUTE02 (link option)  to see if it makes a difference.
example:  (I looked it up) where "..." indicates existing part of what you have for link.exe
...  /BASE:0x180000000 ...
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: TimoVJL on October 07, 2022, 10:13:23 PM
Process Explorer show also same addresses, so it's possible and x64 feature.
Process Explorer v16.43 (https://learn.microsoft.com/en-us/sysinternals/downloads/process-explorer)
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: bluedevil on October 08, 2022, 01:31:13 AM
@TimoVJL and @zedd151 thank you for your brilliant comments. I have realized that my code actually works normal!

I have double checked by using, Process Explorer and x64dbg, they both gave the same ImageBase and EntryPoint values. Only IDA Pro doesn't; and I think IDA Pro rebases executable to default imagebases.

Also M$ Docs (https://learn.microsoft.com/en-us/cpp/build/reference/base-base-address?view=msvc-170) clearly states that:
Quote
For security reasons, Microsoft recommends you use the /DYNAMICBASE option instead of specifying base addresses for your executables. /DYNAMICBASE generates an executable image that can be randomly rebased at load time by using the address space layout randomization (ASLR) feature of Windows. The /DYNAMICBASE option is on by default.

So I have relinked msgbox.exe with /DYNAMICBASE:NO, then I got the default imagebase address!

Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: zedd151 on October 08, 2022, 02:02:10 AM
Ah, ida pro. That's weird.
For me, I could actually care less what M$ says about security reasons. If they knew anything about computer security we would all be happily running Windows xp still. Their best OS, imo.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: bluedevil on October 08, 2022, 02:03:49 AM
Quote from: zedd151 on October 08, 2022, 02:02:10 AM
Ah, ida pro. That's weird.
For me, I could actually care less what M$ says about security reasons. If they knew anything about computer security we would all be happily running Windows xp still. Or even Windows 2000.

You are wisdom :eusa_clap:  :eusa_clap:
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: jj2007 on October 08, 2022, 02:14:22 AM
Quote from: bluedevil on October 08, 2022, 01:31:13 AMAlso M$ Docs (https://learn.microsoft.com/en-us/cpp/build/reference/base-base-address?view=msvc-170) clearly states that:
Quote
For security reasons, Microsoft recommends you use the /DYNAMICBASE option instead of specifying base addresses for your executables. /DYNAMICBASE generates an executable image that can be randomly rebased at load time by using the address space layout randomization (ASLR) feature of Windows. The /DYNAMICBASE option is on by default.

/DYNAMICBASE for security reasons is nonsense: (https://www.blackhat.com/presentations/bh-dc-07/Whitehouse/Paper/bh-dc-07-Whitehouse-WP.pdf)
QuoteOur analysis of the results uncovers predictability in the implementation that reduces its effectiveness.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: zedd151 on October 08, 2022, 02:37:33 AM
Quote from: jj2007 on October 08, 2022, 02:14:22 AM
/DYNAMICBASE for security reasons is nonsense: (https://www.blackhat.com/presentations/bh-dc-07/Whitehouse/Paper/bh-dc-07-Whitehouse-WP.pdf)
QuoteOur analysis of the results uncovers predictability in the implementation that reduces its effectiveness.
:biggrin:
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: hutch-- on October 08, 2022, 10:19:23 AM
If its the one I am thinking of, its fundamentally a good idea, randomising the start address of and executable to make hacking it a lot more complicated. I have some time ago done test pieces where you randomly alter ESP (in 32 bit) at the entry point of an executable which made some forms of hacking unreliable but it was never any use to me so I never pursued it.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: bluedevil on October 09, 2022, 12:12:42 AM
Quote from: hutch-- on October 08, 2022, 10:19:23 AM
I have some time ago done test pieces where you randomly alter ESP (in 32 bit) at the entry point of an executable which made some forms of hacking unreliable but it was never any use to me so I never pursued it.

You got my attention   :icon_idea:
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: hutch-- on October 09, 2022, 12:17:16 AM
You basically have to alter ESP right at the entry point. The tests I did some time ago called a random algo within a plus or minus range, modified ESP and then the normal code was run and it seemed to work OK.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: bluedevil on October 09, 2022, 05:14:48 AM
But I still know the entry point right? And what about 'esp' before main? It seem to me like I still can learn how much you changed esp?
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: NoCforMe on October 09, 2022, 07:12:47 AM
So you're basically relocating the entire stack to a new place, right? How do you figure out where to relocate it? Can't just plop it anywhere ...
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: jj2007 on October 09, 2022, 07:48:10 AM
Well, almost everywhere... but it must be downwards, and you need to probe the stack
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: hutch-- on October 09, 2022, 08:03:34 AM
It must be done directly AFTER the program entry point, set a range of plus and minus 1k for a random algo and then add that to ESP.

After that, just run the normal app code.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: jj2007 on October 09, 2022, 09:18:24 AM
Are you sure you can increase esp?
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: hutch-- on October 09, 2022, 09:43:32 AM
With a default 1 meg stack, twiddling it in either direction by up to 1k is no big deal.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: jj2007 on October 09, 2022, 11:10:39 AM
Quote from: hutch-- on October 09, 2022, 09:43:32 AM
With a default 1 meg stack, twiddling it in either direction by up to 1k is no big deal.

Now I am curious, Hutch. Attached is a minimal window application, 38 lines of plain simple Masm64 SDK code. Where would you insert an add rsp, 1000h?

Subtracting works fine:
WinMain proc
LOCAL msg:MSG
  sub rsp, 1000h
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: hutch-- on October 09, 2022, 02:34:24 PM
 :biggrin:

It Verx !

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm64\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    sub rsp, 512

    conout "How D",lf

    waitkey

    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: jj2007 on October 09, 2022, 07:49:52 PM
Quote from: hutch-- on October 09, 2022, 02:34:24 PM
:biggrin:

It Verx !
entry_point proc

    sub rsp, 512


I know. Now what about add rsp, 512?

Quote from: hutch-- on October 09, 2022, 09:43:32 AM
With a default 1 meg stack, twiddling it in either direction by up to 1k is no big deal.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: hutch-- on October 09, 2022, 08:37:52 PM
 :biggrin:

Well, thats simple, change the example to ADD rather than SUB.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: jj2007 on October 09, 2022, 08:48:54 PM
Quote from: jj2007 on October 09, 2022, 07:48:10 AM
it must be downwards, and you need to probe the stack

Remember we are in the Campus.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: NoCforMe on October 09, 2022, 09:39:31 PM
You raise a much more than trivial point here.

Correct me if I'm wrong, but it's always been my understanding that the stack starts at the end ("top" as in highest address) of what used to be called a "segment" in DOS days, and grows downwards. So that would mean that if you add to the stack you'll be in trouble, as you'll be addressing out-of-bounds memory. Correct? In other words, the stack pointer doesn't start out in the middle of the field, where it can be either added to or subtracted from, right? (There might be a little bit of padding on the bottom, but I'm guessing not much, much less than a K.)
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: jj2007 on October 09, 2022, 09:47:35 PM
Quote from: NoCforMe on October 09, 2022, 09:39:31 PMif you add to the stack you'll be in trouble, as you'll be addressing out-of-bounds memory. Correct?

Correct.

Quote from: jj2007 on October 09, 2022, 07:48:10 AM
it must be downwards, and you need to probe the stack

Please find attached Hutch' marginally modified code. Here are the changes:

entry_point proc
   mov ecx, 800      ; 800kBytes
@@:   sub rsp, 1024
   mov al, [rsp]
   dec ecx
   jge @B

    conout "How D",lf
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: hutch-- on October 10, 2022, 12:04:06 AM
This is basically the tests I did years ago but now in 64 bit.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm64\include64\masm64rt.inc

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    rcall GetTickCount                  ; get a seed
    bswap rax                           ; invert bytes for fastest changing
    rcall seed_rrand,rax                ; use it as a random seed
    mov rax, rvcall(rrand,1,16)         ; call the range random algo
    shl rax, 3                          ; mul by 8, keep stack aligned

    sub rsp, rax                        ; sub rax from rsp

    conout "RSP = ",str$(rsp),lf,lf     ; display rsp
    conout "How D",lf                   ; a text message

    waitkey                             ; wait for result

    .exit                               ; bye

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: jj2007 on October 10, 2022, 01:10:40 AM
Yep, looks good :thumbsup:

Here is a simple variant, tested only on Win7:

entry_point proc
mov ecx, 1000 ; 1000kBytes
@@: sub rsp, 1024
mov al, [rsp]
dec ecx
jge @B

    conout "Stack is stuck at ", hex$(rsp), "h", lf

    waitkey


Output: Stack is stuck at 35A70h :tongue:
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: hutch-- on October 10, 2022, 11:56:12 AM
Here is a tweaked version.

; «»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»

;       The design is to produce and option range of random OFFSETs that are aligned by 8 to
;       modify the 64 bit stack pointer. 16 potential random numbers multiplied by 8 to
;       maintain stack alignment.

; «»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»

    include \masm64\include64\masm64rt.inc

    .data?
      sptr dq ?
      cntr dq ?

    .code

; «»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»

entry_point proc

    mov sptr, rsp

    rcall GetTickCount                          ; get a seed
    bswap rax                                   ; invert bytes for more deviation
    rcall seed_rrand,rax                        ; use it as a random seed

    mov cntr, 1024                              ; run many iterations
  lp:
    mov rax, rvcall(rrand,1,16)                 ; call the range random algo
    sub cntr, 1
    jnz lp

    shl rax, 3                                  ; mul by 8, produces aligned multiply

    sub rsp, rax                                ; sub rax from rsp

    conout "RSP = ",str$(rsp),lf,lf             ; display rsp
    conout "How D",lf                           ; a text message

  ; ---------------------------------------------------------------
  ; This would be put somewhere in the app that is not easy to find.
  ; ---------------------------------------------------------------
    .if rsp == sptr
      conout "Phark, someone has hacked the app !!!!",lf
    .endif
  ; ---------------------------------------------------------------

    waitkey                                     ; wait for result

    .exit                                       ; bye

entry_point endp

; «»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»«»

    end
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: bluedevil on October 10, 2022, 06:15:03 PM
I hope I didn't miss something. hutch-- your technique works perfectly on my win10x64 machine.

But what I wanted to ask is; we do not need this technique because of /DYNAMICBASE parameter right?

Linker puts /DYNAMICBASE:YES by default and in every run rsp value changes already?
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: TimoVJL on October 10, 2022, 06:23:28 PM
ASLR is just a bit in PE header, easy to change.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: bluedevil on October 10, 2022, 06:32:48 PM
Quote from: TimoVJL on October 10, 2022, 06:23:28 PM
ASLR is just a bit in PE header, easy to change.

But if I have executable I already can reverse/disassemble/debug the binary. Even so I liked hutch--'s approach.

Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: TimoVJL on October 10, 2022, 07:48:41 PM
Of course an application can check that bit from header or PEB and act their own way and alert user.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: hutch-- on October 11, 2022, 03:06:08 AM
Here is a test UI app that uses the above technique. It must be run directly after the entry point and for a UI app, the range of OFFSETS must be aligned by 16. The test is buried in the "StatusBar" proc to make it harder to find.

While anything can be broken if the attacker is both patient enough and knows enough, small tricks like this increase the complexity of hacking an app and combined with a range of other tricks, you can help the attacker grow old trying to break an app.
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: NoCforMe on October 11, 2022, 06:39:31 PM
Continuing the discussion of just how the stack works (under Windows), check this page of Raymond Chen's (https://devblogs.microsoft.com/oldnewthing/20190111-00/?p=100685). Excellent explanation of what can and can't be done with the stack (talking X86 here; he covers other architectures also).

I especially like this little illustration from his article:
Title: Re: Accessing Union elements inside a Structure in MASM64
Post by: jj2007 on October 11, 2022, 07:22:14 PM
I generally like Chen's articles a lot, but this one is not very clear. Note also that the "red zone" (why "still valid"?) does not exist for the two architectures we are dealing with in this forum, x86 and x64.

To take away: mov [esp-100], eax is not a good idea, because your debugger might shamelessly use that area.