flat assembler
Message board for the users of flat assembler.

Index > Linux > How to call 32-bit code from 64-bit in Linux?

Author
Thread Post new topic Reply to topic
CandyMan



Joined: 04 Sep 2009
Posts: 297
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
CandyMan
Below is the code that calls the 32-bit procedure in the EAX registry.
This works only in windows. I would like to convert it to work in Linux.
Please help me.
Code:
procedure Call32BitCode;{$IFDEF FPC}nostackframe;{$ENDIF}
assembler;asm
        LEA     RCX,@@Dest[RIP]
        LEA     RBX,@@Next[RIP]
        PUSH    RAX
        PUSH    RDX
        MOV     EAX,SS
        LEA     RDX,[RSP+8*2]
        XCHG    RAX,[RSP+8*1]   // SS
        XCHG    RDX,[RSP+8*0]   // RSP
        PUSH    $0202           // RFL
        PUSH    $0023           // CS
        DB      $51             // PUSH ECX=RIP
        DB      $48,$CF         // IRETQ
@@Dest: PUSH    $0033           // CS
        DB      $53             // PUSH EBX=EIP
        DB      $FF,$D0,$90     // CALL EAX
        DB      $CB             // RETF
@@Next:
end;    

_________________
smaller is better
Post 11 Oct 2019, 07:50
View user's profile Send private message Reply with quote
st



Joined: 12 Jul 2019
Posts: 33
Location: Russia
st
I think it kinda works, at least it should reach the @@Dest label with CS register set to 0x23.

However PUSH $0033 produces SIGSEGV because ESP points to an arbitrary address (probably with no memory pages mapped). In the original code ESP is truncated from RSP that points above 4G space.

As a quick hack I have added some space allocated inside ELF for the CPU stack and couple of instructions to get the 'Hello world!' message.
Code:
format ELF64 executable
entry start

segment readable executable

start:
        lea     rsp, [sspace]
        LEA     RCX,[@@Dest]
        LEA     RBX,[@@Next]
        PUSH    RAX
        PUSH    RDX
        MOV     EAX,SS
        LEA     RDX,[RSP+8*2]
        XCHG    RAX,[RSP+8*1]   ;// SS
        XCHG    RDX,[RSP+8*0]   ;// RSP
        lea     eax, [hello]
        PUSH    $0202           ;// RFL
        PUSH    $0023           ;// CS
        DB      $51             ;// PUSH ECX=RIP
        DB      $48,$CF         ;// IRETQ
@@Dest: PUSH    $0033           ;// CS
        DB      $53             ;// PUSH EBX=EIP
        DB      $FF,$D0,$90     ;// CALL EAX
        DB      $CB             ;// RETF
@@Next:

use32
hello:
        mov     eax, 4
        mov     ebx, 1
        mov     ecx, msg
        mov     edx, msg_size
        int     0x80

        mov     eax, 1
        xor     ebx, ebx
        int     0x80

segment readable writeable

msg db 'Hello world!', 0xA
msg_size = $-msg

rq 256
sspace:
    
Please note it exits process with int 0x80 and RETF is newer executed.

Here is some more info about the topic http://blog.dolezel.info/2017/02/running-32-bit-code-in-64-bit-linux.html
We need also set DS register to 0x2b to allow memory access.
Post 12 Oct 2019, 07:43
View user's profile Send private message Visit poster's website Reply with quote
CandyMan



Joined: 04 Sep 2009
Posts: 297
Location: film "CandyMan" directed through Bernard Rose OR Candy Shop
CandyMan
Thank you so much.
Post 17 Oct 2019, 07:23
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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-2019, Tomasz Grysztar.

Powered by rwasa.