Модераторы: feodorv, GremlinProg, xvr, Fixin
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Перехват упраления программой, рбота с достпом к файлу 
:(
    Опции темы
F0b0S
  Дата 12.10.2004, 18:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 12.10.2004

Репутация: нет
Всего: нет



Отцы помогите пожалуйста рашить проблему stena.gif

проблема заключается в следующем:
есть файл1на жестком диске.
есть программа1 которая работает с этим файлом.
нужно:
1. отлавить обращение этой программы к файлу1
2. тормознуть программу1
3. загрузить файлв1память
4. выполнить некотрые действия с ним
5. подсунуть данные файла1 (находящиеся в памяти) этой прогорамме, не сохраняя данные файла1 на диск
6. возобновить работу прграммы1

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

Программа работает с файлом только в режиме ReadOnly.
PM MAIL   Вверх
Step
Дата 12.10.2004, 18:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: нет
Всего: 25



точно не скажу... но советую поискать доку по перехвату функци winapi и перехватывать открытие файла... можно конечно и прогу в реалтайме бомбить, но геморно


--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
<Spawn>
Дата 13.10.2004, 11:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Око кары:)
****


Профиль
Группа: Экс. модератор
Сообщений: 2776
Регистрация: 29.1.2003
Где: Екатеринбург

Репутация: нет
Всего: 64



Да, как уже сказал Step, тебе нужно в реалтайме попасть в адресное пространство целевого процесса(например, при помощи хуков) и там перехватывать вызов CreateFile.

Это сообщение отредактировал(а) <Spawn> - 13.10.2004, 11:51


--------------------
"Для некоторых людей программирование является такой же внутренней потребностью, подобно тому, как коровы дают молоко, или писатели стремятся писать" - Николай Безруков.
PM MAIL ICQ   Вверх
F0b0S
Дата 13.10.2004, 14:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 12.10.2004

Репутация: нет
Всего: нет



sad.gif В теории это конечно все хорошо (я примерно так себе это и представлял).... А не могли бы Вы дать хоть какое нибудь описание, как это можно сделать.... Например я в курсе о формирование ловушек (хуков), но о попадание внутрь адресного пространства..... это честно говоря немного не понятно....
Рализовывал хуки на перехват глобальных сообщений ОС, но некогда не пробывал перехватить конкретные сообщения конкретной программы...
Если есть такая возможность, дайте какие - нибудь ссылки на документацию по этому вопросу, либо, если не сложно, скиньте мне их на почту [email protected]
PM MAIL   Вверх
Step
Дата 13.10.2004, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: нет
Всего: 25



F0b0S, по сути это вопросы системного программирования, которое почемуто в нашем форуме не развиваеться, специалистов такого уровня маловато....
покачто вам придеться искать решения самим...

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

вообщем вам нужно искать...



--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
F0b0S
Дата 13.10.2004, 14:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 12.10.2004

Репутация: нет
Всего: нет



Вся задача сводится к перенаправлению запросов программы к файлу в память.... Вся проблема - это сделать перенаправление.....
Добавлено @ 14:15
Step, читая сообщения форума, я уже заметил, что вопросы низкоуровневого программирования здесь почти не обсуждаются....
Добавлено @ 14:20
Step По поводу риалтаймого доступа к самой программе, пробывал, на уровне ассемблера, но здесь загвоздка - поскольку я не знаю структуры работы программы, при молейшем перехвате контроля программа вываливалась с ошибкой, поэтому я сделал вывод, что единственным вариантом является - работа на уровне сообщений системы....

PM MAIL   Вверх
chipset
Дата 14.10.2004, 12:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 4071
Регистрация: 11.1.2003
Где: Seattle, US

Репутация: 2
Всего: 164



Сделаешь - расскажи плз как smile.gif
Одно из моих бредовизмов - сделать защищеный файл и ловить access-denied.



--------------------
Цитата(Jimi Hendrix)
Well, I stand up next to a mountain
And I chop it down with the edge of my hand
PM MAIL WWW   Вверх
Step
Дата 14.10.2004, 14:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5151
Регистрация: 26.9.2002
Где: дурдом.UA

Репутация: нет
Всего: 25



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



--------------------
- Дурак учится на своих ошибках, умный на чужих.
 - умные учатся у дураков
PM MAIL ICQ   Вверх
0bs3rv3r
Дата 16.10.2004, 19:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 16.10.2004

Репутация: 1
Всего: 1



Недавно писал прогу, которая к мультилекс конектится и выдирает переводы
Вот код длл которая внедряется в нужный процесс:
Код

#include "stdafx.h"
#include <stdio.h>
HWND hLex=0;
HWND hParent=0;
char LexWinClass[]={"MultLexWnd"};//имя класса главного окна
HHOOK hHook=0;
bool IsInLex=false;
int CALLBACK FindLex(HWND wnd,long zero)
{
char tt[512];
GetClassName(wnd,tt,500);
if(strcmp(tt,LexWinClass)==0)
{
 hLex=wnd;
 return 0;
}
return 1;
}

LRESULT CALLBACK DummyHook(int code, WPARAM wParam, LPARAM lParam)
{
long BT;
if(code==1&&wParam==1)
{
 //_asm int 3;
 if(!hHook)
 {
  hHook=SetWindowsHookEx(WH_CALLWNDPROC,DummyHook,(HINSTANCE)hCurModule,0);
  int i=GetLastError();
 }
 else
 {
  UnhookWindowsHookEx(hHook);
 }
  return 0;
}
CallNextHookEx(hHook,code,wParam,lParam);
return 0;
}

BOOL APIENTRY DllMain( HANDLE hModule,
                      DWORD  ul_reason_for_call,
                      LPVOID lpReserved
     )
{
hCurModule=hModule;
if(ul_reason_for_call!=DLL_PROCESS_ATTACH)
{
 return true;
}
while(EnumWindows(FindLex,0));
DWORD LexPid;
GetWindowThreadProcessId(hLex,&LexPid);
if(GetCurrentProcessId()!=LexPid)
{
 return true;
}
MessageBox(0,"LexProbe Active!",0,MB_OK);//отсюда мы в нужном процессе
IsInLex=true;
   return TRUE;
}


вызывается это дело так:
Код

HOOKPROC HP;
void LoadToProc()
{
hLib=LoadLibrary("..\\LexProbe.dll");
HP=(HOOKPROC)GetProcAddress(hLib,"DummyHook");
HP(1,1,1);
}
[/s]

далее так (уже в длл)
Код

struct jmp_far
{
 BYTE instr_push;  //здесь будет код инструкции push
 DWORD arg;         //аргумент push
 BYTE  instr_ret;    //здесь будет код инструкции ret
};
BYTE old[6]; //область для хранения 6-ти затираемых байт начала функции
DWORD adr_MessageBoxA //будущий адрес оригинальной функции
DWORD written; //вспомогательная переменная
jmp_far jump; //здесь будет машинный код инструкции перехода
void InterceptFunction(void)
{
 DWORD op;
 //сначала получим абсолютный адрес функции для перехвата
 adr_MessageBoxA = (DWORD)GetProcAddress(GetModuleHandle("user32.dll"),
                   "MessageBoxA");
 if(adr_MessageBoxA == 0)
 {
   MessageBox(NULL, "Can`t get adr_MessageBoxA", "Error!", 0);
   return;
 }

 // Зададим машинный код инструкции перехода, который затем впишем
 // в начало полученного адреса:
 jump.instr_push = 0x68;
 jump.arg = (DWORD)&Intercept_MessageBoxA;
 jump.instr_ret = 0xC3;

 //Прочитаем и сохраним первые оригинальные 6 байт стандартной API функции
 ReadProcessMemory(GetCurrentProcess(),(void*) adr_MessageBoxA,
                   (void*)&old, 6, &written);

//Запишем команду перехода на нашу функцию поверх этих 6-ти байт
WriteProcessMemory(GetCurrentProcess(), (void*)adr_MessageBoxA,
    (void*)&jump, sizeof(jmp_far), &written);
}

а сюды оно обратится
Код

BOOL WINAPI Intercept_MessageBoxA(HWND hwnd, char *text, char *hdr, UINT utype)
{
 //Сначала восстанавливаем 6 первых байт функции. Это не обязательное
 // действие, просто мы решили подшутить над пользователем, и все
 // сообщения функции MessageBoxA переделать на свои, поэтому нам придется
 // вызвать оригинальную функцию, а для этого следует восстановить ее адрес:
 WriteProcessMemory(GetCurrentProcess(), (void*)adr_MessageBoxA,
                    (void*)&old, 6, &written);

 //Здесь вы можете порезвиться от души и выполнить любые, пришедшие вам
 // в голову действия. Мы просто заменили сообщение функции на свое:
 char *str = "Hi From MessageBOX!!!!";

 //Вызываем оригинальную функцию через указатель
 ((BOOL (__stdcall*)(HWND, char*, char*, UINT))adr_MessageBoxA)(hwnd,
            str, hdr, utype);

 //Снова заменяем  6 байт функции на команду перехода на нашу функцию
 WriteProcessMemory(GetCurrentProcess(), (void*)adr_MessageBoxA,
                    (void*)&jump, 6,&written);
 return TRUE;
}
[/s]
вторая половина не моя[s]

Это сообщение отредактировал(а) 0bs3rv3r - 16.10.2004, 19:50
PM MAIL   Вверх
0bs3rv3r
Дата 16.10.2004, 20:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 2
Регистрация: 16.10.2004

Репутация: 1
Всего: 1



чуть не забыл к проджекту нужно еще .def добавить вида
LIBRARY "LexProbe"
EXPORTS
DummyHook
PM MAIL   Вверх
menkaur
Дата 24.10.2004, 03:13 (ссылка)    |    (голосов: 0) Загрузка ... Загрузка ... Быстрая цитата Цитата


Unregistered











Следующий класс позволяет заменить в адресном пространстве любого процесса системное api на твое собственное:
class KPEFile
{
PIMAGE_DOS_HEADER pDOSHeader;
PIMAGE_NT_HEADERS pNTHeader;

public:
const char * pModule;

const char * RVA2Ptr(unsigned rva)
{
if ( (pModule!=NULL) && rva )
return pModule + rva;
else
return NULL;
}

KPEFile(HMODULE hModule);
const void * GetDirectory(int id);
PIMAGE_IMPORT_DESCRIPTOR GetImportDescriptor(LPCSTR pDllName);
const unsigned * GetFunctionPtr(PIMAGE_IMPORT_DESCRIPTOR
pImport, LPCSTR pProcName);

FARPROC SetImportAddress(LPCSTR pDllName, LPCSTR pProcName,
FARPROC pNewProc);

FARPROC SetExportAddress(LPCSTR pProcName, FARPROC pNewProc);
};

---------------------------------------------------------------------------------------------------------------------------------------------------
#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include "pehack.h"

KPEFile::KPEFile(HMODULE hModule)
{
pModule = (const char *) hModule;

if ( IsBadReadPtr(pModule, sizeof(IMAGE_DOS_HEADER)) )
{
pDOSHeader = NULL;
pNTHeader = NULL;
}
else
{
pDOSHeader = (PIMAGE_DOS_HEADER) pModule;

if ( IsBadReadPtr(RVA2Ptr(pDOSHeader->e_lfanew),
sizeof(IMAGE_NT_HEADERS)) )
pNTHeader = NULL;
else
pNTHeader = (PIMAGE_NT_HEADERS) RVA2Ptr(pDOSHeader->
e_lfanew);
}
}


// returns address of a PE directory
const void * KPEFile::GetDirectory(int id)
{
return RVA2Ptr(pNTHeader->OptionalHeader.DataDirectory[id].
VirtualAddress);
}


// returns PIMAGE_IMPORT_DESCRIPTOR for an imported module
PIMAGE_IMPORT_DESCRIPTOR KPEFile::GetImportDescriptor(
LPCSTR pDllName)
{
// first IMAGE_IMPORT_DESCRIPTOR
PIMAGE_IMPORT_DESCRIPTOR pImport = (PIMAGE_IMPORT_DESCRIPTOR)
GetDirectory(IMAGE_DIRECTORY_ENTRY_IMPORT);

if ( pImport==NULL )
return NULL;

while ( pImport->FirstThunk )
{
if ( stricmp(pDllName, RVA2Ptr(pImport->Name))==0 )
return pImport;

// move to next imported module
pImport ++;
}

return NULL;
}


// returns address of __imp__xxx variable for an import function
const unsigned * KPEFile::GetFunctionPtr(
PIMAGE_IMPORT_DESCRIPTOR pImport, LPCSTR pProcName)
{
PIMAGE_THUNK_DATA pThunk;

pThunk = (PIMAGE_THUNK_DATA) RVA2Ptr(pImport->
OriginalFirstThunk);

for (int i=0; pThunk->u1.Function; i++)
{
bool match;

if ( pThunk->u1.Ordinal & 0x80000000 ) // by ordinal
match = (pThunk->u1.Ordinal & 0xFFFF) ==
((DWORD) pProcName);
else
match = stricmp(pProcName, RVA2Ptr((unsigned)
pThunk->u1.AddressOfData)+2) == 0;

if ( match )
return (unsigned *) RVA2Ptr(pImport->FirstThunk)+i;

pThunk ++;
}

return NULL;
}


BOOL HackWriteProcessMemory(HANDLE hProcess, void * pDest, void * pSource, DWORD nSize, DWORD * pWritten)
{
__try
{
memcpy(pDest, pSource, nSize);
}
__except ( EXCEPTION_EXECUTE_HANDLER )
{
__try
{
MEMORY_BASIC_INFORMATION mbi;

VirtualQuery(pDest, & mbi, sizeof(mbi));
VirtualProtect(mbi.BaseAddress, mbi.RegionSize, PAGE_READWRITE, & mbi.Protect);

memcpy(pDest, pSource, nSize);
}
__except ( EXCEPTION_EXECUTE_HANDLER )
{
return FALSE;
}
}

* pWritten = nSize;

return TRUE;
}

FARPROC KPEFile::SetImportAddress(LPCSTR pDllName,
LPCSTR pProcName, FARPROC pNewProc)
{
PIMAGE_IMPORT_DESCRIPTOR pImport =
GetImportDescriptor(pDllName);

if ( pImport )
{
const unsigned * pfn = GetFunctionPtr(pImport, pProcName);

if ( IsBadReadPtr(pfn, sizeof(DWORD)) )
return NULL;

// read the original function address
FARPROC oldproc = (FARPROC) * pfn;

DWORD dwWritten;

// overwrite with new function address
HackWriteProcessMemory(GetCurrentProcess(), (void *) pfn,
& pNewProc, sizeof(DWORD), & dwWritten);

return oldproc;
}
else
return NULL;
}


FARPROC KPEFile::SetExportAddress(LPCSTR pProcName,
FARPROC pNewProc)
{
PIMAGE_EXPORT_DIRECTORY pExport = (PIMAGE_EXPORT_DIRECTORY)
GetDirectory(IMAGE_DIRECTORY_ENTRY_EXPORT);

if ( pExport==NULL )
return NULL;

unsigned ord = 0;

if ( (unsigned) pProcName < 0xFFFF ) // ordinal ?
ord = (unsigned) pProcName;
else
{
const DWORD * pNames = (const DWORD *) RVA2Ptr(pExport->AddressOfNames);
const WORD * pOrds = (const WORD *) RVA2Ptr(pExport->AddressOfNameOrdinals);

// find the entry with the function name
for (unsigned i=0; i<pExport->AddressOfNames; i++)
if ( stricmp(pProcName, RVA2Ptr(pNames[i]))==0 )
{
// get the corresponding ordinal
ord = pExport->Base + pOrds[i];
break;
}
}

if ( (ord<pExport->Base) || (ord>pExport->NumberOfFunctions) )
return NULL;

// use ordinal to get the address where export RVA is stored
DWORD * pRVA = (DWORD *) RVA2Ptr(pExport->AddressOfFunctions) +
ord - pExport->Base;

// read original function address
DWORD rslt = * pRVA;

DWORD dwWritten = 0;
DWORD newRVA = (DWORD) pNewProc - (DWORD) pModule;
HackWriteProcessMemory(GetCurrentProcess(), pRVA, & newRVA, sizeof(DWORD), & dwWritten);

return (FARPROC) RVA2Ptr(rslt);
}
-----------------------------------------------------------------------------------------------------------------------------------------------------
Вот, как это работает на деле:
#define STRICT
#define WIN32_LEAN_AND_MEAN

#include <windows.h>
#include "..\..\include\pehack.h"

int WINAPI MyMessageBoxA(HWND hWnd, LPCSTR pText, LPCSTR pCaption,
UINT uType)
{
WCHAR wText[MAX_PATH];
WCHAR wCaption[MAX_PATH];

MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pText,
-1, wText, MAX_PATH);
wcscat(wText, L" - intercepted");

MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pCaption,
-1, wCaption, MAX_PATH);
wcscat(wCaption, L" - intercepted");

return MessageBoxW(hWnd, wText, wCaption, uType);
}

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
{
KPEFile pe(hInstance);

pe.SetImportAddress("user32.dll", "MessageBoxA", (FARPROC) MyMessageBoxA);

MessageBoxA(NULL, "Test", "SetImportAddress", MB_OK);
}

HMODULE hUser = GetModuleHandle("user32.dll");

KPEFile user32(hUser);

FARPROC oldproc = GetProcAddress(hUser, "MessageBoxA");

user32.SetExportAddress("MessageBoxA", (FARPROC) MyMessageBoxA);

FARPROC newproc = GetProcAddress(hUser, "MessageBoxA");

char temp[64];
wsprintf(temp, "GetProcAddress(MessageBoxA)\n"
"changes from %x to %x", oldproc, newproc);
MessageBoxA(NULL, temp, "SetExportAddress", MB_OK);

return 0;
}

Для внедрения можеш использовать hooks, но мне нравится следующий способ:
HKLM\Software\Microsoft\Windows NT\Current Version\Windows\AppInit_DLLs
Сюда нужно записать полный путь к твоей dll. После етого система автоматически будет внедрять ее в каждый новый процесс. Заменять адреса я можна в DllMain.

Приятных развлечений!
  Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Системное программирование и WinAPI"
Fixin
GremlinProg
xvr
feodorv
  • Большое количество информации и примеров с использованием функций WinAPI можно найти в MSDN
  • Описание сообщений, уведомлений и примеров с использованием компонент WinAPI (BUTTON, EDIT, STATIC, и т.п.), можно найти в MSDN Control Library
  • Непосредственно, перед созданием новой темы, проверьте заголовок и удостоверьтесь, что он отражает суть обсуждения.
  • После заполнения поля "Название темы", обратите внимание на наличие и содержание панели "А здесь смотрели?", возможно Ваш вопрос уже был решен.
  • Приводите часть кода, в которой предположительно находится проблема или ошибка.
  • Если указываете код, пользуйтесь тегами [code][/code], или их кнопочными аналогами.
  • Если вопрос решен, воспользуйтесь соответствующей ссылкой, расположенной напротив названия темы.
  • Один топик - один вопрос!
  • Перед тем как создать тему - прочтите это .

На данный раздел распространяются Правила форума и Правила раздела С++:Общие вопросы .


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Chipset, Step, Fixin, GremlinProg, xvr. feodorv.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Системное программирование и WinAPI | Следующая тема »


 




[ Время генерации скрипта: 0.0842 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.