Автор:
Пару дней назад возник спор по поводу возможности-невозможности запуска
программ в сегменте памяти .DATA. В принципе сегменты CODE отличаются
от сегментов DATA тем, что в них запрещена запись. При записи вырабатывается
исключение. Поэтому не вижу никаких проблем с запуском кода в сегменте данных
так же данный пример показывает еще один способ передачи функции члена класса
в качестве callback функции.
//---------------------------------------------------------------------------
// демонстрация обхода "в лоб" невозможности передачи функции члена класса
// в качестве callback функции. (в том числе и protected и private).
// Пример взят из конкретного проэкта, только вырезаны не важные
// для нас участки кода.
#ifndef ChaiHolderH
#define ChaiHolderH
#include "classes.hpp"
#include "vcl.h"
typedef void __fastcall ( __closure *TChaiEvent )( char chan, int status );
//---------------------------------------------------------------------------
class CChaiHolder : TComponent
{
__published:
__property int Channel = { read = chan, write = WrChan };
__property TChaiEvent OnReceive = { read = FOnReceive, write = FOnReceive };
__property TChaiEvent OnTransmit = {read = FOnTransmit, write = FOnTransmit };
__property TChaiEvent OnError = { read = FOnError, write = FOnError };
public:
__fastcall virtual CChaiHolder(void* AOwner);
private:
void prepare_holders(...);
TChaiEvent FOnReceive;
TChaiEvent FOnTransmit;
TChaiEvent FOnError;
void __fastcall WrChan(int channel) { chan = channel;};
protected:
int chan;
};
//---------------------------------------------------------------------------
#endif
//Файл ChaiHoldr.cpp
//---------------------------------------------------------------------------
#include "ChaiHolder.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
__fastcall CChaiHolder::CChaiHolder( void* AOwner) : TComponent((TComponent*)AOwner)
{
prepare_holders( Owner, &InternalRC, &InternalTR, &InternalER );
}
//---------------------------------------------------------------------------
void __fastcall CChaiHolder::InternalRC(unsigned short status)
{
if( OnReceive )
FOnReceive( chan, status );
}
//---------------------------------------------------------------------------
void __fastcall CChaiHolder::InternalTR(unsigned short status)
{
if( OnTransmit )
FOnTransmit( chan, status );
}
//---------------------------------------------------------------------------
void __fastcall CChaiHolder::InternalER(unsigned short status)
{
if( OnError )
FOnError( chan, status );
}
//---------------------------------------------------------------------------
void CChaiHolder::prepare_holders(...)
{
cb0 = new char[64];
memcpy(cb0,
"\x55\x89\xe5\xb8\x00\x00\x00\x00\x8b\x55\x08\xe8\xff\xff\xff\xff\x5d\xc3",
19);
memcpy((char*)(cb0)+19,
"\x55\x89\xe5\xb8\x00\x00\x00\x00\x8b\x55\x08\xe8\xff\xff\xff\xff\x5d\xc3",
19);
memcpy((char*)(cb0)+38,
"\x55\x89\xe5\xb8\x00\x00\x00\x00\x8b\x55\x08\xe8\xff\xff\xff\xff\x5d\xc3",
19);
unsigned long ha= (unsigned long)(cb0);
asm{
mov eax,[ebp+0x08]
mov ebx,[ebp+0x10]
mov ecx,[ebp+0x18]
mov edx,[ebp+0x20]
mov edi,ha
add edi,4
mov [edi],eax
add edi,8
sub ebx,edi
sub ebx,4
mov [edi],ebx
add edi,11
mov [edi],eax
add edi,8
sub ecx,edi
sub ecx,4
mov [edi],ecx
add edi,11
mov [edi],eax
add edi,8
sub edx,edi
sub edx,4
mov [edi],edx
}
};
//--------------------------------------------------
Комментарии:
- said...
-
точна!!! процессору абсолютно все равно данные это или код.
если вооружится таблицами из Интеловских мануалов то можна писать в машинных кодах. имхо конечно изврат но зато поймешь принцип составления ассемблерных команд
посмотрел в код - мало что понял.пойду еще раз гляну :-)
- said...
-
вот еще пример(т.к. у некоторых не оказалось билдера )
следующим каментом выложу ссылку на исходник, мап-файл(чтобы убедился что в сегменте DATA и экзешник)
:
//-----------------------------------------------
#include "stdio.h"
#include "mem.h"
//-----------------------------------------------
typedef void (*tproc)(void);
char *proc = "123456789012345678901234567890123";
//-----------------------------------------------
void myprint(void)
{
printf("test from DATA segmet!\n");
}
//-----------------------------------------------
void tst( void )
{
_EAX = (unsigned long)&myprint;
asm{
call eax
}
}
//-----------------------------------------------
int main( int argc, char **argv)
{
printf("test from CODE segment!\n");
memcpy(proc, &tst, 32);
(tproc(proc))();
}
//----------------------------------------------- - said...
-
вот для скачивания экзешника с исходником.
- said...
-
polonezzz?, я кое-кому из этого блога час доказывал, что процессор не отличает код от данных :-)
- said...
-
Насколь я помню суть дискусии, вы доказывали друг другу одно и то же. :)
- said...
-
.nornad, кое-кто как раз таки доказывал, что процессор умеет отличать инструкции от кода, и приводил в пример дизассемблер IDA Pro :-)
- said...
-
Если честно, то вы меня уже задолбали этим спором "в одни ворота". Встретьтесь уже в реале и разберитесь, кто, что и кому пытался доказать. В сети ваш спор себя уже изжил - вы сейчас даже разобраться уже точно не сможете, кто что пытался доказать. Имхо, имело место банальное непонимание, которое умудрились раздуть до интересных размеров. :)
- said...
-
А насчёт собственно вопроса, умеет ли процессор различать инструкции и код могу сказать, что это зависит от точки зрения и используемых понятий. В одном из вариантов очень даже правильными оказываются мои слова, что он их различает интуитивно. ;)
- said...
-
посмотрел утром камменты и обнаружил что я с кем то спорил и кому то что-то доказывал. наверно это был не Я а субъЯ или на край ОНО :-)
Читайте также
Последние новости
План занятий
Обучение детей от года до 3 лет плаванию, как правило, проходит в три этапа. На первом этапе ребенок должен адаптироваться к воде, избавиться от страха перед глубиной, неизвестной средой. Намного проще дети привыкают к бассейну, где есть бортики, вода теплая и прозрачная. Чуть сложнее дети адаптируются к открытым водоемам с темной и прохладной ...Читать далее »
Гимнастика от 2 лет до 2 лет 6 месяцев
1. Самостоятельная ходьба. 2. Бег вдогонку за взрослым или к взрослому в разном темпе. 3. Руки вверх, потянуться – «деревья большие большие», развести руки в стороны. 4. Ходьба по доске, приподнятой над полом на 15–20 см. 5. Приседания. 6. Подъем туловища с опорой на ладони в положении лежа на животе. 7. Хлопк...Читать далее »
Проблема: ожоги, ушибы, травмы
Немного повзрослев, ребенок начинает интересоваться источниками огня, что чревато ожогом. При незначительном ожоге необходимо поврежденный участок тела поместить под холодную проточную воду, а затем обработать антиожоговым аэрозолем. В период выздоровления применяют массаж, который способствует улучшению лимфо– и кровотока. В резуль...Читать далее »
Проблема: плоскостопие
Когда ребенок начинает ходить, его первые шаги могут быть омрачены плоскостопием. К сожалению, если эта болезнь наследственная, то волнения вполне обоснованны. И здесь без посещения детского врача ортопеда не обойтись. Его рекомендации относятся к укреплению подошвенного свода стопы вашего ребенка. Костная структура стопы ребенка ...Читать далее »
Рефлекторные движения
Рефлекторные гимнастические упражнения, В основе которых лежат врожденные двигательные рефлекторные реакции, проводятся первые три пять месяцев жизни ребенка, когда еще не утрачены безусловные двигательные рефлексы – «автоматическая походка», ладонно ротовой рефлекс, хоботковый рефлекс, сохранение равновесия, защитно оборонительные рефлексы. Рефлекторные гимнасти...Читать далее »
Техника выполнения: растирание
Прямолинейное растирание Выполняется концевыми фалангами одного или нескольких пальцев. Движение проводится прямолинейно одной рукой или обеими, иногда с отягощением. Круговое растирание Проводится с помощью круговых движений концевыми фалангами одного или нескольких пальцев. Кисть располагается с опорой на основании ладони, а манипуляции выполняют в сторону мизинца одной рук...Читать далее »
Проблема: пупочная грыжа
Пупочная грыжа – это патологическое состояние, в котором через несколько расширенное пупочное кольцо происходит выпячивание брюшины, сальника и даже кишечника. Причина заболевания следующая: вследствие дефекта передней брюшной стенки и пупочного кольца проявляется округлое или овальное выпячивание. Чаще факторами, провоцирующими повышение внутрибрюшного давления, являются кашель, запоры ...Читать далее »
