Relocating (x86 asm)

Started by
8 comments, last by LessBread 15 years, 2 months ago
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]
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]
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]
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.
[TheUnbeliever]
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]
Crypter, that link was very interesting :)
Rainweaver Framework (working title)

IronLua (looking for a DLR expert)



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)
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
Quote:Original post by Crypter
Check out my site (Clicky).

It's called "environment", not "envirement" ;)
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.
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.

"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man

This topic is closed to new replies.

Advertisement