Jump to content
  • Advertisement
Sign in to follow this  
Crypter

Relocating (x86 asm)

This topic is 3494 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone, I am working on a software system using Microsoft Visual C++ 2008. My code is running at physical address 0x10000 but is capable of loading files and programs to the same location. I want the system to relocate itself to another part of memory when these types of programs are being read. Because only one program is ran at one time; I figure just relocate the code to 1mb. I managed to get it working fine inline (ie; inside of a function, but not its own routine) Im looking for a cleaner method though and for it to be in a routine. It relocates it fine but I cannot seem to be able to return from the routine without problems (page faults, general protection errors..) Does anyone spot where I might be going wrong? ...Perhaps I am messing up the stack somehow? (Although I dont see how..)
void  core::relocate () {

	_asm {

		; save stack
		mov		eax, esp

		; copies ourself to 1mb	
		cld
		mov		esi, 0x10000
		mov		edi, 0x100000
		mov		ecx, [_osloader_size]
		rep		movsd

		; jumps to relocated addr
		mov		ebx, 0x100000 + (cont-0x10000)
		push		ebx
		ret

	cont:
		; restore stack
		mov		esp, eax

		; change return eip to reloc+return eip
		pop		ebx
		sub		ebx, 0x10000		; turn return eip into offset
		add		ebx, 0x100000		; ..and add reloc addr

		; return to relocated code (Crashes when it returns here :( )
		push		ebx
		ret
	}
}
I can post more info if needed. Thanks for any help [smile]

Share this post


Link to post
Share on other sites
Advertisement
The biggest problem I see currently is that you are using that assembly code in a C++ class function. The problem with that is you are not only getting prolog/epilog instructions inserted from VS, you are also getting additional code that was used to setup the class member function call. Also, you are going to be getting some stack checks as well (_RTC_CheckEsp, _RTC_CheckStackVars, and __security_check_cookie for example)

To see what I am talking about, what you can do is:
1. Add about 6 _asm nop at the top of the function.
2. Download OllyDbg
3. Open your executable (debug mode works best) in OllyDbg.
4. Hit ctrl + S to bring up the Find sequence of commands
5. Type NOP on seperate lines 6 times and hit Find, you should hit your function.
6. Breakpoint on the function entry and being tracing the code, you should see why it crashes at the end, you will be returning with a messed up stack due to epilog code not being executed.

I think you should be able to hack up a solution this way [smile]

Share this post


Link to post
Share on other sites
You are right--I didn't even think about my usage of it being a class member function.

I decided to make the routine global and modified the code using the disassembly as a guide (the prolog/epilog code, specifically.) Its working now, thank you for your help! [smile]

Here's the new routine in case anyone is interested. It returns to the next instruction to follow the relocate call + its relocation address.

void relocate (uint32_t curAddr, uint32_t newAddr, uint32_t n) {

#ifdef _MSC_VER
_asm {

; save stack
mov eax, esp

; copies ourself to reloc addr
cld
mov esi, [curAddr]
mov edi, [newAddr]
mov ecx, [n]
rep movsd

; jumps to relocated addr
mov ebx, cont
sub ebx, [curAddr] ; cont-curAddr; turn cont into offset
add ebx, [newAddr] ; ...and add the new base addr
push ebx
ret

cont:

; change return eip to reloc+return eip
mov eax, [esp+16]
sub eax, [curAddr] ; (prev eip - prev base) turn return eip into offset
add eax, [newAddr] ; ..and add reloc addr

; write the new return eip
mov [esp+16], eax

; restore stack
pop edi ; stack frame from epilog code
pop esi
pop ebx
pop ebp

; return to relocated code
ret
}
#endif
}


*edit: there was a bug with the old code...it was returning to the old eip address rather then the relocated address. Updated post with new code.

[Edited by - Crypter on January 25, 2009 1:02:35 PM]

Share this post


Link to post
Share on other sites
Off-topic, but how did you get Visual Studio to cooperate for writing freestanding code?

I'd like to get back into OS dev but the hassle of dual-booting into a Linux and creating a cross-compiling toolchain puts me off.

Share this post


Link to post
Share on other sites
Quote:
Off-topic, but how did you get Visual Studio to cooperate for writing freestanding code?

Check out my site (Clicky). It describes everything needed. I originally wrote it for Visual C++ 2005 but it also works with Visual C++ 2008. Hope it helps you out [smile]

Share this post


Link to post
Share on other sites
Quote:
Original post by Crypter
Check out my site (Clicky). It describes everything needed. I originally wrote it for Visual C++ 2005 but it also works with Visual C++ 2008. Hope it helps you out [smile]


What is the status of your page fault handler? Will you use a trap frame to catch and dissipate page faults? Do you really need a more evolved OS to dissipate page faults? (per VM)

Share this post


Link to post
Share on other sites
Quote:
What is the status of your page fault handler? Will you use a trap frame to catch and dissipate page faults? Do you really need a more evolved OS to dissipate page faults? (per VM)

I am still considering the method that I will use. You don't really *need* a more evolved OS but without a disk driver of any type you would be forced to use other methods for swapping pages from disk (ie; real mode bios perhaps?) or a completely different method for handling them.

My real system uses a trap frame, yes. er.. rather my *old* system did; it does not yet apply to my new system though sense its being rewritten.

Quote:
It's called "environment", not "envirement" ;)

Thanks for the typo [smile] I tend to misspell things alot in the series; not to the point of losing comprehension though. I do plan on going back through it and cleaning it up; but for now I am more worried about its content then anything else. Of course, I clean up misspellings when I see them though or others point them out.

Share this post


Link to post
Share on other sites
Quote:
Original post by Crypter
Quote:
What is the status of your page fault handler? Will you use a trap frame to catch and dissipate page faults? Do you really need a more evolved OS to dissipate page faults? (per VM)

I am still considering the method that I will use. You don't really *need* a more evolved OS but without a disk driver of any type you would be forced to use other methods for swapping pages from disk (ie; real mode bios perhaps?) or a completely different method for handling them.


I see. The Intel CPU docs contain a lot of information about virtual memory management without touching on disks too much, but I suppose pages can't be swapped without a disk to swap them from.

Quote:
Original post by Crypter
My real system uses a trap frame, yes. er.. rather my *old* system did; it does not yet apply to my new system though sense its being rewritten.


That would be "since" not "sense". Sense is what you do with your senses (eyes, ears, etc). [grin]

At any rate, I think trap frames are neat, sort of like kernel mode exception handlers.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!