View Full Version : I need help to understand the result of an asm operation

February 20th, 2008, 06:15
Hi friends!
I'm reversing a free PeCompact static unpacker and I'm stuck with something I can't understand.

Here is the piece of code:


004022D0 <> . 83EC 20 SUB ESP,20
004022D3 . A1 407B4000 MOV EAX,DWORD PTR DS:[407B40]
004022D8 . 8B0D 687B4000 MOV ECX,DWORD PTR DS:[407B68]
004022DE . 53 PUSH EBX
004022DF . 55 PUSH EBP
004022E0 . 8B5401 01 MOV EDX,DWORD PTR DS:[ECX+EAX+1]
004022E4 . 8B2D C4794000 MOV EBP,DWORD PTR DS:[4079C4] ; unpecomp.00400000
004022EA . 2BD5 SUB EDX,EBP

The value that is being moved to EAX is the Mem mapped packed file pointer that in my case is 0x01AF0000 ECX contains the entrypoint from the PeHeader which is 0x00001000.

My problem is the instruction at 0x004022E0. After MOV EDX,DWORD PTR DS:[ECX+EAX+1], EDX is equal to 0x00462CE0. Shouldn't it be 0x01AF1001?


February 20th, 2008, 06:41
The key to the mystery is that the expression:


is a POINTER operation. ECX, EAX are being interpreted as addresses, That is what the [brackets] are there for. What gets moved to EDX is the value located at the address ECX+EAX+1

February 20th, 2008, 07:39
Thanks naides! Before I had time to post a message saying that I figured it out you replied it.
Thanks very much.

February 20th, 2008, 12:44
This should be moved to newbie section, this is a basic assembly question.

February 21st, 2008, 06:52
Now I'll post my question on the right forum :-) sorry for the last one.
I still have a doubt about the last code I posted here and I found nothing helpful googling for it.

In fact I already solved the problem but I want to fully understand what is going on.

The code I posted on the first message seems to get the value at the entrypoint without reckoning the FileOffset first. I really don't understand how it works when I debug the application with olly, because neither in inline asm nor in c that code works.
I could only get the same result shown in olly with this code:


DWORD Offset = RvaToFileOffset( g_FileBuffer, (int)g_FileSize, g_PeHeader->OptionalHeader.AddressOfEntryPoint + 1, g_PeHeader );
unsigned char* pBuffer = MAKEPTR(unsigned char*,g_FileBuffer,Offset);
if ( pBuffer == NULL )
return 0;
DWORD Value = *(DWORD*)pBuffer - g_ImageBase;

Am I missing something in the asm code?

February 21st, 2008, 07:08
Cthulhu, you lost me.
Please rephrase the question making far less assumptions about the reader's knowledge of your current problem.
You need to provide far more context, and explain what the fuck hell that C type code snippet is doing in there.

February 21st, 2008, 08:28
I have seen a lot of replies like that recently on this forum and I don't see a reason for such rude and unpolite answers.

What I tried to explain here as I said in the message is that the asm snippet seems to be very simple and it just reads a dword value from the entrypoint of a pecompacted pe file and it does not calculates the file offset and then sums it with the begining of the compacted file buffer to achive this value and I only could get the same value doing it so.

I just provided the C code to show the amount of code I needed to get the same result olly shows in a much simpler way and even using inline assembly just like the code in olly it didn't work for me.

But nevermind, as I said in the message the problem is already solved I just wanted to understand why I had to do it in a different way.

February 21st, 2008, 09:03
Excuse me. My post was not intended as offense, actually I had my best intent to help you.
That is just the way I talk.

February 24th, 2008, 18:06
[Originally Posted by Cthulhu;72849]I have seen a lot of replies like that recently on this forum and I don't see a reason for such rude and unpolite answers.

You have to distinguish between rudeness and frustration. The c-type code you posted made no sense whatsoever. I'm a construction worker and I thought naides was overly polite.

Look at the first statement in your assembler:
004022D0 <> . 83EC 20 SUB ESP,20

It is making room for 8 DWORDS on the stack. Your code doesn't indicate why. It may be an attempt to obscure what they are doing. What does the RET statement say at the end of the function?

One trick used by protectionists is to PUSH a value onto the stack followed closely by a RET. In that manner, they can RET to an address other than the one immediately after the CALL statement. Using that method, they wouldn't have to calculate offsets as the RET would go straight to the last address on the stack.