• XSS.stack #1 – первый литературный журнал от юзеров форума

FASM передача переменных в GetVolumeInformationA через стек

haxking

HDD-drive
Пользователь
Регистрация
21.06.2023
Сообщения
45
Реакции
6
Приветствую! Начинаю более боевое изучение ASM, пробую написать запросы для получения информации о системе через WinAPI, не могу разобраться с передачей параметров в функцию через стек. Например, передать два параметра в GetComputerNameA не составляет никаких проблем invoke GetComputerNameA, eax, ebx, но для передачи/получения данных используя GetVolumeInformationA не достаточно свободных регистров, потому приходится загонять в стек:

Код:
 lea eax, [VolumeName]
 lea ebx, [VolumeSerialNumber]
 lea ecx, [FileSystemFlags]
 lea edx, [FileSystemName]
 push edx
 push ecx
 push ebx
 push eax
 push 260
 lea eax, [VolumePathName]
 lodstra 'C:\'
 push eax
 call GetVolumeInformationA
 test eax, eax
после пробую сверить с заранее записанной в коде строкой (данный код отрабатывает с GetComputerNameA):
Код:
lea ebx, [String]
lodstra '00000-00000.....' ; bad serial number
lea eax, [VolumeSerialNumber]
cinvoke strcmp, eax, ebx
test eax, eax
jz stop_app

но всё безрезультатно, данный код не отрабатывает как надо, не могу понять как правильно провести работу с регистрами. Прошу помощи на форуме.
 
Что выдаёт GetLastError? У тебя всего 6 инструкций push, если lodstra кладёт строку на стек то 7, у GetVolumeInformationA 8 аргументов. Скинь полный код, без отладчика тяжело понять, что не так.
 
но для передачи/получения данных используя GetVolumeInformationA не достаточно свободных регистров, потому приходится загонять в стек:
Если проблема в invoke, то ему можно передавать локальные и глобальные переменные (для локальных надо указать явно перед именем addr или взять в квадратные скобки) вот пример:

Код:
proc GetInfo
  locals
     lpMaximumComponentLength dd ?
     lpFileSystemFlags dd ?
     lpVolumeSerialNumber dd ?
  endl

  invoke GetVolumeInformationA, lpRootPath,lpVolumeNameBuffer,260,[lpVolumeSerialNumber],[lpMaximumComponentLength],\
                               [lpFileSystemFlags],lpFileSystemNameBuffer,260  
 endp

section '.data' data readable writeable
  lpRootPath db 'C:\',0
  lpFileSystemNameBuffer db 260 dup(0)
  lpVolumeNameBuffer db 260 dup(0)

Если по какой-то причине не хочется юзать инвок, то и одного регистра достаточно

Код:
proc GetInfo
  locals
     lpMaximumComponentLength dd ?
     lpFileSystemFlags dd ?
     lpVolumeSerialNumber dd ?
  endl

  push 260
 
  lea eax,[lpFileSystemNameBuffer]
  push eax
 
  lea eax,[lpFileSystemFlags]
  push eax
 
  lea eax,[lpMaximumComponentLength]
  push eax
 
  lea eax,[lpVolumeSerialNumber]
  push eax
 
  push 260
 
  lea eax,[lpVolumeNameBuffer]
  push eax
 
  lea eax,[lpRootPath]
  push eax
 
  call [GetVolumeInformationA]

  ret
endp
 
Если проблема в invoke, то ему можно передавать локальные и глобальные переменные (для локальных надо указать явно перед именем addr или взять в квадратные скобки) вот пример:
в квадратных скобках передаётся значение переменной а не адрес на неё

Syntax:
BOOL GetVolumeInformationA(
[in, optional] LPCSTR lpRootPathName,
[out, optional] LPSTR lpVolumeNameBuffer,
[in] DWORD nVolumeNameSize,
[out, optional] LPDWORD lpVolumeSerialNumber,
[out, optional] LPDWORD lpMaximumComponentLength,
[out, optional] LPDWORD lpFileSystemFlags,
[out, optional] LPSTR lpFileSystemNameBuffer,
[in] DWORD nFileSystemNameSize
);

таким образом правильно не так:

invoke GetVolumeInformationA, lpRootPath,lpVolumeNameBuffer,260,[lpVolumeSerialNumber],[lpMaximumComponentLength],\
[lpFileSystemFlags],lpFileSystemNameBuffer,260

а так

Код:
invoke GetVolumeInformationA, lpRootPath,lpVolumeNameBuffer,addr lpVolumeSerialNumber,addr lpMaximumComponentLength,\
                               addr lpFileSystemFlags,lpFileSystemNameBuffer,260
 
Пожалуйста, обратите внимание, что пользователь заблокирован
в квадратных скобках передаётся значение переменной а не адрес на неё
В квадратных скобках указан адрес ячейки памяти, с содержимым которой уже и работает инструкция.
Тоесть, манипуляция происходит по адресу, указанному в скобках.
 
Вариант с запросом имени тома и выводом на консоль:

C-подобный:
format   pe console
include 'win32ax.inc'
entry    start
;//------------
.data
PathName       rb  8     ;// буфер под имя тома - пример С:\
VolName        rb  16    ;// буфер под метку тома
FSName         rb  16    ;// буфер под имя FS
VolSN          dd  0     ;// под указатель на серийник
MaxLen         dd  0     ;// под указатель на макс.длину имени файлов
FSflags        dd  0     ;// флаги FS
;//------------
.code
start:  cinvoke  printf,<10,' Vol name: ',0>
        cinvoke  scanf,<'%s',0>,PathName

         invoke  GetVolumeInformation, PathName, VolName,16,\
                                       VolSN, MaxLen, FSflags, FSName,16
         invoke  CharToOem,VolName,VolName
         mov     eax,[VolSN]
         mov     ebx,eax
         shr     eax,16
         and     ebx,0xffff
        cinvoke  printf, <10,' Volume Info',\
                          10,' ----------------',\
                          10,' Label    :  %s',\
                          10,' Serial   :  %04X-%04X',\
                          10,' FSystem  :  %s',\
                          10,' fName len:  %d',\
                          10,' FS flags :  %08X',0>,\
                          VolName,eax,ebx,FSName,[MaxLen],[FSflags]
        cinvoke  getch
        cinvoke  exit,0
;//------------
section '.idata' import data readable
library kernel32,'kernel32.dll',user32,'user32.dll',msvcrt,'msvcrt.dll'
import  msvcrt,printf,'printf',scanf,'scanf',getch,'_getch',exit,'exit'
include 'api\kernel32.inc'
include 'api\user32.inc'

VolInfo.jpg
 


Напишите ответ...
  • Вставить:
Прикрепить файлы
Верх