Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations strongm on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

__asm jmp and call

Status
Not open for further replies.

blackArt9

Programmer
Apr 23, 2006
3
IT
Hi all. Im a C/C++ programmer with an only theoretical (academic) knowledge of assembly, indeed i have very little experience of practical assembly programming. Theres a problem im not able so solve (after 2 days of work :( ). Intel Pentium architecture.

Im programming with C++ (vc express edition, then MASM 6.1 assembler). Inside my code there are pointers.

void * p1, * p2, ...

Im loocking for a way to jump unconditionally at the memory locations held by these pointers. The values stored by the pointers can change and are not predictable until run-time. Its important, to my purposes, to obtain absolute jumps (i.e. not based on offsets). In a very abstract way, something of similar to:

void * p1 = 0x12345678;
__asm jmp 0x12345678;

Ive failed, till now, to reach this objective. The instruction __asm jmp dword ptr [p1], for example, generate a "jmp mem16" (FF 65 F8) jump. Moreover, why "__asm call p1" fail to reach the memory address referenced by p1?

Can you suggest me the right way to do an absolute jump? One more thing, if possible. Whats the correct procedure to save and restore (push and pop) cs and ip registers? Im obtaining unexpected errors :|

A big "Thank you" to anyone.
 
So why don't you cast the pointer to a function pointer and just call it?

Code:
void * p1 = 0x12345678;
void (*fp1)(void) = (void(*)(void))p1;
fp1();

Are you expecting any kind of return from these?

--
 
| void * p1 = 0x12345678;
| __asm jmp 0x12345678;
|
|Ive failed, till now, to reach this objective. The |instruction __asm jmp dword ptr [p1], for example, |generate a "jmp mem16" (FF 65 F8) jump. Moreover, |why "__asm call p1" fail to reach the memory address |referenced by p1?

__asm call p1 == makes a call to the memory location
holding the pointer, not to the location
in that memory location.

you have to use something like:

__asm mov esi p1
__asm call [esi] == esi holds the contents of the pointer
and [esi] marks for use eis as
the memory location to call to.

C++ and many other higher level language will not allow
you to use a absolute jmp, since all code is running
under some operating system that my have placed your
code and even the way you "see" where your code is, in
some place and some way that absolute jump will go where
you were not want to go to.

Succes, Tessa
 
First thing, thanks. In order:

> void * p1 = 0x12345678;
> void (*fp1)(void) = (void(*)(void))p1;
> fp1();

I wanted to avoid function pointers for 3 reasons. 1st i'm locking for a more general way to retrieve instructions, 2nd they generate a lot of code and, i see, os dependent:

void (*fp1)(void) = (void(*)(void))p1;
004114EC 8B 45 F8 mov eax,dword ptr [p1]
004114EF 89 45 E0 mov dword ptr [fp1],eax
fp1();
004114F2 8B F4 mov esi,esp
004114F4 FF 55 E0 call dword ptr [fp1]
004114F7 3B F4 cmp esi,esp
004114F9 E8 3D FC FF FF call @ILT+310(__RTC_CheckEsp) (41113Bh)

3rd the call instruction keeps to fail (Unhandled exception (Access violation)) :|.

> __asm call p1 == makes a call to the memory location
> holding the pointer, not to the location
> in that memory location.

i think you are right, but examinating the code masm seems to translate automatically "call p1" into "call dword ptr [p1]". call fails anyway.

right now i've "patched" in this way:

__asm
{
mov eax, p1
jmp eax
}

this bring me to p1. having previously populated p1 in this manner:

p1[0] = 0x90; // nop
p1[1] = 0xB8; // mov eax
memcpy( &(p1[2]), &p1, 4 ); // value held by p1
p1[6] = 0xff; p1[7] = 0xe0; // jmp eax

i obtain an infinite nop loop. as you see im trying to inject code and execute it at convenience. now i only need to correctly save cs and ip registers before the jump in order to correctly recover the calling point. push/pop, this shouldnt be too hard.

fabio

ps: assembly is REALLY interesting.
 
Mmmmmmmmmmm...

Question to self....


Why do I think that someone would want to inject code & execute it at his/her/its convenience....

Mmmmm...

Tricky one that, for an old cynic like me... :eek:)
 
I too am very curious as to what kind of problem needs this kind of solution.

--
 
lol! i didnt realize your comments immediatly... :)
no no, im not writing a virus nor something of offensive (really). indeed im only interested in manipulating my own program area; im exploring a new way to support particular interactions between code "at top speed".
i understand that this is not a comprehensive answer, but i hope to have made a bit of light.

btw... dont be scared by the nick, its due to a "... assembly is not a black art..." sentence in a book.

regards

 
And for the "oldy's" (I am one myself), a debugger that is not depending on single stepping hardware or debugging
register is often written with the use of self modifing
code.
You can trace a programming by copying the code in a
memory location add a ret to it and just call the memory
location.
Ceep in mind that you have to handle jmp call int, etc
by jourself.

p.s. BlackArt9 in most assembler you have to put in the
[ and ] since you could have wanted the offset
moved into the register.
With [ ] it always knows that it has to use its value.

The code you created is exectly the same as I was
explaning you. (only you use eax and I esi)
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top