Проблема Ассемблер. Проблема

  • Автор темы Автор темы Gemfory
  • Дата начала Дата начала

Gemfory

Green Team
03.01.2026
22
8
Специализация
  1. Реверс-инжиниринг
  2. Анализ ВПО
Разрабатываю собственный протектор с реализацией виртуализации инструкций.
На этапе инициализации возникла проблема, программа успешно находит целевой файл, но отказывается выполнять его маппинг в адресное пространство процесса, уже минут 30 не могу понять в чем проблема.
Был бы благодарен, если бы кто-то помог решить данную проблему
1774690743584.webp


C:
_MAP_FILE_TO_MEMORY:
            lea        rcx, [array]
            mov        rdx, 80000000h 
            mov        r8, 1         
            xor        r9, r9
            mov        qword [rsp + 20h], 3 
            mov        qword [rsp + 28h], 80h 
            mov        qword [rsp + 30h], 0
            call    [CreateFileA]

            cmp        rax, -1
            je        _FATAL_ERROR
            mov        [hFile], rax
            mov        r14, rax

            mov        rcx, r14
            xor        rdx, rdx
            mov        r8d, 2         
            xor        r9d, r9d
            mov        qword [rsp + 20h], 0
            mov        qword [rsp + 28h], 0
            call    [CreateFileMappingA]

            test    rax, rax
            jz        _FATAL_ERROR
            mov        [hMap], rax

            mov        rcx, rax
            mov        edx, 4     
            xor        r8d, r8d
            xor        r9d, r9d
            mov        qword [rsp + 20h], 0
            call    [MapViewOfFile]

            test    rax, rax
            jz        _FATAL_ERROR
            mov        [pMap], rax
            mov        r13, rax

            lea        rcx, [mapping_ok]
            call    [printf]

            jmp        _PARSE_PE_HEADER
C:
format PE64 console
entry start
include 'win64a.inc'


; const
INVALID_FILE_ATTRIBUTES equ -1
;-----
section '.data' data readable writeable
inputs db "Please specify the full path to the file: ", 0
fmt_path db '%[^\n]s', 0
; ----
msg_ok  db 27, '[92m[GOOD]', 27, '[0m File accepted for processing! Compiling...', 10, 0
msg_bad db 27, '[91m[ERROR]', 27, '[0m This file does not exist or you have specified an incorrect path!', 10, 0
; ----
msg_no_mapping db 27, '[91m[ERROR]', 27, '[0m The file could not be mapped!', 10, 0
mapping_ok db 27, '[92m[GOOD]', 27, '[0m [+] File mapping...', 10, 0

section '.bss' readable writeable
hFile        dq    ?
hMap        dq    ?
pMap        dq    ?
dwSize        dd    ?
dwMode        dd    ?
hOut        dq    ?
array        rb    260

section '.code' code readable executable
start:
            sub     rsp, 48h
            mov     rcx, -11
            call    [GetStdHandle]
            mov     [hOut], rax

            mov     rcx, [hOut]
            mov     rdx, dwMode
            call     [GetConsoleMode]

            mov     rcx, [hOut]
            mov     edx, [dwMode]
            or         edx, 4
            call    [SetConsoleMode]
        ; --- ---
            lea     rcx, [inputs]
            call    [printf]
          
            lea     rcx, [fmt_path]
            lea     rdx, [array]   
            call    [scanf]
          
            lea     rcx, [array]
            call     [GetFileAttributesA]
          
            cmp        eax, INVALID_FILE_ATTRIBUTES
            je      file_not_found
          
        ; -----
            lea     rcx, [msg_ok]
            call    [printf]
            call    [_getch]
          
_MAP_FILE_TO_MEMORY:
            lea        rcx, [array]
            mov        rdx, 80000000h 
            mov        r8, 1         
            xor        r9, r9
            mov        qword [rsp + 20h], 3 
            mov        qword [rsp + 28h], 80h 
            mov        qword [rsp + 30h], 0
            call    [CreateFileA]

            cmp        rax, -1
            je        _FATAL_ERROR
            mov        [hFile], rax
            mov        r14, rax

            mov        rcx, r14
            xor        rdx, rdx
            mov        r8d, 2         
            xor        r9d, r9d
            mov        qword [rsp + 20h], 0
            mov        qword [rsp + 28h], 0
            call    [CreateFileMappingA]

            test    rax, rax
            jz        _FATAL_ERROR
            mov        [hMap], rax

            mov        rcx, rax
            mov        edx, 4     
            xor        r8d, r8d
            xor        r9d, r9d
            mov        qword [rsp + 20h], 0
            call    [MapViewOfFile]

            test    rax, rax
            jz        _FATAL_ERROR
            mov        [pMap], rax
            mov        r13, rax

            lea        rcx, [mapping_ok]
            call    [printf]

            jmp        _PARSE_PE_HEADER
_FATAL_ERROR:
            lea     rcx, [msg_no_mapping]
            call     [printf]
            jmp     _CLEANUP
          
_CLEANUP:
            mov     rcx, [pMap]
            test    rcx, rcx
            jz      @f
            call    [UnmapViewOfFile]
        @@:
            mov     rcx, [hMap]
            test    rcx, rcx
            jz      @f
            call    [CloseHandle]
        @@:
            mov     rcx, [hFile]
            test    rcx, rcx
            jz      @f
            call    [CloseHandle]
        @@:
            call    [_getch]
            xor     rcx, rcx
            call    [ExitProcess]
_PARSE_PE_HEADER:
          
file_not_found:
            lea     rcx, [msg_bad]
            call     [printf]
            call     [_getch]
          
            add        rsp, 48h
            ret
      
section '.idata' import data readable
    library kernel32, 'kernel32.dll', \
            msvcrt,   'msvcrt.dll'

    import kernel32, \
           GetStdHandle,        'GetStdHandle', \
           GetConsoleMode,      'GetConsoleMode', \
           SetConsoleMode,      'SetConsoleMode', \
           ExitProcess,         'ExitProcess', \
           GetFileAttributesA,  'GetFileAttributesA', \
           CreateFileA,         'CreateFileA', \
           CreateFileMappingA,  'CreateFileMappingA', \
           MapViewOfFile,       'MapViewOfFile', \
           UnmapViewOfFile,     'UnmapViewOfFile', \
           CloseHandle,         'CloseHandle', \
           GetFileSize,         'GetFileSize'

    import msvcrt, \
           printf,  'printf', \
           _getch,  '_getch', \
           scanf,   'scanf', \
           gets,    'gets'
 
GetLastError() что говорит?
Вот процедура, которая покажет код ошибки в читабельном виде - вставьте её вызов после MapViewOfFile(), и узнаете проблему.

C-подобный:
proc  GetError
        push    rax
        invoke  GetLastError
        invoke  FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,0,eax,0,errBuff,128,0
        invoke  MessageBox,0, errBuff, 0,0
        pop     rax
        ret
endp
 
GetLastError() что говорит?
Вот процедура, которая покажет код ошибки в читабельном виде - вставьте её вызов после MapViewOfFile(), и узнаете проблему.

C-подобный:
proc  GetError
        push    rax
        invoke  GetLastError
        invoke  FormatMessage,FORMAT_MESSAGE_FROM_SYSTEM,0,eax,0,errBuff,128,0
        invoke  MessageBox,0, errBuff, 0,0
        pop     rax
        ret
endp
Пишет ошибка прав доступа, странно.
Пробовал запускать от имени администратора, программа которая маппится написана мною
OneDrive отключен
 

Вложения

  • generr.pdf
    generr.pdf
    287,9 КБ · Просмотры: 53
Сомнительно, что это сработает так, как вы предполагаете.

З. Ы. Вообще говоря, подобные ошибки лучше смотреть в отладчике.
Вроде как реализация с fmt работает идеально
А в отладчике бы показало что-то вроде "Ошибка. Нет прав доступа"
 
Вот преобразование вашего исходного кода с ошибкой в псевдокод с явным указанием всех аргументов:

Код:
FUNCTION MapFileToMemory():
    // Подготовка стека для shadow space (4 регистра = 32 байта + 8 байт выравнивания)
    // В оригинале нет выделения места на стеке!
    
    // Вызов CreateFileA
    hFile = CreateFileA(
        lpFileName = &array,                    // указатель на имя файла
        dwDesiredAccess = 0x80000000,           // GENERIC_READ (только чтение)
        dwShareMode = 1,                        // FILE_SHARE_READ
        lpSecurityAttributes = NULL,             // нет атрибутов безопасности
        dwCreationDisposition = 3,               // OPEN_EXISTING (открыть существующий)
        dwFlagsAndAttributes = 0x80,             // FILE_ATTRIBUTE_NORMAL
        hTemplateFile = NULL                     // нет шаблона
    )
    
    IF hFile == INVALID_HANDLE_VALUE (-1) THEN
        GOTO _FATAL_ERROR
    END IF
    
    Store hFile in [hFile] and r14
    
    // Вызов CreateFileMappingA
    hMap = CreateFileMappingA(
        hFile = r14,                            // хэндл открытого файла
        lpAttributes = NULL,                    // атрибуты безопасности
        flProtect = 2,                          // PAGE_READONLY (только чтение!)
        dwMaximumSizeHigh = 0,
        dwMaximumSizeLow = 0,                   // размер = размер файла
        lpName = NULL                           // без имени
    )
    
    IF hMap == NULL THEN
        GOTO _FATAL_ERROR
    END IF
    
    Store hMap in [hMap]
    
    // Вызов MapViewOfFile
    pView = MapViewOfFile(
        hFileMappingObject = hMap,              // хэндл отображения
        dwDesiredAccess = 4,                    // FILE_MAP_WRITE (ЗАПИСЬ!) ⚠️
        dwFileOffsetHigh = 0,
        dwFileOffsetLow = 0,                    // с начала файла
        dwNumberOfBytesToMap = 0                 // весь файл
    )
    
    IF pView == NULL THEN
        GOTO _FATAL_ERROR
    END IF
    
    RETURN pView
    
_FATAL_ERROR:
    // Обработка ошибки
    RETURN NULL
END FUNCTION

## Ключевое противоречие (причина ERROR_ACCESS_DENIED):

Код:
CreateFile:           GENERIC_READ (только чтение)
                     ↓
CreateFileMapping:    PAGE_READONLY (страницы только для чтения)
                     ↓
MapViewOfFile:        FILE_MAP_WRITE (ЗАПИСЬ!) ❌ НЕСОВМЕСТИМО!

## Исправленный вариант (для чтения):

Код:
FUNCTION MapFileToMemory_ReadOnly():
    // Выделяем shadow space
    AllocateStack(40h)
    
    hFile = CreateFileA(
        lpFileName = &array,
        dwDesiredAccess = GENERIC_READ,         // 0x80000000
        dwShareMode = FILE_SHARE_READ,          // 1
        lpSecurityAttributes = NULL,
        dwCreationDisposition = OPEN_EXISTING,  // 3
        dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL, // 0x80
        hTemplateFile = NULL
    )
    
    IF hFile == INVALID_HANDLE THEN GOTO Error
    
    hMap = CreateFileMappingA(
        hFile = hFile,
        lpAttributes = NULL,
        flProtect = PAGE_READONLY,              // 2
        dwMaximumSizeHigh = 0,
        dwMaximumSizeLow = 0,
        lpName = NULL
    )
    
    IF hMap == NULL THEN GOTO ErrorCloseFile
    
    pView = MapViewOfFile(
        hFileMappingObject = hMap,
        dwDesiredAccess = FILE_MAP_READ,        // 2 (исправлено!)
        dwFileOffsetHigh = 0,
        dwFileOffsetLow = 0,
        dwNumberOfBytesToMap = 0
    )
    
    IF pView == NULL THEN GOTO ErrorCloseMap
    
    FreeStack(40h)
    RETURN pView
    
ErrorCloseMap:
    CloseHandle(hMap)
ErrorCloseFile:
    CloseHandle(hFile)
Error:
    FreeStack(40h)
    RETURN NULL
END FUNCTION

## Таблица соответствия прав доступа:

| Режим | CreateFile | CreateFileMapping | MapViewOfFile |
|-------|------------|-------------------|---------------|
| Только чтение | GENERIC_READ | PAGE_READONLY (2) | FILE_MAP_READ (2) |
| Чтение/Запись | GENERIC_READ \| GENERIC_WRITE | PAGE_READWRITE (4) | FILE_MAP_WRITE (4) |
| Копирование при записи | GENERIC_READ | PAGE_WRITECOPY (8) | FILE_MAP_COPY (1) |

Проблема в вашем коде: при открытии файла только для чтения, вы пытаетесь получить отображение с правами на запись (FILE_MAP_WRITE), что система не позволяет сделать, возвращая ERROR_ACCESS_DENIED.
 
Сомнительно, что это сработает так, как вы предполагаете.
Вроде как реализация с fmt работает идеально
А в отладчике бы показало что-то вроде "Ошибка. Нет прав доступа"
Замените
на
fmt_path db '%[^',10,']s', 0
и будет вам счастье.

А недоинтеллект в очередной раз облажался. Почему-то я не удивлён.
 
А недоинтеллект в очередной раз облажался. Почему-то я не удивлён.

В чем облажался, предполагается что файл открывается: GetFileAttributes() окей.

Из всех апи переход на общий адрес, это может приводить к неопределенности по конкр. апи.
 
В чем облажался
Хотя бы в том, что 4 - это FILE_MAP_WRITE. И, как следствие, - в итоговом диагнозе.
На самом деле 4 означает FILE_MAP_READ.

Верить на слово дипсикам и прочим ГПТ - полный моветон. И ещё больший моветон - публиковать это, не сделав даже элементарную проверку.
 
Хотя бы в том, что 4 - это FILE_MAP_WRITE. И, как следствие, - в итоговом диагнозе.
На самом деле 4 означает FILE_MAP_READ.

Константы конечно нужно проверять:

C-подобный:
#define FILE_MAP_WRITE      SECTION_MAP_WRITE
#define FILE_MAP_READ       SECTION_MAP_READ
#define FILE_MAP_ALL_ACCESS SECTION_ALL_ACCESS

#define SECTION_QUERY       0x0001
#define SECTION_MAP_WRITE   0x0002
#define SECTION_MAP_READ    0x0004
#define SECTION_MAP_EXECUTE 0x0008
#define SECTION_EXTEND_SIZE 0x0010

Отображение секции это заглушка для нэйтив, не содержащая какой либо логики XPSP1/NT/base/win32/client/filemap.c, #375
 
Вроде как реализация с fmt работает идеально
Нет, надо заменить её, как советовал nick8606
В общем вот немного причёсанный ваш код, который исправно мапит указанный файл в память. В отладчике видно, что ошибок нет, а в памяти появляется проекция.

C-подобный:
format  pe64 console
include 'win64ax.inc'
entry   start

;// const
INVALID_FILE_ATTRIBUTES equ -1
;//-----
section '.data' data readable writeable
inputs     db "Please specify the full path to the file: ", 0
fmt_path   db '%[^',10,']s',0

msg_ok     db 27,'[92m[GOOD]', 27,'[0m File accepted for processing! Compiling...',10,0
msg_bad    db 27,'[91m[ERROR]',27,'[0m This file does not exist or you have specified an incorrect path!',10,0

msg_no_mapping  db 27,'[91m[ERROR]',27,'[0m The file could not be mapped!',10,0
mapping_ok      db 27,'[92m[GOOD]', 27,'[0m [+] File mapping...',10,0

section '.bss' readable writeable
hFile      dq   0
hMap       dq   0
pMap       dq   0
dwSize     dd   0
dwMode     dd   0
hOut       dq   0
array      rb   260

section '.code' code readable executable
start:   push    rbp
         invoke  GetStdHandle,-11
         mov     [hOut],rax

         invoke  GetConsoleMode,[hOut],dwMode
         mov     edx,[dwMode]
         or      edx,4
         invoke  SetConsoleMode,[hOut],rdx

        cinvoke  printf,inputs
        cinvoke  scanf,fmt_path,array
         invoke  GetFileAttributes,array
         cmp     eax,INVALID_FILE_ATTRIBUTES
         je      file_not_found
         
        cinvoke  printf,msg_ok
        cinvoke  _getch
         
_MAP_FILE_TO_MEMORY:
         invoke  CreateFile,array,\
                            GENERIC_READ + GENERIC_WRITE,\
                            FILE_SHARE_READ + FILE_SHARE_WRITE,\
                            0,OPEN_EXISTING,0,0
         cmp     rax,-1
         je      _FATAL_ERROR
         mov     [hFile],rax

         invoke  CreateFileMapping,rax,0,\
                            PAGE_READWRITE,\    ;// + SEC_IMAGE = 0x1000000 ?
                            0,0,0
         or      eax,eax
         jz      _FATAL_ERROR
         mov     [hMap],rax

         invoke  MapViewOfFile,rax,\
                            FILE_MAP_READ,0,0,0

         or      rax, rax
         jz      _FATAL_ERROR
         mov     [pMap],rax
         mov     r13, rax
        cinvoke  printf,mapping_ok
         jmp     _PARSE_PE_HEADER

_FATAL_ERROR:
        cinvoke  printf,msg_no_mapping

_CLEANUP:
         mov     rcx,[pMap]
         test    rcx,rcx
         jz      @f
         invoke  UnmapViewOfFile,rcx
         invoke  CloseHandle,rcx

@@:      mov     rcx,[hFile]
         test    rcx,rcx
         jz      @f
         invoke  CloseHandle,rcx
@@:     cinvoke  _getch
         invoke  ExitProcess,0

_PARSE_PE_HEADER:
        cinvoke  printf,<10,' Mapping OK!'>
         jmp     @b

file_not_found:
        cinvoke  printf,msg_bad
        cinvoke  _getch
         invoke  ExitProcess,0
;//-------------------------

section '.idata' import data readable
library  kernel32,'kernel32.dll', \
         msvcrt,   'msvcrt.dll'

include  'api\kernel32.inc'
import   msvcrt, \
         printf,'printf', scanf,'scanf',\
         _getch,'_getch', gets, 'gets'
 
  • Нравится
Реакции: Gemfory
Мы в соцсетях:

Взломай свой первый сервер и прокачай скилл — Начни игру на HackerLab

🚀 Первый раз на Codeby?
Гайд для новичков: что делать в первые 15 минут, ключевые разделы, правила
Начать здесь →
🔴 Свежие CVE, 0-day и инциденты
То, о чём ChatGPT ещё не знает — обсуждаем в реальном времени
Threat Intel →
💼 Вакансии и заказы в ИБ
Pentest, SOC, DevSecOps, bug bounty — работа и проекты от проверенных компаний
Карьера в ИБ →

HackerLab