News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Runtime Error When Trying To Call Printf In X64 Masm

Started by assembler, December 24, 2016, 07:59:09 AM

Previous topic - Next topic

assembler

What's wrong with this code:
includelib msvcrt.lib
includelib ucrt.lib
includelib libucrt.lib
includelib user32.lib
includelib kernel32.lib

extrn system :proc
extrn puts :proc
extrn printf :proc
extrn ExitProcess :proc

.data

string_title_x64_printf db "title x64 printf",0
string_color_0F db "color 0F",0
string_pause db "pause",0
string db "string",0
string_pd_newline db "%d",10,0

.code

main proc c

lea rcx, string_title_x64_printf
call system
lea rcx, string_color_0F
call system
lea rcx, string
call puts

lea rcx, string_pd_newline
mov rdx, 3
call printf

lea rcx, string_pause
call system

call ExitProcess

main endp

end


This exception is thrown:
QuoteUnhandled exception at 0x0000000077528F24 (ntdll.dll) in x64 printf.exe: 0xC0000005: Access violation writing location 0x0000000000000024.

Note that I am running this x64 code in Visual Studio 2015 Enterprise.

jj2007

Works for me, but with some modifications, see attached project. Where exactly does it crash? What do you see in the debugger?

assembler

Quote from: jj2007 on December 24, 2016, 09:05:50 AM
Works for me, but with some modifications, see attached project. Where exactly does it crash? What do you see in the debugger?
It crashes on line/instruction: "call printf".
In the debugger I see the exception, which I already quoted in the question and I will quote it again:

QuoteUnhandled exception at 0x0000000077528F24 (ntdll.dll) in x64 printf.exe: 0xC0000005: Access violation writing location 0x0000000000000024.

And I don't have the requirements of your modifications. Visual Studio 2015 Enterprise doesn't come with include files (.inc files) for masm at all!

jj2007

Quote from: assembler on December 24, 2016, 09:52:00 AMIt crashes on line/instruction: "call printf".

Interesting.

  lea rcx, string_pd_newline
  mov rdx, 11111
  call printf

  lea rcx, string_pd_newline
  mov rdx, 22222
  jinvoke crt_printf, @

  jinvoke crt_printf, addr string_pd_newline, 33333


All three variants work, output is ...
11111
22222
33333

... as expected, no exceptions here 8)

mabdelouahab

QuoteUnhandled exception at 0x0000000077528F24 (ntdll.dll) in x64 printf.exe: 0xC0000005: Access violation writing location 0x0000000000000024.

I think the problem in Stack Alignement, Check out Frame Prologue

jj2007

Unlikely: Access violation writing location 0x0000000000000024

Doesn't look like a stack alignment problem...

hutch--

One of the thing I learnt when first doing research on x64 with ML64 was that if you want to use high level code (c runtime etc..) you must construct a stack frame that is aligned correctly. For pure mnemonic code, you don't need a stack frame.

JJ is correct here, if you are getting a page fault from OFFSET 24, you have an addressing error in you code somewhere. Sounds like a null pointer with an added offset.

mabdelouahab

Quote from: jj2007 on December 24, 2016, 12:29:06 PM
Unlikely: Access violation writing location 0x0000000000000024

Doesn't look like a stack alignment problem...
you are right JJ, thank you
the code worked properly without ucrt.lib and libucrt.lib

includelib msvcrt.lib
;includelib ucrt.lib
;includelib libucrt.lib
;includelib user32.lib
includelib kernel32.lib

extrn system :proc
extrn puts :proc
extrn printf :proc
extrn ExitProcess :proc

.data

string_title_x64_printf db "title x64 printf",0
string_color_0F db "color 0F",0
string_pause db "pause",0
string db "string",0
string_pd_newline db "%d",10,0

.code

main proc c

   lea rcx, string_title_x64_printf
   call system
   lea rcx, string_color_0F
   call system
   lea rcx, string
   call puts

   lea rcx, string_pd_newline
   mov rdx, 3
   call printf

   lea rcx, string_pause
   call system

   call ExitProcess

main endp

end

Vortex

Shadow space created with the sub command :

includelib  msvcrt.lib
includelib  kernel32.lib

EXTRN   system:PROC
EXTRN   puts:PROC
EXTRN   printf:PROC
EXTRN   ExitProcess:PROC

.data

string_title_x64_printf db "title x64 printf",0
string_color_0F         db "color 0F",0
string_pause            db "pause",0
string                  db "string",0
string_pd_newline       db "%d",10,0

.code

mainCRTStartup PROC C

    sub     rsp,4*8
   
    lea     rcx, string_title_x64_printf
    call    system

    lea     rcx, string_color_0F
    call    system
   
    lea     rcx, string
    call    puts

    lea     rcx, string_pd_newline
    mov     rdx, 3
    call    printf

    lea     rcx, string_pause
    call    system

    call ExitProcess
    ret

mainCRTStartup ENDP

END

sinsi

    sub     rsp,4*8
Don't you need another 8? The entry is aligned 8, not 16, unless C does things differently?

Vortex

Hi sinsi,

The statement mainCRTStartup PROC C creates a stack frame. Disassembling the object module with Agner Fog's objconv :

mainCRTStartup PROC

        push    rbp                                     
        mov     rbp, rsp                               
        sub     rsp, 32                                 
        lea     rcx, ptr [string_title_x64_printf]     
        call    system                                 
        lea     rcx, ptr [string_color_0F]             
        call    system                                 
        lea     rcx, ptr [string]                     
        call    puts                                 
        lea     rcx, ptr [string_pd_newline]         
        mov     rdx, 3                               
        call    printf                               
        lea     rcx, ptr [string_pause]               
        call    system                                 
        call    ExitProcess                             
        leave                                           
        ret
                                           
mainCRTStartup ENDP

TWell

What msvc 2015 in C do?void __declspec(noreturn) ExitProcess(int);
#pragma comment(lib, "kernel32.lib")
int system(const char *string);
int puts(const char *string);
int printf(const char *format, ...);
#pragma comment(lib, "msvcrt.lib")

char *string_title_x64_printf = "title x64 printf";
char *string_color_0F = "color 0F";
char *string_pause = "pause";
char *string = "string";
char *string_pd_newline = "%d\n";
void mainCRTStartup(void)
{
system(string_title_x64_printf);
system(string_color_0F);
puts(string);
printf(string_pd_newline, 3);
system(string_pause);
ExitProcess(0);
}
mainCRTStartup:
    sub               rsp,28h
    mov               rcx,qword ptr [string_title_x64_printf]
    call              system
    mov               rcx,qword ptr [string_color_0F]
    call              system
    mov               rcx,qword ptr [string]
    call              puts
    mov               rcx,qword ptr [string_pd_newline]
    mov               edx,3
    call              printf
    mov               rcx,qword ptr [string_pause]
    call              system
    xor               ecx,ecx
    call              ExitProcess
and ml64.exemainCRTStartup:
    push              rbp
    mov               rbp,rsp
    lea               rcx,[string_title_x64_printf]
    call              system
    lea               rcx,[string_color_0F]
    call              system
    lea               rcx,[string]
    call              puts
    lea               rcx,[string_pd_newline]
    mov               rdx,3
    call              printf
    lea               rcx,[string_pause]
    call              system
    call              ExitProcess
    leave             
    ret

sinsi


GoneFishing

I'm almost sure the problem is in MS VS
Try assembling your project from command line