Re[6]: Перехват вызова не WINAPI функции
От: _Dinosaur Россия  
Дата: 15.10.08 09:47
Оценка: :)
Здравствуйте, Alexander G, Вы писали:

AG>Здравствуйте, _Dinosaur, Вы писали:


_D>>Это он динамически длину команд вычисляет?

AG>

AG>To copy instructions, Detours uses a simple table-driven disassembler.

ясно
остается надеятся, что таблицы находятся в актуальном состоянии и включают недокументированные инструкции...
Завидую людям, которые могут себе позволить никуда не спешить.
Re: Перехват вызова не WINAPI функции
От: INsect  
Дата: 15.10.08 12:50
Оценка: +2
И так, подытожим.
Стояла задача : имея исполняемый файл программы произвести перехват функций не импортируемых из внешних dll, а родом из стандартных хедеров, в частности stdio.h. Исполняемый файл собран в конфигурации Release
Вердикт: detours нам не поможет нам в этом случае, а поможет нам терпение и труд, которые, как известно все перетрут. От себя добавим, что задача это геморойная, так что лучше поискать обходные пути...
Все так?
Re[2]: Перехват вызова не WINAPI функции
От: gear nuke  
Дата: 18.10.08 08:43
Оценка:
Здравствуйте, INsect, Вы писали:

IN>Стояла задача : имея исполняемый файл программы произвести перехват функций не импортируемых из внешних dll, а родом из стандартных хедеров, в частности stdio.h. Исполняемый файл собран в конфигурации Release

IN>Вердикт: detours нам не поможет нам в этом случае, а поможет нам терпение и труд, которые, как известно все перетрут.

Поможет знание факта, что fwrite находится в некотором объектнике из поставки компилятора и линкуется в исполняетмый файл. Значит, что можно однозначно определить сигнатуру fwrite, найти функцию по ней и пропатчить (либо поставить аппаратную точку останова).

IN> От себя добавим, что задача это геморойная, так что лучше поискать обходные пути...


Это просто некрасиво, потребуется дополнительный загрузчик.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[8]: Перехват вызова не WINAPI функции
От: Аноним  
Дата: 18.10.08 22:23
Оценка:
Здравствуйте, Аноним, Вы писали:

IN>>Все действия, требующие пересборки проекта будут рассматриваться в последнюю очередь.

А>Сплайсинг считается менее рисковым чем пересборка проекта. Ужас какой

И не говори...
В соседнем топике человек готов VTBL подменять, вместо того,
чтобы сделать DLL из статической либы.

Куда мир катится?
Re[9]: Перехват вызова не WINAPI функции
От: yar4i  
Дата: 17.12.08 07:55
Оценка:
Передо мной возникла подобная проблема, поэтому хотелось бы узнать о ваших результатах,вы решили поставленную задачу?
Меня интересует поиск по сигнатурам.В книге "Искусство взлома и защиты систем" авторов Джека Козиола и Дэвида Личфилда на 299 странице описана общая методика поиска по сигнатурам.Но, честно говоря, мне все еще слабо представляется как это можно реализовать на практике.
Re: Перехват вызова не WINAPI функции
От: Аноним  
Дата: 18.12.08 07:06
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Добрый день. В сети полно примеров перехвата апи функций. Меня заинтересовала данная тем и я наткнулся на вопрос, а как быть с функциями не импортируемыми из dll?

А>1. Ведь я так понимаю что когда в коде используется функция например из stdio.h, то в исполняемом файле она находится не в таблице импорта, а целиком помещается в сегмент кода?
А>2. Получается мне надо лопатить сегмент кода в поисках требуемой функции?
А>3. Что делать дальше? В начало функции писать jump на мою функцию ?
А>4. Есть ли какие то средства облегчающие проведение таких операций?

Читай здесь
Автор:
Дата: 18.12.08
. Это для тебя, просто не туда запостил.
Re[2]: Перехват вызова не WINAPI функции
От: yar4i  
Дата: 18.12.08 07:23
Оценка:
Здравствуйте, Аноним, Вы писали:
А>Читай здесь
Автор:
Дата: 18.12.08
. Это для тебя, просто не туда запостил.

это же перехват winapi функций!вопрос изначально стоял о перехвате функций которые не содержатся в таблице импорта.
Re[3]: Перехват вызова не WINAPI функции
От: Аноним  
Дата: 18.12.08 07:46
Оценка:
Здравствуйте, yar4i, Вы писали:

Y>Здравствуйте, Аноним, Вы писали:

А>>Читай здесь
Автор:
Дата: 18.12.08
. Это для тебя, просто не туда запостил.

Y>это же перехват winapi функций!вопрос изначально стоял о перехвате функций которые не содержатся в таблице импорта.


1. Ведь я так понимаю что когда в коде используется функция например из stdio.h, то в исполняемом файле она находится не в таблице импорта, а целиком помещается в сегмент кода?

Дык на сколько я понял задача ведь стояла перехватить что нить из stdio.h, а в частности файловые операции, просто подумал что вопрос стоит не корректно!
Re[4]: Перехват вызова не WINAPI функции
От: yar4i  
Дата: 20.12.08 19:26
Оценка:
Здравствуйте, Аноним, Вы писали:

А>1. Ведь я так понимаю что когда в коде используется функция например из stdio.h, то в исполняемом файле она находится не в таблице импорта, а целиком помещается в сегмент кода?


да

А>Дык на сколько я понял задача ведь стояла перехватить что нить из stdio.h, а в частности файловые операции, просто подумал что вопрос стоит не корректно!


ну чтобы понятнее было поставим задачу так:мы создали Unit1.h в нем есть функция void hook_me(),так же есть еще Unit2.cpp,в котором написано:
#include "Unit1.h";
...
hook_me();
...

Так вот задача в том чтобы перехватить функцию hook_me(),при том что исходники править нельзя.
Как мне видится копать нужно в направлении поиска функций по сигнатуре.Пока я не особо накопал,поэтому и спрашиваю вашего совета.
Re[5]: Перехват вызова не WINAPI функции
От: yar4i  
Дата: 28.12.08 17:53
Оценка:
В общем реализовал я таки сигнатурный поиск и перехват функции.Хочу поделиться кодом,может кому пригодится.На самом деле код скорее всего сыроват(еще не оптимизировал),но он работает и я, честно говоря, так счастлив что хочу скорее его опубликовать
Программа перехватывает функцию внутри самой себя,но если внедрить этот код в другой процесс,то можно перехватывать и чужие функции(если нужно внедрение могу выложить,но это отдельная песня).Итак код:

#include <stdio.h>
#include <windows.h>
#include <conio.h>

struct TInterceptInfo    //структура для перехвата
    {
        PVOID     FunctionAddr;     //адрес перехватываемой функции
        PVOID     HookAddr;         //адрес функции заменителя
        byte     FunctionCode[5];//первые пять байт перехватываемой функции
        byte     HookJmp[5];     //код с JMP
    };

TInterceptInfo* LStrCpyInterceptInfo; //массив структур,
int n=0; //количество структур

//функция устанавливает/убирает перехватчик
bool SetHookCode(TInterceptInfo InterceptInfo,bool ASetHook)
{
    bool Result=false;
    DWORD OldProtect,Tmp;
    int CodeSize=5;
    //изменяем режим доступа к странице памяти,где содержится перехватываемая функция
    VirtualProtect(InterceptInfo.FunctionAddr,CodeSize,PAGE_EXECUTE_READWRITE,&OldProtect);

    if (ASetHook)
        {//заменяем первые пять байт функции
            Result=WriteProcessMemory(GetCurrentProcess(),InterceptInfo.FunctionAddr,
                                      &InterceptInfo.HookJmp,CodeSize,NULL);
        }
    else {//убираем перехватчик
            Result=WriteProcessMemory(GetCurrentProcess(),InterceptInfo.FunctionAddr,
                                    &InterceptInfo.FunctionCode,CodeSize,NULL);            
        }
    //возвращаем предыдущий режим доступа к странице
    VirtualProtect(InterceptInfo.FunctionAddr,CodeSize,OldProtect,&Tmp);

    return(Result);    
}

//функция поиска последовательности байт в массиве байт
UINT FindAinB(BYTE* pbyB, BYTE* pbyA, UINT uiALen, UINT uiBLen)
{
  for (int i=0;i<uiBLen;i++)
  {
      if (pbyB[i]==pbyA[0]){
        if (memcmp(&pbyB[i], pbyA, uiALen) == 0) 
            return (UINT) i;
        }
      else continue;
  }
  return uiBLen;
}
//функция поиска сигнатуры и заполнения массива структур LStrCpyInterceptInfo
void Hooking(byte* signature,int length_str,TInterceptInfo* &InterceptInfo,PVOID HookFunc)
{
    DWORD Tmp;
    DWORD Jmp_Rel;
    UINT pdest=0;
    SIZE_T sizebuf=0;
    byte *pointer;
    byte *buffer;
    char tmpstr[16]="\0";
    DWORD  result;
    MEMORY_BASIC_INFORMATION mbi;
    int m_ptr = 0;
    SIZE_T readsize;
    HANDLE hProcess;

    hProcess=GetCurrentProcess();
    //читаем постранично память процесса
    while(VirtualQueryEx(hProcess, (void *)m_ptr, &mbi, sizeof(mbi)) > 0){
        buffer=(byte*)malloc(mbi.RegionSize);
        readsize=0;
        //всю страницу кладем в buffer
        if(ReadProcessMemory(hProcess,mbi.BaseAddress,buffer,mbi.RegionSize,&readsize)){
            if (readsize>0)
                {
                    //ида всегда показывала что сегмент кода начинается с этого адреса
                    //+ в рихтере написано что это адрес сегмента кода,ну как то так,
                    //собственно эту проверку можно убрать и тогда будут сканироваться все
                    //страницы адресного пространства процесса
                    if (((DWORD)mbi.BaseAddress+(DWORD)mbi.RegionSize)>0x00401000) //рут функция?
                    {
                    pdest = 0;
                    pointer = buffer;
                    sizebuf = readsize;
                    for(;;)
                    {
                    //ищем сигнатуру
                    pdest = FindAinB(pointer,signature,length_str,sizebuf);
                    if ( pdest != sizebuf ){
                        //нашли сигнатуру,она находится по адресу result
                        result = (DWORD)mbi.BaseAddress+(pointer-buffer)+pdest;
                        printf( "Signature found at position 0x%08x\n", result );
                        //выделяем память под структуру InterceptInfo
                        n++;
                        if (n==1)    InterceptInfo=(TInterceptInfo*)malloc(n);
                        else InterceptInfo=(TInterceptInfo*)realloc(InterceptInfo,n);
                        //и начинаем ее заполнять
                        InterceptInfo[n].FunctionAddr=(PVOID)result;
                        InterceptInfo[n].HookAddr=HookFunc;
                        //вычисление адреса на который нужно сделать jmp
                        //формирование 5 байт для перехвата
                        ReadProcessMemory(GetCurrentProcess(),InterceptInfo[n].FunctionAddr,&InterceptInfo[n].FunctionCode,5,NULL);
                        Jmp_Rel=(DWORD)InterceptInfo[n].HookAddr-(DWORD)InterceptInfo[n].FunctionAddr-5;
                        InterceptInfo[n].HookJmp[0]=0xE9;
                        CopyMemory(&InterceptInfo[n].HookJmp[1],&Jmp_Rel,4);
                        //идем дальше по буферу в поисках сигнатуры
                        pointer=(byte*)((int)pointer+pdest+length_str);
                        sizebuf=sizebuf-pdest-length_str;
                    }
                    else{
                            break;
                        }
                    }
                    }
                }
            }
        //следующая страница
        m_ptr=(int)mbi.BaseAddress+mbi.RegionSize;
        free(buffer);
    }
}
//перехватываемая функция копирует одну строку в другую
LPSTR my_copy(LPSTR dest,LPSTR src,int n)
{
    LPSTR retval;
    for (int i=0;i<n;i++) dest[i]=src[i];
    dest[n]='\0';
    retval=dest;
    return retval;
}
//функция заменитель копирует строку задом наперед
LPSTR my_copy2(LPSTR dest,LPSTR src,int n)
{
    LPSTR retval;
    for (int i=0;i<n;i++) dest[i]=src[n-i-1];
    dest[n]='\0';
    retval=dest;
    return retval;
}

int main()
{
    char dest[20];
    char src[]="1234";
    //сигнатура my_copy

byte signature[]="\x55\x8b\xec\x81\xec\xd8\x00\x00\x00\x53
\x56\x57\x8d\xbd\x28\xff\xff\xff\xb9\x36\x00\x00\x00\xb8\xcc\xcc\xcc
\xcc\xf3\xab\xc7\x45\xec\x00\x00\x00\x00\xeb\x09\x8b\x45\xec\x83\xc0
\x01\x89\x45\xec\x8b\x45\xec\x3b\x45\x10\x7d\x12\x8b\x45\x08\x03";

    int length_str=60;//ее длина

    my_copy(dest,src,4);    //копируем без перехватчика
    printf("%s\n",dest);

    //ищем сигнатуру,заменяем первые 5 байт перехватываемой функции,
    //кодом перехватчика
    Hooking(signature,length_str,LStrCpyInterceptInfo,&my_copy2); 
    
    SetHookCode(LStrCpyInterceptInfo[1],true);//установили хук

    my_copy(dest,src,4);    //копируем
    printf("%s\n",dest);    //но функция перехвачена и выводится результат работы my_copy2

    SetHookCode(LStrCpyInterceptInfo[1],false);//сняли хук

    my_copy(dest,src,4); //копируем
    printf("%s\n",dest); //все хоккей!!!

    free(LStrCpyInterceptInfo);
    getch();
    return 0;
}


Вуаля!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.