Переопределение push-pop fasm

Тема в разделе "WASM.ASSEMBLER", создана пользователем qwe8013, 17 дек 2011.

  1. qwe8013

    qwe8013 New Member

    Публикаций:
    0
    Регистрация:
    28 май 2009
    Сообщения:
    198
    Здравстауйте, мне понадобилось определить, на сколько push и pop изменяют esp, что-то вроде:
    Код (Text):
    1. delta equ n
    2. push something
    3. ;delta=n+4
    Всё было бы просто, но fasm поддерживает подобные конструкции:
    Код (Text):
    1. push param1 param2 param3 ...
    2. pop param1 param2 param3 ...
    Я пытался использовать irps при переопределении push и pop, но он при использовании чего-нибудь вроде [mem] считает это
    разными словами: "[", "mem", "]".
    Кто-нибудь знает, как это делается?
     
  2. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    Вобще-то фасм ничего подобного не поддерживает, просто у тебя где-то описан макрос, меняющий push и pop. Соответственно просто переопредели его, или замени совсем
    Код (Text):
    1. purge push,pop
    2. !r.32 fix <eax,ebx,ecx,edx,esi,edi,esp,ebp>
    3. !r.16 fix <ax,bx,cx,dx,si,di,sp,bp,cs,ds,es,fs,gs>
    4.  
    5. %esp = 0
    6. macro  push [p] {
    7.            if p in !r.32
    8.              %esp=%esp+4
    9.            else if p in !r.16
    10.              %esp=%esp+2
    11.            else
    12.            
    13.            end if
    14. }
    Правда в таком виде невозможно отличить push dword x от push word x, но если это принципиально - сделай нормальный разбор параметров match. Но быстро это работать не будет.
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    xRom2
    Поддерживает.
    qwe8013
    Проще всего, наверное, запихать в virtual и декодировать инструкции. Такой себе микродизассемблер в директивах fasm.
     
  4. qwe8013

    qwe8013 New Member

    Публикаций:
    0
    Регистрация:
    28 май 2009
    Сообщения:
    198
    xRom2
    Попробуйте собрать такой код:
    Код (Text):
    1. use32
    2. push eax edx dword [esi]
    всё нормально собирается, так что всё-таки поддерживает, в общем-то в этом и проблема.
     
  5. xRom2

    xRom2 New Member

    Публикаций:
    0
    Регистрация:
    25 апр 2011
    Сообщения:
    63
    Действительно, я проверял с запятыми, а он вишь как. Ну все равно - замени команду макросом, и в нем сделай нормальную форму передачи аргументов, тогда пуш можно будет использовать ТОЛЬКО с параметрами, переданными через запятую, что в принципе и правильно.
     
  6. qwe8013

    qwe8013 New Member

    Публикаций:
    0
    Регистрация:
    28 май 2009
    Сообщения:
    198
    В общем проблема решена:
    Код (Text):
    1. format PE gui
    2. entry start
    3.  
    4. section 'qweasd' readable writeable executable
    5.  
    6. %esp = 0
    7.  
    8. macro the_push arg
    9. {
    10.   local ..start,push@x
    11.   ..start:
    12.   push arg
    13.   load push@x byte from ..start
    14.   if push@x=66h
    15.   %esp=%esp+2
    16.   else
    17.   %esp=%esp+4
    18.   end if
    19. }
    20.  
    21. macro push args
    22. {
    23. local _qwe_,comma,no_reg
    24. _qwe_ equ
    25. comma equ
    26. no_reg equ 0
    27. irps reg,args
    28. \{
    29.  
    30. match =0,no_reg
    31. \\{
    32.  
    33.   no_reg equ 1
    34.   comma equ
    35.  
    36.   match =eax,reg
    37.   \\\{
    38.     no_reg equ 0
    39.     comma equ ,
    40.   \\\}
    41.  
    42.   match =ecx,reg
    43.   \\\{
    44.     no_reg equ 0
    45.     comma equ ,
    46.   \\\}
    47.  
    48.   match =edx,reg
    49.   \\\{
    50.     no_reg equ 0
    51.     comma equ ,
    52.   \\\}
    53.  
    54.   match =ebx,reg
    55.   \\\{
    56.     no_reg equ 0
    57.     comma equ ,
    58.   \\\}
    59.  
    60.   match =esp,reg
    61.   \\\{
    62.     no_reg equ 0
    63.     comma equ ,
    64.   \\\}
    65.  
    66.   match =ebp,reg
    67.   \\\{
    68.     no_reg equ 0
    69.     comma equ ,
    70.   \\\}
    71.  
    72.   match =esi,reg
    73.   \\\{
    74.     no_reg equ 0
    75.     comma equ ,
    76.   \\\}
    77.  
    78.   match =edi,reg
    79.   \\\{
    80.     no_reg equ 0
    81.     comma equ ,
    82.   \\\}
    83.  
    84.   match =ax,reg
    85.   \\\{
    86.     no_reg equ 0
    87.     comma equ ,
    88.   \\\}
    89.  
    90.   match =cx,reg
    91.   \\\{
    92.     no_reg equ 0
    93.     comma equ ,
    94.   \\\}
    95.  
    96.   match =dx,reg
    97.   \\\{
    98.     no_reg equ 0
    99.     comma equ ,
    100.   \\\}
    101.  
    102.   match =bx,reg
    103.   \\\{
    104.     no_reg equ 0
    105.     comma equ ,
    106.   \\\}
    107.  
    108.   match =sp,reg
    109.   \\\{
    110.     no_reg equ 0
    111.     comma equ ,
    112.   \\\}
    113.  
    114.   match =bp,reg
    115.   \\\{
    116.     no_reg equ 0
    117.     comma equ ,
    118.   \\\}
    119.  
    120.   match =si,reg
    121.   \\\{
    122.     no_reg equ 0
    123.     comma equ ,
    124.   \\\}
    125.  
    126.   match =di,reg
    127.   \\\{
    128.     no_reg equ 0
    129.     comma equ ,
    130.   \\\}
    131.  
    132. \\}
    133.  
    134. match =],reg
    135. \\{
    136.   no_reg equ 0
    137.   comma equ ,
    138. \\}
    139.  
    140. _qwe_ equ _qwe_ reg
    141. match =,,comma
    142. \\{
    143.   the_push _qwe_
    144.   _qwe_ equ
    145. \\}
    146.  
    147.  
    148. \}
    149.  
    150. }
    151.  
    152. macro the_pop arg
    153. {
    154.   local ..start,pop@x
    155.   ..start:
    156.   pop arg
    157.   load pop@x byte from ..start
    158.   if pop@x=66h
    159.   %esp=%esp-2
    160.   else
    161.   %esp=%esp-4
    162.   end if
    163. }
    164.  
    165. macro pop args
    166. {
    167. local _qwe_,comma,no_reg
    168. _qwe_ equ
    169. comma equ
    170. no_reg equ 0
    171. irps reg,args
    172. \{
    173.  
    174. match =0,no_reg
    175. \\{
    176.  
    177.   no_reg equ 1
    178.   comma equ
    179.  
    180.   match =eax,reg
    181.   \\\{
    182.     no_reg equ 0
    183.     comma equ ,
    184.   \\\}
    185.  
    186.   match =ecx,reg
    187.   \\\{
    188.     no_reg equ 0
    189.     comma equ ,
    190.   \\\}
    191.  
    192.   match =edx,reg
    193.   \\\{
    194.     no_reg equ 0
    195.     comma equ ,
    196.   \\\}
    197.  
    198.   match =ebx,reg
    199.   \\\{
    200.     no_reg equ 0
    201.     comma equ ,
    202.   \\\}
    203.  
    204.   match =esp,reg
    205.   \\\{
    206.     no_reg equ 0
    207.     comma equ ,
    208.   \\\}
    209.  
    210.   match =ebp,reg
    211.   \\\{
    212.     no_reg equ 0
    213.     comma equ ,
    214.   \\\}
    215.  
    216.   match =esi,reg
    217.   \\\{
    218.     no_reg equ 0
    219.     comma equ ,
    220.   \\\}
    221.  
    222.   match =edi,reg
    223.   \\\{
    224.     no_reg equ 0
    225.     comma equ ,
    226.   \\\}
    227.  
    228.   match =ax,reg
    229.   \\\{
    230.     no_reg equ 0
    231.     comma equ ,
    232.   \\\}
    233.  
    234.   match =cx,reg
    235.   \\\{
    236.     no_reg equ 0
    237.     comma equ ,
    238.   \\\}
    239.  
    240.   match =dx,reg
    241.   \\\{
    242.     no_reg equ 0
    243.     comma equ ,
    244.   \\\}
    245.  
    246.   match =bx,reg
    247.   \\\{
    248.     no_reg equ 0
    249.     comma equ ,
    250.   \\\}
    251.  
    252.   match =sp,reg
    253.   \\\{
    254.     no_reg equ 0
    255.     comma equ ,
    256.   \\\}
    257.  
    258.   match =bp,reg
    259.   \\\{
    260.     no_reg equ 0
    261.     comma equ ,
    262.   \\\}
    263.  
    264.   match =si,reg
    265.   \\\{
    266.     no_reg equ 0
    267.     comma equ ,
    268.   \\\}
    269.  
    270.   match =di,reg
    271.   \\\{
    272.     no_reg equ 0
    273.     comma equ ,
    274.   \\\}
    275.  
    276. \\}
    277.  
    278. match =],reg
    279. \\{
    280.   no_reg equ 0
    281.   comma equ ,
    282. \\}
    283.  
    284. _qwe_ equ _qwe_ reg
    285. match =,,comma
    286. \\{
    287.   the_pop _qwe_
    288.   _qwe_ equ
    289. \\}
    290.  
    291.  
    292. \}
    293.  
    294. }
    295.  
    296. ret_addr equ esp+%esp
    297. start:
    298.  
    299. mov eax,[ret_addr]
    300. push di eax
    301. mov eax,[ret_addr]
    302. pop ebx
    303. mov eax,[ret_addr]
    304. push word [esp]
    305. mov eax,[ret_addr]
    306. pop bx
    307. mov eax,[ret_addr]
    308. lea esp,[ret_addr]
    309.  
    310. retn
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    qwe8013
    Круто решена. push 1 2 3 тоже правильно отработает? А как насчёт push dword 1 2 word 3? А если так: push $ $ $? А так: @@: push word rva @B $$ %t? А ещё (по секрету) можно написать push label_1 label_2 label_3, да ещё и атрибутики (rva, dword) добавить можно.
     
  8. qwe8013

    qwe8013 New Member

    Публикаций:
    0
    Регистрация:
    28 май 2009
    Сообщения:
    198
    l_inc
    Вы правы, я чего-то тупанул, так что пришлось всё-таки писать как вы в #3 рекомендовали, и вот что получилось:
    Код (Text):
    1. format PE gui
    2. entry start
    3.  
    4. section 'qweasd' readable writeable executable
    5.  
    6. %esp = 0
    7.  
    8. macro push arg
    9. {
    10. local push@x,_qwe_,_end_,sib,mod00,mod01,mod10;,mod11
    11. sib equ (push@x and 00000111b)=00000100b
    12. mod00 equ (push@x and 11000000b)=00000000b
    13. mod01 equ (push@x and 11000000b)=01000000b
    14. mod10 equ (push@x and 11000000b)=10000000b
    15. ;mod11 equ (push@x and 11000000b)=11000000b
    16.  
    17. _qwe_=$
    18. push arg
    19. _end_=$
    20.  
    21. while _qwe_<_end_
    22.  
    23.   is16=0
    24.  
    25.   load push@x byte from _qwe_
    26.   _qwe_=_qwe_+1
    27.   while (push@x=0F0h) | (push@x=0F2h) | (push@x=0F3h) | (push@x=2Eh) | (push@x=36h) | (push@x=3Eh) | (push@x=26h) | (push@x=64h) | (push@x=65h) | (push@x=66h)
    28.   ;push@x in <0F0h,0F2h,0F3h,2Eh,36h,3Eh,26h,64h,65h,66h> does not work, why?
    29.  
    30.     if push@x=66h
    31.     is16=1
    32.     end if
    33.  
    34.     load push@x byte from _qwe_
    35.     _qwe_=_qwe_+1
    36.  
    37.   end while
    38.  
    39.   ;push@x=opcode
    40.   if push@x=0Fh
    41.   _qwe_=_qwe_+1
    42.   else if push@x=0FFh
    43.  
    44.     load push@x byte from _qwe_
    45.     _qwe_=_qwe_+1
    46.  
    47.     ;push@x=modrm
    48.     ;_qwe_=modrm+1
    49.     if mod00
    50.  
    51.       if sib
    52.  
    53.         load push@x byte from _qwe_
    54.         _qwe_=_qwe_+1
    55.  
    56.         ;push@x=sib
    57.         if (push@x and 00000111b)=00000101b
    58.         _qwe_=_qwe_+4
    59.         end if
    60.  
    61.       else if (push@x and 00000111b)=00000101b;r/m=101b
    62.       _qwe_=_qwe_+4
    63.       else
    64.  
    65.         ;
    66.  
    67.       end if
    68.  
    69.     else if mod01
    70.  
    71.       if sib
    72.       _qwe_=_qwe_+2
    73.       else
    74.       _qwe_=_qwe_+1
    75.       end if
    76.  
    77.     else if mod10
    78.  
    79.       if sib
    80.       _qwe_=_qwe_+5
    81.       else
    82.       _qwe_=_qwe_+4
    83.       end if
    84.  
    85.     else;mod11
    86.  
    87.       ;_qwe_ points to next instruction
    88.  
    89.     end if
    90.  
    91.   else if push@x=6Ah
    92.  
    93.     _qwe_=_qwe_+1
    94.  
    95.   else if push@x=68h
    96.  
    97.     if is16=1
    98.     _qwe_=_qwe_+2
    99.     else
    100.     _qwe_=_qwe_+4
    101.     end if
    102.  
    103.   else
    104.   ;push r(32/16)/seg
    105.   end if
    106.  
    107.  
    108.   ;;;;;;;;;;;;;;;;;;;;;;;;
    109.   if is16=0
    110.   %esp=%esp+4
    111.   else
    112.   %esp=%esp+2
    113.   end if
    114.  
    115. end while
    116. }
    117.  
    118. macro pop arg
    119. {
    120. local pop@x,_qwe_,_end_,sib,mod00,mod01,mod10;,mod11
    121. sib equ (pop@x and 00000111b)=00000100b
    122. mod00 equ (pop@x and 11000000b)=00000000b
    123. mod01 equ (pop@x and 11000000b)=01000000b
    124. mod10 equ (pop@x and 11000000b)=10000000b
    125. ;mod11 equ (pop@x and 11000000b)=11000000b
    126.  
    127. _qwe_=$
    128. pop arg
    129. _end_=$
    130.  
    131. while _qwe_<_end_
    132.  
    133.   is16=0
    134.  
    135.   load pop@x byte from _qwe_
    136.   _qwe_=_qwe_+1
    137.   while (pop@x=0F0h) | (pop@x=0F2h) | (pop@x=0F3h) | (pop@x=2Eh) | (pop@x=36h) | (pop@x=3Eh) | (pop@x=26h) | (pop@x=64h) | (pop@x=65h) | (pop@x=66h)
    138.   ;pop@x in <0F0h,0F2h,0F3h,2Eh,36h,3Eh,26h,64h,65h,66h> does not work, why?
    139.  
    140.     if pop@x=66h
    141.     is16=1
    142.     end if
    143.  
    144.     load pop@x byte from _qwe_
    145.     _qwe_=_qwe_+1
    146.  
    147.   end while
    148.  
    149.   ;pop@x=opcode
    150.   if pop@x=0Fh
    151.   _qwe_=_qwe_+1
    152.   else if pop@x=08Fh
    153.  
    154.     load pop@x byte from _qwe_
    155.     _qwe_=_qwe_+1
    156.  
    157.     ;pop@x=modrm
    158.     ;_qwe_=modrm+1
    159.     if mod00
    160.  
    161.       if sib
    162.  
    163.         load pop@x byte from _qwe_
    164.         _qwe_=_qwe_+1
    165.  
    166.         ;pop@x=sib
    167.         if (pop@x and 00000111b)=00000101b
    168.         _qwe_=_qwe_+4
    169.         end if
    170.  
    171.       else if (pop@x and 00000111b)=00000101b;r/m=101b
    172.       _qwe_=_qwe_+4
    173.       else
    174.  
    175.         ;
    176.  
    177.       end if
    178.  
    179.     else if mod01
    180.  
    181.       if sib
    182.       _qwe_=_qwe_+2
    183.       else
    184.       _qwe_=_qwe_+1
    185.       end if
    186.  
    187.     else if mod10
    188.  
    189.       if sib
    190.       _qwe_=_qwe_+5
    191.       else
    192.       _qwe_=_qwe_+4
    193.       end if
    194.  
    195.     else;mod11
    196.  
    197.       ;_qwe_ points to next instruction
    198.  
    199.     end if
    200.  
    201.   else if pop@x=6Ah
    202.  
    203.     _qwe_=_qwe_+1
    204.  
    205.   else if pop@x=68h
    206.  
    207.     if is16=1
    208.     _qwe_=_qwe_+2
    209.     else
    210.     _qwe_=_qwe_+4
    211.     end if
    212.  
    213.   else
    214.   ;push r(32/16)/seg
    215.   end if
    216.  
    217.  
    218.   ;;;;;;;;;;;;;;;;;;;;;;;;
    219.   if is16=0
    220.   %esp=%esp-4
    221.   else
    222.   %esp=%esp-2
    223.   end if
    224.  
    225. end while
    226. }
    227.  
    228. ret_addr equ esp+%esp
    229. start:
    230.  
    231. mov eax,[ret_addr]
    232. push word [esp]
    233. mov eax,[ret_addr]
    234. push @f
    235. mov eax,[ret_addr]
    236. pop bx
    237. mov eax,[ret_addr]
    238. push 10 rva start word [esp]
    239. mov eax,[ret_addr]
    240. pop cx dx
    241. mov eax,[ret_addr]
    242. pop edi
    243. mov eax,[ret_addr]
    244. pop bp ebx
    245. mov eax,[ret_addr]
    246.  
    247. @@:
    248.  
    249. retn
    Зря я на самом деле префиксы проверял (кроме 66h), всё-равно при использовании префикса он использует оригинальный push/pop.
     
  9. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    qwe8013
    Нунифигасебе надекодировали. Вряд ли до этого руки дойдут, но таки добавлю себе в конец todo list'а реализацию дизассемблера длин в директивах fasm.
    Потому что оператор in проверяет равенство, как оператор eq, а не как оператор =.