PE 구조를 살펴보는 데는 Detect It Easy
툴을 사용하면 된다
Detect It Easy
는 다음과 같은 기능(정보)을 제공한다
세 번째 예제 abexcm3.exe
를 열어서 알 수 있는 것은?
이제 실행해보자
함수 호출 규약의 3가지 방식
cedcl
ADD ESP 8
를 통해 스택의 위치를 증가시켜 정리// [caller]
PUSH 2
PUSH 1
CALL callee
ADD ESP 8
stdcall
- 인자가 오른쪽에서 왼쪽으로 순서대로 스택으로 전달
RETN 8
// [caller]
PUSH 2
PUSH 1
CALL callee
...
// [callee]
PUSH EBP
MOV EBP, ESP
...
POP EBP
RETN 8
fastcall
- 인자가 오른쪽에서 왼쪽으로 순서대로 레지스터를 사용해서 전달
- 스택 정리할 필요 없음
- 피호출자 (= callee)가 RETN
// [caller]
MOV EDX 2
MOV ECX 1
CALL callee
...
// [callee]
PUSH EBP
MOV EBP, ESP
...
MOV DWORD PTR SS:[EBP-8], EDX
MOV DWORD PTR SS:[EBP-4], ECX
...
POP EBP
RETN
이제 abexcm3.exe
프로그램의 구조에 대해 분석
분석으로 알아낼 수 있는 프로그램 실행 순서
CreateFileA()
함수를 통해서 키를 담은 파일 abex.12c
가 있는지 확인해서 EAX
에 저장
파일이 없다면 "Hmmm, I can't find the file!"
메시지 부분으로 JMP
파일이 있다면 GetFileSize()
함수를 통해 파일 크기를 확인해서 EAX
에 저장
"Yep, keyfile found!"
"The found file is not a valid keyfile!"
CreateFileA()
함수 상단에 FileName = abex.12c
HANDLE CreateFileA(
[in] LPCSTR lpFileName,
[in] DWORD dwDesiredAccess,
[in] DWORD dwShareMode,
[in, optional] LPSECURITY_ATTRIBUTES lpSecurityAttributes,
[in] DWORD dwCreationDisposition,
[in] DWORD dwFlagsAndAttributes,
[in, optional] HANDLE hTemplateFile
);
메모장을 열어서 키를 담을 파일 abex.12c
를 생성하고, 내용은 대충 아무거나 10바이트 넣어본다
파일의 크기를 검사하는 부분에 BP를 걸고 실행
프로그램의 크기가 EAX
레지스터에 10
이라고 적힌 부분을 찾을 수 있고, 유효한 값은 16진수로 12
임을 알 수 있다
abex.12c
에 문자를 더 입력해서 18 바이트 (= 16진수로 12 바이트) 로 만들어준다
실행하면 CMP
에서 ZF
가 1
로 설정되어서 JNE
구문은 점프하지 않음
성공!