• ! Привет посетитель !

    Зачем данный ресурс нужен ?

    В рунете было много ресурсов с интересными обсуждениями и работами по вирусным технологиям, а также в область ИБ.

    Но со временем у людей меняются интересы, а кто-то просто не может держать такие сайты, сайты удаляются, я подумал а печему-бы не сделать такой архив со статьями на тематику вирусов и ИБ.

    Цель ресурса:

    Собрать какие-то актуальные утеренные обсуждения и работы.

    Пока-что поднял два сайта:

    1) https://archivevx.net/exelab/f/

    2)Vxlab.info - Тут просто сделаю перепост статей сюда:https://archivevx.net/index.php?forums/vxlab-info-Статьи-ресурса.4/

Создаём скрытый TeamViewer #3

Настало время наполнить нашу DLL кодом!

Для начала преобразуем проект Visual Studio под DLL, для этого изменим Makefile:
Код:
CFLAGS=/c /GS- /MT
LDFLAGS=/DLL /SUBSYSTEM:WINDOWS,"5.1"
NAME=
INCPATH=/I.
LIBPATH=
SRC=main.c
OBJ=main.obj
LIBS=
NAME=Version.dll

all:
cl.exe $(CFLAGS) $(SRC) $(INCPATH)
link.exe $(LDFLAGS) $(LIBS)  $(OBJ) /DEF:Version.def $(LIBPATH) /OUT:Version.dll


bdebug:
cl.exe $(CFLAGS) /Zi $(SRC) $(INCPATH)
link.exe $(LDFLAGS) $(LIBS)  $(OBJ) /DEF:Version.def $(LIBPATH) /DEBUG /OUT:Version.dll

Заметьте, появились новые флаги:

/DLL — говорит link.exe собирать динамическую библиотеку
/DEF:Version.def — в файле размещаются функции, которые будет экспортировать наша библиотека

Файл Version.def пока не имеет функций, это лишь только заготовка:
Код:
LIBRARY   Version.dll

main.c
Код:
#include <Windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
    // Perform actions based on the reason for calling.
    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
            break;

        case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

        case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

        case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

Нажимаем в F7 и наша DLL скомпилирована.

Начинаем новые эксперименты, подкидываем полученную Version.dll к распакованному TeamViewer (в папку tvfiles) и запускаем TeamViewer.exe.

Получаем ошибку при загрузке Version.dll

1608890267490.png


Эти ошибки означают то что загрузчик не смог найти в экспорте Version.dll нужных функций. Удовлетворим потребность Windows загрузчика! Для этого:
  1. Объявляем функцию с таким же названием как в ошибке
  2. В теле функции получаем адрес оригинальной и вызываем её
Код который получает адрес оригинальной функции:
Код:
VOID *GetAPI(char *lib,char *name)
{
HMODULE mod;
CHAR path[MAX_PATH];
CHAR fname[MAX_PATH];
GetSystemDirectoryA(path,MAX_PATH);
sprintf(fname,"%s\\%s",path,lib);
mod=LoadLibraryA(fname);
if (mod)
{
return GetProcAddress(mod,name);
}
return 0;
}

На вход функции GetAPI подается два параметра lib — имя библиотеки, name — имя функции. LoadLibraryA загружает динамическую библиотеку по абсолютному пути, тем самым мы избегаем hijacking.

Рассмотрим этот процесс по шагам:
  1. Запоминаем название функции из сообщения об ошибке (например, GetFileVersionInfoSizeW)
  2. Гуглим «GetFileVersionInfoSizeW msdn» link
  3. Смотрим в каком заголовочном файле (header) объявлена наша функция — Windows.h
  4. Вписываем слово GetFileVersionInfoSizeW в DllMain и нажимаем F12 (Go To Definition), тем самым переходя на ее объявление.
Код:
DWORD
APIENTRY
GetFileVersionInfoSizeW(
        __in        LPCWSTR lptstrFilename, /* Filename of version stamped file */
        __out_opt LPDWORD lpdwHandle       /* Information for use by GetFileVersionInfo */
        );

5.Копируем объявление функции и вставляем в main.c:

Код:
DWORD
(APIENTRY
*fGetFileVersionInfoSizeW)(
        __in        LPCWSTR lptstrFilename, /* Filename of version stamped file */
        __out_opt LPDWORD lpdwHandle       /* Information for use by GetFileVersionInfo */
        );


DWORD
APIENTRY
GetFileVersionInfoSizeW(
        __in        LPCWSTR lptstrFilename, /* Filename of version stamped file */
        __out_opt LPDWORD lpdwHandle       /* Information for use by GetFileVersionInfo */
        )
{
fGetFileVersionInfoSizeW=GetAPI("VERSION.dll","GetFileVersionInfoSizeW");
if (!fGetFileVersionInfoSizeW)
{
return 0;
}
return fGetFileVersionInfoSizeW(lptstrFilename,lpdwHandle);
}

6.Добавляем имя функции GetFileVersionInfoSizeW в Version.def:
Код:
LIBRARY   Version.dll
EXPORTS
GetFileVersionInfoSizeW

7.Компилируем по F7, и убеждаемся что нет ошибок.

8.Повторяем до получения рабочей библиотеки =)

В результате данной работы вы получите следующий код:

main.c
Код:
#include <Windows.h>
#include <Winternl.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
 
 
VOID *GetAPI(char *lib,char *name)
{
HMODULE mod;
CHAR path[MAX_PATH];
CHAR fname[MAX_PATH];
GetSystemDirectoryA(path,MAX_PATH);
sprintf(fname,"%s\\%s",path,lib);
mod=LoadLibraryA(fname);
if (mod)
{
return GetProcAddress(mod,name);
}
return 0;
}
 
 
DWORD
(APIENTRY
*fGetFileVersionInfoSizeW)(
        __in        LPCWSTR lptstrFilename, /* Filename of version stamped file */
        __out_opt LPDWORD lpdwHandle       /* Information for use by GetFileVersionInfo */
        );
 
 
DWORD
APIENTRY
GetFileVersionInfoSizeW(
        __in        LPCWSTR lptstrFilename, /* Filename of version stamped file */
        __out_opt LPDWORD lpdwHandle       /* Information for use by GetFileVersionInfo */
        )
{
fGetFileVersionInfoSizeW=GetAPI("VERSION.dll","GetFileVersionInfoSizeW");
if (!fGetFileVersionInfoSizeW)
{
return 0;
}
return fGetFileVersionInfoSizeW(lptstrFilename,lpdwHandle);
 
}
 
 
BOOL
(APIENTRY
*fGetFileVersionInfoW)(
        __in                LPCWSTR lptstrFilename, /* Filename of version stamped file */
        __reserved          DWORD dwHandle,          /* Information from GetFileVersionSize */
        __in                DWORD dwLen,             /* Length of buffer for info */
        __out_bcount(dwLen) LPVOID lpData            /* Buffer to place the data structure */
        );
 
BOOL
APIENTRY
GetFileVersionInfoW(
        __in                LPCWSTR lptstrFilename, /* Filename of version stamped file */
        __reserved          DWORD dwHandle,          /* Information from GetFileVersionSize */
        __in                DWORD dwLen,             /* Length of buffer for info */
        __out_bcount(dwLen) LPVOID lpData            /* Buffer to place the data structure */
        )
{
fGetFileVersionInfoW=GetAPI("VERSION.dll","GetFileVersionInfoW");
if (!fGetFileVersionInfoW)
{
return 0;
}
return fGetFileVersionInfoW(lptstrFilename,dwHandle,dwLen,lpData);
}
 
BOOL
(APIENTRY
*fVerQueryValueW)(
        __in LPCVOID pBlock,
        __in LPCWSTR lpSubBlock,
        __deref_out_xcount("buffer can be PWSTR or DWORD*") LPVOID * lplpBuffer,
        __out PUINT puLen
        );
 
BOOL
APIENTRY
VerQueryValueW(
        __in LPCVOID pBlock,
        __in LPCWSTR lpSubBlock,
        __deref_out_xcount("buffer can be PWSTR or DWORD*") LPVOID * lplpBuffer,
        __out PUINT puLen
        )
{
fVerQueryValueW=GetAPI("VERSION.dll","VerQueryValueW");
if (!fVerQueryValueW)
{
return 0;
}
return fVerQueryValueW(pBlock,lpSubBlock,lplpBuffer,puLen);
}
 
 
BOOL
(APIENTRY
*fGetFileVersionInfoA)(
        __in                LPCSTR lptstrFilename, /* Filename of version stamped file */
        __reserved          DWORD dwHandle,          /* Information from GetFileVersionSize */
        __in                DWORD dwLen,             /* Length of buffer for info */
        __out_bcount(dwLen) LPVOID lpData            /* Buffer to place the data structure */
        );
BOOL
APIENTRY
GetFileVersionInfoA(
        __in                LPCSTR lptstrFilename, /* Filename of version stamped file */
        __reserved          DWORD dwHandle,          /* Information from GetFileVersionSize */
        __in                DWORD dwLen,             /* Length of buffer for info */
        __out_bcount(dwLen) LPVOID lpData            /* Buffer to place the data structure */
        )
{
fGetFileVersionInfoA=GetAPI("VERSION.dll","GetFileVersionInfoA");
if (!fGetFileVersionInfoA)
{
return 0;
}
return fGetFileVersionInfoA(lptstrFilename,dwHandle,dwLen,lpData);
}
 
 
 
BOOL (APIENTRY *fGetFileVersionInfoExW)(__in DWORD dwFlags,
                                    __in LPCWSTR lpwstrFilename,
                                    __reserved DWORD dwHandle,
                                    __in DWORD dwLen,
                                    __out_bcount(dwLen) LPVOID lpData);
BOOL APIENTRY GetFileVersionInfoExW(__in DWORD dwFlags,
                                    __in LPCWSTR lpwstrFilename,
                                    __reserved DWORD dwHandle,
                                    __in DWORD dwLen,
                                    __out_bcount(dwLen) LPVOID lpData)
{
fGetFileVersionInfoExW=GetAPI("VERSION.dll","GetFileVersionInfoExW");
if (!fGetFileVersionInfoExW)
{
return 0;
}
return fGetFileVersionInfoExW(dwFlags,lpwstrFilename,dwHandle,dwLen,lpData);
}
 
 
DWORD (APIENTRY *fGetFileVersionInfoSizeExA)(__in DWORD dwFlags, __in LPCSTR lpwstrFilename, __out LPDWORD lpdwHandle);
DWORD APIENTRY GetFileVersionInfoSizeExA(__in DWORD dwFlags, __in LPCSTR lpwstrFilename, __out LPDWORD lpdwHandle)
{
fGetFileVersionInfoSizeExA=GetAPI("VERSION.dll","GetFileVersionInfoSizeExA");
if (!fGetFileVersionInfoSizeExA)
{
return 0;
}
return fGetFileVersionInfoSizeExA(dwFlags,lpwstrFilename,lpdwHandle);
 
}
 
DWORD (APIENTRY *fGetFileVersionInfoSizeExW)(__in DWORD dwFlags, __in LPCWSTR lpwstrFilename, __out LPDWORD lpdwHandle);
DWORD APIENTRY GetFileVersionInfoSizeExW(__in DWORD dwFlags, __in LPCWSTR lpwstrFilename, __out LPDWORD lpdwHandle)
{
fGetFileVersionInfoSizeExW=GetAPI("VERSION.dll","GetFileVersionInfoSizeExW");
if (!fGetFileVersionInfoSizeExW)
{
return 0;
}
return fGetFileVersionInfoSizeExW(dwFlags,lpwstrFilename,lpdwHandle);
}
 
 
DWORD
(APIENTRY
*fGetFileVersionInfoSizeA)(
        __in        LPCSTR lptstrFilename, /* Filename of version stamped file */
        __out_opt LPDWORD lpdwHandle       /* Information for use by GetFileVersionInfo */
        );
DWORD
APIENTRY
GetFileVersionInfoSizeA(
        __in        LPCSTR lptstrFilename, /* Filename of version stamped file */
        __out_opt LPDWORD lpdwHandle       /* Information for use by GetFileVersionInfo */
        )
{
fGetFileVersionInfoSizeA=GetAPI("VERSION.dll","GetFileVersionInfoSizeA");
if (!fGetFileVersionInfoSizeA)
{
return 0;
}
return fGetFileVersionInfoSizeA(lptstrFilename,lpdwHandle);
}
 
 
BOOL
(APIENTRY
*fVerQueryValueA)(
        __in LPCVOID pBlock,
        __in LPCSTR lpSubBlock,
        __deref_out_xcount("buffer can be PWSTR or DWORD*") LPVOID * lplpBuffer,
        __out PUINT puLen
        );
 
BOOL
APIENTRY
VerQueryValueA(
        __in LPCVOID pBlock,
        __in LPCSTR lpSubBlock,
        __deref_out_xcount("buffer can be PWSTR or DWORD*") LPVOID * lplpBuffer,
        __out PUINT puLen
        )
{
fVerQueryValueA=GetAPI("VERSION.dll","VerQueryValueA");
if (!fVerQueryValueA)
{
return 0;
}
return fVerQueryValueA(pBlock,lpSubBlock,lplpBuffer,puLen);
}
 
BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
    // Perform actions based on the reason for calling.
    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
            MessageBoxA(0,"I'm Hacker!","Hi",0);
            break;
 
        case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;
 
        case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;
 
        case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}

В DllMain я добавил вывод сообщения — MessageBoxA(0,»I’m Hacker!»,»Hi»,0), которое будет отображаться при успешной загрузке Version.dll

Version.def
Код:
LIBRARY   Version.dll
EXPORTS
GetFileVersionInfoSizeW
GetFileVersionInfoW
VerQueryValueW
VerQueryValueA
GetFileVersionInfoExW
GetFileVersionInfoA
GetFileVersionInfoSizeA
GetFileVersionInfoSizeExW
GetFileVersionInfoSizeExA

Makefile
Код:
CFLAGS=/c /GS- /MT
LDFLAGS=/DLL /SUBSYSTEM:WINDOWS,"5.1"
NAME=
INCPATH=/I.
LIBPATH=
SRC=main.c
OBJ=main.obj
LIBS=user32.lib
NAME=Version.dll

all:
cl.exe $(CFLAGS) $(SRC) $(INCPATH)
link.exe $(LDFLAGS) $(LIBS)  $(OBJ) /DEF:Version.def $(LIBPATH) /OUT:Version.dll
copy Version.dll ..\..\tvfiles\Version.dll


bdebug:
cl.exe $(CFLAGS) /Zi $(SRC) $(INCPATH)
link.exe $(LDFLAGS) $(LIBS)  $(OBJ) /DEF:Version.def $(LIBPATH) /DEBUG /OUT:Version.dll
copy Version.dll ..\..\tvfiles\Version.dll

Компилируем и убеждаемся что у Version.dll появился экспорт. Для этого переходим в Far к Version.dll и нажимаем Alt+F4 -> Enter (hex отображение) -> F8 -> F9 (просмотр экспорта) И увидим в Hiew:
1608890518592.png


Забрасываем Version.dll в tvfiles, запускаем TeamViewer.exe и видим сообщение:
1608890536737.png


После нажатия OKей, ошибок c экспортом больше нет, TeamViewer запустился. Это означает что мы подменили функции корректно.

Настраиваем отладку

Для удобной разработки кода в Version.dll нужно настроить отладку в Visual Studio, для этого размещаем распакованный tvfiles рядом с каталогом проекта tv, и в настройках студии прописываем путь до файла TeamViewer.exe

1608890567336.png


При запуске студия скажет, что не нашла символы pdb, и спросит нужно ли исполнять файл, выбираем Yes, и можно поставить галочку что бы окно больше не появлялось.

Теперь мы можем отлаживать код внутри процесса TeamViewer.exe, не правда ли удобно?

1608890601374.png


В следующем выпуске мы научимся перехватывать API функции, и управлять поведением TeamViewer.exe