2013-02-24 4 views
0

Я рассматриваю следующую разборку для исполняемого файла Win32 в IDA pro и получить часть snwprintf, но я не понимаю цели инструкции mov ecx, [eax+4] здесь (они отбрасывают часть строка здесь?).Попытка выяснить следующую информацию о разборке

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" 

Любое понимание этого было бы замечательным.

+0

'call ds: wcslen' - это косвенный вызов через указатель функции в разделе данных, правильно? Таким образом, в синтаксисе NASM это будет 'call [wcslen]'? –

ответ

-1

Во-первых, ebp не устанавливается во время этого блока разборки, возможно, это сделано ранее на этом блоке разборки. Если это было записано в сборке, оно может указывать на другое место, а не на стек, поскольку оно обычно используется на языках более высокого уровня (C, C++ и т. Д.).

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) 
+0

Способ использования почти уверен, что это часть функции, скомпилированной с помощью указателей на рамки. Дисассемблер может быть совершенно ошибочным при выборе имен, таких как 'arg_inPass' для смещений от ebp, но я в этом сомневаюсь. Вероятно, это только делает это, если он видит обычную установку стека в прологе. В этом случае, похоже, что у него даже было достаточно информации об отладке, чтобы назвать arg. –

1

Это

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

нагрузки eax со значением аргумента функции (названный arg_inpPass по дизассемблер), который случается быть указателем, а затем разыменовывает его, пропуская первые 4 байта.

Не зная, что делает код или видит больше кода, невозможно сказать, почему пропускаются первые 4 байта. Может быть, указатель указывает на структуру, и функция заинтересована в доступе к ее члену со смещением 4. Это может быть что-то еще.

-1
mov  eax, [ebp+arg_inpPass] 
mov  ecx, [eax+4] 
mov  [ebp+var_14], ecx 

Первая линия, грузы 4 байта (32 бита или DWORD) из адреса, на который указывает [EBP + arg_inpPass]

Вторая строка загружает 32 бита значения из предыдущего адреса строки плюс 4, то есть, если EAX находится 12345678h, то ECX становится 32 бит значение указываемого адреса 1234567Ch

Третья строка перемещает значение ECX по адресу, указанному на [EBP + var_14]

вы уверены, что первая строка не инструкция LEA ?, если это действительно мотив, то код обеспечивает способ ccess местоположение памяти, предоставленное пользователем.

+0

Зачем компилятор должен использовать 'lea eax, [ebp + arg_inPass]'/'mov ecx, [eax + 4]' вместо 'mov ecx, [ebp + arg_inPass + 4]'? Это тот же режим адресации ('[base_reg + disp8]'). –

+0

'if eax is 12345678h, тогда ecx становится 1234567Ch'. Неправильно. 'eax' разыменовывается, разница между eax и ecx зависит от содержимого памяти. Это нагрузка, а не LEA. (И терминология: используйте «load» вместо «extract») –

+0

Что еще более важно, просто объясняя, что каждая инструкция делает сама по себе, не помогает ответить на вопрос, почему компилятор мог их использовать; то есть код, который фактически выполняет как часть общей картины. Это не было бы полезным ответом, даже если бы это было правильно. –