дизайн виртуальной файловой системы - PullRequest
4 голосов
/ 22 марта 2012

Я запускаю проект, подобный защитному устройству / упаковщику / связующему.

цель - когда у вас есть полный каталог приложений с

  • / изображения /
  • / музыка /
  • база * .ini файлов
  • 1012 * DLLs *
  • * 1014 EXEs *

вы просто используете файл packer.exe, и все эти файлы упакованы, зашифрованы и сохранены в полученном exe-файле.

Затем полученный exe создает прозрачную виртуальную файловую систему, которая возвращается к «реальной», если файл не найден.

я уже могу обрабатывать (не очень точно) загрузку dll из памяти и т. Д., Но у меня проблема с хмм-хуками ..

на данный момент, как ProofOfConcept, я подключаю отладчик (написанный на c ++) к target.exe

это выглядит как

======= Started [target.exe] =======
> Placing breakpoint on EP : 0x401130
Process started
Loaded module : [target.exe]
Loaded module : [ntdll.dll]
Loaded module : [kernel32.dll]
[...]
Break point at [0x401130]
 > Restored EP byte.
 Loaded module : [bass.dll]
Break point at [0x760fcc4e]
Found set bp : kernel32!CreateFileW
[!] CreateFileW Callback Function :
       FileName : C:\Users\user\Desktop\cppve\loader\bin\Debug\target.exe
       Access   : 0x80000000
       Return Addr: 0x741b91e6
 > Re-setting bp at [0x760fcc4e]
Break point at [0x760fcc4e]
Found set bp : kernel32!CreateFileW
[!] CreateFileW Callback Function :
       FileName : .\beyond_v.mod
       Access   : 0x80000000
       Return Addr: 0x760fcfa0

Я обрабатываю точки останова в отладчике для таких вещей, как CreateFileW, ReadFile и т. Д. У меня проблемы с обеспечением цели полезными данными.

Должен ли я создать фальшивый дескриптор, а затем поймать его и обработать? или слишком много вещей могут пойти не так с этим подходом?

вот пример функции обратного вызова для CreateFileW

void callback_createfilew(CONTEXT* ct){
//stub
cout<<"[!] CreateFileW Callback Function :"<<endl;

void* returnaddr=MemReadDwordPtr(hProcess,(void*)ct->Esp);
string fn=MemReadCString(hProcess,MemReadDwordPtr(hProcess,(void*)ct->Esp+4),true);
void* access=MemReadDwordPtr(hProcess,(void*)ct->Esp+8);
void* sharemode=MemReadDwordPtr(hProcess,(void*)ct->Esp+12);
void* dwCreationDisposition=MemReadDwordPtr(hProcess,(void*)ct->Esp+20);
void* dwFlagsAndAttributes=MemReadDwordPtr(hProcess,(void*)ct->Esp+24);

cout<<"       FileName : "<<fn<<endl;
cout<<"       Access   : "<<(void*)access<<endl;
cout<<"       Return Addr: "<<(void*)returnaddr<<endl;

if(fn.compare(".\\beyond_v.mod")==0){
    // this is wrong, we need to call it from the target process...
    HANDLE ret=CreateFileA(".\\_beyond_v.mod",(DWORD)access,(DWORD)sharemode,NULL,(DWORD)dwCreationDisposition,(DWORD)dwFlagsAndAttributes,NULL);
    ct->Esp+=0x20;
    ct->Eax=(DWORD)ret;
    ct->Eip=(DWORD)returnaddr;
}

если я сделаю кодовую пещеру в процессе и вставлю шелл-коды [Редактировать: извините, я использую многие из этих слов для описания разных вещей, но я думаю, вы поймете, что я :) :) там, чтобы выполнить мой поддельный код?

или, может быть, внедрить dll, которая будет обрабатывать int3 и передавать ему управление через обработчики исключений, установленные загрузчиком? однако это может оказаться сложным ... что DLL должна быть в виртуальной файловой системе! поэтому мне нужно было бы загрузить его вручную, прежде чем произойдет какая-либо другая инициализация.

Я бы хотел в окончательной версии полностью удалить отладчик. это только вызовет проблемы и серьезно усложнит защитную часть проекта.

1 Ответ

1 голос
/ 03 апреля 2012

Если вы хотите, чтобы ваш «упаковщик» работал прозрачно на предварительно скомпилированных двоичных файлах и хотите, чтобы все было в результирующем одиночном двоичном файле, упаковщик должен добавить код перехвата в двоичный файл, возможно, заставив его работать как самая первая вещьзатем передайте управление исходной точке входа двоичного файла.Это не очень тривиально, хотя, безусловно, выполнимо.

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

Что касается поддельных дескрипторов, я посмотрю, возможно ли этооткрыть файл несколько раз и получить разные ручки.Если это так, просто откройте любой существующий файл для чтения в режиме совместного использования, запомните дескриптор и используйте его для файла в памяти.Нужна другая ручка?Откройте файл еще раз, чтобы получить один.Это гарантирует отсутствие столкновения с другими настоящими ручками.

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