Теперь мы должны скопировать нашу DLL, которая находится там же где и EMBEDDING.EXE по пути который мы указали в реестре. В случае не имения прав открывать реестр и что-то туда записывать Вас предупредят.
void CembeddingDlg::OnBnClickedButton2()
{
HKEY hk1;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows",0,KEY_ALL_ACCESS,&hk1)
==ERROR_SUCCESS)
{
char s[57];
_tcscpy((char *)&(s[0]), "c:\\WINNT\\System32\\intercpt.dll");
RegSetValueEx(hk1,"AppInit_DLLs",0,REG_SZ,(LPBYTE)s,57);
RegCloseKey(hk1);
char *cmd, *str, *stl;
cmd = GetCommandLine();
int path = strlen(cmd);
while (cmd[path] != '\\')
{
cmd[path] = '\0';
path--;
}
cmd[path+1] = 'i';
cmd[path+2] = 'n';
cmd[path+3] = 't';
cmd[path+4] = 'e';
cmd[path+5] = 'r';
cmd[path+6] = 'c';
cmd[path+7] = 'p';
cmd[path+8] = 't';
cmd[path+9] = '.';
cmd[path+10] = 'd';
cmd[path+11] = 'l';
cmd[path+12] = 'l';
stl = &(cmd[1]);
int path1 = strlen(stl);
str = "c:\\winnt\\system32\\intercpt.dll";
CopyFile(stl,str, FALSE);
}
else
{
MessageBox("Извините у Вас нет прав, обратитесь к администратору.");
return;
}
}
Функция обрабатывающая нажатие на кнопку «Снять защиту». Снова открываем реестр и стираем там путь к нашей DLL.
void CembeddingDlg::OnBnClickedButton3()
{
HKEY hk1;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows",0,KEY_ALL_ACCESS,&hk1)
==ERROR_SUCCESS)
{
char s[57];
_tcscpy((char *)&(s[0]), "");
RegSetValueEx(hk1,"AppInit_DLLs",0,REG_SZ,(LPBYTE)s,2);
RegCloseKey(hk1);
}
else
{
MessageBox("У Вас нет прав, обратитесь к администратору.");
return;
}
}
Рассмотрим поближе DLL. Называется она intercpt.dll. В ней используется первый метод перехвата API-функций “Перехват API непосредственной записью в код системной функции.”, который был описан выше. Перехватывает она функцию CreateFileA находящуюся с системной библиотеке KERNEL32.DLL
Подключим библиотеки:
#include "stdafx.h"
#include "intercpt.h"
#include "string.h"
#include <stdlib.h>
#include <stdio.h>
Далее подготовим структуру, содержащую код дальнего перехода на нашу функцию-двойник. Практика показала, что вместо обычного jmp лучше применять комбинацию:
push xxxxxxxx
ret
struct jmp_far
{
BYTE instr_push; //здесь будет код инструкции push
DWORD arg; //аргумент push
BYTE instr_ret; //здесь будет код инструкции ret
Зададим нужные переменные:
BYTE old[6]; //область для хранения 6-ти затираемых байт начала функции
DWORD adr_CreateFileA //будущий адрес оригинальной функции
DWORD written; //вспомогательная переменная
jmp_far jump; //здесь будет машинный код инструкции перехода
Зададим так же массив под список файлов: char m_Files[90][40]; И это значит что наша система может защищать не более сорока файлов по девяносто символов в каждом файле(пути к файлу).
Если система подключает DLL к какому либо процессу, она сначала вызовет главную функцию DLL с параметром DLL_PROCESS_ATTACH на что мы сразу открываем файл winfs.ini со списком файлов которые нужно защитить. И вызываем нашу функцию InterceptFunctions, которая произведет подмену стандартной API функции CreateFileA нашей функцией Intercept_CreateFileA.
Теперь посмотрим, как выглядит сама функция-двойник. Она должна заменить стандартную CreateFileA, поэтому её тип и состав параметров должны точно соответствовать оригиналу:
HANDLE WINAPI Intercept_CreateFileA(
LPCSTR lpFileName,
DWORD dwDesiredAccess,
DWORD dwShareMode,
LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition,
DWORD dwFlagsAndAttributes,
HANDLE hTemplateFile)
{
WriteProcessMemory(GetCurrentProcess(), (void*)adr_CreateFileA, (void*)&old, 6, &written);
bool find = false;
int sdf;
for (int i=0; i < c; i++)
{
int lp, m_F;
m_F = strlen(m_Files[i]);
lp = strlen(lpFileName);
sdf = strcmp(m_Files[i],lpFileName);
if(m_Files[i][m_F-6] == lpFileName[lp-4])
if(m_Files[i][m_F-7] == lpFileName[lp-5])
if(m_Files[i][m_F-8] == lpFileName[lp-6])
if(m_Files[i][m_F-9] == lpFileName[lp-7])
find = true;
if (sdf == 0)
{
find = true;
break;
}
}
if (find)
{
MessageBox(NULL,"Нет доступа к файлу","перехват",MB_OK);
WriteProcessMemory(GetCurrentProcess(), (void*)adr_CreateFileA, (void*)&jump, 6,&written);
return NULL;
}
else
{
HANDLE hp = ((HANDLE (__stdcall *)(LPCSTR ,
DWORD ,
DWORD ,
LPSECURITY_ATTRIBUTES ,
DWORD ,
DWORD ,
HANDLE )) adr_CreateFileA)( lpFileName,
dwDesiredAccess,
dwShareMode,
lpSecurityAttributes,
dwCreationDisposition,
dwFlagsAndAttributes,
hTemplateFile);
WriteProcessMemory(GetCurrentProcess(), (void*)adr_CreateFileA, (void*)&jump, 6,&written);
return hp;
}
}
Теперь подробнее. Сначала восстанавливаем первых шесть байт оригинальной функции что бы можно было ее вызвать. Затем сравниваем параметр lpFileName, передаваемый функции со списком файлов, которые нужно защитить. Если имя хотя бы одного их защищаемых файлов совпало с lpFileName то высылаем окошко – «нет доступа к файлу» и игнорируем вызов функции и открытие файла. Снова заменяем первых шесть байт оригинальной функции, на случай повторного
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.