Страница: 1 | 2 |
Вопрос: Запуск кода функции из переменной
Добавлено: 11.08.06 11:03
Автор вопроса: alex
Подскажите почему не работает такой код?
Мне нужно создавать много экземпляров функции Test, и запускать их на выполение..
#Dim All
Function Test(ByVal p1 As Long) As Long
!JMP Start
!db "H","E","L","L","O"
Start:
! Ret
End Function
Sub TestEnd()
!ret
End Sub
Function PBMain () As Long
Dim GetBinaryCode As String
Dim hFunct As Dword
GetBinaryCode =Peek$(CodePtr(Test), CodePtr(TestEnd)- CodePtr(Test) )
hFunct=StrPtr(GetBinaryCode)
Call Dword hFunct
End Function
Ответы
Всего ответов: 18
Номер ответа: 1
Автор ответа:
GSerg
Вопросов: 0
Ответов: 1876
Профиль | | #1
Добавлено: 11.08.06 11:49
Это новое слово в программировании...
Номер ответа: 2
Автор ответа:
alex
Вопросов: 84
Ответов: 453
Профиль | | #2
Добавлено: 11.08.06 12:02
Ничего нового, обычное бинарное наследование.
Пример на тему:
http://www.powerbasic.com/support/forums/Forum7/HTML/001328.html
Номер ответа: 3
Автор ответа:
JMP
Вопросов: 6
Ответов: 171
Профиль | | #3
Добавлено: 12.08.06 09:56
А если так?
#COMPILE EXE
#DIM ALL
FUNCTION PBMAIN () AS LONG
 IM GetBinaryCode AS STRING
 IM hFunct AS DWORD
GetBinaryCode = PEEK$(CODEPTR(Test), CODEPTR(TestEnd)- CODEPTR(Test) )
hFunct=STRPTR(GetBinaryCode)
CALL DWORD hFunct
EXIT FUNCTION
Test:
!JMP Start
!db "H","E","L","L","O"
Start:
! Ret
TestEnd:
END FUNCTION
с метками в данном случае надо работать в пределах функции, а так как Вы показали , совсем не обязательно
что SUB TestEnd окажеться после компиляции позади SUB Test.
Номер ответа: 4
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #4
Добавлено: 12.08.06 13:07
Да, но функция объявлена с параметром, а вызываешь ты без него. Видимо он и не находит адрес возврата.
Номер ответа: 5
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #5
Добавлено: 12.08.06 13:09
Попробуй так
Номер ответа: 6
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #6
Добавлено: 12.08.06 13:13
Вот так в 8-ке работает
#Dim All
Function Test(ByVal p1 As Long) As Long
!JMP Start
!db "H","E","L","L","O"
Start:
Exit Function
End Function
Sub TestEnd()
!ret
End Sub
Function PBMain () As Long
Dim GetBinaryCode As String
Dim hFunct As Dword
GetBinaryCode =Peek$(CodePtr(Test), CodePtr(TestEnd)- CodePtr(Test) )
hFunct=StrPtr(GetBinaryCode)
Call Dword hFunct
End Function
Номер ответа: 7
Автор ответа:
alex
Вопросов: 84
Ответов: 453
Профиль | | #7
Добавлено: 14.08.06 10:00
что SUB TestEnd окажеться после компиляции позади SUB Test.
TestEnd всегда будет после SUB Test, PB складывает функции в EXE в порядке их описания.
Кстати, почему при запуске из строки не работают PB RTL функции?
Только IF, FOR, SELECT CASE, +,-,*
Номер ответа: 8
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #8
Добавлено: 14.08.06 19:22
Лучше всего дизассемблировать и посмотреть. Могу предположить что используются (в некоторых местах конечно) относительные джампы. Хотя это только предположение.
Номер ответа: 9
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #9
Добавлено: 14.08.06 20:20
Вот примерно тоже, что сделал и автор (Chuck de Young) по ссылке из (2).
#Dim All
Global A1 As String*4096
Declare Function Test(ByVal p1 As Long) As Long
Sub Msg2
Dim a As Integer
a=1
MsgBox "!!!"
End Sub
Function Test(ByVal p1 As Long) As Long
!JMP Start
!db "H","E","L","L","O"
Start:
Call Dword p1
Exit Function
End Function
Sub TestEnd()
!ret
End Sub
Function PBMain () As Long
Dim GetBinaryCode As String
Dim hFunct As Dword
Dim z2 As Dword
A1 =Peek$(CodePtr(Test), CodePtr(TestEnd)- CodePtr(Test) )
hFunct=VarPtr(A1)
z2=CodePtr(Msg2)
Call Dword hFunct Using Test(z2)
End Function
Если в двух словах, то он передавал в процедру-строку адреса процедур с функциями MsgBox и в этой строке-процедуре вызывал их не прямо, а по CALL DWORD. Честно говоря я не догадываюсь о различиях между CALL и CALL DWORD на уровне машкодов, но вызывал он именно так. И вышепреведенный рабочий листинг (во всяком случае для MsgBox) тому прямое подтверждение.
PS: Да, кстати, в XP по идее должна быть встроена защита от запуска кода из кучи. Мне переключать системы лень, а то бы я проверил конечно.
Номер ответа: 10
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #10
Добавлено: 14.08.06 21:01
Вообще DEP работает только на процах, которые это поддерживают
Номер ответа: 11
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #11
Добавлено: 14.08.06 23:27
Не совсем так
http://www.microsoft.com/technet/prodtechnol/winxppro/maintain/sp2mempr.mspx
An additional set of data execution prevention security checks have been added to Windows XP SP2. These checks, known as software-enforced DEP, are designed to mitigate exploits of exception handling mechanisms in Windows. Software-enforced DEP runs on any processor which is capable of running Windows XP SP2. By default, software-enforced DEP only protects limited system binaries, regardless of the hardware-enforced DEP capabilities of the processor.
Номер ответа: 12
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #12
Добавлено: 15.08.06 04:10
Разве эту эмуляцию можно назвать словом "работает"? На васме была дискуссия по этому поводу, сошлись, что нельзя
Номер ответа: 13
Автор ответа:
JMP
Вопросов: 6
Ответов: 171
Профиль | | #13
Добавлено: 15.08.06 05:17
ИМХО если делать все по человечески, не через строки а
через VirtualAlloc & WriteProcessMemory, по идее не должно быть конфликтов т.к. на стадии выделения памяти
оговариваеться с какими атрибутами создаеться блок памяти.
#COMPILE EXE
#DIM ALL
'
#INCLUDE "win32api.inc"
'
DECLARE FUNCTION Test(BYVAL p1 AS LONG) AS LONG
'
SUB Msg2
 IM a AS INTEGER
a=1
MSGBOX "!!!"
END SUB
'
FUNCTION Test(BYVAL p1 AS LONG) AS LONG
!JMP Start
!db "H","E","L","L","O"
Start:
CALL DWORD p1
EXIT FUNCTION
END FUNCTION
'
SUB TestEnd()
!ret
END SUB
'
FUNCTION PBMAIN () AS LONG
 IM GetBinaryCode AS STRING
 IM hFunct AS DWORD
 IM z2 AS DWORD
'
hFunct=VirtualAlloc (BYVAL %NULL,BYVAL CODEPTR(TestEnd)- CODEPTR(Test), BYVAL %MEM_COMMIT, BYVAL %PAGE_EXECUTE_READWRITE)
WriteProcessMemory(BYVAL GetCurrentProcess(),BYVAL hFunct,BYVAL CODEPTR(Test), BYVAL CODEPTR(TestEnd)- CODEPTR(Test), BYVAL %NULL)
'
z2=CODEPTR(Msg2)
CALL DWORD hFunct USING Test(z2)
END FUNCTION
To: CyRax
Спасибо за EXIT FUNCTION вместо ! RET.
Честно говоря всегда думал что EXIT FUNCTION это и есть ! RET. Но судя по всему там еще что то делается.
Номер ответа: 14
Автор ответа:
alex
Вопросов: 84
Ответов: 453
Профиль | | #14
Добавлено: 15.08.06 10:13
Call - можно рассматривать как переход к метке
! jmp Funct1
.....
Funct1:
Call DWORD - переход по адресу хранящемуся в переменной
! jmp @Var1
Номер ответа: 15
Автор ответа:
CyRax
Разработчик Offline Client
ICQ: 204447456
Вопросов: 180
Ответов: 4229
Web-сайт:
Профиль | | #15
Добавлено: 15.08.06 10:25
Пожалуйста. Ты что тоже этой темой интересуешся?
Нет, EXIT FUNCTION - это полный комплекс выхода из процедуры. В частности восстановление стека (MOV ESP,EBP), восстановление ESI и EDI и т.д. По такому же (примерно) шаблону я организовал вход/выход в процедуру в Local Assembler.