1
votes

Edit/Upate

So I think what confuses me is that:

LEA ESI, [EBX + 8*EAX + 4]

Loads an address, but:

LEA ESI, [EBX + 4]

Loads the content (value?) and not an address. How is this not dereferencing?

I am also still not sure what

mov [eax+1], ecx

does?

Original Question

I am trying to learn to read assembly, however I am starting to struggle. Sorry if there are typos, I cannot copy from my lab machine. This is from malicious code, so it may not be optimal.

I think I have a flawed understanding somewhere, but I just can't figure this out.

var_30 = byte ptr -30h     
lea eax, [ebp+esi+var_30]

My understanding is that a load effective address will become whatever address is calculated from [basepointer-30h+esi]. I don't know what esi or edi is.

lea ecx, [esi+edi] 
lea ebx, [esi+6] 

So I believe that ebx is the resultant address of esi + 6 bytes?

mov esi, ds:WriteProcessMemory

esi points to the WriteProcessMemory API call

mov byte ptr [eax], 68h 

Which I believe puts the instruction PUSH into the address of eax (which is currently [basepointer-30h+esi]

mov [eax+1], ecx

I believe ecx, which is now the address of [esi+edi], contains the argument to give to the PUSH instruction. Does this mean that eax+1 now points to the contents ecx (whatever was in [esi+edi]]?

mov byte ptr [eax+5], 0C3h 

This I think puts the instruction RET into the address [eax+5].

lea eax, [epb+var_30]

This essentially moves eax back/forward by whatever esi was, but I am not sure why?

push [ebp+lpBaseAddress]; lpBaseAddress
push 0FFFFFFFFh; hProcess (-1 = this process)

call esi

What confuses me:

ebx is used as the argument for nSize, but why would the length of the content would be stored at the address [esi+6]? I initially thought that it was +6 because that could be the length of 'PUSH arg RET (eax to eax+5)', but it is an address and not a short int. Is the short int (nSize) placed at that address by a previous subroutine?

Why is eax (lpBuffer - the content to write) now at [eax-30h]. Did esi allocate space, but start writing content from the end? Something like:

ebp+var_30+esi (eax, start of buffer address) : PUSH(eax) : arg(eax+1) RET(eax+5) : ebp+var_30 (new eax, end of buffer address)?

I don't think I fully understand what esi or edi are doing, but I don't have the full code to work out what they are.

Thanks

1
I think you'll have an easier time learning assembly language by starting with simpler programs rather than malware. Malware is notoriously hard to understand.Raymond Chen
@nissimabehcera this looks like windows code judging from the WriteProcessMemory, lpBaseAddress, hProcess and the windows tag. Also it's 32 bit. Your claim that "edi register store the first parameter of function and esi second parameter of function" applies to 64 bit sysv calling convention, not 32 bit windows.Jester
lea ebx, [esi+6] load effective address of CONTENT pointed by esi+6 . For exemple, if esi register's value is 0xffff1234, [esi+6] is value stored at address 0xffff1234 plus 6 bytes. It's similar of pointers in C language, like (*ptr+6) => *ptr access to value pointed by ptr and add 6 . [epb+var_30] = [ebp-30h] ebp (base pointer register) points to beginning of stack, and stack grows downwards. So if you push data on the stack, a pointer needs to be "decreased" by the size of pushed data.nissim abehcera
For exemple, ebp=0xffff3698 , and i need to store on the stack a value 10 then a value 20 => mov [ebp],10 mov [ebp-4] ,20 ( because a stack is 4 bytes aligned ). "but start writing content from the end " ? yes for exemple , you have "abc" to push into stack, if cpu insert at beginning of string, the content of stack looks like cba but from the end , abcnissim abehcera
The full code, including the call to WriteProcessMemory, would help to understand what's going on better.Margaret Bloom

1 Answers

5
votes

Addressing your edit

If you are confused by LEA think of it like this:

  • Calculate everything in the source operand.
  • Put the result of the calculation (of the source operand) into the destination operand.

So I think what confuses me is that:

LEA ESI, [EBX + 8*EAX + 4]

Technically the instruction doesn't care if it's an address (moreover in flat memory everything in a register can be an address).

Take the following pre-conditions:

  • EBX = 2
  • EAX = 1

Then calculate the source:

  • [EBX + 8*EAX + 4] = 2 + 8 * 1 + 4 = 2 + 8 + 4 = 14

Move the result into ESI:

  • LEA ESI, [EBX + 8*EAX + 4] ; ESI = 14 (EBX = 2; EAX = 1)

LEA ESI, [EBX + 4] Loads the content (value?) and not an address. How is this not dereferencing?

The same applies here. Let's say EBX = 2 and you end up with ESI = 6.

I am also still not sure what mov [eax+1], ecx does?

Take the value of EAX then add 1; now this value (eax + 1) is a pointer at which you'll store the 32-bit (assuming no size override) value in ECX.

Simple example:

  • EAX = 0x8000
  • ECX = 2

Now, calculate: EAX + 1 = 0x8001

  • Take this value as a pointer (or if you wish a memory location)
  • Store the value of ECX (2; as a 32-bit value) at address 0x8001.
     0x8000  0x8001  0x8002  0x8003  0x8004  0x8005
     +-----+ +-----+ +-----+ +-----+ +-----+ +-----+
...  |  ?? | |  02 | | 00  | |  00 | |  00 | | ??  |   ...
     +-----+ +-----+ +-----+ +-----+ +-----+ +-----+