The MASM Forum

General => The Workshop => Topic started by: Biterider on March 12, 2018, 05:53:18 AM

Title: mailto x64
Post by: Biterider on March 12, 2018, 05:53:18 AM
Hi
I'm having troubles with a simple line of code

invoke ShellExecute, 0, NULL, $OfsCStr("mailto:pepe@gmail.com"), NULL, NULL, SW_SHOWDEFAULT

It makes what it should under 32 bit, bit in x64 it fails with an exception.
I haven't found any useful help with Google. Maybe you have an indication of what's going wrong here.

Regards, Biterider

Title: Re: mailto x64
Post by: aw27 on March 12, 2018, 06:42:36 AM
Biterider,
Interesting macro name $ofsCStr which I never heard about before.

However this works:
invoke ShellExecute, 0, NULL, chr$("mailto:pepe@gmail.com"), NULL, NULL, SW_SHOWDEFAULT when you include the masm64rt.inc, which we are believing was your idea.
Title: Re: mailto x64
Post by: Biterider on March 12, 2018, 07:13:58 AM
Hi
I copied the line of code 1 to 1 and unfortunately it fails again.


invoke CoInitializeEx, NULL, COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE
invoke ShellExecuteA, 0, NULL, chr$("mailto:pepe@gmail.com"), NULL, NULL, SW_SHOWDEFAULT


using


    chr$ MACRO dbdata:VARARG
      LOCAL tname,ptxt
      .data
        tname db dbdata,0
        ptxt dq tname
      .code
      EXITM <ptxt>
    ENDM


I would look into your code and exe to see if it is my system... I tested the code on 2 machines with 2 different mail clients (Thunderbird & Outlook).

Biterider
Title: Re: mailto x64
Post by: jj2007 on March 12, 2018, 08:33:30 AM
Quote from: Biterider on March 12, 2018, 05:53:18 AMIt makes what it should under 32 bit, bit in x64 it fails with an exception.

Post the exe... this works fine:

include \Masm32\MasmBasic\Res\JBasic.inc
Init           ; OPT_64 1      ; put 0 for 32 bit, 1 for 64 bit assembly
  jinvoke ShellExecute, 0, 0, Chr$("mailto:pepe@gmail.com?Subject=Greetings%20from%20Assembler&Body=That%20was%20easy"), 0, 0, SW_SHOWDEFAULT
  Inkey Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format")
EndOfCode


Project attached, requires Masm32, UAsm64 and MasmBasic (http://masm32.com/board/index.php?topic=94.0) (and nothing else :P).
Title: Re: mailto x64
Post by: Raistlin on March 12, 2018, 04:13:48 PM
See also on the old forum - http://www.masmforum.com/board/index.php?topic=6578.0 - might help.
Title: Re: mailto x64
Post by: Biterider on March 12, 2018, 07:01:58 PM
Hello
I tested JJ's code and mine on a third machine and both work fine.
I suspect now that the problem lies somewhere on my dev PC.
Thanks for your help.

Biterider
Title: Re: mailto x64
Post by: jj2007 on March 12, 2018, 09:27:31 PM
Quote from: Raistlin on March 12, 2018, 04:13:48 PM
See also on the old forum - http://www.masmforum.com/board/index.php?topic=6578.0 - might help.

Draakie... hmmm... should we know this member? ;-)

Nice code btw. I've been inspired to Send mail with attachments (http://masm32.com/board/index.php?topic=6483.msg74689#msg74689). Attention Micros**t is trying to declare MAPISendMail obsolete, and replace it with MAPISendMailW, which will not work on Win7 and older. Redmond, we are watching you 8)
Title: Re: mailto x64
Post by: aw27 on March 12, 2018, 09:53:42 PM
Quote from: jj2007 on March 12, 2018, 09:27:31 PM
Attention Micros**t is trying to declare MAPISendMail obsolete, and replace it with MAPISendMailW, which will not work on Win7 and older. Redmond, we are watching you 8)
They want you to be able to read subject lines like this one: ☁❄☃☀☺☂☹✝
which you could not using the obsolete mapi.
Anyway, real programmers don't use mapi, they work it out through winsock.
Title: Re: mailto x64
Post by: jj2007 on March 12, 2018, 09:55:41 PM
Quote from: aw27 on March 12, 2018, 09:53:42 PMAnyway, real programmers don't use mapi.

Why does almost every post of you contain some form of insult? Too much spare time, José?
Title: Re: mailto x64
Post by: aw27 on March 12, 2018, 09:58:14 PM
Quote from: jj2007 on March 12, 2018, 09:55:41 PM
Quote from: aw27 on March 12, 2018, 09:53:42 PMAnyway, real programmers don't use mapi.

Why does almost every post of you contain some form of insult? Too much spare time, José?
Not an insult, mapi is for VB, and script kids programmers. ASM programmers need it rough.
Anyway, it is easy to do as well and will provide a learning experience which you will not have using receipts prepared for lazy people.
Title: Re: mailto x64
Post by: Biterider on March 16, 2018, 06:31:44 AM
Hello
I still struggle with this trivial code.
It would be very helpful if someone could test the code and provide feedback.
I am getting the following error on Win10 Home Edition and Thunderbird as an email client.
Thanks!
Biterider
Title: Re: mailto x64
Post by: jj2007 on March 16, 2018, 07:52:38 AM
It crashes on Win7-64, i.e. it throws an exception in ShellExecuteExW :(

My version (identical source):
000000014000100C   | BA 06 00 00 00            | mov edx,6                               |
0000000140001011   | 33 C9                     | xor ecx,ecx                             |
0000000140001013   | FF 15 6F 03 00 00         | call qword ptr ds:[<&CoInitializeEx>]   |
0000000140001019   | 41 BA 0A 00 00 00         | mov r10d,A                              | A:'\n'
000000014000101F   | 4C 89 54 24 28            | mov qword ptr ss:[rsp+28],r10           |
0000000140001024   | 45 33 D2                  | xor r10d,r10d                           |
0000000140001027   | 4C 89 54 24 20            | mov qword ptr ss:[rsp+20],r10           |
000000014000102C   | 45 33 C9                  | xor r9d,r9d                             |
000000014000102F   | 4C 8D 05 A3 01 00 00      | lea r8,qword ptr ds:[1400011D9]         | r8:"mailto:pepe@hotmail.com", 1400011D9:"mailto:pepe@hotmail.com"
0000000140001036   | 48 8D 15 97 01 00 00      | lea rdx,qword ptr ds:[1400011D4]        | rdx:"open", 1400011D4:"open"
000000014000103D   | 33 C9                     | xor ecx,ecx                             |
000000014000103F   | FF 15 4B 03 00 00         | call qword ptr ds:[<&ShellExecuteA>]    |


Your version:
0000000001151004 | 33 C9                             | xor ecx, ecx                      |
0000000001151006 | BA 06 00 00 00                    | mov edx, 6                        | edx:"open"
000000000115100B | FF 15 EF 0F 00 00                 | call qword ptr ds:[<&CoInitialize |
0000000001151011 | 33 C9                             | xor ecx, ecx                      |
0000000001151013 | 48 BA 20 20 15 01 00 00 00 00     | movabs rdx, test_shellexecute.115 | rdx:"open", 1152020:"open"
000000000115101D | 49 B8 25 20 15 01 00 00 00 00     | movabs r8, test_shellexecute.1152 | r8:"mailto:pepe@hotmail.com", 1152025:"mailto:pepe@hotmail.com"
0000000001151027 | 45 33 C9                          | xor r9d, r9d                      |
000000000115102A | 48 C7 44 24 20 00 00 00 00        | mov qword ptr ss:[rsp+20], 0      |
0000000001151033 | C7 44 24 28 0A 00 00 00           | mov dword ptr ss:[rsp+28], A      |
000000000115103B | FF 15 CF 0F 00 00                 | call qword ptr ds:[<&ShellExecute |


Stack alignment is OK and identical for both versions. Right now I am too tired to dig deeper, and can't see any significant differences here. A mystery 8)
Title: Re: mailto x64
Post by: fearless on March 16, 2018, 09:17:41 AM
I had a look at this and dived down the rabbit hole to see it returned exceptions after WaitForMultipleObjects down to NTWaitForMultipleObjects.

I built an example using Uasm with radasm for x64 and pretty much copied the code as is, and ran my copy and it worked ok, got a msgbox about no default mail handler and it opened internet explorer with address bar with the mailto string - so all seemed ok.

I compared both exes with CFF explorer to check imports etc matched, they did. Both showed as PE64. AMD64 as machine in file header was same, characteristics have one difference: Mine had the app can handle >2gb address space, whereas the Test_ShellExecute did not have this checked. Optional headers had a minor difference in DLLCharacteristics 8160 vs 8140 for Test_ShellExecute. My test app had a .data section no debug section - probably not the issue. I would guess something to do with the linker your using maybe?

Im using Microsoft (R) Incremental Linker Version 12.00.31101.0 with:
\UASM\Bin\LINK.EXE /SUBSYSTEM:WINDOWS /RELEASE /VERSION:4.0 /MACHINE:X64 /LIBPATH:"\UASM\Lib\x64" /OUT:"mailtest.exe" "mailtest.obj" "mailtest.res"

Not sure if that will help, hope it does
Title: Re: mailto x64
Post by: aw27 on March 16, 2018, 03:25:31 PM
As fearless found and as JJ disassembly shows the file appears to have been linked with the switch /LARGEADDRESSAWARE:NO, which is something that should not be done in 64-bit unless there are reasons for that (which I never found to this date).
Title: Re: mailto x64
Post by: jj2007 on March 16, 2018, 07:18:24 PM
Right, I just tested it and that switch makes it crash. Good point, José :t

I wonder, though, why it crashes; when using the switch, the exe gets loaded low, i.e. at 401000h like a 32-bit exe. And the 32-bit version doesn't crash. Can anybody see a good reason why ShellExecute can't handle 403004h?

Perhaps Mikl has an idea why his use of ShellExecute (https://translate.google.it/translate?sl=auto&tl=en&js=y&prev=_t&hl=en&ie=UTF-8&u=https%3A%2F%2Fwasm.in%2Fthreads%2Fshellexecute-i-reestr.32131%2F&edit-text=) with /LARGEADDRESSAWARE:NO works but ours not?

With switch /LARGEADDRESSAWARE:NO:
000000000040100B   | CC                        | int3                                    |
000000000040100C   | 41 BA 0A 00 00 00         | mov r10d,A                              | r10d:&"P.-w", A:'\n'
0000000000401012   | 4C 89 54 24 28            | mov qword ptr ss:[rsp+28],r10           |
0000000000401017   | 45 33 D2                  | xor r10d,r10d                           | r10d:&"P.-w"
000000000040101A   | 4C 89 54 24 20            | mov qword ptr ss:[rsp+20],r10           |
000000000040101F   | 45 33 C9                  | xor r9d,r9d                             |
0000000000401022   | 4C 8D 05 DB 1F 00 00      | lea r8,qword ptr ds:[403004]            | ###### 403004:"mailto:pepe@gmail
0000000000401029   | 33 D2                     | xor edx,edx                             |
000000000040102B   | 33 C9                     | xor ecx,ecx                             |
000000000040102D   | FF 15 A5 21 00 00         | call qword ptr ds:[<&ShellExecuteA>]    |


No switch:
000000014000100B   | CC                        | int3                                    |
000000014000100C   | 41 BA 0A 00 00 00         | mov r10d,A                              | r10d:&"P.-w", A:'\n'
0000000140001012   | 4C 89 54 24 28            | mov qword ptr ss:[rsp+28],r10           |
0000000140001017   | 45 33 D2                  | xor r10d,r10d                           | r10d:&"P.-w"
000000014000101A   | 4C 89 54 24 20            | mov qword ptr ss:[rsp+20],r10           |
000000014000101F   | 45 33 C9                  | xor r9d,r9d                             |
0000000140001022   | 4C 8D 05 DB 1F 00 00      | lea r8,qword ptr ds:[140003004]         | ###### 140003004:"mailto:pepe@gmail
0000000140001029   | 33 D2                     | xor edx,edx                             |
000000014000102B   | 33 C9                     | xor ecx,ecx                             |
000000014000102D   | FF 15 A5 21 00 00         | call qword ptr ds:[<&ShellExecuteA>]


Btw putting the address into a register doesn't help - but PrintLine alias crt_printf has no problem:
  mov rsi, Chr$("mailto:pepe@gmail.com?Subject=Greetings%20from%20Assembler&Body=That%20was%20easy")
  PrintLine rsi
  jinvoke ShellExecute, 0, 0, rsi, 0, 0, SW_SHOWDEFAULT


So it's probably a bug design feature of ShellExecuteExW 8)
Title: Re: mailto x64
Post by: Biterider on March 16, 2018, 09:51:18 PM
Hello everybody
I can confirm that removing the "/LARGEADDRESSAWARE:NO" switch, the problem is gone.
Why it is so, is a matter of discussion.

Thanks for your support!  :t

Biterider
Title: Re: mailto x64
Post by: aw27 on March 17, 2018, 04:31:04 AM
It works in VS C with some magic done by mainCRTStartup. If we bypass the default mainCRTStartup it is broken as well.


#include <windows.h>
#include <shellapi.h>
#include <ole2.h>

#define __NORMAL

#ifdef __NORMAL // Works
int main()
#else
int mainCRTStartup() // Broken
#endif
{
CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
ShellExecute(NULL, "open", "mailto:pepe@hotmail.com", NULL, NULL, SW_SHOWDEFAULT);
    return 0;
}
Title: Re: mailto x64
Post by: six_L on March 17, 2018, 07:02:26 PM
it works ok.
.xmm
option casemap:none
option dotname
option win64:11
option stackbase:rsp

POINTER typedef ptr

include \UASM64\include\windows.inc
include \UASM64\include\ole2.inc
;include \UASM64\include\shellapi.inc

includelib \UASM64\Lib\kernel32.lib
includelib \UASM64\Lib\user32.lib
;includelib \UASM64\Lib\Shell32.lib
includelib \UASM64\Lib\ole32.lib

_ShellExecuteEx typedef proto pExecInfo:QWORD
PShellExecuteEx typedef ptr _ShellExecuteEx

.const
Verb db "open",0
File db "mailto:pepe@hotmail.com",0

.data?
@ShellExecuteEx PShellExecuteEx ?
hShell32_dll dq ?
pExecInfo SHELLEXECUTEINFO <?>

.code

WinMainCRTStartup proc

invoke LoadLibrary,CStr("Shell32.dll")
.if rax
mov hShell32_dll,rax
invoke GetProcAddress,hShell32_dll,CStr("ShellExecuteEx")
.if rax!=0
mov @ShellExecuteEx,rax
.else
invoke MessageBox,NULL,CStr("ShellExecuteEx get Failed"),CStr("GetProcAddress"),MB_OK
JMP @exit
.endif
.else
invoke MessageBox,NULL,CStr("shell32.dll load Failed"),CStr("LoadLibrary"),MB_OK
JMP @exit
.endif

invoke CoInitializeEx, NULL, COINIT_APARTMENTTHREADED or COINIT_DISABLE_OLE1DDE

invoke RtlZeroMemory,offset pExecInfo,SIZEOF pExecInfo
mov pExecInfo.cbSize,SIZEOF pExecInfo
lea rax,Verb
mov pExecInfo.lpVerb,rax
lea rax,File
mov pExecInfo.lpFile,rax
mov pExecInfo.nShow,SW_SHOWDEFAULT

invoke @ShellExecuteEx, offset pExecInfo
@exit:
invoke FreeLibrary,hShell32_dll
invoke ExitProcess,NULL
ret
WinMainCRTStartup endp   


end WinMainCRTStartup

Quote\UASM64\bin\uasm64 -c -win64 -Zp8 shelltest.asm
    \UASM64\bin\Link /ENTRY:WinMainCRTStartup /SUBSYSTEM:windows %name%.obj
the Attachment is exe.
Title: Re: mailto x64
Post by: aw27 on March 17, 2018, 07:16:48 PM
Quote
\UASM64\bin\Link /ENTRY:WinMainCRTStartup /SUBSYSTEM:windows %name%.obj

Now,  add /LARGEADDRESSAWARE:NO to the link command line.

You forgot to read from the beginning.  :biggrin:
Title: Re: mailto x64
Post by: six_L on March 17, 2018, 07:29:14 PM
Quoteadd /LARGEADDRESSAWARE:NO to the link command line.
the error is being happened.
QuoteVirtual Address Space
By default, 64-bit Microsoft Windows-based applications have a user-mode address space of several terabytes. For precise values, see Memory Limits for Windows and Windows Server Releases. However, applications can specify that the system should allocate all memory for the application below 2 gigabytes. This feature is beneficial for 64-bit applications if the following conditions are true:

A 2 GB address space is sufficient.
The code has many pointer truncation warnings.
Pointers and integers are freely mixed.
The code has polymorphism using 32-bit data types.
All pointers are still 64-bit pointers, but the system ensures that every memory allocation occurs below the 2 GB limit, so that if the application truncates a pointer, no significant data is lost. Pointers can be truncated to 32-bit values, then extended to 64-bit values by either sign extension or zero extension.

To specify this memory limitation, use the /LARGEADDRESSAWARE:NO linker option. Note that /LARGEADDRESSAWARE:NO is ignored for an ARM64 binary. However, be aware that problems can occur when using this option. If you build a DLL that uses this option and the DLL is called by an application that does not use this option, the DLL could truncate a 64-bit pointer whose upper 32 bits are significant. This can cause application failure without any warning.

Title: Re: mailto x64
Post by: aw27 on March 17, 2018, 07:41:36 PM
As I mentioned, it works from C with the proper runtime initialization.
Although the source code for the runtime is available with all VC distributions it is rather complicated and I can not spend time looking for the magic it does, but would love to know it.