0

I am looking at the following disassembly for a Win32 executable in IDA pro and get the snwprintf part but I don't understand the purpose of the mov ecx, [eax+4] instruction here (are they discarding part of the string here?).

loc_4018E7:
mov     eax, 0DEEDh
push    eax
push    offset asc_402270 ; "%X"
push    4               ; size_t no. chars
lea     ecx, [ebp+var_inpPassStr]
push    ecx             ; wchar_t * opBuffer
call    ds:_snwprintf   ; convert number to HEX string
add     esp, 10h
xor     edx, edx
mov     [ebp+var_8], dx
mov     eax, [ebp+arg_inpPass]
mov     ecx, [eax+4]
mov     [ebp+var_14], ecx
lea     edx, [ebp+var_inpPassStr]
push    edx             ; wchar_t *
call    ds:wcslen
add     esp, 4
mov     esi, eax
mov     eax, [ebp+var_14]
push    eax             ; wchar_t *
call    ds:wcslen
add     esp, 4
cmp     esi, eax
jnz     short loc_401984; this prints "invalid pass"

Any insight on this would be great.

Bootstrapper
  • 1,089
  • 3
  • 14
  • 33
  • `call ds:wcslen` is an indirect call through a function pointer in the data section, right? So in NASM syntax it would be `call [wcslen]`? – Peter Cordes Jul 27 '16 at 04:46

3 Answers3

1

This

mov     eax, [ebp+arg_inpPass]
mov     ecx, [eax+4]

loads eax with the value of a function argument (named arg_inpPass by the disassembler), which happens to be a pointer, and then dereferences it, skipping the first 4 bytes.

Without knowing what the code is doing or seeing more of the code it's impossible to tell why the first 4 bytes are skipped. It could be that the pointer points to a structure and the function is interested in accessing its member at offset 4. It could be something else.

Alexey Frunze
  • 61,140
  • 12
  • 83
  • 180
-1

First, ebp does not get set during this disassembly block, probably it's done some lines earlier to this disassembly block. If this was written in assembly, it could point to somewhere else and not into the stack, as it is normally used in higher-level languages (C, C++ etc.).

mov     eax, [ebp+arg_inpPass]    ; read a dword variable (it's a pointer)
                                  ; from the stack into eax
mov     ecx, [eax+4]              ; use that pointer plus 4 to read a dword value
                                  ; from memory into ecx
mov     [ebp+var_14], ecx         ; store the value read into ecx into
                                  ; a local variable (in the stack)
nrz
  • 10,435
  • 4
  • 39
  • 71
  • The way it's used makes it nearly certain this is part of a function compiled with frame pointers enabled. The disassembler could be totally mistaken in choosing names like `arg_inPass` for the offsets from ebp, but I doubt it. It probably only does that if it sees the usual stack-frame setup in the prologue. In this case, it looks like it even had enough debug info to name the arg. – Peter Cordes Jul 27 '16 at 04:45
-1
mov     eax, [ebp+arg_inpPass]
mov     ecx, [eax+4]
mov     [ebp+var_14], ecx

First line, loads 4 bytes (32 bits or DWORD) from the address pointed by [ebp+arg_inpPass]

Second line loads 32 bits value from previous line address plus 4, meaning if eax is 12345678h, then ecx becomes a 32 bit value pointed by address 1234567Ch

Third line moves the value of ecx to address pointed by [ebp+var_14],

are you sure the first line is not LEA instruction?, if its really a mov then the code provides a way to access a memory location provided by the user.

rcd
  • 112
  • 1
  • 4
  • Why would any sane compiler use `lea eax, [ebp+arg_inPass]` / `mov ecx, [eax+4]` instead of `mov ecx, [ebp+arg_inPass+4]`? It's the same addressing mode (`[base_reg + disp8]`). – Peter Cordes Jul 27 '16 at 04:36
  • `if eax is 12345678h, then ecx becomes 1234567Ch`. Wrong. `eax` is dereferenced, to the difference between eax and ecx depends on the contents of memory. It's a load, not an LEA. (And terminology: use "load" instead of "extract") – Peter Cordes Jul 27 '16 at 04:38
  • More importantly, just explaining what each instruction does on its own doesn't help answer the question of why the compiler might have used them; i.e. what the code is actually doing as part of the big picture. This wouldn't be a useful answer even if it was correct. – Peter Cordes Jul 27 '16 at 04:39