В общем работа ведется в двух направлениях: 1)собрать из MSCOFF генерируемого фасмом бинарник: Код (Text): format MS COFF ; ************************************** Define "prototype" extrn '_puts@4' as puts:dword extrn '_Disasm@4' as Disasm:dword extrn '_ExitProcess@4' as ExitProcess:dword ; ************************************** includes include '%fasminc%\win32ax.inc' ; <--- extended headers to enable macroinstruction .if .elseif .end include '%fasminc%\library\BeaEngineFasm32.inc' section '.data' data readable writeable MyDisasm _Disasm <> i db 100 szoutofblock db "Security alert. Disasm tries to read unreadable memory",0 section '.text' code readable executable public start start: ; *********************** Init EIP mov eax, start mov [MyDisasm.EIP], eax ; *********************** loop for disasm MakeDisasm: push MyDisasm call Disasm .if eax = OUT_OF_BLOCK push szoutofblock call puts add esp, 4 push 0 call ExitProcess .elseif eax = UNKNOWN_OPCODE inc [MyDisasm.EIP] .else add [MyDisasm.EIP], eax .endif push MyDisasm.CompleteInstr call puts add esp, 4 dec byte [i] jne MakeDisasm push 0 call ExitProcess Все это хозяйство собирается в обьектник и я собственно говоря пытаюсь его собрать в РЕ: Код (Text): C:\>"D:\Microsoft Visual Studio\VC98\Bin\link.exe" /ENTRY:start /SUBSYSTEM:CONSOLE "D:\RadASM\Fasm\Projects\beaengine\beaengine.obj" "D:\RadASM\ Fasm\Projects\beaengine\BeaEngine.lib" "D:\Microsoft Visual Studio\VC98\Lib\msvcrt.lib" "D:\Microsoft Visual Studio\VC98\Lib\kernel32.lib" и получаю следующее: Код (Text): LINK : error LNK2001: unresolved external symbol _start beaengine.obj : error LNK2001: unresolved external symbol _puts@4 beaengine.exe : fatal error LNK1120: 2 unresolved externals ЗЫ: хотя экстерны в коде фасма присутствуют. Хотя я тут могу что-то недопонимать в принципе 2) Пробую всетаки собрать без сношений с линковкой и т.д и т.п: Код (Text): format PE GUI 4.0 include '%fasminc%\win32a.inc' include '%fasminc%\MACRO\IF.inc' include '%fasminc%\MACRO\MASM.inc' include '%fasminc%\library\BeaEngineFasm32.inc' section '.text' code readable writable executable entry start start: xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax xor eax,eax MakeDisasm: mov eax,start push MyDisasm call MyDisasm .if eax = OUT_OF_BLOCK push szoutofblock call puts add esp, 4 push 0 call ExitProcess .elseif eax = UNKNOWN_OPCODE int 3 inc [_Disasm.EIP] .else add [_Disasm.EIP], eax .endif push _Disasm.CompleteInstr call puts add esp, 4 dec byte [i] jne MakeDisasm push 0 call ExitProcess __exit: invoke ExitProcess,NULL section '.data' data readable writable executable dd ? disasm rb 0x1024 ;MyDisasm = Disasm i db 100 szoutofblock db "Security alert. Disasm tries to read unreadable memory",0 section '.rdata' import data readable writable library kernel32, 'KERNEL32.DLL',\ user32, 'USER32.DLL',\ shell32, 'SHELL32.DLL',\ msvcrt, 'MSVCRT.DLL' library BeaEngine, '%fasminc%\library\BeaEngine.dll' import BeaEngine, MyDisasm,'_Disasm@4',\ _ExitProcess@4,'ExitProcess',\ puts,'_puts@4' include '%fasminc%\api\KERNEL32.INC' include '%fasminc%\api\SHELL32.INC' include '%fasminc%\api\USER32.INC' import msvcrt,atoi,'atoi' после инструкций: Код (Text): push MyDisasm call MyDisasm Мы попадаем в функу дизасма, но там стопоримся на третьей инструкции(оно-то и понятно): Код (Text): 0040408A 96 XCHG EAX,ESI 0040408B 40 INC EAX [b]0040408C 0000 ADD BYTE PTR DS:[EAX],AL[/b] 0040408E A2 40000000 MOV BYTE PTR DS:[40],AL 00404093 0000 ADD BYTE PTR DS:[EAX],AL 00404095 0000 ADD BYTE PTR DS:[EAX],AL 00404097 005F 44 ADD BYTE PTR DS:[EDI+44],BL 0040409A 6973 61 736D403>IMUL ESI,DWORD PTR DS:[EBX+61],34406D73 Правильно, потому что мы нифига не заполнили структуру _Disasm: Код (Text): struct _Disasm EIP dd 0 VirtualAddr dq 0 SecurityBlock dd 0 CompleteInstr db 64 dup(0) Archi dd 0 Options dd 0 Instruction INSTRTYPE Argument1 ARGTYPE Argument2 ARGTYPE Argument3 ARGTYPE Prefix PREFIXINFO Reserved_ dd 40 dup(0) ends в оригинальном примере следующее: Код (Text): mov eax, start mov [MyDisasm.EIP], eax и выше кода определяется: MyDisasm _Disasm <> т.е определяется пустая структура. Так можно делать только тогда, когда мы формируем MSCOFF, при генерации format PE мы так сделать не можем. Как определить пустую структуру при format PE ? Вообще кто-то прикручивал сей инструмент к фасму ? Я плотно погуглил по форуму транслятора и там либо драйвера, либо примеры с генерированием MSCOFF. В общем нужно как-то определить пустую структуру, чтобы потом в нее засунуть значения типа: Код (Text): lea eax,dword [_Disasm] mov eax,[eax+_Disasm+EIP] push MyDisasm call Disasm В общем я в легком шоке
Хоть сейчас у меня почти уже утро, но все же мне кажется что тут нужно через invoke, то есть: invoke MyDisasm , MyDisasm А какая цель задачи? А то неясно, что сделать то нужно.
common_up А как вы себе представляете память в которую ничего не записано? А вообще Код (Text): MyDisasm _Disasm без <>
Всё ровно. Следующий вопрос: после отработки функции дизасма хотелось бы знать не только размер инструкции, а и длину аски комманды. Вручную парсить строку или есть какой-то более внятный способ ?
common_up Ну это вот уже можете и сами придумать. Вариантов много, очевидных и не очень. Главное - воображение. ЗЫ Почему бы просто не вычислить разницу (после)-(до) [указатель строки Х формирования строки с описанием инструкции]
Не получится так сделать потому, что каждая дизасмленная ascii кладется в член структуры, который определен как Код (Text): CompleteInstr db 64 dup(0) т.е адрес статичен. В общем думаю, может сделать поиск конца вручную ?
common_up что значит не получится, по завершению копирования/формирования текста команды у вас в регистре/переменной дубет адрес вида CompleteInstr+StrLen достаточно из этого регистра вычесть CompleteInstr. что сложного (со статическими адресами это даже проще)
Ты имеешь ввиду внутри самой функции дизасма ? Там предлагаешь ловить расмер строки ascii ? Просто после отработки функции дизасма: Код (Text): call [Disasm] мы в регистрах не имеем размера ascii строки, а лишь длину инструкции, которая не совпадает с длиной ascii строки к примеру после 1 вызова(push MyDisasm): eax=5 ecx=402010 после 2 вызова(call [Disasm]): eax=6 ecx=402010 где eax = длина инструкции, ecx = указатель на член структуры Disasm.EIP
Да уж, не стоило огород огородить. К чему всё это сношение ? просто нужно было использовать апи lstrlen и все. Топик можно считать закрытым. Огромное спасибо max7C4.