Консультация № 195579
11.05.2019, 14:10
0.00 руб.
0 9 0
Здравствуйте! Прошу помощи в следующем вопросе:
Windows 10 x64, fasm.
Занимаюсь по книге "Аблязов - программирование на ассемблере на платформе х86-64", застопорился на DLL, стр 167. Но работая по примерам они выдают ошибку, что на win10 что на XP. Выдают BadImage.

Гугление привело к таким же подобным примерам и проблемам. При том замечу, если брать готовый DLL который был в примерах, то работает всё нормально. Если же компилировать самому пример, то получается вышеописанная ошибка. То есть возникает вопрос, может я компилирую неправильно?
Примеры из книги.
скачать файл program.ASM [5.1 кб]
скачать файл DLL_sample.ASM [623 байт]
готовый DLL из книги:
скачать файл dll_sample.dll [2.0 кб]

Я понимаю что по "простецки" всё так написал, взвалив на Вас, можно сказать, роль преподавателей. Поэтому Я приму в помощь если Вы дадите материал с примерами на fasm, для win 10. Я думаю, что не исключено что компилируя в 64битной среде у Меня и появляются эти ошибки, хотя Я пробывал на 32 битной 10ке, тоже самое было, но так как нюансов очень много то Я возможно где нибудь и Сам что либо не досмотрел. Буду благодарен.

Обсуждение

давно
Посетитель
402031
115
11.05.2019, 18:15
общий
Ты хотя бы показал, Что и как ты вояешь.
Читать твою статью, думаю никто не кинется.
Так что давай свой код в студию. (код не из гниги, а твой)
По тому как с DLL в MASM проблем нет.
давно
Посетитель
402218
66
11.05.2019, 20:02
общий
11.05.2019, 20:03
Адресаты:
Вычисляется формула (a+3)*6+a*(100-a)
в библиотеке DLL_sample.dll будет находится процесс вычисления
[code lang=asm]format PE GUI 4.0 DLL
entry DllEntryPoint

include 'win32a.inc'

section '.code' code readable executable

proc DllEntryPoint hinstDLL,fdwReason,lpvReserved
mov eax, TRUE
ret
endp

proc CalcValue Value
push ebx
push edx

push eax
add eax, 3
imul eax, 6
mov ebx, eax ; ebx = (a+3)*6

mov edx, 100 ;
pop eax
sub edx, eax
imul eax, edx ; eax = a*(100-a)

add eax, ebx ; eax = res

pop edx
pop ebx
ret
endp

section '.edata' export data readable

export 'DLL_sample.DLL',\
CalcValue,'CalcValue'
section '.reloc' fixups data discardable[/code]
Основная программа.
[code lang=asm]format PE Console 4.0
entry start

include 'win32a.inc'

section '.data' data readable writeable
inputa db 'Input a ',0

InputHandle dd 0
OutputHandle dd 0

Writed dd 0
Readed dd 0

MAX_VALUE_LENGTH equ 30


cons db 'CON',0
message db '(a+3)*6+a*(100-a)='
a_str db MAX_VALUE_LENGTH dup (0)

DLL_name db 'DLL_sample.DLL',0
FUNC_name db 'CalcValue',0

section '.code' code executable readable writeable

start:

invoke GetStdHandle, STD_INPUT_HANDLE
mov [InputHandle], eax

invoke GetStdHandle, STD_OUTPUT_HANDLE
mov [OutputHandle], eax


invoke WriteConsole, [OutputHandle], inputa, 8,Writed,0
invoke ReadConsole, [InputHandle], a_str, MAX_VALUE_LENGTH, Readed,0

mov edi, a_str
call GetZSLength
sub eax, 2
mov ebx, eax
add eax, a_str
mov word [eax], 0

mov esi, a_str
call STR_to_DWORD_EX
push eax

invoke LoadLibrary, DLL_name ; eax = DLL handle
invoke GetProcAddress, eax, FUNC_name ; eax = func address
mov ebx, eax ; ebx = eax
pop eax ; eax = value
stdcall ebx, eax ; call func

mov esi, a_str
mov ebx, 10
call dword_to_STR


mov edi, message
call GetZSLength

invoke WriteConsole, [OutputHandle], message, eax,Writed,0
invoke ReadConsole, [InputHandle], a_str, 1,0,0

invoke ExitProcess, 0

GetZSLength:
; get zero-string length
;IN
; EDI ZS offset
;OUT
; EAX ZS length

push ecx
push esi
push edi

cld
xor al, al
mov ecx, 0FFFFFFFFh
mov esi, edi
repne scasb
sub edi, esi
mov eax, edi
dec eax

pop edi
pop esi
pop ecx
ret

dword_to_STR:
;на входе EAX число 32 бит
; ESI указатель на строку
; EBX разрядность результата
pushad
cmp ebx, 16
ja .end
cmp eax, 7FFFFFFFh
jna .sign_plus
mov byte [esi], '-'
inc esi
not eax
inc eax
.sign_plus:
xor ecx, ecx
sub esp, 32

.repeat:
xor edx, edx
div ebx
mov edi, eax
mov al, dl
cmp al, 10
sbb al, 69h
das
mov byte [esp+ecx], al
mov eax, edi

inc ecx
cmp eax, 0
jz .endrep
jmp .repeat
.endrep:
mov edi, esp
add edi, ecx
.copyrep:
dec edi
mov dl, byte [edi]
mov byte [esi], dl
inc esi

loop .copyrep
add esp, 32
.end:
popad
ret

STR_to_DWORD_EX:
; IN ESI = pointer to ZS
; OUT EAX = result
push esi
push ebx
push edi

xor ebx, ebx
cmp byte [esi], '-'
jnz .sign_plus
mov ebx, 1
inc esi
.sign_plus:

mov edi, esi
call GetZSLength
mov edi, eax
add edi, esi
dec edi
cmp byte [edi], "b"
jnz .oct
mov eax, 2
xchg byte [edi], bh
jmp .convert
.oct:
cmp byte [edi], "o"
jnz .hex
mov eax, 8
xchg byte [edi], bh
jmp .convert
.hex:
cmp byte [edi], "h"
jnz .decim
mov eax, 16
xchg byte [edi], bh
jmp .convert
.decim:
mov eax, 10
mov bh, byte [edi]
.convert:
call STR_to_DWORD
xchg byte [edi], bh
xor bh, bh
cmp ebx, 1
jnz .end
xor ebx, ebx
sub ebx, eax
mov eax, ebx
.end:
pop edi
pop ebx
pop esi
ret


STR_to_DWORD:
; IN ESI = pointer to ZS
; EAX = notation
; OUT EAX = result
push esi
push ebx
push edi
push edx
push ecx

cmp eax, 16
ja .error
cmp eax, 2
jb .error

mov ecx, eax

mov edi, esi
call GetZSLength
mov edi, eax
add edi, esi ; edi point to end ZS

xor eax, eax
xor edx, edx
inc edx

.rep:
dec edi

xor ebx, ebx
mov bl, [edi]
cmp bl, 30h
jb .error
cmp bl, 39h
jna .digit
cmp bl, 41h
jb .error
@@:
cmp bl, 46h
jna .sim_upcase
cmp bl, 61h
jb .error
@@:
cmp bl, 66h
jna .sim_lowcase
ja .error

.digit:
sub bl, 30h
jmp @f
.sim_upcase:
sub bl, 37h
jmp @f
.sim_lowcase:
sub bl, 57h
@@:
cmp bl, cl
ja .error

imul ebx, edx
add eax, ebx
imul edx, ecx
cmp edi, esi
jnz .rep
.endrep:


jmp @f
.error:
xor eax, eax
@@:

pop ecx
pop edx
pop edi
pop ebx
pop esi
ret



section '.relocs' fixups readable writeable

section '.idata' import data readable writeable

library kernel,'KERNEL32.DLL',\
user, 'user32.dll'

import kernel,\
ExitProcess,'ExitProcess', \
GetStdHandle, 'GetStdHandle',\
ReadConsole, 'ReadConsoleA',\
WriteConsole, 'WriteConsoleA',\
WriteFile, 'WriteFile',\
ReadFile, 'ReadFile',\
CreateFile, 'CreateFileA',\
LoadLibrary, 'LoadLibraryA',\
GetProcAddress, 'GetProcAddress'

import user,\
MessageBox,'MessageBoxA'[/code]

давно
Посетитель
402218
66
13.05.2019, 19:36
общий
Проблема решилась тем, что добавил в DLL ещё одну функцию, MessageBox. Но можно было вообще любую другую функцию добавить которая пользовалась бы другими библиотеками. До этого дошел таким способом, что взял родной пример который идёт с FASM компилятором, вставил функцию из книги, и всё заработало, затем удалил функцию из родного примера, оставив одну функцию из книги и старая ошибка. Так же пробовал проделывать что то подобное делая функцию DLL которая работала бы только с регистрами, и он будучи единственной, создавала ошибку.
давно
Посетитель
402031
115
14.05.2019, 07:10
общий
Адресаты:
Добавление сторонней функции, это не правильное решение.
Вот ссылка почитай. https://wasm.in/blogs/category/uroki-iczeliona.2/?page=5
статья Win32 API. Урок 17. Динамические библиотеки
давно
Посетитель
402218
66
14.05.2019, 13:33
общий
Адресаты:
Да, неправильно конечно Я написал - что решил проблему, но согласитесь что это странный способ работы. Спасибо, в планах было читать и Икселиона, думал буду книги по очереди читать, но видимо придется читать по темам параллельно. И искать посылы того почему длл не работоспособна при том варианте который Я описывал.
давно
Посетитель
402031
115
14.05.2019, 13:47
общий
Адресаты:
Да у тебя вроде DLL была правильно оформлена.
Я могу предположить, нет таблицы импорта. Нужен еще файл с расширением .def
Я в FASMе не силен. Пишу на MASM под API.
давно
Посетитель
402031
115
14.05.2019, 13:53
общий
Адресаты:
Хотя принцип построения DLL, к языку программирования никак не привязан. Пиши хоть на китайском, только соблюдай правила.
давно
Посетитель
7438
7205
15.05.2019, 14:21
общий
Адресаты:
Помощь еще нужна? Если да, то постараюсь найти время посмотреть...
Об авторе:
"Если вы заметили, что вы на стороне большинства, —
это верный признак того, что пора меняться." Марк Твен
давно
Посетитель
402218
66
15.05.2019, 15:57
общий
15.05.2019, 16:27
Адресаты:
Здравствуйте. Если только Вы раньше делали DLL на FASM'e. Но только желательно прокампилировать его в win10 x64, и посмотрите будет ли Он работать иль нет. Cain52 тоже обратил внимание что принцип построения соблюдён, а вот ошибка ли эта для FASM, или для другой среды отличной от win XP, уже другой вопрос.
так же и на win xp проверил. то же самое.
Форма ответа