Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: CALLBACK Функции  (Прочитано 23586 раз)
0 Пользователей и 1 Гость смотрят эту тему.
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« : 30-03-2006 09:26 » 

Нужно реализовать вызов метода фабрики классов из поражденных класов,
 можно передать указатель на класс, но хочу для разнообразия поробовать реализовать это через CALLBACK функцию.

Нужно реализовать что то похожее на это
class Mc
{
int CallBack(int a, int b){...};
 CreateNext();
}
Mc::CreateNext()
{
c * pc;
pc=new c;
pc->init (&CallBack);
}


class c
{
void * pCallBack;
 init (void * CallBack);
}
c::init (void * CallBack)
{
pCallBack=CallBack;
....
int z;
z=pCallBack(2,3);
}


вот только никак не могу найти как это синтаксически оформляется....
Записан

Да да нет нет все остальное от лукавого.
Джон
просто
Администратор

de
Online Online
Пол: Мужской

« Ответ #1 : 30-03-2006 10:43 » 

С приватной функцией класса сразу не скажу. Наверное никак не сделаешь. А почему она private?

А вообще-то тип определяется так:

typedef int (*MYCALLBACKFUNC)(int*,int*);

Потом делаешь указатель на неё  MYCALLBACKFUNC pCallBack;

зы Ещё раз - CallBack у тебя private - тут я не знаю что делать?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« Ответ #2 : 30-03-2006 11:46 » 

Она не приватная... этоя просто когда пример писал Public  забыл

А где тут учитывается то что функция член класса?

Или это не играет роли?
Записан

Да да нет нет все остальное от лукавого.
Джон
просто
Администратор

de
Online Online
Пол: Мужской

« Ответ #3 : 30-03-2006 12:20 » 

Ок, в случае с глобальной функцией - всё просто - имя - указатель.

Сажем так:

int CallBack(int, int);

тогда для передачи в ф-ю Init делаем так:

c::init (MYCALLBACKFUNC pfnCallBack)
{
      int z = pfnCallBack(2,3);
}

c *p = new c();
c->Init(CallBack);
...

А вот как быть в случае с ф-ей мембером - не знаю. Может так:

c->Init(Mc::CallBack);

А в классике смотрел? У меня ща времени нет. А так я никогда наверное не делал. Я делал только с глобальными -  не соврать, там ещё макрос должен быть, или нет - не помню.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Джон
просто
Администратор

de
Online Online
Пол: Мужской

« Ответ #4 : 30-03-2006 12:24 » 

Ааааа блин - забудь всё эт я в шары долблюсь.
Ша ещё раз твои пример посмотрел.
В одном классе это прокатит (должно прокатить). Я решил, что ты хочешь ф-ю в другом классе предать. А ты делаешь это в этом же.

class Mc
{
    int CallBack(int a, int b){...};
    CreateNext();
}

Mc::CreateNext()
{
  c * pc = new c;
  pc->init (CallBack);
}

Вот так должно работать, только определение остаётся

c::init (MYCALLBACKFUNC pfnCallBack)
{
      int z = pfnCallBack(2,3);
}

Попробуй
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 30-03-2006 17:34 » 

Джон, ещё вопрос

вот тут я объявляю указатель на  и заполняю его адресом ::AfxBeginThread

Код:
typedef CWinThread* (AFXAPI *AfxThreadPtr_Proc)(AFX_THREADPROC pfnThreadProc, LPVOID pParam,int nPriority = THREAD_PRIORITY_NORMAL, UINT nStackSize = 0,DWORD dwCreateFlags = 0, LPSECURITY_ATTRIBUTES lpSecurityAttrs = NULL);

//будем использовать для запуска потока
AfxThreadPtr_Proc m_pAfxBeginThread;

//заполняем указатель на AfxBeginThread
DWORD dwdafx=(DWORD)(AfxThreadPtr_Proc)(::AfxBeginThread);
DWORD* pdwdafx=&dwdafx;
m_pAfxBeginThread=(AfxThreadPtr_Proc)(*pdwdafx);

строки с DWORD тут у меня вот для чего: Цель: охота загрузить адрес так, чтобы явной ссылки в коде на ::AfxBeginThread не было () , а в коде всё равно стоит offset

004462CE   mov         dword ptr [ecx],offset CGuard2View::`vftable' (0052b5f4)

а например можно как-нить по байту адрес получить - и затем сложить их в указатель?

Окончательная цель - чтобы было неясно, откуда я потоки новые запускаю (то есть при помощи указателя на ::AfxBeginThread, который заполнен втихую)
« Последнее редактирование: 20-12-2007 14:56 от Алексей1153++ » Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 30-03-2006 17:38 » 

DWORD dwdafx=(DWORD)((BYTE*)(DWORD*)(AfxThreadPtr_Proc)(::AfxBeginThread));

 - беру первый байт адреса - всё равно ссылка

а брать адрес цифрой в лоб, я так понимаю, низя?    004ac9dc
« Последнее редактирование: 30-03-2006 17:40 от Алексей1153 » Записан

Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #7 : 30-03-2006 20:44 » 

Леш, он в другой раз загрузиться по совершенно другому адресу. Если хочешь чтобы было неясно откуда запускаешь потоки, скинь все в длл-ку и грузи функции по ординалу. Улыбаюсь

Никто не найдет, особенно, если подключать динамически, будет видно, что какую-то функцию получил, а что за функция, откуда она, хрен поймешь без исходников.

А так, компилятор все равно, подставит смещение, через таблицу виртуальных функций, и никак его не переубедишь Улыбаюсь Можно на низком уровне попробовать, но больше геморроя..., чем результата
Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #8 : 30-03-2006 21:27 » 

Scorp__),
то есть в принципе

m_pAfxBeginThread=(AfxThreadPtr_Proc)::AfxBeginThread);
достаточно?

или?


>>Если хочешь чтобы было неясно откуда запускаешь потоки, скинь все в длл-ку и грузи
>> функции по ординалу.  -
а по русски? Улыбаюсь

-----
кстати - как сделать длл и как её подключают?
« Последнее редактирование: 30-03-2006 21:29 от Алексей1153 » Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #9 : 30-03-2006 22:18 » 

Цитата
кстати - как сделать длл и как её подключают?
Книжка Рихтера. В 3 главах разжевывается все, что связано с библиотеками.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #10 : 31-03-2006 07:40 » 

PSD, ты собираешся вызывать callback только из С++ кода?  Тогда не надо заморачиваться с указателями на функции, это не ООП-шно.  В ООП гораздо уместнее передавать указатель на объект с заданным интерфейсом.

Если же ты хочешь, чтобы вызывалось из Си кода (без плюсов), то метод должен быть статическим.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Джон
просто
Администратор

de
Online Online
Пол: Мужской

« Ответ #11 : 31-03-2006 09:16 » 

Лёш, из кода нифига не понял. Ща времени нет разбираться, поэтому для особо одарённых можно ещё раз - что ты хочешь? И главное - зачем?
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 31-03-2006 15:22 » 

Джон, цель - запутать крекера Улыбаюсь Хотя бы на день.

 Поскольку сразу вызывая ::Afx (для краткости - не полностью пишу) явно, я предполагаю, что место вызова можно найти в программе. И если я кратко запускаю через ::Afx некий тайных поток, то можно найти , где он запускается (это мои мысли - не знаю, насколько моя имха близка к реальности). А идея такая - где-то неявно загрузить в указатель адрес ::Afx, и даже, по возможности, не весь сразу, а по байтам - то есть загружаемый адрес размажется по коду. А потом в разных местах программы вызывать ::Afx через указатель.

з.ы. вот.
Записан

Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #13 : 31-03-2006 15:57 » 

Леш, ну теоретически можно и так, как у тебя в последнем посте, но на день это не остановит крекера, хотя смотря какого... Все равно по ассемблерному коду можно будет отследить операции с указателем. Т.е. если ты делаешь вот так:
Код:
// Какой-то код
DWORD* pdwdafx=(DWORD*)(AfxThreadPtr_Proc)(::AfxBeginThread));
// скажем для путанности
if ((DWORD)pdwdafx &= 0xFFFF0000)
    // Блок каких нибудь странных действий

// Какой-то код
DWORD* pdwdafx1=(DWORD*)(AfxThreadPtr_Proc)(::AfxBeginThread));
// скажем для путанности
if ((DWORD)pdwdafx &= 0x0000FFFF)
    // Блок каких нибудь странных действий

// Какой-то код
pdwdafx |= pdwdafx1;

// Код затем вызов по полученному указателю


На некоторое время это собьет хакера с толку, и ему придется анализировать это некоторое время. Для переменных в целях увеличения путаницы лучше сделать запрос register. И не знаю, как отреагирует компилятор на такие вольности с типами.  В любом случае IDA сразу определит указатель какой функции ты взял и все Жаль считай рубеж рухнул, дальше скорость распознавания указателя зависит от опыта хакера.

Про dll. Улыбаюсь Сделать ее довольно просто, в студии мастером проектов она создается на ура. Выбираешь проект Win32,  не консольный. В настройках приложения ставишь DLL. Размещаешь там свои функции, ставишь для них спецификатор (все настройки для Visual Studio 2003) __declspec( dllexport )

Затем создаешь .DEF файл где пишешь примерно следующее
Код:
LIBRARY MYDLL

EXPORTS

MyFunc1              @1
MyFunc2 @2
Потом в приложении пишешь примерно следующее
Код:
             uResult = GetSystemDirectory((LPTSTR)pBuffer, MAX_PATH+1);
if (!uResult) return;

strcat(pBuffer, "\\MyDll");
HMODULE hMod;
hMod = LoadLibrary((LPTSTR)pBuffer);
if(!hMod) return;

MyOrdinal1 = (MYPROC)GetProcAddress(hMod, (LPCSTR)1);
if(!StartPulseSurvey)
dwResult = GetLastError();
MyOrdinal2 = (MYPROC)GetProcAddress(hMod, (LPCSTR)2);
if(!StartPulseSurvey)
dwResult = GetLastError();
И вызываешь функции уже по новым указателям. Правда и здесь опытный хакер лишь недовольно крякнет запустит dumpbin и посмотрит какие ординалы у функций в библиотеке... Но уж тут тогда надо строить более серьезную защиту, чем мы напридумывали выше.
Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #14 : 31-03-2006 17:37 » 

Алексей1153, А зачем это нужно? Этому крякеру не нужно будет даже разбираться, откуда запускается поток. Сушествует куча утилиток, которые смогут сказать, сколько потоков, и по каким адресам они запушены. Отследить все запуски потоков, тоже от нечего делать можно. Ты будеш больше ломать голову, создавая свой шедевр. Чем крякер, ломая твой код.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #15 : 31-03-2006 17:46 » 

Finch, это не так просто как кажется. Сделать это можно только под дебаггером, а это очень агрессивная среда. Анализировать код в дебаггере - хуже не придумать, ничего под рукой, даже переменные не назовешь, как надо. А адрес-то потом изменится и в дизассемблере опять ничего не видно.

Я так понимаю, что Алексею надо скрыть что именно поток делает, а не его запуск. Постараться усложнить анализ, для этого и попытка замаскировать вызов функции AfxBeginThread(), чтобы по параметрам нельзя было тут же увидеть, где прячеться функция потока.

Хотя, против опытного хакера, все эти приемчики не подействуют. Уж лучше упаковка исполняемого файла. Так ему хоть распаковщик придется искать, да еще и таблицы перемещаемых элементов собьются Улыбаюсь
Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #16 : 31-03-2006 18:11 » 

Scorp__), Перехватываеш CreateThread. И не нужно с дебагером бегать по коду. Сама программа все выложит.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #17 : 31-03-2006 18:27 » 

Finch, угу Улыбаюсь непосредственные смещения Улыбаюсь выдаст. Конечно если вопрос об анализе функций потока не стоит, то...
Хотя, вообще ты прав, можно ведь по сигнатуре функцию потока найти, скажем взять первые 64 байта. Ищем их в дизассемблере и вуаля, все что хотели перед глазами.

Ну а если потоков несколько, создаются они все с помощью CreateThread в конечном итоге. Как тогда найти нужный нам поток скажем подсчета денег на счету, ну или проверяющий регистрацию или еще какой? Тем более, что CreateThread запрятана глубоко в обертку AfxBeginThread() и вывалимся мы именно в обертку... И восстановить логику программы в этом случае довольно тяжело.

Нет, все-таки при грамотном использовании этих приемов, неопытного хакера это введет в ступор, а среднего заставит повозиться несколько часов, а может и день.
Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #18 : 31-03-2006 18:36 » 

Scorp__), Это все расчитано на не опытного ломателя, который не знает WinAPI вообше. Во всех остальных случаях Это только вопрос времени. Чем дороже программа, тем больше ломатель уделит времени. Мне в свое время нравилась зашита FineReader. Крякнутая версия работала. Потом в какой то момент просто забывала, как записывать файлы, как работать с буфером обмена, как печатать. Т.е. толку, что отсканировано и распознано НУЛЬ.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 31-03-2006 18:38 » 

кАроче Улыбаюсь

в связи с тем, что поток выывается на очень краткое время и вообще со стороны людям неизвестно, что он запускается.  Вот тут поможет ли то, что Scorp__) говорит?
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #20 : 31-03-2006 18:41 » 

а, и ещё - сильно много денег тратить на наём хакера не станут - проще нашу продукцию купить будет Улыбаюсь
Записан

Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #21 : 31-03-2006 20:30 » 

Finch, а это она не до конца крякнута была Улыбаюсь У них так триал работал, значит не все флаги повычистили. А так, вообще не существует абсолютных защит, есть порог, когда программу дешевле купить, чем ломать ее.

Леш, если дойдет, до того, что хакера станут нанимать, и он будет настоящим, а не чьим-нибудь племянником ни разу не видевшим ассемблер, то программа будет взломана все равно, просто может быть на нее потратят чуть больше времени.

То, на какое время вызывается поток ни на что не влияет, да хоть на три инструкции Улыбаюсь Обнаружить его вызов действительно можно. Для увеличения времени взлома можно накидать ложных целей, то есть повызывать потоки, которые примерно равны по размеру твоему и делают что-то непонятное с непонятными числами Улыбаюсь

А объясни подробнее, для чего тебе это надо. Ну то есть понятно, чтоб ломателя задержать. Но почему ты решил именно скрыть вызов функции потока? Может быть найдется поэффективней решение. Но..., невзламываемых защит не бывает.
Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 31-03-2006 20:36 » 

не бывает, знаю Улыбаюсь)

но придумали кое-что. Раскрывать не буду Улыбаюсь У нас проблемы на работе
Записан

Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #23 : 31-03-2006 20:41 » 

Ну, хорошо, что придумали Улыбаюсь
Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines