ASM
해당값이 NULL인 경우를 표현하는 일반적인 패턴
==========================================================
if( m_pwcsExeName )
swprintf_s( wcsBuf, _countof(wcsBuf), L"[%s] ", m_pwcsExeName );
mov r9, qword ptr [mod!CSyncError::m_pwcsExeName]
test r9,r9
je jmpAddr ; r9이 0이면 jmpAddr로 감
==========================================================
멀티바이트 nop 인스트럭션(nop dword ptr)
우연히 아래와 같은 OP-CODE를 확인하게 되었다.
000007fe`f2a11123 0f838f020000 jae xx64!DllMain+0x3b8 (000007fe`f2a113b8)
000007fe`f2a11129 0f1f8000000000 nop dword ptr [rax]000007fe`f2a11130 483919 cmp qword ptr [rcx],rbx ds:00000000`49f49000={msvcrt!memset (000007fe`fef51000)}
000007fe`f2a11133 740e je xx64!DllMain+0x143 (000007fe`f2a11143)
000007fe`f2a11135 4883c108 add rcx,8
000007fe`f2a11139 483bc8 cmp rcx,rax
데이터정렬 목적으로다가 패딩개념으로 사용된다고 하는데, 그냥 nop이 여러개 있는 것으로 생각하면 될 것 같다.(인텔 매뉴얼. 3.5.1.19 섹션을 확인해봐라!)
여기서는 7바이트짜리 nop 코드. 실행에는 영향을 미치지 않는다
sete dest 설명
sete는 비교결과 Zero Flag가 SET되고 오퍼랜드의 바이트를 1로 세팅을 하는 거고
그외에는 오퍼랜드의 바이트를 0으로 세팅을 하는 거다.
아래와 같은 명령문이 있을때
g_dwVideoTest = !g_dwVideoTest;
이것의 ASM은 보통 다음과 같이 된다.
xor eax, eax
cmp dword ptr[g_dwVideoTest], 0 ; 만약 0과 같은 경우 ZeroFlag SET
sete al ; g_dwVideoTest가 0인 경우는 al이 1로 될거고 0이 아닌 경우는 al이 0이 된다
mov dword ptr[g_dwVideoTest], eax
JE/JZ : 결과가 0이면 분기
JNE/JNZ : 결과가 0이 아니면 분기
JL/JNGE : 결과가 작으면 분기(부호화된 수)
JB/JNAE : 결과가 작으면 분기(부호화안된 수)
JS : 부호 플래그가 1이면 분기
JNS : 부호 플래그가 0이면 분기
LOOP : CX를 감소하면서 0이 될때까지 지정된 라벨로 분기
LOOPZ/LOOPE : 제로이면(제로 플래그가 1)서 CX!=0이면 지정된 라벨로 분기
LOOPNZ/LOOPNE : 제로가 아니면서(제로 플래그가 0) CX!=0이면 지정된 라벨로 분기
wcslen() 구현
0006 118f lea eax, [esp+28h] // 시작주소
0006 1193 lea edx, [eax+2] //
0006 1196 mov cx, word ptr[eax]
0006 1199 add eax, 2
0006 119c test cx, cx // cx가 0 이면 즉, 스트링이 끝났으면 jne 다음으로 이동
0006 119f jne 00061196
0006 11a1 sub eax, edx // eax는 총길이
0006 11a3 sar eax, 1 // eax >> 1 유니코드이므로 2로 나누어줌
0006 11a5 mov edx, eax // edx가 wcslen()의 결과값
0006 1193 lea edx, [eax+2] //
0006 1196 mov cx, word ptr[eax]
0006 1199 add eax, 2
0006 119c test cx, cx // cx가 0 이면 즉, 스트링이 끝났으면 jne 다음으로 이동
0006 119f jne 00061196
0006 11a1 sub eax, edx // eax는 총길이
0006 11a3 sar eax, 1 // eax >> 1 유니코드이므로 2로 나누어줌
0006 11a5 mov edx, eax // edx가 wcslen()의 결과값
cdq(convert doubleword to quadword)
notifyEntry->pSignalContext
ebp-10 : 85d9ea68
ebp-c : 00000001
ebp-8 : 876ce2e8
mov eax, dword ptr[ebp-8]
cdq ; edx = FFFFFFFF, eax = eax(EDX:EAX = signed-extend of EAX)
mov ecx, dword ptr[ebp-10]
mov dword ptr[ecx+21bh], eax
mov dword ptr[ecx+21fh], edx
==================================================
x64에서 낮은 바이트값을 접근하는데 사용하는 레지스터(bpl)
| 64-bit register | Lower 32 bits | Lower 16 bits | Lower 8 bits |
|---|---|---|---|
rax
|
eax
|
ax
|
al
|
rbx
|
ebx
|
bx
|
bl
|
rcx
|
ecx
|
cx
|
cl
|
rdx
|
edx
|
dx
|
dl
|
rsi
|
esi
|
si
|
sil
|
rdi
|
edi
|
di
|
dil
|
rbp
|
ebp
|
bp
|
bpl
|
rsp
|
esp
|
sp
|
spl
|
r8
|
r8d
|
r8w
|
x86과는 달리, C/C++ 컴파일러는 x64에 대해서 한개의 호출 관례만을 지원한다. 이러한 호출 관례는 x64에서 이용 가능하게 된 레지스터를 이용한다.
순차적으로 rcx, rdx, r8, r9를 사용한다.
floating-pointer 파라미터는 순차적으로 xmm0-xmm3을 사용한다.
====================================================
멀티바이트 nop 인스터럭션(nop dword ptr)
우연히 아래와 같은 OP-CODE를 확인하게 되었다.
000007fe`f2a11123 0f838f020000 jae xx64!DllMain+0x3b8 (000007fe`f2a113b8)
000007fe`f2a11129 0f1f8000000000 nop dword ptr [rax]000007fe`f2a11130 483919 cmp qword ptr [rcx],rbx ds:00000000`49f49000={msvcrt!memset (000007fe`fef51000)}
000007fe`f2a11133 740e je xx64!DllMain+0x143 (000007fe`f2a11143)
000007fe`f2a11135 4883c108 add rcx,8
000007fe`f2a11139 483bc8 cmp rcx,rax
데이터정렬 목적으로다가 패딩개념으로 사용된다고 하는데, 그냥 nop이 여러개 있는 것으로 생각하면 될 것 같다.(인텔 매뉴얼. 3.5.1.19 섹션을 확인해봐라!)
여기서는 7바이트짜리 nop 코드. 실행에는 영향을 미치지 않는다
====================================================
sete dest 설명
sete는 비교결과 Zero Flag가 SET되고 오퍼랜드의 바이트를 1로 세팅을 하는 거고
그외에는 오퍼랜드의 바이트를 0으로 세팅을 하는 거다.
아래와 같은 명령문이 있을때
g_dwVideoTest = !g_dwVideoTest;
이것의 ASM은 보통 다음과 같이 된다.
xor eax, eax
cmp dword ptr[g_dwVideoTest], 0 ; 만약 0과 같은 경우 ZeroFlag SET
sete al ; g_dwVideoTest가 0인 경우는 al이 1로 될거고 0이 아닌 경우는 al이 0이 된다
mov dword ptr[g_dwVideoTest], eax
그외에는 오퍼랜드의 바이트를 0으로 세팅을 하는 거다.
아래와 같은 명령문이 있을때
g_dwVideoTest = !g_dwVideoTest;
이것의 ASM은 보통 다음과 같이 된다.
xor eax, eax
cmp dword ptr[g_dwVideoTest], 0 ; 만약 0과 같은 경우 ZeroFlag SET
sete al ; g_dwVideoTest가 0인 경우는 al이 1로 될거고 0이 아닌 경우는 al이 0이 된다
mov dword ptr[g_dwVideoTest], eax
댓글
댓글 쓰기