Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++

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

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

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

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

Перехват и подмена вызываемых функций - C++
Здравствуйте. Нужно подменить вызов таких функций как open(), lstat(), stat(), read(), write(), mkdir(), chdir(), getcwd() для...

Статья на rsdn, перехват API-функций - C++
Разбираю статью на рсдн, а именно Метод 1. Перехват API непосредственной записью в код системной функции. dll вроде скомпилировал, дошел...

Преобразование заголовков процедур паскаля в заголовки функций С++ - C++ Builder
В тексте программы на паскале преобразовать заголовки процедур в заголовки функций С++(не трогая аргументов).

Копирование объектов пользовательских классов - C++ Builder
Доброго времени суток) Есть вот такие структуры: Struct A { Shape *S; }; Struct B

Переопределение операторов внутри пользовательских классов - C++ Builder
Проблема: Например, создан класс комплексных чисел (или вообще любой).. Как внутри него правильно переопределять операторы (напр.,...

Создание окна для выдачи пользовательских ошибок - C++ Builder
Имеется программа, которая создаёт внутри себя несколько потоков. Каждый поток внутри себя может выдавать пользовательское сообщение об...

3
Avazart
Эксперт С++
7246 / 5418 / 297
Регистрация: 10.12.2010
Сообщений: 24,042
Записей в блоге: 17
13.06.2015, 22:03 #2
Нет нельзя.

Не по теме:

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

0
Kastaneda
Jesus loves me
Эксперт С++
4688 / 2892 / 236
Регистрация: 12.12.2009
Сообщений: 7,354
Записей в блоге: 2
Завершенные тесты: 1
17.06.2015, 11:31 #3
Вообще можно подхачить экзешник - встроить туда свой код, который будет при каждом вызове нужной процедуры что-то делать. Только зачем? В экзешнике даже имен функций то нет.
0
hoggy
6691 / 2873 / 493
Регистрация: 15.11.2014
Сообщений: 6,465
Завершенные тесты: 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
//=============================================================================
код примитивен и служит исключительно для ознакомительных целей.
код имеет массу недостатков.
например: не безопасен в многопоточной среде.
и не рекомендован для использования в реальной практике.


/зы
в интернетах можно поискать:
есть специализированные библиотеки для действительно качественного перехвата.
жаль названия запамятовал.
0
17.06.2015, 23:30
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
17.06.2015, 23:30
Привет! Вот еще темы с ответами:

Перегрузка функций, шаблоны функций Функция определения объемов: шара по его радиусу - C++ Builder
Перегрузка функций, шаблоны функций Функция определения объемов: шара по его радиусу (V=4/3пиR2), конуса по радиусу основания и высоте...

Применение пользовательских процедур - Delphi
В каждом из массивов P(7), T(8) вычислить сумму положительных и сумму отрицательных элементов. Повторяющуюся часть реализовать с помощью...

написание пользовательских процедур на языке ассемблер - Assembler
y = (x – 1)! + x помогите как написать на ассемблере

построить в разных системах координат при x[-1,5;1,5] графики следующих функций с использо-ванием пользовательских функций - MS Excel
построить в разных системах координат при x графики следующих функций с использо-ванием пользовательских функций


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

Или воспользуйтесь поиском по форуму:
4
Ответ Создать тему
Опции темы

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