Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Assembler

Страница: 1 | 2 |

 

  Вопрос: Почему обнуляется? Добавлено: 22.09.04 03:33  

Автор вопроса:  CyRax  | Web-сайт: basicproduction.nm.ru | ICQ: 204447456 
Пишу я значит код вызова MessageBox на своём ассемблере.
Адрес MessageBoxA хранится в EBP-16.

Если так:
PUSH 0& 'MB_OK
PUSH [ebp-20] 'Title
PUSH [ebp-24] 'Caption
PUSH 0& 'hWnd
CALL [EBP-16] 'Addressof MessageBoxA

,то выбивает. Проверил и оказалось что после PUSH значение в EBP-16 обнуляется.

А так работает:
MOV EAX,[EBP-16]
PUSH 0&
PUSH [ebp-20]
PUSH [ebp-24]
PUSH 0&
CALL EAX

Может так не должно быть и мой ассемблер сглючил? Я блин 2 часа не мог причину найти.

Ответить

  Ответы Всего ответов: 29  

Номер ответа: 1
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #1
Добавлено: 22.09.04 04:07
Вот опкоды с WDasm

Это для CALL [EBP-16]
:0000004E 6800000000 push 00000000
:00000053 FF75EC push [ebp-14]
:00000056 FF75E8 push [ebp-18]
:00000059 6800000000 push 00000000
:0000005E FF55F0 call [ebp-10]

Это для MOV EAX,[EBP-16]
:0000004B 8B45F0 mov eax, dword ptr [ebp-10]
:0000004E 6800000000 push 00000000
:00000053 FF75EC push [ebp-14]
:00000056 FF75E8 push [ebp-18]
:00000059 6800000000 push 00000000
:0000005E FFD0 call eax

Ответить

Номер ответа: 2
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #2 Добавлено: 22.09.04 04:32
CALL [EBP-16] 'Addressof MessageBoxA



Call dword ptr [EBP-16]

хотя я не понял, почему у тебя в минус идёт?
у меня [ebp+8]

Ответить

Номер ответа: 3
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #3 Добавлено: 22.09.04 04:41

Полный код процедуры такой:

Message proc ProcAddr:DWORD, hWin:dword,lpTitle:DWORD,lpMess:DWORD

push 0
push dword ptr [ebp+14h]
push dword ptr [ebp+10h]
push dword ptr [ebp+0Ch]
Call dword ptr [ebp+8]

ret

Message endp

Ответить

Номер ответа: 4
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #4 Добавлено: 22.09.04 04:47
Вот так тоже работает:

mov eax,ProcAddr
push 0
push dword ptr [ebp+14h]
push dword ptr [ebp+10h]
push dword ptr [ebp+0Ch]
Call eax

Ответить

Номер ответа: 5
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #5
Добавлено: 22.09.04 04:53
В минус, потому что это локальная переменная.
[EBP+imm] - это параметры.
[EBP-imm] - это уже локальные переменные.
Отрицательных чисел конечно же в АСМ не существует. Но ассемблеры (и компиляторы кстати тоже) условно принимают большую половину числа за отрицательный диапазон.
К примеру [EBP-1] - это [EBP+FF], [EBP-4] - это [EBP+FC] и т.д.

PS: Я просто поддержку макросов сделал у себя. Вот тестирую тперь. Хочу потом какой нибудь аналог Invoke приделать.

Ответить

Номер ответа: 6
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #6
Добавлено: 22.09.04 05:04
Invoke наверное всё же прийдётся сделать. Я думал макросы упростят вызов API, но у меня они его только усложнили. Можешь не разбираться в коде. Просто глянь сколько его только на вызов окна сообщения:

#API
CONST EntryPoint EQU [EBP+8]
CONST LoadLibrary EQU [EBP+&HC]
CONST GetProcAddress EQU [EBP+&H10]
CONST Parameters EQU [EBP+&H14]

#MACRO ASCZ Src,reg32
MOV reg32,[EBP+8]
ADD reg32,Src
#END MACRO
#MACRO LIB ASCZ,reg32
PUSH ASCZ
CALL [EBP+&HC]
#END MACRO
#MACRO PROC LIB,ASCZ,reg32
PUSH ASCZ
PUSH LIB
CALL [EBP+&H10]
#END MACRO

CONST str_User32 EQU EBP-4
CONST hUser32 EQU EBP-8
CONST str_MessageBox EQU EBP-12
CONST hMessageBox EQU EBP-16

' USER32.DLL hModule
ASCZ USER32,EDX
MOV [str_User32],EDX
LIB [str_User32],EAX
MOV [hUser32],EAX

'MessageBox proc addr
ASCZ MsgBox,EDX
MOV [str_MessageBox],EDX
PROC [hUser32],[str_MessageBox],EAX
MOV [hMessageBox],EAX

CONST Title1 EQU ebp-20
CONST Caption1 EQU ebp-24
ASCZ MsgTitle,EDX
MOV [Title1],EDX
ASCZ Caption,EDX
MOV [Caption1],EDX


MOV EAX,[hMessageBox]
PUSH 0&
PUSH [Title1]
PUSH [Caption1]
PUSH 0&
CALL EAX
END &H10

' Строки вынесем в конец чтобы не путать дизассемблеры
USER32 DB "USER32.DLL",0
MsgBox DB "MessageBoxA",0
MsgTitle DB "Title",0
Caption DB "Caption",0

Ответить

Номер ответа: 7
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #7 Добавлено: 22.09.04 05:17
Так ты разобрался, Call dword ptr [] работает?

А хороший макрос - это вещь.

Ответить

Номер ответа: 8
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #8
Добавлено: 22.09.04 14:30
Так ты разобрался, Call dword ptr [] работает?

 Там и так DWORD PTR. Не веришь смотри опкоды.
FF/55/8 CALL [EBP+8]
FF/55/8 CALL DWORD PTR [EBP+8]

Это ж не MASM.
У меня стоит автокоррекция. Например такой вид записи допустим:
MOV ECX,[EBP+8]
MOV CX,[EBP+8]
MOV CL,[EBP+8]
это тоже что и
MOV ECX, DWORD PTR [EBP+8]
MOV CX, WORD PTR [EBP+8]
MOV CL, BYTE PTR [EBP+8]
И это вполне логично с точки зрения процессора. Потому как различные операнды недопустимы. Например опкода MOV ECX, BYTE PTR [EBP+8] не существует. Или MOV CL, DWORD PTR [EBP+8].

А по поводу CALL, который кстати BYTE PTR не поддерживает, то там по умолчанию DWORD PTR. А знаешь почему? Да потому что адресация 32-битная. Тут кроме DWORD PTR ничего нельзя ставить. Короче - без вариантов. Что такое WORD PTR я думаю ты уже понял.

Короче все эти приставки (PTR) придумала Микрософт хрен знает с какого бодуна. Потому как длина операнда-памяти всегда равна длине второго операнда. Будь то регистр или число.

А хороший макрос - это вещь.

 Такое добро нынче днём с огнём не сыскать ;)

Ответить

Номер ответа: 9
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #9 Добавлено: 22.09.04 16:19
По идее, опкоды CALL [EBP+8] и CALL DWORD PTR [EBP+8] одинаковые, вот только на первую команду компилер ml.exe ругается, на вторую нет. А приставки ...PTR - Возможно, это сделано для того, чтобы человек придерживался правильного стиля при написании. Что до некоторой степени предохраняет его от ошибок, которые могут возникнуть например с movzx eax,byte ptr[..]. В этом случае автоматом подставлять не получается, неизвестно, что будет: можно и byte ptr, можно и word ptr

Программа с CALL [EBP+8] работает, но только через отладчик OllyDbg. Почему - непонятно.

Ответить

Номер ответа: 10
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #10
Добавлено: 22.09.04 22:52
movzx eax,byte ptr[..].

 По моему она и MOVSX. Всё больше таких нет, ориентированных именно на разные размеры операндов. Кстати в моём ассемблере нет операнда по умолчанию для этих операций. И без добавления приставки PTR он информирует об ошибочных операндах.


Программа с CALL [EBP+8] работает, но только через отладчик OllyDbg. Почему - непонятно.

 В смысле? Тебе удалось скомпилировать через MASM без добавления приставки PTR?

Ответить

Номер ответа: 11
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #11 Добавлено: 22.09.04 23:18
Удалось. Правда RadASM при попытке компиляции и одновременно запуска из IDE ругнулся на эту строку и файл не запустился, но потом я ему указал запустить через дебаггер (в RadASM есть такая фича) и он вызвал OllyDbg c параметром "имя моей проги", и уже из Olly я запустил программу. Она исправно выдала MessageBox.

Ответить

Номер ответа: 12
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #12
Добавлено: 22.09.04 23:38
По моему решение моей проблемы нашлось. Я не выделил память для локальной переменной.
Это делается так: SUB ESP,Count*4
Глянь
http://www.masmforum.com/viewtopic.php?t=4151

Только я никак не могу взять в толк что делает эта операция SUB ESP,imm. Не подскажешь?

Ответить

Номер ответа: 13
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #13 Добавлено: 23.09.04 01:40
делает эта операция SUB ESP,imm


В стеке:
Var1(dword) --> [esp-10]
sub esp,4
Var1(dword) --> [esp-0С]

Переменная где была в памяти, там и осталась (её адрес прежний), но за счёт sub esp ты выделил под стек ещё 4 байта, а так как esp всегда указывает на вершину, то адрес твоей переменной по отношению к вершине сместился на 4 байта. И также сама вершина в абсолютном адресном пространстве сместилась на 4. К примеру: адрес в esp был 100000h, адрес Var1 был FFFF0, ты сместил esp на 4 байта вниз, в esp теперь содержится FFFFC (новый адрес вершины), и адрес Var1 относительно вершины (esp) теперь FFFFC-FFFF0=0С. Как я понимаю, sub esp,4 должен увеличить пространство под стек на 4 байта, и в этом дополнительном 4-байтном куске ты можешь разместить свою новую переменную, иначе эта инструкция нахрен не нужна. Имхо.

Ты мне вот такой прикол объясни: есть dll. Она работала, всё нормально. Потом внутри dll я исправил кое-что, откомпилил, слинковал, получил файл .dll и заменил им старый, называется также, положил как в системную папку, так и в папку с программой. И программа перестала его находить, хотя вот он, есть, и в системной папке тоже есть. А прога (и VB6 IDE) пишут, что не могут его найти. Они что ослепли на оба глаза сразу, или я сбесился? До этого переделывал её раз 20 наверное, проблем не было. А тут не видят они dll и всё. Перезагружался - не помогло

Ответить

Номер ответа: 14
Автор ответа:
 cresta



Вопросов: 117
Ответов: 1538
 Профиль | | #14 Добавлено: 23.09.04 01:48

А насчёт ошибки - я так понимаю, ты залез в адресное пространство, не выделенное для тебя, поэтому программу выбивало. И может обнуляло (вернее, не давало записать в область, где ты хотел сохранить адрес ф-ции) по той же причине.

Ответить

Номер ответа: 15
Автор ответа:
 CyRax



Разработчик Offline Client

ICQ: 204447456 

Вопросов: 180
Ответов: 4229
 Web-сайт: basicproduction.nm.ru
 Профиль | | #15
Добавлено: 23.09.04 02:25
Нет, выбивало потому что обнуляло. В результате вместо вызова адреса MessageBoxA, вызывался 0. Да и в GPF'е он показывал EIP=0. За розъяснение спасибо. Общую картину понял, а вот в частности похоже там несколько другое. Ещё помедитирую и скажу что.
 Да, ты заметил что в MASM EIP как операнд вообще не фигурирует? Да и опкодов я к нему не нашёл. Не знаешь как найти текущий адрес?

 По поводу библы. По моему у меня тоже такое было. Это вроде твоя ошибка. Пришли пример я гляну.

Ответить

Страница: 1 | 2 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам