-
20140818 (Assembly CDECL, STDCALL, PE구조)부산IT학원/스마트컨트롤러 2014. 8. 18. 15:35
121일차
---------------
Assembly
---------------
------- CDECL & STDCALL 방식
CDECL , STDCALL 방식은 함수 호출 후 인수를 정리하는 방식으로
호출한 곳에서 인수를 정리하면 CDECL 방식,
호출당한 곳에서 인수를 정리하면 STDCALL 방식이다.
--- CDECL 방식 예제코드
aaa() 함수를 호출한 main() 함수에서 add esp , 8 로 인수를 정리하고 있다.
--- STDCALL 방식 예제코드
호출당한 aaa() 함수에서 마지막에 ret 8 로 인수를 정리하고 있다.
위의 소스에서 확인할 수 있듯이 __stdcall을 붙이면 STDCALL 방식으로 되고
생략 시 CDECL 방식으로 작성된다.
STDCALL 방식이 1byte 더 아낄 수 있다고 하는데...
얼마 전에 배운 ARM 같은 경우, 인수 4개까지 Reg에 저장한다고 한다.
적절히 사용할 경우 더 효율적으로 사용할 수 있다.
------- STST 함수와 LDST 함수
STST() 함수는 Register들을 저장하는 것이고,
LDST() 함수는 STST() 함수를 저장할 당시 Register 들의 상태로 되돌리고
STST() 이후로 돌아가는 함수이다.
--------------
PE 구조
--------------
PE(Portable Executable)파일은 말 그대로 옮겨다니면서 실행시킬수 있는 파일을 말합니다.
Microsoft가 다른 운영체제와 이식성을 좋게 하기 위해서 만든 파일 포멧입니다.그러면 Microsoft가 이런 PE파일을 만들기 위해 제작한 PE 파일 구조에 대해서 공부를 해보겠습니다.1. PE 파일공식적으로 PE파일의 종류는
이렇게 OBJ를 제외한 나머지는 모두 실행 가능한 파일로 이루어져 있습니다.실행 계열 : EXE, SCR 드라이버 계열 : SYS, VXD 라이브러리 계열 : DLL, OCX, CPL, DRV 오브젝트 파일 계열 : OBJ 2. 배우는 이유PE파일 구조를 배우면 파일이 실행되기 위한 모든 정보를 얻을 수 있습니다.예를 들어 어느 메모리의 주소에 로딩이 되는지, 프로그램이 사용하는 API의 정보 등 등을 얻을 수 있습니다.3. PE 파일 구조이런식으로 파일과 메모리에 영역이 구분되어서 PE파일들이 메모리에 맵핑이됩니다.앞으로 이 PE구조 안에 있는 작은 DOS header, DOS stub 등 등을 공부해보겠습니다.4. PE 헤더PE헤더란 PE파일 구조중에서 DOS header부터 Section header까지를 말합니다.그러면 PE헤더에 있는 각각의 부분에 대해서 가르쳐 드리겠습니다.1) DOS headertypedef struct _IMAGE_DOS_HEADER {WORD e_magic; // DOS signature : 4D5A ("MZ")
WORD e_cblp;
WORD e_cp;
WORD e_crlc;
WORD e_cparhdr;
WORD e_minalloc;
WORD e_maxalloc;
WORD e_ss;
WORD e_sp;
WORD e_csum;
WORD e_ip;
WORD e_cs;
WORD e_lfarlc;
WORD e_ovno;
WORD e_res[4];
WORD e_oemid;
WORD e_oeminfo;
WORD e_res2[10];
LONG e_lfanew; // offset to NT header
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;여기서 중요한 값은 e_magic, e_lfanew 이렇게 2개가 있습니다.
여기서 e_magic의 값은 DOS signature로 MZ라는 문자열입니다.
(MZ는 Mark Zbikowski라고 DOS실행파일을 설계한 사람의 이니셜입니다.)
또한 e_lfanew의 값은 NT header의 RVA형태의 주소값을 가지고있습니다.
(이 값은 꼭 40이상의 크기를 가질 필요는 없습니다.)
_IMAGE_DOS_HEADER 확인 예제 코드)
#include <windows.h>
#include <stdio.h>
#include <fcntl.h>
#define READ_EXE_FILE_SIZE 256
int main()
{
IMAGE_DOS_HEADER * stpExe;
unsigned char ucBuff[READ_EXE_FILE_SIZE];
int iFile;
iFile = open("print_test.bin", O_RDONLY);
if(0 > iFile)
{
fprintf(stderr, "File open error!\n");
return 0;
}
read(iFile, &ucBuff, READ_EXE_FILE_SIZE);
stpExe = (IMAGE_DOS_HEADER *)ucBuff;
printf("e_magic\t\t\t\t: [ %c%c ]\n", ucBuff[0], ucBuff[1]);
printf("bytes on last page of file\t: [ %d ]\n", stpExe->e_cblp);
printf("Pages in file\t\t\t: [ %d ]\n", stpExe->e_cp);
printf("Relocations\t\t\t: [ %d ]\n", stpExe->e_crlc);
printf("Size of header in paragraphs\t: [ %d ]\n", stpExe->e_cparhdr);
printf("Minimum extra paragraphs needed\t: [ %d ]\n", stpExe->e_minalloc);
printf("Maximum extra paragraphs needed\t: [ %d ]\n", stpExe->e_maxalloc);
printf("Initial (relative) SS value\t: [ %d ]\n", stpExe->e_ss);
printf("Initial SP value\t\t: [ %d ]\n", stpExe->e_sp);
printf("Checksum\t\t\t: [ %d ]\n", stpExe->e_csum);
printf("Initial IP value\t\t: [ %d ]\n", stpExe->e_ip);
printf("Initial (relative) CS value\t: [ %d ]\n", stpExe->e_cs);
printf("File address of relocation table : [ %d ]\n", stpExe->e_lfarlc);
printf("Overlay number\t\t\t: [ %d ]\n", stpExe->e_ovno);
printf("Reserved words\t\t\t: [ %d ]\n", stpExe->e_res[4]);
printf("OEM identifier (for e_oeminfo)\t: [ %d ]\n", stpExe->e_oemid);
printf("OEM information; e_oemid specific : [ %d ]\n", stpExe->e_oeminfo);
printf("Reserved words\t\t\t: [ %d ]\n", stpExe->e_res2[10]);
printf("File address of new exe header\t: [ %d ]\n", stpExe->e_lfanew);
return 0;
}실행 결과
'부산IT학원 > 스마트컨트롤러' 카테고리의 다른 글
20140822 (다른 프로그램 실행 분석 프로그램 작성) (0) 2014.08.22 20140820 (PE 구조) (0) 2014.08.20 20140805 (Assembly 함수 return 값, 인수) (0) 2014.08.05 20140804 (Assembly procedure(함수 구현), call, ret, 지역변수, Entry Code, Exit Code) (0) 2014.08.04 20140801 (Assembly push, pop, pushad, popad, pushfd, popfd) (0) 2014.08.01