Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

HookAPI

3
15 декабря 2006 года
Green
4.8K / / 20.01.2000
Вот в коем разе решил поделиться наработками... :)
Взять можно здесь: http://sources.codenet.ru/download/1205/HookApi_h.html

HookApi - базовый класс для перехвата вызовов функций API из текущего процесса.
Класс позволяет как мониторить вызовы (перехватывать и отдавать управление в реальную функцию API), так и самостоятельно обрабатывать вызовы (возвращать управление вызывающему коду, не передавая управление в реальную функцию API).

ВНИМАНИЕ! Код перехвата изменяет значения регистра ECX.
Для моих целей это было нестрашно, но для ваших может быть серьезной помехой. Так что применяйте обдуманно.


Использовать класс очень просто. Наследуете от него класс для перехвата определенной функции API, переопределеяте в наследнике виртуальный метод handler. Для удобства установки хука можно определить ещё специальный метод hook.

Подробнее о виртуальном методе handler:
 
Код:
virtual DWORD HookApi::handler(void** stack, PDWORD result);

Аргументы:
stack - указатель на вершину стека при вызове API, т.е. по большому счету указатель на адрес возврата, за которым следуют параметры вызова.
result - указатель на возвращаемое вместо API-функции значение. Если установленный хук сам обрабатывает вызов не передавая управление в реальную функцию API, то в DWORD, на который указывает result, должно быть помещено якобы возвращаемое из API-функции значение.

Возвращаемое значение:
Если меньше нуля, то это значит, что управление из перехватчика будет передано в реальную функцию;
Если больше, либо равно нулю, то это размер аргументов на стеке передаваемых в API-функцию. Т.к. API-функции имеют спецификацию cdecl, т.е. обязаны сами очищать стек, от переданных им параметров, а количество переданных параметров зависит от конкретной функции, то при эмуляции (перехвате с обработкой без вызова реальной API-функции) перехватывающий код должен сам очистить стек от этих параметров, а для этого надо указать сколько они занимали места на стеке.

Пример использования:
Код:
#include <windows.h>
#include <iostream>
using namespace std;

#include "HookApi.h"


//
// Перехватчик API-функции NtOpenFile
//
class HookNtOpenFile :public HookApi
{
public:
    bool hook() {
        return HookApi::hook("ntdll", "NtOpenFile");
    }

private:
    virtual DWORD handler(void** stack, PDWORD result) {
        wcout << "HookNtOpenFile" << endl;

        return -1;    // Передаем управление в реальную API-функцию
    }
};


//
// Перехватчик API-функции RtlDosSearchPath_U
//
class HookRtlDosSearchPath_U :public HookApi
{
public:
    bool hook() {
        return HookApi::hook("ntdll", "RtlDosSearchPath_U");
    }

private:
    virtual DWORD handler(void** stack, PDWORD result) {
        // читаем параметры вызова из стека
        PWSTR  lpPath        = (PWSTR)stack[1];
        PWSTR  lpFileName    = (PWSTR)stack[2];
        PWSTR  lpExtension   = (PWSTR)stack[3];
        ULONG  nBufferLength = (ULONG)stack[4];
        PWSTR  lpBuffer      = (PWSTR)stack[5];
        PWSTR* lpFilePart    = (PWSTR*)stack[6];

        wcout << "HookRtlDosSearchPath_U: " << endl;
        wcout << lpPath << endl;
        wcout << lpFileName << endl;

        // Здесь производим собственную обработку
        ...................................

        *result = 0;    // Выставляем возвращаемое в вызывающий код значение

        return 6 * sizeof(DWORD);    // Возвращаем управление в вызывающий
                                               // код без передачи в реальную API-функцию.
                                              // Шесть параметров занимают на стеке 6 * sizeof(DWORD)
    }
};


int main()
{
    // Устанавливаем хуки
    HookNtOpenFile hookNtOpenFile;
    hookNtOpenFile.hook();

    HookRtlDosSearchPath_U hookRtlDosSearchPath_U;
    hookRtlDosSearchPath_U.hook();
 
    // Код вызывающий прохученные функции
    ................................

    return 0;
Страницы:
261
15 декабря 2006 года
ahilles
1.5K / / 03.11.2005
жаль что код сишный потому что я дельфист
а так то нормально, цивильно
ну надо же придумать через объект устанаваливать перехват на АПИ
63
15 декабря 2006 года
Zorkus
2.6K / / 04.11.2006
Впечатляет...тут копать и копать:).
P.S. Прохученные - какое слово-то нашел... ладно хоть не хуканутые:D
3
24 декабря 2006 года
Green
4.8K / / 20.01.2000
HookApi v2.0
Вторая версия базового класса для перехвата вызовов функций API из текущего процесса.
Взять можно здесь: http://sources.codenet.ru/download/1225/HookApi_v2_0.html

Класс позволяет как мониторить вызовы (перехватывать и отдавать управление в реальную функцию API), так и самостоятельно обрабатывать вызовы (возвращать управление вызывающему коду, не передавая управление в реальную функцию API).

Основное отличие от первой версии в том, что теперь параметры обрабатывающей функции такие же, как у функции, на которую этот хук поставлен. Т.о. можно просто скопировать объявление API-функции и заменить её имя на handler и описание функции перехвата готово.
Добавлена возможность снятия хука (метод unhook), в т.ч. через деструктор объекта (в деструкторе базового класса вызывается метод unhook).
Теперь код перехвата не изменяет значения регистра ECX.
Единственный регистр, значение которого изменяется, - это EAX.

Использовать класс очень просто. Наследуете от него класс для перехвата определенной функции API, определеяте в наследнике метод handler (теперь не виртуальный). Параметры этого метода (аргументы и возвращаемое значение) должны быть такие же, как у функции, которую перехватываем.
Внимание: базовый класс является шаблонным, наследоваться нужно от него, инстациированого дочерним классом (см. пример использования).

Для того, чтобы после обработки перехватчиком управление не было передано в реальную функцию, необходимо вызвать метод setHandled.

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

Пример использования:
Код:
#define _WIN32_WINNT    0x0500

#include <windows.h>
#include <winternl.h>
#include <iostream>
using namespace std;

#include "HookApi.h"


class HookNtOpenFile :public HookApi<HookNtOpenFile>
{
public:
    bool hook() {
        return HookApi::hook("ntdll", "NtOpenFile");
    }

    NTSTATUS handler(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock,
        IN ULONG ShareAccess, IN ULONG OpenOptions)
    {
            wcout << "HookNtOpenFile: " << ObjectAttributes->ObjectName->Buffer << endl;
            return 0;
    }
};


#define STATUS_OBJECT_NAME_NOT_FOUND     ((NTSTATUS)0xC0000034L)

class HookNtOpenSection :public HookApi<HookNtOpenSection>
{
public:
    bool hook() {
        return HookApi::hook("ntdll", "NtOpenSection");
    }

    NTSTATUS handler(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess,
            IN POBJECT_ATTRIBUTES ObjectAttributes)
    {
        wcout << "NtOpenSection: " << ObjectAttributes->ObjectName->Buffer << endl;

        if( !wcsicmp(ObjectAttributes->ObjectName->Buffer, L"USER32.DLL") ) {
            cout << "BINGO!" << endl;
            *SectionHandle = NULL;
            setHandled();                         // Возвращаем управление в вызывающий
            return STATUS_OBJECT_NAME_NOT_FOUND;  //код без передачи в реальную API-функцию.
           
        }

        return 0;
    }
};


int main()
{
    HookNtOpenFile hookNtOpenFile;
    hookNtOpenFile.hook();

    HookNtOpenSection hookNtOpenSection;
    hookNtOpenSection.hook();

    HMODULE nMod = LoadLibrary("user32.dll");

    return 0;
}


P.S. Обратите внимание, что теперь не надо указывать сколько аргументов функция принимает, это делается автоматически (для функций, у которых до 16 аргументов). Как это делается можно узнать, взглянув в файл ArgumentsCount.h.
Может кто-то предложит способ сделать это изящнее?

Ещё обратите внимание на шаблон super_cast. :D
63
24 декабря 2006 года
Zorkus
2.6K / / 04.11.2006
Как я понимаю, невозможно сделать, чтобы значения всех регистров оставались целыми?
P.S. Спасибо за пример:)
3
24 декабря 2006 года
Green
4.8K / / 20.01.2000
Цитата: Zorkus
Как я понимаю, невозможно сделать, чтобы значения всех регистров оставались целыми?



Да нет, возможно. Только для EAX это не требуется, т.к. в нем, все равно, будет возвращаемое значение.

Цитата: Zorkus
P.S. Спасибо за пример


На этот раз пример использования вполне рабочий. Можно скопировать, построить и запустить.
Если интересно, могу рассказать в чем его суть (что он делает). Это хитрый пример. ;)

63
26 декабря 2006 года
Zorkus
2.6K / / 04.11.2006
Цитата: Green
Да нет, возможно. Только для EAX это не требуется, т.к. в нем, все равно, будет возвращаемое значение.


На этот раз пример использования вполне рабочий. Можно скопировать, построить и запустить.
Если интересно, могу рассказать в чем его суть (что он делает). Это хитрый пример. ;)


Интересно, конечно...только вот я асм плохо знаю:) так что не знаю как понимать буду.

63
26 декабря 2006 года
Zorkus
2.6K / / 04.11.2006
Цитата: Green
Да нет, возможно. Только для EAX это не требуется, т.к. в нем, все равно, будет возвращаемое значение.


Вот про это интересно. В мсдене про это как то невнятно написано. Я так понимаю, при любом формате вызова, 4 регистра сохраняются, ESI , EDI , EBX , EBP. А как быть с остальными?
Вот, например, EFLASS. В нем что то остается неизменно? или нет?

3
27 декабря 2006 года
Green
4.8K / / 20.01.2000
Если мы говорим про ассемблер, то если сам не позаботишься, ничего не сохранится.
Сохранять надо самому, обычно на стеке. Т.е. в начале функции сохраняешь все регистры, которые будешь использовать, а при выходе восстанавливаешь:
push ebp
push ebx
..........
pop ebx
pop ebx

Что касается специальных регистров (epi, efl), то их значения, на сколько мне известно, напрямую не сохранить, да и зачем?
7
28 декабря 2006 года
@pixo $oft
3.4K / / 20.09.2006
А PushAD/PushF+PopAD/PopF не судьба использовать?
2 Green:ну ты,зелёный,сказал-epi
9
28 декабря 2006 года
Lerkin
3.0K / / 25.03.2003
Цитата: @pixo $oft
А PushAD/PushF+PopAD/PopF не судьба использовать?



Про флаги.
Использование оправдано только в тандеме с CLI/STI. Да и то, если после восстановления флагового регистра, не произойдет NMI. Сие действо усложняется в PM и при мультизадачности, ибо CPL :). Имхо, нет смысла.
Данная возможность полезна для принудительной работы с регистром EFLAGS флагов:

 
Код:
pushf
    pop ax
    ...
    push ax
    popf

Хотя это и не принципиально, но флаги VM и RF сохраняются нулевыми.

Про PushAD/PopAD.
Эта команда только для 8-ми регистров общего назначения. Ни MMX (это понятно, они в сопроцессоре), ни XMM регистры она не сохраняет. Как, кстати, и EIP. Возвращаемое значение, обычно, хранится в (E)AX, и соответственно, после применения POPAD... :)
Конечно, можно сохранить возвращаемое значение в памяти, а после восстановления регистров поместить его в EAX, при этом получив 'пенальти' в несколько сотен тактов. Так что, для оперативной работы эти команды не подходят (к сожалению).
7
15 января 2007 года
@pixo $oft
3.4K / / 20.09.2006
1)Ему надо сохранять только регистры общего назначения,
2)так будет короче(чем сохранять все используемые регистры)
6.8K
12 июня 2007 года
Coffein
46 / / 07.03.2005
Цитата: Green
Да нет, возможно. Только для EAX это не требуется, т.к. в нем, все равно, будет возвращаемое значение.


На этот раз пример использования вполне рабочий. Можно скопировать, построить и запустить.
Если интересно, могу рассказать в чем его суть (что он делает). Это хитрый пример. ;)



Да, давненько это было, но Green очень интересный пример. В принципе понятно что осуществляется перехват, но расскажи пожалуста поподробней в чем суть и какая хитрость?

6.8K
13 июня 2007 года
Coffein
46 / / 07.03.2005
И еще не подскажешь где найти winternl.h
3
13 июня 2007 года
Green
4.8K / / 20.01.2000
Цитата: Coffein
В принципе понятно что осуществляется перехват, но расскажи пожалуста поподробней в чем суть и какая хитрость?


Хитрость не в перехвате, а в том, что перехватывается.
В примере производиться попытка загрузки user32.dll. Эта DLL относиться к так называемым KnownDLL и поэтому загружается она в процесс не с диска, как другие DLL, а делается её копия в память процесса с помощью NtOpenSection.
Т.о. если поставить хук на NtOpenFile, то можно увидеть, как открываются файлы обычных DLL при их загрузке, но открытия файла user32.dll не последует.
Однако, если перехватить NtOpenSection и вернуть STATUS_OBJECT_NAME_NOT_FOUND, то система попытается загрузить эту DLL с диска, как обычную.
Собственно, таким "обманом" и занимается пример.

Цитата: Coffein
И еще не подскажешь где найти winternl.h


Она обычно входит в стандартную поставку VC++ и находиться в папке PlatformSDK\Include.

6.8K
16 июня 2007 года
Coffein
46 / / 07.03.2005
Green, я пробовал с компилить твой пример2, но у меня выдает кучу ошибок. Я воообще делфист, и в С++ разбераюсь не так уверено. Помоги разобраться, проверь еще раз у тебя исходник компилится нормально или есть ньюансы?
У меня при компиляции выдает такие ошибки:
error C2146: syntax error : missing ';' before identifier 'handler'
error C2501: 'HookNtOpenFile::NTSTATUS' : missing storage-class or type specifiers
Первый пример у меня компилится нормально, а второй не хочет.
602
07 июля 2007 года
KPI Student
265 / / 16.12.2006
Народ, не могу разобраться, как все работает. Вроде все понятно, но второй пример (с незначительными исправлениями, выдает пусой экран)
Перехват MessageBoxA тоже не выходит :confused:

На вызове setHandled() происходит Access Violation
Из-за чего не работает?

Код:
class HookMessageBoxA :public HookApi<HookMessageBoxA>
{
public:
    bool hook() {
        return HookApi<HookMessageBoxA>::hook("user32", "MessageBoxA");
    }

    int handler(HWND hWnd,const char *lpText,const char *lpCaption,unsigned int uType)
    {
        setHandled();
        return 1;
    }
};

int main()
{
    HookMessageBoxA hookMessageBoxA;
    bool flag=hookMessageBoxA.hook();

    int i=MessageBoxA(NULL,"text","text",0);

    return 0;
}


Кроме того, не компилируется, если не заменить в обьявлении базового класса protected на public
3
07 июля 2007 года
Green
4.8K / / 20.01.2000
Какая ОС, какой компилятор?
Сейчас, к сожалению, проверить не могу.
Вернусь в Питер, посмотрю подробнее.
602
07 июля 2007 года
KPI Student
265 / / 16.12.2006
Borland Developer Studio 2006
Windows XP SP2
-------------
C++ Builder 6 выдает кучу ошибок в winntrnl.h
3
07 июля 2007 года
Green
4.8K / / 20.01.2000
Ну, вообще-то, библиотечка под MSVC...
Твой пример там нормально компилируктся и работает.
winntrnl.h для него не нужен, нужно лишь:
 
Код:
#include <windows.h>
#include <stddef.h>
#include "HookApi.h"

обрати книмание на stddef.h
это надо для offsetof
602
08 июля 2007 года
KPI Student
265 / / 16.12.2006
Возможно, пролема в выравнивании, чуть позже гляну. Дело в том, что почему-то DeveloperStudio выставляет сам 8-ми байтовое выравнивание, наверное, по 64-му процессору, хотя винда х32. Поменяю - отпишусь
3
28 июня 2008 года
Green
4.8K / / 20.01.2000
HookApi v3.0
Третья версия базового класса для перехвата вызовов функций API из текущего процесса.
Взять можно здесь: http://sources.codenet.ru/download/2070/HookApi_v3_0.html

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

Основное отличие от второй версии в способе передачи управления перехваченной функции API. Теперь если надо вызывать перехваченную функцию это делается с помощью вызова callOrgFunc с соотв. функции API параметрами.
Ещё одно изменение в том, что теперь экземпляру перехватчика указывается адрес перехватываемой ф-ции (в методе init), а не её имя.

Использовать класс очень просто. Наследуете от него класс для перехвата определенной функции API, определеяте в наследнике метод handler. Параметры этого метода (аргументы и возвращаемое значение) должны быть такие же, как у функции, которую перехватываем.
Внимание: базовый класс является шаблонным, наследоваться нужно от него, инстациированого дочерним классом (см. пример использования).

Код:
#define _WIN32_WINNT    0x0500

#include <windows.h>
#include <winternl.h>
#include <iostream>
using namespace std;

#include "HookApi.h"


class HookNtOpenFile :public HookApi<HookNtOpenFile>
{
public:
    NTSTATUS handler(OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock,
        IN ULONG ShareAccess, IN ULONG OpenOptions)
    {
        wcout << "HookNtOpenFile: " << ObjectAttributes->ObjectName->Buffer << endl;

        // Вызов перехваченной ф-ции API
        return callOrgFunc(FileHandle, DesiredAccess, ObjectAttributes, IoStatusBlock,
            ShareAccess, OpenOptions);
    }
};


#define STATUS_OBJECT_NAME_NOT_FOUND     ((NTSTATUS)0xC0000034L)

class HookNtOpenSection :public HookApi<HookNtOpenSection>
{
public:
    NTSTATUS handler(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObjectAttributes)
    {
        wcout << "NtOpenSection: " << ObjectAttributes->ObjectName->Buffer << endl;

        if( !wcsicmp(ObjectAttributes->ObjectName->Buffer, L"USER32.DLL") ) {
            cout << "BINGO!" << endl;
            *SectionHandle = NULL;

            // Возвращаем управление в вызывающий код без вызова в реальной API-функции.
            return STATUS_OBJECT_NAME_NOT_FOUND;  
        }

        // Вызов перехваченной ф-ции API
        return callOrgFunc(SectionHandle, DesiredAccess, ObjectAttributes);
    }
};


int main()
{
    // Создание перехватчиков
    HookNtOpenFile hookNtOpenFile;
    HookNtOpenSection hookNtOpenSection;

    // Инициализация перехватчиков адресами ф-ций API
    HMODULE hDll = LoadLibrary("ntdll");      
    hookNtOpenFile.init( GetProcAddress(hDll, "NtOpenFile") );
    hookNtOpenSection.init( GetProcAddress(hDll, "NtOpenSection") );

    // Установка перехватчиков
    hookNtOpenFile.hook();
    hookNtOpenSection.hook();

    // Проверяем, как работает :)
    HMODULE nMod = LoadLibrary("user32.dll");

    return 0;
}
39K
30 июня 2008 года
vcher
13 / / 30.06.2008
HookAPI v3 падает после навешивания хука. OS - WinXP SP2, IDE - MSVC 9.0
3
30 июня 2008 года
Green
4.8K / / 20.01.2000
Где падает? После навешивания какого хука? На какую функцию?
Почему падает?
Дело может быть не в HookAPI, а в том, что ты неправильно написал обработчик.
39K
30 июня 2008 года
vcher
13 / / 30.06.2008
Я сделал хук на FindFirstFile. После того как метод hook отработал, все падает на вызове ::FindFirstFile.

вот мой класс:

class HookFindFirstFile :public HookApi<HookFindFirstFile>
{
public:
HANDLE handler(IN LPCTSTR lpFileName, OUT LPWIN32_FIND_DATA lpFindFileData)
{
//wcout << "HookFindFirstFile: " << lpFileName << endl;

// Вызов перехваченной ф-ции API
return callOrgFunc(lpFileName, lpFindFileData);
}
};

Под отладчиком вижу, что в handler еще не попадаю.
3
30 июня 2008 года
Green
4.8K / / 20.01.2000
У меня все ок:
Код:
#include <windows.h>
#include <iostream>
using namespace std;

#include "HookApi.h"


class HookFindFirstFile :public HookApi<HookFindFirstFile>
{
public:
    HANDLE handler(IN LPCTSTR lpFileName, OUT LPWIN32_FIND_DATA lpFindFileData)
    {
        wcout << "HookFindFirstFile: " << lpFileName << endl;

        // Вызов перехваченной ф-ции API
        return callOrgFunc(lpFileName, lpFindFileData);
    }
};


int main()
{
    HookFindFirstFile hookFindFirstFile;
    hookFindFirstFile.init(&FindFirstFile);
    hookFindFirstFile.hook();

    WIN32_FIND_DATA FindFileData;
    HANDLE hFind = FindFirstFile("asd", &FindFileData);

    return 0;
}


Если ты получаешь адрес ф-ции с помощью GetProcAddress, то учти, что FindFirstFile - это не ф-ция, а макрос, который раскрывается в FindFirstFileA или FindFirstFileW.
Полезно проверять полученный адрес прежде, чем передавать его в инициализатор хука:
 
Код:
PVOID addr = GetProcAddress(hDll, "FindFirstFile")
if(addr == NULL) {
    // ERROR
}
39K
30 июня 2008 года
vcher
13 / / 30.06.2008
Ситуация не изменилась, тем более что про макрос FindFirstFile я знаю. Вот дизассемблер, падает на строчке, отмеченной стрелкой:

0013FF56 push ebp
0013FF57 mov ebp,esp
-> 0013FF59 mov ecx,13FF4Ch
0013FF5E jmp @ILT+790(HookFindFirstFile::handler) (0040131b)
3
30 июня 2008 года
Green
4.8K / / 20.01.2000
Она даже теоретически не может падать на этом месте, т.к. это всеголишь запись числа в регистр.

А падает с каким cообщением?
Ты собираешь тот пример, что я привел постом выше?
Покажи трассировку от вызова FindFirstFile, до падения.
У меня это выглядит так:
Код:
HANDLE hFind = FindFirstFile("asd", &FindFileData);
004116D5 8B F4            mov         esi,esp
004116D7 8D 85 7C FE FF FF lea         eax,[ebp-184h]
004116DD 50               push        eax  
004116DE 68 FC 86 41 00   push        offset string "asd" (4186FCh)
004116E3 FF 15 20 C3 41 00 call        dword ptr [__imp__FindFirstFileA@8 (41C320h)]

_FindFirstFileA@8:
7C8137D9 E9 5B C7 91 83   jmp         0012FF39

0012FF39 B9 2C FF 12 00   mov         ecx,12FF2Ch
0012FF3E E9 05 14 2E 00   jmp         HookFindFirstFile::handler (411348h)
39K
30 июня 2008 года
vcher
13 / / 30.06.2008
Да, я собираю твой пример.
У меня дизассемблер выглядит так:

25: int main()
26: {
00411760 push ebp
00411761 mov ebp,esp
00411763 push 0FFFFFFFFh
00411765 push offset __ehhandler$_main (416F58h)
0041176A mov eax,dword ptr fs:[00000000h]
00411770 push eax
00411771 sub esp,254h
00411777 push ebx
00411778 push esi
00411779 push edi
0041177A lea edi,[ebp-260h]
00411780 mov ecx,95h
00411785 mov eax,0CCCCCCCCh
0041178A rep stos dword ptr es:[edi]
0041178C mov eax,dword ptr [___security_cookie (41C048h)]
00411791 xor eax,ebp
00411793 mov dword ptr [ebp-10h],eax
00411796 push eax
00411797 lea eax,[ebp-0Ch]
0041179A mov dword ptr fs:[00000000h],eax
27: HookFindFirstFile hookFindFirstFile;
004117A0 lea ecx,[ebp-3Ch]
004117A3 call HookFindFirstFile::HookFindFirstFile (411014h)
004117A8 mov dword ptr [ebp-4],0
28: hookFindFirstFile.init(&FindFirstFile);
004117AF mov eax,dword ptr [__imp__FindFirstFileA@8 (41D2D4h)]
004117B4 push eax
004117B5 lea ecx,[ebp-3Ch]
004117B8 call HookApiBase::init (411032h)
29: hookFindFirstFile.hook();
004117BD lea ecx,[ebp-3Ch]
004117C0 call HookApi<HookFindFirstFile>::hook (4112ADh)
30:
31: WIN32_FIND_DATA FindFileData;
32: HANDLE hFind = FindFirstFile("asd", &FindFileData);
004117C5 mov esi,esp
004117C7 lea eax,[ebp-184h]
004117CD push eax
004117CE push offset string "asd" (419800h)
004117D3 call dword ptr [__imp__FindFirstFileA@8 (41D2D4h)]
004117D9 cmp esi,esp
004117DB call @ILT+675(__RTC_CheckEsp) (4112A8h)
004117E0 mov dword ptr [ebp-190h],eax
33:
34: return 0;
004117E6 mov dword ptr [ebp-25Ch],0
004117F0 mov dword ptr [ebp-4],0FFFFFFFFh
004117F7 lea ecx,[ebp-3Ch]
004117FA call HookFindFirstFile::~HookFindFirstFile (4112C6h)
004117FF mov eax,dword ptr [ebp-25Ch]
35: }
39K
30 июня 2008 года
vcher
13 / / 30.06.2008
Еще часть:

_FindFirstFileA@8:
7C813559 jmp 0013FF39

0013FF39 mov ecx,13FF2Ch
0013FF3E jmp HookFindFirstFile::handler (4112CBh)
3
30 июня 2008 года
Green
4.8K / / 20.01.2000
мне нужен трейс от точки
004117D3 call dword ptr [__imp__FindFirstFileA@8 (41D2D4h)]

или выложи exe + pdb
3
30 июня 2008 года
Green
4.8K / / 20.01.2000
Ок, увидел второй пост с трейсом. Там все Ок.
Это какая-то наведенная ошибка.
С каким сообщением падает?
Выложи exe + pdb

И смотри ещё странность: в одном посте ты приводишь код
-> 0013FF59 mov ecx,13FF4Ch
0013FF5E jmp @ILT+790(HookFindFirstFile::handler) (0040131b)

а в другом:
0013FF39 mov ecx,13FF2Ch
0013FF3E jmp HookFindFirstFile::handler (4112CBh)

что изменилось между сборками?
39K
30 июня 2008 года
vcher
13 / / 30.06.2008
Я сделал рар, переименовал в зип, чтобы можно было приаттачить.
3
30 июня 2008 года
Green
4.8K / / 20.01.2000
Хм... окружение не подходит, у меня MSVS 8.0
Пересобери с /MTd
39K
30 июня 2008 года
vcher
13 / / 30.06.2008
Собрал проект под vc 8.0 - та же ситуация. Файлики снова рар, переименованный в зип.
3
30 июня 2008 года
Green
4.8K / / 20.01.2000
У меня не запускается: "Не удается выполнить указанную программу."
Построй релиз с /MTd и скажи, с каким сообщением падает?
39K
30 июня 2008 года
vcher
13 / / 30.06.2008
Unhandled exception at 0x0012fcdd in HookApiTest.exe: 0xC0000005: Access violation.

---------------------------
HookApiTest.exe - Ошибка приложения
---------------------------
Инструкция по адресу "0x0012fcdd" обратилась к памяти по адресу "0x0012fcdd". Память не может быть "written".
3
30 июня 2008 года
Green
4.8K / / 20.01.2000
Чтоб не заливать файл сюда, можно выслать на почту (см. в HookAPI.h)
39K
30 июня 2008 года
vcher
13 / / 30.06.2008
послал файлы на почту
3
30 июня 2008 года
Green
4.8K / / 20.01.2000
Цитата: vcher
послал файлы на почту


Это не /MTd
Exe с таким ключом должен весить ~500k

Посмотри Project -> Properties -> C/C++ -> Code Generation -> Runtime Lbrary -> Multi-threaded Debug (/MTd)

39K
30 июня 2008 года
vcher
13 / / 30.06.2008
Ты попросил релиз с этой опцией. Я включил эту опцию (/MTd). Сейчас послал на почту debug c /MTd
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог