flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Conditional definition based on type?

Author
Thread Post new topic Reply to topic
a rabbit



Joined: 12 Oct 2009
Posts: 13
a rabbit
Hello!

I want to do the following:

Code:
esi_plus_one equ ; dunno

mov eax, [esi_plus_one] ; should assemble to MOV EAX,[ESI+1]
push esi_plus_one ; should assemble to INC ESI/PUSH ESI/DEC ESI    


Is there any way to do that on FASM?
thx
Post 29 Oct 2009, 01:33
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17474
Location: In your JS exploiting you and your system
revolution
Code:
macro push [args] {
    common
    local done
     done equ 0
  match =esi=+=1,args \{
                inc esi
             push esi
            dec esi
             done equ 1
  \}
    match =0,done \{
              push args
   \}
}
esi_plus_one equ esi+1
mov eax, [esi_plus_one]
push esi_plus_one    
Post 29 Oct 2009, 02:16
View user's profile Send private message Visit poster's website Reply with quote
a rabbit



Joined: 12 Oct 2009
Posts: 13
a rabbit
Thanks for the replay!

It won't work for the following situation, though:
Code:
mov eax, esi_plus_one    


Also I'd like it to support all the instructions.
Is there any way to make a global macro or something like that?
Post 29 Oct 2009, 02:38
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17474
Location: In your JS exploiting you and your system
revolution
fasm does not support inline macros. Perhaps with fasm2 you may be able to do it.
Post 29 Oct 2009, 02:51
View user's profile Send private message Visit poster's website Reply with quote
a rabbit



Joined: 12 Oct 2009
Posts: 13
a rabbit
Actually, what I'm trying to do is to write some position-independent code, which I'm going to inject to another process.
It's really easy to do on x64, as the addresses are relative to RIP by default, but a bit troublesome on 32-bit assembly.

Here's my code: (position-dependent)
Code:
format PE GUI 4.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Code        

LoadDll:
.LoadLibrary:                 dd 0xdeadbeef ; kinda variable 1
.GetProcAddress:              dd 0xdeadbeef ; kinda variable 2

    ; LoadLibrary(dll_str);
    push dll_str
    call dword [.LoadLibrary]

    ; *.LoadLibrary = eax;
    mov dword [.LoadLibrary], eax

    ; GetProcAddress(eax, import_name);
    push import_name
    push eax
    call dword [.GetProcAddress]

    ; *.GetProcAddress = eax;
    mov dword [.GetProcAddress], eax

    ; return;
    retn 4

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data
import_name db 'SetOptions',0
dll_str db 'C:\test.dll',0    


And here is my solution to make the code position-independent:
Code:
format PE GUI 4.0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Macros for position-independency

macro _set_as_index reg ; will be set to .pstart and used, don't modify!
{
    index_reg equ reg

    call $+5
    pop index_reg

    delta = ($-1)-.pstart
}

macro _set_other_as_index reg
{
    mov reg, index_reg

    restore index_reg
    index_reg equ reg
}

macro _label_cmd label, [cmd]
{
common
    _the_label equ index_reg
    if (label-.pstart)-delta <> 0
        add index_reg, (label-.pstart)-delta
    end if
    cmd
    restore _the_label

    delta = (label-.pstart)
}

macro _laptr_cmd label, [cmd]
{
common
    _the_label equ index_reg+(label-.pstart)-delta
    cmd
    restore _the_label
}

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Code

LoadDll:
.pstart:
.LoadLibrary:                 dd 0xdeadbeef
.GetProcAddress:              dd 0xdeadbeef

    ; we use edi as our index!
    push edi
    _set_as_index edi

    ; LoadLibrary(dll_str);
    _label_cmd dll_str,       push _the_label
    _laptr_cmd .LoadLibrary,  call dword [_the_label]

    ; *.LoadLibrary = eax;
    _laptr_cmd .LoadLibrary,  mov dword [_the_label], eax

    ; GetProcAddress(eax, import_name);
    _label_cmd import_name,   push _the_label
    push eax
    _laptr_cmd .GetProcAddress, call dword [_the_label]

    ; *.GetProcAddress = eax;
    _laptr_cmd .GetProcAddress, mov dword [_the_label], eax

    ; return;
    pop edi
    retn 4

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Data
import_name db 'SetOptions',0
dll_str db 'C:\test.dll',0    


It works, and the produced binary isn't too junky, but the source is Sad
Maybe you have some suggestions for a better solution?

P.S.
revolution wrote:
fasm does not support inline macros.

Any assembler does?
Post 29 Oct 2009, 03:13
View user's profile Send private message Reply with quote
Fanael



Joined: 03 Jul 2009
Posts: 168
Fanael
Microsoft Macro Assembler does.
Post 29 Oct 2009, 07:08
View user's profile Send private message Reply with quote
a rabbit



Joined: 12 Oct 2009
Posts: 13
a rabbit
Thanks.

push esi+1 assembles as PUSH ESI/PUSH 1
Is that a feature? O_o
push 1+1 assembles correctly.
Post 29 Oct 2009, 22:35
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 17474
Location: In your JS exploiting you and your system
revolution
The expression parser is greedy. That mean that if it can evaluate an expression it will. So 1+1 evaluates to 2 and pushes 2. With esi+1 the evaluator can only parse esi and then the next try finds +1. 'push 1 2 3 4 +5 -6 +7' will push: 1, 2, 3, and then 2.
Post 30 Oct 2009, 02:11
View user's profile Send private message Visit poster's website 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-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.