Форум программистов, компьютерный форум, киберфорум
C++: WinAPI
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
Эксперт WindowsАвтор FAQ
17589 / 7432 / 884
Регистрация: 25.12.2011
Сообщений: 11,227
Записей в блоге: 16
1

Создание удаленного потока

09.09.2015, 01:24. Просмотров 1442. Ответов 2

Приветствую!

Собственно имеется код, который создает поток, подгружающий DLL в чужой процесс:

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "windows.h"
#include "stdio.h"
 
#define LOG_ERR(Func,...) printf("[ERROR]\t" __VA_ARGS__); printf("\r\n" __FUNCTION__ "\t" #Func "  Last error = 0x%.8lx.\r\n", GetLastError())
 
int main(int argc, char *argv[]) 
{
    char* buffer = "h:\\_AVZ\\Наши разработки\\ClearLNK 2.0(2)\\1\\GetAppID.dll";
 
    system("tasklist.exe /nh | sort /r");
 
    printf("\r\nEnter PID: ");
 
    // Get process handle passing in the process ID.
 
    int procID;
    scanf_s("%i", &procID);
 
    HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE, procID);
    if (hProc == NULL) {
        LOG_ERR(OpenProcess, "The specified process couldn't be found.");
        goto ErrorExit;
    }
 
    // Get address of the LoadLibrary function.
    
    LPVOID addr = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
    if (addr == NULL) {
        LOG_ERR(GetProcAddress, "The LoadLibraryA function was not found inside kernel32.dll library.");
        goto ErrorExit;
    }
        
    // Allocate new memory region inside the process's address space.
    
    LPVOID arg = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(buffer), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    if (arg == NULL) {
        LOG_ERR(VirtualAllocEx, "The memory could not be allocated inside the chosen process.");
        goto ErrorExit;
    }
    
    // Write the argument to LoadLibraryA to the process's newly allocated memory region.
    
    int n = WriteProcessMemory(hProc, arg, buffer, strlen(buffer), NULL);
    if (n == 0) {
        LOG_ERR(WriteProcessMemory, "Error: there was no bytes written to the process's address space.");
        goto ErrorExit;
    }
 
    // Inject our DLL into the process's address space.
    
    HANDLE threadID = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)addr, arg, NULL, NULL);
    if (threadID == NULL) {
        LOG_ERR(CreateRemoteThread, "The remote thread could not be created");
    } else {
        printf("Success: the remote thread was successfully created.\r\n");
    }
    
    // Close the handle to the process, becuase we've already injected the DLL.
    
    CloseHandle(hProc);
    getchar();
    getchar();
 
    return EXIT_SUCCESS;
 
ErrorExit:
 
    if (hProc) CloseHandle(hProc);
    getchar();
    getchar();
 
    return EXIT_FAILURE;
}


И сама DLL:

Кликните здесь для просмотра всего текста
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include "stdafx.h"
#include "windows.h"
#include "stdio.h"
#include "Shobjidl.h"
 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    PWSTR AppID;
    HRESULT hRes;
    FILE *file;
    fopen_s(&file, "h:\\_AVZ\\Наши разработки\\ClearLNK 2.0(2)\\1\\my.log", "a+");
 
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        fprintf(file, "DLL process attach function called.\n");
        
        hRes = GetCurrentProcessExplicitAppUserModelID(&AppID);
 
        if (S_OK == hRes) {
            fprintf(file, "\r\n%ls\r\n", AppID);
        } else {
            fprintf(file, "Cannot obtain Current process' AppUserModelID. HRESULT code = 0x%.8lx\r\n", hRes);
        }
        break;
    case DLL_THREAD_ATTACH:
        fprintf(file, "DLL thread attach function called.\n");
        break;
    case DLL_THREAD_DETACH:
        fprintf(file, "DLL thread detach function called.\n");
        break;
    case DLL_PROCESS_DETACH:
        fprintf(file, "DLL process detach function called.\n");
        break;
    }
    
    fclose(file);
 
    return TRUE;
}


Для некоторых процессов (например, AkelPad) нормально пишется лог:

DLL process attach function called.
Alex.Dragokas.ClearLNK
DLL thread detach function called.
DLL process detach function called.
Для других:
DLL выбивает исключение fprint.c - line 55. str != NULL
Ну здесь как обычно где-то в типах или инициализации запутался.

Для третьих (chrome.exe, собственно то, что мне требуется) - поток создается успешно.
LastDllError тоже проверял ( = 0 ), но такое впечатление что код DLL не выполняется, т.к. лог-файл не создается.
Программу запускаю с повышенными привилегиями.

Что можно улучшить, как исправить ошибки?
Спасибо.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
09.09.2015, 01:24
Ответы с готовыми решениями:

Создание удаленного потока
Пытаюсь реализовать простой инжект(VirtualAllocEx,WriteProcessMemory, CreateRemoteThread и т.д)...

Создание удаленного потока
Доброго времени суток. Назрел вопрос в создание потока в адресном пространстве другого процесса....

Создание нового потока из работающего потока
насколько это корректно? вроде всё нормально работает и именно так как задумывалось, но вопрос...

Создание удалённого доступа
Здравствуйте, при создании программы у меня появилась идейка об удалённом доступе, т.е. я написал...

2
Ушел с форума
Эксперт С++
16411 / 7386 / 1184
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
09.09.2015, 10:21 2
Цитата Сообщение от Dragokas Посмотреть сообщение
Для третьих (chrome.exe, собственно то, что мне требуется) - поток создается успешно.
LastDllError тоже проверял ( = 0 ), но такое впечатление что код DLL не выполняется, т.к. лог-файл не создается.
Код, который создает удаленный поток, а также внедряемая dll, должны быть одинаковой с
процессом-"жертвой" разрядности и выполняться с ним в одном и том же сеансе.
Это самое первое.

А не пишет в файл, скорее всего, из-за нехватки прав. Процессы chrome, как и IE в
защищенном режиме, выполняются на уровнях целостности low и untrusted. Чтобы с этих
уровней обращаться к файлам, реестру, процессам и другим объектам, на этих объектах
должна стоять соответствующая разрешающая метка. См. icacls, опция setintegritylevel.
К сожалению, метку "untrusted" эта утилита не понимает, только "low".

Windows Integrity Mechanism Design
https://msdn.microsoft.com/en-... 25963.aspx

Understanding and Working in Protected Mode Internet Explorer
https://msdn.microsoft.com/en-... s.85).aspx

A Developer's Survival Guide to IE Protected Mode
http://www.codeproject.com/Art... ected-Mode

На Windows 8 и выше процессы также могут выполняться в "песочнице" (AppContainer).
В списке разрешений объектов, доступ к которым требуется из процессов-песочниц,
должен быть прописан SID соответствующего AppContainer-а, или, как вариант,
SID "All Application Packages" (S-1-15-2-1).

У Chrome, кстати говоря, вообще очень мощная песочница, не удивляйся, если
даже после загрузки туда dll все равно толком не будет работать:

Sandbox
https://www.chromium.org/devel... ts/sandbox

Для некоторых процессов может быть выставлена защита (Vista Protected Processes или
Protected Processes Light на Windows 8.1 и выше), открыть такие процессы с нужными
для инжекта правами не получится даже из-под администратора или системы, и привилегия
отладки не поможет.

Еще загрузка dll в процесс может блокироваться т.н. "Mitigation Policy", см. здесь:

UpdateProcThreadAttribute function
https://msdn.microsoft.com/en-... s.85).aspx

Например, если для процесса выставлен флаг "FORCE_RELOCATE_IMAGES_ALWAYS_ON_REQ_RELOCS",
то в него возможна только загрузка dll, которые умеют загружаться по произвольному
адресу ("dll rebase", см. опции сборки /DYNAMICBASE (ASLR) и /FIXED:NO в Visual C++).

Цитата Сообщение от Dragokas Посмотреть сообщение
Что можно улучшить
Во-первых, перед работой с процессами всегда полезно попытаться включить привилегию
отладки (SE_DEBUG_NAME).

Во-вторых, в DllMain можно безопасно вызывать только некоторое подможество функций
kernel32.dll и ntdll.dll, но не GetCurrentProcessExplicitAppUserModelID из shell32.dll.
Нет никакой гарантии, что shell32.dll уже проинициализирована на момент вызова и
что вызов не будет связан с работой других потоков процесса, а они на время работы
DllMain не могут создаваться и уничтожаться.

DllMain entry point
https://msdn.microsoft.com/en-... s.85).aspx

Dynamic-Link Library Best Practices
https://msdn.microsoft.com/en-... s.85).aspx

Я бы посоветовал из DllMain вызвать CreateThread/_beginthreadex, и уже в функции
созданного потока проделать всю нужную работу.
0
Эксперт WindowsАвтор FAQ
17589 / 7432 / 884
Регистрация: 25.12.2011
Сообщений: 11,227
Записей в блоге: 16
12.09.2015, 16:51  [ТС] 3
Спасибо за столь развернутый ответ.
Похоже здесь максимум из того, что мне может потребоваться.

Делюсь результатами, на чем остановился... по просьбам из другой темы.

Убедился через Диспетчер задач, что процессы-"жертвы" имеют одинаковую разрядность с DLL и процессом, который ее внедряет (x32).

Понизил уровень целостности контейнера до уровня "Низкий".
По сути проблема № 2 с "вылетом" (это внедрение в iexplore.exe) решилась выведением кода получения UMID в отдельный поток.
Поправил ошибки в "украденном" коде с типами данных и незакрытым хендлом.
Задействовал альтернативные способы обмена данными между процессами:
метюкс, событие, сообщение WM_COPYDATA, запись в файл, создание переменной окружения.

Inject
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
include "windows.h"
#include "stdio.h"
#include "Shobjidl.h"
 
#define LOG_ERR(Func,...) printf("[ERROR]\t" __VA_ARGS__); printf("\r\n" __FUNCTION__ "\t" #Func "  Last error = 0x%.8lx.\r\n", GetLastError())
 
int setPrivilege(LPCWSTR);
 
 
int main(int argc, char *argv[]) 
{
    // Lib to inject
    char* strLib = "h:\\_AVZ\\Наши разработки\\ClearLNK 2.0(2)\\1\\InjectDll\\Release\\InjectDll.dll";
    //char* strLib = "c:\\users\\alex\\desktop\\InjectDll.dll";
 
    // Process & PID list
 
    system("tasklist.exe /nh | sort /r");
 
    // Prepare low integrity level folder
 
    system("md c:\\temp");
    system("icacls c:\\temp /setintegritylevel (OI)(CI)L");  // Object & container inherit, Low IL
 
    // Obtain Debug privileges
 
    if (0 == setPrivilege(SE_DEBUG_NAME))
        printf("Success with obtain SE_DEBUG privilege.\r\n");
 
    // Test working with UMID
 
    if (S_OK == SetCurrentProcessExplicitAppUserModelID(L"Alex.Dragokas.Injection.Test"))
        printf("Success with setting of AppUserModelID.\r\n");
    
    PWSTR AppID = NULL;
    HRESULT hRes = GetCurrentProcessExplicitAppUserModelID(&AppID);
 
    if (S_OK == hRes) {
        printf("\r\nAppUMID: %ls\r\n", AppID);
    } else {
        printf("Cannot obtain Current process' AppUserModelID. HRESULT code = 0x%.8lx", hRes);
    }
    
    printf("\r\nEnter PID: ");
 
    int procID;
    scanf_s("%i", &procID);
 
    // Get process handle passing in the process ID.
 
    HANDLE hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE, procID);
    if (hProc == NULL) {
        LOG_ERR(OpenProcess, "The specified process couldn't be found.");
        goto ErrorExit;
    }
 
    // Get address of the LoadLibrary function.
    
    LPVOID addrLib = (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");
    if (addrLib == NULL) {
        LOG_ERR(GetProcAddress, "The LoadLibraryA function was not found inside kernel32.dll library.");
        goto ErrorExit;
    }
        
    // Allocate new memory region inside the process' address space.
    
    LPVOID lpMem = (LPVOID)VirtualAllocEx(hProc, NULL, strlen(strLib), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);
    if (lpMem == NULL) {
        LOG_ERR(VirtualAllocEx, "The memory could not be allocated inside the chosen process.");
        goto ErrorExit;
    }
    
    // Write the argument to LoadLibraryA to the process's newly allocated memory region.
    
    if (0 == WriteProcessMemory(hProc, lpMem, strLib, strlen(strLib), NULL)) 
    {
        LOG_ERR(WriteProcessMemory, "Error: there was no bytes written to the process's address space.");
        goto ErrorExit;
    }
 
    // Inject our DLL into process' address space.
    
    HANDLE hThread = CreateRemoteThread(hProc, NULL, 0, (LPTHREAD_START_ROUTINE)addrLib, lpMem, NULL, NULL);
    if (hThread == NULL) {
        LOG_ERR(CreateRemoteThread, "The remote thread could not be created");
    } else {
        LOG_ERR(CreateRemoteThread, "Success: the remote thread was successfully created.\r\n");
        CloseHandle(hThread);
    }
    
    CloseHandle(hProc);
    getchar();
    getchar();
 
    return EXIT_SUCCESS;
 
ErrorExit:
 
    if (hProc) CloseHandle(hProc);
    getchar();
    getchar();
 
    return EXIT_FAILURE;
}
 
int setPrivilege(LPCWSTR privilege_name) {
    LUID    luid;
    HANDLE  hToken;
    DWORD   dwSize = sizeof (TOKEN_PRIVILEGES);
    TOKEN_PRIVILEGES tp;
    TOKEN_PRIVILEGES oldtp;
 
    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken)) {
        LOG_ERR(OpenProcessToken);
        return 1;
    }
 
    if (!LookupPrivilegeValue(NULL, privilege_name, &luid)) {
        LOG_ERR(LookupPrivilege);
        CloseHandle(hToken);
        return 1;
    }
 
    ZeroMemory(&tp, sizeof (tp));
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Luid = luid;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
 
    if (!AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), &oldtp, &dwSize)) {
        LOG_ERR(AdjustTokenPrivileges);
        CloseHandle(hToken);
        return 1;
    }
    CloseHandle(hToken);
    return 0;
}


Library
Кликните здесь для просмотра всего текста

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <Shobjidl.h>
 
unsigned __stdcall Thread(void *ArgList) {
    PWSTR AppID;
    FILE *file;
 
    // Mark for everyone that this library execution is alive
 
    CreateEventW(NULL, TRUE, TRUE, L"Browser.InjectDll.Event.Thread.Alive");
    CreateMutexW(NULL, TRUE, L"Browser.InjectDll.Mutex.Thread.Alive");
 
    SetEnvironmentVariable(L"A_MyEnvVariable", L"Value");
 
    // Obtain UMID of process
 
    HRESULT hRes = GetCurrentProcessExplicitAppUserModelID(&AppID);
 
    // Window to be receive our message
 
    wchar_t* WindowTitle = L"Get_WM_COPYDATA";
 
    // Send data via WM_COPYDATA
 
    HWND hwnd = FindWindowW(NULL, WindowTitle);
 
    if (0 != hwnd)
    {
        COPYDATASTRUCT cds;
        cds.dwData = 1;
        cds.cbData = sizeof(PWSTR) * (wcslen(AppID) + 1);
        cds.lpData = AppID;
        SendMessage(hwnd, WM_COPYDATA, (WPARAM)hwnd, (LPARAM)(LPVOID)&cds);
        CloseHandle(hwnd);
    }
 
    // Send data via file
 
    HANDLE hFile = CreateFileW(L"c:\\users\\alex\\AppData\\LocalLow\\AppID.log", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
    if (hFile) 
        CloseHandle(hFile);
 
    fopen_s(&file, "c:\\temp\\AppID.log", "a+");
 
    if (S_OK == hRes) {
        fprintf(file, "\r\n%ls\r\n", AppID);
    } else {
        fprintf(file, "Cannot obtain Current process' AppUserModel.ID. HRESULT code = 0x%.8lx\r\n", hRes);
    }
    fclose(file);
 
    return 0;
}
 
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
    unsigned ThreadId;
    HANDLE hThread;
    
    if (DLL_PROCESS_ATTACH == ul_reason_for_call) {
        hThread = (HANDLE)_beginthreadex(NULL, 0, Thread, 0, 0, &ThreadId);
    }
    return TRUE;
}


Попытка внедрить DLL в iexplore.exe x32 (v.11.0.9600.17959), OS Win7 x64 получилась успешна (ie создает сразу 2 процесса, один из которых защищен от создания удаленного потока, CreateRemoteThread Error = 5).
Все функции библиотеки выполнены без ограничений.

Sysinternals WinObj также показал, что событие и мютекс были созданы.
Переменная окружения создана. Сообщение также пришло, если соблюдается согласование уровней целостности процесса IE и принимающей стороны.

Попытка создать поток в процессе Chrome.exe как и раньше - успешна.
Извне песочницы никаких признаков того, что код библиотеки выполнятся, к сожалению, не установлено. Защита хорошая.

Моя же проблема решена, т.к. искомый мною UMID хром создает не для процесса, а для окна,
получить который не составило труда через SHGetPropertyStoreForWindow и интерфейс IPropertyStore.
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
12.09.2015, 16:51

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

создание удаленного пользователя на локальном пк.
Поскажите или намекните как создать и как удолинить пользователя удоленого рабочего стола? ...

Создание удалённого доступа windows server 2003
народ такой вопрос дома три компа интернет для них раздаёт роутер, ос win serv 2003, локально с...

Создание удаленного репозитория только через консоль
Ребята, не могу понять. Можно ли вообще сделать удаленный репозиторий ТОЛЬКО через консоль? или все...

Создание потока из потока.
Надо создать поток 1, в нем создать поток 2, сам я жуткий дураг, немаловероятно что правильного в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.