Hawke
Hawke

Reputation: 584

What is this assembly code doing - Writing to process memory

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

Upvotes: 1

Views: 2030

Answers (1)

Neitsa
Neitsa

Reputation: 8166

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 | | ??  |   ...
     +-----+ +-----+ +-----+ +-----+ +-----+ +-----+

Upvotes: 5

Related Questions