The MASM Forum

64 bit assembler => UASM Assembler Development => Topic started by: aw27 on June 07, 2019, 01:16:56 AM

Title: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 07, 2019, 01:16:56 AM
Heaven's Gate: 64-bit code in 32-bit file (http://web.archive.org/web/20110929081358/http://vx.netlux.org/lib/vrg02.html)
Closing "Heaven's Gate" (http://www.alex-ionescu.com/?p=300)

This is a fast essay to test the OPTION FLAT:1. We enter the Heaven's Gate, collect a value from the RCX register, split in 2 registers to return to 32-bit, and print it in the 32-bit World.

Hello from 32 bit. RCX sent you this from x64: 0x12345678abcdef


Note: It has bugs, but works  :skrewy:
(https://www.dropbox.com/s/1pedr7monpngvgc/Itworkswhy.jpg?dl=1)

Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 07, 2019, 05:00:28 AM
This is a reviewed version. The other one is messy and not even I could explain correctly why it worked.
Now is clear like water.

Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: LiaoMi on June 07, 2019, 06:39:59 AM
 :biggrin:

(https://www.designzzz.com/wp-content/uploads/2015/08/Why-programmers-stay-awake.jpg)

In the last topic, almost all variations work. I thought that if I debugged one option, I could debug the second one. This was a mistake, in Windbg it is possible to debug with the transition to different states, it will be interesting to try the new debugger, see how replay works  :azn:
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: 2B||!2B on June 07, 2019, 02:26:43 PM
Nice example there AW.

The mixing is a good idea. However, it comes with some limitations like one can not load modules that depend on other modules like kernel32 64bit. It works only if your module depends on Ntdll only.
When it comes to debugging, WinDbg x64 is the only debugger as i know of that is capable of switching between 32bit and 64bit on the fly.
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 07, 2019, 05:02:25 PM
Thank you, LiaoMi - Your investigations are always very useful!  :thumbsup:

@2B||!2B
It is indeed difficult to navigate in these waters. Some of the barriers are welcome, though, to put a frein on malware.

An interesting problem I faced is that it is not possible, or I could not figure out how, to write to the .data section from the 64-bit code. In other words, it points correctly to the variable but produces an exception when writing. Are writing permissions for 64-bit different from 32-bit on PE sections? Any idea? 
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: jj2007 on June 07, 2019, 05:10:54 PM
Any idea why this...
to64bitWorld proc
mov     edi,dword ptr [rsp]
int 3
jmp     fword ptr [rdx]    ; <<<<<<<<<<<<<<<<<<<<


... ends up here?
RtlUserThreadStart  Ú$  894424 04                   mov [esp+4], eax
776401E8            ³.  895C24 08                   mov [esp+8], ebx
776401EC            À. E9 C9950200                 jmp 776697BA


In case somebody has way too much free time: read this (http://esec-lab.sogeti.com/posts/2016/09/12/deep-dive-wow64.html) :cool:
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 07, 2019, 05:29:07 PM
Quote from: jj2007 on June 07, 2019, 05:10:54 PM
Any idea why this...
to64bitWorld proc
mov     edi,dword ptr [rsp]
int 3
jmp     fword ptr [rdx]    ; <<<<<<<<<<<<<<<<<<<<


... ends up here?
RtlUserThreadStart  Ú$  894424 04                   mov [esp+4], eax
776401E8            ³.  895C24 08                   mov [esp+8], ebx
776401EC            À. E9 C9950200                 jmp 776697BA


I end up here:
0040105f 8b3c24          mov     edi,dword ptr [esp]
00401062 cc              int     3
00401063 ff2a            jmp     fword ptr [edx]

But is a good point, because in there we are still in 32-bit. The procedure should be changed to (removing the USE64 from where it was):

to64bitWorld proc
mov     edi,dword ptr [esp]
USE64
jmp     fword ptr [rdx]
offjump::
mov rcx, 012345678ABCDEFh
mov rax, rcx
mov rdx, rcx
shr rdx, 32

; Return to 32-bit World
mov     dword ptr [rsp+4],23h
mov     dword ptr [rsp],edi
jmp     fword ptr [rsp]
to64bitWorld endp


Does it make any difference in your debugger?
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: jj2007 on June 07, 2019, 05:34:11 PM
Quote from: AW on June 07, 2019, 05:29:07 PMDoes it make any difference in your debugger?

Yes, it chokes and shows only garbage:0040105C            Ú$  CC                          int3
0040105D            ³.  67:8B3C                     mov edi, [si]
00401060            ³.  24 FF                       and al, FF
00401062            ³.  2A48 B9                     sub cl, [eax-47]
00401065            ³.  EF                          out dx, eax
00401066            ³.  CD AB                       int 0AB
00401068            ³. 78 56                       js short 004010C0


How does WinDbg behave?
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 07, 2019, 05:41:34 PM
Quote from: jj2007 on June 07, 2019, 05:34:11 PM
How does WinDbg behave?

Windbg does not go astray but reports the next instruction as "jmp     fword ptr [edx]" and it is right. We are still in 32-bit there, only on the next instruction we enter 64-bit..
So, does it help if you change to? :

to64bitWorld proc
mov     edi,dword ptr [esp]
jmp     fword ptr [edx]
USE64
offjump::
.....
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: 2B||!2B on June 07, 2019, 06:21:45 PM
Try these macros to enter/leave 64bit mode. It is similar to wow64cpu!X86SwitchTo64BitMode/wow64cpu!CpuSimulate

X64_Start macro
PUSH CS
CALL $+5
ADD [ESP],5
RETF   
endm

X64_End MACRO
    LOCAL  xx, rt
    call   $+5
    xx  equ $
    mov    dword ptr [rsp + 4], 23h
    add    dword ptr [rsp], rt - xx
    retf
    rt:
ENDM



Problem is, i can not test since i am on a 32bit machine and VMWare stopped working all of a sudden.

Quote from: AW on June 07, 2019, 05:02:25 PM
An interesting problem I faced is that it is not possible, or I could not figure out how, to write to the .data section from the 64-bit code. In other words, it points correctly to the variable but produces an exception when writing. Are writing permissions for 64-bit different from 32-bit on PE sections? Any idea?

Maybe you faced the same issue i faced there in my topic where the warnings of BSS in BIN that is caused by _flat section does not have writeable characteristics. It will take the place of .data section.
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 07, 2019, 06:50:04 PM
Quote from: 2B||!2B on June 07, 2019, 06:21:45 PM
Maybe you faced the same issue i faced there in my topic where the warnings of BSS in BIN that is caused by _flat section does not have writeable characteristics. It will take the place of .data section.

The BSS issue will probably be solved if you initialize to 0 instead of putting a question mark. But I don't know if it will work after that or if it is a bug (it sound like that).
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: jj2007 on June 07, 2019, 07:59:58 PM
Quote from: AW on June 07, 2019, 05:41:34 PMSo, does it help if you change to?

to64bitWorld proc
mov     edi,dword ptr [esp]
jmp     fword ptr [edx]
USE64
offjump::


No change, disassembly looks ok, and stepping with F7 through the jmp brings you straight to RtlUserThreadStart. Which is the part that I don't yet understand: Does the transition trigger an interrupt that brings you there, or is it the debugger (Olly) that opens a thread for some reason? Same behaviour with X32Dbg. That's why I asked how WinDbg behaves.
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 07, 2019, 09:34:00 PM
@JJ,
Within WinDbg I can single step from x86 to x64. It will not go astray. I tested with x32dbg and there are problems.

@Attention Johsa and Habran:
In the attached new release, I found 2 "possible" bugs which I mention in the comments:
Possible Bug 1 -
mov    rcx, ‭012345678ABCDEFh  now produces "Error A2167: Missing quotation mark in string"
Possible Bug 2 -
Some Function Prototypes cause error if placed on top, but work if placed after USE32 clause

Other than the "possible" bugs, this new release transfers data from x64 to x86 through a memory mapped file. Now, no need to transport values in registers as we did previously (given that we can not transfer them through the heap - i.e .data section, this is a great step forward).
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 07, 2019, 09:55:11 PM
Another bug, possibly directly related to the use of ESP based stack frames.

If I change main like this:

main proc C
LOCAL hMapFile : ptr
invoke CreateFileMappingA, -1, 0, 4, 0, sizeof TBUFFMAP, 0
mov hMapFile, eax
invoke MapViewOfFile, hMapFile, 0f001fh, 0,0,sizeof TBUFFMAP ; <--- Will fail
mov esi, eax
call heavensGate

invoke printf, offset msg32, [esi+4], [esi]
invoke CloseHandle, hMapFile ; <--- Already fails
invoke ExitProcess,0
main endp


Fails happened because we are pushing parameters pointed to by the ESP based stack frame, so they change position after the push. Please have a look with a debugger, if not clear.

Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: LiaoMi on June 07, 2019, 10:31:12 PM
Quote from: jj2007 on June 07, 2019, 07:59:58 PM
Quote from: AW on June 07, 2019, 05:41:34 PMSo, does it help if you change to?

to64bitWorld proc
mov     edi,dword ptr [esp]
jmp     fword ptr [edx]
USE64
offjump::


No change, disassembly looks ok, and stepping with F7 through the jmp brings you straight to RtlUserThreadStart. Which is the part that I don't yet understand: Does the transition trigger an interrupt that brings you there, or is it the debugger (Olly) that opens a thread for some reason? Same behaviour with X32Dbg. That's why I asked how WinDbg behaves.

Hi jj2007,

Most user-mode debuggers indeed don't handle that transition well for multiple reasons (one being the debugger assumes a 32bit process, while you're now executing 64bit code, another being user-mode debugging APIs don't support that).

TL;DR: The "solution" for that situation is to debug using a debugger that explicitly made the effort to support 32 and 64 bit interleaved processes. Although this is often easier for a kernel mode debugger), such as windbg, or other debuggers that support both 32 and 64 bit modes (x64dbg should be able to do it, although I never tried As mentioned in the comments x64dbg is unable to do that).


I can only debug specially-crafted code, I don't know the dependency, even in this case, only 32 bit code is displayed, not 64 bit.
my mistake, debugger always points in ...

CMP     DWORD PTR DS:[7755E968], 0
JE      ntdll.774B41F7
MOV     ECX, DWORD PTR DS:[7755E968]
CALL    DWORD PTR DS:[<&RtlDebugPrintTimes>]
JMP     ECX
MOV     DWORD PTR SS:[ESP + 4], EAX
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: hutch-- on June 08, 2019, 02:06:09 AM
 :biggrin:

I use the slob approach when dealing with interactions between 32 bit and 64 bit apps. Memory mapped files are easy to set up between them and HWND_BROADCAST works on both so you have both messaging and accessible memory that both can read/write.

Something I did for the sheer amusement was to write what was effectively a memory bank in 64 bit that could be used from a 32 bit app to store data so it could free up available 32 bit memory to do other things. The size of the memory mapped file was limited by the 32 bit address range but you could make multiple writes to the 64 bit software as data storage. Worked OK but I could not find a use for it, if I need big memory, I write it in 64 bit.
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 08, 2019, 03:18:59 AM
Quote from: hutch-- on June 08, 2019, 02:06:09 AM
:biggrin:

I use the slob approach when dealing with interactions between 32 bit and 64 bit apps. Memory mapped files are easy to set up between them and HWND_BROADCAST works on both so you have both messaging and accessible memory that both can read/write.

Something I did for the sheer amusement was to write what was effectively a memory bank in 64 bit that could be used from a 32 bit app to store data so it could free up available 32 bit memory to do other things. The size of the memory mapped file was limited by the 32 bit address range but you could make multiple writes to the 64 bit software as data storage. Worked OK but I could not find a use for it, if I need big memory, I write it in 64 bit.

Memory mapped files are extremely useful for inter-process communication and are extremely handy for inter-platform communication within the same process because the mapped file doesn't even need to be reopened - the same pointer can be used by both platforms, a direct line from Heaven to Earth..
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: habran on June 08, 2019, 05:01:08 AM
AW,
when I copied your mov rcx, 0123456789ABCDEFh it was not working because it was unicode
when I retyped it it was working fine:
mov rcx, 0123456789ABCDEFh
0000000000401010 48 B9 EF CD AB 89 67 45 23 01 mov         rcx,123456789ABCDEFh
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: habran on June 08, 2019, 12:47:53 PM
here is what is wrong with your characters:

<006D><006F><0076><0020><0020><0020><0020><0072><0063><0078><002C><0020><202D><0030><0031><0032><0033><0034><0035><0036><0037><0038><0041><0042><0043><0044><0045><0046><0068>

that is why I get this: error A2102: Symbol not defined : ?012345678ABCDEFh
and VS was asking me if I want to save the file as a unicode
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 08, 2019, 02:50:06 PM
Thank you Habran,  :thumbsup:

This was driving me crazy. Some phantom characters, very likely UTF-8, where inserted in the interstices of the instruction. This is what I am seeing with a hex editor:

00000310  66 66 6A 75 6D 70 3A 3A 0D 0A 09 09 3B 6D 6F 76  ffjump::....;mov
00000320  20 09 72 63 78 2C 20 E2 80 AD 30 31 32 33 34 35   .rcx, â€.012345
00000330  36 37 38 41 42 43 44 45 46 68 20 3B 22 45 72 72  678ABCDEFh ;"Err
00000340  6F 72 20 41 32 31 36 37 3A 20 4D 69 73 73 69 6E  or A2167: Missin
00000350  67 20 71 75 6F 74 61 74 69 6F 6E 20 6D 61 72 6B  g quotation mark
00000360  20 69 6E 20 73 74 72 69 6E 67 22 21 20 57 68 79   in string"! Why

What the hell!
Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: aw27 on June 11, 2019, 12:10:23 AM
I have been exploring the Heaven's Gate and found an innovative way (or better an improvement over an existing method) to load the 64-bit kernel32.dll (even in Windows 10, with the latest updates). See picture.
This contradicts this (http://www.alex-ionescu.com/?p=300) and many others (probably all the others).

(https://www.dropbox.com/s/i96axinwr90dl77/heaven1.jpg?dl=1)

I am not going to publish the source code here, may be I will do it somewhere else when I can compose something interesting  to illustrate. Of course, I will tell you guys when done.

I have been using UASM and need to congratulate the team for the work done.
Of course, there are a few bugs, which I have reported so far (one of them was not a bug).
I can manoeuvre even with the bugs, no worries. It is impressive that the high-level constructs like .while/.endw, .for/.endfor, etc work both in USE32 and USE64 . It is really a time saving. I will be back to this novel again.  :thumbsup:




Title: Re: Entering the Heaven's Gate with FLAT:1
Post by: johnsa on June 12, 2019, 01:53:29 AM
Awesome investigation this! I await the complete saga :)

In the meantime I'll PM you about the specific bugs and add them to the fix list.