Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: win syscall : args  (Прочитано 8014 раз)
0 Пользователей и 1 Гость смотрят эту тему.
0xfadec0de
Интересующийся

ru
Offline Offline

« : 17-11-2009 20:45 » 

Здравствуйте. Всем доброго времени суток.

У меня есть кусочек кода.

Код:
ULONG  ncall = 0x019 // CloseHandle
__declspec(naked)NTSTATUS
__stdcall
syscall(ULONG a1,ULONG a2,ULONG a3,)
{
__asm {
mov eax, ncall
call FastSystemCall
ret 0xс
FastSystemCall:
mov edx, esp
sysenter
ret
}   
}

Собсвенно вопрос: как поведет себя ядерный обработчик при таком  вызове
Код:
syscall(0x28,0xfadec0de,0xffffffff);

Как я понимаю на обработку пойдет только первый аргумент(0x28),  второй и третий  будут "отброшены"?

Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 19-11-2009 19:13 » 

почему? разве они уже не в стеке после вызова syscall по спецификации _stdcall?
в eax - код функции
в edx==esp - вершина стека, где должны быть a1,a2,a3 помещенные в процессе _stdcall функции syscall().
которые по ret 0xC подчищаются вместо стандартного выхода (esp=esp-12)

ЗЫ а вообще изврат) можно было и на asm-e сразу функцию написать)
« Последнее редактирование: 19-11-2009 19:16 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
0xfadec0de
Интересующийся

ru
Offline Offline

« Ответ #2 : 19-11-2009 23:08 » 

Данный кусок кода выполняет вызов системной функции под номером ncall
Например функция с номером 0x19 (WinXP sp3) это CloseHandle. Тоесть вместо CloseHandle
мы можем воспользоваться следующей функцией.

Код:
__declspec(naked)NTSTATUS
__stdcall
syscall(ULONG hnd,)
{
__asm {
mov eax, 0x19 // номер системной функции windows
call FastSystemCall // вызов системной функции
ret 0x4
FastSystemCall:
mov edx, esp  //сохраняем вершину стека (как я понял по edx + 8 лежат наши передаваемые ядру аргументы.
sysenter //быстрый вызов системной процедуры нулевого уровня[tt][/tt]
ret
}   
}

HANDLE hFile;
LPCWSTR fname = L"D:\\tst.txt";
hFile = CreateFile(fname,GENERIC_READ|GENERIC_WRITE,
                            FILE_SHARE_READ,NULL,OPEN_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);       
syscall((ULONG) hFIle); // аналогично CloseHandle(hFile);

Я имел ввиду про обработку аргументов  передаваемых именно ядерному обработчику  при вызове системной функции. Так как CloseHandle принимает только один аргумент , что будет делать ядро если передать еще несколько? IMHO я думаю, что возьмет с вершины нужное кол-во,а остальные проигнорирует. Просто хочу убедится,  поспрашивать у других товарищей Скромно так...
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 20-11-2009 04:50 » 

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

PS а вообще лажа. call - тоже сохраняет данные в стеке. на вскидку не помню, но там кажется большой список регистров был.
PPS и какой смысл в такой функции вообще? все равно два лишних stdcall
PPPS _asm sysenter - вообще разрешена в контексте пользовательского процесса?
« Последнее редактирование: 20-11-2009 04:58 от Ochkarik » Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
0xfadec0de
Интересующийся

ru
Offline Offline

« Ответ #4 : 20-11-2009 06:19 » 

Цитата
PPPS _asm sysenter - вообще разрешена в контексте пользовательского процесса?
Да

Цитата
в стеке все три агрумента есть - есть. (кстати _stdcall - это передача аргументов  справа-налево, если не путаю. так что кто будет первым в стеке?
вызов
Код:
syscall(0x28,0xfadec0de,0xffffffff);
получаем
Код:
будет 
push 0xffffffff
push 0xfadec0de
push 0x28 // будет первым в стеке  на момент
call ...        // вызова call
_stdcall говорит только то что аргументы функции буду передавться только через стек и стек очищает сама функция
Цитата
PS а вообще лажа. call - тоже сохраняет данные в стеке. на вскидку не помню, но там кажется большой список регистров был.
Данные о чем сохраняет call в стеке? Какой еще "большой список регистров"?
Цитата
про CloseHandle - не знаю. по интерфейсу агрумент один, а что внутри - фиг его знает
все сведется к
Код:
MOV EAX,19
MOV EDX,7FFE0300
CALL DWORD PTR DS:[EDX]
RETN 4
где CALL DWORD PTR DS:[EDX]
Код:
MOV EDX,ESP
SYSENTER
RETN
Цитата
если так интересно поставить отладчик, поставить BP на CloseHandle и посмотреть по шагам.
Смотрели , потому и спрашиваем. Если интерестно взгляните тоже.
Цитата
PPS и какой смысл в такой функции вообще? все равно два лишних stdcall
Вызов системной функции без использования каких-либо API-вызовов.
Записан
Ochkarik
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 20-11-2009 15:55 » new

CALL DWORD PTR DS:[EDX]
это не
JMP DWORD PTR DS:[EDX]

Цитата
Команда call прямого ближнего вызова заносит в стек относительный адрес точки возврата в текущем программном сегменте и модифицирует IP так, чтобы в нем содержатся относительный адрес точки перехода в том же программном сегменте. Необходимая для вычисления этого адреса величина смещения от точки возврата до точки перехода содержится в коде команды, который занимает 3 байт (код операции E8h и смещение к точке перехода).

Команда call прямого дальнего вызова заносит в стек два слова - сначала сегментный адрес текущего программного сегмента, а затем (выше, в слово с меньшим адресом) относительный адрес точки возврата в текущем программном сегменте. Далее модифицируются регистры IP и CS: в IP помещается относительный адрес точки перехода в том сегменте, куда осуществляется переход, а в CS - сегментный адрес этого сегмента. Обе эти величины берутся из кода команды, который занимает 5 байтов (код операции 9А1г, относительный адрес вызываемой подпрограммы и ее сегментный адрес).

Косвенные вызовы отличаются тем, что адрес перехода извлекается не из кода команды, а из ячеек памяти; в коде команды содержится информация о том, где находится адрес вызова. Длина кода команды зависит от используемого способа адресации.
PS ну действительно не большой список) это я с чем то еще перепутал.
Записан

RTFM уже хоть раз наконец!  RTFM :[ ну или хотя бы STFW...
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines