aerelorn
asked on
Calling inline assembly directly
Howdy,
Basically, I need a way to get the memory address of the first instruction in an __asm block. Here's an example of what I'm talking about:
void ThisFunctionNeverGetsCalle dDirectly( )
{
__asm
{
mov eax, 1
add eax, 2
jmp MEMADDRESS
}
printf("This never gets executed because the asm block jumps back to where it was called from");
}
Basically, at runtime I'm going to change the instruction at MEMADDRESS-1 to jmp to the first statement, "mov eax, 1"(obviously just a placeholder for now). The rest of the asm block runs, then jmps back to MEMADDRESS and the program will proceed as normal.
The only problem is I need to find the address of that first instruction in order to make the jmp to it. I don't want to call ThisFunctionNeverGetsCalle dDirectly( ) because __asm modifies all the registers, the stack pointer,etc. The point is I want the assembly code to execute seamlessly as though it actually existed between MEMADDRESS-1 and MEMADDRESS.
Thanks for the help.
Basically, I need a way to get the memory address of the first instruction in an __asm block. Here's an example of what I'm talking about:
void ThisFunctionNeverGetsCalle
{
__asm
{
mov eax, 1
add eax, 2
jmp MEMADDRESS
}
printf("This never gets executed because the asm block jumps back to where it was called from");
}
Basically, at runtime I'm going to change the instruction at MEMADDRESS-1 to jmp to the first statement, "mov eax, 1"(obviously just a placeholder for now). The rest of the asm block runs, then jmps back to MEMADDRESS and the program will proceed as normal.
The only problem is I need to find the address of that first instruction in order to make the jmp to it. I don't want to call ThisFunctionNeverGetsCalle
Thanks for the help.
This is not fixed address, function is allocated on stack. Possibly this is [ESP], but all your idea looks strange, try to describe what you want to do. Maybe thete are another ways.
Why don't you want to use label:
__asm
{
start:
mov eax, 1
add eax, 2
jmp start
}
__asm
{
start:
mov eax, 1
add eax, 2
jmp start
}
HGLOBAL WINAPI MyGlobalAlloc(UINT uFlags, SIZE_T dwBytes)
{
PDWORD pRetAddr = (PDWORD)((&pRetAddr) + 2);
pRetAddr = (PDWORD)*pRetAddr;
}
pRetAddr is the return address.
But don't forget to clear the stack before jmp.
Some kind of protection code?
Good luck.
{
PDWORD pRetAddr = (PDWORD)((&pRetAddr) + 2);
pRetAddr = (PDWORD)*pRetAddr;
}
pRetAddr is the return address.
But don't forget to clear the stack before jmp.
Some kind of protection code?
Good luck.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Hi grg99,
I forgive you "the valiant attempts" and remind you again - take your points here:
http://oldlook.experts-exchange.com/questions/20766073/Points-for-grg99.html
Good luck.
I forgive you "the valiant attempts" and remind you again - take your points here:
http://oldlook.experts-exchange.com/questions/20766073/Points-for-grg99.html
Good luck.
>> // printf("This never gets executed because the asm block jumps back to where it was called from");
This would never get called anyway because it is commented out. :-)
Sorry grg99, I couldn't resist.
Exceter
This would never get called anyway because it is commented out. :-)
Sorry grg99, I couldn't resist.
Exceter
>Hi grg99,
>I forgive you "the valiant attempts" and remind you again - take your points here:
>http://oldlook.experts-exchange.com/questions/20766073/Points-for-grg99.html
>Good luck.
The EE user interface being like it is, I don't see any hint or button on that question that says "TAKE YOUR POINTS".
Also it's a bit curious why one would have to TAKE one's points. You'd think that could be done automatically.
>I forgive you "the valiant attempts" and remind you again - take your points here:
>http://oldlook.experts-exchange.com/questions/20766073/Points-for-grg99.html
>Good luck.
The EE user interface being like it is, I don't see any hint or button on that question that says "TAKE YOUR POINTS".
Also it's a bit curious why one would have to TAKE one's points. You'd think that could be done automatically.
>> The EE user interface being like it is, I don't see any hint or button on that question that says "TAKE YOUR POINTS".
It says that in the question title.
>> Also it's a bit curious why one would have to TAKE one's points. You'd think that could be done automatically.
I won't get into it here but, if you are interested, you can create a thread in referecne to this in the expert input TA.
Exceter
It says that in the question title.
>> Also it's a bit curious why one would have to TAKE one's points. You'd think that could be done automatically.
I won't get into it here but, if you are interested, you can create a thread in referecne to this in the expert input TA.
Exceter
>> The EE user interface being like it is, I don't see any hint or button on that question that says "TAKE YOUR POINTS".
>It says that in the question title.
I know it says that.... but HOW, Fawlty, HOW?
I know, it was posted at the Town Hall, in the barricaded bathroom in the basement,
in the filing cabinet with "STAY OUT. RABID COUGAR" emblazened.
>It says that in the question title.
I know it says that.... but HOW, Fawlty, HOW?
I know, it was posted at the Town Hall, in the barricaded bathroom in the basement,
in the filing cabinet with "STAY OUT. RABID COUGAR" emblazened.
>> I know it says that.... but HOW, Fawlty, HOW?
All you have to do is post. AlexFM will then accept your comment as the answer to the question. It's been standard proceedure around here for quite awhile.
Exceter
All you have to do is post. AlexFM will then accept your comment as the answer to the question. It's been standard proceedure around here for quite awhile.
Exceter
void ThisFunctionNeverGetsCalle dDirectly( )
{
__asm
{
Here:
mov eax, 1
add eax, 2
lea ebx, Here
jmp [ebx]
}
printf("This never gets executed because the asm block jumps back to where it was called from");
}
{
__asm
{
Here:
mov eax, 1
add eax, 2
lea ebx, Here
jmp [ebx]
}
printf("This never gets executed because the asm block jumps back to where it was called from");
}
ASKER
Okay, evidently I haven't explained this well enough. I posted it right before I went to bed hoping to have an answer by morning, but I was too tired to be clear. Please ignore everything I said above, it wouldn't work.
Here's what I'm starting with. This is code in my executable. The memory address(for this example 0040000) is found after my program loads:
00400000 MOV EAX,DWORD PTR SS:[ESP+2C]
00400004 ADD EAX,10h
00400007 PUSH EAX
What I want to do is execute a block of instructions seamlessly between the ADD and the PUSH. I figured I could do this by overwriting the original instructions like so:
00400000 NOP
00400001 NOP
00400002 JMP SOMEMEMORYADDRESS
00400007 PUSH EAX
SOMEMEMORYADDRESS+0 MOV EAX,DWORD PTR SS:[ESP+2C]
SOMEMEMORYADDRESS+4 ADD EAX,10h
SOMEMEMORYADDRESS+7 Insert my code here
SOMEMEMORYADDRESS+X jmp 00400007
Right now the only way I can think to do this is to:
1. Reserve an area of memory for my custom code
2. Copy a hand-assembled version of the code to that location
3. Set the final instruction, "JMP 00400007" because 00400007 isn't known at compile time(like I thought when I initially posted)
4. Overwrite the original memory with the 2 NOP's and the JMP to the reserved mem area
That should work(if it won't, somebody please correct me). The part I'm trying to avoid is the hand-assembled part. I was hoping there's some way I can trick the compiler into doing it for me.
Hopefully this is a bit clearer.
Here's what I'm starting with. This is code in my executable. The memory address(for this example 0040000) is found after my program loads:
00400000 MOV EAX,DWORD PTR SS:[ESP+2C]
00400004 ADD EAX,10h
00400007 PUSH EAX
What I want to do is execute a block of instructions seamlessly between the ADD and the PUSH. I figured I could do this by overwriting the original instructions like so:
00400000 NOP
00400001 NOP
00400002 JMP SOMEMEMORYADDRESS
00400007 PUSH EAX
SOMEMEMORYADDRESS+0 MOV EAX,DWORD PTR SS:[ESP+2C]
SOMEMEMORYADDRESS+4 ADD EAX,10h
SOMEMEMORYADDRESS+7 Insert my code here
SOMEMEMORYADDRESS+X jmp 00400007
Right now the only way I can think to do this is to:
1. Reserve an area of memory for my custom code
2. Copy a hand-assembled version of the code to that location
3. Set the final instruction, "JMP 00400007" because 00400007 isn't known at compile time(like I thought when I initially posted)
4. Overwrite the original memory with the 2 NOP's and the JMP to the reserved mem area
That should work(if it won't, somebody please correct me). The part I'm trying to avoid is the hand-assembled part. I was hoping there's some way I can trick the compiler into doing it for me.
Hopefully this is a bit clearer.
ASKER
I went and re-read the previous comments, and am thinking that the following modification of grg99's code would work.
void ThisFunctionReturnsTwoPoin ters(void* Begin, void* End)
{
__asm
{
lea Begin,BeginLabel
lea End,EndLabel
jmp Ret
BeginLabel:
mov EAX,DWORD PTR SS:[ESP+2C]
add EAX,10h
mov eax, 1
add eax, 2
//more of my code here
EndLabel:
Ret:
}
}
In my main program:
#define JMP 0xE9
#define NOP 0x90
DWORD ReturnAddress,Temp;
void* Mem,Begin,End;
DWORD Length;
BYTE jmp=JMP;
BYTE nop=NOP;
ReturnAddress = GetReturnAddress(); //this would be the 00400007 from above
ThisFunctionReturnsTwoPoin ters(Begin , End); //gets begin and end of asm block
Length = (DWORD)Begin - (DWORD)End;
Mem = malloc(Length + 5);
CopyMemory(Mem, Begin, Length); //copy the asm code to my reserved block
CopyMemory(Mem + Length, (void*)&jmp, 1); //add the jmp code
CopyMemory(Mem + Length + 1, (void*)&ReturnAddress, 4); //add the jmp address
//change original code
CopyMemory((void*)(ReturnA ddress - 7), (void*)&nop, 1);
CopyMemory((void*)(ReturnA ddress - 6), (void*)&nop, 1);
CopyMemory((void*)(ReturnA ddress - 5), (void*)&jmp, 1);
Temp=(DWORD)Begin;
CopyMemory((void*)(ReturnA ddress - 4), (void*)&Temp, 4);
Could someone look over this and confirm that it would work and does what I want?
void ThisFunctionReturnsTwoPoin
{
__asm
{
lea Begin,BeginLabel
lea End,EndLabel
jmp Ret
BeginLabel:
mov EAX,DWORD PTR SS:[ESP+2C]
add EAX,10h
mov eax, 1
add eax, 2
//more of my code here
EndLabel:
Ret:
}
}
In my main program:
#define JMP 0xE9
#define NOP 0x90
DWORD ReturnAddress,Temp;
void* Mem,Begin,End;
DWORD Length;
BYTE jmp=JMP;
BYTE nop=NOP;
ReturnAddress = GetReturnAddress(); //this would be the 00400007 from above
ThisFunctionReturnsTwoPoin
Length = (DWORD)Begin - (DWORD)End;
Mem = malloc(Length + 5);
CopyMemory(Mem, Begin, Length); //copy the asm code to my reserved block
CopyMemory(Mem + Length, (void*)&jmp, 1); //add the jmp code
CopyMemory(Mem + Length + 1, (void*)&ReturnAddress, 4); //add the jmp address
//change original code
CopyMemory((void*)(ReturnA
CopyMemory((void*)(ReturnA
CopyMemory((void*)(ReturnA
Temp=(DWORD)Begin;
CopyMemory((void*)(ReturnA
Could someone look over this and confirm that it would work and does what I want?
ASKER
Okay, I was able to get a variant on what's above working. Thanks grg99, I didn't know lea could be used on labels like that.
grg99,
In the question you helped me I wrote: take your points here... and you could read this after receiving e-mail notification. Possibly you missed this e-mail or didn't read my comment. Usually this works without adding any special features to EE.
In the question you helped me I wrote: take your points here... and you could read this after receiving e-mail notification. Possibly you missed this e-mail or didn't read my comment. Usually this works without adding any special features to EE.
By the way, I saved this page and will read it carefully to improve my rudimentary Assembly knowledge.
ASKER
I'm not sure if you'll read this again AlexFM, but if you do here's the final version of the code so you can see how it all fit together:
#define JMP 0xE9
#define NOP 0x90
#define REPLACEADDR 0x0050D5DD
#define RETADDR 0x0050D5F6
void SetupFunction()
{
DWORD BeginLabel,EndLabel;
__asm
{
lea eax,BeginLabel
mov Begin,eax
lea eax,EndLabel
mov End,eax
jmp EndLabel
BeginLabel:
mov eax,DWORD PTR SS:[ESP+0x2C]
add eax,10h
//more of my code here
nop //placeholders for jmp
nop //placeholders for jmp
nop //placeholders for jmp
nop //placeholders for jmp
nop //placeholders for jmp
EndLabel:
}
DWORD ReplaceAddr,RetAddr,Length ;
long Offset;
BYTE jmp=JMP,nop=NOP;
RetAddr=RETADDR;
ReplaceAddr=REPLACEADDR;
Length=End-Begin;
hProcess=OpenProcess(PROCE SS_ALL_ACC ESS,false, hProcessId );
Offset=RetAddr-(Begin+Leng th);
//add jmp instruction
WriteProcessMemory(hProces s,(void*)( Begin+Leng th-5),(voi d*)&jmp,si zeof(jmp), NULL);
//add the jmp address
WriteProcessMemory(hProces s,(void*)( Begin+Leng th-4),(voi d*)&Offset ,sizeof(Of fset),NULL );
//change original code
Offset=Begin-ReplaceAddr;
WriteProcessMemory(hProces s,(void*)( ReplaceAdd r-7),&nop, sizeof(nop ),NULL);
WriteProcessMemory(hProces s,(void*)( ReplaceAdd r-6),&nop, sizeof(nop ),NULL);
WriteProcessMemory(hProces s,(void*)( ReplaceAdd r-5),&jmp, sizeof(jmp ),NULL);
WriteProcessMemory(hProces s,(void*)( ReplaceAdd r-4),&Offs et,sizeof( Offset),NU LL);
}
void ClearFunction()
{
DWORD ReplaceAddr;
ReplaceAddr=REPLACEADDR;
WriteProcessMemory(hProces s,(void*)( ReplaceAdd r-7),(void *)(Begin+1 ),7,NULL);
}
Cheers.
#define JMP 0xE9
#define NOP 0x90
#define REPLACEADDR 0x0050D5DD
#define RETADDR 0x0050D5F6
void SetupFunction()
{
DWORD BeginLabel,EndLabel;
__asm
{
lea eax,BeginLabel
mov Begin,eax
lea eax,EndLabel
mov End,eax
jmp EndLabel
BeginLabel:
mov eax,DWORD PTR SS:[ESP+0x2C]
add eax,10h
//more of my code here
nop //placeholders for jmp
nop //placeholders for jmp
nop //placeholders for jmp
nop //placeholders for jmp
nop //placeholders for jmp
EndLabel:
}
DWORD ReplaceAddr,RetAddr,Length
long Offset;
BYTE jmp=JMP,nop=NOP;
RetAddr=RETADDR;
ReplaceAddr=REPLACEADDR;
Length=End-Begin;
hProcess=OpenProcess(PROCE
Offset=RetAddr-(Begin+Leng
//add jmp instruction
WriteProcessMemory(hProces
//add the jmp address
WriteProcessMemory(hProces
//change original code
Offset=Begin-ReplaceAddr;
WriteProcessMemory(hProces
WriteProcessMemory(hProces
WriteProcessMemory(hProces
WriteProcessMemory(hProces
}
void ClearFunction()
{
DWORD ReplaceAddr;
ReplaceAddr=REPLACEADDR;
WriteProcessMemory(hProces
}
Cheers.
Thanks.