파라미터 전달 순서 왼쪽 -> 오른쪽 파라미터 순서대로

Integer & Pointer ->  rdi, rsi, rdx, rcx, r8, r9

floating-point(float, double) -> xmm0, xmm1, xmm2, xmm3, xmm4, xmm5, xmm6, xmm7



파라미터는 오른쪽부터 왼쪽 순으로 스택에 push 되고 함수 호출 후 caller(호출자)에 의해 정리 되어야 한다. 


함수가 호출되어지면 return address는 rsp에 위치하고 첫번째 파라미터는 rsp+8로 참조된다 


스택포인터 rsp는 16바이트 단위로 정렬 되어야 하지만

서브루틴 호출의 리턴 어드레스는 8byte만 push 하기 때문에

16바이트 경계를 맞춰주기 위해 rsp에서 8바이트를 더하거나 빼야 한다.


서브루틴이 보존해야 하는 레지스터는 

rbp, rbx, r12, r13, r14, r15 이며,  나머지 모든 레지스터는 자유롭게 서브루틴에서 변경 할 수 있다.

Posted by $Zero
:

REP = 다음에 나오는 명령어를 ECX 만큼 반복해서 수행 

REPNE, REPNZ = Zero Flag 가 0이 아니며 ECX 만큼 수행. Zero Flag가 0이되면 빠져나옴.  (Zero Flag != 0 , ECX > 0 )

REPE, REPZ = Zero Flag 0 일 경우 ECX만큼 수행. Zero Flag 가 설정되면 빠져나옴. (Zero Flag == 0, ECX > 0)

STOS = AX의 값을 EDI 주소에 저장

SCAS = AX의 값과 EDI 주소에 있는 값과 비교 

SCASB = SCAS 를 byte 단위로 비교 

SCASW = SCAS 를 word 단위로 비교 

SCASD = SCAS 를 DWORD 단위로 비교

LODS = ESI 가 가리키는 메모리의 값을 읽어 EAX로 복사 (STOS와 같이 b,w,d 의 단위 연산자가 있음)

LOOPD = ECX만큼 피연산자의 주소로 goto 하는 명령

ROL = 왼쪽으로 shift(<<) 명령 최상위 비트가 오른쪽 끝으로 이동

SHR = 왼쪽으로 shift(<<) 명령 최상위 비트가 CF 로 이동 


LODSB/LODSW/LODSD (Load String Byte/Word/Double) 바이트/워드/더블워드의 자료를 esi가르키는 곳으로 부터 읽어와서 al/ax /eax 레지스터에 전송시킨다. 전송된 후 esi는 다음번 문자열 요소를 가르 키도록 갱신되는 데, df이 0이면 1/2/4만큼 증가되고, df가 1이면 1/2/4 만큼 감소된다.



----JMP----


JL(Jump if Less) = (SF!=0F) 비교 결과가 작으면 점프. 

JLE(Jump if Less or Equal) =  (ZF=1 or SF!=0F) 비교 결과가 작거나 같으면 점프.

JNE(Jump if Not Equa) = (ZF=0) 비교 결과가 다르면 점프.

JNB(Jump if Not Below) = (CF=0) 비교 결과가 크거나 같으면 점프.

JBE(Jump if (unsigned) below or Equal) CF=1 or ZF=1

JB(Jump if Below) = (a < b) 뒤의 피연산자의 값이 클 경우 점프

JA(Jump if Above) = (a > b) 앞의 피연산자의 값이 클 경우 점프 (CF=0 and ZF=0)

JG(Jump if Greater) = (a > b) 왼쪽 인자의 값이 오른쪽 인자의 값보다 크면 점프 (ZF=0 and SF=0F)



----PUSH & POP----


PUSHFD = 플래그 레지스터를 스택에 저장 

PUSHAD = 모든 레지스터를 스택에 저장.

POPAD = PUSHAD로 저장된 레지스터를 모두 복원

POPFD = 스택에서 플래그 레지스터 복원

PUSHA,POPA : 16bit 버전 


----------------------------


CLI = 인터럽트 플래그를 0으로 만든다. (인터럽트 무시)

STI = 인터럽트 플래그를 1로 만든다. (인터럽트 허용)




Posted by $Zero
:





win XP의 CreateRemoteThread 실행 과정


kernel32!CreateRemoteThread() -> ntdll!ZwCreateThread()


windows7 의 CreateRemoteThread 실행 과정


kernel32!CreateRemoteThread() -> kernelbase!CreateRemoteThreadEx() -> ntdll!ZwCreateThreadEx()


kernelbase는 Vista 이상부터 추가된 dll 파일 . 


zwCreateThreadEx() native API를 호출하는 코드루틴을 보면 


Suspend 모드로 쓰레드를 생성하고 


Resume API를 호출하기전에 어떠한 변수값을 비교한 후 점프를 함 .


만약 그 변수값이 틀릴 경우 Resume을 호출하지 않고 그대로 ExitThread API함수로 건너 뜀 


Resume 이 실행되야 Suspend모드에서 빠져나올 수 있으므로 


해당 CMP 명령어에서 변수값을 똑같도록 맞춰주면 DLL인젝션이 성공적으로 이루어짐

'레퍼런스 > Reversing' 카테고리의 다른 글

ADM 64 Linux 호출 규약  (0) 2018.05.18
[리버싱] 어셈블리어 정리  (1) 2014.05.13
Posted by $Zero
: