Форум программистов, компьютерный форум CyberForum.ru

C++

Войти
Регистрация
Восстановить пароль
 
killsyx
0 / 0 / 0
Регистрация: 09.05.2015
Сообщений: 6
#1

Перехват пользовательских функций (процедур) - C++

12.06.2015, 13:54. Просмотров 330. Ответов 3
Метки нет (Все метки)

Возможно перехватить API сообщение или функцию, а также любую другую ф-цию вызываемую из библиотеки. Но есть ли возможность перехватить пользовательскую ф-цию, которая выполняется непосредственно в exe файле???
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
12.06.2015, 13:54     Перехват пользовательских функций (процедур)
Посмотрите здесь:

помогите с создание пользовательских функций C++
Программирование пользовательских функций C++
C++ Разработка и отладка алгоритмов и программ с применением пользовательских функций
Исправить программу.Создание пользовательских функций. C++
C++ Создание пользовательских функций
C++ Создание пользовательских функций
C++ Выполнить программу с использованием пользовательских функций
C++ Разработка и отладка алгоритмов и программ с применением пользовательских функций
C++ Обработка массивов данных с использование пользовательских функций
Обработка двумерного массива с использование пользовательских функций C++
C++ Вызов различных пользовательских функций с помощью switch
Использование пользовательских функций в WM_PAINT C++ WinAPI

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
7046 / 5223 / 259
Регистрация: 10.12.2010
Сообщений: 22,966
Записей в блоге: 17
13.06.2015, 22:03     Перехват пользовательских функций (процедур) #2
Нет нельзя.

Не по теме:

И так умер очередной недохакер ))

Kastaneda
Форумчанин
Эксперт С++
4264 / 2796 / 219
Регистрация: 12.12.2009
Сообщений: 7,122
Записей в блоге: 1
Завершенные тесты: 1
17.06.2015, 11:31     Перехват пользовательских функций (процедур) #3
Вообще можно подхачить экзешник - встроить туда свой код, который будет при каждом вызове нужной процедуры что-то делать. Только зачем? В экзешнике даже имен функций то нет.
hoggy
6012 / 2452 / 438
Регистрация: 15.11.2014
Сообщений: 5,432
Завершенные тесты: 1
17.06.2015, 23:30     Перехват пользовательских функций (процедур) #4
http://yandex.ru/search/?text=%D1%81...D0%B3&lr=21630


простейший пример:

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
// InterceptFunc.h
 
#ifndef __INTERCEPT_H_
#define __INTERCEPT_H_
 
#define METHOD_JUMP        // закоментировать для метода перехвата поиском в таблице .idata!
 
 
#pragma pack(1)
struct jmp_far
{
    BYTE instr_push;  //здесь будет код инструкции push
    DWORD arg;         //аргумент push
    BYTE  instr_ret;    //здесь будет код инструкции ret
};
#pragma pack()
 
 
#ifndef METHOD_JUMP
bool InterceptFunction(char *NameDllIntercept, char *NameFunIntercept, void *myfun, void *apifun);
#else
bool InterceptFunction(char *NameDllIntercept, char *NameFunIntercept, void *myfun, void *apifun, char *argold, jmp_far *argjump);
extern DWORD _interceptapiwritten;
#endif
 
#ifdef METHOD_JUMP  //затирание/восстановление кода
#define INTERCEPT_BEGIN(a) WriteProcessMemory(GetCurrentProcess(), (void*)adr_##a, (void*)old_##a, 6, &_interceptapiwritten);
#define INTERCEPT_END(a) WriteProcessMemory(GetCurrentProcess(), (void*)adr_##a, (void*)&jump_##a, 6,&_interceptapiwritten);
#define InterceptAPIF(a,b) InterceptFunction(a, #b, &ic##b, &adr_##b, old_##b, &jump_##b);
#define INTERCEPT_DECLARE_INFO(a) char old_##a##[6]; jmp_far jump_##a##; DWORD adr_##a##;
#define INTERCEPT_REALCALL(a) a
#else
#define INTERCEPT_BEGIN(a)
#define INTERCEPT_END(a)
#define InterceptAPIF(a,b) InterceptFunction(a, #b, &ic##b, &adr_##b);
#define INTERCEPT_DECLARE_INFO(a) DWORD adr_##a##;
#define INTERCEPT_REALCALL(a) ((BOOL (__stdcall*)(...))adr_##a)
#endif
#endif
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
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include <stdio.h>
#include <windows.h>
 
#include "InterceptFunc.h"
 
 
//=============================================================================
// Эта функция ищет в таблице импорта - .idata нужный адрес и меняет на
// адрес процедуры-двойника
#ifndef METHOD_JUMP
bool InterceptFunction(char *NameDllIntercept, char *NameFunIntercept, void *myfun, void *apifun)
{
    int i;
    char strbuf[2048];
    // Начало отображения в памяти процесса
    BYTE *pimage = (BYTE*)GetModuleHandle(NULL);
    BYTE *pidata;
    // Стандартные структуры описания PE заголовка
    IMAGE_DOS_HEADER *idh;
    IMAGE_OPTIONAL_HEADER *ioh;
    IMAGE_SECTION_HEADER *ish;
    IMAGE_IMPORT_DESCRIPTOR *iid;
    DWORD *isd;  //image_thunk_data dword
 
    // Получаем указатели на стандартные структуры данных PE заголовка
    idh = (IMAGE_DOS_HEADER*)pimage;
    ioh = (IMAGE_OPTIONAL_HEADER*)(pimage + idh->e_lfanew
        + 4 + sizeof(IMAGE_FILE_HEADER));
    ish = (IMAGE_SECTION_HEADER*)((BYTE*)ioh + sizeof(IMAGE_OPTIONAL_HEADER));
    //если не обнаружен магический код, то у этой программы нет PE заголовка
    if (idh->e_magic != 0x5A4D)
    {
        MessageBox(NULL, "Not exe hdr", "Error!", 0);
        return false;
    }
 
    //ищем секцию .idata
    for(i=0; i<16; i++)
        if(strcmp((char*)((ish+ i)->Name) , ".idata") == 0) break;
    if(i==16)
    {
        MessageBox(NULL, "Unable to find .idata section", "Error!", 0);
        return false;
    }
 
    // Получаем адрес секции .idata(первого элемента IMAGE_IMPORT_DESCRIPTOR)
    iid = (IMAGE_IMPORT_DESCRIPTOR*)(pimage + (ish +i)->VirtualAddress );
 
    // Получаем абсолютный адрес функции для перехвата
    *(DWORD*)apifun = (DWORD)GetProcAddress(
        GetModuleHandle(NameDllIntercept), NameFunIntercept);
    if(*(DWORD*)apifun == 0)
    {
        sprintf(strbuf, "Can`t get addr %s", NameFunIntercept);
        MessageBox(NULL, strbuf, "Error!", 0);
        return false;
    }
 
    // В таблице импорта ищем соответствующий элемент для
    // библиотеки user32.dll
    while(iid->Name)  //до тех пор пока поле структуры не содержит 0
    {
        if(strcmp((char*)(pimage + iid->Name), NameDllIntercept) ==0 ) break;
        iid++;
    }
 
    // Ищем в IMAGE_THUNK_DATA нужный адрес
    isd = (DWORD*)(pimage + iid->FirstThunk);
    while(*isd!=*(DWORD*)apifun && *isd!=0)  isd++;
    if(*isd == 0)
    {
        sprintf(strbuf, "addr %s not found in .idata", NameFunIntercept);
        MessageBox(NULL, strbuf, "Error!", 0);
        return false;
    }
 
    // Заменяем адрес на свою функцию
 
    DWORD buf =  (DWORD)myfun;
    DWORD op;
 
    DWORD written;
 
    // Обычно страницы в этой области недоступны для записи
    // поэтому принудительно разрешаем запись
    VirtualProtect((void*)(isd),4,PAGE_READWRITE, &op);
 
    // Пишем новый адрес
    WriteProcessMemory(GetCurrentProcess(), (void*)(isd),
        (void*)&buf,4,&written);
    //восстанавливаем первоначальную защиту области по записи
    VirtualProtect((void*)(isd),4,op, &op);
    //если записать не удалось - увы, все пошло прахом:
    if(written!=4)
    {
        MessageBox(NULL, "Unable rewrite address", "Error!", 0);
        return false;
    }
    return true;
}
#endif
//=============================================================================
#ifdef METHOD_JUMP
DWORD _interceptapiwritten;
bool InterceptFunction(char *NameDllIntercept, char *NameFunIntercept, void *myfun, void *apifun, char *argold, jmp_far *argjump)
{
    char sbuf[2048];
    char* old = argold;
    jmp_far &jump = *argjump;
 
#define adr_ (*(DWORD*)apifun)
 
    adr_ = (DWORD)GetProcAddress(GetModuleHandle(NameDllIntercept), NameFunIntercept);
    if(adr_ == 0)
    {
        printf(sbuf, "Can't get addr %s", NameFunIntercept);
        MessageBox(NULL, sbuf, "Error!", 0);
        return false;
    }
 
    // Зададим машинный код инструкции перехода, который затем впишем
    // в начало полученного адреса:
    jump.instr_push = 0x68;
    jump.arg = (DWORD)myfun;
    jump.instr_ret = 0xC3;
 
 
    DWORD op;
    DWORD *isd = (DWORD*)adr_;  //image_thunk_data dword
    // поэтому принудительно разрешаем запись
    VirtualProtect((void*)(isd),4,PAGE_READWRITE, &op);
 
    //Прочитаем и сохраним первые оригинальные 6 байт стандартной API функции
    ReadProcessMemory(GetCurrentProcess(),(void*) adr_,
        (void*)old, 6, &_interceptapiwritten);
 
    //Запишем команду перехода на нашу функцию поверх этих 6-ти байт
    WriteProcessMemory(GetCurrentProcess(), (void*)adr_,
        (void*)&jump, sizeof(jmp_far), &_interceptapiwritten);
 
    //восстанавливаем первоначальную защиту области по записи
    VirtualProtect((void*)(isd),4,op, &op);
 
    return true;
}
#endif
//=============================================================================
код примитивен и служит исключительно для ознакомительных целей.
код имеет массу недостатков.
например: не безопасен в многопоточной среде.
и не рекомендован для использования в реальной практике.


/зы
в интернетах можно поискать:
есть специализированные библиотеки для действительно качественного перехвата.
жаль названия запамятовал.
Yandex
Объявления
17.06.2015, 23:30     Перехват пользовательских функций (процедур)
Ответ Создать тему
Опции темы

Текущее время: 04:18. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru