Исходники моей программы по некоторым причинам приводить не хочу, хотя бы потому, что 30Kb чистой мнемоники.
Пробовал разными путями получить ошибку, вылезающую в моей программе и написал маленькую программульку имитирующую вызов Win32API при котором происходит ошибка (востановил контекст регистров и младшие 16 бит регистра флагов). К сожалению требуемого результата не достиг, буду копать дальше, может удастся выделить условия возникновения ошибки.
Вот код имитирующей программы:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
db 2800h DUP (0)
.code
TestSTD PROC
LOCAL hStdout :DWORD
mov eax, 3d2eh
mov ebx, 4039b0h
mov ecx, 14h
mov edx, 14h
mov edi, 4039afh
mov esi, 132559h
pushf
pop ax
mov ax, 246h
push ax
popf
; xor eax, eax
;std
push dword ptr 0
call ExitProcess
; invoke ExitProcess, eax
ret
TestSTD ENDP
end TestSTD
Ваяя на ASM'е натолкнулся на такую "фичу" - если выполнить std (установка флага направления для операций со строками), а потом выполнить функцию Win32API (работает ли это для фсех функций - не знаю), то subj!!!
Вот такой простой пример:
std
invoke ExitProcess, 0
В Win2K видим замечательную ошибку: The instruction at "0x..." referenced memory at "0x00000010". The memory could not be "read".
Жаль у меня нет SoftIce'а, с удовольствием бы поглядел, что происходит внутрях. Глядишь - еще одна уязвимость ака получение привелегий обнаружилась бы...
Мля-я-я-я-я... Не перестаю удивляться.17.03.04 20:41 Автор: Den <Денис Т.> Статус: The Elderman
Под рукой нет MSDN а в сайте M$ он сильно урезан и все особенности работы с Win32API приходится осваивать методом хождения по граблям.
После многочасовых долбаний головой о стену случайно выяснил, что функции работы с файлами (по крайней мере CreateFile и OpenFile) чувствительны к невыровненному по DWORD (двойное слово) указателю стека (регистр ESP).
Если при выровненном по DWORD указателе стека (регистр ESP) в стек засунуть слово (WORD - 16бит), а потом вызвать правильно оформленную функцию CreateFile или OpenFile, то эти функция вернет -1 (INVALID_HANDLE_VALUE = 0xffffffff)
:))))17.03.04 22:09 Автор: NKritsky <Nickolay A. Kritsky> Статус: Elderman
> Под рукой нет MSDN а в сайте M$ он сильно урезан и все > особенности работы с Win32API приходится осваивать методом > хождения по граблям.
"А как же! И только так!!" (С) Покровский.
> После многочасовых долбаний головой о стену случайно > выяснил, что функции работы с файлами (по крайней мере > CreateFile и OpenFile) чувствительны к невыровненному по > DWORD (двойное слово) указателю стека (регистр ESP). > > Если при выровненном по DWORD указателе стека (регистр ESP) > в стек засунуть слово (WORD - 16бит), а потом вызвать > правильно оформленную функцию CreateFile или OpenFile, то > эти функция вернет -1 (INVALID_HANDLE_VALUE = 0xffffffff)
Причем такие траблы только на семействе NT! с 9х кривой стек проходит нормально. Я когда-то очень удивлялся почему простенькая прога пашет в 9х и не пашет в NT. NT-шное ядро проверяет выравнивние стека при вызове системных функций через int 2e. Насколько я помню, даже не выравнивание стека, а выравнивание параметров в стеке. Очень долго я ругался тогда :))
Очень многим функциям это надо17.03.04 22:06 Автор: amirul <Serge> Статус: The Elderman
> Если при выровненном по DWORD указателе стека (регистр ESP) > в стек засунуть слово (WORD - 16бит), а потом вызвать > правильно оформленную функцию CreateFile или OpenFile, то > эти функция вернет -1 (INVALID_HANDLE_VALUE = 0xffffffff) В частности в свое время у меня таким образом не захотела работать LoadLibrary с совершенно непонятной ошибкой вылетала. Я целый день потратил только чтобы найти этот баг
:))) Я потратил почти два дня.17.03.04 22:34 Автор: Den <Денис Т.> Статус: The Elderman
У меня из главной процедуры вызывается процедурка в которой сначала делается:
push eax
push edx
push ecx
push ebx
pushf ; ! - ! - ! - ! - ! - ! младшие 16бит регистра флагов - WORD
а потом invoke CreateFile, .....
Вот я попарился...
Пока разобрался в чем проблема, все маты на M$ сложил.
А у меня __declspec(naked)18.03.04 00:38 Автор: amirul <Serge> Статус: The Elderman
Писал полиморфиный загрузчик-расшифровщик и в самом конце при переходе на реальную Entry Point меня совершенно не устраивало стандартное закрытие стекового фрейма. Но в то же время писать ВСЕ на асме не хотелось, а в C без локальных переменных - жисть не жисть.
Ну и сделал
push ebp
mov ebp,esp
sub esp,250
Если бы в последней команде случайно поставил чего нить кратное 4-м - и не узнал бы.
Компилятор masm32 сделал бы add esp, 0fffffffah18.03.04 12:08 Автор: Den <Денис Т.> Статус: The Elderman Отредактировано 18.03.04 12:09 Количество правок: 1
Я здесь уже писал, что GetPixell под VC-шным отладчиком для не 24 битных контекстов возвращает ffffffff. По-крайней мере, под 98-й. Я думал, что это и в правду, так. Из-за этого свой графический редактор писать бросил.
Пока не залез в Фотошоп декомпилером и не обнаружил, что он везде Get/SetPixel юзает!
Ну ё.... т....... м....., людям уже и в справку в лом заглянуть. Уязвимость блин они нашли....
Берем SDK, читаем:
Register saving conventions
Procedures and functions must preserve the EBX, ESI, EDI, and EBP registers,
but can modify the EAX, EDX, and ECX registers. When implementing a
constructor or destructor in assembler, be sure to preserve the DL register.
Procedures and functions are invoked with the assumption that the CPU's
direction flag is cleared (corresponding to a CLD instruction) and must return
with the direction flag cleared.
---
Для особо одаренных: std и cld - взаимно обратные ф-ции.
Ну и че дальше-то???11.03.04 15:49 Автор: Den <Денис Т.> Статус: The Elderman
> Register saving conventions
> Procedures and functions must preserve the EBX, ESI, EDI,
> and EBP registers,
> but can modify the EAX, EDX, and ECX registers. When
> implementing a
> constructor or destructor in assembler, be sure to preserve
> the DL register.
---
1. Вообще-то это соглашение для stdcall функций. А причем здесь ошибка доступа к памяти в kernel32?
2. Я разве сказал, что программирую на АСМе в Си? Я вообще хоть слово сказал об ООП? Так с какого хрена этот флейм?
> Procedures and functions are invoked with the assumption
> that the CPU's
> direction flag is cleared (corresponding to a CLD
> instruction) and must return
> with the direction flag cleared.
>
---
> Для особо одаренных: std и cld - взаимно обратные ф-ции.
Мля ты серьезно что-ли??? Ну спасибо!!! Безценная информация, как раз для моего случая!
Выходит, что WinAPI-функции предполагают, что флаг направления должен быть сброшен.
Взгляни например на код функции lstrcatA в kernel32.dll. В WinXP она просто делает rep movsd, и никакаих манипуляций c флагом направления. Наверняка так себя ведет не только lstrcatA...
А кто мне объяснит в чем смысл такого предположения M$?11.03.04 17:24 Автор: Den <Денис Т.> Статус: The Elderman
__asm
{
mov edi, ExitProcess
xor eax, eax
push eax
std
call edi
}
Странно... У меня тоже SP4, только SRV ENG09.03.04 12:25 Автор: Den <Денис Т.> Статус: The Elderman Отредактировано 09.03.04 12:37 Количество правок: 1
xor eax, eax> push eax
> call ... ; call на jmp dword ptr в kernel32.dll !
> ExitProcess
---
А подробнее? Например такая запись в асме вижуала
call ExitProcess не приводит к синтаксической ошибке но получаем изнасилование доступа. В дизасме видно что вместо вызова ExitProcess там идет вызов какой то фигни а ExitProcess отсутствует даже а таблице импортирта. И вообще имхо забывать обрабатывать флаги - это уже слишком. И делается это не программерами а компилятором генерирующим код функции, а такую дыру в вижуале давно бы нашли.
ASM не вижуал, а самый обычный masm32 v6.14.844409.03.04 14:46 Автор: Den <Денис Т.> Статус: The Elderman
Исходники моей программы по некоторым причинам приводить не хочу, хотя бы потому, что 30Kb чистой мнемоники.
Пробовал разными путями получить ошибку, вылезающую в моей программе и написал маленькую программульку имитирующую вызов Win32API при котором происходит ошибка (востановил контекст регистров и младшие 16 бит регистра флагов). К сожалению требуемого результата не достиг, буду копать дальше, может удастся выделить условия возникновения ошибки.
Вот код имитирующей программы:
.386
.model flat,stdcall
option casemap:none
include windows.inc
include kernel32.inc
includelib kernel32.lib
.data
db 2800h DUP (0)
.code
TestSTD PROC
LOCAL hStdout :DWORD
mov eax, 3d2eh
mov ebx, 4039b0h
mov ecx, 14h
mov edx, 14h
mov edi, 4039afh
mov esi, 132559h
pushf
pop ax
mov ax, 246h
push ax
popf
; xor eax, eax
;std
push dword ptr 0
call ExitProcess
; invoke ExitProcess, eax
ret
TestSTD ENDP
end TestSTD
---
В стек заталкивается двойное слово по адресу ds:[0] =)
09.03.04 16:42 Автор: :-) <:-)> Статус: Elderman