I'm still working on my minimal exe packer, and I have ran into a problem:

I have some code which I during runtime won't know the exact address of (part of the unpacking process). This code needs to read a memory position that is located 16 bytes before itself in the code. Is there any way to read this data without first having to find out the run-time address of the code?

I know I can quite easily find out the runtime address of the code, e.g. with a call/pop, but I'd much rather use a "pure relative" means of reading the data. Is this possible in any way, or will I have no choice at all but to resort to finding out the runtime address of the code first?

Any info or tips whatsoever about this would be greatly appreciated.

Posted on 2003-03-03 15:11:22 by dELTA
Posted on 2003-03-03 16:21:12 by comrade
Are you completely sure? :)
Come on now guys, where are the besserwissers that trash other people's replies with their own overly clever solutions when you need them? ;)
Posted on 2003-03-03 16:36:12 by dELTA
Posted on 2003-03-03 16:45:45 by comrade
If you know the data that is in the code and you just want to find the address.
Store the Eip at begining of program with call & pop. then store to a variable in .data . Then you can load esi with eip of variable.

mov ecx,08h
mov edx,Mark1
rol edx,8
mov ebx,regEIP ; find address marker
mov esi,ebx
mov al,
inc esi
cmp al,dl
jnz $-05h
mov regEIP,esi
dec cx
jnz $-1ah

This will point to end of data if data is 8bytes specified by ecx
Posted on 2003-03-03 23:57:35 by mrgone
Thanks mrgone, but as I mentioned in my original post, I already know I can do it this way, I was just wondering if it could be done in a "truly relative way" (i.e. without ever knowing the current EIP), but I guess that's not possible. Thanks everyone anyway!
Posted on 2003-03-04 05:54:41 by dELTA
If it's not using EIP, how can it be relative? :grin:
While some processors have a PC (EIP) relative addressing mode, the x86 only provides that mode for jump and call destinations, not for data access.
Posted on 2003-03-04 11:16:24 by tenkey
Ok, ok, without explicitly using EIP then. :tongue:

But it was something like that relative addressing mode that you mentioned that I was looking for anyway. Too bad x86 doesn't have it.
Posted on 2003-03-04 14:12:15 by dELTA

Are you completely sure? :)
Come on now guys, where are the besserwissers that trash other people's replies with their own overly clever solutions when you need them? ;)

that's a new one :tongue:
Posted on 2003-03-04 14:33:04 by Tola
You mean like:

mov ebx,XXX...h
mov al,
inc ebx
mov ah,

something like that? relative to a pointer? Sure you can do all that. Just make sure the memory is accessable or you may need to allocate in one way or another.
Your original question had to do with data inside your EXE. I don't think you can access that. You need to put it in a seperate file then open it with CreateFile and allocate some memory for it than you can relatively address it to your hearts content.
Posted on 2003-03-04 16:24:22 by mrgone
Hmm, if I'm not mistaken, that pointer ("XXX...h") must be relative to EIP, which is exactly the same as directly using EIP, so you're cheating. ;) Since this code is moved in memory after it was compiled/assembled, that pointer must have been written during the current runtime session for it to work... by some code using EIP as a reference. :rolleyes:

And no, there is no problem reading data from your own code segment in an exe file. If you want to write it you'll have to pay a visit to VirtualProtect first though.
Posted on 2003-03-04 19:06:35 by dELTA
Yeah I remember I had trouble writing into my EXE. I tried to over wright some nop's.
Ok back to your question. Relative to what? Well all pointers are relative to a segment. The Eip is relative to the code segment. THe EBP & ESP are relative to Stack Segment. Even through the memory is a virtual flat mapping it still has it's underlying structure of Segments and offsets. The ESI & EDI are used interchangeably with the Data Segment & Extra Segment and I think FS & GS. Now there are some rules when doing string movements example:

Mov ecx,0FFh
mov esi,1000h
mov edi,2000h

That will move CX no. of bytes from DS:ESI to ES:EDI so if it's flat memory that would mean FF bytes from addr 1000 to 2000.

In the virtual world each task is alotted 4GIG supposedly in it's flat memory model. I guess that comes from the assumption that all segment registers are set to the same value and the 32bit addressing is your usable memory being 2 to the 32nd power. Well I don't know about you but I have 512Meg physical memory in my machine and I have to ask Windows everytime I want a page of memory to write to and the operating system has to reside somewhere. I wish I had a method of examining the Task State Segments and Local Descriptor tables to see exactly what we do have. I'll bet it is surprizingly less than 4Gig. I don't know if I should go any further right here unless you varify that you have a general understanding of Protected Mode. Look for your response..Frank

Inside the virtual shell you can initialize your pointers,EBX,ESI,EDI (used in data manipulation) to anything. So you can increment a pointer and read or write and add offsets etc. They will all be relative to the Data Segment. Infact I wish I knew how to do a segment over ride. It is still supported in 386 and up but I don't think MASM supports it. By the way you seem like you pick alittle. Do you know how to machine code in an instruction with MASM?
Posted on 2003-03-04 20:36:56 by mrgone
Thanks for the info mrgone, but I know all that, and it still doesn't solve my problem.

You see, I'm working on an executable packer. I'm not sure if you know how these work, but they often deal with injecting code into other executables, and even building parts of executables themselves. Hence, situations can arise where you cannot rely on any pointer that was written during compile-time, since parts of the code has been moved out of its original executable and the code position is now relative to nothing. Hence, you cannot reference any data segment or anything like that from the code, so the one and only reference you have is the current address of execution.

Hence, I have a situation where I want to do the following:

Address Content
---------- -----------

???????? some_data:
???????? ...
???????? ...
???????? some_code:
???????? <code here reading "some_data">
???????? ...
???????? ...

The only way to do this (except for explicitly fetching the contents of the EIP register and then manipulating this pointer) would be if there, directly or indirectly, was available an addressing mode that could reference data with a position relative to the current instruction. According to the info received in this thread, the x86 architecture does not support any such features, and hence I'm screwed. ;) There are no other ways around it. I hope you understand now.

Anyway, I'm not sure what you mean with your question "Do you know how to machine code in an instruction with MASM", but please clarify and I will do my best to help.
Posted on 2003-03-05 11:10:51 by dELTA
There woudn't be much use for such an instruction as you usually don't read or write your own code. Is a call+pop that bad?

Posted on 2003-03-05 11:58:45 by Thomas
There's a couple solutions. Either use relocation data, or keep your unpacking code at a fixed location (#2 will only really work for 'standard' EXEs though).
Posted on 2003-03-05 12:10:46 by f0dder
f0dder: Thanks for the input.

Thomas: call+pop is bad because some stupid virus scanners give false alarms on it (see earlier thread about false virus alarm with MASM example program) and I don't want people to think that my packed files are infected with a virus. :(
Posted on 2003-03-05 14:06:08 by dELTA
What about:

mov eax, [esp]
call getNextIP
; eax equals eip now

This looks like a normal function call so probably won't alarm any virus scanners.

Posted on 2003-03-05 14:12:36 by Thomas
Well, you never know how "smart" their heuristic engines are, but I also guess it depends on how far away you are from the entrypoint of the program. Anyway, I know there are many variations on how to do it by using a call, and that most of them will most likely cause no trouble with anti-virus software, I just wanted to know if there was a cleaner way first. Thanks for the info anyway!
Posted on 2003-03-05 14:40:48 by dELTA
Isn't it about time for chapter 5 of the assembly networking tutorial soon Thomas? ;)
Posted on 2003-03-05 14:42:33 by dELTA

Isn't it about time for chapter 5 of the assembly networking tutorial soon Thomas? ;)

Hehe I know I know.. It's been too long ago. But actually I was working on it right now. I had to make quite a few images (timeline diagrams), they are finally finished now. Chapter 5 is an overview of all the I/O models (not enough info to use them yet, they will each be discussed in a seperate chapter later on). The blocking/polling/select/asyncselect/eventselect sections for chapter 5 are finished (totalling around 3000 words or so), I still need to do 4 sections on overlapped I/O and some final sections.
So it should be finished soon.

Posted on 2003-03-05 15:01:19 by Thomas