Форум программистов, компьютерный форум, киберфорум
C/C++: WinAPI
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.64/11: Рейтинг темы: голосов - 11, средняя оценка - 4.64
Эксперт WindowsАвтор FAQ
 Аватар для Dragokas
18031 / 7734 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16

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

09.09.2015, 01:24. Показов 2072. Ответов 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
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
09.09.2015, 01:24
Ответы с готовыми решениями:

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

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

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

2
Ушел с форума
Эксперт С++
 Аватар для Убежденный
16481 / 7444 / 1187
Регистрация: 02.05.2013
Сообщений: 11,616
Записей в блоге: 1
09.09.2015, 10:21
Цитата Сообщение от 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_REL OCS",
то в него возможна только загрузка 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
 Аватар для Dragokas
18031 / 7734 / 892
Регистрация: 25.12.2011
Сообщений: 11,502
Записей в блоге: 16
12.09.2015, 16:51  [ТС]
Спасибо за столь развернутый ответ.
Похоже здесь максимум из того, что мне может потребоваться.

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

Убедился через Диспетчер задач, что процессы-"жертвы" имеют одинаковую разрядность с 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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
12.09.2015, 16:51
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
Новые блоги и статьи
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Символьное дифференцирование
igorrr37 13.02.2026
/ * Программа принимает математическое выражение в виде строки и выдаёт его производную в виде строки и вычисляет значение производной при заданном х Логарифм записывается как: (x-2)log(x^2+2) -. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru