0 / 0 / 0
Регистрация: 27.12.2015
Сообщений: 2
1

Перехват API вызовов

28.12.2015, 00:21. Показов 1695. Ответов 3
Метки нет (Все метки)

Здравствуйте! Пытаюсь перехватить вызов функции CreateFileW и заменить на свою MyCreateFileW. Для этого в процесс(тестовая программа, совершающая копирование при нажатии на кнопку) внедряется библиотека(код представлен ниже). С внедрением проблем нет, но получается, что в таблице импорта нет ссылки на нужную функцию.
При попытке, например, перехвата MeesageBoxW, происходит тоже самое.
Подскажите, пожалуйста, как решить проблему, может в коде ошибка?
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
#define _CRT_SECURE_NO_WARNINGS
#include "stdafx.h"
#include "MyFunctionsDll.h"
#include "windows.h"
#include "Tlhelp32.h"
#include "Imagehlp.h"
#include <fstream>
#include <string>
#include <string.h>
#pragma comment(lib, "Dbghelp.lib")
void GetCurrentProcessName(ULONG ID ,LPSTR szExeName);
void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller);
void INIT ();
HMODULE GetCurrentModule();
int WINAPI MyMessageBox(HWND hWnd,LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
BOOL WINAPI MyCopyFileW(LPCWSTR, LPCWSTR ,BOOL);
BOOL WINAPI DllMain(HMODULE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{ 
    switch( fdwReason ){
        case DLL_PROCESS_ATTACH:
            { 
INIT();
            }
 
            break;
        case DLL_THREAD_ATTACH: 
            break;
        case DLL_THREAD_DETACH: 
            break;
        case DLL_PROCESS_DETACH: 
            break;     
    return TRUE;  
}
 
void INIT (HMODULE)
{
    PROC pfnOrig = GetProcAddress(GetModuleHandle((LPCWSTR)"krenel32"), "CopyFileW");   
    PROC pfnMy = GetProcAddress(GetCurrentModule(), "MyCopyFileW");
    HMODULE hmodCaller = GetModuleHandle(0);//получение хендла тек процесса   
    ReplaceIATEntryInOneMod("kernel32.DLL", pfnOrig, pfnMy, GetCurrentModule());
       return;
}
 
HMODULE GetCurrentModule()
{
    DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS;
    HMODULE hm = 0;
    ::GetModuleHandleEx( flags, reinterpret_cast<LPCTSTR>( GetCurrentModule ), &hm );   
    return hm;
} 
BOOL WINAPI MyCopyFileW(_In_ LPCWSTR lpExistingFileName, _In_ LPCWSTR lpNewFileName, _In_ BOOL bFailIfExists)
{
    BOOL res = CopyFileW((LPCWSTR)"c:\\1\\MyHookDll.dll", (LPCWSTR)"c:\\Users\\win7user\\Desktop\\My1.dll", bFailIfExists);
    return res;
}
void GetCurrentProcessName(ULONG ID ,LPSTR szExeName)
{
        PROCESSENTRY32 Pc = { sizeof(PROCESSENTRY32) };
        HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, 0);
        if(Process32First(hSnapshot, &Pc))
        {
                do
                {
                        if(Pc.th32ProcessID==ID)
                        {
                                strcpy(szExeName,(const char*)Pc.szExeFile);
                                return ;
                        }
                }
                while(Process32Next(hSnapshot, &Pc));
        }
}
 
 void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
{
    ULONG ulSize;
 
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)ImageDirectoryEntryToData(hmodCaller, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
 
    if (pImportDesc == NULL) return;
 
    for (; pImportDesc->Name; pImportDesc++)
    {
        PSTR pszModName = (PSTR)((PBYTE)hmodCaller + pImportDesc->Name);
 
        if (lstrcmpiA(pszModName, pszCalleeModName) == 0) break;
    }
 
    PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)((PBYTE)hmodCaller + pImportDesc->FirstThunk);
 
    for (; pThunk->u1.Function; pThunk++)
    {
        if ((PROC)pThunk->u1.Function == pfnCurrent)
        {
            DWORD old = 0;          
            VirtualProtect(&pThunk->u1.Function, 4, PAGE_READWRITE, &old);
            pThunk->u1.Function = (DWORD)pfnNew;
            VirtualProtect(&pThunk->u1.Function, 4, old, &old); 
            return;
        }
    } 
}
__________________
Помощь в написании контрольных, курсовых и дипломных работ здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.12.2015, 00:21
Ответы с готовыми решениями:

Перехват API вызовов через таблицу импорта
Доброго времени суток. Есть следующая задача. Нужно перехватить вызов некоторых определённых...

Перехват API
Сразу код ) DWORD dwProtect = PAGE_READWRITE; BYTE old; BYTE * fPtr; #pragma...

Перехват API функции
Доброго времени суток всем! Уважаемые форумчене помогите решить задачу, я взял функцию MessageBox и...

Перехват API функций
Разработать программу, которая запускает приложение, переданное программе на вход. После запуска...

3
Ушел с форума
Эксперт С++
16429 / 7393 / 1186
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
28.12.2015, 00:26 2
C++
1
PROC pfnOrig = GetProcAddress(GetModuleHandle((LPCWSTR)"krenel32"), "CopyFileW");
Опечатка. Нет в системе такого модуля - krenel32, есть kernel32.

C++
1
2
3
4
5
6
7
HMODULE GetCurrentModule()
{
    DWORD flags = GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS;
    HMODULE hm = 0;
    ::GetModuleHandleEx( flags, reinterpret_cast<LPCTSTR>( GetCurrentModule ), &hm );   
    return hm;
}
Жуть. Проще сразу взять HMODULE из DllMain и не мучиться.

Вместо GetCurrentProcessName можно использовать GetModuleFileName с NULL.

C++
1
pThunk->u1.Function = (DWORD)pfnNew;
Приведение указателя (8 байт на x64) к DWORD (всегда 4 байта) чревато,
лучше так никогда не делать.

Да, и проверки ошибок тоже не видно. Я бы этот код выбросил на помоечку и
написал с нуля, аккуратно, вдумчиво...
0
0 / 0 / 0
Регистрация: 27.12.2015
Сообщений: 2
28.12.2015, 01:14  [ТС] 3
Спасибо, исправила первые 2 ошибки, но не получилось. Заменила ReplaceIATEntryInOneMod, но все равно не получается, выводит MessageBox.
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
void ReplaceIATEntryInOneMod(PCSTR pszCalleeModName, PROC pfnCurrent, PROC pfnNew, HMODULE hmodCaller)
{                   
    ULONG ulSize = 0;
    PIMAGE_SECTION_HEADER* pImSecHead = NULL;
    PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR) ImageDirectoryEntryToData(hmodCaller, TRUE,IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);
    
    if (pImportDesc == NULL) 
            return; 
    for (; pImportDesc->Name; pImportDesc++) 
    {
        PSTR pszModName = (PSTR) ((PBYTE) hmodCaller + pImportDesc->Name);
        if (lstrcmpiA(pszModName, pszCalleeModName) == 0)
            break;
    }
    if (pImportDesc->Name == 0) 
        return;
    PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA) ((PBYTE) hmodCaller + pImportDesc->FirstThunk); 
    for (; pThunk->u1.Function; pThunk++) 
    { 
        PROC* ppfn = (PROC*) &pThunk->u1.Function;
        BOOL fFound = (*ppfn == pfnCurrent);
        if (fFound) 
        {
                DWORD dwDummy;
                 VirtualProtect(ppfn, sizeof(ppfn), PAGE_EXECUTE_READWRITE, &dwDummy);
                WriteProcessMemory(GetCurrentProcess(), ppfn, &pfnNew, sizeof(pfnNew), NULL);
                VirtualProtect(ppfn, sizeof(ppfn), dwDummy , &dwDummy);
                return;
        }
    }
    MessageBox(0,(LPCWSTR)"2",(LPCWSTR)"2",0);
}
Добавлено через 25 минут
Поменяла INIT, сообщения нет, но перехвата не происходит
C++
1
2
3
4
5
6
7
8
void INIT (HMODULE hinstDLL)
{
    PROC pfnOrig = GetProcAddress(GetModuleHandle((LPCWSTR)"kernel32.dll"), "CopyFileW"); 
    PROC pfnMy = GetProcAddress(hinstDLL, "MyCopyFileW");
    HMODULE hmodCaller = GetModuleHandle(NULL);
    ReplaceIATEntryInOneMod("kernel32.DLL", pfnOrig, pfnMy, GetModuleHandle(NULL));
    return;
}
0
Ушел с форума
Эксперт С++
16429 / 7393 / 1186
Регистрация: 02.05.2013
Сообщений: 11,617
Записей в блоге: 1
28.12.2015, 10:54 4
Тут проблема не в коде, а в его оформлении. Продолжай исправлять ошибки.
Например, нужно убрать приведение к LPCWSTR здесь (и в других схожих местах):

C++
1
PROC pfnOrig = GetProcAddress(GetModuleHandle((LPCWSTR)"kernel32.dll"), "CopyFileW");
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.12.2015, 10:54

Перехват API, Рихтер
Всем доброго времени суток! Собственно такой вопросик... я вот читаю сейчас Рихтера и мне интересен...

Перехват API с возвратом значения
Я тут решил разобраться в перехвате API с помощью инжектированной dll. Спустя 2 дня написал...

Перехват API функций. Таблица импорта
Необходимо лoггиpoвaть вызовы некоторых API-шных функций (для примера CloseHandle) в заданном...

Перехват api-вызова. Ошибка при выполнении
Здравствуйте, есть dll-ка, которая успешно внедряется во все(или почти все) оконные приложения с...

Перенаправление файловых потоков, перехват системных вызовов
Есть несколько программ, например C:\p1dir\prog1.exe, C:\p2dir\prog2.exe, C:\p3dir\prog3.exe каждая...

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


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

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

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