Мелкий вопрос по fasm

Тема в разделе "WASM.BEGINNERS", создана пользователем common_up, 8 июл 2010.

  1. common_up

    common_up New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    85
    В общем работа ведется в двух направлениях:
    1)собрать из MSCOFF генерируемого фасмом бинарник:
    Код (Text):
    1. format MS COFF
    2.  
    3. ; ************************************** Define "prototype"
    4.  
    5. extrn '_puts@4' as puts:dword
    6. extrn '_Disasm@4' as Disasm:dword
    7. extrn '_ExitProcess@4' as ExitProcess:dword
    8.  
    9. ; ************************************** includes
    10. include '%fasminc%\win32ax.inc'     ; <--- extended headers to enable macroinstruction .if .elseif .end
    11. include '%fasminc%\library\BeaEngineFasm32.inc'
    12.  
    13.  
    14. section '.data' data readable writeable
    15.  
    16.  
    17.     MyDisasm       _Disasm       <>
    18.     i               db            100
    19.     szoutofblock    db            "Security alert. Disasm tries to read unreadable memory",0
    20.  
    21.  
    22. section '.text' code readable executable
    23.  
    24.  public start
    25.  
    26.  start:
    27.  
    28.     ; *********************** Init EIP
    29.     mov eax, start
    30.     mov [MyDisasm.EIP], eax
    31.    
    32.     ; *********************** loop for disasm
    33.     MakeDisasm:
    34.         push MyDisasm
    35.         call Disasm
    36.         .if eax = OUT_OF_BLOCK
    37.             push szoutofblock
    38.             call puts
    39.             add esp, 4
    40.             push 0
    41.             call ExitProcess
    42.         .elseif eax = UNKNOWN_OPCODE
    43.             inc [MyDisasm.EIP]
    44.         .else
    45.             add [MyDisasm.EIP], eax
    46.         .endif
    47.         push MyDisasm.CompleteInstr
    48.         call puts                          
    49.         add esp, 4
    50.         dec byte [i]
    51.         jne MakeDisasm
    52.     push 0
    53.     call ExitProcess
    Все это хозяйство собирается в обьектник и я собственно говоря пытаюсь его собрать в РЕ:
    Код (Text):
    1. C:\>"D:\Microsoft Visual Studio\VC98\Bin\link.exe" /ENTRY:start /SUBSYSTEM:CONSOLE "D:\RadASM\Fasm\Projects\beaengine\beaengine.obj" "D:\RadASM\
    2. Fasm\Projects\beaengine\BeaEngine.lib"  "D:\Microsoft Visual Studio\VC98\Lib\msvcrt.lib" "D:\Microsoft Visual Studio\VC98\Lib\kernel32.lib"
    и получаю следующее:
    Код (Text):
    1. LINK : error LNK2001: unresolved external symbol _start
    2. beaengine.obj : error LNK2001: unresolved external symbol _puts@4
    3. beaengine.exe : fatal error LNK1120: 2 unresolved externals
    ЗЫ: хотя экстерны в коде фасма присутствуют. Хотя я тут могу что-то недопонимать в принципе


    2) Пробую всетаки собрать без сношений с линковкой и т.д и т.п:
    Код (Text):
    1. format PE GUI 4.0
    2. include '%fasminc%\win32a.inc'
    3. include '%fasminc%\MACRO\IF.inc'
    4. include '%fasminc%\MACRO\MASM.inc'
    5. include '%fasminc%\library\BeaEngineFasm32.inc'
    6. section '.text' code readable writable executable
    7.         entry start
    8. start:
    9.     xor eax,eax
    10.     xor eax,eax
    11.     xor eax,eax
    12.     xor eax,eax
    13.    
    14.     xor eax,eax
    15.     xor eax,eax
    16.     xor eax,eax
    17.     xor eax,eax
    18.     xor eax,eax
    19.     xor eax,eax
    20.     xor eax,eax
    21.    
    22.    
    23.     MakeDisasm:
    24.         mov eax,start
    25.         push MyDisasm
    26.         call MyDisasm
    27.         .if eax = OUT_OF_BLOCK
    28.             push szoutofblock
    29.             call puts
    30.             add esp, 4
    31.             push 0
    32.             call ExitProcess
    33.         .elseif eax = UNKNOWN_OPCODE
    34.            int 3
    35.             inc [_Disasm.EIP]
    36.         .else
    37.             add [_Disasm.EIP], eax
    38.         .endif
    39.         push _Disasm.CompleteInstr
    40.         call puts                          
    41.         add esp, 4
    42.         dec byte [i]
    43.         jne MakeDisasm
    44.     push 0
    45.     call ExitProcess
    46.  
    47.  
    48.  
    49.  
    50.  
    51.  
    52. __exit:
    53.         invoke ExitProcess,NULL
    54. section '.data' data readable writable executable
    55. dd ?
    56. disasm rb 0x1024
    57. ;MyDisasm = Disasm
    58.     i               db            100
    59.     szoutofblock    db            "Security alert. Disasm tries to read unreadable memory",0
    60.  
    61.  
    62. section '.rdata' import data readable writable
    63. library             kernel32,               'KERNEL32.DLL',\
    64.                     user32,                 'USER32.DLL',\
    65.                     shell32,                'SHELL32.DLL',\
    66.                     msvcrt,                 'MSVCRT.DLL'
    67. library BeaEngine, '%fasminc%\library\BeaEngine.dll'
    68. import BeaEngine,   MyDisasm,'_Disasm@4',\
    69.                     _ExitProcess@4,'ExitProcess',\
    70.                     puts,'_puts@4'
    71.  
    72. include '%fasminc%\api\KERNEL32.INC'
    73. include '%fasminc%\api\SHELL32.INC'
    74. include '%fasminc%\api\USER32.INC'         
    75.  
    76. import msvcrt,atoi,'atoi'
    после инструкций:
    Код (Text):
    1. push MyDisasm
    2. call MyDisasm
    Мы попадаем в функу дизасма, но там стопоримся на третьей инструкции(оно-то и понятно):
    Код (Text):
    1. 0040408A    96              XCHG EAX,ESI
    2. 0040408B    40              INC EAX
    3. [b]0040408C    0000            ADD BYTE PTR DS:[EAX],AL[/b]
    4. 0040408E    A2 40000000     MOV BYTE PTR DS:[40],AL
    5. 00404093    0000            ADD BYTE PTR DS:[EAX],AL
    6. 00404095    0000            ADD BYTE PTR DS:[EAX],AL
    7. 00404097    005F 44         ADD BYTE PTR DS:[EDI+44],BL
    8. 0040409A    6973 61 736D403>IMUL ESI,DWORD PTR DS:[EBX+61],34406D73
    Правильно, потому что мы нифига не заполнили структуру _Disasm:
    Код (Text):
    1. struct _Disasm
    2.     EIP             dd   0
    3.     VirtualAddr     dq   0
    4.     SecurityBlock   dd   0
    5.     CompleteInstr   db   64 dup(0)
    6.     Archi           dd   0
    7.     Options         dd   0
    8.     Instruction     INSTRTYPE
    9.     Argument1       ARGTYPE
    10.     Argument2       ARGTYPE
    11.     Argument3       ARGTYPE
    12.     Prefix          PREFIXINFO
    13.     Reserved_       dd   40 dup(0)
    14. ends
    в оригинальном примере следующее:
    Код (Text):
    1. mov eax, start
    2. mov [MyDisasm.EIP], eax
    и выше кода определяется:
    MyDisasm _Disasm <>
    т.е определяется пустая структура. Так можно делать только тогда, когда мы формируем MSCOFF, при генерации format PE мы так сделать не можем. Как определить пустую структуру при format PE ? Вообще кто-то прикручивал сей инструмент к фасму ? Я плотно погуглил по форуму транслятора и там либо драйвера, либо примеры с генерированием MSCOFF. В общем нужно как-то определить пустую структуру, чтобы потом в нее засунуть значения типа:
    Код (Text):
    1. lea eax,dword [_Disasm]
    2. mov eax,[eax+_Disasm+EIP]
    3. push MyDisasm
    4. call Disasm
    В общем я в легком шоке:)
     
  2. ziral2088

    ziral2088 New Member

    Публикаций:
    0
    Регистрация:
    16 авг 2009
    Сообщения:
    283
    Хоть сейчас у меня почти уже утро, но все же мне кажется что тут нужно через invoke, то есть: invoke MyDisasm , MyDisasm

    А какая цель задачи? А то неясно, что сделать то нужно.
     
  3. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    common_up
    А как вы себе представляете память в которую ничего не записано?
    А вообще
    Код (Text):
    1. MyDisasm       _Disasm
    без <>
     
  4. common_up

    common_up New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    85
    Всё ровно. Следующий вопрос: после отработки функции дизасма хотелось бы знать не только размер инструкции, а и длину аски комманды. Вручную парсить строку или есть какой-то более внятный способ ?
     
  5. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    common_up
    Ну это вот уже можете и сами придумать. Вариантов много, очевидных и не очень. Главное - воображение.
    ЗЫ Почему бы просто не вычислить разницу (после)-(до) [указатель строки Х формирования строки с описанием инструкции]
     
  6. common_up

    common_up New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    85
    Не получится так сделать потому, что каждая дизасмленная ascii кладется в член структуры, который определен как
    Код (Text):
    1. CompleteInstr   db   64 dup(0)
    т.е адрес статичен. В общем думаю, может сделать поиск конца вручную ?
     
  7. max7C4

    max7C4 New Member

    Публикаций:
    0
    Регистрация:
    17 мар 2008
    Сообщения:
    1.203
    common_up
    что значит не получится, по завершению копирования/формирования текста команды у вас в регистре/переменной дубет адрес вида CompleteInstr+StrLen достаточно из этого регистра вычесть CompleteInstr. что сложного (со статическими адресами это даже проще)
     
  8. common_up

    common_up New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    85
    Ты имеешь ввиду внутри самой функции дизасма ? Там предлагаешь ловить расмер строки ascii ?
    Просто после отработки функции дизасма:
    Код (Text):
    1. call [Disasm]
    мы в регистрах не имеем размера ascii строки, а лишь длину инструкции, которая не совпадает с длиной ascii строки

    к примеру после 1 вызова(push MyDisasm):
    eax=5
    ecx=402010
    после 2 вызова(call [Disasm]):
    eax=6
    ecx=402010

    где eax = длина инструкции, ecx = указатель на член структуры Disasm.EIP
     
  9. common_up

    common_up New Member

    Публикаций:
    0
    Регистрация:
    4 июл 2010
    Сообщения:
    85
    Да уж, не стоило огород огородить. К чему всё это сношение ?:)
    просто нужно было использовать апи lstrlen и все. Топик можно считать закрытым. Огромное спасибо max7C4.
     
  10. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    common_up,

    lstrlen() опасна #GP, если сильно не повезёт. Где же strnlen()? :derisive: