메모리 피라미드




범용 16bit register 용도
 
AX : 산술연산, 함수 반환결과
BX : 간접주소 참조용
CX : 반복문의 반복 횟수
DX : 다른 레지스터를 보조
SI : 대용량 복사(출발지 주소)
DI : 대용량 복사(도착지 주소)
SP : 스택의 지점(top)
BP : 스택의 지점(base)
 
32bit
EAX : 산술연산, 함수 반환결과
EBX : 간접주소 참조용
ECX : 반복문의 반복 횟수
EDX : 다른 레지스터를 보조
ESI : 대용량 복사(출발지 주소)
EDI : 대용량 복사(도착지 주소)
ESP : 스택의 지점(top)
EBP : 스택의 지점(base)
 
64bit
32bit
RAX : 산술연산, 함수 반환결과
RBX : 간접주소 참조용
RCX : 반복문의 반복 횟수
RDX : 다른 레지스터를 보조
RSI : 대용량 복사(출발지 주소)
RDI : 대용량 복사(도착지 주소)
RSP : 스택의 지점(top)
RBP : 스택의 지점(base)
 
사이즈
byte : 1byte
word : 2byte
dword : 4byte
qword : 8byte
 
byte order
multi bytes data, string(x) : little endian
 
 
디센딩 스택 : 데이터가 쌓일수록 주소체계가 작아진다.
어센딩 스택 : 데이터가 쌓일수록 주소체계가 커진다.
 
empty 스택 : 스택의 top을 비워두는 것
full 스택 : 스택의 top을 채워놓은 것
 
 
데이터이동
 push, pop, mov, movsx, movs, lea
데이터처리
 add, sub, mul, imul, div, idiv, inc, dec,
 and, or, not, xor, neg, shl, shr, sal, sar, rol, ror,
 cmp, test
데이터실행
 jmp, rep, call, ret
 
 
 
mov eax, DWORD pt ss:[100]
설명 : 100번지를 찾아가서 4byte를 eax에 넣음
(ss:[100]는 스택 세그먼트로 100만큼 떨어진 주소)
 
movzx : 조건 sizeof(oper1) > sizeof(oper2)
//남은 공간을 0으로 채움
 
movsz : 조건 sizeof(oper2) < sizeof(oper2)
//부호비트를 부호비트로 채운다.
 
mov bl, 80
= movsx ax, bl -> FF80
= movzx ax bl -> 0080
 
movs oper1, oper2
 
mov ecx, 2
rep movs DWORD ptr ss:[edi], DWORD ptr ss:[esi]
//rep은 반복
//esi의 주소의 데이터를 4바이트씩 2번 edi의 주소 메모리 공간에 복사를 해라.
 
 
 
lea oper1, oper2
//oper2의 주소를 oper1에 넣어라
 
add oper1 , oper2
//oper1 += oper2
 
sub oper1, oper2
//oper1 -= oper2
 
mul oper1
ex) mul cl -> al * cl (eax에서 같은 위치를 찾아서 곱한다.)
1바이트 *1바이트 = 2바이트(확장해서 저장)
 
ac * cx = dx:ax(dx의 도움을 받아서 저장한다.)
 
mul ecx -> eax * ecx = edx:eax
 
imul oper1
 mul동일
imul oper1, oper2
 oper1 *= oper2(오버플로되는 것은 버려버림)
imul oper1, oper2, oper3
 oper1 = oper2 * oper3(오버플로 되는 것은 버림)
//부호를 보는 연산
 
 
div cl
 ah:al / cl
div cx
 dx:ax / cx
 
div ecx
 edx:eax / ecx
 
idiv oper1
cbw : al -> ah:al 부호를 보면서 확장
cwd : ax -> dx:ax
cdq : eax -> edx:eax
 
inc eax : 1증가
dec eax : 1감소
 
비트연산
and oper1, oper2
 oper1 &= oper2
or oper1, oper2
 oper1 |= oper2
 
not oper1
 oper1 = ~oper1
 
xor oper1 , oper2
 oper1 ^= oper2
 
not oper1
 oper1 =~oper1
 
neg oper1
 oper1 = -oper1
 
 
shl oper1 , oper2
shl al, 2
//왼쪽으로 비트를 2번 밀어라
 
왼쪽으로 1번 밀었을 경우
10111011 -> 0110110
//왼쪽 밀린 것은 버리고 오른쪽 끝은 0으로 채운다.
 
ro : 비트 회전이동
 
cmp oper1, oper2
//비교 내부적으로 두 개의 데이터를 뺀다
//oper1 - oper2
 
flag register(CPU의 상태)
//or 연산
- SF (음수면 1, ZF는 0으로 세팅됨)
- ZF (0인지)
 
mask(지정, 기준)
//and 연산
test oper1, oper2
//oper1 & oper2
test eax, eax
//eax의 값을 확인하기 위해 and연산을 한다.
 
jmp oper1(address//코드주소)
 mov eip, oper1(실제로 EIP를 건드릴 수는 없다.)
 
text영역 (코드영역)
스택영역 : 지역변수
 
EIP : 다음에 실행할 코드를 가리킴
 
jmp 조합
-------------------------
j g a >
 e z =
 l b <
 n  !
-------------------------
 
 
rep opcode
//어떤 특정 opcode를 반복해라
//ecx가 0이 되기 전까지
//ecx를 1씩 감소시킨다
repxx -> xx는 옵션
repne 같지 않을때만 반복
 
call oper1
 push eip
 jmp oper1
 
ret
 pop eip
 
ret oper1
 pop eip
 add esp, oper1
rep opcode
//하나의 코드를 반복
 
loop oper1(address)
//구간 반복
//
 
 
 
OllyDbg 다운


.
공식 사이트에서 왼쪽바에 Odbg110.zip을 다운 받는다.압축을 푼다

plugin, udd 폴더를 만든다.

Options -> Directories -> udd,plugin 폴더의 위치로 설정한다.

Options -> Directories -> Fonts  글꼴을 지정한다.



Add OllyDbg to를 클릭하고 done을 누른후 올리를 끈다.






ctrl + f2 : 재시작
f7 ; step into
f8 : step over
f9 : run
f2 : break point
 
error
 syntax error : 컴파일 에러 (문법에러 )
 exception(예외발생) -> runtime error : 실행도중 에러

간단한 예제
MOV EAX,9FFAF023     //2진수로 10011111~~~이 됨
MOV ECX,100
CDQ 

EAX가 1로 시작하는데 CDQ를 사용함으로써 부호가 있는 데이터 취급하여 음수가 되어버림 그리고 EDX로 비트확장이 일어난다. 이후 나머지를 저장할 EDX는 음부부호 이진수 111~~~ 16진수 FFFF~~~로 채워짐



FFFFFFFF9FFAF023 / 100 이 되어버린다.
몫은 FFFFFFFF9FFAF0 나머지는 23이 되는데 FFFFFFFF9FFAF0를 EAX에 넣을 수 없기 때문에 오버플로우가 발생한다.


+ Recent posts