flat assembler
Message board for the users of flat assembler.

Index > Macroinstructions > Macro to generate x64 opcodes

Author
Thread Post new topic Reply to topic
alorent



Joined: 05 Dec 2005
Posts: 201
alorent
Hello all,

I'm trying to do a weird example to inject some x64 instructions into a PE64 from my Win32 patcher.

I'm a newbie in macros and don't know if this would be possible.

Can I generate opcodes for x64 using Macros?

Example:

_MOV RAX, RBX

Where "_MOV" is a macro that will generate the corresponding:

db xx
db xx
...

The generated "db's" will represent the opcodes for the x64 instruction.

Thanks a lot.
Post 04 Jan 2006, 07:48
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7739
Location: Kraków, Poland
Tomasz Grysztar
Theoretically it would be possible, but you actually don't need macros for this. Just do it like:
Code:
use64
 mov rax,rbx
use32    

to make any x64 instructions in your Win32 program.
Post 04 Jan 2006, 08:02
View user's profile Send private message Visit poster's website Reply with quote
alorent



Joined: 05 Dec 2005
Posts: 201
alorent
Thanks a lot. It's amazing how powerful FASM is Very Happy Didn't know you could switch between use32 and use64 in a single application Smile

Anyway, I have been trying to make this macro for a long time but "manually" (without the use64 directive) and my curiosity is killing me Smile

Any hint on how that could be done? An example for the _MOV instruction will be great so I could extend it to the other instructions Wink

Thanks a lot!
Post 04 Jan 2006, 08:10
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
It's quite difficult.. You'll have to do A LOT of ifs, match and other to write instructions manually with db directive. Of course, you must also know the x86-64 encoding scheme to do it.
Post 04 Jan 2006, 12:39
View user's profile Send private message Reply with quote
alorent



Joined: 05 Dec 2005
Posts: 201
alorent
Hello,

Yes, you might be right. Too much work that can be easily done by "use64" Smile

Thanks.
Post 04 Jan 2006, 12:53
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
And also too much overhead, for every mov instruction you use. It's best to let assembler 'assemble' it with it's fast internal core Smile
Post 04 Jan 2006, 12:55
View user's profile Send private message Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend
I wrote some macro that should enable (at least partially) the functionality you want:
Code:
; first define which instructions to overload
; you can give whatever you wish
overload64 mov, add, sub

; normal code
        mov     eax, 100
        add     eax, 200
; now let's put 64bit code
        _mov    <rax, rdx>
        _add    <rcx, rax>    
1. First define which instructions to overload
2. Macro creates other macros with '_' in the beginning like _mov, _add, etc.
3. Operands must be in < >

And here's the macro:
Code:
macro overload64 [instr] {
 local __macro_name
 __macro_name equ _ # instr
 match name, __macro_name \{
  macro name operand \\{
   use64
    instr operand
   use32 \\} \} }    


BTW. Can anyone plz tell me how to create lists in macro? I want to have them in some 'equ' variable just as they were passed to macro. Like this: someone wrote 'imul edx, ecx, 16', and my macro gets one by one: 'edx', 'ecx', '16'. How to put it together again to 'edx, ecx, 16'? I know it's possible (I've seen it somewhere), but none of my match tries, neither forward/reverse, nor EQUs worked Smile
Post 04 Jan 2006, 16:37
View user's profile Send private message Visit poster's website Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
Have you tried the # operator? irp might also prove useful.
Do you need a variable-length list or a fixed-length list?

something like this (dunno if it works, though):
Code:
params equ p1#,#p2#,#p3  ; p1, p2 and p3 are eax edx 16    


I don't know how to do it for variable-length lists, maybe rept, irp or irps will help there.
Post 04 Jan 2006, 16:55
View user's profile Send private message Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
Or, if you have something like:

Code:
macro xxx [p]
{
  common params equ
  forward
   ; do some stuff for each param...
   params equ params,p
  common
   ; now you want to use the params to imul
   imul params
}    


But I think you can get away with a simple imul p without needing params constant.

EDIT: Apparently, it seems the list will begin with a comma. Try this at the end:
Code:
match =,any, params \{
 \forward restore params
 \common
  restore params ; the empty value
  define params any
\}    

then use imul params.

Does this help?
Post 04 Jan 2006, 17:56
View user's profile Send private message Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend
Lists are not of fixed length. Some instructions don't have any operands, some have even three. I remember it was possible with heavy usage of match - but the version as I remember it just didn't work for me. And AFAIK it is posssible without rept, irp or irps

AFTER A LONG WHILE CODING
I got this finally Smile As usual - the simplest is the correct one.
Code:
macro _64 [instr] {
 local _name
 _name equ _#instr
 match any, _name \{
  macro any [operand] \\{
   \\common
    local _args
    _args equ operand
    use64
     instr _args
    use32 \\} \} }

        _64     mov, sub, shl

        _mov    rax, rdx
        _sub    rcx, rax
        _shl    rax, 1    

Thanks The_Grey_Beast for help. But the soultion is just to 'equ' in 'common'.

BTW. Which keywords have to be reserved? I had problems because I didn;t know that common must have \. What are the other words?
Post 04 Jan 2006, 18:23
View user's profile Send private message Visit poster's website Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 7739
Location: Kraków, Poland
Tomasz Grysztar
You should escape any operations that otherwise would get processed by the outer macro. So these are all the symbols that are processed by macro processor: "forward", "reverse", "common", "local", "#", "`"; in case of nested "struct" macros you might need to escape the symbol starting with dot, too.

I tried to explain it simply but completely in the manual. If you've got suggestions what more samples would I put there, write them to me.


Last edited by Tomasz Grysztar on 04 Jan 2006, 18:33; edited 1 time in total
Post 04 Jan 2006, 18:32
View user's profile Send private message Visit poster's website Reply with quote
Borsuc



Joined: 29 Dec 2005
Posts: 2466
Location: Bucharest, Romania
Borsuc
Glad you got it working. And sorry about fixed-length lists confusion. Smile
Post 04 Jan 2006, 18:33
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-2020, Tomasz Grysztar. Also on YouTube, Twitter.

Website powered by rwasa.