Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2002.04.25;
Скачать: [xml.tar.bz2];

Вниз

определить адрес процедуры из нее самой   Найти похожие ветки 

 
MBo   (2002-03-18 16:13) [0]

В конференции Borland встретился вопрос (вообще-то, по моему, нелепый), сводящийся к тому, как определить Subj.
Получилось у меня так:
procedure TForm1.Button1Click(Sender: TObject);
var p:pbyte;
function DummyFunc: Pointer;
asm
xor eax, eax
end;
begin
p:=@DummyFunc;
inc(p,4);
label3.caption:=classname+"."+methodname(p);
end;
Но более радикально было бы для этого вызывать внешнюю по отношению к данной процедуре функцию.

function ACaller:pointer;
asm
mov eax, [esp]
end;

procedure TForm1.CheckBox1Click(Sender: TObject);
var p,p1:pbyte;
begin
p1:=ACaller;
dec(p1,53);//Magic Number
p:=methodaddress("CheckBox1Click");//для контроля
label3.caption:=inttohex(cardinal(p),8);
label4.caption:=inttohex(cardinal(p1),8);
label2.caption:=classname+"."+methodname(p1);
end;

Так работает, но Magic Number, естественно, зависит от пролога данной процедуры и может меняться. Полагаю, методы для subj можно найти,(кроме methodaddress и @procname, естественно). Идеи есть?


 
VuDZ   (2002-03-18 16:28) [1]

т.е. положение в памяти этого куска кода?


 
VuDZ   (2002-03-18 16:35) [2]

кстати, почему не лепый - вот применение:

#include <windows.h>
#include <stdio.h>
#include <conio.h>

typedef INT (proc)(VOID);

int main(){
void *v = &main;
proc *p = (proc*)v;
try{
(*p)();
}
catch (...) {
printf("Fucked stack :<\n");
}

return 0;
}

простенько и со вкусом :>


 
MBo   (2002-03-18 16:37) [3]

точку входа ( в примере по ней можно найти имя метода).
т.е. адрес первого push ebp
в зависимости от того, что есть в процедуре (например, строки)
до call ACaller (когда я могу поймать esp) разное расстояние


 
MBo   (2002-03-18 16:41) [4]

во-во, только мне интересно без void *v = &main - т.е. явного указания


 
VuDZ   (2002-03-18 16:51) [5]

нате:

int main(){
_asm{
call next;
next:
pop eax;
sub eax, 0x1d;
call eax;

}
return 0;
}


 
MBo   (2002-03-18 16:58) [6]

нечто вроде этого у меня в первом примере, только без Stack OverFlow ;)


 
VuDZ   (2002-03-18 17:06) [7]

а это мой любимое :>
а зачем ещё что-то? мне приходилось пользоваться такими трюками, но только зачем это?


 
MBo   (2002-03-18 17:11) [8]

просто заинтересовался ;)


 
VuDZ   (2002-03-18 17:15) [9]

а слабо сделать такую фичу:
classA
member int foo();
member float doo():

classB
bool foo();
int doo();

classA A;
a->doo();

?
просто заинтерисовался...


 
MBo   (2002-03-18 17:20) [10]

чем отличаются декларации с member и без него?


 
VuDZ   (2002-03-18 17:23) [11]

ну в смысле у тебя есть указатель на один класс, а надо вызвать по нему методы другого класса :>
на самом деле я не помню как это звучит правильно, но делалось это через мухлёж с vtpr, и было досаточно красиво :>
сейчас попробую повторить


 
VuDZ   (2002-03-18 17:30) [12]

вот пример, правда он делает не совсем то:

#include <windows.h>
#include <stdio.h>
#include <conio.h>

typedef INT (proc)(VOID);

class A{
public:
int foo() { printf("A::foo()\n"); return 1; }
float doo(){ printf("A::doo()\n"); return 1.0; }
};

class B{
public:
bool foo(){ printf("B::foo()\n"); return false; }
float doo(){ printf("B::doo()\n"); return 0.0; }
};

int main(){
A a;
a.foo();
a.doo();

B * t = reinterpret_cast<B*>(&a);
t->doo();
return getch();
}

Результат:
B::doo() !!! хотя взято из A :>


 
MBo   (2002-03-18 17:56) [13]

function TB.Foo: integer;
begin
Result:=1;
end;

function TA.Foo: integer;
begin
Result:=2;
end;

procedure TForm1.Button1Click(Sender: TObject);
var a:ta; b:tb;
pa,pb:^Pointer;
begin
a:=ta.create;
b:=tb.create;
pa:=ta.methodaddress("Foo");
pb:=tb.methodaddress("Foo");
label1.caption:=inttostr(a.foo);
pa^:=pb^;
label2.caption:=inttostr(a.foo);
в первой метке выводится 1, во второй - 2
можно и через vmtMethodTable сделать


 
VuDZ   (2002-03-19 01:51) [14]

эт нето....
вот, вот такой пример, только смеяться не надо:

class A{
public:
A(int n){
m_nVal = n;
}
int foo(int);
int m_nVal;
void doo(){
printf("doo\n");
printf("m_nVal = %i\n", m_nVal);
}
};

int A::foo(int n){
printf("foo called\n");
printf("%i\n", n);
doo();
return 0;
}

class B{
public:
int i1, i2, i3, i4;
B(){
i1 = 1;
i2 = 0x2;
i3 = 0x3;
i4 = 0x4;
}

void bInit(){
i1 = 1;
i2 = 0x2;
i3 = 0x3;
i4 = 0x4;
}
double foo(){
printf("B::foo()\n");
printf("%i = i1\n", i1);
return 0.0;
}

void v(){
printf("B::v\n");
printf("%i = i2\n", i2);
}

void doo(){
printf("B::doo()\n");
printf("%i = i3\n", i3);
}

void doo2(){
printf("B::doo2()\n");
printf("%i = i4\n", i4);
}
};

class Stub{
};

int main(){
int k = 666;

B b = *reinterpret_cast<B*>(&k); // !!! from integer to class
b.bInit(); // only for variables initialization, nothing more

b.foo();
b.v();
b.doo();
b.doo2();

A n = (A)*(reinterpret_cast<A*>(&b));
n.A(1234);
n.doo();
n.foo(777);

printf("%i\n", k);
return getch();
}


PS из-за n.A(1234);, явного вызова конструктора, это соберут не все компиляторы, MS VC++ послал меня в пешее эротическое путешествие, так сильно это мотивируя, что захотело его стереть.

смысл, я думаю ясен - int -> B - > A, и всё работает, только вот переменный надо инициализировать, а то глюки могут быть. Хотя тут ничего особогои нет.

Для контроля- вывод:
B::foo()
1 = i1
B::v
2 = i2
B::doo()
3 = i3
B::doo2()
4 = i4
doo
m_nVal = 1234
foo called
777
doo
m_nVal = 1234
666

sya



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2002.04.25;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.49 MB
Время: 0.005 c
1-80959
Windeus
2002-04-12 10:08
2002.04.25
fonts -> rc, Indy smtp


1-80888
kaif
2002-04-14 15:08
2002.04.25
TabSet и клавиатура


1-80921
SergeyB
2002-04-04 13:47
2002.04.25
Прозрачный потомок TCustomControl


1-80880
Citen
2002-04-13 14:42
2002.04.25
Документация по QReport.


1-80861
Air
2002-04-13 13:03
2002.04.25
Как поймать сообщение клиента при дисконнекте?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский