Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.77/35: Рейтинг темы: голосов - 35, средняя оценка - 4.77
21 / 29 / 2
Регистрация: 04.12.2013
Сообщений: 263
1

Запуск приложения из ресурсов (без распаковки на диск)

03.09.2014, 09:01. Показов 6843. Ответов 12
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день всем!

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

Зачем это мне нужно. Все просто. Есть желание разобраться в защите программ и когда-нибудь написать shareware-программу, защитив ее на определенное время от взлома и распространения.

Методик на эту тему много: от подсчета crc файла, до шифрования кусков кода и выполнение их по мере необходимости. Можно использовать и все вместе.

Погуглив на эту тему я понял, что толкового решения для Builder C++ нет. Все советуют или использовать сторонние утилиты (ExeCriptor, ASPProtect и т.д.) или реализовывать облачное выполнение.

Облачное выполнение для большей части фрилансеров вещь довольно дорогая и не совсем понятная в реализации. Поэтому решил шифровать части (функции) своего приложения.
Подумав на эту тему, пришел к выводу, что можно сделать несколько ехе-фалов, которые будут выполнять свою часть функционала, а эти ехе-файлы добавить в ресурсы. Конечно защита будет не очень сложная, но для большинства программистов, со стоимостью их программ в 1000 - 2000 руб. вполне пригодное.
Создал несколько ехе-фалов, которые выводят просто окна-сообщения. Создал основное приложение, добавив в его ресурсы эти самые ехе-фалы.

Теперь возник вопрос: как запустить выполнение ехе файла из ресурсов?
Ведь просто сохранять файл на диск, а потом его запускать, будет глупостью несусветной, ибо ничто не мешает этот файл с диска просто сохранить в другую папку и все. Следовательно надо запускать файл без сохранения его на диске.

Попутный вопрос: может я вообще не то реализую и есть какие-то способы проще?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
03.09.2014, 09:01
Ответы с готовыми решениями:

Запуск exe из ресурсов без распаковки на диск
Всем привет, как спрятать exe файл и запустить его в своей программе "не извлекая на диск"? Как я...

Запуск исполняемого файла из ресурсов без распаковки на диск
Вообщем нужна помощь как запустить .ехе с процесса программы по нажатию кнопки, не копируя .ехе на...

Запуск exe из ресурсов без распаковки
Всем доброго времени суток! Сразу оговорка: нужно для легальных целей - защита другой программы...

Запуск приложения из ресурсов
Нужно реализовать запуск стороннего приложения которое лежит в ресурсах моего. Пробовал так:...

12
4043 / 2332 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
04.09.2014, 17:42 2
У NT есть множество классных возможностей, которые далеко не очевидны, если только вы не читаете документацию ДЕЙСТВИТЕЛЬНО внимательно.

Одна из моих любимых - то, что я называю “временные” временные файлы.

“Временный” временный файл - это такой файл, содержимое которого никогда не сбрасывается на диск (при отсутствии нехваток памяти, конечно же). Он ведёт себя точно как файл (потому что это и есть файл), но менеджер кэша отключает отложенную запись файла, а файловая система в курсе, что страницы, содержащие метаданные файла, никогда не нужно сбрасывать на диск.

Чтобы создать “временный” файл, вы должны вызвать*CreateFile, указывая в параметре dwFlagsAndAttributes комбинацию FILE_ATTRIBUTE_TEMPORARY or FILE_FLAG_DELETE_ON_CLOSE. Эта комбинация битов работает как подсказка файловой системе, что данные файла никогда не должны сбрасываться на диск. Другими словами, такой файл может быть создан, в него могут писаться данные, из него можно читать, а система при этом ни разу даже не коснётся диска.

Видите ли, другим большим плюсом “временных” временных файлов по сравнению с буферами в памяти является то, что их размер ограничен доступным свободным местом на диске, а НЕ в памяти. Поэтому, если рендеринг в памяти может обломаться с данными в 1 Гб (потому что вы не смогли выделить непрерывный кусок памяти в 1 Гб), то у рендеринга во “временный” временный файл таких проблем нет (в предположении, что у вас есть свободное дисковое пространство). Если у вас закончится память - менеджер памяти будет сбрасывать ваш файл на диск. Конечно же, это повлияет на производительность, но, по-крайней мере, ваша операция будет успешна.
It's only temporary. Larry Osterman.
3
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
28.06.2017, 20:42 3
Приветствую всех. Заинтересовала эта тема. В функции CreateFile необходимо указывать путь к файлу. В случае создания "временного" временного файла что указывать в параметре lpFileName?
0
129 / 65 / 16
Регистрация: 03.09.2015
Сообщений: 832
03.07.2017, 13:17 4
Смотри здесь https://github.com/codecrack3/... /RunPE.cpp
0
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
03.07.2017, 20:22 5
ziqp, не увидел применения функции CreateFile в коде по ссылке. Хотя, наверное, вопрос запуска файла из памяти там раскрыт.
И все же. Если обычный исполняемый файл поместить в ресурсы приложения, то как его оттуда запустить используя функцию CreateFile и без сохранения на диск?
0
138 / 138 / 53
Регистрация: 14.06.2016
Сообщений: 467
03.07.2017, 20:53 6
Цитата Сообщение от d7d1cd Посмотреть сообщение
используя функцию CreateFile и без сохранения на диск
эта функция только с файлами и работает.
Цитата Сообщение от d7d1cd Посмотреть сообщение
Если обычный исполняемый файл поместить в ресурсы приложения, то как его оттуда запустить
сделать всё, что обычно делает загрузчик - установить правильный протект памяти для всех секций, настроить релоки, разрешить импорт, выполнить tls коллбэки, если есть и затем точку входа. (минимум)
эта техника - довольно таки высший пилотаж.
если желание очень сильное - гуглить ManualMapping и изучать структуру PE заголовка.
но я всё таки советую ограничиться выгрузкой временного файла на диск.
1
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.07.2017, 21:07 7
Цитата Сообщение от d7d1cd Посмотреть сообщение
все же. Если обычный исполняемый файл поместить в ресурсы приложения, то как его оттуда запустить используя функцию CreateFile и без сохранения на диск?
А как вам вы хотите что бы ответили, так что бы вы прекратили задавать глупые вопросы и все же вникли в то что вам отвечают?

Очевидно то что ответил BRcr не является прямом ответом на поставленный вопрос ибо подразумевают выгрузку файла из ресурсов на диск и запуск его с диска.Просто используется временный файл.
По крайней мере это то что я понял.

А вот ответ ziqp, интересен.
(Хотя лично сомневаюсь что там рабочий код)

Добавлено через 6 минут
Цитата Сообщение от jr_ Посмотреть сообщение
но я всё таки советую ограничиться выгрузкой временного файла на диск.
Да только тогда возникает вопрос нафига экзе тогда пихать в ресурсы.
0
Ушел с форума
Эксперт С++
16478 / 7441 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
03.07.2017, 21:45 8
Цитата Сообщение от jr_ Посмотреть сообщение
эта техника - довольно таки высший пилотаж.
если желание очень сильное - гуглить ManualMapping и изучать структуру PE заголовка.
но я всё таки советую ограничиться выгрузкой временного файла на диск
+1
В последних Windows столько всего наворотили, что сделать качественный PoC
на тему "load exe from memory", который был бы для системы неотличим от
"нормального" exe, - задача практически нереальная.

Такие вещи только для мелких трюков типа выполнить 20 байт и быстро
завершиться, пока все не грохнулось.
0
Эксперт С++
8482 / 6149 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
03.07.2017, 21:47 9
И антивирусы такое любят )))
1
Ушел с форума
Эксперт С++
16478 / 7441 / 1187
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
03.07.2017, 21:53 10
О, да!

Но мне как-то показывали один трюк, который работает в том числе и на последних версиях
Windows - сохранить exe-файл в NTFS-поток, а затем запустить его оттуда. После чего поток
можно удалять. Все никак руки не дойдут поковырять этот способ (например, куда будут
выгружаться страницы памяти при нехватке ресурсов?)
0
129 / 65 / 16
Регистрация: 03.09.2015
Сообщений: 832
08.07.2017, 19:35 11
Не совсем понял что такое PoC..
Но сам давно пользуюсь запуском файла в памяти в моем проекте. Если в проекте парочка форм, кнопочки и запуск файла в памяти на кнопку, а не автоматически, то антивирям всеравно.
Конечно, это не тот код, который я привел выше. В своем я делаю массив из байтов памяти, складываю и запускаю в памяти
0
279 / 156 / 52
Регистрация: 30.06.2011
Сообщений: 1,712
08.07.2017, 21:57 12
Цитата Сообщение от ziqp Посмотреть сообщение
сам давно пользуюсь запуском файла в памяти в моем проекте
ziqp, покажите как Вы это делаете.
0
129 / 65 / 16
Регистрация: 03.09.2015
Сообщений: 832
09.07.2017, 20:47 13
h файл с функцией:
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
typedef LONG (WINAPI * NtUnmapViewOfSection)(HANDLE ProcessHandle, PVOID BaseAddress);
 
class runPE{
public:
void run(LPSTR szFilePath, PVOID pFile) 
{
  PIMAGE_DOS_HEADER IDH;     
    PIMAGE_NT_HEADERS INH;     
    PIMAGE_SECTION_HEADER ISH; 
    PROCESS_INFORMATION PI;    
    STARTUPINFOA SI;           
    PCONTEXT CTX;              
    PDWORD dwImageBase;        
    NtUnmapViewOfSection xNtUnmapViewOfSection;
    LPVOID pImageBase;         
    int Count;                 
    IDH = PIMAGE_DOS_HEADER(pFile);
    if (IDH->e_magic == IMAGE_DOS_SIGNATURE)
    {
        INH = PIMAGE_NT_HEADERS(DWORD(pFile) + IDH->e_lfanew);
        if (INH->Signature == IMAGE_NT_SIGNATURE)
        {
            RtlZeroMemory(&SI, sizeof(SI));
            RtlZeroMemory(&PI, sizeof(PI));
            if (CreateProcessA(szFilePath, NULL, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &SI, &PI))
            {
                CTX = PCONTEXT(VirtualAlloc(NULL, sizeof(CTX), MEM_COMMIT, PAGE_READWRITE));
                CTX->ContextFlags = CONTEXT_FULL;
                if (GetThreadContext(PI.hThread, LPCONTEXT(CTX)))
                {
                    ReadProcessMemory(PI.hProcess, LPCVOID(CTX->Ebx + 8), LPVOID(&dwImageBase), 4, NULL);
                    if (DWORD(dwImageBase) == INH->OptionalHeader.ImageBase)
                    {
                        xNtUnmapViewOfSection = NtUnmapViewOfSection(GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtUnmapViewOfSection"));
                        xNtUnmapViewOfSection(PI.hProcess, PVOID(dwImageBase));
                    }
                    pImageBase = VirtualAllocEx(PI.hProcess, LPVOID(INH->OptionalHeader.ImageBase), INH->OptionalHeader.SizeOfImage, 0x3000, PAGE_EXECUTE_READWRITE);
                    if (pImageBase)
                    {
                        WriteProcessMemory(PI.hProcess, pImageBase, pFile, INH->OptionalHeader.SizeOfHeaders, NULL);
                        for (Count = 0; Count < INH->FileHeader.NumberOfSections; Count++)
                        {
                            ISH = PIMAGE_SECTION_HEADER(DWORD(pFile) + IDH->e_lfanew + 248 + (Count * 40));
                            WriteProcessMemory(PI.hProcess, LPVOID(DWORD(pImageBase) + ISH->VirtualAddress), LPVOID(DWORD(pFile) + ISH->PointerToRawData), ISH->SizeOfRawData, NULL);
                        }
                        WriteProcessMemory(PI.hProcess, LPVOID(CTX->Ebx + 8), LPVOID(&INH->OptionalHeader.ImageBase), 4, NULL);
                        CTX->Eax = DWORD(pImageBase) + INH->OptionalHeader.AddressOfEntryPoint;
                        SetThreadContext(PI.hThread, LPCONTEXT(CTX));
                        ResumeThread(PI.hThread);
                    }
 
                }
            }
        }
    }
    VirtualFree(pFile, 0, MEM_RELEASE);
}
};
Запуск:
C++
1
2
3
4
runPE runner; //запуск в памяти
    TCHAR szFilePath[1024];
    GetModuleFileNameA(0, LPSTR(szFilePath), 1024);
    runner.run(LPSTR(szFilePath), shellcode);
Вид shellcode:
C++
1
2
3
4
unsigned char shellcode[] = {
    77,90,144,0,3,0,0,0,4,0,0,0, и т. д. (раньше значения были в 16-ричном, но в один момент решил, что и так сойдет
        };
const unsigned int size = 52736; //кол-во байтов образа
Добавлено через 9 минут
Минус метода в том, что слишком большой образ не скомпилируется
2
09.07.2017, 20:47
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.07.2017, 20:47
Помогаю со студенческими работами здесь

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

Как скопировать файл на диск из ресурсов приложения?
Всем добрый вечер! Очень срочная проблема. У меня в солюшне несколько проектов. В основном...

Хранение ресурсов приложения без БД
Помогите пожалуйста, как лучше организовать приложение. Создаю, грубо говоря, книгу. В левой части...

Запуск .exe из приложения (не извлекая его на жёсткий диск)
Доброго времени суток, такой вопрос, наткнулся на тему, в ней выложен исходник проекта, в котором...


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

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru